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 librararies 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: editor.c /main/4 1998/04/02 18:18:47 rafi $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
28 * (c) Copyright 1993, 1994 Novell, Inc.
34 * A simple editor based on the DtEditor widget.
42 #include <Dt/Editor.h>
48 #define ApplicationClass "Editor"
54 typedef struct _AppData {
55 XtAppContext appContext;
62 Widget fileSelectionBox;
67 Widget deselectButton;
68 Widget cutPopupButton;
69 Widget copyPopupButton;
72 Boolean overstrikeModeOn;
76 * Used to specify whether data is being loaded, inserted, or saved
77 * from the editor. Used used by the FSB and its callbacks.
80 typedef enum _LoadSaveType {
97 static void SetResizeHints(void);
98 static void DisplayMessage(char *);
99 static Widget CreateMenuBar(Widget);
100 static Widget CreatePopupMenu(Widget);
101 static Widget CreateEditor(Widget);
102 static Widget CreateButton(Widget, String, char, XtCallbackProc, XtPointer);
103 static Widget CreateToggle(Widget, String, char, XtCallbackProc, XtPointer, Boolean);
104 static Widget CreateCascade(Widget, String, char, Widget);
105 static void PopupHandler(Widget, XtPointer, XEvent*, Boolean*);
106 static void SetSelectionState(Boolean);
113 void main(int argc, char **argv)
118 XtSetLanguageProc( (XtAppContext)NULL, (XtLanguageProc)NULL,
121 /* Initialize the application's data */
122 ad.fileSelectionBox = (Widget) NULL;
123 ad.wordWrapOn = False;
124 ad.statusLineOn = False;
125 ad.overstrikeModeOn = False;
127 /* Initialize the toolkit and open the display */
128 ad.top = XtAppInitialize(&ad.appContext, ApplicationClass, NULL, 0,
129 &argc, argv, NULL, NULL, 0);
130 ad.display = XtDisplay(ad.top);
132 /* Create MainWindow. */
134 ad.mainWindow = (Widget) XmCreateMainWindow (ad.top, "main", al, ac);
135 XtManageChild (ad.mainWindow);
137 /* Create MenuBar in MainWindow. */
138 ad.menuBar = CreateMenuBar(ad.mainWindow);
139 XtManageChild(ad.menuBar);
141 /* Create editor widget in MainWindow. */
142 ad.editor = CreateEditor(ad.mainWindow);
143 XtManageChild(ad.editor);
144 ad.messageTextF = DtEditorGetMessageTextFieldID(ad.editor);
146 /* Create the editor popup menu */
147 CreatePopupMenu(ad.editor);
149 /* Set the main window widgets. */
150 XmMainWindowSetAreas(ad.mainWindow, ad.menuBar, NULL, NULL, NULL, ad.editor);
152 /* Realize toplevel widget */
153 XtRealizeWidget (ad.top);
155 /* Set the resize increment and minimum window size properties. */
158 /* Set up menu buttons dependent on selection */
159 SetSelectionState(False);
161 XtAppMainLoop(ad.appContext);
165 /************************************************************************
169 ************************************************************************/
172 * File menu callbacks
175 static void ResetEditorCb(Widget w, XtPointer cd, XtPointer cb)
177 DtEditorReset(ad.editor);
180 static void OpenFileCb( Widget w, XtPointer cd, XtPointer cb)
182 DtEditorErrorCode error;
183 XmFileSelectionBoxCallbackStruct *fcb = (XmFileSelectionBoxCallbackStruct *) cb;
184 LoadSaveType LoadSaveFlag = (LoadSaveType)cd;
185 char *name = (char *) XtMalloc( sizeof(char) * fcb->length + 1 );
190 * Get the name of the file & pass it to the editor widget
193 name = XmStringUnparse(fcb->value, NULL, XmCHARSET_TEXT,
194 XmCHARSET_TEXT, NULL, 0, XmOUTPUT_ALL);
197 * Load or insert the file, as specified
199 if ( LoadSaveFlag == LOAD_DATA )
200 error = DtEditorSetContentsFromFile(ad.editor, name);
202 error = DtEditorInsertFromFile(ad.editor, name);
206 case DtEDITOR_NO_ERRORS:
208 DisplayMessage("File loaded");
211 case DtEDITOR_NULLS_REMOVED:
213 DisplayMessage( "All embedded null characters removed from the file" );
216 case DtEDITOR_READ_ONLY_FILE:
218 DisplayMessage( "The file is write protected" );
221 case DtEDITOR_NONEXISTENT_FILE:
223 DisplayMessage( "Could not find file" );
226 case DtEDITOR_DIRECTORY:
228 DisplayMessage( "The name given is a directory" );
231 case DtEDITOR_CHAR_SPECIAL_FILE:
233 DisplayMessage( "The name given is a character special device" );
236 case DtEDITOR_BLOCK_MODE_FILE:
238 DisplayMessage( "The name given is a block mode device");
241 case DtEDITOR_INSUFFICIENT_MEMORY:
243 DisplayMessage( "Not enough available memory to load file");
246 case DtEDITOR_UNREADABLE_FILE:
249 DisplayMessage( "Could not read the file" );
255 * Remove the OK callback so it can be added again with a new value for
256 * the LoadSaveFlag flag.
258 XtRemoveCallback(w, XmNokCallback, OpenFileCb, cd);
261 * Remove the FSB dialog & clean up
268 static void SaveAsFileCb(Widget w, XtPointer cd, XtPointer cb)
270 DtEditorContentRec cr;
271 DtEditorErrorCode error;
272 Boolean overWrite = False,
273 hardCarriageReturns = True,
274 markContentsAsSaved = True;
275 XmFileSelectionBoxCallbackStruct *fcb = (XmFileSelectionBoxCallbackStruct *)cb;
276 LoadSaveType LoadSaveFlag = (LoadSaveType) cd;
278 char *name = XtMalloc(sizeof(char) * fcb->length + 1 );
280 XmStringGetLtoR(fcb->value, XmFONTLIST_DEFAULT_TAG, &name);
283 * Ask the widget to save its contents to the named file.
286 error = DtEditorSaveContentsToFile(ad.editor, name, overWrite,
287 hardCarriageReturns, markContentsAsSaved);
291 case DtEDITOR_NO_ERRORS:
293 DisplayMessage( "The file has been saved" );
296 case DtEDITOR_UNWRITABLE_FILE:
298 DisplayMessage( "The file is read only" );
301 case DtEDITOR_WRITABLE_FILE:
303 DisplayMessage( "File not saved, it already exists" );
306 case DtEDITOR_DIRECTORY:
308 DisplayMessage( "The name given is a directory" );
311 case DtEDITOR_CHAR_SPECIAL_FILE:
313 DisplayMessage( "The name given is a character special device" );
316 case DtEDITOR_BLOCK_MODE_FILE:
318 DisplayMessage( "The name given is a block mode device");
321 case DtEDITOR_SAVE_FAILED:
324 DisplayMessage( "Could not save the file. Check disc space" );
330 * Remove the OK callback so it can be added again with a new value for
331 * the LoadSaveFlag flag.
333 XtRemoveCallback(w, XmNokCallback, SaveAsFileCb, cd);
336 * Remove the FSB dialog & clean up
338 XtUnmanageChild( w );
344 static void CancelOpenCb(Widget w, XtPointer cd, XtPointer cb)
346 /* Remove the OK callback so it can be added again with a new value for
347 * the LoadSaveFlag flag.
349 XtRemoveCallback(w, XmNokCallback, OpenFileCb, cd);
351 /* Remove the FSB dialog & clean up */
356 static void DisplayFsbCb(Widget w, XtPointer cd, XtPointer cb)
360 XmString tmpStr1, tmpStr2;
362 LoadSaveType LoadSaveFlag = (LoadSaveType) cd;
364 /* Create the FSB, if we need to */
366 if (ad.fileSelectionBox == (Widget) NULL)
369 ad.fileSelectionBox = XmCreateFileSelectionDialog(ad.mainWindow,
372 XtAddCallback(ad.fileSelectionBox, XmNcancelCallback, CancelOpenCb,
373 (XtPointer)LoadSaveFlag);
378 * Set FSB title & label depending up whether loading, inserting, or
379 * saving a container.
381 switch ( LoadSaveFlag )
385 tmpStr1 = XmStringCreateLocalized("Open a File");
386 tmpStr2 = XmStringCreateLocalized("File to open");
389 * Add the OK callback so the curent value of the LoadSaveFlag
392 XtAddCallback(ad.fileSelectionBox, XmNokCallback, OpenFileCb,
393 (XtPointer)LoadSaveFlag);
399 tmpStr1 = XmStringCreateLocalized("Include a File");
400 tmpStr2 = XmStringCreateLocalized("File to include");
403 * Add the OK callback so the curent value of the LoadSaveFlag
406 XtAddCallback(ad.fileSelectionBox, XmNokCallback, OpenFileCb,
407 (XtPointer)LoadSaveFlag);
413 tmpStr1 = XmStringCreateLocalized("Save to File");
414 tmpStr2 = XmStringCreateLocalized("Save to file");
417 * Add the OK callback so the save as callback is called.
419 XtAddCallback(ad.fileSelectionBox, XmNokCallback, SaveAsFileCb,
420 (XtPointer)LoadSaveFlag);
430 XtVaSetValues(ad.fileSelectionBox,
431 XmNdialogTitle, tmpStr1,
432 XmNselectionLabelString, tmpStr1,
435 XmStringFree(tmpStr1);
436 XmStringFree(tmpStr2);
438 /* Display the FSB */
440 XtManageChild (ad.fileSelectionBox);
444 static void ExitCb(Widget w, XtPointer cd, XtPointer cb)
449 /*****************************************************
451 * Edit menu callbacks
455 static void UndoCb(Widget w, XtPointer cd, XtPointer cb)
457 DtEditorUndoEdit(ad.editor);
460 static void CutCb(Widget w, XtPointer cd, XtPointer cb)
462 DtEditorCutToClipboard(ad.editor);
465 static void CopyCb(Widget w, XtPointer cd, XtPointer cb)
467 DtEditorCopyToClipboard(ad.editor);
470 static void PasteCb(Widget w, XtPointer cd, XtPointer cb)
472 DtEditorPasteFromClipboard(ad.editor);
475 static void ClearCb(Widget w, XtPointer cd, XtPointer cb)
477 DtEditorClearSelection(ad.editor);
480 static void DeleteCb(Widget w, XtPointer cd, XtPointer cb)
482 DtEditorDeleteSelection(ad.editor);
485 static void SelectAllCb(Widget w, XtPointer cd, XtPointer cb)
487 DtEditorSelectAll(ad.editor);
490 static void DeselectCb(Widget w, XtPointer cd, XtPointer cb)
492 DtEditorDeselect(ad.editor);
495 static void FindCb(Widget w, XtPointer cd, XtPointer cb)
497 DtEditorInvokeFindChangeDialog(ad.editor);
500 static void SpellCb(Widget w, XtPointer cd, XtPointer cb)
502 DtEditorInvokeSpellDialog(ad.editor);
505 /*****************************************************
507 * Format menu callbacks
511 static void FormatAllCb(Widget w, XtPointer cd, XtPointer cb)
513 DtEditorFormat(ad.editor, (DtEditorFormatSettings *) NULL,
514 DtEDITOR_FORMAT_ALL);
517 static void FormatParaCb(Widget w, XtPointer cd, XtPointer cb)
519 DtEditorFormat(ad.editor, (DtEditorFormatSettings *) NULL,
520 DtEDITOR_FORMAT_PARAGRAPH);
523 static void InvokeFormatDlgCb(Widget w, XtPointer cd, XtPointer cb)
525 DtEditorInvokeFormatDialog(ad.editor);
528 /*****************************************************
530 * Options menu callbacks
534 static void OverstrikeCb(Widget w, XtPointer cd, XtPointer cb)
536 ad.overstrikeModeOn = ad.overstrikeModeOn ? False : True;
537 XtVaSetValues(ad.editor, DtNoverstrike, ad.overstrikeModeOn, NULL);
540 static void StatusLineCb(Widget w, XtPointer cd, XtPointer cb)
542 ad.statusLineOn = ad.statusLineOn ? False : True;
543 XtVaSetValues(ad.editor, DtNshowStatusLine, ad.statusLineOn, NULL);
545 /* Reset the resize increment and minimum window size properties. */
550 static void WordWrapCb(Widget w, XtPointer cd, XtPointer cb)
552 ad.wordWrapOn = ad.wordWrapOn ? False : True;
553 XtVaSetValues(ad.editor, DtNwordWrap, ad.wordWrapOn, NULL);
556 /*****************************************************
562 static void HelpCb(Widget w, XtPointer cd, XtPointer cb)
564 DtEditorHelpCallbackStruct *ecb = (DtEditorHelpCallbackStruct *)cb;
566 DisplayMessage( "Received a request for help");
569 static void TextSelectedCb(Widget w, XtPointer cd, XtPointer cb)
571 SetSelectionState(True);
574 static void TextUnselectedCb(Widget w, XtPointer cd, XtPointer cb)
576 SetSelectionState(False);
579 static void SetSelectionState(Boolean state)
581 XtSetSensitive(ad.cutButton, state);
582 XtSetSensitive(ad.copyButton, state);
583 XtSetSensitive(ad.deleteButton, state);
584 XtSetSensitive(ad.clearButton, state);
585 XtSetSensitive(ad.deselectButton, state);
586 XtSetSensitive(ad.cutPopupButton, state);
587 XtSetSensitive(ad.copyPopupButton, state);
590 /************************************************************************
594 ************************************************************************/
596 /************************************************************************
598 * SetResizeHints - Set the resize increment properties
602 static void SetResizeHints(void)
607 DtEditorGetSizeHints(ad.editor, &sh);
610 * Add Menu Bar height to the height of the Editor widget
612 XtVaGetValues( ad.menuBar, XmNheight, &MBheight, NULL);
613 sh.min_height += MBheight;
614 sh.base_height += MBheight;
616 XSetWMSizeHints(ad.display, XtWindow(ad.top), &sh, XA_WM_NORMAL_HINTS);
619 /************************************************************************
621 * DisplayMessage - Display message in DtEditor's message area
625 static void DisplayMessage(char *message)
627 XmTextFieldSetString(ad.messageTextF, message);
630 /************************************************************************
632 * CreateFileMenu - Create the File pulldown menu
636 static Widget CreateFileMenu(Widget menuBar)
640 fileMenu = (Widget) XmCreatePulldownMenu (menuBar, "fileMenu", NULL, 0);
641 CreateCascade(menuBar, "File", 'F', fileMenu);
642 CreateButton(fileMenu, "New", 'N', ResetEditorCb, NULL);
643 CreateButton(fileMenu, "Open...", 'O', DisplayFsbCb, (XtPointer)LOAD_DATA);
644 CreateButton(fileMenu, "Include...", 'I', DisplayFsbCb,
645 (XtPointer)INSERT_DATA);
646 XtManageChild(XmCreateSeparatorGadget(fileMenu, "sep1", NULL, 0));
647 CreateButton(fileMenu, "Save As...", 'A', DisplayFsbCb, (XtPointer)SAVE_DATA);
648 XtManageChild(XmCreateSeparatorGadget(fileMenu, "sep2", NULL, 0));
649 CreateButton(fileMenu, "Exit", 'x', ExitCb, NULL);
654 /************************************************************************
656 * CreateEditMenu - Create the Edit pulldown menu
660 static Widget CreateEditMenu(Widget menuBar)
664 editMenu = XmCreatePulldownMenu (menuBar, "editMenu", NULL, 0);
666 CreateCascade(menuBar, "Edit", 'E', editMenu);
668 CreateButton(editMenu, "Undo", 'U', UndoCb, NULL);
669 XtManageChild(XmCreateSeparatorGadget(editMenu, "sep1", NULL, 0));
670 ad.cutButton = CreateButton(editMenu, "Cut", 't', CutCb, NULL);
671 ad.copyButton = CreateButton(editMenu, "Copy", 'C', CopyCb, NULL);
672 CreateButton(editMenu, "Paste", 'P', PasteCb, NULL);
673 ad.clearButton = CreateButton(editMenu, "Clear", 'e', ClearCb, NULL);
674 ad.deleteButton = CreateButton(editMenu, "Delete", 't', DeleteCb, NULL);
675 CreateButton(editMenu, "Select All", 'S', SelectAllCb, NULL);
676 ad.deselectButton = CreateButton(editMenu, "Deselect", 'D', DeselectCb, NULL);
677 XtManageChild(XmCreateSeparatorGadget(editMenu, "sep2", NULL, 0));
678 CreateButton(editMenu, "Find/Change...", 'F', FindCb, (XtPointer)ad.editor);
679 CreateButton(editMenu, "Check Spelling...", 'p', SpellCb, (XtPointer)ad.editor);
685 /************************************************************************
687 * CreateFormatMenu - Create the FormatEdit pulldown menu
691 static Widget CreateFormatMenu(Widget menuBar)
695 formatMenu = XmCreatePulldownMenu (menuBar, "formatMenu", NULL, 0);
697 CreateCascade(menuBar, "Format", 'r', formatMenu);
699 CreateButton(formatMenu, "Settings...", 'S', InvokeFormatDlgCb, NULL);
700 CreateButton(formatMenu, "All", 'A', FormatAllCb, NULL);
701 CreateButton(formatMenu, "Paragraph", 'P', FormatParaCb, NULL);
706 /************************************************************************
708 * CreateOptionsMenu - Create the Options pulldown menu
712 static Widget CreateOptionsMenu(Widget menuBar)
716 optionsMenu = XmCreatePulldownMenu (menuBar, "optionsMenu", NULL, 0);
718 CreateCascade(menuBar, "Options", 'O', optionsMenu);
720 CreateToggle(optionsMenu, "Overstrike", 'O', OverstrikeCb, NULL, ad.overstrikeModeOn);
721 CreateToggle(optionsMenu, "Word Wrap", 'W', WordWrapCb, NULL,ad.wordWrapOn);
722 XtManageChild(XmCreateSeparatorGadget(optionsMenu, "sep1", NULL, 0));
723 CreateToggle(optionsMenu, "Status Line", 'S', StatusLineCb, NULL, ad.statusLineOn);
725 return (optionsMenu);
729 * CreatePopupMenu - Create popup menu in editor window
732 static Widget CreatePopupMenu(Widget parent)
738 popupMenu = XmCreatePopupMenu(parent, "popupMenu", NULL, 0);
740 XtAddEventHandler(parent, ButtonPressMask, False, PopupHandler,
741 (XtPointer)popupMenu);
743 fileMenu = XmCreatePulldownMenu (popupMenu, "fileMenu", NULL, 0);
744 CreateCascade(popupMenu, "File", 'F', fileMenu);
745 CreateButton(fileMenu, "Open...", 'O', DisplayFsbCb, (XtPointer)LOAD_DATA);
746 CreateButton(fileMenu, "Include...", 'I', DisplayFsbCb,
747 (XtPointer)INSERT_DATA);
748 CreateButton(fileMenu, "Save As...", 'A', DisplayFsbCb, (XtPointer)SAVE_DATA);
749 CreateButton(fileMenu, "New", 'N', ResetEditorCb, NULL);
751 editMenu = XmCreatePulldownMenu (popupMenu, "editMenu", NULL, 0);
752 CreateCascade(popupMenu, "Edit", 'E', editMenu);
753 CreateButton(editMenu, "Undo", 'U', UndoCb, (XtPointer)LOAD_DATA);
754 ad.cutPopupButton = CreateButton(editMenu, "Cut", 't', CutCb, NULL);
755 ad.copyPopupButton = CreateButton(editMenu, "Copy", 'C', CopyCb, NULL);
756 CreateButton(editMenu, "Paste", 'P', PasteCb, NULL);
758 CreateButton(popupMenu, "Find/Change...", 'F', FindCb, (XtPointer)ad.editor);
763 static void PopupHandler(Widget w, XtPointer cd, XEvent *event, Boolean *ctd)
765 if (((XButtonEvent *)event)->button != Button3) return;
767 XmMenuPosition((Widget)cd, (XButtonEvent *)event);
768 XtManageChild ((Widget)cd);
773 * CreateMenuBar - Create MenuBar in MainWindow
776 static Widget CreateMenuBar(Widget parent)
780 menuBar = XmCreateMenuBar(parent, "menuBar", NULL, 0);
782 CreateFileMenu(menuBar);
783 CreateEditMenu(menuBar);
784 CreateFormatMenu(menuBar);
785 CreateOptionsMenu(menuBar);
792 * CreateEditor - Create the editor widget
795 static Widget CreateEditor(Widget parent)
801 /* create editor widget */
804 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
805 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
806 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
807 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
808 XtSetArg(al[ac], DtNrows, 40); ac++;
809 XtSetArg(al[ac], DtNcolumns, 80); ac++;
810 w = DtCreateEditor(parent, "editor", al, ac);
814 XtAddCallback(w, DtNtextSelectCallback, TextSelectedCb, (XtPointer) w);
815 XtAddCallback(w, DtNtextDeselectCallback, TextUnselectedCb, (XtPointer) w);
816 XtAddCallback(w, XmNhelpCallback, HelpCb, NULL);
821 static Widget CreateButton(Widget parent, String label, char mnemonic, XtCallbackProc callback, XtPointer callData)
824 XmString labelString;
828 labelString = XmStringCreateLocalized(label);
831 XtSetArg(al[ac], XmNlabelString, labelString); ac++;
832 XtSetArg(al[ac], XmNmnemonic, mnemonic); ac++;
833 button = XmCreatePushButtonGadget(parent, label, al, ac);
834 XtAddCallback(button, XmNactivateCallback, callback, callData);
835 XtManageChild(button);
837 XmStringFree(labelString);
842 static Widget CreateToggle(Widget parent, String label, char mnemonic, XtCallbackProc callback, XtPointer callData, Boolean value)
845 XmString labelString;
849 labelString = XmStringCreateLocalized(label);
852 XtSetArg(al[ac], XmNlabelString, labelString); ac++;
853 XtSetArg(al[ac], XmNmnemonic, mnemonic); ac++;
854 XtSetArg(al[ac], XmNvisibleWhenOff, True); ac++;
855 XtSetArg(al[ac], XmNset, value); ac++;
856 button = XmCreateToggleButtonGadget(parent, label, al, ac);
857 XtAddCallback(button, XmNvalueChangedCallback, callback, callData);
858 XtManageChild(button);
860 XmStringFree(labelString);
865 static Widget CreateCascade(Widget parent, String label, char mnemonic, Widget subMenu)
868 XmString labelString;
872 labelString = XmStringCreateLocalized(label);
875 XtSetArg(al[ac], XmNlabelString, labelString); ac++;
876 XtSetArg(al[ac], XmNsubMenuId, subMenu); ac++;
877 XtSetArg(al[ac], XmNmnemonic, mnemonic); ac++;
878 button = XmCreateCascadeButtonGadget(parent, label, al, ac);
879 XtManageChild(button);
881 XmStringFree(labelString);