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: Editor.c /main/24 1999/10/14 16:38:25 mgreess $
24 **********************************<+>*************************************
25 ***************************************************************************
29 ** Project: Text Editor widget
33 ** This is the main source file for the Text Editor widget.
35 *******************************************************************
36 * (c) Copyright 1996 Digital Equipment Corporation.
37 * (c) Copyright 1993, 1994, 1996 Hewlett-Packard Company.
38 * (c) Copyright 1993, 1994, 1996 International Business Machines Corp.
39 * (c) Copyright 1993, 1994, 1996 Sun Microsystems, Inc.
40 * (c) Copyright 1996 Novell, Inc.
41 * (c) Copyright 1996 FUJITSU LIMITED.
42 * (c) Copyright 1996 Hitachi.
43 * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
44 ********************************************************************
46 **************************************************************************
47 **********************************<+>*************************************/
49 /*-------------------------------------------------------------
59 # if (_XOPEN_VERSION==3)
65 #elif defined(__linux__)
68 #elif defined(CSRG_BASED)
78 #include <limits.h> /* For LINE_MAX definition */
79 #include <sys/errno.h> /* For Error handling */
83 #include "X11/Xutil.h"
84 #include <X11/StringDefs.h>
85 #include <X11/keysymdef.h>
87 #include <Xm/MessageB.h>
88 #include <Xm/MwmUtil.h>
90 #include <Xm/LabelG.h>
91 #include <Xm/SeparatoG.h>
92 #include <Xm/PushBG.h>
93 #include <Xm/ToggleBG.h>
94 #include <Xm/RowColumn.h>
96 /* Need the following for _DtOkString */
99 #include <Dt/DtMsgsP.h>
100 #include <Dt/HourGlass.h>
102 #include "DtWidgetI.h"
105 * Private functions borrowed from Motif.
107 extern XmTextLineTable _XmTextGetLineTable(Widget widget, int *total_lines);
108 extern char * _XmStringSourceGetString(XmTextWidget tw,
111 #if NeedWidePrototypes
115 #endif /* NeedWidePrototypes */
118 /*-------------------------------------------------------------
120 **-------------------------------------------------------------
123 /******** Public Function Declarations ********/
125 /******** End Public Function Declarations ********/
127 /*-------------------------------------------------------------
128 ** Forward Declarations
129 **-------------------------------------------------------------
132 /******** Static Function Declarations ********/
134 static void ClassInitialize(void);
135 static void Initialize(
139 Cardinal *num_args) ;
141 static void VariableInitialize(
144 static void ValidateResources(
146 DtEditorWidget request);
148 static Widget CreateText(
149 DtEditorWidget parent);
151 static void extractFontMetrics(
157 static void getFontMetrics(
163 static void SetStatusLine(
165 Boolean statusLineOn);
167 static Widget CreateStatusLine(
168 DtEditorWidget parent);
170 static Boolean SetValues(
175 static void _DtEditorGetCenterToggleLabel(
180 static void _DtEditorGetChangeAllButtonLabel(
185 static void _DtEditorGetChangeButtonLabel(
190 static void _DtEditorGetChangeFieldLabel(
195 static void _DtEditorGetColumns(
200 static void _DtEditorGetCurrentLineLabel(
205 static void _DtEditorGetCursorPosition(
210 static void _DtEditorGetFindButtonLabel(
215 static void _DtEditorGetFindFieldLabel(
220 static void _DtEditorGetFormatAllButtonLabel(
225 static void _DtEditorGetFormatParagraphButtonLabel(
230 static void _DtEditorGetJustifyToggleLabel(
235 static void _DtEditorGetLeftAlignToggleLabel(
240 static void _DtEditorGetLeftMarginFieldLabel(
245 static void _DtEditorGetMaxLength(
250 static void _DtEditorGetMisspelledListLabel(
255 static void _DtEditorGetRightAlignToggleLabel(
260 static void _DtEditorGetRightMarginFieldLabel(
265 static void _DtEditorGetRows(
270 static void _DtEditorGetScrollLeftSide(
275 static void _DtEditorGetScrollTopSide(
280 static void _DtEditorGetTextBackground(
285 static void _DtEditorGetTextForeground(
290 static void _DtEditorGetTopCharacter(
295 static void _DtEditorGetLineCountLabel(
300 static void FixWordWrap( /* XXX Word Wrap workaround */
301 Widget w, /* XXX Word Wrap workaround */
302 Boolean wrapOn); /* XXX Word Wrap workaround */
304 static void BackwardChar(
308 Cardinal *num_params);
310 static void BackwardPara(
314 Cardinal *num_params);
316 static void BackwardWord(
320 Cardinal *num_params);
322 static void BeginningOfFile(
326 Cardinal *num_params);
328 static void BeginningOfLine(
332 Cardinal *num_params);
334 static void ClearSelection(
338 Cardinal *num_params);
340 static void CopyClipboard(
344 Cardinal *num_params);
346 static void CutClipboard(
350 Cardinal *num_params);
352 static void DeleteNextChar(
356 Cardinal *num_params);
358 static void DeleteNextWord(
362 Cardinal *num_params);
364 static void DeletePrevChar(
368 Cardinal *num_params);
370 static void DeletePrevWord(
374 Cardinal *num_params);
376 static void DeleteToEOL(
380 Cardinal *num_params);
382 static void DeleteToSOL(
386 Cardinal *num_params);
388 static void DeselectAll(
392 Cardinal *num_params);
394 static void EndOfFile(
398 Cardinal *num_params);
400 static void EndOfLine(
404 Cardinal *num_params);
406 static void ForwardChar(
410 Cardinal *num_params);
412 static void ForwardPara(
416 Cardinal *num_params);
418 static void ForwardWord(
422 Cardinal *num_params);
424 static void GoToLine(
428 Cardinal *num_params);
430 static void GoToLine_I(
434 Cardinal *num_params);
440 Cardinal *num_params);
442 static void InsertString(
446 Cardinal *num_params);
448 static void KeySelect(
452 Cardinal *num_params);
454 static void NewlineAndBackup(
458 Cardinal *num_params);
460 static void NewlineAndIndent(
464 Cardinal *num_params);
466 static void NextPage(
470 Cardinal *num_params);
472 static void PageLeft(
476 Cardinal *num_params);
478 static void PageRight(
482 Cardinal *num_params);
484 static void PasteClipboard(
488 Cardinal *num_params);
490 static void PreviousPage(
494 Cardinal *num_params);
496 static void ProcessCancel(
500 Cardinal *num_params);
502 static void ProcessDown(
506 Cardinal *num_params);
508 static void ProcessShiftDown(
512 Cardinal *num_params);
514 static void ProcessShiftUp(
518 Cardinal *num_params);
520 static void ProcessUp(
524 Cardinal *num_params);
526 static void QuoteNextChar(
530 Cardinal *num_params);
532 static void QuoteNextChar_I(
536 Cardinal *num_params);
538 static void SelectAll(
542 Cardinal *num_params);
544 static void ToggleInsertMode(
548 Cardinal *num_params);
550 static void ToggleInsertMode_I(
554 Cardinal *num_params);
556 static void UndoEdit(
560 Cardinal *num_params);
562 static void UndoEdit_I(
566 Cardinal *num_params);
568 static void Call_TextSelectCallback(
569 DtEditorWidget editor);
571 static void Call_TextDeselectCallback(
572 DtEditorWidget editor);
574 static void Editor_SetSelectionProc(
577 XmTextPosition right,
580 static void CallHelpCallback(
581 DtEditorWidget editor,
584 static void HelpEditWindowCB(
589 static void HelpStatusCurrentLineCB(
594 static void HelpStatusTotalLinesCB(
599 static void HelpStatusMessageCB(
604 static void HelpStatusOverstrikeCB(
609 static void RegisterDropZone(
612 static void UnregisterDropZone(
615 static void SetInfoDialogTitle(
616 DtEditorWidget editor );
618 static int FormatText (
621 static void AdjustParaCB(
626 static void AdjustAllCB(
631 static DtEditorErrorCode DoAdjust(
632 DtEditorWidget editor,
635 unsigned int alignment,
636 XmTextPosition start,
639 static void SetFormatDialogTitle(
640 DtEditorWidget editor);
642 static void ResetFormatDialog(
643 DtEditorWidget editor);
645 static void CreateFormatDialog(
646 DtEditorWidget editor);
648 static void GetAdjustSettings(
650 DtEditorFormatSettings *formatSettings);
652 static void UpdateOverstrikeIndicator(
653 DtEditorWidget widget,
654 Boolean overstrikeOn );
656 /******** End Static Function Declarations ********/
659 /****************************************************************
661 * Compatability routines
663 ****************************************************************/
664 #if defined(NO_putwc)
665 static wint_t putwc(wint_t wc, FILE *stream)
667 int rc = putc((int) wc, stream);
671 static wint_t getwc(FILE *stream)
673 int rc = getc(stream);
676 #endif /* NO_putwc */
678 /****************************************************************
680 * Translations and Actions
682 ****************************************************************/
685 * The following are the translations which DtEditor places (overrides)
686 * on the scrolled text widget. If the DtNtextTranslations resource is
687 * set, it will also be added (in override mode) to the text widget.
689 static char EditorTranslationTable[] = "\
690 ~s ~c ~m ~a <Key>Return: newline-and-indent()\n\
691 ~s m<Key>osfBackSpace: I-undo-edit()\n\
692 ~s c<Key>osfBackSpace: delete-previous-word()\n\
693 s<Key>osfBackSpace: delete-to-start-of-line()\n\
694 ~s ~c <Key>osfInsert: I-toggle-insert-mode()\n\
695 <Key>osfUndo: I-undo-edit()\n\
696 c<Key>g: I-go-to-line()\n\
697 c<Key>q: I-quote-next-character()\n\
698 c<Key>z: I-undo-edit()";
701 * The following are DtEditor's actions. A few are internal only (_I
702 * suffix) and will be called by the default translations DtEditor places
703 * on the text widget (see previous comment). The rest will only be called
704 * from an application with XtCallActionProc(). The main difference is
705 * the internal ones will be passed a text widget ID, while the public
706 * ones will be passed a DtEditor ID.
708 static XtActionsRec EditorActionTable[] = {
709 {"I-go-to-line", (XtActionProc)GoToLine_I},
710 {"I-toggle-insert-mode", (XtActionProc)ToggleInsertMode_I},
711 {"I-undo-edit", (XtActionProc)UndoEdit_I},
712 {"I-quote-next-character", (XtActionProc)QuoteNextChar_I},
713 {"backward-character", (XtActionProc)BackwardChar},
714 {"backward-paragraph", (XtActionProc)BackwardPara},
715 {"backward-word", (XtActionProc)BackwardWord},
716 {"beginning-of-file", (XtActionProc)BeginningOfFile},
717 {"beginning-of-line", (XtActionProc)BeginningOfLine},
718 {"clear-selection", (XtActionProc)ClearSelection},
719 {"copy-clipboard", (XtActionProc)CopyClipboard},
720 {"cut-clipboard", (XtActionProc)CutClipboard},
721 {"delete-next-character", (XtActionProc)DeleteNextChar},
722 {"delete-next-word", (XtActionProc)DeleteNextWord},
723 {"delete-previous-character", (XtActionProc)DeletePrevChar},
724 {"delete-previous-word", (XtActionProc)DeletePrevWord},
725 {"delete-to-end-of-line", (XtActionProc)DeleteToEOL},
726 {"delete-to-start-of-line", (XtActionProc)DeleteToSOL},
727 {"deselect-all", (XtActionProc)DeselectAll},
728 {"end-of-file", (XtActionProc)EndOfFile},
729 {"end-of-line", (XtActionProc)EndOfLine},
730 {"forward-character", (XtActionProc)ForwardChar},
731 {"forward-paragraph", (XtActionProc)ForwardPara},
732 {"forward-word", (XtActionProc)ForwardWord},
733 {"go-to-line", (XtActionProc)GoToLine},
734 {"Help", (XtActionProc)Help},
735 {"insert-string", (XtActionProc)InsertString},
736 {"key-select", (XtActionProc)KeySelect},
737 {"newline-and-backup", (XtActionProc)NewlineAndBackup},
738 {"newline-and-indent", (XtActionProc)NewlineAndIndent},
739 {"next-page", (XtActionProc)NextPage},
740 {"page-left", (XtActionProc)PageLeft},
741 {"page-right", (XtActionProc)PageRight},
742 {"paste-clipboard", (XtActionProc)PasteClipboard},
743 {"previous-page", (XtActionProc)PreviousPage},
744 {"process-cancel", (XtActionProc)ProcessCancel},
745 {"process-down", (XtActionProc)ProcessDown},
746 {"process-shift-down", (XtActionProc)ProcessShiftDown},
747 {"process-shift-up", (XtActionProc)ProcessShiftUp},
748 {"process-up", (XtActionProc)ProcessUp},
749 {"quote-next-character", (XtActionProc)QuoteNextChar},
750 {"select-all", (XtActionProc)SelectAll},
751 {"toggle-insert-mode", (XtActionProc)ToggleInsertMode},
752 {"undo-edit", (XtActionProc)UndoEdit},
756 /****************************************************************
760 ****************************************************************/
765 #define iswctype(a,b) is_wctype(a,b)
766 #define wctype(a) get_wctype(a)
769 #if !(defined(sun) && (_XOPEN_VERSION==3))
770 #if !(defined(__FreeBSD__))
771 # define iswblank(wc) iswctype((wc),blnkclass)
772 # undef getwc /* Use the libc function */
774 #if defined(_AIX) /* _AIX */
775 /* IBM defines wctype to get_wctype above - don't use const. */
776 static char *blankString = "space";
778 static const char *blankString = "space";
780 static wctype_t _DtEditor_blankClass;
782 # define wctype_t int
784 # define iswblank(a) iswspace(a)
785 # define iswctype(a,b) _iswctype(a,b)
786 # define wcwidth(a) sun_wcwidth(a)
789 #define MAXTABSIZE 100 /* max legal tabsize */
792 /****************************************************************
794 * Define misc data structures
796 ****************************************************************/
798 static wctype_t ekinclass = 0; /* Prop value for "ekinsoku" class */
799 static wctype_t bekinclass = 0; /* Prop value for "bekinsoku" class */
800 static wctype_t blnkclass = 0; /* Prop value for "Blank" Class */
802 /****************************************************************
806 ****************************************************************/
808 static XmSyntheticResource syn_resources[] =
812 DtNcolumns, sizeof(short),
813 XtOffset (DtEditorWidget, editor.editStuff.columns),
814 _DtEditorGetColumns, NULL
817 DtNcenterToggleLabel, sizeof (XmString),
818 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
819 _DtEditorGetCenterToggleLabel, NULL
822 DtNchangeAllButtonLabel, sizeof (XmString),
823 XtOffset (DtEditorWidget,
824 editor.searchStuff.changeAllButtonLabel),
825 _DtEditorGetChangeAllButtonLabel, NULL
828 DtNchangeButtonLabel, sizeof (XmString),
829 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
830 _DtEditorGetChangeButtonLabel, NULL
833 DtNchangeFieldLabel, sizeof (XmString),
834 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
835 _DtEditorGetChangeFieldLabel, NULL
838 DtNcurrentLineLabel, sizeof (XmString),
839 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
840 _DtEditorGetCurrentLineLabel, NULL
843 DtNcursorPosition, sizeof (XmTextPosition),
844 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
845 _DtEditorGetCursorPosition, NULL
848 DtNfindButtonLabel, sizeof (XmString),
849 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
850 _DtEditorGetFindButtonLabel, NULL
853 DtNfindFieldLabel, sizeof (XmString),
854 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
855 _DtEditorGetFindFieldLabel, NULL
858 DtNformatAllButtonLabel, sizeof (XmString),
859 XtOffset(DtEditorWidget,
860 editor.formatStuff.formatAllButtonLabel),
861 _DtEditorGetFormatAllButtonLabel, NULL
864 DtNformatParagraphButtonLabel, sizeof (XmString),
865 XtOffset(DtEditorWidget,
866 editor.formatStuff.formatParaButtonLabel),
867 _DtEditorGetFormatParagraphButtonLabel, NULL
870 DtNjustifyToggleLabel, sizeof (XmString),
871 XtOffset (DtEditorWidget,
872 editor.formatStuff.justifyToggleLabel),
873 _DtEditorGetJustifyToggleLabel, NULL
876 DtNleftAlignToggleLabel, sizeof (XmString),
877 XtOffset (DtEditorWidget,
878 editor.formatStuff.leftAlignToggleLabel),
879 _DtEditorGetLeftAlignToggleLabel, NULL
882 DtNleftMarginFieldLabel, sizeof (XmString),
883 XtOffset (DtEditorWidget,
884 editor.formatStuff.leftMarginFieldLabel),
885 _DtEditorGetLeftMarginFieldLabel, NULL
888 DtNmaxLength, sizeof(int),
889 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
890 _DtEditorGetMaxLength, NULL
893 DtNmisspelledListLabel, sizeof (XmString),
894 XtOffset (DtEditorWidget,
895 editor.searchStuff.misspelledListLabel),
896 _DtEditorGetMisspelledListLabel, NULL
899 DtNrightAlignToggleLabel, sizeof (XmString),
900 XtOffset (DtEditorWidget,
901 editor.formatStuff.rightAlignToggleLabel),
902 _DtEditorGetRightAlignToggleLabel, NULL
905 DtNrightMarginFieldLabel, sizeof (XmString),
906 XtOffset (DtEditorWidget,
907 editor.formatStuff.rightMarginFieldLabel),
908 _DtEditorGetRightMarginFieldLabel, NULL
911 DtNrows, sizeof(short),
912 XtOffset (DtEditorWidget, editor.editStuff.rows),
913 _DtEditorGetRows, NULL
916 DtNscrollLeftSide, sizeof (Boolean),
917 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
918 _DtEditorGetScrollLeftSide, NULL
921 DtNscrollTopSide, sizeof (Boolean),
922 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
923 _DtEditorGetScrollTopSide, NULL
926 DtNtextBackground, sizeof(Pixel),
927 XtOffset (DtEditorWidget, editor.editStuff.background),
928 _DtEditorGetTextBackground, NULL
931 DtNtextForeground, sizeof(Pixel),
932 XtOffset (DtEditorWidget, editor.editStuff.foreground),
933 _DtEditorGetTextForeground, NULL
936 DtNtopCharacter, sizeof(XmTextPosition),
937 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
938 _DtEditorGetTopCharacter, NULL
941 DtNtotalLineCountLabel, sizeof (XmString),
942 XtOffset (DtEditorWidget, editor.statusStuff.totalLineLabel),
943 _DtEditorGetLineCountLabel, NULL
947 static XtResource resources[] =
950 DtNautoShowCursorPosition,
951 DtCAutoShowCursorPosition, XmRBoolean, sizeof (Boolean),
952 XtOffset(DtEditorWidget,
953 editor.editStuff.autoShowCursorPos),
954 XmRImmediate, (XtPointer) True
957 DtNbuttonFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
958 XtOffsetOf(struct _XmBulletinBoardRec,
959 bulletin_board.button_font_list),
960 XmRFontList, (XtPointer) NULL
963 DtNblinkRate, DtCBlinkRate, XmRInt, sizeof(int),
964 XtOffset(DtEditorWidget, editor.editStuff.blinkRate),
965 XmRImmediate, (XtPointer) 500
968 DtNcenterToggleLabel, DtCCenterToggleLabel,
969 XmRXmString, sizeof (XmString),
970 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
971 XmRImmediate, (XtPointer) DtUNSPECIFIED
974 DtNchangeAllButtonLabel, DtCChangeAllButtonLabel,
975 XmRXmString, sizeof (XmString),
976 XtOffset (DtEditorWidget,
977 editor.searchStuff.changeAllButtonLabel),
978 XmRImmediate, (XtPointer) DtUNSPECIFIED
981 DtNchangeButtonLabel, DtCChangeButtonLabel,
982 XmRXmString, sizeof (XmString),
983 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
984 XmRImmediate, (XtPointer) DtUNSPECIFIED
987 DtNchangeFieldLabel, DtCChangeFieldLabel,
988 XmRXmString, sizeof (XmString),
989 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
990 XmRImmediate, (XtPointer) DtUNSPECIFIED
993 DtNcolumns, DtCColumns, XmRShort, sizeof(short),
994 XtOffset (DtEditorWidget, editor.editStuff.columns),
995 XmRImmediate, (XtPointer) DtUNSPECIFIED
998 DtNcurrentLineLabel, DtCCurrentLineLabel,
999 XmRXmString, sizeof (XmString),
1000 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
1001 XmRImmediate, (XtPointer) DtUNSPECIFIED
1004 DtNcursorPosition, DtCCursorPosition, XmRTextPosition,
1005 sizeof (XmTextPosition),
1006 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
1007 XmRImmediate, (XtPointer) DtUNSPECIFIED
1010 DtNcursorPositionVisible, DtCCursorPositionVisible,
1011 XmRBoolean, sizeof (Boolean),
1012 XtOffset(DtEditorWidget,
1013 editor.editStuff.cursorPosVisible),
1014 XmRImmediate, (XtPointer) True
1017 DtNdialogTitle, DtCDialogTitle, XmRXmString, sizeof (XmString),
1018 XtOffsetOf(struct _XmBulletinBoardRec,
1019 bulletin_board.dialog_title),
1020 XmRString, (XtPointer) NULL
1023 DtNeditable, DtCEditable, XmRBoolean, sizeof (Boolean),
1024 XtOffset (DtEditorWidget, editor.editStuff.editable),
1025 XmRImmediate, (XtPointer) True
1028 DtNfindButtonLabel, DtCFindButtonLabel,
1029 XmRXmString, sizeof (XmString),
1030 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
1031 XmRImmediate, (XtPointer) DtUNSPECIFIED
1034 DtNfindChangeDialogTitle, DtCFindChangeDialogTitle,
1035 XmRXmString, sizeof (XmString),
1036 XtOffset(DtEditorWidget, editor.searchStuff.fndChngTitle),
1037 XmRString, (XtPointer) NULL
1040 DtNfindFieldLabel, DtCFindFieldLabel,
1041 XmRXmString, sizeof (XmString),
1042 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
1043 XmRImmediate, (XtPointer) DtUNSPECIFIED
1046 DtNformatAllButtonLabel, DtCFormatAllButtonLabel,
1047 XmRXmString, sizeof (XmString),
1048 XtOffset(DtEditorWidget,
1049 editor.formatStuff.formatAllButtonLabel),
1050 XmRImmediate, (XtPointer) DtUNSPECIFIED
1053 DtNformatParagraphButtonLabel, DtCFormatParagraphButtonLabel,
1054 XmRXmString, sizeof (XmString),
1055 XtOffset(DtEditorWidget,
1056 editor.formatStuff.formatParaButtonLabel),
1057 XmRImmediate, (XtPointer) DtUNSPECIFIED
1060 DtNformatSettingsDialogTitle, DtCFormatSettingsDialogTitle,
1061 XmRXmString, sizeof (XmString),
1062 XtOffset(DtEditorWidget, editor.formatStuff.formatDialogTitle),
1063 XmRString, (XtPointer) NULL
1066 DtNinformationDialogTitle, DtCInformationDialogTitle,
1067 XmRXmString, sizeof (XmString),
1068 XtOffset(DtEditorWidget, editor.warningStuff.infoDialogTitle),
1069 XmRString, (XtPointer) NULL
1072 DtNinsertLabel, DtCInsertLabel, XmRXmString, sizeof (XmString),
1073 XtOffset (DtEditorWidget, editor.statusStuff.ins),
1074 XmRImmediate, (XtPointer) DtUNSPECIFIED
1077 DtNjustifyToggleLabel, DtCJustifyToggleLabel,
1078 XmRXmString, sizeof (XmString),
1079 XtOffset(DtEditorWidget, editor.formatStuff.justifyToggleLabel),
1080 XmRImmediate, (XtPointer) DtUNSPECIFIED
1083 DtNlabelFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1084 XtOffsetOf(struct _XmBulletinBoardRec,
1085 bulletin_board.label_font_list),
1086 XmRFontList, (XtPointer) NULL
1089 DtNleftAlignToggleLabel, DtCLeftAlignToggleLabel,
1090 XmRXmString, sizeof (XmString),
1091 XtOffset(DtEditorWidget,
1092 editor.formatStuff.leftAlignToggleLabel),
1093 XmRImmediate, (XtPointer) DtUNSPECIFIED
1096 DtNleftMarginFieldLabel, DtCLeftMarginFieldLabel,
1097 XmRXmString, sizeof (XmString),
1098 XtOffset(DtEditorWidget,
1099 editor.formatStuff.leftMarginFieldLabel),
1100 XmRImmediate, (XtPointer) DtUNSPECIFIED
1103 DtNmaxLength, DtCMaxLength, XmRInt, sizeof(int),
1104 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
1105 XmRImmediate, (XtPointer) DtUNSPECIFIED
1108 DtNmisspelledListLabel, DtCMisspelledListLabel,
1109 XmRXmString, sizeof (XmString),
1110 XtOffset (DtEditorWidget,
1111 editor.searchStuff.misspelledListLabel),
1112 XmRImmediate, (XtPointer) DtUNSPECIFIED
1115 DtNoverstrike, DtCOverstrike, XmRBoolean, sizeof (Boolean),
1116 XtOffset(DtEditorWidget, editor.editStuff.overstrikeMode),
1117 XmRImmediate, (XtPointer) False
1120 DtNoverstrikeLabel, DtCOverstrikeLabel,
1121 XmRXmString, sizeof (XmString),
1122 XtOffset (DtEditorWidget, editor.statusStuff.ovr),
1123 XmRImmediate, (XtPointer) DtUNSPECIFIED
1126 DtNrightAlignToggleLabel, DtCRightAlignToggleLabel,
1127 XmRXmString, sizeof (XmString),
1128 XtOffset(DtEditorWidget,
1129 editor.formatStuff.rightAlignToggleLabel),
1130 XmRImmediate, (XtPointer) DtUNSPECIFIED
1133 DtNrightMarginFieldLabel, DtCRightMarginFieldLabel,
1134 XmRXmString, sizeof (XmString),
1135 XtOffset(DtEditorWidget,
1136 editor.formatStuff.rightMarginFieldLabel),
1137 XmRImmediate, (XtPointer) DtUNSPECIFIED
1140 DtNrows, DtCRows, XmRShort, sizeof(short),
1141 XtOffset (DtEditorWidget, editor.editStuff.rows),
1142 XmRImmediate, (XtPointer) DtUNSPECIFIED
1145 DtNscrollHorizontal, DtCScroll, XmRBoolean, sizeof (Boolean),
1146 XtOffset (DtEditorWidget, editor.editStuff.scrollHorizontal),
1147 XmRImmediate, (XtPointer) True
1150 DtNscrollLeftSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1151 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
1152 XmRImmediate, (XtPointer) DtUNSPECIFIED
1155 DtNscrollTopSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1156 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
1157 XmRImmediate, (XtPointer) DtUNSPECIFIED
1160 DtNscrollVertical, DtCScroll, XmRBoolean, sizeof (Boolean),
1161 XtOffset (DtEditorWidget, editor.editStuff.scrollVertical),
1162 XmRImmediate, (XtPointer) True
1166 DtCShowStatusLine, XmRBoolean, sizeof (Boolean),
1167 XtOffset (DtEditorWidget, editor.statusStuff.showStatusLine),
1168 XmRImmediate, (XtPointer) False
1171 DtNspellDialogTitle, DtCSpellDialogTitle,
1172 XmRXmString, sizeof (XmString),
1173 XtOffset(DtEditorWidget, editor.searchStuff.spellTitle),
1174 XmRString, (XtPointer) NULL
1177 DtNspellFilter, DtCSpellFilter, XmRString, sizeof(XmRString),
1178 XtOffset (DtEditorWidget, editor.searchStuff.spellFilter),
1182 DtNtextBackground, DtCBackground,
1183 XmRPixel, sizeof(Pixel),
1184 XtOffset (DtEditorWidget, editor.editStuff.background),
1185 XmRImmediate, (XtPointer) DtUNSPECIFIED
1188 DtNtextDeselectCallback,
1189 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1190 XtOffset (DtEditorWidget, editor.textDeselect),
1191 XtRCallback, (XtPointer) NULL
1194 DtNtextForeground, DtCForeground,
1195 XmRPixel, sizeof(Pixel),
1196 XtOffset (DtEditorWidget, editor.editStuff.foreground),
1197 XmRImmediate, (XtPointer) DtUNSPECIFIED
1200 DtNtextFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1201 XtOffsetOf(struct _XmBulletinBoardRec,
1202 bulletin_board.text_font_list),
1203 XmRFontList, (XtPointer) NULL
1206 DtNtextSelectCallback,
1207 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1208 XtOffset (DtEditorWidget, editor.textSelect),
1209 XtRCallback, (XtPointer) NULL
1212 DtNtextTranslations, DtCTranslations,
1213 XmRTranslationTable, sizeof (XtTranslations),
1214 XtOffsetOf(struct _XmBulletinBoardRec,
1215 bulletin_board.text_translations),
1216 XmRImmediate, (XtPointer) NULL
1219 DtNtopCharacter, DtCTopCharacter,
1220 XmRTextPosition, sizeof(XmTextPosition),
1221 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
1222 XmRImmediate, (XtPointer) DtUNSPECIFIED
1225 DtNtotalLineCountLabel, DtCTotalLineCountLabel,
1226 XmRXmString, sizeof (XmString),
1227 XtOffset (DtEditorWidget,
1228 editor.statusStuff.totalLineLabel),
1229 XmRImmediate, (XtPointer) DtUNSPECIFIED
1233 DtCWordWrap, XmRBoolean, sizeof (Boolean),
1234 XtOffset (DtEditorWidget, editor.editStuff.wordWrap),
1235 XmRImmediate, (XtPointer) False
1239 /****************************************************************
1241 * Public Function Declarations
1243 ****************************************************************/
1245 /****************************************************************
1249 ****************************************************************/
1251 externaldef( dteditorclassrec ) DtEditorClassRec
1257 (WidgetClass) &xmFormClassRec, /* superclass */
1258 "DtEditor", /* class_name */
1259 sizeof (DtEditorRec), /* widget_size */
1260 ClassInitialize, /* class_initialize */
1261 NULL, /* class_part_initialize*/
1262 False, /* class_inited */
1263 (XtInitProc) Initialize, /* initialize */
1264 NULL, /* initialize_hook */
1265 XtInheritRealize, /* realize */
1266 (XtActionList)EditorActionTable,/* actions */
1267 (Cardinal)XtNumber(EditorActionTable), /* num_actions */
1268 resources, /* resources */
1269 XtNumber (resources), /* num_resources */
1270 NULLQUARK, /* xrm_class */
1271 True, /* compress_motion */
1272 XtExposeCompressMaximal, /* compress_exposure */
1273 False, /* compress_enterleave */
1274 False, /* visible_interest */
1275 (XtWidgetProc) Destroy, /* destroy */
1276 XtInheritResize, /* resize */
1277 XtInheritExpose, /* expose */
1278 (XtSetValuesFunc) SetValues, /* set_values */
1279 NULL, /* set_values_hook */
1280 XtInheritSetValuesAlmost, /* set_values_almost */
1281 NULL, /* get_values_hook */
1282 XtInheritAcceptFocus, /* accept_focus */
1283 XtVersion, /* version */
1284 NULL, /* callback private */
1285 XtInheritTranslations, /* tm_table */
1286 XtInheritQueryGeometry, /* query_geometry */
1287 (XtStringProc)NULL, /* display_accelerator */
1288 NULL, /* extension */
1294 XtInheritGeometryManager, /* geometry_manager */
1295 XtInheritChangeManaged, /* change_managed */
1296 XtInheritInsertChild, /* insert_child */
1297 XtInheritDeleteChild, /* delete_child */
1298 NULL, /* extension */
1305 NULL, /* constraint_resources */
1306 0, /* num_constraint_resource */
1307 sizeof(XmFormConstraintRec), /* size of constraint */
1308 NULL, /* initialization */
1309 NULL, /* constraint_destroy */
1310 NULL, /* constraint_set_values */
1311 NULL, /* extension */
1317 XmInheritTranslations, /* default_translations */
1318 syn_resources, /* syn_resources */
1319 XtNumber(syn_resources), /* num_syn_resources */
1320 NULL, /* syn_cont_resources */
1321 0, /* num_syn_cont_resources */
1322 XmInheritParentProcess, /* parent_process */
1323 NULL, /* extension */
1326 /* XmbulletinBoard Part
1329 FALSE, /* always_install_accelerators */
1330 (XmGeoCreateProc)NULL, /* geo_matrix_create */
1331 XmInheritFocusMovedProc, /* focus_moved_proc */
1332 NULL, /* extension */
1338 NULL, /* extension */
1348 WidgetClass dtEditorWidgetClass = (WidgetClass) &dtEditorClassRec;
1350 /*-------------------------------------------------------------
1352 **-------------------------------------------------------------
1355 /****************************************************************
1359 ****************************************************************/
1362 /*-------------------------------------------------------------
1363 ** Function: static void ClassInitialize (void);
1367 ** Purpose: This is the Editor class initializzation routine.
1368 ** It is called once, before the first instance
1372 ClassInitialize(void)
1374 #if !(defined(sun) && (_XOPEN_VERSION==3))
1375 _DtEditor_blankClass = wctype(blankString);
1378 ** These calls determine if the particular value is True for
1379 ** the current locale. A value of -1 is returned if the locale
1380 ** does not support the charclass. If the locale supports the
1381 ** charclass, the return value is passed as a parameter to the
1384 ekinclass = wctype("ekinsoku");
1385 bekinclass = wctype("bkinsoku");
1386 blnkclass = wctype("blank");
1387 #endif /* end not Sun */
1391 /*-------------------------------------------------------------
1392 ** Function: static void Initialize (
1395 ** ArgList arg_list,
1396 ** Cardinal *num_args)
1400 ** Purpose: This is the Editor widget initialize routine.
1401 ** It is responsible for the following:
1402 ** 1) Validate all resources the user passed in,
1403 ** 2) Override any invalid resources,
1404 ** 3) Initialize the internal data structures,
1405 ** 4) Create the edit area widget
1406 ** 5) Create the status area widget, if requested
1407 ** 6) Add any callbacks and actions
1417 DtEditorWidget request = (DtEditorWidget) rw,
1418 new = (DtEditorWidget) nw;
1420 /* Initialize non-resource portion of the instance structure */
1421 VariableInitialize (new);
1423 /* Validate the incoming arguments to make sure they are OK */
1424 ValidateResources (new, request);
1427 * Create & customize the scrolled text widget
1429 M_text(new) = CreateText (new);
1430 XtManageChild( M_text(new)) ;
1433 * If the widget is not "read only" then register it as a drop zone
1435 if ( M_editable(new) == True )
1436 RegisterDropZone( new );
1439 * Compute the width & height of the scrolled text's font. These values
1440 * will be used when formatting and in calculating the window manager
1443 getFontMetrics(new);
1446 * Create the status line
1448 SetStatusLine( new, M_status_showStatusLine(request) );
1451 } /* end Initialize */
1454 /*-------------------------------------------------------------
1455 ** Function: static void VariableInitialize (
1456 ** DtEditorWidget new )
1458 ** Parameters: The Editor widget being created
1460 ** Purpose: This routine:
1461 ** 1) Initializes the widget's instance structure
1470 * Initialize the non-resource instance fields
1473 M_display(new) = XtDisplayOfObject( (Widget)new->core.parent );
1474 M_app_context(new) = XtDisplayToApplicationContext(M_display(new));
1477 * Empty 'for' walks up the widget tree to find a shell.
1479 for (thisParent = new->core.parent;
1480 thisParent != (Widget)NULL && XtIsShell(thisParent) == False;
1481 thisParent = XtParent(thisParent));
1482 M_topLevelShell(new) = thisParent;
1484 /* Initialize edit area fields */
1485 M_loadingAllNewData(new) = False;
1486 M_unreadChanges(new) = False; /* There have not been any changes since */
1487 /* the app requested the data */
1488 M_deletionStart(new) = NO_DELETION_IN_PROGRESS;
1489 M_deletedText(new) = (char *)NULL;
1490 M_insertStart(new) = 0;
1491 M_insertionLength(new) = 0;
1492 M_textSelectCbCalled(new) = False;
1493 M_fontWidth(new) = -1;
1495 /* Initialize status line fields */
1496 M_status_statusArea(new) = (Widget)NULL;
1497 M_status_messageText(new) = (Widget)NULL;
1498 M_status_currentLine(new) = -1;
1499 M_status_lastLine(new) = -1;
1501 /* Initialize search function data */
1502 M_search_dialog(new) = (Widget) NULL;
1503 M_search_dialogMode(new) = SPELL;
1504 M_search_string(new) = (char *)NULL;
1505 M_replace_string(new) = (char *)NULL;
1506 M_misspelled_string(new) = (char *)NULL;
1507 M_misspelled_found(new) = False;
1509 /* Initialize format function data */
1510 M_format_dialog(new) = (Widget)NULL;
1512 /* Initialize warning dialogs data */
1513 M_gen_warning(new) = (Widget)NULL;
1515 } /* end VariableInitialize */
1518 /*-------------------------------------------------------------
1519 ** Function: static void ValidateResources (
1520 ** DtEditorWidget new,
1521 ** DtEditorWidget request )
1523 ** Parameters: The Editor widget being created & its requested
1526 ** Purpose: This routine:
1527 ** 1) Validates the widget's requested resources
1532 DtEditorWidget request)
1535 * Validate the requested values for the editor's resources
1539 * Make local copies of all resource strings assigned by the application.
1542 if (M_spellFilter(request) != (char *) NULL)
1543 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
1546 * Copy the dialog titles if the application set them, otherwise,
1547 * get their values from the message catalog.
1550 if (M_spellTitle(request) != (XmString) NULL)
1551 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
1553 M_spellTitle(new) = XmStringCreateLocalized(SPELL_TITLE);
1555 if (M_fndChngTitle(request) != (XmString) NULL)
1556 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
1558 M_fndChngTitle(new) = XmStringCreateLocalized(FIND_TITLE);
1560 if (E_format_dialogTitle(request) != (XmString) NULL)
1561 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
1563 E_format_dialogTitle(new) = XmStringCreateLocalized(FORMAT_SETTINGS);
1565 if (E_infoDialogTitle(request) != (XmString) NULL)
1566 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
1568 E_infoDialogTitle(new) = XmStringCreateLocalized(INFO_TITLE);
1571 * Copy the insert & overstrike label indicators if the appli-
1572 * cation set them, otherwise, get their value from the message
1574 * Check for DtUNSPECIFIED because NULL is a valid value.
1577 if (M_status_insertLabel(request) != (XmString) DtUNSPECIFIED)
1578 M_status_insertLabel(new) =
1579 XmStringCopy( M_status_insertLabel(request) );
1581 M_status_insertLabel(new) = XmStringCreateLocalized(INS);
1583 if (M_status_overstrikeLabel(request) != (XmString) DtUNSPECIFIED)
1584 M_status_overstrikeLabel(new) =
1585 XmStringCopy( M_status_overstrikeLabel(request) );
1587 M_status_overstrikeLabel(new) = XmStringCreateLocalized(OVR);
1589 } /* end ValidateResources */
1592 /*-------------------------------------------------------------
1593 ** Function: static Widget CreateText (
1594 ** DtEditorWidget parent)
1596 ** Parameters: The parent of the text widget
1598 ** Purpose: This routine creates the scrolled text widget which
1599 ** lives inside the editor widget.
1600 ** It is responsible for the following:
1601 ** 1) Creating the scrolled text widget,
1602 ** 2) Adding specific translations,
1603 ** 3) Adding our own callbacks,
1604 ** 4) Substituting our own set selection routine.
1608 DtEditorWidget parent)
1610 int ac; /* arg count */
1611 Arg al[21]; /* arg list */
1615 * First, set up the hardwired scrolled text widget resource values.
1616 * (Change these and you die! Aha! Ha! Ha! Ha! [evil laugh])
1620 XtSetArg (al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
1621 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1622 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1623 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1624 XtSetArg(al[ac], XmNpendingDelete, True); ac++;
1627 * Now, set up the resource values which can vary (passed in from
1628 * application or default values).
1630 * If a synthetic resource is DtUNSPECIFIED don't set it, but let
1631 * it default to the scrolled text default value.
1632 * If it is specified, clear the data field after setting the
1633 * resource because the value in the field will be out of sync
1634 * with the real value.
1636 XtSetArg(al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(parent));
1639 XtSetArg(al[ac], XmNblinkRate, M_blinkRate(parent)); ac++;
1641 if ( M_columns(parent) != DtUNSPECIFIED) {
1642 XtSetArg (al[ac], XmNcolumns, M_columns(parent) ); ac++;
1643 M_columns(parent) = (short) DtUNSPECIFIED;
1646 if ( M_cursorPos(parent) != DtUNSPECIFIED) {
1647 XtSetArg (al[ac], XmNcursorPosition, M_cursorPos(parent)); ac++;
1648 M_cursorPos(parent) = (XmTextPosition) DtUNSPECIFIED;
1651 XtSetArg(al[ac], XmNcursorPositionVisible, M_cursorPosVisible(parent));
1654 XtSetArg(al[ac], XmNeditable, M_editable(parent)); ac++;
1656 if ( E_textFontList(parent) != (XmFontList) NULL) {
1657 XtSetArg (al[ac], XmNfontList, E_textFontList(parent)); ac++;
1660 if ( M_maxLength(parent) != DtUNSPECIFIED) {
1661 XtSetArg (al[ac], XmNmaxLength, M_maxLength(parent) ); ac++;
1662 M_maxLength(parent) = (int) DtUNSPECIFIED;
1665 if ( M_rows(parent) != DtUNSPECIFIED) {
1666 XtSetArg (al[ac], XmNrows, M_rows(parent) ); ac++;
1667 M_rows(parent) = (short) DtUNSPECIFIED;
1670 XtSetArg (al[ac], XmNscrollHorizontal, M_scrollHorizontal(parent) ); ac++;
1672 if ( M_scrollLeftSide(parent) != (Boolean)DtUNSPECIFIED) {
1673 XtSetArg (al[ac], XmNscrollLeftSide, M_scrollLeftSide(parent) ); ac++;
1674 M_scrollLeftSide(parent) = (Boolean)DtUNSPECIFIED;
1677 if ( M_scrollTopSide(parent) != (Boolean)DtUNSPECIFIED) {
1678 XtSetArg (al[ac], XmNscrollTopSide, M_scrollTopSide(parent) ); ac++;
1679 M_scrollTopSide(parent) = (Boolean)DtUNSPECIFIED;
1682 XtSetArg (al[ac], XmNscrollVertical, M_scrollVertical(parent) ); ac++;
1684 if ( M_topCharacter(parent) != DtUNSPECIFIED) {
1685 XtSetArg (al[ac], XmNtopCharacter, M_topCharacter(parent) ); ac++;
1686 M_topCharacter(parent) = (XmTextPosition) DtUNSPECIFIED;
1689 XtSetArg (al[ac], XmNwordWrap, M_wordWrap(parent) ); ac++;
1691 /* Create text widget */
1692 text = XmCreateScrolledText ( (Widget) parent, "text", al, ac );
1696 * Now, set the foreground & background of the text widget. Could not
1697 * set it at create time because the scrolled window would have
1698 * picked it up, too.
1702 if ( M_textBackground(parent) != DtUNSPECIFIED) {
1703 XtSetArg (al[ac], XmNbackground, M_textBackground(parent) ); ac++;
1704 M_textBackground(parent) = (Pixel) DtUNSPECIFIED;
1707 if ( M_textForeground(parent) != DtUNSPECIFIED) {
1708 XtSetArg (al[ac], XmNforeground, M_textForeground(parent) ); ac++;
1709 M_textForeground(parent) = (Pixel) DtUNSPECIFIED;
1713 XtSetValues( text, al, ac);
1716 /* XXX Word Wrap workaround. See comments for FixWordWrap() */
1717 if ( M_scrollHorizontal(parent) ) /* XXX Word Wrap workaround */
1718 FixWordWrap(text, M_wordWrap(parent)); /* XXX Word Wrap workaround */
1721 /* Put the editor-specific translation routines in place. */
1722 XtOverrideTranslations(text,
1723 XtParseTranslationTable(EditorTranslationTable));
1725 /* Add any translations set by the application. */
1726 if ( E_textTranslations(parent) != (XtTranslations)NULL ) {
1727 XtOverrideTranslations(text, E_textTranslations(parent));
1732 * Add modify verify callback
1734 XtAddCallback(text, XmNmodifyVerifyCallback,
1735 (XtCallbackProc) _DtEditorModifyVerifyCB,
1736 (XtPointer) parent);
1739 * Add the Help callback
1741 XtAddCallback( text, XmNhelpCallback, (XtCallbackProc) HelpEditWindowCB,
1742 (XtPointer) parent );
1746 * Substitute our own Set Selection routine which can
1747 * call the textSelect and textDeselect callback procs
1749 if(((XmTextWidget)(text))->text.source->SetSelection !=
1750 Editor_SetSelectionProc) {
1751 M_setSelection(parent) =
1752 ((XmTextWidget)(text))->text.source->SetSelection;
1753 ((XmTextWidget)(text))->text.source->SetSelection =
1754 Editor_SetSelectionProc;
1758 XtSetSensitive (text, True);
1761 } /* end CreateText */
1764 /*-------------------------------------------------------------
1765 ** Function: static int extractFontMetrics (
1766 ** XmFontList fontlist )
1768 ** Purpose: Given a font list, determine the width & height
1769 ** of the characters.
1771 ** This routine is lifted almost straight out of
1772 ** lib/Xm/TextOut.c (see LoadFontMetrics() ) so the editor will
1773 ** select the same font the text widget is working with.
1778 XmFontList fontlist,
1782 XmFontContext context;
1783 XmFontListEntry next_entry;
1784 XmFontType type_return = XmFONT_IS_FONT;
1787 Boolean have_font_struct = False;
1788 Boolean have_font_set = False;
1789 Boolean use_font_set = False;
1790 XFontSetExtents *fs_extents;
1791 unsigned long tmp_width = 0;
1792 int font_descent, font_ascent;
1793 char* font_tag = NULL;
1796 *width = *height = 0;
1797 if (XmFontListInitFontContext(&context, fontlist)) {
1800 * Look through the font list for a fontset with the default tag.
1801 * If we do not find it, use the first font set we came to, otherwise,
1802 * use the first font struct we came to.
1805 Boolean do_break = False;
1807 next_entry = XmFontListNextEntry(context);
1810 tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
1811 if (type_return == XmFONT_IS_FONTSET) {
1816 font_tag = XmFontListEntryGetTag(next_entry);
1818 if (!have_font_set){
1821 * Save the first fontset found in case we don't find
1822 * a default tag font set.
1824 have_font_set = True; /* we have a font set. */
1825 use_font_set = True;
1826 font = (XFontStruct *)tmp_font;
1829 * We have a font set, so no need to consider future font
1832 have_font_struct = True;
1835 * If this is the default font set break out, we've
1836 * found the one we want.
1838 if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
1842 else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)) {
1844 * If this is the default font set save it & break out,
1845 * we've found the one we want.
1847 font = (XFontStruct *)tmp_font;
1848 have_font_set = True;
1852 if (NULL != font_tag)
1858 else if (!have_font_struct){
1863 use_font_set = False;
1866 * Save the first one in case no font set is found
1868 font = (XFontStruct *)tmp_font;
1869 use_font_set = False;
1870 have_font_struct = True;
1875 } while (next_entry != NULL);
1877 XmFontListFreeFontContext(context);
1880 * Now, extract the font metrics from the font set or font that
1888 fs_extents = XExtentsOfFontSet((XFontSet)font);
1890 if (XmDirectionMatch(w->manager.string_direction,
1891 XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
1892 tmp_width = (unsigned long)fs_extents->max_ink_extent.width;
1894 tmp_width = (unsigned long)fs_extents->max_logical_extent.width;
1896 /* max_logical_extent.y is number of pixels from origin to top of
1897 * rectangle (i.e. y is negative) */
1898 font_ascent = -fs_extents->max_logical_extent.y;
1899 font_descent = fs_extents->max_logical_extent.height +
1900 fs_extents->max_logical_extent.y;
1905 * Chose a font struct
1907 font_ascent = font->max_bounds.ascent;
1908 font_descent = font->max_bounds.descent;
1909 if ( (!XGetFontProperty(font, XA_QUAD_WIDTH, &tmp_width)) ||
1912 if ( font->per_char && font->min_char_or_byte2 <= '0' &&
1913 font->max_char_or_byte2 >= '0' )
1914 tmp_width = font->per_char['0' - font->min_char_or_byte2].width;
1916 tmp_width = font->max_bounds.width;
1921 if (tmp_width <= 0) tmp_width = 1;
1922 *width = (int)tmp_width; /* This assumes there will be no truncation */
1923 *height = font_descent + font_ascent;
1927 } /* end extractFontMetrics */
1931 /*-------------------------------------------------------------
1932 ** Function: static void getFontMetrics (
1933 ** DtEditorWidget w )
1935 ** Parameters: An Editor widget
1937 ** Purpose: Determine the height & width of the scrolled text
1945 Arg al[10]; /* arg list */
1946 XmFontList fontlist;
1950 * Get the text widget's font list
1952 * Note, have to retrieve the fontList from the text widget rather
1953 * than use the DtNtextFontList resource because the text widget may
1954 * have rejected the font specified with DtNtextFontList. This way
1955 * we will get the fontList actually used by the text widget.
1958 XtSetArg(al[0], XmNfontList, &fontlist);
1959 XtGetValues(M_text(w), al, 1);
1962 * Now, extract the height and width
1964 extractFontMetrics( w, fontlist, &height, &width );
1965 M_fontWidth(w) = width;
1966 M_fontHeight(w) = height;
1968 } /* end getFontMetrics */
1971 /*-------------------------------------------------------------
1973 ** Release resources allocated for a widget instance.
1979 DtEditorWidget editor = (DtEditorWidget) widget;
1982 * Cleanup the edit window
1986 * (Nothing to be done. Unregistering it as a drop site is handled
1987 * automatically by the DnD library.)
1991 * Cleanup the status line
1994 if (M_status_insertLabel(editor) != (XmString)DtUNSPECIFIED)
1995 XmStringFree(M_status_insertLabel(editor));
1997 if (M_status_overstrikeLabel(editor) != (XmString)DtUNSPECIFIED)
1998 XmStringFree(M_status_overstrikeLabel(editor));
2000 if (E_status_currentLineLabel(editor) != (XmString)DtUNSPECIFIED)
2001 XmStringFree(E_status_currentLineLabel(editor));
2003 if (E_status_totalLineCountLabel(editor) != (XmString)DtUNSPECIFIED)
2004 XmStringFree(E_status_totalLineCountLabel(editor));
2007 * Cleanup the Find/Change & Spell dialogs
2010 if (M_search_string(editor))
2011 XtFree(M_search_string(editor));
2013 if (M_replace_string(editor))
2014 XtFree(M_replace_string(editor));
2016 if (M_misspelled_string(editor))
2017 XtFree(M_misspelled_string(editor));
2019 if (M_spellFilter(editor))
2020 XtFree(M_spellFilter(editor));
2022 if (M_spellTitle(editor) != (XmString)NULL)
2023 XmStringFree(M_spellTitle(editor));
2025 if (E_misspelledListLabel(editor) != (XmString)DtUNSPECIFIED)
2026 XmStringFree(E_misspelledListLabel(editor));
2028 if (M_fndChngTitle(editor) != (XmString)NULL)
2029 XmStringFree(M_fndChngTitle(editor));
2031 if (E_findFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2032 XmStringFree(E_findFieldLabel(editor));
2034 if (E_changeFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2035 XmStringFree(E_changeFieldLabel(editor));
2037 if (E_findButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2038 XmStringFree(E_findButtonLabel(editor));
2040 if (E_changeButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2041 XmStringFree(E_changeButtonLabel(editor));
2043 if (E_changeAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2044 XmStringFree(E_changeAllButtonLabel(editor));
2047 * Cleanup the Format Settings dialog
2049 if (E_format_dialogTitle(editor) != (XmString)NULL)
2050 XmStringFree(E_format_dialogTitle(editor));
2052 if (E_format_leftMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2053 XmStringFree(E_format_leftMarginFieldLabel(editor));
2055 if (E_format_rightMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2056 XmStringFree(E_format_rightMarginFieldLabel(editor));
2058 if (E_format_leftAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2059 XmStringFree(E_format_leftAlignToggleLabel(editor));
2061 if (E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2062 XmStringFree(E_format_rightAlignToggleLabel(editor));
2064 if (E_format_justifyToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2065 XmStringFree(E_format_justifyToggleLabel(editor));
2067 if (E_format_centerToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2068 XmStringFree(E_format_centerToggleLabel(editor));
2070 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2071 XmStringFree(E_format_formatAllButtonLabel(editor));
2073 if (E_format_formatParagraphButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2074 XmStringFree(E_format_formatParagraphButtonLabel(editor));
2077 * Cleanup the Information dialog
2079 if (E_infoDialogTitle(editor) != (XmString)NULL)
2080 XmStringFree(E_infoDialogTitle(editor));
2083 * Cleanup the Undo deletion context
2086 _DtEditorResetUndo(editor);
2091 /*-------------------------------------------------------------
2093 ** Handle changes in resource data.
2103 Boolean redisplay_flag = False;
2104 Arg al[15]; /* arg list */
2105 int ac; /* arg count */
2107 Boolean resetSpellTitle = False,
2108 resetFormatTitle = False,
2109 resetInfoTitle = False,
2110 newButtonFontList = False,
2111 newLabelFontList = False,
2112 newTextFontList = False,
2113 NeedToFixWordWrap = False; /* XXX Word Wrap workaround*/
2115 DtEditorWidget current = (DtEditorWidget) cw;
2116 DtEditorWidget request = (DtEditorWidget) rw;
2117 DtEditorWidget new = (DtEditorWidget) nw;
2120 * XXX Need to propagate changes to Core resources, like XmNbackground,
2125 * If a synthetic resource is specified, clear the data field
2126 * after setting the resource because the value in the field
2127 * will be out of sync with the real value (contained in the
2132 * General changes, not directly affecting a child
2135 /* Check for a new spell filter */
2137 if ( strcmp(M_spellFilter(request), M_spellFilter(current)) != 0 )
2139 XtFree( M_spellFilter(current) );
2140 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
2143 /* Check for new font lists */
2145 if ( E_buttonFontList(request) != E_buttonFontList(current) )
2146 newButtonFontList = True;
2148 if ( E_labelFontList(request) != E_labelFontList(current) )
2149 newLabelFontList = True;
2151 if ( E_textFontList(request) != E_textFontList(current) )
2152 newTextFontList = True;
2155 * Check for any changes which affect the dialog titles
2158 if (XmStringCompare(E_dialogTitle(request),E_dialogTitle(current)) == False) {
2159 resetSpellTitle = resetFormatTitle = resetInfoTitle = True;
2162 if (XmStringCompare(M_spellTitle(request),M_spellTitle(current)) == False) {
2163 XmStringFree( M_spellTitle(current) );
2164 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
2165 resetSpellTitle = True;
2168 if (XmStringCompare(M_fndChngTitle(request),M_fndChngTitle(current)) == False)
2170 XmStringFree( M_fndChngTitle(current) );
2171 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
2172 resetSpellTitle = True;
2175 if (XmStringCompare(E_format_dialogTitle(request),
2176 E_format_dialogTitle(current) ) == False)
2178 XmStringFree( E_format_dialogTitle(current) );
2179 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
2180 resetFormatTitle = True;
2183 if (XmStringCompare(E_infoDialogTitle(request),
2184 E_infoDialogTitle(current) ) == False)
2186 XmStringFree( E_infoDialogTitle(current) );
2187 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
2188 resetInfoTitle = True;
2192 * Calculate new titles for the dialogs depending upon which resources
2195 if ( resetSpellTitle == True ) {
2197 * No need to do anything because the Spell and Find/Change dialog
2198 * titles are recomputed every time.
2200 redisplay_flag = True;
2203 if ( resetFormatTitle == True ) {
2204 SetFormatDialogTitle( new );
2205 redisplay_flag = True;
2208 if ( resetInfoTitle == True ) {
2209 SetInfoDialogTitle( new );
2210 redisplay_flag = True;
2215 * Check for any changes which affect the status line
2217 if (M_status_showStatusLine(request) != M_status_showStatusLine(current)) {
2218 SetStatusLine( new, M_status_showStatusLine(request) );
2219 redisplay_flag = True;
2222 if ( M_overstrikeMode(request) != M_overstrikeMode(current) ) {
2224 UpdateOverstrikeIndicator( new, M_overstrikeMode(request) );
2225 XtCallActionProc( (Widget) M_text(current), "toggle-overstrike",
2226 (XEvent *)NULL, (String *)NULL, 0 );
2227 redisplay_flag = True;
2230 if ( M_status_statusArea(current) != (Widget)NULL ) {
2232 if (newLabelFontList == True) {
2233 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2234 XtSetValues( (Widget) M_status_lineLabel(current), al, 1);
2235 XtSetValues( (Widget) M_status_totalLabel(current), al, 1);
2236 XtSetValues( (Widget) M_status_totalText(current), al, 1);
2237 XtSetValues( (Widget) M_status_overstrikeWidget(current), al, 1);
2241 if (newTextFontList == True) {
2242 XtSetArg( al[ac], XmNfontList, E_textFontList(request) ); ac++;
2245 if ( M_textBackground(request) != DtUNSPECIFIED) {
2246 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2249 if ( M_textForeground(request) != DtUNSPECIFIED) {
2250 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2254 XtSetValues( (Widget) M_status_lineText(current), al, ac);
2255 XtSetValues( (Widget) M_status_messageText(current), al, ac);
2262 * Check for any changes which affect the dialog boxes
2265 /* Information dialog */
2267 if ( M_gen_warning(current) != (Widget)NULL ) {
2269 if ( newButtonFontList == True ) {
2270 XtSetArg (al[0], XmNfontList, E_buttonFontList(request) );
2272 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_OK_BUTTON),
2276 if ( newLabelFontList == True ) {
2277 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2279 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_MESSAGE_LABEL),
2285 /* Find/Change dialog */
2286 if ( M_search_dialog(current) != (Widget)NULL )
2288 if ( newButtonFontList == True ) {
2289 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2290 XtSetValues( (Widget)M_search_findBtn(current), al, 1 );
2291 XtSetValues( (Widget)M_search_replaceBtn(current), al, 1 );
2292 XtSetValues( (Widget)M_search_replaceAllBtn(current), al, 1 );
2293 XtSetValues( (Widget)M_search_closeBtn(current), al, 1 );
2294 XtSetValues( (Widget)M_search_helpBtn(current), al, 1 );
2297 if ( newLabelFontList == True ) {
2298 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2299 XtSetValues( (Widget)M_search_listLbl(current), al, 1 );
2300 XtSetValues( (Widget)M_search_findLbl(current), al, 1 );
2301 XtSetValues( (Widget)M_search_replaceLbl(current), al, 1);
2304 if ( newTextFontList == True ) {
2305 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2306 XtSetValues( (Widget)M_search_spellList(current), al, 1);
2307 XtSetValues( (Widget)M_findText(current), al, 1 );
2308 XtSetValues( (Widget)M_replaceText(current), al, 1 );
2312 if ( M_textBackground(request) != DtUNSPECIFIED) {
2313 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2316 if ( M_textForeground(request) != DtUNSPECIFIED) {
2317 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2321 XtSetValues( (Widget) M_findText(current), al, ac);
2322 XtSetValues( (Widget) M_replaceText(current), al, ac);
2327 /* Format Settings dialog */
2328 if ( M_format_dialog(current) != (Widget)NULL )
2330 if ( newButtonFontList == True ) {
2331 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2332 XtSetValues( (Widget)M_format_leftJust(current), al, 1 );
2333 XtSetValues( (Widget)M_format_rightJust(current), al, 1);
2334 XtSetValues( (Widget)M_format_bothJust(current), al, 1 );
2335 XtSetValues( (Widget)M_format_center(current), al, 1 );
2336 XtSetValues( (Widget)M_format_paragraph(current), al, 1);
2337 XtSetValues( (Widget)M_format_all(current), al, 1 );
2338 XtSetValues( (Widget)M_format_close(current), al, 1 );
2339 XtSetValues( (Widget)M_format_help(current), al, 1 );
2342 if ( newLabelFontList == True ) {
2343 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2344 XtSetValues( (Widget)M_format_leftLabel(current), al, 1 );
2345 XtSetValues( (Widget)M_format_rightLabel(current), al, 1);
2348 if ( newTextFontList == True ) {
2349 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2350 XtSetValues( (Widget)M_format_leftMarginField(current), al, 1 );
2351 XtSetValues( (Widget)M_format_rightMarginField(current), al, 1);
2355 if ( M_textBackground(request) != DtUNSPECIFIED) {
2356 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2359 if ( M_textForeground(request) != DtUNSPECIFIED) {
2360 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2364 XtSetValues( (Widget) M_format_leftMarginField(current), al, ac);
2365 XtSetValues( (Widget) M_format_rightMarginField(current), al, ac);
2372 * Check for any changes which affect the edit area (scrolled text widget)
2376 if ( M_autoShowCursorPos(request) != M_autoShowCursorPos(current) ) {
2377 XtSetArg( al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(request));
2381 if ( M_blinkRate(request) != M_blinkRate(current) ) {
2382 XtSetArg( al[ac], XmNblinkRate, M_blinkRate(request)); ac++;
2385 if ( M_columns(request) != DtUNSPECIFIED) {
2386 XtSetArg (al[ac], XmNcolumns, M_columns(request) ); ac++;
2387 M_columns(new) = (short) DtUNSPECIFIED;
2388 redisplay_flag = True;
2391 /* PERF - disable redisplay for all SetValues */
2392 if ( M_cursorPos(request) != DtUNSPECIFIED) {
2393 XmTextSetCursorPosition( M_text(new), M_topCharacter(request) );
2394 M_cursorPos(new) = (XmTextPosition) DtUNSPECIFIED;
2397 if ( M_cursorPosVisible(request) != M_cursorPosVisible(current) ) {
2398 XtSetArg( al[ac], XmNcursorPositionVisible, M_cursorPosVisible(request));
2402 if ( M_editable(request) != M_editable(current) ) {
2403 XtSetArg( al[ac], XmNeditable, M_editable(request)); ac++;
2405 if( M_editable(request) ) {
2408 * If the widget is becoming editable, register it as a
2411 RegisterDropZone( new );
2414 * ...turn back on the Change To field in the Find/Change dialog
2416 if ( M_search_dialog(current) != (Widget)NULL ) {
2417 XtSetSensitive(M_search_replaceLbl(current), True);
2418 XtSetSensitive(M_replaceText(current), True);
2424 * It's no longer available as a drop site.
2426 UnregisterDropZone( current );
2429 if ( M_maxLength(request) != DtUNSPECIFIED) {
2430 XtSetArg (al[ac], XmNmaxLength, M_maxLength(request) ); ac++;
2431 M_maxLength(new) = (int) DtUNSPECIFIED;
2434 if ( M_rows(request) != DtUNSPECIFIED) {
2435 XtSetArg (al[ac], XmNrows, M_rows(request) ); ac++;
2436 M_rows(new) = (short) DtUNSPECIFIED;
2437 redisplay_flag = True;
2440 if ( M_textBackground(request) != DtUNSPECIFIED) {
2441 XtSetArg (al[ac], XmNbackground, M_textBackground(request) ); ac++;
2442 M_textBackground(new) = (XmTextPosition) DtUNSPECIFIED;
2443 redisplay_flag = True;
2446 if ( newTextFontList == True ) {
2447 XtSetArg (al[ac], XmNfontList, E_textFontList(request) ); ac++;
2448 redisplay_flag = True;
2451 if ( M_textForeground(request) != DtUNSPECIFIED) {
2452 XtSetArg (al[ac], XmNforeground, M_textForeground(request) ); ac++;
2453 M_textForeground(new) = (XmTextPosition) DtUNSPECIFIED;
2454 redisplay_flag = True;
2457 /* PERF - disable redisplay for all SetValues */
2458 if ( M_topCharacter(request) != DtUNSPECIFIED) {
2459 XmTextSetTopCharacter( M_text(new), M_topCharacter(request) );
2460 M_topCharacter(new) = (XmTextPosition) DtUNSPECIFIED;
2463 if ( M_wordWrap(request) != M_wordWrap(current) ) {
2464 XtSetArg( al[ac], XmNwordWrap, M_wordWrap(request)); ac++;
2465 NeedToFixWordWrap=M_scrollHorizontal(current);/*XXX Word Wrap workaround*/
2468 if ( NeedToFixWordWrap ) /*XXX Word Wrap workaround*/
2469 FixWordWrap(M_text(new), M_wordWrap(request));/*XXX Word Wrap workaround*/
2472 XtSetValues( (Widget) M_text(new), al, ac);
2474 if ( E_textTranslations(request) != E_textTranslations(current) ) {
2475 XtOverrideTranslations(M_text(new), E_textTranslations(request));
2478 if ( newTextFontList == True ) {
2479 getFontMetrics(new);
2482 return (redisplay_flag);
2484 } /* end Set values */
2487 /**************************************************************
2489 ** Get values routines for synthetic resources
2494 _DtEditorGetCenterToggleLabel(
2496 int resource_offset,
2499 DtEditorWidget editor = (DtEditorWidget) wid;
2504 * Get the value directly from the field in the instance structure.
2505 * If it is DtUNSPECIFIED then either:
2506 * 1) the value has been assigned to the widget (so get it from
2508 * 2) the value has never been set (so return the default value).
2511 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2512 data = XmStringCopy( E_format_centerToggleLabel(editor) );
2513 else if (M_format_dialog(editor) != (Widget)NULL)
2515 XtSetArg( al[0], XmNlabelString, &data) ;
2516 XtGetValues( (Widget) M_format_center(editor), al, 1) ;
2519 data = XmStringCreateLocalized(CENTER);
2520 *value = (XtArgVal) data ;
2523 } /* end _DtEditorGetCenterToggleLabel */
2526 _DtEditorGetChangeAllButtonLabel(
2528 int resource_offset,
2531 DtEditorWidget editor = (DtEditorWidget) wid;
2536 * Get the value directly from the field in the instance structure.
2537 * If it is DtUNSPECIFIED then either:
2538 * 1) the value has been assigned to the widget (so get it from
2540 * 2) the value has never been set (so return the default value).
2543 if (E_changeAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2544 data = XmStringCopy( E_changeAllButtonLabel(editor) );
2545 else if (M_search_dialog(editor) != (Widget) NULL)
2547 XtSetArg( al[0], XmNlabelString, &data) ;
2548 XtGetValues( (Widget) M_search_replaceAllBtn(editor), al, 1) ;
2551 data = XmStringCreateLocalized(CHNG_ALL_BUTTON);
2552 *value = (XtArgVal) data ;
2555 } /* end _DtEditorGetChangeAllButtonLabel */
2558 _DtEditorGetChangeButtonLabel(
2560 int resource_offset,
2563 DtEditorWidget editor = (DtEditorWidget) wid;
2568 * Get the value directly from the field in the instance structure.
2569 * If it is DtUNSPECIFIED then either:
2570 * 1) the value has been assigned to the widget (so get it from
2572 * 2) the value has never been set (so return the default value).
2575 if (E_changeButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2576 data = XmStringCopy( E_changeButtonLabel(editor) );
2577 else if (M_search_dialog(editor) != (Widget) NULL)
2579 XtSetArg( al[0], XmNlabelString, &data) ;
2580 XtGetValues( (Widget) M_search_replaceBtn(editor), al, 1) ;
2583 data = XmStringCreateLocalized(CHANGE_BUTTON);
2584 *value = (XtArgVal) data ;
2587 } /* end _DtEditorGetChangeButtonLabel */
2590 _DtEditorGetChangeFieldLabel(
2592 int resource_offset,
2595 DtEditorWidget editor = (DtEditorWidget) wid;
2600 * Get the value directly from the field in the instance structure.
2601 * If it is DtUNSPECIFIED then either:
2602 * 1) the value has been assigned to the widget (so get it from
2604 * 2) the value has never been set (so return the default value).
2607 if (E_changeFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2608 data = XmStringCopy( E_changeFieldLabel(editor) );
2609 else if (M_search_dialog(editor) != (Widget) NULL)
2611 XtSetArg( al[0], XmNlabelString, &data) ;
2612 XtGetValues( (Widget) M_search_replaceLbl(editor), al, 1) ;
2615 data = XmStringCreateLocalized(CHANGE_LABEL);
2616 *value = (XtArgVal) data ;
2619 } /* end _DtEditorGetChangeFieldLabel */
2622 _DtEditorGetColumns(
2624 int resource_offset,
2627 DtEditorWidget editor = (DtEditorWidget) wid;
2631 XtSetArg( al[0], XmNcolumns, &data) ;
2632 XtGetValues( (Widget) M_text(editor), al, 1) ;
2633 *value = (XtArgVal) data ;
2636 } /* end _DtEditorGetColumns */
2639 _DtEditorGetCurrentLineLabel(
2641 int resource_offset,
2644 DtEditorWidget editor = (DtEditorWidget) wid;
2649 * Get the value directly from the field in the instance structure.
2650 * If it is DtUNSPECIFIED then either:
2651 * 1) the value has been assigned to the widget (so get it from
2653 * 2) the value has never been set (so return the default value).
2656 if (E_status_currentLineLabel(editor) != (XmString) DtUNSPECIFIED)
2657 data = XmStringCopy( E_status_currentLineLabel(editor) );
2658 else if (M_status_statusArea(editor) != (Widget) NULL)
2660 XtSetArg( al[0], XmNlabelString, &data) ;
2661 XtGetValues( (Widget) M_status_lineLabel(editor), al, 1) ;
2664 data = XmStringCreateLocalized(LINE);
2665 *value = (XtArgVal) data ;
2668 } /* end _DtEditorGetCurrentLineLabel */
2671 _DtEditorGetCursorPosition(
2673 int resource_offset,
2676 DtEditorWidget editor = (DtEditorWidget) wid;
2677 XmTextPosition data;
2680 XtSetArg( al[0], XmNcursorPosition, &data) ;
2681 XtGetValues( (Widget) M_text(editor), al, 1) ;
2682 *value = (XtArgVal) data ;
2685 } /* end _DtEditorGetCursorPosition */
2688 _DtEditorGetFindButtonLabel(
2690 int resource_offset,
2693 DtEditorWidget editor = (DtEditorWidget) wid;
2698 * Get the value directly from the field in the instance structure.
2699 * If it is DtUNSPECIFIED then either:
2700 * 1) the value has been assigned to the widget (so get it from
2702 * 2) the value has never been set (so return the default value).
2705 if (E_findButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2706 data = XmStringCopy( E_findButtonLabel(editor) );
2707 else if (M_search_dialog(editor) != (Widget) NULL)
2709 XtSetArg( al[0], XmNlabelString, &data) ;
2710 XtGetValues( (Widget) M_search_findBtn(editor), al, 1) ;
2713 data = XmStringCreateLocalized(FIND_BUTTON);
2714 *value = (XtArgVal) data ;
2717 } /* end _DtEditorGetFindButtonLabel */
2720 _DtEditorGetFindFieldLabel(
2722 int resource_offset,
2725 DtEditorWidget editor = (DtEditorWidget) wid;
2730 * Get the value directly from the field in the instance structure.
2731 * If it is DtUNSPECIFIED then either:
2732 * 1) the value has been assigned to the widget (so get it from
2734 * 2) the value has never been set (so return the default value).
2737 if (E_findFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2738 data = XmStringCopy( E_findFieldLabel(editor) );
2739 else if (M_search_dialog(editor) != (Widget) NULL)
2741 XtSetArg( al[0], XmNlabelString, &data) ;
2742 XtGetValues( (Widget) M_search_findLbl(editor), al, 1) ;
2745 data = XmStringCreateLocalized(FIND_LABEL);
2746 *value = (XtArgVal) data ;
2749 } /* end _DtEditorGetFindFieldLabel */
2752 _DtEditorGetFormatAllButtonLabel(
2754 int resource_offset,
2757 DtEditorWidget editor = (DtEditorWidget) wid;
2762 * Get the value directly from the field in the instance structure.
2763 * If it is DtUNSPECIFIED then either:
2764 * 1) the value has been assigned to the widget (so get it from
2766 * 2) the value has never been set (so return the default value).
2769 if (E_format_formatAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2770 data = XmStringCopy( E_format_formatAllButtonLabel(editor) );
2771 else if (M_format_dialog(editor) != (Widget)NULL)
2773 XtSetArg( al[0], XmNlabelString, &data) ;
2774 XtGetValues( (Widget) M_format_all(editor), al, 1) ;
2777 data = XmStringCreateLocalized(ALL);
2778 *value = (XtArgVal) data ;
2781 } /* end _DtEditorGetFormatAllButtonLabel */
2784 _DtEditorGetFormatParagraphButtonLabel(
2786 int resource_offset,
2789 DtEditorWidget editor = (DtEditorWidget) wid;
2794 * Get the value directly from the field in the instance structure.
2795 * If it is DtUNSPECIFIED then either:
2796 * 1) the value has been assigned to the widget (so get it from
2798 * 2) the value has never been set (so return the default value).
2801 if(E_format_formatParagraphButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2802 data = XmStringCopy( E_format_formatParagraphButtonLabel(editor) );
2803 else if (M_format_dialog(editor) != (Widget)NULL)
2805 XtSetArg( al[0], XmNlabelString, &data) ;
2806 XtGetValues( (Widget) M_format_paragraph(editor), al, 1) ;
2809 data = XmStringCreateLocalized(PARAGRAPH);
2810 *value = (XtArgVal) data ;
2813 } /* end _DtEditorGetFormatParagraphButtonLabel */
2816 _DtEditorGetJustifyToggleLabel(
2818 int resource_offset,
2821 DtEditorWidget editor = (DtEditorWidget) wid;
2826 * Get the value directly from the field in the instance structure.
2827 * If it is DtUNSPECIFIED then either:
2828 * 1) the value has been assigned to the widget (so get it from
2830 * 2) the value has never been set (so return the default value).
2833 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2834 data = XmStringCopy( E_format_justifyToggleLabel(editor) );
2835 else if (M_format_dialog(editor) != (Widget)NULL)
2837 XtSetArg( al[0], XmNlabelString, &data) ;
2838 XtGetValues( (Widget) M_format_bothJust(editor), al, 1) ;
2841 data = XmStringCreateLocalized(JUSTIFY);
2842 *value = (XtArgVal) data ;
2845 } /* end _DtEditorGetJustifyToggleLabel */
2848 _DtEditorGetLeftAlignToggleLabel(
2850 int resource_offset,
2853 DtEditorWidget editor = (DtEditorWidget) wid;
2858 * Get the value directly from the field in the instance structure.
2859 * If it is DtUNSPECIFIED then either:
2860 * 1) the value has been assigned to the widget (so get it from
2862 * 2) the value has never been set (so return the default value).
2865 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2866 data = XmStringCopy( E_format_leftAlignToggleLabel(editor) );
2867 else if (M_format_dialog(editor) != (Widget)NULL)
2869 XtSetArg( al[0], XmNlabelString, &data) ;
2870 XtGetValues( (Widget) M_format_leftJust(editor), al, 1) ;
2873 data = XmStringCreateLocalized(LEFT_ALIGN);
2874 *value = (XtArgVal) data ;
2877 } /* end _DtEditorGetLeftAlignToggleLabel */
2880 _DtEditorGetLeftMarginFieldLabel(
2882 int resource_offset,
2885 DtEditorWidget editor = (DtEditorWidget) wid;
2890 * Get the value directly from the field in the instance structure.
2891 * If it is DtUNSPECIFIED then either:
2892 * 1) the value has been assigned to the widget (so get it from
2894 * 2) the value has never been set (so return the default value).
2897 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2898 data = XmStringCopy( E_format_leftMarginFieldLabel(editor) );
2899 else if (M_format_dialog(editor) != (Widget)NULL)
2901 XtSetArg( al[0], XmNlabelString, &data) ;
2902 XtGetValues( (Widget) M_format_leftLabel(editor), al, 1) ;
2905 data = XmStringCreateLocalized(LEFT_MARGIN);
2906 *value = (XtArgVal) data ;
2909 } /* end _DtEditorGetLeftMarginFieldLabel */
2912 _DtEditorGetMaxLength(
2914 int resource_offset,
2917 DtEditorWidget editor = (DtEditorWidget) wid;
2921 XtSetArg( al[0], XmNmaxLength, &data) ;
2922 XtGetValues( (Widget) M_text(editor), al, 1) ;
2923 *value = (XtArgVal) data ;
2926 } /* end _DtEditorGetMaxLength */
2929 _DtEditorGetMisspelledListLabel(
2931 int resource_offset,
2934 DtEditorWidget editor = (DtEditorWidget) wid;
2939 * Get the value directly from the field in the instance structure.
2940 * If it is DtUNSPECIFIED then either:
2941 * 1) the value has been assigned to the widget (so get it from
2943 * 2) the value has never been set (so return the default value).
2946 if (E_misspelledListLabel(editor) != (XmString) DtUNSPECIFIED)
2947 data = XmStringCopy( E_misspelledListLabel(editor) );
2948 else if (M_search_dialog(editor) != (Widget) NULL)
2950 XtSetArg( al[0], XmNlabelString, &data) ;
2951 XtGetValues( (Widget) M_search_listLbl(editor), al, 1) ;
2954 data = XmStringCreateLocalized(MISSPELLED);
2955 *value = (XtArgVal) data ;
2958 } /* end _DtEditorGetMisspelledListLabel */
2961 _DtEditorGetRightAlignToggleLabel(
2963 int resource_offset,
2966 DtEditorWidget editor = (DtEditorWidget) wid;
2971 * Get the value directly from the field in the instance structure.
2972 * If it is DtUNSPECIFIED then either:
2973 * 1) the value has been assigned to the widget (so get it from
2975 * 2) the value has never been set (so return the default value).
2978 if (E_format_rightAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2979 data = XmStringCopy( E_format_rightAlignToggleLabel(editor) );
2980 else if (M_format_dialog(editor) != (Widget)NULL)
2982 XtSetArg( al[0], XmNlabelString, &data) ;
2983 XtGetValues( (Widget) M_format_rightJust(editor), al, 1) ;
2986 data = XmStringCreateLocalized(RIGHT_ALIGN);
2987 *value = (XtArgVal) data ;
2990 } /* end _DtEditorGetRightAlignToggleLabel */
2993 _DtEditorGetRightMarginFieldLabel(
2995 int resource_offset,
2998 DtEditorWidget editor = (DtEditorWidget) wid;
3003 * Get the value directly from the field in the instance structure.
3004 * If it is DtUNSPECIFIED then either:
3005 * 1) the value has been assigned to the widget (so get it from
3007 * 2) the value has never been set (so return the default value).
3010 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
3011 data = XmStringCopy( E_format_rightMarginFieldLabel(editor) );
3012 else if (M_format_dialog(editor) != (Widget)NULL)
3014 XtSetArg( al[0], XmNlabelString, &data) ;
3015 XtGetValues( (Widget) M_format_rightLabel(editor), al, 1) ;
3018 data = XmStringCreateLocalized(RIGHT_MARGIN);
3019 *value = (XtArgVal) data ;
3022 } /* end _DtEditorGetRightMarginFieldLabel */
3027 int resource_offset,
3030 DtEditorWidget editor = (DtEditorWidget) wid;
3034 XtSetArg( al[0], XmNrows, &data) ;
3035 XtGetValues( (Widget) M_text(editor), al, 1) ;
3036 *value = (XtArgVal) data ;
3039 } /* end _DtEditorGetRows */
3042 _DtEditorGetScrollLeftSide(
3044 int resource_offset,
3047 DtEditorWidget editor = (DtEditorWidget) wid;
3051 XtSetArg( al[0], XmNscrollLeftSide, &data) ;
3052 XtGetValues( (Widget) M_text(editor), al, 1) ;
3053 *value = (XtArgVal) data ;
3056 } /* end _DtEditorGetScrollLeftSide */
3059 _DtEditorGetScrollTopSide(
3061 int resource_offset,
3064 DtEditorWidget editor = (DtEditorWidget) wid;
3068 XtSetArg( al[0], XmNscrollTopSide, &data) ;
3069 XtGetValues( (Widget) M_text(editor), al, 1) ;
3070 *value = (XtArgVal) data ;
3073 } /* end _DtEditorGetScrollTopSide */
3076 _DtEditorGetTextBackground(
3078 int resource_offset,
3081 DtEditorWidget editor = (DtEditorWidget) wid;
3085 XtSetArg( al[0], XmNbackground, &data) ;
3086 XtGetValues( (Widget) M_text(editor), al, 1) ;
3087 *value = (XtArgVal) data ;
3090 } /* end _DtEditorGetTextBackground */
3093 _DtEditorGetTextForeground(
3095 int resource_offset,
3098 DtEditorWidget editor = (DtEditorWidget) wid;
3102 XtSetArg( al[0], XmNforeground, &data) ;
3103 XtGetValues( (Widget) M_text(editor), al, 1) ;
3104 *value = (XtArgVal) data ;
3107 } /* end _DtEditorGetTextForeground */
3110 _DtEditorGetTopCharacter(
3112 int resource_offset,
3115 DtEditorWidget editor = (DtEditorWidget) wid;
3116 XmTextPosition data;
3119 XtSetArg( al[0], XmNtopCharacter, &data) ;
3120 XtGetValues( (Widget) M_text(editor), al, 1) ;
3121 *value = (XtArgVal) data ;
3124 } /* end _DtEditorGetTopCharacter */
3127 _DtEditorGetLineCountLabel(
3129 int resource_offset,
3132 DtEditorWidget editor = (DtEditorWidget) wid;
3137 * Get the value directly from the field in the instance structure.
3138 * If it is DtUNSPECIFIED then either:
3139 * 1) the value has been assigned to the widget (so get it from
3141 * 2) the value has never been set (so return the default value).
3144 if (E_status_totalLineCountLabel(editor) != (XmString) DtUNSPECIFIED)
3145 data = XmStringCopy( E_status_totalLineCountLabel(editor) );
3146 else if (M_status_statusArea(editor) != (Widget) NULL)
3148 XtSetArg( al[0], XmNlabelString, &data) ;
3149 XtGetValues( (Widget) M_status_totalLabel(editor), al, 1) ;
3152 data = XmStringCreateLocalized(TOTAL);
3153 *value = (XtArgVal) data ;
3156 } /* end _DtEditorGetLineCountLabel */
3159 /**************************************************************
3161 ** Action Procedures
3166 * The following are DtEditor's actions. A few are internal only (_I
3167 * suffix) and will be called by the default translations DtEditor places
3168 * on the text widget. The rest will be called from an application with
3169 * XtCallActionProc(). The main difference is the internal ones will be
3170 * passed a text widget ID, while the public ones will be passed a DtEditor ID.
3178 Cardinal *num_params)
3181 DtEditorWidget editor = (DtEditorWidget)w;
3183 XtCallActionProc( M_text(editor), "backward-character", event,
3184 params, *num_params );
3192 Cardinal *num_params)
3195 DtEditorWidget editor = (DtEditorWidget)w;
3197 XtCallActionProc( M_text(editor), "backward-paragraph", event,
3198 params, *num_params );
3206 Cardinal *num_params)
3209 DtEditorWidget editor = (DtEditorWidget)w;
3211 XtCallActionProc( M_text(editor), "backward-word", event,
3212 params, *num_params );
3220 Cardinal *num_params)
3223 DtEditorWidget editor = (DtEditorWidget)w;
3225 XtCallActionProc( M_text(editor), "beginning-of-file", event,
3226 params, *num_params );
3234 Cardinal *num_params)
3237 DtEditorWidget editor = (DtEditorWidget)w;
3239 XtCallActionProc( M_text(editor), "beginning-of-line", event,
3240 params, *num_params );
3248 Cardinal *num_params)
3251 DtEditorWidget editor = (DtEditorWidget)w;
3253 XtCallActionProc( M_text(editor), "clear-selection", event,
3254 params, *num_params );
3257 * Clearing selected text also deselects the selection, but for some
3258 * reason the selection proc (Editor_SetSelectionProc) does not get
3259 * called, therefore, we need to call the DtNtextDeselectCallback
3262 Call_TextDeselectCallback(editor);
3271 Cardinal *num_params)
3274 DtEditorWidget editor = (DtEditorWidget)w;
3276 XtCallActionProc( M_text(editor), "copy-clipboard", event,
3277 params, *num_params );
3285 Cardinal *num_params)
3288 DtEditorWidget editor = (DtEditorWidget)w;
3290 XtCallActionProc( M_text(editor), "cut-clipboard", event,
3291 params, *num_params );
3299 Cardinal *num_params)
3302 DtEditorWidget editor = (DtEditorWidget)w;
3304 XtCallActionProc( M_text(editor), "delete-next-character", event,
3305 params, *num_params );
3313 Cardinal *num_params)
3316 DtEditorWidget editor = (DtEditorWidget)w;
3318 XtCallActionProc( M_text(editor), "delete-next-word", event,
3319 params, *num_params );
3327 Cardinal *num_params)
3330 DtEditorWidget editor = (DtEditorWidget)w;
3332 XtCallActionProc( M_text(editor), "delete-previous-character", event,
3333 params, *num_params );
3341 Cardinal *num_params)
3344 DtEditorWidget editor = (DtEditorWidget)w;
3346 XtCallActionProc( M_text(editor), "delete-previous-word", event,
3347 params, *num_params );
3355 Cardinal *num_params)
3358 DtEditorWidget editor = (DtEditorWidget)w;
3360 XtCallActionProc( M_text(editor), "delete-to-end-of-line", event,
3361 params, *num_params );
3369 Cardinal *num_params)
3372 DtEditorWidget editor = (DtEditorWidget)w;
3374 XtCallActionProc( M_text(editor), "delete-to-start-of-line", event,
3375 params, *num_params );
3383 Cardinal *num_params)
3386 DtEditorWidget editor = (DtEditorWidget)w;
3388 XtCallActionProc( M_text(editor), "deselect-all", event,
3389 params, *num_params );
3397 Cardinal *num_params)
3400 DtEditorWidget editor = (DtEditorWidget)w;
3402 XtCallActionProc( M_text(editor), "end-of-file", event,
3403 params, *num_params );
3411 Cardinal *num_params)
3414 DtEditorWidget editor = (DtEditorWidget)w;
3416 XtCallActionProc( M_text(editor), "end-of-line", event,
3417 params, *num_params );
3425 Cardinal *num_params)
3428 DtEditorWidget editor = (DtEditorWidget)w;
3430 XtCallActionProc( M_text(editor), "forward-character", event,
3431 params, *num_params );
3439 Cardinal *num_params)
3442 DtEditorWidget editor = (DtEditorWidget)w;
3444 XtCallActionProc( M_text(editor), "forward-paragraph", event,
3445 params, *num_params );
3453 Cardinal *num_params)
3456 DtEditorWidget editor = (DtEditorWidget)w;
3458 XtCallActionProc( M_text(editor), "forward-word", event,
3459 params, *num_params );
3467 Cardinal *num_params)
3469 DtEditorWidget editor = (DtEditorWidget)w;
3471 if( M_status_statusArea(editor) != (Widget)NULL &&
3472 XtIsManaged(M_status_statusArea(editor)) == True )
3476 * Set the input focus to the "Line" text field.
3479 XmProcessTraversal(M_status_lineText(editor), XmTRAVERSE_CURRENT);
3482 * Select the current contents to allow easy modification.
3485 XtCallActionProc( (Widget)M_status_lineText(editor), "select-all",
3486 event, (String *)NULL, 0 );
3489 } /* end GoToLine */
3492 * Internal action called only from the scrolled text widget
3499 Cardinal *num_params)
3501 XmTextWidget tw = (XmTextWidget)w;
3502 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3504 GoToLine( (Widget)editor, event, params, num_params );
3506 } /* end GoToLine_I */
3513 Cardinal *num_params)
3516 CallHelpCallback((DtEditorWidget)w, DtEDITOR_HELP_EDIT_WINDOW);
3525 Cardinal *num_params)
3528 DtEditorWidget editor = (DtEditorWidget)w;
3530 XtCallActionProc( M_text(editor), "insert-string", event,
3531 params, *num_params );
3539 Cardinal *num_params)
3542 DtEditorWidget editor = (DtEditorWidget)w;
3544 XtCallActionProc( M_text(editor), "key-select", event,
3545 params, *num_params );
3553 Cardinal *num_params)
3556 DtEditorWidget editor = (DtEditorWidget)w;
3558 XtCallActionProc( M_text(editor), "newline-and-backup", event,
3559 params, *num_params );
3567 Cardinal *num_params)
3570 DtEditorWidget editor = (DtEditorWidget)w;
3572 XtCallActionProc( M_text(editor), "newline-and-indent", event,
3573 params, *num_params );
3581 Cardinal *num_params)
3584 DtEditorWidget editor = (DtEditorWidget)w;
3586 XtCallActionProc( M_text(editor), "next-page", event,
3587 params, *num_params );
3595 Cardinal *num_params)
3598 DtEditorWidget editor = (DtEditorWidget)w;
3600 XtCallActionProc( M_text(editor), "page-left", event,
3601 params, *num_params );
3609 Cardinal *num_params)
3612 DtEditorWidget editor = (DtEditorWidget)w;
3614 XtCallActionProc( M_text(editor), "page-right", event,
3615 params, *num_params );
3623 Cardinal *num_params)
3626 DtEditorWidget editor = (DtEditorWidget)w;
3628 XtCallActionProc( M_text(editor), "paste-clipboard", event,
3629 params, *num_params );
3637 Cardinal *num_params)
3640 DtEditorWidget editor = (DtEditorWidget)w;
3642 XtCallActionProc( M_text(editor), "previous-page", event,
3643 params, *num_params );
3651 Cardinal *num_params)
3654 DtEditorWidget editor = (DtEditorWidget)w;
3656 XtCallActionProc( M_text(editor), "process-cancel", event,
3657 params, *num_params );
3665 Cardinal *num_params)
3668 DtEditorWidget editor = (DtEditorWidget)w;
3670 XtCallActionProc( M_text(editor), "process-down", event,
3671 params, *num_params );
3679 Cardinal *num_params)
3682 DtEditorWidget editor = (DtEditorWidget)w;
3684 XtCallActionProc( M_text(editor), "process-shift-down", event,
3685 params, *num_params );
3693 Cardinal *num_params)
3696 DtEditorWidget editor = (DtEditorWidget)w;
3698 XtCallActionProc( M_text(editor), "process-shift-up", event,
3699 params, *num_params );
3707 Cardinal *num_params)
3710 DtEditorWidget editor = (DtEditorWidget)w;
3712 XtCallActionProc( M_text(editor), "process-up", event,
3713 params, *num_params );
3716 /************************************************************************
3717 * GetModeSwitchModifier
3718 * Find if any Mod<n> modifier is acting as the Group modifier - you
3719 * can't assume Mod1Mask is always it.
3720 * Returns the mask of the modifier key to which the Mode_switch
3721 * keysym is attached.
3723 ************************************************************************/
3726 GetModeSwitchModifier(
3729 XModifierKeymap *pMap;
3730 int mapIndex, keyCol, mapSize;
3732 unsigned int modeSwitchModMask = 0;
3733 pMap = XGetModifierMapping(dpy);
3734 mapSize = 8*pMap->max_keypermod;
3736 for (mapIndex = 3*pMap->max_keypermod; mapIndex < mapSize; mapIndex++) {
3737 /* look only at the first 4 columns of key map */
3738 for (keyCol = 0; keyCol < 4; keyCol++) {
3739 keySym = XKeycodeToKeysym(dpy, pMap->modifiermap[mapIndex], keyCol);
3740 if (keySym == XK_Mode_switch)
3741 modeSwitchModMask |= 1 << (mapIndex / pMap->max_keypermod);
3745 XFreeModifiermap(pMap);
3746 return modeSwitchModMask;
3749 /************************************************************************
3751 * DtEditorQuoteNextChar
3752 * This action routine circumvents the normal XtDispatchEvent
3753 * mechanism, inserting the next control or extended character
3754 * directly into text without processed by event handlers or the
3755 * translation manager. This means, for
3756 * example, that the next control or extended character will be
3757 * inserted into text without being intrepreted as a Motif menu
3758 * or text widget accelerator.
3760 ************************************************************************/
3767 Cardinal *num_params)
3769 DtEditorWidget editor = (DtEditorWidget)widget;
3770 static unsigned int ExtendcharMask = 0;
3772 /* NOTE: ExtendcharMask could be a global set via a MappingNotify
3773 * event handler. But it isn't...
3776 if (! ExtendcharMask)
3779 if (! ExtendcharMask)
3780 ExtendcharMask = GetModeSwitchModifier( M_display(editor) );
3790 * We cannot let XtAppNextEvent bloc, because the intrinsics
3791 * will release locks and some other thread might dispatch
3792 * the event we want to trap.
3795 XtAppContext app = XtWidgetToApplicationContext(widget);
3796 while ((mask = XtAppPending(app)) == 0)
3798 if (XtAppGetExitFlag(app))
3802 if (mask & XtIMXEvent)
3805 XtAppNextEvent(M_app_context(editor), &next);
3806 if ((next.type == KeyPress) &&
3807 (! IsModifierKey(XLookupKeysym((XKeyEvent *) &next, 0))) )
3809 if (next.xkey.state & (ControlMask|ExtendcharMask))
3810 XtCallActionProc(M_text(editor), "self-insert", &next, NULL, 0);
3812 XtDispatchEvent(&next);
3816 XtDispatchEvent(&next);
3821 /* Some (non-X) event is pending, so this should not block. */
3822 XtAppProcessEvent(app, mask);
3827 } /* end QuoteNextChar */
3830 * Internal action called only from the scrolled text widget
3837 Cardinal *num_params)
3839 XmTextWidget tw = (XmTextWidget)w;
3840 DtEditorWidget editor = (DtEditorWidget) M_editor(tw);
3842 QuoteNextChar( (Widget)editor, event, params, num_params );
3844 } /* end QuoteNextChar_I */
3851 Cardinal *num_params)
3854 DtEditorWidget editor = (DtEditorWidget)w;
3856 XtCallActionProc( M_text(editor), "select-all", event,
3857 params, *num_params );
3865 Cardinal *num_params)
3867 DtEditorWidget editor = (DtEditorWidget)w;
3870 * Toggle the state of the DtNoverstrike resource
3872 XtVaSetValues(w, DtNoverstrike, !M_overstrikeMode(editor), NULL);
3874 } /* end ToggleInsertMode */
3881 Cardinal *num_params)
3883 XmTextWidget tw = (XmTextWidget)w;
3884 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3886 ToggleInsertMode( (Widget)editor, event, params, num_params );
3888 } /* end ToggleInsertMode_I */
3896 Cardinal *num_params)
3899 DtEditorUndoEdit(w);
3901 } /* end UndoEdit */
3908 Cardinal *num_params)
3910 XmTextWidget tw = (XmTextWidget)w;
3912 UndoEdit( (Widget)M_editor(tw), event, params, num_params );
3914 } /* end UndoEdit_I */
3918 * XXX All lines in this file marked "XXX Word Wrap workaround"
3919 * XXX are related to a Motif 1.2 Text widget design defect regarding
3920 * XXX word wrap. For Motif 1.2, the Text widget was designed so word
3921 * XXX wrap will not function if the scrolled text widget has a
3922 * XXX horizontal scroll bar ("a hscrollbar means the paper is infinite
3923 * XXX so there is no edge to wrap at"). This change was made in
3924 * XXX Xm/TextOut.c RCS version 1.71 checked in July, 1991. A
3925 * XXX CMVC report was filed 9/8/94 & assigned number 4772.
3927 #include <Xm/TextOutP.h> /* XXX Word Wrap workaround */
3928 static void /* XXX Word Wrap workaround */
3929 FixWordWrap( /* XXX Word Wrap workaround */
3930 Widget w, /* XXX Word Wrap workaround */
3931 Boolean wrapOn) /* XXX Word Wrap workaround */
3932 { /* XXX Word Wrap workaround */
3933 XmTextWidget tw = (XmTextWidget)w; /* XXX Word Wrap workaround */
3934 OutputData data = tw->text.output->data; /* XXX Word Wrap workaround */
3936 data->scrollhorizontal = !wrapOn; /* XXX Word Wrap workaround */
3937 } /* XXX Word Wrap workaround */
3940 Call_TextSelectCallback(
3941 DtEditorWidget editor)
3944 DtEditorSelectCallbackStruct select_cb;
3947 * Call the Editor widget's DtNtextSelectCallback proc
3948 * if it hasn't been called since the last select.
3951 if ( !M_textSelectCbCalled(editor) ) {
3953 M_textSelectCbCalled(editor) = True;
3954 select_cb.reason = DtEDITOR_TEXT_SELECT;
3955 select_cb.event = (XEvent *)NULL;
3956 XtCallCallbackList ((Widget)editor, M_textSelect(editor),
3957 (XtPointer) &select_cb);
3960 } /* end Call_TextSelectCallback */
3963 Call_TextDeselectCallback(
3964 DtEditorWidget editor)
3967 DtEditorSelectCallbackStruct select_cb;
3970 * Call the Editor widget's DtNtextDeselectCallback proc
3971 * if it hasn't been called since the last deselect.
3974 if ( M_textSelectCbCalled(editor) ) {
3976 M_textSelectCbCalled(editor) = False;
3977 select_cb.reason = DtEDITOR_TEXT_DESELECT;
3978 select_cb.event = (XEvent *)NULL;
3979 XtCallCallbackList ((Widget)editor, M_textDeselect(editor),
3980 (XtPointer) &select_cb);
3983 } /* end Call_TextDeselectCallback */
3986 * Editor_SetSelectionProc
3987 * is put into the widget->text.source->SetSelection.
3988 * Used to call the DtEditor's select/unselect callbacks
3991 Editor_SetSelectionProc(
3992 XmTextSource source,
3993 XmTextPosition left,
3994 XmTextPosition right,
3997 XmSourceData data = source->data;
4000 DtEditorWidget editor;
4006 if (!XtIsRealized((Widget)data->widgets[0]) ||
4007 data->numwidgets <= 0)
4010 if (left < 0) left = right = 0;
4012 widget = (Widget) data->widgets[0];
4013 tw = (XmTextWidget)widget;
4014 editor = M_editor(tw);
4016 if (!editor->core.being_destroyed) {
4020 * There is a selected area if left < right so call the
4021 * DtNtextSelectCallback.
4024 Call_TextSelectCallback( editor );
4029 * Left = Right so nothing is selected; call the
4030 * DtNtextDeselectCallback.
4033 Call_TextDeselectCallback( editor );
4039 * Now, call the text widget's real Set Selection proc
4041 (*M_setSelection(editor))(source, left, right, set_time);
4043 } /* end Editor_SetSelectionProc */
4046 /**************************************************************
4048 ** Drag and drop routines
4054 * Handles drops of a file into the text editor, after validation in the
4055 * transfer callback. Files are handled by reading their contents.
4056 * Text is handled by Motif.
4058 * Changing the contents of the text widget occurs here, rather than in
4059 * the transfer callback, because of the visual changes which occur when
4060 * changing the text widget.
4066 XtPointer client_data,
4067 XtPointer call_data )
4070 DtEditorErrorCode error;
4072 DtDndDropAnimateCallbackStruct *animateInfo =
4073 (DtDndDropAnimateCallbackStruct *) call_data;
4074 DtEditorWidget editor = (DtEditorWidget) client_data;
4077 * XXX Only really needed if # of items is > 1
4079 _DtTurnOnHourGlass( M_topLevelShell(editor) );
4082 * How many items are being dropped on us?
4084 numItems = animateInfo->dropData->numItems;
4086 switch (animateInfo->dropData->protocol)
4088 case DtDND_FILENAME_TRANSFER:
4091 * OK, insert each file we are given
4093 for (ii = 0; ii < numItems; ii++)
4095 error = DtEditorInsertFromFile( (Widget)editor,
4096 animateInfo->dropData->data.files[ii] );
4099 * If the file was not inserted successfully, then quit
4100 * (don't care if the file is read only or if it contained
4101 * nulls that were stripped out).
4103 if( error != DtEDITOR_NO_ERRORS &&
4104 error != DtEDITOR_READ_ONLY_FILE &&
4105 error != DtEDITOR_NULLS_REMOVED )
4107 ii = numItems; /* break out of loop */
4114 } /* end file transfer case */
4116 case DtDND_BUFFER_TRANSFER:
4119 * OK, insert each buffer we are given
4122 DtDndBuffer *buffers = animateInfo->dropData->data.buffers;
4123 DtEditorContentRec cr;
4124 cr.type = DtEDITOR_DATA;
4126 for (ii = 0; ii < numItems; ii++)
4128 cr.value.data.buf = buffers[ii].bp;
4129 cr.value.data.length = buffers[ii].size;
4131 error = DtEditorInsert( (Widget)editor, &cr );
4134 * If the buffer was not inserted successfully, then quit
4135 * (don't care if the file contained nulls that were stripped out).
4137 if( error != DtEDITOR_NO_ERRORS && error != DtEDITOR_NULLS_REMOVED )
4139 ii = numItems; /* break out of loop */
4146 } /* end buffer transfer case */
4148 case DtDND_TEXT_TRANSFER:
4151 * Receiving a text drop.
4153 * Text drag and drop is handled by Motif so this switch
4154 * will never be called.
4159 } /* end text transfer case */
4168 * XXX Only really needed if # of items is > 1
4170 _DtTurnOffHourGlass( M_topLevelShell(editor) );
4172 } /* end AnimateCallback */
4176 * Validates a drop of a file into the text widget.
4178 * Changing the contents of the text widget occurs in the animate
4179 * callback, rather than here, because of the visual changes which
4180 * occur when changing the text widget.
4187 XtPointer client_data,
4188 XtPointer call_data)
4191 DtEditorErrorCode error;
4193 DtDndTransferCallbackStruct *transferInfo =
4194 (DtDndTransferCallbackStruct *) call_data;
4196 transferInfo->status = DtDND_SUCCESS;
4199 * How many items are being dropped on us?
4201 numItems = transferInfo->dropData->numItems;
4203 switch (transferInfo->dropData->protocol)
4205 case DtDND_FILENAME_TRANSFER:
4209 * Check to see if we can read each file we are given
4211 for (ii = 0; ii < numItems; ii++)
4213 error = _DtEditorValidateFileAccess(
4214 transferInfo->dropData->data.files[ii],
4218 * Can't access it for reading so reject drop
4220 if ( error != DtEDITOR_NO_ERRORS ) {
4221 transferInfo->status = DtDND_FAILURE;
4222 ii = numItems; /* break out of loop */
4225 } /* end for each file */
4229 } /* end file transfer case */
4231 case DtDND_BUFFER_TRANSFER:
4234 * Receiving a buffer drop.
4235 * -- do nothing in transfer
4239 } /* end buffer transfer case */
4241 case DtDND_TEXT_TRANSFER:
4244 * Receiving a text drop.
4246 * Text drag and drop is handled by Motif so this switch
4247 * will never be called.
4252 } /* end text transfer case */
4256 transferInfo->status = DtDND_FAILURE;
4262 } /* end TransferCallback */
4265 /*-------------------------------------------------------------
4266 ** Function: static void RegisterDropZone (
4267 ** DtEditorWidget w)
4269 ** Parameters: A DtEditor widget
4271 ** Purpose: This routine registers the edit window's text widget
4272 ** as a drop site for file & buffer drops. Because it
4273 ** is a text widget it will automatically accept text
4283 XtCallbackRec transferCB[] = { {TransferCallback, NULL}, {NULL, NULL} };
4284 XtCallbackRec animateCB[] = { {AnimateCallback, NULL}, {NULL, NULL} };
4285 transferCB[0].closure = (XtPointer) w;
4286 animateCB[0].closure = (XtPointer) w;
4289 * Register file & buffer transfers... let Motif handle text DnD
4292 XtSetArg( al[ac], DtNdropAnimateCallback, animateCB ); ac++;
4294 DtDndDropRegister( M_text(w),
4295 DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER,
4296 XmDROP_COPY, transferCB, al, ac );
4298 } /* end RegisterDropZone */
4300 /*-------------------------------------------------------------
4301 ** Function: static void UnregisterDropZone (
4302 ** DtEditorWidget w)
4304 ** Parameters: A DtEditor widget
4306 ** Purpose: This routine unregisters the edit window
4313 DtDndDropUnregister( M_text(w) );
4315 } /* end UnregisterDropZone */
4317 /************************************************************************
4319 * SetInfoDialogTitle - Change the title for the Information dialog
4321 ************************************************************************/
4325 DtEditorWidget editor)
4331 * If the Information dialog has been created, change its title
4333 if( M_gen_warning(editor) != (Widget)NULL )
4337 * Prepend the DialogTitle resource, if it has been set
4339 if( E_dialogTitle(editor) != (XmString)NULL ) {
4343 * Add the "functional title" to the DialogTitle
4345 titleStr = XmStringConcat( E_dialogTitle(editor),
4346 E_infoDialogTitle(editor) );
4348 XtSetArg( al[0], XmNdialogTitle, titleStr );
4349 XtSetValues(M_gen_warning(editor), al, 1);
4351 XmStringFree( titleStr );
4355 XtSetArg( al[0], XmNdialogTitle, E_infoDialogTitle(editor) );
4356 XtSetValues(M_gen_warning(editor), al, 1);
4360 } /* end SetInfoDialogTitle */
4362 /************************************************************************
4364 * _DtEditorWarning - get a message to the user
4366 ************************************************************************/
4370 DtEditorWidget editor,
4372 unsigned char dialogType)
4379 tmpMess = strdup(mess);
4381 /* create the dialog if it is the first time */
4382 if(M_gen_warning(editor) == (Widget) NULL)
4384 XmString titleStr = (XmString) NULL;
4390 * First, create the dialog's title, prepending the
4391 * DtNdialogTitle resource, if it is set
4394 if( E_dialogTitle(editor) != (XmString)NULL ) {
4397 * Add the "functional title" to the DialogTitle
4399 titleStr = XmStringConcat( E_dialogTitle(editor),
4400 E_infoDialogTitle(editor) );
4402 XtSetArg (al[ac], XmNdialogTitle, titleStr ); ac++;
4406 XtSetArg (al[ac], XmNdialogTitle, E_infoDialogTitle(editor)); ac++;
4409 okStr = XmStringCreateLocalized((char*) _DtOkString);
4410 XtSetArg (al[ac], XmNokLabelString, okStr); ac++;
4411 M_gen_warning(editor) = (Widget) XmCreateMessageDialog(
4412 M_topLevelShell(editor), "Warn",
4415 if (titleStr != (XmString) NULL)
4416 XmStringFree( titleStr );
4417 XmStringFree(okStr);
4419 /* Set the correct font lists for the message & OK button. */
4420 XtSetArg (al[0], XmNfontList, E_buttonFontList(editor));
4422 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_OK_BUTTON),
4425 XtSetArg (al[0], XmNfontList, E_labelFontList(editor));
4427 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_MESSAGE_LABEL),
4430 /* Unmanage unneeded children. */
4431 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4432 XmDIALOG_CANCEL_BUTTON) );
4433 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4434 XmDIALOG_HELP_BUTTON) );
4436 XtRealizeWidget (M_gen_warning(editor));
4438 XtSetArg(al[ac], XmNmwmInputMode,
4439 MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
4440 XtSetValues(XtParent(M_gen_warning(editor)), al, ac);
4443 tmpStr = XmStringCreateLocalized(tmpMess);
4445 XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
4446 XtSetArg(al[ac], XmNmessageString, tmpStr); ac++;
4447 XtSetValues(M_gen_warning(editor), al, ac);
4448 XmStringFree(tmpStr);
4450 XtFree( (char *) tmpMess );
4452 XtManageChild (M_gen_warning(editor));
4454 } /* end _DtEditorWarning */
4457 /*********************************************************************
4459 * The following section contains the procedures related to the staus
4462 *********************************************************************/
4465 #define DONT_FORCE False
4468 * PositionActivateCB is invoked when the user presses [Return] after
4469 * (presumably) modifying the current line text field. It retrieves
4470 * the user specified line number and calls DtEditorGoToLine().
4477 caddr_t client_data,
4480 DtEditorWidget editor = (DtEditorWidget)client_data;
4481 char *lineStr = XmTextFieldGetString(M_status_lineText(editor));
4482 int newLineNum = atoi(lineStr);
4485 DtEditorGoToLine ((Widget)editor, newLineNum);
4486 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
4488 } /* PositionActivateCB */
4491 * _DtEditorUpdateLineDisplay updates the current & total line displays
4492 * in the status line, if needed. Normally, the displays are not changed
4493 * if the correct numbers are (supposedly) displayed. Setting forceUpdate
4494 * will cause the numbers to be updated anyways. This is primarily used
4495 * when the user enters a number into the current line display to force
4496 * display of the correct number.
4499 _DtEditorUpdateLineDisplay(
4500 DtEditorWidget editor,
4502 Boolean forceUpdate )
4504 XmTextWidget tw = (XmTextWidget) M_text(editor);
4511 * Only change the current & total lines displays if the status
4514 if ( M_status_showStatusLine(editor) == True )
4519 if (M_status_currentLine(editor) != currentLine || forceUpdate)
4521 sprintf(tmpChars, "%d", currentLine);
4522 XmTextFieldSetString(M_status_lineText(editor), tmpChars);
4523 M_status_currentLine(editor) = currentLine;
4529 lastLine = tw->text.total_lines;
4530 if(M_status_lastLine(editor) != lastLine )
4533 sprintf(tmpChars, "%d", lastLine);
4534 tmpXmStr = XmStringCreateLocalized(tmpChars);
4535 XtSetArg(al[0], XmNlabelString, tmpXmStr);
4536 XtSetValues( M_status_totalText(editor), al, 1 );
4538 XmStringFree(tmpXmStr);
4539 M_status_lastLine(editor) = lastLine;
4543 } /* end _DtEditorUpdateLineDisplay */
4547 UpdateOverstrikeIndicator(
4548 DtEditorWidget widget,
4549 Boolean overstrikeOn )
4553 DtEditorWidget ew = (DtEditorWidget) widget;
4556 * Only change the overstrike indicator if the status line is visible
4558 if ( M_status_showStatusLine(ew) == True &&
4559 M_status_overstrikeWidget(ew) != (Widget) NULL )
4563 if ( overstrikeOn == True ) {
4564 XtSetArg(al[ac], XmNlabelString, M_status_overstrikeLabel(ew)); ac++;
4567 XtSetArg(al[ac], XmNlabelString, M_status_insertLabel(ew)); ac++;
4570 XtSetValues( M_status_overstrikeWidget(ew), al, ac );
4573 } /* end UpdateOverstrikeIndicator */
4577 _DtEditorGetLineIndex(
4581 int startLine, lastLine, middleLine;
4582 XmTextLineTable lineTab = tw->text.line_table;
4585 lastLine = tw->text.total_lines - 1;
4587 while(startLine != lastLine)
4589 middleLine = (startLine + lastLine)/2;
4590 if(middleLine == startLine || middleLine == lastLine)
4593 * We're down to 2 lines. It's gotta be on one of these
4596 if(pos < (XmTextPosition) lineTab[lastLine].start_pos)
4597 lastLine = startLine;
4599 startLine = lastLine;
4603 if (pos < (XmTextPosition) lineTab[middleLine].start_pos)
4604 lastLine = middleLine;
4606 startLine = middleLine;
4610 } /* end _DtEditorGetLineIndex */
4614 * SetCursorPosStatus is called as an XmNmotionVerifyCallback on the
4615 * text widget when the statusLine is turned on. It computes and
4616 * displays the new line of the insert cursor.
4621 caddr_t client_data,
4624 DtEditorWidget editor = (DtEditorWidget)client_data;
4625 XmTextWidget tw = (XmTextWidget)w;
4626 XmTextVerifyCallbackStruct * cb = (XmTextVerifyCallbackStruct *) call_data;
4629 startLine = _DtEditorGetLineIndex(tw, cb->newInsert) + 1;
4631 _DtEditorUpdateLineDisplay( editor, startLine, FORCE );
4633 } /* end SetCursorPosStatus */
4639 Boolean statusLineOn)
4644 XmTextPosition cursorPos;
4646 M_status_showStatusLine(ew) = statusLineOn;
4648 if( statusLineOn == True )
4650 if( M_status_statusArea(ew) == (Widget)NULL )
4651 M_status_statusArea(ew) = CreateStatusLine( ew );
4654 * Update the line counts
4657 cursorPos = (XmTextPosition)DtEditorGetInsertionPosition( (Widget)ew );
4658 currentLine = _DtEditorGetLineIndex( (XmTextWidget) M_text(ew),
4660 _DtEditorUpdateLineDisplay( ew, currentLine, DONT_FORCE );
4663 * Update the overstrike indicator
4665 UpdateOverstrikeIndicator( ew, M_overstrikeMode(ew) );
4668 * Show the status line
4671 XtManageChild( M_status_statusArea(ew) );
4674 * Hook the scrolled text widget to the status line
4677 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_WIDGET ); ac++;
4678 XtSetArg( al[ac], XmNbottomWidget, M_status_statusArea(ew) ); ac++;
4679 XtSetValues( XtParent(M_text(ew)), al, ac );
4681 XtAddCallback( M_text(ew), XmNmotionVerifyCallback,
4682 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4688 * Hook the scrolled text widget to the bottom of the form
4691 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4692 XtSetValues( XtParent(M_text(ew)), al, ac );
4694 XtRemoveCallback( M_text(ew), XmNmotionVerifyCallback,
4695 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4698 * Hide the status line
4700 if( M_status_statusArea(ew) != (Widget)NULL )
4701 XtUnmanageChild( M_status_statusArea(ew) );
4705 } /* SetStatusLine */
4708 /************************************************************************
4710 * CreateStatusLine - Creates the status line
4712 ************************************************************************/
4716 DtEditorWidget parent)
4722 Pixel background, foreground;
4725 * Match the background & foreground colors of the edit window
4726 * Don't use DtNtextBackground/Foreground directly because they
4727 * will be DtUNSPECIFIED.
4730 XtSetArg(al[ac], XmNforeground, &foreground); ac++;
4731 XtSetArg(al[ac], XmNbackground, &background); ac++;
4732 XtGetValues(M_text(parent), al, ac);
4735 * Create the status line container
4738 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4739 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4740 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4741 XtSetArg( al[ac], XmNverticalSpacing, 3 ); ac++;
4742 XtSetArg( al[ac], XmNhorizontalSpacing, 3 ); ac++;
4743 container = (Widget) XmCreateForm( (Widget)parent, "statusLine",
4747 * Create the current line label and text field
4750 if (E_status_currentLineLabel(parent) != (XmString)DtUNSPECIFIED)
4753 * Use the resource value & clear it (to save space).
4755 tmpStr = XmStringCopy(E_status_currentLineLabel(parent));
4756 E_status_currentLineLabel(parent) = (XmString)DtUNSPECIFIED;
4760 * The resource has not been set so use its default value
4762 tmpStr = XmStringCreateLocalized(LINE);
4765 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4766 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4767 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4769 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4770 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4771 M_status_lineLabel(parent) = (Widget) XmCreateLabelGadget( container,
4772 "lineLabel", al, ac);
4773 XtManageChild(M_status_lineLabel(parent));
4774 XtAddCallback(M_status_lineLabel(parent), XmNhelpCallback,
4775 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4776 XmStringFree(tmpStr);
4779 XtSetArg(al[ac], XmNcolumns, 6); ac++;
4780 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4781 XtSetArg(al[ac], XmNbackground, background); ac++;
4782 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4783 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4784 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4785 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4786 XtSetArg( al[ac], XmNleftWidget, M_status_lineLabel(parent) ); ac++;
4787 M_status_lineText(parent) = XmCreateTextField( container, "lineText",
4789 XtManageChild(M_status_lineText(parent));
4790 XtAddCallback(M_status_lineText(parent), XmNactivateCallback,
4791 (XtCallbackProc)PositionActivateCB, parent);
4792 XtAddCallback(M_status_lineText(parent), XmNhelpCallback,
4793 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4796 * Create the total lines labels
4799 if (E_status_totalLineCountLabel(parent) != (XmString)DtUNSPECIFIED)
4802 * Use the resource value & clear it (to save space).
4804 tmpStr = XmStringCopy(E_status_totalLineCountLabel(parent));
4805 E_status_totalLineCountLabel(parent) = (XmString)DtUNSPECIFIED;
4809 * The resource has not been set so use its default value
4811 tmpStr = XmStringCreateLocalized(TOTAL);
4814 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4815 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4816 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4817 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4818 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4819 XtSetArg( al[ac], XmNleftWidget, M_status_lineText(parent) ); ac++;
4820 M_status_totalLabel(parent) = (Widget) XmCreateLabelGadget( container,
4821 "totalLabel", al, ac);
4822 XtManageChild(M_status_totalLabel(parent));
4823 XtAddCallback(M_status_totalLabel(parent), XmNhelpCallback,
4824 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4825 XmStringFree(tmpStr);
4828 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4829 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4830 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4831 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4832 XtSetArg( al[ac], XmNleftWidget, M_status_totalLabel(parent) ); ac++;
4833 M_status_totalText(parent) = (Widget) XmCreateLabelGadget( container,
4834 "totalText", al, ac);
4835 XtManageChild(M_status_totalText(parent));
4836 XtAddCallback(M_status_totalText(parent), XmNhelpCallback,
4837 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4840 * Create the overstrike indicator
4844 XtSetArg(al[ac], XmNrecomputeSize, False); ac++;
4846 XtSetArg(al[ac], XmNmarginLeft, 0); ac++;
4847 XtSetArg(al[ac], XmNmarginRight, 0); ac++;
4848 XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
4849 XtSetArg( al[ac], XmNrightOffset, 3 ); ac++;
4850 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4851 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4852 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4853 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4854 M_status_overstrikeWidget(parent) =
4855 (Widget) XmCreateLabelGadget( container, "overstrikeLabel", al, ac);
4856 XtManageChild(M_status_overstrikeWidget(parent));
4857 XtAddCallback(M_status_overstrikeWidget(parent), XmNhelpCallback,
4858 (XtCallbackProc)HelpStatusOverstrikeCB, parent);
4861 * Create the application message area
4864 XtSetArg(al[ac], XmNbackground, parent->core.background_pixel); ac++;
4865 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4866 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4867 XtSetArg(al[ac], XmNeditable, False); ac++;
4868 XtSetArg(al[ac], XmNcursorPositionVisible, False); ac++;
4869 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
4870 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4871 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4872 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4873 XtSetArg( al[ac], XmNleftWidget, M_status_totalText(parent) ); ac++;
4874 XtSetArg( al[ac], XmNleftOffset, 17 ); ac++;
4875 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_WIDGET ); ac++;
4876 XtSetArg(al[ac], XmNrightWidget, M_status_overstrikeWidget(parent)); ac++;
4877 M_status_messageText(parent) =
4878 XmCreateTextField( container, "messageText", al, ac );
4880 XtManageChild(M_status_messageText(parent));
4881 XtAddCallback(M_status_messageText(parent), XmNhelpCallback,
4882 (XtCallbackProc)HelpStatusMessageCB, parent);
4884 return( container );
4886 } /* end CreateStatusLine */
4889 /*********************************************************************
4891 * The following section contains the procedures related to help
4893 *********************************************************************/
4898 DtEditorWidget editor,
4901 DtEditorHelpCallbackStruct help_cb;
4903 help_cb.reason = reason;
4904 help_cb.event = (XEvent *) NULL;
4905 XtCallCallbackList( (Widget)editor, M_HelpCB(editor),
4906 (XtPointer) &help_cb );
4908 } /* end CallHelpCallback */
4911 * Edit window help callbacks
4918 caddr_t client_data,
4921 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_EDIT_WINDOW);
4925 * Status Line help callbacks
4936 caddr_t client_data,
4939 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_STATUS_LINE);
4944 HelpStatusCurrentLineCB(
4946 caddr_t client_data,
4949 CallHelpCallback( (DtEditorWidget)client_data,
4950 DtEDITOR_HELP_STATUS_CURRENT_LINE );
4955 HelpStatusTotalLinesCB(
4957 caddr_t client_data,
4960 CallHelpCallback( (DtEditorWidget)client_data,
4961 DtEDITOR_HELP_STATUS_TOTAL_LINES );
4966 HelpStatusMessageCB(
4968 caddr_t client_data,
4971 CallHelpCallback( (DtEditorWidget)client_data,
4972 DtEDITOR_HELP_STATUS_MESSAGE );
4977 HelpStatusOverstrikeCB(
4979 caddr_t client_data,
4982 CallHelpCallback( (DtEditorWidget)client_data,
4983 DtEDITOR_HELP_STATUS_OVERSTRIKE );
4987 * Format Settings dialog help callbacks
4994 caddr_t client_data,
4997 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_FORMAT_DIALOG);
5002 HelpFormatRightMarginCB(
5004 caddr_t client_data,
5007 CallHelpCallback( (DtEditorWidget)client_data,
5008 DtEDITOR_HELP_FORMAT_RIGHT_MARGIN);
5013 HelpFormatLeftMarginCB(
5015 caddr_t client_data,
5018 CallHelpCallback( (DtEditorWidget)client_data,
5019 DtEDITOR_HELP_FORMAT_LEFT_MARGIN);
5024 HelpFormatJustifyButtonsCB(
5026 caddr_t client_data,
5029 CallHelpCallback( (DtEditorWidget)client_data,
5030 DtEDITOR_HELP_FORMAT_ALIGNMENT);
5034 * Find/Change & Spell dialogs help callbacks
5039 _DtEditorHelpSearchCB(
5041 caddr_t client_data,
5044 DtEditorWidget editor = (DtEditorWidget)client_data;
5046 switch (M_search_dialogMode(editor))
5049 CallHelpCallback( (DtEditorWidget)client_data,
5050 DtEDITOR_HELP_SPELL_DIALOG);
5054 CallHelpCallback( (DtEditorWidget)client_data,
5055 DtEDITOR_HELP_CHANGE_DIALOG);
5058 } /* _DtEditorHelpSearchCB */
5062 _DtEditorHelpSearchFindCB(
5064 caddr_t client_data,
5067 CallHelpCallback( (DtEditorWidget)client_data,
5068 DtEDITOR_HELP_CHANGE_FIND);
5072 _DtEditorHelpSearchChangeCB(
5074 caddr_t client_data,
5077 DtEditorWidget editor = (DtEditorWidget)client_data;
5079 switch (M_search_dialogMode(editor))
5082 CallHelpCallback( (DtEditorWidget)client_data,
5083 DtEDITOR_HELP_SPELL_CHANGE);
5087 CallHelpCallback( (DtEditorWidget)client_data,
5088 DtEDITOR_HELP_CHANGE_CHANGE);
5091 } /* _DtEditorHelpSearchChangeCB */
5095 _DtEditorHelpSearchSpellCB(
5097 caddr_t client_data,
5100 CallHelpCallback( (DtEditorWidget)client_data,
5101 DtEDITOR_HELP_SPELL_MISSPELLED_WORDS);
5104 /*********************************************************************
5106 * The following section contains the procedures related to formating
5107 * text and the Format Settings dialog.
5109 *********************************************************************/
5112 * Do simple formatting of paragraphs of text.
5113 * Designed for speed, at some cost in complexity and redundancy.
5115 * There is a minor undocumented bug in Dump(). It calls Justify() in the
5116 * case where the last word of the last line of a paragraph is an end-of-
5117 * sentence word (typical) and ends just one blank before the margin
5118 * (rare). This results in one blank being inserted in the line when it's
5119 * not necessary. It happens because the two trailing blanks after the
5120 * word cause an "ordinary" line dump before Fill() sees the next line and
5121 * knows it has an end of paragraph. WARNING: The situation would be
5122 * aggravated if FillWord() ever set blanks to an even larger number.
5126 ** This section contains changes for EUC_4B compatibility.
5127 ** WPI interface is used.
5130 /* Global Variables and extern declarations */
5132 typedef struct _WORD{ /* describe one word */
5133 wint_t *cp; /* word location in buffer */
5134 int inlinenum; /* word start line in input */
5135 int incolumn; /* word start column in input */
5136 int length; /* size of word */
5137 int score; /* word + next for jflag */
5138 int blanks; /* output trailing blanks need */
5139 int wclen; /* Length of wide character word */
5147 /* FORMATTING CONTROL */
5151 int tabsize; /* tab size in use */
5152 int centerstartpara; /* expect para. start? in "Center" */
5154 /* Global/static vars used in "Fill" */
5155 wint_t *wordbuf; /* see comments for "Fill" for discussion */
5172 int indent1, indent2;
5175 #define isekinsoku(wc) iswctype((wc),ekinclass)
5176 #define isbekinsoku(wc) iswctype((wc),bekinclass)
5178 #define LINESIZE BUFSIZ /* how big a line can be */
5179 #define WORDMAX LINESIZE /* see above for discussion */
5181 #define WORDNEXT(d,at) { if (++at == d->wordlimit) at = d->wordbase; } /* statement */
5182 #define WORDPREV(d,at) (((at == d->wordbase) ? d->wordlimit : at) - 1) /* function */
5185 extern int _nl_space_alt;
5189 * Forward declarations
5191 static int DoLine (FormatData *data, FILE *filep);
5192 static void Center (FormatData *data,
5193 wint_t *in_line, wint_t *inlinelim);
5194 static void Fill (FormatData *data, wint_t *in_line, wint_t *inlinelim);
5195 static void FillWord (FormatData *data);
5196 static void Dump (FormatData *data, int endpara);
5197 static void PrintIndent (FormatData *data, int indent);
5198 static void PrintTag (FormatData *data, WORD *wordpast);
5199 static void PrintWords (FormatData *data, WORD *wordpast);
5200 static void Justify (FormatData *data, int blanks, WORD *wordpast);
5201 static int CompareWords (const void *, const void *);
5202 static int EkinBekinProc(FormatData *data, WORD **wordpast);
5203 static void postEkinBekinProc(FormatData *data, int *poutchars, WORD *wordpast);
5207 * A small workaround for systems that don't have wcwidth...
5214 char mbstr[MB_LEN_MAX + 1];
5216 status = wctomb(mbstr, wc);
5219 return(euccol(mbstr));
5226 * The following utilities: lineBlank, findNonBlank, and countBlanks all
5227 * require the lineLen parameter to specify the number of characters, not
5228 * bytes, in the line.
5236 int byteNum, charNum;
5238 size_t mbCurMax = MB_CUR_MAX;
5240 for(byteNum = charNum = 0; charNum < lineLen;
5241 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5243 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5244 #if !(defined(sun) && (_XOPEN_VERSION==3))
5245 if( !iswctype(wc, _DtEditor_blankClass) )
5250 #endif /* not sun */
5260 int byteNum, charNum;
5262 size_t mbCurMax = MB_CUR_MAX;
5264 for(byteNum = charNum = 0; charNum < lineLen;
5265 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5267 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5268 #if !(defined(sun) && (_XOPEN_VERSION==3))
5269 if( !iswctype(wc, _DtEditor_blankClass) )
5270 return &pLine[byteNum];
5273 return &pLine[byteNum];
5274 #endif /* not sun */
5276 return &pLine[byteNum];
5284 int byteNum, charNum, count;
5286 size_t mbCurMax = MB_CUR_MAX;
5288 for(byteNum = charNum = 0, count = 0; charNum < lineLen;
5289 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5291 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5294 if(mblen(&pLine[byteNum], mbCurMax) == 1)
5296 switch((int) pLine[byteNum])
5299 * I don't really know what to do with weird embedded chars.
5300 * This is just a guess. In non-ascii locales this could
5301 * screw up, but I don't know how else to deal with
5302 * weird embedded control characters.
5304 case '\n': /* newline */
5305 case '\f': /* form feed */
5308 case '\t': /* horizontal tab */
5311 case '\b': /* backspace */
5314 case '\r': /* carriage return */
5322 count++; /* multibyte control chars??? */
5325 #if !(defined(sun) && (_XOPEN_VERSION==3))
5326 if(!iswctype(wc, _DtEditor_blankClass))
5331 #endif /* not sun */
5339 * fixLeftMarginAndNewlines - writes out a substring from the text widget,
5340 * inserting leading blanks as needed to set the left margin, and adding
5341 * newlines at all "virtual" (i.e. word-wrapped) lines. It assumes that the
5342 * specified substring is an integer number of lines - i.e. the substring
5343 * cannot begin or end in the middle of a line. Non-complying substrings
5344 * are expanded to encompass whole lines.
5347 fixLeftMarginAndNewlines(
5348 DtEditorWidget editor,
5355 Widget widget = M_text(editor);
5356 XmTextLineTable lineTable;
5358 int lineIndex, lineLen, nextLen, lineIndent, lastIndex,
5359 lineByteLen, total_lines;
5360 Boolean newPara = True;
5361 char *pLine, *pNext, *pFirstNonBlank, *pLastChar;
5362 size_t mbCurMax = MB_CUR_MAX;
5364 lineTable = _XmTextGetLineTable(widget, &total_lines);
5366 if (leftMargin > rightMargin || leftMargin < 0)
5369 lineIndent = leftMargin;
5372 * calculate the starting line number and ending line number
5373 * for the [sub]string we're operating upon.
5375 lineIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), startPos);
5377 lastIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), endPos);
5380 * This loop terminates with one line unwritten. This is correct
5381 * if we're not formatting the last line of the file, as that means
5382 * that we must be formatting a paragraph, and the paragraph adjust
5383 * code has trouble locating the end of a paragraph (as opposed to the
5384 * beginning of the next paragraph. If the last line of the text is
5385 * to be formatted, it is handled after this loop terminates.
5387 for(; lineIndex < lastIndex; lineIndex++)
5390 * if the current line was word-wrapped, put out a nl.
5392 if(lineTable[lineIndex].virt_line)
5393 fwrite("\n", sizeof(char), 1, fp);
5395 lineLen = lineTable[lineIndex + 1].start_pos -
5396 lineTable[lineIndex].start_pos;
5397 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5398 lineTable[lineIndex].start_pos,
5399 lineTable[lineIndex + 1].start_pos, False);
5400 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5401 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5403 if(lineBlank(pLine, lineLen))
5406 * Blank lines indicate the start of a new paragraph.
5407 * They also don't require any indent adjustment so are
5408 * quick/easy to write out.
5410 fwrite( pLine, sizeof(char),
5411 _DtEditorGetPointer(pLine, lineLen) - pLine, fp );
5420 * Calc the proper indent for the first line, and
5421 * the indent for the rest of the lines
5422 * in the paragraph. If there's only one line in the
5423 * paragraph, then the proper indent is adjustStuff.left_margin.
5427 * Get the next line.
5429 if((total_lines - lineIndex) > 2)
5430 nextLen = lineTable[lineIndex + 2].start_pos -
5431 lineTable[lineIndex + 1].start_pos;
5433 nextLen = XmTextGetLastPosition(widget) -
5434 lineTable[lineIndex + 1].start_pos;
5435 pNext = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5436 lineTable[lineIndex + 1].start_pos,
5437 lineTable[lineIndex + 1].start_pos + nextLen, False);
5439 if(lineBlank(pNext, nextLen)) /* single line paragraph */
5440 firstIndent = lineIndent = leftMargin;
5443 int curFirstIndent, curSecondIndent, offset;
5445 curFirstIndent = countBlanks(pLine, lineLen);
5446 curSecondIndent = countBlanks(pNext, nextLen);
5448 offset = curFirstIndent - curSecondIndent;
5451 /* second line is closer to the left margin */
5454 * Note, the first line will still be indented even
5455 * if the remaining words in the paragraph can
5456 * all fit on the first line. The end result is a
5457 * one line indented paragraph. I am mentioning
5458 * this because some may think this is a defect.
5461 firstIndent = leftMargin + offset;
5462 lineIndent = leftMargin;
5466 firstIndent = leftMargin;
5467 lineIndent = leftMargin - offset;
5470 for(i = firstIndent; i-- > 0;)
5471 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5472 pFirstNonBlank = findNonBlank(pLine, lineLen);
5473 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5474 (pFirstNonBlank - pLine), fp);
5480 for(i = lineIndent; i-- > 0;)
5481 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5482 pFirstNonBlank = findNonBlank(pLine, lineLen);
5483 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5484 (pFirstNonBlank - pLine), fp);
5488 if((total_lines - lineIndex) == 1)
5491 * Now we have to handle the last line.
5493 if(lineTable[lineIndex].virt_line)
5494 fwrite("\n", sizeof(char), 1, fp);
5496 if((total_lines - lineIndex) > 2)
5497 lineLen = lineTable[lineIndex + 1].start_pos -
5498 lineTable[lineIndex].start_pos;
5500 lineLen = XmTextGetLastPosition(widget) -
5501 lineTable[lineIndex].start_pos;
5505 for(i = lineIndent; i-- > 0;)
5506 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5508 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5509 lineTable[lineIndex].start_pos,
5510 lineTable[lineIndex].start_pos + lineLen, False);
5511 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5512 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5513 if(lineBlank(pLine, lineLen))
5515 fwrite(pLine, sizeof(char), lineByteLen, fp);
5519 pFirstNonBlank = findNonBlank(pLine, lineLen);
5520 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5521 (pFirstNonBlank - pLine), fp);
5526 XtFree((XtPointer)lineTable);
5530 /************************************************************************
5533 * Initialize, check arguments embedded in AdjRec, open and read files,
5534 * and pass a series of lines to lower-level routines.
5543 long maxmargin; /* max allowed */
5544 FILE *filep; /* file to read */
5549 * INITIALIZE FOR NLS
5551 mbtowc(&data.Blank," ",1);
5554 * Initialize global/statics.
5556 if((data.wordbuf = malloc(sizeof(wint_t) * LINESIZE * 3)) == (wint_t *)NULL)
5558 if((data.word = malloc(sizeof(WORD) * WORDMAX)) == (WORD *)NULL)
5563 data.tabsize = 8; /* default tab size */
5564 data.centerstartpara = True;
5566 data.fillmargin = data.centermiddle = pAdjRec->margin;
5567 data.m0flag = (data.fillmargin == 0L);
5570 * Initialize global/statics for "Fill".
5572 data.wordcp = data.wordbuf;
5573 data.wordcpwrap = data.wordbuf + (LINESIZE * 2);
5574 data.wordbase = & data.word [0];
5575 data.wordlimit = & data.word [WORDMAX];
5576 data.wordfirst = & data.word [0];
5577 data.wordnext = & data.word [0];
5579 data.outlinenum = 1;
5586 if (pAdjRec->cflag + pAdjRec->jflag + pAdjRec->rflag > 1)
5592 maxmargin = pAdjRec->cflag? (LINESIZE / 2) : LINESIZE;
5593 if ((data.fillmargin < 0L) || (data.fillmargin > maxmargin))
5599 if ((pAdjRec->tabsize > 0) && (pAdjRec->tabsize <= MAXTABSIZE))
5600 data.tabsize = pAdjRec->tabsize;
5603 * OPEN AND READ INPUT FILE:
5606 filep = pAdjRec->infp;
5607 data.pAdj = pAdjRec; /* set (file) global var to passed in rec */
5609 while (DoLine (&data, filep))
5613 * DUMP LAST LINE AND EXIT:
5616 if (! data.pAdj->cflag) /* not centering */
5618 Dump (&data, True); /* force end paragraph */
5624 if(data.wordbuf != (wint_t *)NULL)
5628 if(data.word != (WORD *)NULL)
5637 /************************************************************************
5640 * Read one input line and do generic processing (read chars from input
5641 * to in_line, crunching backspaces). Return True if successful, else
5642 * false at end of input file. This must be done before expanding tabs;
5643 * pass half-processed line to Center() or Fill() for more work.
5645 * Assumes getc() is efficient.
5646 * in_line[] is static so it is only allocated once.
5650 DoLine (FormatData *data,
5651 FILE *filep) /* open file to read */
5653 wint_t in_line [LINESIZE]; /* after reading in */
5654 wint_t *incp = in_line; /* place in in_line */
5655 wint_t *incplim = in_line + LINESIZE; /* limit of in_line */
5659 * READ LINE WITH BACKSPACE CRUNCHING:
5662 while (incp < incplim) /* buffer not full */
5664 c = getwc (filep); /* get and save wide char */
5669 if (incp == in_line) /* nothing read yet */
5672 case L'\0': /* fall through */
5673 case L'\n': /* end of line */
5674 incplim = incp; /* set limit (quit loop) */
5677 case L'\b': /* backspace */
5678 if (incp > in_line) /* not at start */
5679 incp--; /* just back up */
5682 default: /* any other char */
5687 /* now incplim is correctly set to last char + 1 */
5690 * PASS LINE ON FOR MORE WORK:
5693 if (data->pAdj->cflag) Center (data, in_line, incplim);
5694 else Fill (data, in_line, incplim);
5696 return (True); /* maybe more to read */
5701 /************************************************************************
5704 * Center text (starting at in_line, ending before inlinelim). First copy
5705 * chars from in_line to outline skipping nonprintables and expanding tabs.
5706 * For efficiency (at the cost of simplicity), note and skip indentation
5707 * at the same time. Then, print outline with indentation to center it.
5709 * outline[] is static so it is only allocated once; startpara so it is
5710 * used for successive lines.
5714 Center (FormatData *data,
5715 wint_t *in_line, /* start of input line */
5716 wint_t *inlinelim) /* end of line + 1 */
5718 wint_t *incp; /* pointer in in_line */
5719 wint_t outline [LINESIZE + MAXTABSIZE]; /* after generic work */
5720 wint_t *outcp = outline; /* place in outline */
5721 wint_t *outlinelim = outline + LINESIZE; /* limit of outline*/
5723 int haveword = False; /* hit word in in_line? */
5724 wint_t ch; /* current working char */
5725 int needsp; /* spaces need for tab */
5726 int indent = 0; /* size of indentation */
5727 int textwidth; /* size of text part */
5728 int extwidth = 0; /* additional width for MBCS */
5735 for (incp = in_line; (incp < inlinelim) && (outcp < outlinelim); incp++)
5746 needsp = ((ch != L'\t') && (iswblank(ch))) ?
5747 1 : data->tabsize - ((indent + outcp - outline) % data->tabsize);
5749 if (! haveword) /* indentation */
5751 else /* past text */
5752 for ( ; needsp > 0; needsp--)
5753 *outcp++ = data->Blank;
5757 * CARRY OVER PRINTABLE CHARS AND NOTE INDENTATION:
5760 else if (iswprint (ch)) /* note: ch != ' ' */
5762 *outcp++ = ch; /* just copy it over */
5764 if(MB_CUR_MAX > 1 && wcwidth(ch) > 1)
5765 extwidth += wcwidth(ch) - 1;
5768 /* else do nothing, which tosses other chars */
5772 /* Now outcp is the new outlinelim */
5775 * HANDLE BLANK LINE (no text):
5780 putc ('\n', data->pAdj->outfp); /* "eat" any whitespace */
5781 data->centerstartpara = True; /* expect new paragraph */
5785 * EAT TRAILING BLANKS, SET TEXTWIDTH:
5790 /* note that outcp > outline */
5791 while ((outcp[-1] != L'\t') && iswblank(outcp [-1]))
5794 textwidth = (outcp - outline); /* thus textwidth > 0 */
5797 * SET AUTOMARGIN AND PRINT CENTERED LINE:
5799 * The equations used depend on truncating division:
5802 * Margin Middle Width Results
5803 * odd exact odd exact centering
5804 * odd exact even extra char to right
5805 * even left odd extra char to left
5806 * even left even exact centering (due to "extra" char to right)
5808 * When centermiddle is default or given by user, it is the same as the
5809 * first two lines above (middle exactly specified).
5812 if (data->centerstartpara) /* start of paragraph */
5814 data->centerstartpara = False;
5816 if (data->m0flag) /* set automargin */
5817 /* 1 */ data->centermiddle = (indent + textwidth + extwidth + 1) / 2;
5820 /* 2 */ PrintIndent (data, data->centermiddle - ((textwidth + extwidth + 1) / 2));
5823 for(i = 0; i < textwidth; i++)
5825 putwc(outline[i], data->pAdj->outfp);
5827 putc('\n', data->pAdj->outfp);
5835 /************************************************************************
5836 * WORD DATA STRUCTURES USED TO TRACK WORDS WHILE FILLING:
5838 * This complicated scheme is used to minimize the actual data moving
5839 * and manipulation needed to do the job.
5841 * Words are kept in wordbuf[] without trailing nulls. It is large enough
5842 * to accommodate two lines' worth of words plus wrap around to start a new
5843 * word (which might be as big as a line) without overwriting old words
5844 * not yet dumped. wordcp -> next free location in wordbuf[];
5845 * wordcpwrap -> last place a new word is allowed to start.
5847 * Words are pointed to and described by word[] structures. The array is
5848 * big enough to accommodate two lines' worth of words, assuming each word
5849 * takes at least two characters (including separator). wordbase and
5850 * wordlimit are the bounds of the array. wordfirst remembers the first
5851 * word in the array not yet printed. wordat is the word being worked on
5852 * after wordnext is advanced (and maybe wrapped around). New elements
5853 * are "allocated" using wordnext, a pointer that is wrapped around as
5856 * inlinenum and incolumn track the current input line and column per
5857 * paragraph. outlinenum tracks the next line to print. All are base 1,
5858 * but inlinenum is preset to zero at the start of each paragraph.
5860 * pendchars tracks the number of dumpable characters accrued so far, to
5861 * trigger dumping. indent1 and indent2 remember the indentations seen
5862 * for the first two lines of each paragraph.
5865 /************************************************************************
5868 * Parse an input line (in_line to inlinelim) into words and trigger
5869 * FillWord() as needed to finish each word, which in turn can call
5870 * Dump() to dump output lines. This routine sacrifices simplicity and
5871 * clarity for efficiency. It uses shared global word data except
5872 * outlinenum and pendchars.
5876 Fill (FormatData *data,
5877 wint_t *in_line, /* start of input line */
5878 wint_t *inlinelim) /* end of line + 1 */
5880 wint_t *incp; /* place in in_line */
5881 wint_t ch; /* current working char */
5882 int haveword = False; /* hit word in in_line? */
5883 int inword = False; /* currently in a word? */
5889 data->incolumn = 1; /* starting a line */
5891 for (incp = in_line; incp < inlinelim; incp++)
5896 * AT WHITE SPACE; FINISH PREVIOUS WORD if any, then skip white space:
5901 if (inword) /* was skipping a word */
5907 data->incolumn += ((ch != L'\t') && (iswblank(ch))) ?
5908 1 : data->tabsize - ((data->incolumn - 1) % data->tabsize);
5912 * AT PART OF WORD; START NEW ONE IF NEEDED:
5915 else if (iswprint (ch))
5917 if (! inword) /* start new word */
5921 if (data->wordcp > data->wordcpwrap)/* past wrap point */
5922 data->wordcp = data->wordbuf;/* wraparound buffer */
5924 data->wordat = data->wordnext;
5925 WORDNEXT (data,data->wordnext);
5927 data->wordat->cp = data->wordcp; /* note start of word */
5928 data->wordat->inlinenum = data->inlinenum; /* note input line */
5929 data->wordat->incolumn = data->incolumn; /* note input column */
5930 data->wordat->wclen = 0;
5936 switch (data->inlinenum)/* note indentations */
5939 data->indent1 = data->incolumn - 1;
5942 data->indent2 = data->incolumn - 1;
5949 * SAVE ONE CHAR OF WORD:
5951 *(data->wordcp++) = ch;
5953 int n = wcwidth(ch);
5956 { /* == 0 for a null char */
5957 data->incolumn += n;
5958 data->wordat->wclen++;
5964 /* else skip other chars by doing nothing */
5969 * END OF LINE; HANDLE BLANK LINE, OR FINISH WORD AND AUTOMARGIN:
5972 if (! haveword) /* no text on line */
5974 data->inlinenum--; /* don't count empty lines */
5975 Dump (data, True); /* force end paragraph */
5976 fputc ('\n', data->pAdj->outfp); /* put this empty line */
5977 data->inlinenum = 0; /* start new paragraph */
5979 else /* have text on line */
5981 if (inword) /* line ends in word */
5983 if (data->pendchars > data->fillmargin)
5984 { /* time to dump line */
5985 Dump (data, False); /* not end of paragraph */
5988 if (data->m0flag && (data->inlinenum == 1)) /* need to note right margin */
5989 data->fillmargin = data->wordat->incolumn + data->wordat->length - 1;
5994 /************************************************************************
5997 * Save values for the word just finished and dump the output line if
5998 * needed. Uses shared global word values, but does not touch outlinenum,
5999 * and only increments pendchars.
6001 * Trailing blanks (1 or 2) needed after a word are figured here.
6002 * wordlen is the total length (nonzero) and wordcp points to the char
6003 * past the end of the word. Two blanks are needed after words ending in:
6005 * <terminal>[<quote>][<close>]
6007 * where <terminal> is any of . : ? !
6008 * <quote> is any of ' "
6009 * <close> is any of ) ] }
6011 * For efficiency, this routine avoids calling others to do character
6012 * matching; it does them in line.
6016 FillWord (FormatData *data)
6018 int wordlen; /* length of word to fill */
6019 int blanks = 1; /* trailing blanks needed */
6020 wint_t ch1, ch2, ch3; /* last chars of word */
6022 data->wordat->length = (data->incolumn - data->wordat->incolumn);
6023 wordlen = data->wordat->wclen;
6026 * CHECK FOR SPECIAL END OF WORD:
6029 ch3 = data->wordcp [-1];
6031 if ((ch3 == L'.') || (ch3 == L':') || (ch3 == L'?') || (ch3 ==L'!'))
6033 blanks = 2; /* <terminal> */
6036 else if (wordlen >= 2)
6038 ch2 = data->wordcp [-2];
6040 if( ((ch2 == L'.') || (ch2 == L':') || (ch2 ==L'?') || (ch2 == L'!')) &&
6041 ((ch3 == L'\'') || (ch3 == L'"') || (ch3 ==L')') || (ch3 == L']')
6045 blanks = 2; /* <terminal><quote or close> */
6047 else if (wordlen >= 3)
6049 ch1 = data->wordcp [-3];
6051 if( ((ch1 == L'.') || (ch1 == L':') || (ch1 == L'?') || (ch1 == L'!'))
6052 && ((ch2 == L'\'') || (ch2 == L'"'))
6053 && ((ch3 == L')') || (ch3 == L']') || (ch3 == L'}')) )
6055 blanks = 2; /* <terminal><quote><close> */
6065 data->pendchars += wordlen + (data->wordat->blanks = blanks);
6070 /************************************************************************
6073 * Print output line(s), with all necessary indentation and formatting,
6074 * if required (at end of paragraph) or if permissible. If required,
6075 * indent1 is used if indent2 is not set yet (not on second line of
6076 * input). Otherwise, if not at end of paragraph, dumping is only
6077 * permissible after beginning the second input line, so fillmargin and
6078 * indent2 are known, so tagged paragraphs are done right.
6080 * Whenever dumping, all "full" lines are dumped, which means more than
6081 * just one may be printed per call. jflag or rflag formatting is
6082 * applied to all lines, except that jflag is ignored for the last line
6083 * of each paragraph.
6085 * Uses shared global word data, but does not touch inlinenum, incolumn,
6086 * indent1, or indent2.
6090 Dump (FormatData *data,
6091 int endpara) /* end of paragraph? */
6093 int haveindent2 = (data->inlinenum >= 2); /* indent2 known? */
6094 int startpara; /* start of paragraph? */
6095 int normal; /* non-tagged line? */
6096 WORD *wordpast = data->wordfirst; /* past last to dump */
6097 int wordlen; /* length of one word */
6098 int indent; /* local value */
6099 int outneed; /* chars need to dump */
6100 int outchars; /* chars found to dump */
6103 * IF DUMPING NEEDED, DUMP LINES TILL DONE:
6106 if (! (endpara || haveindent2)) /* not time to dump */
6109 while ( (data->pendchars > data->fillmargin) /* line is full */
6110 || (endpara && (data->wordfirst != data->wordnext)) ) /* more to dump */
6112 startpara = (data->outlinenum < 2);
6113 indent = (startpara || (! haveindent2)) ? data->indent1 : data->indent2;
6116 * CHECK FOR TAGGED PARAGRAPH if needed:
6119 normal = True; /* default == no tag */
6121 if (startpara && haveindent2 && (data->indent1 < data->indent2))
6123 int incol2 = data->indent2 + 1; /* column needed */
6125 while ( (wordpast != data->wordnext) /* more words */
6126 && (wordpast->inlinenum == 1)) /* from line 1 */
6128 if (wordpast->incolumn == incol2) /* bingo */
6133 WORDNEXT (data,wordpast);
6137 wordpast = data->wordfirst; /* reset value */
6140 * PRINT TAG PART OF TAGGED PARAGRAPH:
6145 WORD *wordat = data->wordfirst; /* local value */
6147 while (wordat != wordpast) /* decrement pendchars */
6149 data->pendchars -= wordat->length + wordat->blanks;
6150 WORDNEXT (data,wordat);
6153 PrintIndent (data, indent);
6154 PrintTag (data, wordpast); /* preceding words */
6155 data->wordfirst = wordpast; /* do rest of line */
6156 indent = data->indent2; /* as if second line */
6161 * FIND WORDS WHICH FIT ON [REST OF] LINE:
6164 if (indent >= data->fillmargin) /* don't over indent */
6165 indent = data->fillmargin - 1;
6167 outneed = data->fillmargin - indent; /* always greater than zero */
6169 wordlen = wordpast->length;
6171 do { /* always consume one */
6172 outchars += wordlen + wordpast->blanks;
6173 WORDNEXT (data,wordpast);
6174 } while ( (wordpast != data->wordnext) /* not last word */
6175 && (outchars + (wordlen = wordpast->length) <= outneed)
6181 ** BEKINSOKU/EKINSOKU PROCESSING
6183 if( EkinBekinProc(data, &wordpast) )
6184 postEkinBekinProc(data, &outchars,wordpast);
6185 data->pendchars -= outchars; /* pendchars to consume */
6187 /* from now on, don't include trailing blanks on last word */
6188 outchars -= (WORDPREV (data,wordpast) -> blanks);
6190 /* now wordfirst and wordpast specify the words to dump */
6192 * PRINT INDENTATION AND PREPARE JUSTIFICATION:
6195 if (data->pAdj->rflag) /* right-justify only */
6197 if (normal) /* nothing printed yet */
6198 PrintIndent (data, data->fillmargin - outchars);
6199 else /* indent + tag printed */
6201 int blanks = data->fillmargin - outchars - indent;
6203 while (blanks-- > 0) /* can't use PrintIndent()*/
6204 putwc(data->Blank, data->pAdj->outfp);
6209 if (normal) /* not already done */
6210 PrintIndent (data, indent);
6212 if (data->pAdj->jflag && ! (endpara && (wordpast == data->wordnext)))
6213 Justify (data, outneed - outchars, wordpast);
6217 * PRINT REST OF LINE:
6220 PrintWords (data, wordpast);
6221 putwc('\n', data->pAdj->outfp);
6222 data->wordfirst = wordpast;
6223 data->outlinenum++; /* affects startpara */
6228 data->outlinenum = 1;
6233 /************************************************************************
6234 * P R I N T I N D E N T
6236 * Print line indentation (if > 0), optionally using tabs where possible.
6237 * Does not print a newline.
6241 PrintIndent (FormatData *data,
6242 int indent) /* leading indentation */
6244 if (indent > 0) /* indentation needed */
6246 if (! data->pAdj->bflag) /* unexpand leading blanks */
6248 while (indent >= data->tabsize)
6250 putc ('\t', data->pAdj->outfp);
6251 indent -= data->tabsize;
6254 fprintf (data->pAdj->outfp, "%*s", indent, "");/*[remaining] blanks */
6259 /************************************************************************
6262 * Print paragraph tag words from word[] array beginning with (global)
6263 * wordfirst and ending before (parameter) wordpast, using input column
6264 * positions in each word's data. Assumes indentation of indent1 was
6265 * already printed on the line. Assumes *wordpast is the next word on
6266 * the line and its column position is valid, and appends spaces up to
6267 * the start of that word. Doesn't print a newline.
6269 * Line indentation must already be done, as this routine doesn't know
6270 * how to print leading tabs, only blanks.
6274 PrintTag (FormatData *data,
6275 WORD *wordpast) /* past last to print */
6277 WORD *wordat = data->wordfirst; /* local value */
6278 int outcol = data->indent1 + 1; /* next column */
6279 int wordcol; /* desired column */
6280 wint_t *wordcp; /* place in word */
6281 wint_t *wordcplim; /* limit of word */
6283 while (True) /* till break */
6285 wordcol = wordat->incolumn;
6287 while (outcol < wordcol)/* space over to word */
6289 putwc(data->Blank, data->pAdj->outfp);
6293 if (wordat == wordpast) /* past last word */
6294 break; /* quit the loop */
6296 wordcp = wordat->cp;
6298 wordcplim = wordcp + wordat->wclen;
6300 while (wordcp < wordcplim) /* print word */
6301 putwc(*wordcp++, data->pAdj->outfp);
6303 outcol += wordat->length;
6304 WORDNEXT (data,wordat);
6309 /************************************************************************
6310 * P R I N T W O R D S
6312 * Print words from word[] array beginning with (global) wordfirst and
6313 * ending before (parameter) wordpast, using word sizes and trailing
6314 * blanks (except for last word on line). Doesn't print a newline.
6318 PrintWords (FormatData *data,
6319 WORD *wordpast) /* past last to print */
6321 WORD *wordat = data->wordfirst; /* local value */
6322 wint_t *wordcp; /* place in word */
6323 wint_t *wordcplim; /* limit of word */
6324 int blanks; /* after a word */
6326 while (True) /* till break */
6328 wordcp = wordat->cp;
6329 wordcplim = wordcp + wordat->wclen;
6330 blanks = wordat->blanks; /* set before do WORDNEXT() */
6332 while (wordcp < wordcplim) /* print word */
6334 putwc(*wordcp++, data->pAdj->outfp);
6338 WORDNEXT (data,wordat);
6340 if (wordat == wordpast) /* just did last word */
6343 while (blanks-- > 0) /* print trailing blanks */
6344 putwc(data->Blank, data->pAdj->outfp);
6350 /************************************************************************
6353 * Do left/right justification of [part of] a line in the word[] array
6354 * beginning with (global) wordfirst and ending before (parameter)
6355 * wordpast, by figuring where to insert blanks.
6357 * Gives each word (except the last on the line) a score based on its
6358 * size plus the size of the next word. Quicksorts word indices into
6359 * order of current trailing blanks (least first), then score (most
6360 * first). Cycles through this list adding trailing blanks to word[]
6361 * entries such that words will space out nicely when printed.
6365 Justify (FormatData *data,
6366 int blanks, /* blanks to insert */
6367 WORD *wordpast) /* past last to print */
6369 WORD *wordat; /* local value */
6370 int sortat; /* place in sort[] */
6371 int wordlen; /* size of this word */
6372 int nextlen; /* size of next word */
6373 int level; /* current blanks level */
6375 WORD *sort [WORDMAX]; /* sorted pointers */
6376 int words; /* words in sort[] */
6378 wordat = WORDPREV (data,wordpast); /* last word on line */
6380 if ((blanks < 1) || (wordat == data->wordfirst))
6381 return; /* can't do anything */
6384 * COMPUTE SCORES FOR WORDS AND SORT INDICES:
6386 * March backwards through the words on line, starting with next to last.
6390 nextlen = wordat->length; /* length of last word */
6392 do { /* always at least one */
6393 wordat = WORDPREV (data,wordat);
6394 wordlen = wordat->length;
6395 wordat->score = wordlen + nextlen; /* this plus next */
6397 sort [words++] = wordat; /* prepare for sorting */
6398 } while (wordat != data->wordfirst);
6400 qsort ((wint_t *) sort, words, sizeof (WORD *), CompareWords);
6403 * ADD TRAILING BLANKS TO PAD OUT WORDS:
6405 * Each pass through the sorted list adds one trailing blank to each word
6406 * not already past the current level. Thus all one-blank words are brought
6407 * up to two; then all twos up to three; etc.
6412 while (True) /* till return */
6416 for (sortat = 0; sortat < words; sortat++)
6418 wordat = sort [sortat];
6419 if (wordat->blanks > level) /* end of this level */
6420 break; /* start next level */
6423 if (--blanks <= 0) /* no more needed */
6431 /************************************************************************
6432 * C O M P A R E W O R D S
6434 * Compare two word[] entries based on pointers to (WORD *), as called
6435 * from qsort(3). Tell which entry has priority for receiving inserted
6436 * blanks (least trailing blanks first, then highest scores), by returning
6437 * -1 for the first entry, +1 for second entry, or 0 if no difference.
6438 * (-1 literally means first entry < second entry, so it sorts first.)
6442 CompareWords (const void *p1, const void *p2)
6444 WORD *word1 = *((WORD **)p1); /* (WORD *) pointers */
6445 WORD *word2 = *((WORD **)p2);
6446 int blanks1 = word1->blanks; /* trailing blanks */
6447 int blanks2 = word2->blanks;
6449 if (blanks1 == blanks2) /* commonest case */
6451 int score1 = word1->score; /* word scores */
6452 int score2 = word2->score;
6454 if (score1 > score2) return (-1); /* word1 has priority */
6455 else if (score1 < score2) return ( 1);
6458 else if (blanks1 < blanks2) return (-1); /* word1 has priority */
6461 } /* CompareWords */
6465 ** BKINSOKU and EKINSOKU processing for Japanese text
6467 ** The function scans the wordlist that are ready for printing
6468 ** and updates the "wordpast" pointer based on the rules of
6469 ** BKINSOKU and EKINSOKU characters.
6471 ** The code does not split a line just after a "gyomatu kinsoku"
6472 ** character and just before a "gyoto kinsoku" character.
6473 ** "Gyomatsu kinsoku" (e-kinsoku) are characters which cannot be
6474 ** placed at the end of a line. "Gyoto kinsoku" (b-kinsoku) are
6475 ** characters which can not be placed at the top of a line.
6477 ** Global variables used:
6478 ** wordfirst - beginning the word list (buffer of pending lines)
6479 ** wordnext - next available spot in the pending buffer (i.e.
6480 ** end of the buffer).
6482 ** Global variables modified:
6486 ** 0 - No Post processing is required.
6487 ** 1 - Post processing is required
6490 #if !(defined(sun) && (_XOPEN_VERSION==3))
6492 EkinBekinProc(FormatData *data,
6495 WORD *curword,*compword,*prevword;
6496 int ekinflag = False, margin;
6499 * curword points to the last word of the first line.
6500 * compword points to the first word of the next line or to the next
6501 * available spot if there is no next line.
6503 compword = *wordpast;
6504 curword = WORDPREV(data,compword);
6507 * If the length of the current word is > fillmargin
6508 * or it is the only word then return.
6510 if (curword->length > data->fillmargin || (curword == data->wordfirst))
6514 * EKINSOKU processing
6515 * If this character set supports ekinclass (can't end a line) char,
6516 * start at the end of the line and search back until
6517 * 1) we find a non-ekinsoku character, or
6518 * 2) come to the beginning of the pending buffer.
6522 while (isekinsoku(*(curword->cp+curword->wclen-1)))
6525 if (curword == data->wordfirst) /* Boundary Condition */
6527 curword = WORDPREV(data,curword);
6531 * Post EKIN processing (i.e. we found an ekinsoku character in
6532 * the line before finding an non-ekinsoku).
6536 if (curword != data->wordfirst) {
6538 * We found a non-ekinsoku after we found the ekinsoku.
6539 * Move the end of line to just after the non-ekinsoku.
6541 WORDNEXT(data,curword);
6542 *wordpast = curword;
6545 else { /* Boundary condition */
6547 * Reached the beginning of the buffer without finding a
6548 * non-ekinsoku. If the last word in the line can begin
6549 * a line (i.e. non-bkinsoku) make it the first word of
6552 curword = WORDPREV(data,compword);
6553 if (!isbekinsoku(*curword->cp)) {
6554 *wordpast = curword;
6563 * If we reached this point then:
6564 * 1) the character set does not support ekinclass characters, or
6565 * 2) the last character in the line is non-ekinsoku.
6566 * Now, need to see if we can begin the next line with the first
6567 * character on that line.
6571 * BEKINSOKU processing
6572 * If this character set supports bekinclass (can't begin a line) char,
6573 * search forward from the begining of the next line (curword) to the
6574 * end of the buffer (wordnext) until:
6575 * 1) A non-bekinsoku word is found,
6576 * 2) if the line limit exceeds the set value, or
6577 * 3) we reach the end of the buffer.
6583 * compword points to the first word of the next line.
6586 margin = data->indent2;
6588 while (curword != data->wordnext)
6590 if (!isbekinsoku(*curword->cp))
6592 margin += (curword->length + curword->blanks);
6593 if (margin >= data->fillmargin)
6595 WORDNEXT(data,curword);
6598 if (curword != data->wordnext && curword != compword)
6601 * The first word of the second line is bekinsoku so search
6602 * backwards from end of first line until we are:
6603 * 1) not at the first word of the buffer, and
6604 * 2) not in between either an ekinsoku or bekinsoku character.
6608 * compword points to the first word of the next line.
6609 * curword points to the last word of the first line.
6611 curword = WORDPREV(data,compword);
6612 prevword = WORDPREV(data,curword);
6613 while ( (curword != data->wordfirst) &&
6614 (isbekinsoku(*curword->cp) ||
6615 isekinsoku(*(prevword->cp+prevword->wclen-1)))
6618 margin += curword->length + curword->blanks;
6619 if (margin >= data->fillmargin)
6622 prevword = WORDPREV(data,curword);
6625 if (curword != data->wordfirst) {
6627 * Did not reach the beginning of the buffer so we are between
6628 * two non-ekinsoku & non-bekinsoku characters. Move the end
6629 * of the first line here.
6632 *wordpast = curword;
6642 } /* end EkinBekinProc */
6647 EkinBekinProc(FormatData *data,
6650 WORD *curword,*compword,*prevword,*nextword;
6651 int margin = data->indent2;
6654 * prevword points to the last word of the first line.
6655 * compword & curword point to the first word of the next line or
6656 * to the next available spot in the buffer if there is no next line.
6658 compword = *wordpast;
6660 prevword = WORDPREV(data,curword);
6663 * If the length of the previous word is > fillmargin
6664 * or it is the only word in the line then return.
6665 * wordfirst points to the beginning of the buffer of pending lines.
6667 if (prevword->length > data->fillmargin || (prevword == data->wordfirst))
6671 * Starting at the beginning of the next line, search backwards
6673 * 1) we find two words we can split between lines, or
6674 * 2) we reach the beginning of the buffer.
6676 * If there is no next line start with the last two words of this line
6677 * (wordnext points to the next available space in the buffer (i.e
6678 * the end of the buffer).
6681 if (curword == data->wordnext) {
6683 prevword = WORDPREV(data,curword);
6686 while ( (curword != data->wordfirst) &&
6687 (wdbindf(*(prevword->cp+prevword->wclen-1), *curword->cp, 1) >4)
6691 prevword = WORDPREV(data,curword);
6694 if (curword != data->wordfirst) {
6697 * Did not reach the beginning of the buffer so we are between
6698 * two non-ekinsoku & non-bekinsoku characters. Move the end
6699 * of the first line here.
6702 *wordpast = curword;
6709 * Reached the beginning of the buffer so search forward
6710 * from the beginning of the second line until:
6711 * 1) we find two words we can split between lines,
6712 * 2) we reach the end of the buffer, or
6713 * 3) the line becomes too long.
6715 * If there is no next line then just exit.
6719 * compword points to the first word of the next line or to the
6720 * next available spot in the buffer if there is no next line.
6721 * nextword points to the second word of the next line.
6722 * wordnext points to the next available space in the buffer (i.e
6723 * the end of the buffer)
6726 nextword = compword;
6727 WORDNEXT(data,nextword);
6729 if (curword == data->wordnext)
6732 while (nextword != data->wordnext)
6735 if (wdbindf(*(curword->cp+curword->wclen-1), *nextword->cp, 1) < 5)
6737 margin += (curword->length + curword->blanks);
6738 if (margin >= data->fillmargin)
6741 WORDNEXT(data,nextword);
6744 if (nextword != data->wordnext) {
6747 * Did not reach the end of the buffer so we are between
6748 * two non-ekinsoku & non-bekinsoku characters. Move the end
6749 * of the first line here.
6751 *wordpast = nextword;
6759 } /* end EkinBekinProc */
6761 #endif /* not sun */
6764 postEkinBekinProc(FormatData *data,
6769 int colvalue,curlineno;
6772 * Recompute the value of *poutchars
6777 curword = data->wordfirst;
6778 while (curword != wordpast)
6780 (*poutchars) += curword->length + curword->blanks;
6781 WORDNEXT(data,curword);
6785 ** Adjust the word parameters -
6786 ** inlinenum,incolumn of all the words
6787 ** from 'curword' till 'wordnext'
6791 curlineno = curword->inlinenum+1;
6792 colvalue = data->indent2;
6793 while (curword != data->wordnext)
6795 curword->inlinenum = curlineno;
6796 curword->incolumn = colvalue;
6797 colvalue += curword->length + curword->blanks;
6798 if (colvalue > data->fillmargin)
6800 colvalue = data->indent2;
6803 WORDNEXT(data,curword);
6805 data->incolumn = colvalue;
6806 data->inlinenum = curlineno;
6819 for (i=0; i < pword->wclen; i++)
6820 fprintf(stderr,(const char *)"%c",(char)*(pword->cp+i));
6821 fprintf(stderr,"Word Length :%d\n",pword->wclen);
6830 caddr_t client_data,
6834 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6835 DtEDITOR_FORMAT_PARAGRAPH );
6837 } /* AdjustParaCB */
6843 caddr_t client_data,
6847 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6848 DtEDITOR_FORMAT_ALL );
6855 * DoAdjust - given left & right margin values & an alignment style, formats
6856 * the text from one specified text position to another.
6859 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
6860 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
6862 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
6864 * DtEDITOR_INVALID_TYPE if specified alignment is
6868 static DtEditorErrorCode
6870 DtEditorWidget editor,
6873 unsigned int alignment,
6874 XmTextPosition start,
6877 char tempName1[L_tmpnam], tempName2[L_tmpnam];
6878 DtEditorErrorCode returnVal;
6882 * Check that valid margin values were passed in
6884 if( leftMargin >= 0 &&
6886 rightMargin < 1025 &&
6887 leftMargin <= rightMargin )
6892 _DtTurnOnHourGlass(M_topLevelShell(editor));
6893 if (M_format_dialog(editor) != (Widget)NULL)
6894 _DtTurnOnHourGlass(M_format_dialog(editor));
6896 memset(&adjRec, 0, sizeof(AdjRec));
6898 /* The adjust text formatting code works with a data
6899 representation to the screen of 1 byte per column for
6900 multibyte environment. The Motif text Widget has a data
6901 representation of 2 bytes per column in multibyte, so we must
6902 fool the adjust code into thinking the margins are twice the
6903 size in a multibyte environment.
6908 rightMargin = rightMargin * 2;
6909 leftMargin = leftMargin * 2;
6914 case DtEDITOR_ALIGN_CENTER:
6917 adjRec.margin = (rightMargin + leftMargin) / 2;
6921 case DtEDITOR_ALIGN_JUSTIFY:
6924 adjRec.margin = rightMargin;
6928 case DtEDITOR_ALIGN_RIGHT:
6931 adjRec.margin = rightMargin;
6935 case DtEDITOR_ALIGN_LEFT:
6937 adjRec.margin = rightMargin;
6943 returnVal = DtEDITOR_INVALID_TYPE;
6949 * Turn off converting leading spaces into tabs if we are
6950 * working in a multi-byte locale. This is necessary
6951 * because a tab may not equal (be as wide as) 8 spaces in
6952 * a multi-byte locale.
6957 adjRec.bflag = True;
6959 adjRec.bflag = False;
6963 * Create the two temp files
6965 (void)tmpnam(tempName1);
6966 (void)tmpnam(tempName2);
6967 if ((adjRec.infp = fopen(tempName1, "w+")) != (FILE *)NULL) {
6970 * Successfully opened the first temporary file
6973 if((adjRec.outfp = fopen(tempName2, "w")) != (FILE *)NULL) {
6976 * Successfully opened the second temporary file, so do the
6979 returnVal = DtEDITOR_NO_ERRORS;
6981 fixLeftMarginAndNewlines( editor, adjRec.infp, leftMargin,
6982 rightMargin, (int)start, (int)end );
6983 fflush(adjRec.infp);
6984 rewind(adjRec.infp);
6986 FormatText(&adjRec);
6988 fclose(adjRec.infp);
6991 fclose(adjRec.outfp);
6993 DtEditorReplaceFromFile( (Widget)editor, start, end, tempName2 );
6999 * Could not open second temporary file, so clean up first one
7001 fclose(adjRec.infp);
7003 returnVal = DtEDITOR_NO_TMP_FILE;
7006 } /* end creating temporary files */
7008 returnVal = DtEDITOR_NO_TMP_FILE;
7013 _DtTurnOffHourGlass(M_topLevelShell(editor));
7014 if (M_format_dialog(editor) != (Widget)NULL)
7015 _DtTurnOffHourGlass(M_format_dialog(editor));
7017 } /* end check for valid margins */
7019 returnVal = DtEDITOR_ILLEGAL_SIZE;
7028 caddr_t client_data,
7031 DtEditorWidget editor = (DtEditorWidget )client_data;
7032 XtUnmanageChild (M_format_dialog(editor));
7038 DtEditorWidget editor)
7040 Dimension text_width, highlight_thickness, shadow_thickness,
7043 Arg al[5]; /* arg list */
7044 int ac; /* arg count */
7047 XtSetArg(al[ac], XmNwidth, &text_width); ac++;
7048 XtSetArg(al[ac], XmNhighlightThickness, &highlight_thickness); ac++;
7049 XtSetArg(al[ac], XmNshadowThickness, &shadow_thickness); ac++;
7050 XtSetArg(al[ac], XmNmarginWidth, &margin_width); ac++;
7051 XtGetValues(M_text(editor), al, ac);
7053 if (M_fontWidth(editor) != 0)
7054 rightMargin = ( (int)text_width -
7055 (2 * ((int)highlight_thickness +
7056 (int)shadow_thickness + (int)margin_width))
7057 ) / M_fontWidth(editor);
7059 rightMargin = (int)text_width -
7060 (2 * ((int)highlight_thickness +
7061 (int)shadow_thickness + (int)margin_width));
7063 return( rightMargin );
7065 } /* end ComputeRightMargin */
7071 XtPointer *client_data,
7072 XConfigureEvent *event )
7075 DtEditorWidget editor = (DtEditorWidget) client_data;
7076 char orgnum[20]; /* original margin size string */
7079 XtSetArg(al[0], XmNwidth, &width);
7080 XtGetValues(M_text(editor), al, 1);
7082 if (width == M_textWidth(editor))
7085 M_textWidth(editor) = width;
7087 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7088 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7091 /************************************************************************
7093 * SetFormatDialogTitle - Change the title for the Format Settings dialog
7095 ************************************************************************/
7098 SetFormatDialogTitle(
7099 DtEditorWidget editor)
7104 * If the Format Settings dialog has been created, change its title
7106 if( M_format_dialog(editor) != (Widget)NULL )
7110 * Prepend the DialogTitle resource, if it has been set
7112 if( E_dialogTitle(editor) != (XmString)NULL ) {
7116 * Add the "functional title" to the DialogTitle
7118 titleStr = XmStringConcat( E_dialogTitle(editor),
7119 E_format_dialogTitle(editor) );
7121 XtSetArg( al[0], XmNdialogTitle, titleStr );
7122 XtSetValues(M_format_dialog(editor), al, 1);
7124 XmStringFree( titleStr );
7128 XtSetArg( al[0], XmNdialogTitle, E_format_dialogTitle(editor) );
7129 XtSetValues(M_format_dialog(editor), al, 1);
7134 } /* end SetFormatDialogTitle */
7136 /************************************************************************
7138 * ResetFormatDialog - Reset margins & alignment of the Format Settings
7141 ************************************************************************/
7145 DtEditorWidget editor)
7147 char orgnum[20]; /* original margin size string */
7150 * Reset the margins to default values
7153 /* Right margin default value */
7154 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7155 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7157 /* Left margin default value */
7158 sprintf(orgnum, "%d", 0);
7159 XmTextFieldSetString(M_format_leftMarginField(editor), orgnum);
7162 * Reset the alignment style to default value
7164 XmToggleButtonGadgetSetState(M_format_leftJust(editor), True, True);
7166 } /* end ResetFormatDialog */
7169 /************************************************************************
7171 * CreateFormatDialog - Create & initialize the Format Settings dialog
7173 ************************************************************************/
7177 DtEditorWidget editor)
7179 Arg al[15]; /* arg list */
7180 int ac; /* arg count */
7181 Pixel textBackground, textForeground;
7182 XmString tempString = (XmString)NULL;
7185 * Match the background & foreground colors of the edit window
7186 * Don't use DtNtextBackground/Foreground directly because they
7187 * will be DtUNSPECIFIED.
7190 XtSetArg(al[ac], XmNforeground, &textForeground); ac++;
7191 XtSetArg(al[ac], XmNbackground, &textBackground); ac++;
7192 XtGetValues(M_text(editor), al, ac);
7197 * First, create the dialog's title, prepending the
7198 * DtNdialogTitle resource, if it is set
7200 if( E_dialogTitle(editor) != (XmString)NULL ) {
7203 * Add the "functional title" to the DialogTitle
7205 tempString = XmStringConcat( E_dialogTitle(editor),
7206 E_format_dialogTitle(editor) );
7207 XtSetArg (al[ac], XmNdialogTitle, tempString ); ac++;
7211 XtSetArg(al[ac], XmNdialogTitle, E_format_dialogTitle(editor)); ac++;
7214 XtSetArg (al[ac], XmNautoUnmanage, False); ac++;
7215 XtSetArg (al[ac], XmNmarginWidth, 5); ac++;
7216 XtSetArg (al[ac], XmNmarginHeight, 5); ac++;
7217 XtSetArg (al[ac], XmNshadowThickness, 1); ac++;
7218 XtSetArg (al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
7219 XtSetArg (al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
7220 M_format_dialog(editor) = XmCreateFormDialog(
7221 M_topLevelShell(editor), "ad_dial", al, ac);
7222 if (tempString != (XmString)NULL)
7223 XmStringFree( tempString );
7225 XtAddCallback(M_format_dialog(editor), XmNhelpCallback,
7226 (XtCallbackProc)HelpFormatDialogCB, (XtPointer)editor);
7230 * When creating the fields & buttons use the appropriate label
7231 * resource (e.g. DtNcenterToggleLabel), if it has been set, then
7232 * clear the resource to save space. The field or button widget
7233 * will contain the actual value & it can be gotten from there,
7236 * If the appropriate resource has not been set, use its default
7237 * value from the message catalog.
7241 * create the left margin label and text field
7245 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED) {
7247 * Use the resource value & clear it (to save space).
7249 tempString = XmStringCopy(E_format_leftMarginFieldLabel(editor));
7250 E_format_leftMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7254 * The resource has not been set so use its default value
7256 tempString = XmStringCreateLocalized(LEFT_MARGIN);
7259 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7260 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7261 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7262 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7263 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7264 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7265 M_format_leftLabel(editor) = (Widget) XmCreateLabelGadget (
7266 M_format_dialog(editor), "left_label", al, ac);
7267 XtManageChild (M_format_leftLabel(editor));
7268 XmStringFree (tempString);
7270 XtAddCallback(M_format_leftLabel(editor), XmNhelpCallback,
7271 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7274 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7275 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7276 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7277 XtSetArg (al[ac], XmNleftWidget, M_format_leftLabel(editor)); ac++;
7278 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7279 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7280 XtSetArg (al[ac], XmNrightPosition, 45); ac++;
7281 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7282 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7283 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7284 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7285 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7286 M_format_leftMarginField(editor) = (Widget) XmCreateTextField (
7287 M_format_dialog(editor), "left_text", al, ac);
7288 XtManageChild (M_format_leftMarginField(editor));
7289 XtAddCallback(M_format_leftMarginField(editor), XmNhelpCallback,
7290 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7292 * create the right margin label and text field
7295 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
7298 * Use the resource value & clear it (to save space).
7300 tempString = XmStringCopy(E_format_rightMarginFieldLabel(editor));
7301 E_format_rightMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7306 * The resource has not been set so use its default value
7308 tempString = XmStringCreateLocalized(RIGHT_MARGIN);
7310 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7311 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7312 XtSetArg (al[ac], XmNleftPosition, 55); ac++;
7313 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7314 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7315 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7316 M_format_rightLabel(editor)= (Widget) XmCreateLabelGadget (
7317 M_format_dialog(editor), "right_label", al, ac);
7318 XtManageChild (M_format_rightLabel(editor));
7319 XmStringFree (tempString);
7320 XtAddCallback(M_format_rightLabel(editor), XmNhelpCallback,
7321 (XtCallbackProc)HelpFormatRightMarginCB,
7324 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7325 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7326 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7327 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7328 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7329 XtSetArg (al[ac], XmNleftWidget, M_format_rightLabel(editor)); ac++;
7330 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7331 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7332 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7333 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7334 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7335 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7336 M_format_rightMarginField(editor) = (Widget) XmCreateTextField (
7337 M_format_dialog(editor),
7338 "right_text", al, ac);
7339 XtManageChild (M_format_rightMarginField(editor));
7340 XtAddCallback(M_format_rightMarginField(editor), XmNhelpCallback,
7341 (XtCallbackProc)HelpFormatRightMarginCB,
7345 * create the radio box for justification choices
7348 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7349 XtSetArg (al[ac], XmNleftOffset, 5); ac++;
7350 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7351 XtSetArg (al[ac], XmNtopWidget, M_format_leftMarginField(editor)); ac++;
7352 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7353 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7354 XtSetArg (al[ac], XmNrightOffset, 5); ac++;
7355 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7356 M_format_radioBox(editor) = (Widget) XmCreateRadioBox(
7357 M_format_dialog(editor), "radioBox", al, ac);
7358 XtAddCallback(M_format_radioBox(editor), XmNhelpCallback,
7359 (XtCallbackProc)HelpFormatJustifyButtonsCB,
7361 XtManageChild(M_format_radioBox(editor));
7363 /* Create Left Align toggle */
7365 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7367 * Use the resource value & clear it (to save space).
7369 tempString = XmStringCopy(E_format_leftAlignToggleLabel(editor));
7370 E_format_leftAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7374 * The resource has not been set so use its default value
7376 tempString = XmStringCreateLocalized(LEFT_ALIGN);
7378 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7379 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7380 M_format_leftJust(editor) = (Widget) XmCreateToggleButtonGadget(
7381 M_format_radioBox(editor), "left_just", al, ac);
7382 XmStringFree (tempString);
7383 XtManageChild(M_format_leftJust(editor));
7385 /* Create Right Align toggle */
7387 if(E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED) {
7389 * Use the resource value & clear it (to save space).
7391 tempString = XmStringCopy(E_format_rightAlignToggleLabel(editor));
7392 E_format_rightAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7396 * The resource has not been set so use its default value
7398 tempString = XmStringCreateLocalized(RIGHT_ALIGN);
7400 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7401 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7402 M_format_rightJust(editor) = (Widget) XmCreateToggleButtonGadget(
7403 M_format_radioBox(editor), "right_just", al, ac);
7404 XmStringFree (tempString);
7405 XtManageChild(M_format_rightJust(editor));
7407 /* Create Justify toggle */
7409 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7411 * Use the resource value & clear it (to save space).
7413 tempString = XmStringCopy(E_format_justifyToggleLabel(editor));
7414 E_format_justifyToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7418 * The resource has not been set so use its default value
7420 tempString = XmStringCreateLocalized( JUSTIFY );
7422 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7423 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7424 M_format_bothJust(editor) = (Widget) XmCreateToggleButtonGadget(
7425 M_format_radioBox(editor), "both_just", al, ac);
7426 XmStringFree (tempString);
7427 XtManageChild(M_format_bothJust(editor));
7429 /* Create Center align toggle */
7431 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7433 * Use the resource value & clear it (to save space).
7435 tempString = XmStringCopy(E_format_centerToggleLabel(editor));
7436 E_format_centerToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7440 * The resource has not been set so use its default value
7442 tempString = XmStringCreateLocalized(CENTER);
7444 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7445 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7446 M_format_center(editor) = (Widget) XmCreateToggleButtonGadget(
7447 M_format_radioBox(editor), "center", al, ac);
7448 XmStringFree(tempString);
7449 XtManageChild(M_format_center(editor));
7451 /* Create a separator between the radio box and buttons */
7454 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7455 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7456 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7457 XtSetArg (al[ac], XmNtopWidget, M_format_radioBox(editor)); ac++;
7458 XtSetArg (al[ac], XmNtopOffset, 15); ac++;
7459 M_format_separator(editor) = (Widget) XmCreateSeparatorGadget (
7460 M_format_dialog(editor), "separator", al, ac);
7461 XtManageChild (M_format_separator(editor));
7463 /* Create Format Paragraph button */
7465 if ( E_format_formatParagraphButtonLabel(editor) !=
7466 (XmString) DtUNSPECIFIED ) {
7468 * Use the resource value & clear it (to save space).
7470 tempString = XmStringCopy(E_format_formatParagraphButtonLabel(editor));
7471 E_format_formatParagraphButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7475 * The resource has not been set so use its default value
7477 tempString = XmStringCreateLocalized(PARAGRAPH);
7479 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7480 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7481 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7482 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7483 XtSetArg (al[ac], XmNrightPosition, 25); ac++;
7484 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7485 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7486 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7487 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7488 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7489 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7490 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7491 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7492 M_format_paragraph(editor) = (Widget) XmCreatePushButtonGadget (
7493 M_format_dialog(editor), "para", al, ac);
7494 XtManageChild (M_format_paragraph(editor));
7495 XmStringFree (tempString);
7496 XtAddCallback (M_format_paragraph(editor), XmNactivateCallback,
7497 (XtCallbackProc) AdjustParaCB, (XtPointer) editor);
7499 /* Create Format All button */
7501 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED) {
7503 * Use the resource value & clear it (to save space).
7505 tempString = XmStringCopy(E_format_formatAllButtonLabel(editor));
7506 E_format_formatAllButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7510 * The resource has not been set so use its default value
7512 tempString = XmStringCreateLocalized(ALL);
7514 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7515 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7516 XtSetArg (al[ac], XmNleftPosition, 27); ac++;
7517 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7518 XtSetArg (al[ac], XmNrightPosition, 49); ac++;
7519 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7520 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7521 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7522 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7523 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7524 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7525 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7526 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7527 M_format_all(editor) = (Widget) XmCreatePushButtonGadget(
7528 M_format_dialog(editor), "all", al, ac);
7529 XtManageChild (M_format_all(editor));
7530 XmStringFree (tempString);
7531 XtAddCallback (M_format_all(editor), XmNactivateCallback,
7532 (XtCallbackProc) AdjustAllCB, (XtPointer) editor);
7534 /* Create Close button */
7535 tempString = XmStringCreateLocalized(CLOSE_BUTTON);
7537 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7538 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7539 XtSetArg (al[ac], XmNleftPosition, 51); ac++;
7540 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7541 XtSetArg (al[ac], XmNrightPosition, 73); ac++;
7542 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7543 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7544 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7545 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7546 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7547 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7548 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7549 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7550 M_format_close(editor) = (Widget) XmCreatePushButtonGadget (
7551 M_format_dialog(editor), "close", al, ac);
7552 XtManageChild (M_format_close(editor));
7553 XmStringFree (tempString);
7554 XtAddCallback (M_format_close(editor), XmNactivateCallback,
7555 (XtCallbackProc) AdjustCloseCB, (XtPointer) editor);
7557 tempString = XmStringCreateLocalized(HELP_BUTTON);
7559 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7560 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7561 XtSetArg (al[ac], XmNleftPosition, 75); ac++;
7562 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7563 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7564 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7565 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7566 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7567 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7568 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7569 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7570 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7571 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7572 M_format_help(editor) = (Widget) XmCreatePushButtonGadget(
7573 M_format_dialog(editor), "help", al, ac);
7574 XtManageChild (M_format_help(editor));
7575 XmStringFree (tempString);
7576 XtAddCallback( M_format_help(editor), XmNactivateCallback,
7577 (XtCallbackProc) HelpFormatDialogCB, (XtPointer) editor);
7580 * set the default/activation button.
7582 XtSetArg(al[0], XmNdefaultButton, M_format_close(editor));
7583 XtSetValues(M_format_dialog(editor), al, 1);
7585 XtRealizeWidget (M_format_dialog(editor));
7588 * Initialize the margins & alignment toggles
7590 ResetFormatDialog(editor);
7592 XtSetArg(al[0], XmNwidth, &(M_textWidth(editor)));
7593 XtGetValues(M_text(editor), al, 1);
7595 XtAddEventHandler(M_text(editor), StructureNotifyMask, False,
7596 (XtEventHandler) UpdateAdjust, (XtPointer) editor);
7598 } /* end CreateFormatDialog */
7600 /************************************************************************
7602 * GetAdjustSettings - Read the alignment settings from the Format
7605 ************************************************************************/
7609 DtEditorWidget editor,
7610 DtEditorFormatSettings *formatSettings)
7613 if( M_format_dialog(editor)!= (Widget)NULL ) {
7616 * Read the current alignment settings from the Format Settings
7622 * Get current type of alignment
7624 if (XmToggleButtonGadgetGetState(M_format_leftJust(editor)))
7625 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7626 else if (XmToggleButtonGadgetGetState(M_format_rightJust(editor)))
7627 formatSettings->alignment = DtEDITOR_ALIGN_RIGHT;
7628 else if (XmToggleButtonGadgetGetState(M_format_bothJust(editor)))
7629 formatSettings->alignment = DtEDITOR_ALIGN_JUSTIFY;
7631 formatSettings->alignment = DtEDITOR_ALIGN_CENTER;
7634 * Get current margin settings
7636 num = (char *) XmTextFieldGetString(
7637 (Widget)M_format_rightMarginField(editor) );
7638 formatSettings->rightMargin = atoi(num);
7640 num = (char *) XmTextFieldGetString(
7641 (Widget)M_format_leftMarginField(editor) );
7642 formatSettings->leftMargin = atoi(num);
7649 * The Format Settings dialog box has not been created so use the
7652 formatSettings->leftMargin = 0;
7653 formatSettings->rightMargin = ComputeRightMargin(editor);
7654 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7659 /****************************************************************
7663 ****************************************************************/
7667 /*********************************************************
7670 * Create an instance of an editor and return the widget id.
7680 return( XtCreateWidget(name,dtEditorWidgetClass,parent,arglist,argcount) );
7684 DtEditorCheckForUnsavedChanges(
7687 DtEditorWidget editor = (DtEditorWidget) widget;
7689 _DtWidgetToAppContext(widget);
7692 result = M_unreadChanges( editor );
7696 } /* end DtEditorCheckForUnsavedChanges */
7700 DtEditorDeleteSelection(
7703 XmTextPosition first, last;
7704 DtEditorWidget editor = (DtEditorWidget) widget;
7706 _DtWidgetToAppContext(widget);
7710 * Check for a non-null selection
7712 if ( XmTextGetSelectionPosition(M_text(editor), &first, &last) &&
7715 XmTextRemove(M_text(editor));
7723 } /* end DtEditorDeleteSelection */
7727 * DtEditorClearSelection replaces the currently selected text with
7728 * spaces. It requires an event because the underlying text widget
7729 * routines require one to look at the time stamp within.
7732 DtEditorClearSelection(
7735 DtEditorWidget editor = (DtEditorWidget) widget;
7736 char *params=(char *)NULL;
7737 Cardinal num_params = 0;
7739 _DtWidgetToAppContext(widget);
7743 * Create an event with a correct timestamp
7745 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7748 * Call routine to clear primary selection
7750 ClearSelection( widget, &event, ¶ms, &num_params );
7754 } /* end DtEditorClearSelection */
7759 * DtEditorDeselect - Unselects any selected text of an Editor widget
7766 DtEditorWidget editor = (DtEditorWidget) widget;
7767 char *params=(char *)NULL;
7768 Cardinal num_params = 0;
7770 _DtWidgetToAppContext(widget);
7774 * Create an event with a correct timestamp
7776 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7778 DeselectAll( widget, &event, ¶ms, &num_params );
7783 } /* end DtEditorDeselect */
7788 * DtEditorDisableRedisplay - Temporarily prevent visual update of a
7793 DtEditorDisableRedisplay(
7796 DtEditorWidget editor = (DtEditorWidget) widget;
7797 _DtWidgetToAppContext(widget);
7800 XmTextDisableRedisplay( M_text(editor) );
7802 } /* end DtEditorDisableRedisplay */
7806 * DtEditorEnableRedisplay - Force visual update of an Editor widget
7810 DtEditorEnableRedisplay(
7813 DtEditorWidget editor = (DtEditorWidget) widget;
7814 _DtWidgetToAppContext(widget);
7817 XmTextEnableRedisplay( M_text(editor) );
7819 } /* end DtEditorEnableRedisplay */
7825 * Given left & right margin values & an alignment style,
7826 * formats either the current paragraph or the entire document,
7827 * as specified. If margin values & alignment style are not
7828 * provided, DtEditorFormat will use the current values from
7829 * the Format Settings dialog.
7832 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
7833 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
7835 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
7837 * DtEDITOR_INVALID_RANGE if specified amount to format is
7839 * DtEDITOR_INVALID_TYPE if specified alignment is
7846 DtEditorFormatSettings *formatSettings,
7847 unsigned int amountToFormat )
7850 DtEditorWidget editor = (DtEditorWidget) widget;
7851 DtEditorErrorCode error;
7852 int leftMargin, rightMargin, alignment;
7853 _DtWidgetToAppContext(widget);
7857 * Check to see if we should use the format settings from the
7858 * Format Settings dialog.
7860 if( formatSettings == (DtEditorFormatSettings *) NULL )
7863 DtEditorFormatSettings tmpFormatSettings;
7866 * Get the format settings from the Format Settings dialog
7868 GetAdjustSettings(editor, &tmpFormatSettings);
7871 * Set up the correct format settings
7873 leftMargin = tmpFormatSettings.leftMargin;
7874 rightMargin = tmpFormatSettings.rightMargin;
7875 alignment = tmpFormatSettings.alignment;
7879 leftMargin = formatSettings->leftMargin;
7880 rightMargin = formatSettings->rightMargin;
7881 alignment = formatSettings->alignment;
7885 * Now, do the formatting
7888 switch (amountToFormat)
7890 case DtEDITOR_FORMAT_ALL:
7892 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7893 0, XmTextGetLastPosition(M_text(editor)) );
7897 case DtEDITOR_FORMAT_PARAGRAPH:
7899 XmTextPosition start, end;
7900 char *params=(char *)NULL;
7901 Cardinal num_params = 0;
7904 * Create an event with a correct timestamp
7907 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7910 * Get the beginning & ending positions of the current paragraph
7912 ForwardPara( widget, &event, ¶ms, &num_params );
7913 end = XmTextGetInsertionPosition(M_text(editor));
7914 if( end != XmTextGetLastPosition(M_text(editor)) ) {
7916 * If we're not at the end, then we need to back up to the
7917 * start of this line, otherwise we'll disturb the first line
7918 * of the following paragraph. If we are at the end, then "end"
7919 * must point to the end of the line, or we'll leave the last
7920 * line along with the formatted text.
7922 BeginningOfLine( widget, &event, ¶ms, &num_params );
7923 end = XmTextGetInsertionPosition(M_text(editor));
7926 BackwardPara( widget, &event, ¶ms, &num_params );
7927 BeginningOfLine( widget, &event, ¶ms, &num_params );
7928 start = XmTextGetInsertionPosition(M_text(editor));
7931 * Pass in beginning & ending positions to adjust the current
7934 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7940 error = DtEDITOR_INVALID_RANGE;
7948 } /* DtEditorFormat */
7953 * DtEditorGetMessageTextFieldID - Returns the widget ID of the Text
7954 * Field used to display application status messages.
7958 DtEditorGetMessageTextFieldID(
7961 DtEditorWidget editor = (DtEditorWidget) widget;
7963 _DtWidgetToAppContext(widget);
7967 * Create the status line if is does not exist
7969 if( M_status_statusArea(editor) == (Widget) NULL )
7970 M_status_statusArea(editor) = CreateStatusLine( editor );
7972 result = M_status_messageText(editor);
7977 } /* end DtEditorGetMessageTextFieldID */
7980 * DtEditorGoToLine moves the insert cursor to the beginning of the
7981 * line specified by lineNumber. It figures out the text character
7982 * position corresponding to the specified line and sets the text
7983 * widget's insertionPosition to that location. If this new
7984 * insertionPosition is not currently on-screen, then the
7985 * text widget's contents are scrolled to display the new position.
7987 * The cursor can be moved to last line by specifying DtEDITOR_LAST_LINE
7988 * as the line number.
7989 * If lineNumber is less than one, the insert cursor will be placed
7990 * at the beginning of the first line. If it is greater than the total
7991 * number of lines, the cursor will be placed at the last line of text.
7995 void DtEditorGoToLine(
7999 DtEditorWidget editor = (DtEditorWidget)widget;
8001 XmTextLineTable lineTab;
8002 XmTextPosition newPos;
8003 _DtWidgetToAppContext(widget);
8006 tw = (XmTextWidget)M_text(editor);
8007 lineTab = tw->text.line_table;
8010 * Validate the specified line number, check it is in range.
8011 * If we adjust the line number, then update the current line display
8012 * in the status line so it reflects where we are really going. This
8013 * is only a problem if lineNumber is less/greater than the first/last
8014 * line becausee we won't be moving the cursor so the status line will
8017 if (lineNumber > tw->text.total_lines || lineNumber == DtEDITOR_LAST_LINE)
8019 lineNumber = tw->text.total_lines;
8020 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8022 else if(lineNumber < 1)
8025 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8030 * Move the insertion cursor
8032 newPos = lineTab[lineNumber - 1].start_pos;
8033 XmTextSetInsertionPosition(M_text(editor), newPos);
8036 * Scroll the widget, if necessary
8038 if (newPos < tw->text.top_character || newPos >= tw->text.bottom_position)
8047 XtSetArg(al[ac], XmNheight, &height); ac++;
8048 XtSetArg(al[ac], XmNrows, &rows); ac++;
8049 XtGetValues(M_text(editor), al, ac);
8051 if(XmTextPosToXY(M_text(editor), newPos, &x, &y) == True)
8053 int offset = (y - height/2) * rows;
8054 XmTextScroll(M_text(editor), offset/(int) height);
8059 } /* end DtEditorGoToLine */
8062 * DtEditorGetEditorSizeHints - Set the resize increment, minimum window
8063 * size, and base dimension properties in the supplied XSizeHints
8064 * struct for the editor as a whole.
8066 * NOTE: This routine returns data in the struct pointed to by pHints.
8070 DtEditorGetSizeHints(
8072 XSizeHints *pHints) /* Return */
8074 Arg al[10]; /* arg list */
8075 int ac; /* arg count */
8076 Dimension FormWidth, FormHeight,
8077 Twidth, Theight, statusHeight,
8078 highlightThickness, shadowThickness,
8079 marginWidth, marginHeight,
8080 textRegionWidth, textRegionHeight;
8082 DtEditorWidget editor = (DtEditorWidget) widget;
8083 _DtWidgetToAppContext(widget);
8087 * Window manager should resize in increments of a character or line.
8089 pHints->width_inc = M_fontWidth(editor);
8090 pHints->height_inc = M_fontHeight(editor);
8093 * Size of the Editor (Form)
8096 FormWidth = editor->core.width + (2 * editor->core.border_width);
8097 FormHeight = editor->core.height + (2 * editor->core.border_width);
8100 * Size of the Edit window (text widget)
8103 XtSetArg(al[ac], XmNwidth, &Twidth); ac++;
8104 XtSetArg(al[ac], XmNheight, &Theight); ac++;
8105 XtSetArg(al[ac], XmNhighlightThickness, &highlightThickness); ac++;
8106 XtSetArg(al[ac], XmNshadowThickness, &shadowThickness); ac++;
8107 XtSetArg(al[ac], XmNmarginWidth, &marginWidth); ac++;
8108 XtSetArg(al[ac], XmNmarginHeight, &marginHeight); ac++;
8109 XtGetValues(M_text(editor), al, ac);
8112 * Calculate the width & height of the area within the text widget
8113 * which can actually display characters.
8115 textRegionWidth = (int)Twidth -
8116 (2 * ((int)highlightThickness +
8117 (int)shadowThickness + (int)marginWidth));
8118 textRegionHeight = (int)Theight -
8119 (2 * ((int)highlightThickness +
8120 (int)shadowThickness + (int)marginHeight));
8123 * Set the base width/height to the size of the area which will not
8124 * display characters.
8126 * The base width/height is used by the window manager in concert
8127 * with the height & width increments to display the current size
8128 * (rows & columns) of edit window (text widget) while resizing the
8131 pHints->base_width = FormWidth - textRegionWidth;
8132 pHints->base_height = FormHeight - textRegionHeight;
8135 * Get the height of the status line, if it is turned on.
8136 * Remember, the border width is not included in the height of the
8137 * status line so add it in to account for the border between the
8138 * edit window (text widget) and the status line.
8141 /* XXX Actually, the statusHeight should already be included in the
8142 * FormHeight, so it should not be necessary to add it in again.
8143 * However, the numbers don't come out right otherwise. Hmmm? */
8145 if( M_status_showStatusLine(editor) == True )
8147 XtSetArg( al[0], XmNheight, &statusHeight );
8148 XtGetValues( M_status_statusArea(editor), al, 1 );
8149 statusHeight = statusHeight + editor->core.border_width;
8155 * What is being returned here is the minimum width & height of the
8156 * editor. Leave room for the scrollbars, shadows, etc., plus one
8159 pHints->min_width = pHints->base_width + pHints->width_inc;
8160 pHints->min_height = pHints->base_width + pHints->height_inc +
8163 pHints->flags = PMinSize | PResizeInc | PBaseSize;
8166 } /* end DtEditorGetSizeHints */
8170 DtEditorInvokeFormatDialog(
8173 DtEditorWidget editor = (DtEditorWidget) widget;
8174 _DtWidgetToAppContext(widget);
8178 * Create the dialog if it is the first time
8180 if (M_format_dialog(editor) == (Widget)NULL)
8181 CreateFormatDialog( editor );
8186 XtUnmanageChild (M_format_dialog(editor));
8187 XtManageChild (M_format_dialog(editor));
8188 XmProcessTraversal(M_format_paragraph(editor), XmTRAVERSE_CURRENT);
8191 } /* DtEditorInvokeFormatDialog */
8198 DtEditorContentRec cr;
8199 DtEditorWidget editor = (DtEditorWidget) widget;
8200 _DtWidgetToAppContext(widget);
8204 * Reset the edit window (includes the Undo context)
8206 cr.type = DtEDITOR_TEXT;
8207 cr.value.string = "";
8208 DtEditorSetContents( widget, &cr );
8211 * Reset the status line
8212 * Note, the current & total line displays are reset by DtEditorSetContents()
8214 if( M_status_statusArea(editor) != (Widget) NULL ) {
8216 XmTextFieldSetString( M_status_messageText(editor), "" );
8221 * Reset the Find/Change & Spell dialogs
8223 if ( M_search_string(editor) )
8224 XtFree(M_search_string(editor));
8225 M_search_string(editor) = (char *)NULL;
8227 if ( M_replace_string(editor) )
8228 XtFree(M_replace_string(editor));
8229 M_replace_string(editor) = (char *)NULL;
8231 if (M_misspelled_string(editor))
8232 XtFree(M_misspelled_string(editor));
8233 M_misspelled_string(editor) = (char *)NULL;
8236 * Reset the Format Settings dialog
8238 if (M_format_dialog(editor) != (Widget)NULL)
8239 ResetFormatDialog(editor);
8242 } /* end DtEditorReset */
8247 * DtEditorSelectAll - Selects the contents of an Editor widget
8254 DtEditorWidget editor = (DtEditorWidget) widget;
8255 char *params=(char *)NULL;
8256 Cardinal num_params = 0;
8258 _DtWidgetToAppContext(widget);
8262 * Create an event with a correct timestamp
8264 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
8266 SelectAll( widget, &event, ¶ms, &num_params );
8270 } /* end DtEditorSelectAll */
8274 DtEditorTraverseToEditor(
8277 DtEditorWidget editor = (DtEditorWidget) widget;
8278 _DtWidgetToAppContext(widget);
8281 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
8284 } /* end DtEditorTraverseToEditor */