1 /* $TOG: fileDlg.c /main/8 1999/09/15 15:15:56 mgreess $ */
2 /**********************************<+>*************************************
3 ***************************************************************************
7 ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
10 ** Description: Routines which manipulate the dialogs associated with
11 ** operations in the File menu.
14 *******************************************************************
15 ** (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992. All rights are
16 ** reserved. Copying or other reproduction of this program
17 ** except for archival purposes is prohibited without prior
18 ** written consent of Hewlett-Packard Company.
19 ********************************************************************
21 *******************************************************************
22 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
23 ** (c) Copyright 1993, 1994 International Business Machines Corp.
24 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
25 ** (c) Copyright 1993, 1994 Novell, Inc.
26 ********************************************************************
29 **************************************************************************
30 **********************************<+>*************************************/
32 #include <Xm/DialogS.h>
34 #include <Xm/FileSB.h>
35 #include <Xm/Separator.h>
36 #include <Xm/MwmUtil.h>
37 #include <Dt/HourGlass.h>
39 #define MAX_DIR_PATH_LEN 1024
41 #define SAVE_CH ((char *)GETMESSAGE(5, 1, "Save changes to %s?"))
42 #define SAVE_CH_NONAME ((char *)GETMESSAGE(5, 2, "The current file has no name.\nDo you want to save it?"))
43 #define SAVE_CH_BUF ((char *)GETMESSAGE(5, 40, "Save changes?"))
44 #define SAVE_CH_DOC ((char *)GETMESSAGE(5, 41, "Save changes to \"%s?\""))
45 #define SAVE_DROP ((char *)GETMESSAGE(5, 3, "Do you want to save the current copy of %s\nbefore you Edit %s?"))
46 #define MSG1 ((char *)GETMESSAGE(5, 5, "The file %s already exists.\nDo you want to over write that file\nwith the contents within this edit session? "))
49 /************************************************************************
50 * Forward Declarations
51 ************************************************************************/
52 static void CreateFileSelectionDialog(
54 static void CreateSaveWarning(
58 /************************************************************************
59 * PostAlreadyExistsDlg - Setup and post dialog to determine whether
60 * the user wishes to clobber existing file or try saving it under a
63 * Inputs: pPad->fileStuff.savingName - name of file to save
64 ************************************************************************/
73 SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
75 /* create the dialog if it is the first time */
76 if (!pSaveAs->alrdy_exist)
78 Pixel foreground; /* dialog foreground */
79 Pixel background; /* dialog background */
80 Pixmap pixmap; /* dialog pixmap */
81 XmString tempStr, tempStr2;
85 strcpy(buf, DialogTitle(pPad));
86 strcat(buf, (char *)GETMESSAGE(5, 6, "Warning"));
87 tempStr = XmStringCreateLocalized(buf);
88 XtSetArg(args[n], XmNdialogTitle, tempStr); n++;
89 XtSetArg (args[n], XmNokLabelString,
90 XmStringCreateLocalized((String) _DtOkString)); n++;
91 tempStr2 = XmStringCreateLocalized((char *)GETMESSAGE(2, 1, "Help"));
92 XtSetArg (args[n], XmNhelpLabelString, tempStr2); n++;
93 XtSetArg (args[n], XmNcancelLabelString,
94 XmStringCreateLocalized((String) _DtCancelString)); n++;
95 pSaveAs->alrdy_exist = XmCreateMessageDialog (pPad->app_shell, "Warn",
97 XmStringFree(tempStr);
98 XmStringFree(tempStr2);
100 XtSetArg(args[n], XmNmwmInputMode,
101 MWM_INPUT_PRIMARY_APPLICATION_MODAL);n++;
102 XtSetValues(XtParent(pSaveAs->alrdy_exist), args, n);
106 XtSetArg(args[n], XmNforeground, &foreground); n++;
107 XtSetArg(args[n], XmNbackground, &background); n++;
108 XtGetValues(pSaveAs->alrdy_exist, args, n);
111 pixmap = XmGetPixmap(XtScreen(pSaveAs->alrdy_exist), "warn_image",
112 foreground, background);
113 XtSetArg(args[n], XmNsymbolPixmap, pixmap); n++;
114 XtSetValues(pSaveAs->alrdy_exist, args, n);
116 XtAddCallback (pSaveAs->alrdy_exist, XmNokCallback,
117 (XtCallbackProc) AlrdyExistsOkCB,
119 XtAddCallback (pSaveAs->alrdy_exist, XmNcancelCallback,
120 (XtCallbackProc) AlrdyExistsCancelCB,
122 XtAddCallback (pSaveAs->alrdy_exist, XmNhelpCallback,
123 (XtCallbackProc) HelpFileAlreadyExistsCB,
126 XtRealizeWidget (pSaveAs->alrdy_exist);
130 (char *)XtMalloc(strlen(MSG1) + strlen(pPad->fileStuff.savingName) + 1);
131 sprintf(tmpMess, MSG1, pPad->fileStuff.savingName);
132 tmpMessStr = XmStringCreateLocalized(tmpMess);
134 XtSetArg(args[n], XmNmessageString, tmpMessStr); n++;
135 XtSetValues(pSaveAs->alrdy_exist, args, n);
137 XmStringFree(tmpMessStr);
139 XtManageChild (pSaveAs->alrdy_exist);
144 /************************************************************************
145 * SetSaveAsDirAndFile - Seeds the directory and file name fields of
146 * the SaveAs File Selection Box.
148 * The possibilities for an initial directory are:
150 * 1. The user's previously entered path.
151 * 2. We're editing a file, so use its path.
152 * 3. Use the CWD of our process.
154 ************************************************************************/
156 SetSaveAsDirAndFile(Editor *pPad)
158 char dirbuf[MAX_DIR_PATH_LEN], *currentVal, *directoryVal,
160 int firstSelect = -1, lastSelect = -1;
165 dirbuf[0] = (char) '\0';
167 /* -----> Get the file name field from the previous SaveAs FSB.
168 * XXX - Should use GetValues to get XmNdirSpec. */
169 textField = XmFileSelectionBoxGetChild(
170 pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
172 currentVal = XmTextFieldGetString(textField);
174 /* -----> If the user previously entered a file name via the SaveAs FSB,
176 if (currentVal != (char *)NULL && *currentVal != (char)'\0') {
177 /* -----> If the file name begins with '/', it has a pathname and we
178 * can use it for the initial directory */
179 if ( currentVal[0] == '/' ) {
180 strcpy(dirbuf, currentVal);
181 /* Trim off everything behind the last slash */
182 if ((lastSlash = MbStrrchr(dirbuf, '/')) != (char *)NULL) {
183 *(lastSlash + 1) = (char)'\0';
186 /* -----> The filename does not have a directory, so use the value
187 * from the directory field. */
189 XtSetArg( args[n], XmNdirectory, &dirString ); n++;
190 XtGetValues(pPad->fileStuff.fileWidgets.saveAs.saveAs_form, args, n);
191 directoryVal = (char *) XtMalloc( sizeof(char) *
192 (MAX_DIR_PATH_LEN + 1) );
193 XmStringGetLtoR( dirString, XmFONTLIST_DEFAULT_TAG, &directoryVal );
194 strcpy(dirbuf, directoryVal);
195 XmStringFree(dirString);
196 XtFree( directoryVal );
199 /* -----> No file name was not previously entered via a SaveAs FSB so use
202 if (pPad->fileStuff.pathDir[0] != (char)'\0')
203 strcpy(dirbuf, pPad->fileStuff.pathDir);
204 /* -----> make sure dir ends in '/' */
205 if (dirbuf[0] != (char )'\0') {
206 if (dirbuf[strlen(dirbuf) - 1] != (char)'/')
209 getcwd(dirbuf, MAX_DIR_PATH_LEN - 16);
214 /* -----> set the SaveAs FSB directory mask */
215 firstSelect = strlen(dirbuf);
216 strcat(dirbuf, "[^.]*");
217 dirString = XmStringCreateLocalized(dirbuf);
219 XtSetArg(args[n], XmNdirMask, dirString); n++;
220 XtSetValues(pPad->fileStuff.fileWidgets.saveAs.saveAs_form, args, n);
221 XmStringFree(dirString);
222 dirbuf[firstSelect] = (char)'\0';
224 /* -----> set the default file name and select it */
225 strcpy(dirbuf, GETMESSAGE(5, 21, "UNTITLED"));
226 lastSelect = strlen(dirbuf);
227 XmTextFieldSetString(textField, dirbuf);
228 XmTextFieldSetSelection(textField, 0, lastSelect, CurrentTime);
232 /************************************************************************
233 * CreateNewLineToggles - used by CreateSaveAsDialog and CreateSaveWarning
234 * to create a radio box within 'parent' with two toggle buttons
235 * for adding or not adding new lines if word wrap mode is on.
236 ************************************************************************/
238 CreateNewLineToggles(
241 ToggleWidgets *pToggleWidgets)
245 XmString label_string;
247 /* -----> Create Radio Box */
249 XtSetArg(args[n], XmNshadowThickness, 0); n++;
250 XtSetArg(args[n], XmNtraversalOn, True); n++;
251 XtSetArg(args[n], XmNorientation, XmVERTICAL ); n++;
252 pToggleWidgets->newl_radio = XmCreateRadioBox(parent, "radioBox",
255 /* -----> Create the toggle button for adding newlines. */
256 label_string = XmStringCreateLocalized(((char *)GETMESSAGE(5, 44,
257 "Add newline characters to the end of wrap-to-fit lines.")));
259 XtSetArg(args[n], XmNshadowThickness, 0); n++;
260 XtSetArg(args[n], XmNlabelString, label_string); n++;
261 pToggleWidgets->with_newl = XmCreateToggleButtonGadget(
262 pToggleWidgets->newl_radio,
264 XmStringFree(label_string);
265 XtAddCallback(pToggleWidgets->with_newl, XmNvalueChangedCallback,
266 SaveNewLinesCB, (XtPointer) pPad);
267 XtManageChild(pToggleWidgets->with_newl);
269 /* -----> Create the toggle button for not adding newlines. */
270 label_string = XmStringCreateLocalized(((char *)GETMESSAGE(5, 45,
271 "Do not add newlines. Only line breaks created by [Return]\nwill be preserved.")));
273 XtSetArg(args[n], XmNshadowThickness, 0); n++;
274 XtSetArg(args[n], XmNlabelString, label_string); n++;
275 pToggleWidgets->without_newl = XmCreateToggleButtonGadget(
276 pToggleWidgets->newl_radio,
277 "without_nl", args, n);
278 XmStringFree(label_string);
279 XtAddCallback(pToggleWidgets->without_newl, XmNvalueChangedCallback,
280 SaveNewLinesCB, (XtPointer) pPad);
281 XtManageChild(pToggleWidgets->without_newl);
283 /* -----> Set the default to add newlines (if wordwrap is on) */
284 pPad->fileStuff.saveWithNewlines = True;
285 XmToggleButtonGadgetSetState(pToggleWidgets->with_newl, True, False);
287 /* -----> Display the radio box containing the two toggle buttons only
288 * if wordwrap is on */
289 if (pPad->xrdb.wordWrap == True)
290 XtManageChild(pToggleWidgets->newl_radio);
295 /************************************************************************
297 ************************************************************************/
299 CreateSaveAsDialog(Editor *pPad)
303 XmString label_string;
305 SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
307 _DtTurnOnHourGlass(pPad->app_shell);
309 /* -----> Create the FileSelectionDialog */
310 strcpy(buf, DialogTitle(pPad));
311 if (pPad->xrdb.nameChange) {
312 strcat(buf, (char *)GETMESSAGE(5, 7, "Save As"));
314 strcat(buf, (char *)GETMESSAGE(5, 43, "Copy To File"));
316 label_string = XmStringCreateLocalized(buf);
318 XtSetArg(args[n], XmNdialogTitle, label_string); n++;
319 XtSetArg(args[n], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE); n++;
320 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE);
322 XtSetArg (args[n], XmNallowShellResize, False); n++;
323 pSaveAs->saveAs_form = XmCreateFileSelectionDialog(pPad->app_shell,
324 "save_dialog", args, n);
325 XmStringFree(label_string);
327 /* -----> Add the FSB cancel, ok, and help callbacks */
328 XtAddCallback(pSaveAs->saveAs_form,
330 (XtCallbackProc) SaveAsCancelCB,
332 XtAddCallback(pSaveAs->saveAs_form,
334 (XtCallbackProc) SaveAsOkCB,
336 XtAddCallback(pSaveAs->saveAs_form,
338 (XtCallbackProc)HelpSaveAsDialogCB,
341 /* -----> Don't show the filter stuff when saving
342 *XtUnmanageChild(XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
343 * XmDIALOG_FILTER_TEXT));
344 *XtUnmanageChild(XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
345 * XmDIALOG_FILTER_LABEL));
348 /* -----> Set the useAsyncGeo on the shell */
350 XtSetArg(args[n], XmNuseAsyncGeometry, True); n++;
351 XtSetValues (pPad->app_shell, args, n);
353 /* -----> Set the ok button to the default for the bulletin board.
354 * This causes the return key from the text widget to be properly
356 XtSetArg(args[0], XmNdefaultButton,
357 XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
358 XmDIALOG_OK_BUTTON));
359 XtSetValues (pSaveAs->saveAs_form, args, 1);
361 /* -----> Create a radio box with two toggle buttons for either adding
362 * or not adding new lines if word wrap mode is on. */
363 CreateNewLineToggles(pPad,
364 pSaveAs->saveAs_form, /* parent widget */
365 &pSaveAs->toggleWidgets); /* new widgets */
367 _DtTurnOffHourGlass(pPad->app_shell);
371 /************************************************************************
372 * ExtractAndStoreDir - extracts the directory from the specified
373 * /dir/filename and stores it in pPad->fileStuff.pathDir.
374 ************************************************************************/
381 char *pFirstSlash, *pLastSlash;
383 pFirstSlash = MbStrchr(fileName, '/');
385 if (pFirstSlash != (char *)NULL) {
386 pLastSlash = MbStrrchr(fileName, '/');
387 strncpy(pPad->fileStuff.pathDir, pFirstSlash,
388 pLastSlash - pFirstSlash + 1);
389 pPad->fileStuff.pathDir[pLastSlash - pFirstSlash + 1] = '\0';
393 if (pFirstSlash != (char *)NULL) {
394 pLastSlash = MbStrrchr(fileName, '/');
395 strncpy(pPad->fileStuff.includePathDir, pFirstSlash,
396 pLastSlash - pFirstSlash + 1);
397 pPad->fileStuff.includePathDir[pLastSlash - pFirstSlash + 1] = '\0';
398 if(pPad->fileStuff.lastIncludeName != NULL)
399 XtFree(pPad->fileStuff.lastIncludeName);
401 pPad->fileStuff.lastIncludeName = XtNewString(pLastSlash);
408 /************************************************************************
409 * GetFileName - Ask for a file name via an Xm File Selection Box
410 ************************************************************************/
417 char dirbuf[MAX_DIR_PATH_LEN];
420 int firstSelect = -1;
421 XmString dirString, tmpStr;
422 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
423 FileStuff *pStuff = &pPad->fileStuff;
425 dirbuf[0] = (char) '\0';
427 _DtTurnOnHourGlass(pPad->app_shell);
429 /* -----> create the FSB if it doesn't exits */
430 if (pSelect->file_dialog == NULL) {
431 CreateFileSelectionDialog(pPad);
434 /* Just in case, it was unmanaged */
435 XtManageChild(pSelect->file_dialog);
437 /* -----> set the FSB "ok" and "help" button callbacks */
438 XtRemoveAllCallbacks(pSelect->file_dialog, XmNokCallback);
439 XtAddCallback(pSelect->file_dialog, XmNokCallback,
440 (XtCallbackProc) pStuff->pendingFileFunc,
442 pStuff->pendingFileFunc = (void(*)())NULL;
443 XtRemoveAllCallbacks(pSelect->file_dialog, XmNhelpCallback);
444 XtAddCallback(pSelect->file_dialog, XmNhelpCallback,
445 (XtCallbackProc) pStuff->pendingFileHelpFunc,
447 pStuff->pendingFileHelpFunc = (void (*)())NULL;
449 /* -----> seed FSB directory from either fileName */
451 if (pStuff->pathDir[0] == (char)'\0') {
452 if (pStuff->fileName != NULL) {
453 /* set pStuff->pathDir*/
454 ExtractAndStoreDir(pPad, pStuff->fileName, OPEN);
457 if (pStuff->pathDir[0] != (char)'\0')
458 strcpy(dirbuf, pStuff->pathDir);
459 /* -----> make sure dir ends in '/' */
460 if (dirbuf[0] != (char )'\0') {
461 if (dirbuf[strlen(dirbuf) - 1] != (char)'/')
464 getcwd(dirbuf, MAX_DIR_PATH_LEN - 16);
468 firstSelect = strlen(dirbuf);
469 strcat(dirbuf, "[^.]*");
470 dirString = XmStringCreateLocalized(dirbuf);
472 XtSetArg(al[ac], XmNdirMask, dirString); ac++;
473 XtSetValues(pStuff->fileWidgets.select.file_dialog, al, ac);
474 XmStringFree(dirString);
478 if (pStuff->pathDir[0] != (char)'\0') {
479 tmpStr = XmStringCreateLocalized(pStuff->pathDir);
480 XtSetArg(al[0], XmNdirectory, tmpStr);
481 XtSetValues(pSelect->file_dialog, al, 1);
482 XmStringFree(tmpStr);
486 /* -----> seed FSB directory with include dir */
487 if (pStuff->includePathDir[0] == (char)'\0') {
488 if (pStuff->fileName != (char *)NULL) {
489 /* set pStuff->pathDir*/
490 ExtractAndStoreDir(pPad, pStuff->fileName, INCLUDE);
493 if (pStuff->includePathDir[0] != (char)'\0') {
494 tmpStr = XmStringCreateLocalized(pStuff->includePathDir);
495 XtSetArg(al[0], XmNdirectory, tmpStr);
496 XtSetValues(pSelect->file_dialog, al, 1);
497 XmStringFree(tmpStr);
501 /* -----> find the seeded directory */
502 /*XmFileSelectionDoSearch(pSelect->file_dialog, NULL);*/
504 /* -----> set the FSB title (as passed in) */
505 XtSetArg(al[0], XmNdialogTitle, title);
506 XtSetValues(pSelect->file_dialog, al, 1);
508 /* -----> delete the first entry from the list of dirs
510 * XmListDeletePos(pSelect->dir_list, 1);
515 if(type == INCLUDE) {
516 if(pStuff->lastIncludeName != NULL) {
517 tmpStr = XmStringCreateLocalized(pStuff->lastIncludeName);
518 XmListSelectItem(XmFileSelectionBoxGetChild(pSelect->file_dialog,
519 XmDIALOG_LIST), tmpStr, False);
520 XtSetArg(al[0], XmNtextString, tmpStr);
521 XtSetValues(pSelect->file_dialog, al, 1);
522 XmStringFree(tmpStr);
526 /* -----> manage the FSB */
527 XtManageChild (pSelect->file_dialog);
528 XmProcessTraversal(XmFileSelectionBoxGetChild(pSelect->file_dialog,
529 XmDIALOG_TEXT), XmTRAVERSE_CURRENT);
530 XSync(pPad->display, 0);
532 _DtTurnOffHourGlass(pPad->app_shell);
536 /************************************************************************
537 * CreateFileSelectionDialog -
538 ************************************************************************/
540 CreateFileSelectionDialog(
543 Arg al[10]; /* arg list */
544 register int ac; /* arg count */
546 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
549 tmpStr = XmStringCreateLocalized((char *)GETMESSAGE(2, 1, "Help"));
550 XtSetArg (al[ac], XmNhelpLabelString, tmpStr); ac++;
552 pSelect->file_dialog = XmCreateFileSelectionDialog(pPad->app_shell,
553 "file_sel_dlg", al, ac);
554 XmStringFree(tmpStr);
556 XtAddCallback(pSelect->file_dialog, XmNcancelCallback,
557 (XtCallbackProc) CancelFileSelectCB, (XtPointer)pPad );
559 XtRealizeWidget (pSelect->file_dialog);
560 XSync(pPad->display, 0);
563 * pSelect->dir_list = FS_DirList(pSelect->file_dialog);
566 pSelect->filter_text = XmFileSelectionBoxGetChild(pSelect->file_dialog,
567 XmDIALOG_FILTER_TEXT);
568 pSelect->select_text = XmFileSelectionBoxGetChild(pSelect->file_dialog,
570 pSelect->file_list = XmFileSelectionBoxGetChild(pSelect->file_dialog,
575 /************************************************************************
576 * CreateSaveWarning - Builds a PromptDialog to ask if the current contents
577 * are to be saved prior to some operation. Also used to ask if new
578 * lines characters are to be inserted when word wrap is on.
581 * (message) (unmanaged)
582 * (text input region) (unmanaged)
584 * RowColumn horz orientation
585 * LabelGadget exclamation symbol
586 * LabelGadget prompt text
588 * RadioBox contains two new line toggles
589 * (buttons) OK, Apply, Cancel, Help
591 * The RadioBox is managed only if wordwrap is on.
593 ************************************************************************/
598 Arg al[10]; /* arg list */
599 register int ac; /* arg count */
602 Pixel foreground, background;
603 Pixmap pixmap; /* dialog pixmap */
604 XmString tmpStr1, tmpStr2, tmpStr3, tmpStr4, tmpStr5;
605 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
607 /* -----> Create a SelectionBox PromptDialog with appropriate title and
609 tmpStr1 = XmStringCreateLocalized(((char *)GETMESSAGE(5, 14, "No")));
610 tmpStr2 = XmStringCreateLocalized(((char *)GETMESSAGE(5, 15, "Yes")));
611 strcpy(buf, DialogTitle(pPad));
612 strcat(buf, (char *)GETMESSAGE(5, 16, "Save?"));
613 tmpStr3 = XmStringCreateLocalized(buf);
614 tmpStr4 = XmStringCreateLocalized(((char *)GETMESSAGE(2, 1, "Help")));
615 tmpStr5 = XmStringCreateLocalized((String) _DtCancelString);
617 XtSetArg(al[ac], XmNapplyLabelString, tmpStr1); ac++;
618 XtSetArg(al[ac], XmNokLabelString, tmpStr2); ac++;
619 XtSetArg(al[ac], XmNdialogTitle, tmpStr3); ac++;
620 XtSetArg(al[ac], XmNhelpLabelString, tmpStr4); ac++;
621 XtSetArg(al[ac], XmNcancelLabelString, tmpStr5); ac++;
622 XtSetArg(al[ac], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE); ac++;
623 XtSetArg(al[ac], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE);
625 XtSetArg (al[ac], XmNallowShellResize, False); ac++;
626 pSelect->save_warning = XmCreatePromptDialog(pPad->app_shell, "save_warn",
628 XmStringFree(tmpStr1);
629 XmStringFree(tmpStr2);
630 XmStringFree(tmpStr3);
631 XmStringFree(tmpStr4);
632 XmStringFree(tmpStr5);
634 /* -----> Set the dialog input mode */
636 XtSetArg(al[ac], XmNmwmInputMode, MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
637 XtSetValues(XtParent(pSelect->save_warning), al, ac);
639 /* -----> Create Form to contain the prompt symbol and text (in a RowColumn)
640 * and the "insert new lines?" toggles (in a RadioBox) */
642 XtSetArg(al[ac], XmNshadowThickness, 0); ac++;
643 pSelect->work_area = XmCreateForm(pSelect->save_warning, "wkarea", al, ac);
644 XtManageChild(pSelect->work_area);
646 /* -----> Create a horizontal RowColumn container for the warning symbol
649 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
650 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
651 XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
652 pSelect->row_col = XmCreateRowColumn(pSelect->work_area, "rowCol", al, ac);
653 XtManageChild(pSelect->row_col);
655 /* -----> Place the warning symbol in RowColumn container */
657 XtSetArg(al[ac], XmNforeground, &foreground); ac++;
658 XtSetArg(al[ac], XmNbackground, &background); ac++;
659 XtGetValues(pSelect->save_warning, al, ac);
661 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
662 pixmap = XmGetPixmap(XtScreen(pSelect->save_warning), "warn_image",
663 foreground, background);
664 XtSetArg(al[ac], XmNlabelPixmap, pixmap); ac++;
665 w = XmCreateLabelGadget(pSelect->row_col, "pixmap_label", al, ac);
668 /* -----> Place the prompt string in the RowColumn container
669 * (the prompt string is set in AskIfSave() based on whether
670 * or not a file name has been specified among other things) */
672 pSelect->wkArea_textLabel = XmCreateLabelGadget(pSelect->row_col,
674 XtManageChild(pSelect->wkArea_textLabel);
677 /* -----> Create a separator between message and new line toggles */
679 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
680 XtSetArg(al[ac], XmNtopWidget, pSelect->row_col); ac++;
681 XtSetArg(al[ac], XmNtopOffset, 5); ac++;
682 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
683 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
684 pSelect->separator = XmCreateSeparator(pSelect->work_area, "sep", al, ac);
685 if (pPad->xrdb.wordWrap == True)
686 XtManageChild(pSelect->separator);
688 /* -----> Create a radio box with two toggle buttons for either adding
689 * or not adding new lines if word wrap mode is on. */
690 CreateNewLineToggles(pPad,
691 pSelect->work_area, /* parent widget */
692 &pSelect->toggleWidgets); /* new widgets */
694 /* -----> Place toggle buttons below separator */
696 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
697 XtSetArg(al[ac], XmNtopWidget, pSelect->separator); ac++;
698 XtSetArg(al[ac], XmNtopOffset, 5); ac++;
699 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
700 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
701 XtSetValues(pSelect->toggleWidgets.newl_radio, al, ac);
703 /* -----> manage the apply button of the SelectionBox PromptDialog */
704 w = XmSelectionBoxGetChild (pSelect->save_warning, XmDIALOG_APPLY_BUTTON);
707 /* -----> don't need the SelectionBox PromptDialog text input field and
710 kid[ac++] = XmSelectionBoxGetChild (pSelect->save_warning, XmDIALOG_TEXT);
711 kid[ac++] = XmSelectionBoxGetChild (pSelect->save_warning,
712 XmDIALOG_SELECTION_LABEL);
713 XtUnmanageChildren (kid, ac);
715 /* -----> set the SelectionBox PromptDialog [No] [Cancel] [Help] callbacks
716 * (the [Yes] XmNokCallback is set in AskIfSave() based on whether
717 * or not a file name has been specified among other things) */
718 XtAddCallback(pSelect->save_warning, XmNapplyCallback,
719 (XtCallbackProc) NoSaveCB, (XtPointer) pPad);
720 XtAddCallback(pSelect->save_warning, XmNcancelCallback,
721 (XtCallbackProc) AskIfSaveCancelCB, (XtPointer) pPad);
722 XtAddCallback(pSelect->save_warning, XmNhelpCallback,
723 (XtCallbackProc) HelpAskIfSaveDialogCB, (XtPointer) pPad);
725 /* -----> save the widget id of the Cancel button so that it can be
726 * unmanaged (in AskIfSave) if a "forced" TTDT_QUIT is being
728 pSelect->cancelBtn = XmSelectionBoxGetChild(
729 pSelect->save_warning, XmDIALOG_APPLY_BUTTON);
731 XtRealizeWidget(pSelect->save_warning);
736 /************************************************************************
737 * Warning - posts a information/warning/error message dialog
738 ************************************************************************/
743 unsigned char dialogType)
747 char *tmpMess, buf[256];
748 FileWidgets *pFileWidgets = &pPad->fileStuff.fileWidgets;
751 tmpMess = strdup(mess);
753 /* create the dialog if it is the first time */
754 if (!pFileWidgets->gen_warning)
757 XtSetArg(al[ac], XmNokLabelString,
758 XmStringCreateLocalized((String) _DtOkString)); ac++;
759 pFileWidgets->gen_warning = XmCreateMessageDialog (pPad->app_shell,
761 /* Unmanage unneeded children. */
762 XtUnmanageChild(XmMessageBoxGetChild(pFileWidgets->gen_warning,
763 XmDIALOG_CANCEL_BUTTON) );
764 XtUnmanageChild(XmMessageBoxGetChild(pFileWidgets->gen_warning,
765 XmDIALOG_HELP_BUTTON) );
767 XtRealizeWidget(pFileWidgets->gen_warning);
769 XtSetArg(al[ac], XmNmwmInputMode,
770 MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
771 XtSetValues(XtParent(pFileWidgets->gen_warning), al, ac);
774 strcpy(buf, DialogTitle(pPad));
778 strcat(buf, (char *)GETMESSAGE(5, 17, "Error"));
780 case XmDIALOG_INFORMATION:
781 strcat(buf, (char *)GETMESSAGE(5, 20, "Information"));
783 case XmDIALOG_WARNING:
785 strcat(buf, (char *)GETMESSAGE(5, 6, "Warning"));
790 tempStr = XmStringCreateLocalized(buf);
791 XtSetArg(al[ac], XmNdialogTitle, tempStr); ac++;
792 XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
793 XtSetArg(al[ac], XmNmessageString,
794 XmStringCreateLocalized(tmpMess)); ac++;
795 XtSetValues(pFileWidgets->gen_warning, al, ac);
796 XmStringFree(tempStr);
798 XtManageChild (pFileWidgets->gen_warning);
802 /************************************************************************
803 * PostSaveError - posts a dialog displaying the status returned by
804 * DtEditorSaveContentsToFile() (when called by the "File" menu
806 ************************************************************************/
811 DtEditorErrorCode errorCode)
813 char errorMsg[256], *errorReason;
815 /* -----> determine the reason why save failed */
817 case DtEDITOR_NO_ERRORS:
819 case DtEDITOR_INVALID_FILENAME:
820 Warning(pPad, ((char *)
821 GETMESSAGE(5, 31, "Unable to save file.\nFile name was not specified.")),
824 case DtEDITOR_UNWRITABLE_FILE:
825 errorReason = strdup( (char *)
826 GETMESSAGE(5, 46, "Either file is unwritable or path to\nfile does not exist."));
828 case DtEDITOR_DIRECTORY:
829 errorReason = strdup((char *)
830 GETMESSAGE(5, 35, "File is a directory."));
832 case DtEDITOR_CHAR_SPECIAL_FILE:
833 errorReason = strdup((char *)
834 GETMESSAGE(5, 36, "File is a character special device."));
836 case DtEDITOR_BLOCK_MODE_FILE:
837 errorReason = strdup((char *)
838 GETMESSAGE(5, 37, "File is a block mode device."));
840 case DtEDITOR_INSUFFICIENT_MEMORY:
841 errorReason = strdup((char *)
842 GETMESSAGE(5, 47, "Operation failed due to insufficient memory.\nTry increasing swap space."));
844 case DtEDITOR_INVALID_TYPE: /* this should never occur */
845 errorReason = strdup((char *)
846 GETMESSAGE(5, 38, "Invalid file format."));
848 case DtEDITOR_SAVE_FAILED: /* this should catch everything else */
849 default: /* - but just in case */
850 errorReason = strdup((char *)
851 GETMESSAGE(5, 39, "Unknown reason - possibly not enough disk space."));
855 /* -----> format and display error messages containing the
856 * file name and reason why the save failed */
858 (char *) GETMESSAGE(5, 30, "Unable to save %1$s.\n%2$s"),
861 Warning(pPad, errorMsg, XmDIALOG_ERROR);
864 if (pPad->fileStuff.pendingFileFunc == FileExitCB) {
865 TTfailPendingQuit(pPad);
871 /************************************************************************
872 * AskIfSave - creates a dialog and corresponding "o.k." button callback
873 * to save the current text to a file. The dialog message and
874 * o.k. callback depend on whether or not a name is associated
876 ************************************************************************/
881 Arg al[10]; /* arg list */
882 register int ac; /* arg count */
885 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
887 if (pSelect->save_warning == (Widget) NULL)
888 CreateSaveWarning(pPad);
890 if (pPad->ttQuitReq.contract && pPad->ttQuitReq.force) {
891 XtUnmanageChild(pSelect->cancelBtn);
893 XtManageChild(pSelect->cancelBtn);
896 XtRemoveAllCallbacks(pSelect->save_warning, XmNokCallback);
898 if (pPad->ttEditReq.contract &&
899 pPad->ttEditReq.docName && *pPad->ttEditReq.docName) {
900 /* -----> TT docName supplied in media request, so ask:
901 * "Save changes to "<docName>"?" */
902 tmp = (char *)XtMalloc(strlen(SAVE_CH_DOC) +
903 strlen(pPad->ttEditReq.docName) + 4);
904 sprintf(tmp,SAVE_CH_DOC, pPad->ttEditReq.docName);
905 XtAddCallback(pSelect->save_warning, XmNokCallback,
906 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
907 } else if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
908 /* -----> TT or non-TT filename given, so ask:
909 * "Save changes to <file>?" */
910 tmp = (char *)XtMalloc(strlen(SAVE_CH) +
911 strlen(pPad->fileStuff.fileName) + 4);
912 sprintf(tmp,SAVE_CH, pPad->fileStuff.fileName);
913 XtAddCallback(pSelect->save_warning, XmNokCallback,
914 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
915 } else if (pPad->ttEditReq.contract && pPad->ttEditReq.contents) {
916 /* -----> TT buffer being edited w/o a docName, so simply ask:
918 tmp = (char *)XtMalloc(strlen(SAVE_CH_BUF) + 4);
919 sprintf(tmp,"%s",SAVE_CH_BUF);
920 XtAddCallback(pSelect->save_warning, XmNokCallback,
921 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
923 /* -----> no file/doc name (and not a TT buffer), so ask:
924 * "File has no name. Do you wash to save it?" */
925 tmp = (char *)XtMalloc(strlen(SAVE_CH_NONAME) + 4);
926 sprintf(tmp,"%s",SAVE_CH_NONAME);
927 XtAddCallback(pSelect->save_warning, XmNokCallback,
928 (XtCallbackProc) FileSaveAsCB, (XtPointer) pPad);
931 tmpStr = XmStringCreateLocalized(tmp);
933 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
934 XtSetValues(pSelect->wkArea_textLabel, al, ac);
935 XmStringFree(tmpStr);
939 * Make sure that the AskIfSave will be visible in case the
940 * main window is iconified and the user is closing the window
941 * from a window manager menu.
943 XtPopup(pPad->app_shell, XtGrabNone);
944 XtMapWidget(pPad->app_shell);
946 XtManageChild (pSelect->save_warning);
947 XmProcessTraversal(XmSelectionBoxGetChild(pSelect->save_warning,
948 XmDIALOG_OK_BUTTON), XmTRAVERSE_CURRENT);
952 DialogTitle(Editor *pPad)
954 if (pPad->dialogTitle == NULL)
955 pPad->dialogTitle = strdup((char *)GETMESSAGE(7, 2, "Text Editor - "));
957 return pPad->dialogTitle;