2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: fileDlg.c /main/8 1999/09/15 15:15:56 mgreess $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
29 ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
32 ** Description: Routines which manipulate the dialogs associated with
33 ** operations in the File menu.
36 *******************************************************************
37 ** (c) Copyright Hewlett-Packard Company, 1990, 1991, 1992. All rights are
38 ** reserved. Copying or other reproduction of this program
39 ** except for archival purposes is prohibited without prior
40 ** written consent of Hewlett-Packard Company.
41 ********************************************************************
43 *******************************************************************
44 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
45 ** (c) Copyright 1993, 1994 International Business Machines Corp.
46 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
47 ** (c) Copyright 1993, 1994 Novell, Inc.
48 ********************************************************************
51 **************************************************************************
52 **********************************<+>*************************************/
54 #include <Xm/DialogS.h>
56 #include <Xm/FileSB.h>
57 #include <Xm/Separator.h>
58 #include <Xm/MwmUtil.h>
59 #include <Dt/HourGlass.h>
61 #define MAX_DIR_PATH_LEN 1024
63 #define SAVE_CH ((char *)GETMESSAGE(5, 1, "Save changes to %s?"))
64 #define SAVE_CH_NONAME ((char *)GETMESSAGE(5, 2, "The current file has no name.\nDo you want to save it?"))
65 #define SAVE_CH_BUF ((char *)GETMESSAGE(5, 40, "Save changes?"))
66 #define SAVE_CH_DOC ((char *)GETMESSAGE(5, 41, "Save changes to \"%s?\""))
67 #define SAVE_DROP ((char *)GETMESSAGE(5, 3, "Do you want to save the current copy of %s\nbefore you Edit %s?"))
68 #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? "))
71 /************************************************************************
72 * Forward Declarations
73 ************************************************************************/
74 static void CreateFileSelectionDialog(
76 static void CreateSaveWarning(
80 /************************************************************************
81 * PostAlreadyExistsDlg - Setup and post dialog to determine whether
82 * the user wishes to clobber existing file or try saving it under a
85 * Inputs: pPad->fileStuff.savingName - name of file to save
86 ************************************************************************/
95 SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
97 /* create the dialog if it is the first time */
98 if (!pSaveAs->alrdy_exist)
100 Pixel foreground; /* dialog foreground */
101 Pixel background; /* dialog background */
102 Pixmap pixmap; /* dialog pixmap */
103 XmString tempStr, tempStr2;
107 strcpy(buf, DialogTitle(pPad));
108 strcat(buf, (char *)GETMESSAGE(5, 6, "Warning"));
109 tempStr = XmStringCreateLocalized(buf);
110 XtSetArg(args[n], XmNdialogTitle, tempStr); n++;
111 XtSetArg (args[n], XmNokLabelString,
112 XmStringCreateLocalized((String) _DtOkString)); n++;
113 tempStr2 = XmStringCreateLocalized((char *)GETMESSAGE(2, 1, "Help"));
114 XtSetArg (args[n], XmNhelpLabelString, tempStr2); n++;
115 XtSetArg (args[n], XmNcancelLabelString,
116 XmStringCreateLocalized((String) _DtCancelString)); n++;
117 pSaveAs->alrdy_exist = XmCreateMessageDialog (pPad->app_shell, "Warn",
119 XmStringFree(tempStr);
120 XmStringFree(tempStr2);
122 XtSetArg(args[n], XmNmwmInputMode,
123 MWM_INPUT_PRIMARY_APPLICATION_MODAL);n++;
124 XtSetValues(XtParent(pSaveAs->alrdy_exist), args, n);
128 XtSetArg(args[n], XmNforeground, &foreground); n++;
129 XtSetArg(args[n], XmNbackground, &background); n++;
130 XtGetValues(pSaveAs->alrdy_exist, args, n);
133 pixmap = XmGetPixmap(XtScreen(pSaveAs->alrdy_exist), "warn_image",
134 foreground, background);
135 XtSetArg(args[n], XmNsymbolPixmap, pixmap); n++;
136 XtSetValues(pSaveAs->alrdy_exist, args, n);
138 XtAddCallback (pSaveAs->alrdy_exist, XmNokCallback,
139 (XtCallbackProc) AlrdyExistsOkCB,
141 XtAddCallback (pSaveAs->alrdy_exist, XmNcancelCallback,
142 (XtCallbackProc) AlrdyExistsCancelCB,
144 XtAddCallback (pSaveAs->alrdy_exist, XmNhelpCallback,
145 (XtCallbackProc) HelpFileAlreadyExistsCB,
148 XtRealizeWidget (pSaveAs->alrdy_exist);
152 (char *)XtMalloc(strlen(MSG1) + strlen(pPad->fileStuff.savingName) + 1);
153 sprintf(tmpMess, MSG1, pPad->fileStuff.savingName);
154 tmpMessStr = XmStringCreateLocalized(tmpMess);
156 XtSetArg(args[n], XmNmessageString, tmpMessStr); n++;
157 XtSetValues(pSaveAs->alrdy_exist, args, n);
159 XmStringFree(tmpMessStr);
161 XtManageChild (pSaveAs->alrdy_exist);
166 /************************************************************************
167 * SetSaveAsDirAndFile - Seeds the directory and file name fields of
168 * the SaveAs File Selection Box.
170 * The possibilities for an initial directory are:
172 * 1. The user's previously entered path.
173 * 2. We're editing a file, so use its path.
174 * 3. Use the CWD of our process.
176 ************************************************************************/
178 SetSaveAsDirAndFile(Editor *pPad)
180 char dirbuf[MAX_DIR_PATH_LEN], *currentVal, *directoryVal,
182 int firstSelect = -1, lastSelect = -1;
187 dirbuf[0] = (char) '\0';
189 /* -----> Get the file name field from the previous SaveAs FSB.
190 * XXX - Should use GetValues to get XmNdirSpec. */
191 textField = XmFileSelectionBoxGetChild(
192 pPad->fileStuff.fileWidgets.saveAs.saveAs_form,
194 currentVal = XmTextFieldGetString(textField);
196 /* -----> If the user previously entered a file name via the SaveAs FSB,
198 if (currentVal != (char *)NULL && *currentVal != (char)'\0') {
199 /* -----> If the file name begins with '/', it has a pathname and we
200 * can use it for the initial directory */
201 if ( currentVal[0] == '/' ) {
202 strcpy(dirbuf, currentVal);
203 /* Trim off everything behind the last slash */
204 if ((lastSlash = MbStrrchr(dirbuf, '/')) != (char *)NULL) {
205 *(lastSlash + 1) = (char)'\0';
208 /* -----> The filename does not have a directory, so use the value
209 * from the directory field. */
211 XtSetArg( args[n], XmNdirectory, &dirString ); n++;
212 XtGetValues(pPad->fileStuff.fileWidgets.saveAs.saveAs_form, args, n);
213 directoryVal = (char *) XtMalloc( sizeof(char) *
214 (MAX_DIR_PATH_LEN + 1) );
215 XmStringGetLtoR( dirString, XmFONTLIST_DEFAULT_TAG, &directoryVal );
216 strcpy(dirbuf, directoryVal);
217 XmStringFree(dirString);
218 XtFree( directoryVal );
221 /* -----> No file name was not previously entered via a SaveAs FSB so use
224 if (pPad->fileStuff.pathDir[0] != (char)'\0')
225 strcpy(dirbuf, pPad->fileStuff.pathDir);
226 /* -----> make sure dir ends in '/' */
227 if (dirbuf[0] != (char )'\0') {
228 if (strlen(dirbuf) && dirbuf[strlen(dirbuf) - 1] != (char)'/')
231 getcwd(dirbuf, MAX_DIR_PATH_LEN - 16);
236 /* -----> set the SaveAs FSB directory mask */
237 firstSelect = strlen(dirbuf);
238 strcat(dirbuf, "[^.]*");
239 dirString = XmStringCreateLocalized(dirbuf);
241 XtSetArg(args[n], XmNdirMask, dirString); n++;
242 XtSetValues(pPad->fileStuff.fileWidgets.saveAs.saveAs_form, args, n);
243 XmStringFree(dirString);
244 dirbuf[firstSelect] = (char)'\0';
246 /* -----> set the default file name and select it */
247 strcpy(dirbuf, GETMESSAGE(5, 21, "UNTITLED"));
248 lastSelect = strlen(dirbuf);
249 XmTextFieldSetString(textField, dirbuf);
250 XmTextFieldSetSelection(textField, 0, lastSelect, CurrentTime);
254 /************************************************************************
255 * CreateNewLineToggles - used by CreateSaveAsDialog and CreateSaveWarning
256 * to create a radio box within 'parent' with two toggle buttons
257 * for adding or not adding new lines if word wrap mode is on.
258 ************************************************************************/
260 CreateNewLineToggles(
263 ToggleWidgets *pToggleWidgets)
267 XmString label_string;
269 /* -----> Create Radio Box */
271 XtSetArg(args[n], XmNshadowThickness, 0); n++;
272 XtSetArg(args[n], XmNtraversalOn, True); n++;
273 XtSetArg(args[n], XmNorientation, XmVERTICAL ); n++;
274 pToggleWidgets->newl_radio = XmCreateRadioBox(parent, "radioBox",
277 /* -----> Create the toggle button for adding newlines. */
278 label_string = XmStringCreateLocalized(((char *)GETMESSAGE(5, 44,
279 "Add newline characters to the end of wrap-to-fit lines.")));
281 XtSetArg(args[n], XmNshadowThickness, 0); n++;
282 XtSetArg(args[n], XmNlabelString, label_string); n++;
283 pToggleWidgets->with_newl = XmCreateToggleButtonGadget(
284 pToggleWidgets->newl_radio,
286 XmStringFree(label_string);
287 XtAddCallback(pToggleWidgets->with_newl, XmNvalueChangedCallback,
288 SaveNewLinesCB, (XtPointer) pPad);
289 XtManageChild(pToggleWidgets->with_newl);
291 /* -----> Create the toggle button for not adding newlines. */
292 label_string = XmStringCreateLocalized(((char *)GETMESSAGE(5, 45,
293 "Do not add newlines. Only line breaks created by [Return]\nwill be preserved.")));
295 XtSetArg(args[n], XmNshadowThickness, 0); n++;
296 XtSetArg(args[n], XmNlabelString, label_string); n++;
297 pToggleWidgets->without_newl = XmCreateToggleButtonGadget(
298 pToggleWidgets->newl_radio,
299 "without_nl", args, n);
300 XmStringFree(label_string);
301 XtAddCallback(pToggleWidgets->without_newl, XmNvalueChangedCallback,
302 SaveNewLinesCB, (XtPointer) pPad);
303 XtManageChild(pToggleWidgets->without_newl);
305 /* -----> Set the default to add newlines (if wordwrap is on) */
306 pPad->fileStuff.saveWithNewlines = True;
307 XmToggleButtonGadgetSetState(pToggleWidgets->with_newl, True, False);
309 /* -----> Display the radio box containing the two toggle buttons only
310 * if wordwrap is on */
311 if (pPad->xrdb.wordWrap == True)
312 XtManageChild(pToggleWidgets->newl_radio);
317 /************************************************************************
319 ************************************************************************/
321 CreateSaveAsDialog(Editor *pPad)
325 XmString label_string;
327 SaveAs *pSaveAs = &pPad->fileStuff.fileWidgets.saveAs;
329 _DtTurnOnHourGlass(pPad->app_shell);
331 /* -----> Create the FileSelectionDialog */
332 strcpy(buf, DialogTitle(pPad));
333 if (pPad->xrdb.nameChange) {
334 strcat(buf, (char *)GETMESSAGE(5, 7, "Save As"));
336 strcat(buf, (char *)GETMESSAGE(5, 43, "Copy To File"));
338 label_string = XmStringCreateLocalized(buf);
340 XtSetArg(args[n], XmNdialogTitle, label_string); n++;
341 XtSetArg(args[n], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE); n++;
342 XtSetArg(args[n], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE);
344 XtSetArg (args[n], XmNallowShellResize, False); n++;
345 pSaveAs->saveAs_form = XmCreateFileSelectionDialog(pPad->app_shell,
346 "save_dialog", args, n);
347 XmStringFree(label_string);
349 /* -----> Add the FSB cancel, ok, and help callbacks */
350 XtAddCallback(pSaveAs->saveAs_form,
352 (XtCallbackProc) SaveAsCancelCB,
354 XtAddCallback(pSaveAs->saveAs_form,
356 (XtCallbackProc) SaveAsOkCB,
358 XtAddCallback(pSaveAs->saveAs_form,
360 (XtCallbackProc)HelpSaveAsDialogCB,
363 /* -----> Don't show the filter stuff when saving
364 *XtUnmanageChild(XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
365 * XmDIALOG_FILTER_TEXT));
366 *XtUnmanageChild(XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
367 * XmDIALOG_FILTER_LABEL));
370 /* -----> Set the useAsyncGeo on the shell */
372 XtSetArg(args[n], XmNuseAsyncGeometry, True); n++;
373 XtSetValues (pPad->app_shell, args, n);
375 /* -----> Set the ok button to the default for the bulletin board.
376 * This causes the return key from the text widget to be properly
378 XtSetArg(args[0], XmNdefaultButton,
379 XmFileSelectionBoxGetChild(pSaveAs->saveAs_form,
380 XmDIALOG_OK_BUTTON));
381 XtSetValues (pSaveAs->saveAs_form, args, 1);
383 /* -----> Create a radio box with two toggle buttons for either adding
384 * or not adding new lines if word wrap mode is on. */
385 CreateNewLineToggles(pPad,
386 pSaveAs->saveAs_form, /* parent widget */
387 &pSaveAs->toggleWidgets); /* new widgets */
389 _DtTurnOffHourGlass(pPad->app_shell);
393 /************************************************************************
394 * ExtractAndStoreDir - extracts the directory from the specified
395 * /dir/filename and stores it in pPad->fileStuff.pathDir.
396 ************************************************************************/
403 char *pFirstSlash, *pLastSlash;
405 pFirstSlash = MbStrchr(fileName, '/');
407 if (pFirstSlash != (char *)NULL) {
408 pLastSlash = MbStrrchr(fileName, '/');
409 strncpy(pPad->fileStuff.pathDir, pFirstSlash,
410 pLastSlash - pFirstSlash + 1);
411 pPad->fileStuff.pathDir[pLastSlash - pFirstSlash + 1] = '\0';
415 if (pFirstSlash != (char *)NULL) {
416 pLastSlash = MbStrrchr(fileName, '/');
417 strncpy(pPad->fileStuff.includePathDir, pFirstSlash,
418 pLastSlash - pFirstSlash + 1);
419 pPad->fileStuff.includePathDir[pLastSlash - pFirstSlash + 1] = '\0';
420 if(pPad->fileStuff.lastIncludeName != NULL)
421 XtFree(pPad->fileStuff.lastIncludeName);
423 pPad->fileStuff.lastIncludeName = XtNewString(pLastSlash);
430 /************************************************************************
431 * GetFileName - Ask for a file name via an Xm File Selection Box
432 ************************************************************************/
439 char dirbuf[MAX_DIR_PATH_LEN];
442 int firstSelect = -1;
443 XmString dirString, tmpStr;
444 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
445 FileStuff *pStuff = &pPad->fileStuff;
447 dirbuf[0] = (char) '\0';
449 _DtTurnOnHourGlass(pPad->app_shell);
451 /* -----> create the FSB if it doesn't exits */
452 if (pSelect->file_dialog == NULL) {
453 CreateFileSelectionDialog(pPad);
456 /* Just in case, it was unmanaged */
457 XtManageChild(pSelect->file_dialog);
459 /* -----> set the FSB "ok" and "help" button callbacks */
460 XtRemoveAllCallbacks(pSelect->file_dialog, XmNokCallback);
461 XtAddCallback(pSelect->file_dialog, XmNokCallback,
462 (XtCallbackProc) pStuff->pendingFileFunc,
464 pStuff->pendingFileFunc = (void(*)())NULL;
465 XtRemoveAllCallbacks(pSelect->file_dialog, XmNhelpCallback);
466 XtAddCallback(pSelect->file_dialog, XmNhelpCallback,
467 (XtCallbackProc) pStuff->pendingFileHelpFunc,
469 pStuff->pendingFileHelpFunc = (void (*)())NULL;
471 /* -----> seed FSB directory from either fileName */
473 if (pStuff->pathDir[0] == (char)'\0') {
474 if (pStuff->fileName != NULL) {
475 /* set pStuff->pathDir*/
476 ExtractAndStoreDir(pPad, pStuff->fileName, OPEN);
479 if (pStuff->pathDir[0] != (char)'\0')
480 strcpy(dirbuf, pStuff->pathDir);
481 /* -----> make sure dir ends in '/' */
482 if (dirbuf[0] != (char )'\0') {
483 if (dirbuf[strlen(dirbuf) - 1] != (char)'/')
486 getcwd(dirbuf, MAX_DIR_PATH_LEN - 16);
490 firstSelect = strlen(dirbuf);
491 strcat(dirbuf, "[^.]*");
492 dirString = XmStringCreateLocalized(dirbuf);
494 XtSetArg(al[ac], XmNdirMask, dirString); ac++;
495 XtSetValues(pStuff->fileWidgets.select.file_dialog, al, ac);
496 XmStringFree(dirString);
500 if (pStuff->pathDir[0] != (char)'\0') {
501 tmpStr = XmStringCreateLocalized(pStuff->pathDir);
502 XtSetArg(al[0], XmNdirectory, tmpStr);
503 XtSetValues(pSelect->file_dialog, al, 1);
504 XmStringFree(tmpStr);
508 /* -----> seed FSB directory with include dir */
509 if (pStuff->includePathDir[0] == (char)'\0') {
510 if (pStuff->fileName != (char *)NULL) {
511 /* set pStuff->pathDir*/
512 ExtractAndStoreDir(pPad, pStuff->fileName, INCLUDE);
515 if (pStuff->includePathDir[0] != (char)'\0') {
516 tmpStr = XmStringCreateLocalized(pStuff->includePathDir);
517 XtSetArg(al[0], XmNdirectory, tmpStr);
518 XtSetValues(pSelect->file_dialog, al, 1);
519 XmStringFree(tmpStr);
523 /* -----> find the seeded directory */
524 /*XmFileSelectionDoSearch(pSelect->file_dialog, NULL);*/
526 /* -----> set the FSB title (as passed in) */
527 XtSetArg(al[0], XmNdialogTitle, title);
528 XtSetValues(pSelect->file_dialog, al, 1);
530 /* -----> delete the first entry from the list of dirs
532 * XmListDeletePos(pSelect->dir_list, 1);
537 if(type == INCLUDE) {
538 if(pStuff->lastIncludeName != NULL) {
539 tmpStr = XmStringCreateLocalized(pStuff->lastIncludeName);
540 XmListSelectItem(XmFileSelectionBoxGetChild(pSelect->file_dialog,
541 XmDIALOG_LIST), tmpStr, False);
542 XtSetArg(al[0], XmNtextString, tmpStr);
543 XtSetValues(pSelect->file_dialog, al, 1);
544 XmStringFree(tmpStr);
548 /* -----> manage the FSB */
549 XtManageChild (pSelect->file_dialog);
550 XmProcessTraversal(XmFileSelectionBoxGetChild(pSelect->file_dialog,
551 XmDIALOG_TEXT), XmTRAVERSE_CURRENT);
552 XSync(pPad->display, 0);
554 _DtTurnOffHourGlass(pPad->app_shell);
558 /************************************************************************
559 * CreateFileSelectionDialog -
560 ************************************************************************/
562 CreateFileSelectionDialog(
565 Arg al[10]; /* arg list */
566 int ac; /* arg count */
568 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
571 tmpStr = XmStringCreateLocalized((char *)GETMESSAGE(2, 1, "Help"));
572 XtSetArg (al[ac], XmNhelpLabelString, tmpStr); ac++;
574 pSelect->file_dialog = XmCreateFileSelectionDialog(pPad->app_shell,
575 "file_sel_dlg", al, ac);
576 XmStringFree(tmpStr);
578 XtAddCallback(pSelect->file_dialog, XmNcancelCallback,
579 (XtCallbackProc) CancelFileSelectCB, (XtPointer)pPad );
581 XtRealizeWidget (pSelect->file_dialog);
582 XSync(pPad->display, 0);
585 * pSelect->dir_list = FS_DirList(pSelect->file_dialog);
588 pSelect->filter_text = XmFileSelectionBoxGetChild(pSelect->file_dialog,
589 XmDIALOG_FILTER_TEXT);
590 pSelect->select_text = XmFileSelectionBoxGetChild(pSelect->file_dialog,
592 pSelect->file_list = XmFileSelectionBoxGetChild(pSelect->file_dialog,
597 /************************************************************************
598 * CreateSaveWarning - Builds a PromptDialog to ask if the current contents
599 * are to be saved prior to some operation. Also used to ask if new
600 * lines characters are to be inserted when word wrap is on.
603 * (message) (unmanaged)
604 * (text input region) (unmanaged)
606 * RowColumn horz orientation
607 * LabelGadget exclamation symbol
608 * LabelGadget prompt text
610 * RadioBox contains two new line toggles
611 * (buttons) OK, Apply, Cancel, Help
613 * The RadioBox is managed only if wordwrap is on.
615 ************************************************************************/
620 Arg al[10]; /* arg list */
621 int ac; /* arg count */
624 Pixel foreground, background;
625 Pixmap pixmap; /* dialog pixmap */
626 XmString tmpStr1, tmpStr2, tmpStr3, tmpStr4, tmpStr5;
627 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
629 /* -----> Create a SelectionBox PromptDialog with appropriate title and
631 tmpStr1 = XmStringCreateLocalized(((char *)GETMESSAGE(5, 14, "No")));
632 tmpStr2 = XmStringCreateLocalized(((char *)GETMESSAGE(5, 15, "Yes")));
633 strcpy(buf, DialogTitle(pPad));
634 strcat(buf, (char *)GETMESSAGE(5, 16, "Save?"));
635 tmpStr3 = XmStringCreateLocalized(buf);
636 tmpStr4 = XmStringCreateLocalized(((char *)GETMESSAGE(2, 1, "Help")));
637 tmpStr5 = XmStringCreateLocalized((String) _DtCancelString);
639 XtSetArg(al[ac], XmNapplyLabelString, tmpStr1); ac++;
640 XtSetArg(al[ac], XmNokLabelString, tmpStr2); ac++;
641 XtSetArg(al[ac], XmNdialogTitle, tmpStr3); ac++;
642 XtSetArg(al[ac], XmNhelpLabelString, tmpStr4); ac++;
643 XtSetArg(al[ac], XmNcancelLabelString, tmpStr5); ac++;
644 XtSetArg(al[ac], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE); ac++;
645 XtSetArg(al[ac], XmNmwmDecorations, MWM_DECOR_BORDER | MWM_DECOR_TITLE);
647 XtSetArg (al[ac], XmNallowShellResize, False); ac++;
648 pSelect->save_warning = XmCreatePromptDialog(pPad->app_shell, "save_warn",
650 XmStringFree(tmpStr1);
651 XmStringFree(tmpStr2);
652 XmStringFree(tmpStr3);
653 XmStringFree(tmpStr4);
654 XmStringFree(tmpStr5);
656 /* -----> Set the dialog input mode */
658 XtSetArg(al[ac], XmNmwmInputMode, MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
659 XtSetValues(XtParent(pSelect->save_warning), al, ac);
661 /* -----> Create Form to contain the prompt symbol and text (in a RowColumn)
662 * and the "insert new lines?" toggles (in a RadioBox) */
664 XtSetArg(al[ac], XmNshadowThickness, 0); ac++;
665 pSelect->work_area = XmCreateForm(pSelect->save_warning, "wkarea", al, ac);
666 XtManageChild(pSelect->work_area);
668 /* -----> Create a horizontal RowColumn container for the warning symbol
671 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
672 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
673 XtSetArg(al[ac], XmNorientation, XmHORIZONTAL); ac++;
674 pSelect->row_col = XmCreateRowColumn(pSelect->work_area, "rowCol", al, ac);
675 XtManageChild(pSelect->row_col);
677 /* -----> Place the warning symbol in RowColumn container */
679 XtSetArg(al[ac], XmNforeground, &foreground); ac++;
680 XtSetArg(al[ac], XmNbackground, &background); ac++;
681 XtGetValues(pSelect->save_warning, al, ac);
683 XtSetArg(al[ac], XmNlabelType, XmPIXMAP); ac++;
684 pixmap = XmGetPixmap(XtScreen(pSelect->save_warning), "warn_image",
685 foreground, background);
686 XtSetArg(al[ac], XmNlabelPixmap, pixmap); ac++;
687 w = XmCreateLabelGadget(pSelect->row_col, "pixmap_label", al, ac);
690 /* -----> Place the prompt string in the RowColumn container
691 * (the prompt string is set in AskIfSave() based on whether
692 * or not a file name has been specified among other things) */
694 pSelect->wkArea_textLabel = XmCreateLabelGadget(pSelect->row_col,
696 XtManageChild(pSelect->wkArea_textLabel);
699 /* -----> Create a separator between message and new line toggles */
701 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
702 XtSetArg(al[ac], XmNtopWidget, pSelect->row_col); ac++;
703 XtSetArg(al[ac], XmNtopOffset, 5); ac++;
704 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
705 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
706 pSelect->separator = XmCreateSeparator(pSelect->work_area, "sep", al, ac);
707 if (pPad->xrdb.wordWrap == True)
708 XtManageChild(pSelect->separator);
710 /* -----> Create a radio box with two toggle buttons for either adding
711 * or not adding new lines if word wrap mode is on. */
712 CreateNewLineToggles(pPad,
713 pSelect->work_area, /* parent widget */
714 &pSelect->toggleWidgets); /* new widgets */
716 /* -----> Place toggle buttons below separator */
718 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
719 XtSetArg(al[ac], XmNtopWidget, pSelect->separator); ac++;
720 XtSetArg(al[ac], XmNtopOffset, 5); ac++;
721 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
722 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
723 XtSetValues(pSelect->toggleWidgets.newl_radio, al, ac);
725 /* -----> manage the apply button of the SelectionBox PromptDialog */
726 w = XmSelectionBoxGetChild (pSelect->save_warning, XmDIALOG_APPLY_BUTTON);
729 /* -----> don't need the SelectionBox PromptDialog text input field and
732 kid[ac++] = XmSelectionBoxGetChild (pSelect->save_warning, XmDIALOG_TEXT);
733 kid[ac++] = XmSelectionBoxGetChild (pSelect->save_warning,
734 XmDIALOG_SELECTION_LABEL);
735 XtUnmanageChildren (kid, ac);
737 /* -----> set the SelectionBox PromptDialog [No] [Cancel] [Help] callbacks
738 * (the [Yes] XmNokCallback is set in AskIfSave() based on whether
739 * or not a file name has been specified among other things) */
740 XtAddCallback(pSelect->save_warning, XmNapplyCallback,
741 (XtCallbackProc) NoSaveCB, (XtPointer) pPad);
742 XtAddCallback(pSelect->save_warning, XmNcancelCallback,
743 (XtCallbackProc) AskIfSaveCancelCB, (XtPointer) pPad);
744 XtAddCallback(pSelect->save_warning, XmNhelpCallback,
745 (XtCallbackProc) HelpAskIfSaveDialogCB, (XtPointer) pPad);
747 /* -----> save the widget id of the Cancel button so that it can be
748 * unmanaged (in AskIfSave) if a "forced" TTDT_QUIT is being
750 pSelect->cancelBtn = XmSelectionBoxGetChild(
751 pSelect->save_warning, XmDIALOG_APPLY_BUTTON);
753 XtRealizeWidget(pSelect->save_warning);
758 /************************************************************************
759 * Warning - posts a information/warning/error message dialog
760 ************************************************************************/
765 unsigned char dialogType)
769 char *tmpMess, buf[256];
770 FileWidgets *pFileWidgets = &pPad->fileStuff.fileWidgets;
773 tmpMess = strdup(mess);
775 /* create the dialog if it is the first time */
776 if (!pFileWidgets->gen_warning)
779 XtSetArg(al[ac], XmNokLabelString,
780 XmStringCreateLocalized((String) _DtOkString)); ac++;
781 pFileWidgets->gen_warning = XmCreateMessageDialog (pPad->app_shell,
783 /* Unmanage unneeded children. */
784 XtUnmanageChild(XmMessageBoxGetChild(pFileWidgets->gen_warning,
785 XmDIALOG_CANCEL_BUTTON) );
786 XtUnmanageChild(XmMessageBoxGetChild(pFileWidgets->gen_warning,
787 XmDIALOG_HELP_BUTTON) );
789 XtRealizeWidget(pFileWidgets->gen_warning);
791 XtSetArg(al[ac], XmNmwmInputMode,
792 MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
793 XtSetValues(XtParent(pFileWidgets->gen_warning), al, ac);
796 strcpy(buf, DialogTitle(pPad));
800 strcat(buf, (char *)GETMESSAGE(5, 17, "Error"));
802 case XmDIALOG_INFORMATION:
803 strcat(buf, (char *)GETMESSAGE(5, 20, "Information"));
805 case XmDIALOG_WARNING:
807 strcat(buf, (char *)GETMESSAGE(5, 6, "Warning"));
812 tempStr = XmStringCreateLocalized(buf);
813 XtSetArg(al[ac], XmNdialogTitle, tempStr); ac++;
814 XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
815 XtSetArg(al[ac], XmNmessageString,
816 XmStringCreateLocalized(tmpMess)); ac++;
817 XtSetValues(pFileWidgets->gen_warning, al, ac);
818 XmStringFree(tempStr);
820 XtManageChild (pFileWidgets->gen_warning);
824 /************************************************************************
825 * PostSaveError - posts a dialog displaying the status returned by
826 * DtEditorSaveContentsToFile() (when called by the "File" menu
828 ************************************************************************/
833 DtEditorErrorCode errorCode)
835 char errorMsg[256], *errorReason;
837 /* -----> determine the reason why save failed */
839 case DtEDITOR_NO_ERRORS:
841 case DtEDITOR_INVALID_FILENAME:
842 Warning(pPad, ((char *)
843 GETMESSAGE(5, 31, "Unable to save file.\nFile name was not specified.")),
846 case DtEDITOR_UNWRITABLE_FILE:
847 errorReason = strdup( (char *)
848 GETMESSAGE(5, 46, "Either file is unwritable or path to\nfile does not exist."));
850 case DtEDITOR_DIRECTORY:
851 errorReason = strdup((char *)
852 GETMESSAGE(5, 35, "File is a directory."));
854 case DtEDITOR_CHAR_SPECIAL_FILE:
855 errorReason = strdup((char *)
856 GETMESSAGE(5, 36, "File is a character special device."));
858 case DtEDITOR_BLOCK_MODE_FILE:
859 errorReason = strdup((char *)
860 GETMESSAGE(5, 37, "File is a block mode device."));
862 case DtEDITOR_INSUFFICIENT_MEMORY:
863 errorReason = strdup((char *)
864 GETMESSAGE(5, 47, "Operation failed due to insufficient memory.\nTry increasing swap space."));
866 case DtEDITOR_INVALID_TYPE: /* this should never occur */
867 errorReason = strdup((char *)
868 GETMESSAGE(5, 38, "Invalid file format."));
870 case DtEDITOR_SAVE_FAILED: /* this should catch everything else */
871 default: /* - but just in case */
872 errorReason = strdup((char *)
873 GETMESSAGE(5, 39, "Unknown reason - possibly not enough disk space."));
877 /* -----> format and display error messages containing the
878 * file name and reason why the save failed */
880 (char *) GETMESSAGE(5, 30, "Unable to save %1$s.\n%2$s"),
883 Warning(pPad, errorMsg, XmDIALOG_ERROR);
886 if (pPad->fileStuff.pendingFileFunc == FileExitCB) {
887 TTfailPendingQuit(pPad);
893 /************************************************************************
894 * AskIfSave - creates a dialog and corresponding "o.k." button callback
895 * to save the current text to a file. The dialog message and
896 * o.k. callback depend on whether or not a name is associated
898 ************************************************************************/
903 Arg al[10]; /* arg list */
904 int ac; /* arg count */
907 Select *pSelect = &pPad->fileStuff.fileWidgets.select;
909 if (pSelect->save_warning == (Widget) NULL)
910 CreateSaveWarning(pPad);
912 if (pPad->ttQuitReq.contract && pPad->ttQuitReq.force) {
913 XtUnmanageChild(pSelect->cancelBtn);
915 XtManageChild(pSelect->cancelBtn);
918 XtRemoveAllCallbacks(pSelect->save_warning, XmNokCallback);
920 if (pPad->ttEditReq.contract &&
921 pPad->ttEditReq.docName && *pPad->ttEditReq.docName) {
922 /* -----> TT docName supplied in media request, so ask:
923 * "Save changes to "<docName>"?" */
924 tmp = (char *)XtMalloc(strlen(SAVE_CH_DOC) +
925 strlen(pPad->ttEditReq.docName) + 4);
926 sprintf(tmp,SAVE_CH_DOC, pPad->ttEditReq.docName);
927 XtAddCallback(pSelect->save_warning, XmNokCallback,
928 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
929 } else if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
930 /* -----> TT or non-TT filename given, so ask:
931 * "Save changes to <file>?" */
932 tmp = (char *)XtMalloc(strlen(SAVE_CH) +
933 strlen(pPad->fileStuff.fileName) + 4);
934 sprintf(tmp,SAVE_CH, pPad->fileStuff.fileName);
935 XtAddCallback(pSelect->save_warning, XmNokCallback,
936 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
937 } else if (pPad->ttEditReq.contract && pPad->ttEditReq.contents) {
938 /* -----> TT buffer being edited w/o a docName, so simply ask:
940 tmp = (char *)XtMalloc(strlen(SAVE_CH_BUF) + 4);
941 sprintf(tmp,"%s",SAVE_CH_BUF);
942 XtAddCallback(pSelect->save_warning, XmNokCallback,
943 (XtCallbackProc) FileSaveCB, (XtPointer) pPad);
945 /* -----> no file/doc name (and not a TT buffer), so ask:
946 * "File has no name. Do you wash to save it?" */
947 tmp = (char *)XtMalloc(strlen(SAVE_CH_NONAME) + 4);
948 sprintf(tmp,"%s",SAVE_CH_NONAME);
949 XtAddCallback(pSelect->save_warning, XmNokCallback,
950 (XtCallbackProc) FileSaveAsCB, (XtPointer) pPad);
953 tmpStr = XmStringCreateLocalized(tmp);
955 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
956 XtSetValues(pSelect->wkArea_textLabel, al, ac);
957 XmStringFree(tmpStr);
961 * Make sure that the AskIfSave will be visible in case the
962 * main window is iconified and the user is closing the window
963 * from a window manager menu.
965 XtPopup(pPad->app_shell, XtGrabNone);
966 XtMapWidget(pPad->app_shell);
968 XtManageChild (pSelect->save_warning);
969 XmProcessTraversal(XmSelectionBoxGetChild(pSelect->save_warning,
970 XmDIALOG_OK_BUTTON), XmTRAVERSE_CURRENT);
974 DialogTitle(Editor *pPad)
976 if (pPad->dialogTitle == NULL)
977 pPad->dialogTitle = strdup((char *)GETMESSAGE(7, 2, "Text Editor - "));
979 return pPad->dialogTitle;