2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: Editor.c /main/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 /*-------------------------------------------------------------
55 #if defined(__hpux) || defined(__osf__) || defined(USL)
57 #elif defined(__uxp__)
61 # if (_XOPEN_VERSION==3)
77 #include <limits.h> /* For LINE_MAX definition */
78 #include <sys/errno.h> /* For Error handling */
82 #include "X11/Xutil.h"
83 #include <X11/StringDefs.h>
84 #include <X11/keysymdef.h>
86 #include <Xm/MessageB.h>
87 #include <Xm/MwmUtil.h>
90 /* Need the following for _DtOkString */
93 #include <Dt/DtMsgsP.h>
95 #include "DtWidgetI.h"
98 * Private functions borrowed from Motif.
100 extern XmTextLineTable _XmTextGetLineTable(Widget widget, int *total_lines);
101 extern char * _XmStringSourceGetString(XmTextWidget tw,
104 #if NeedWidePrototypes
108 #endif /* NeedWidePrototypes */
111 /*-------------------------------------------------------------
113 **-------------------------------------------------------------
116 /******** Public Function Declarations ********/
118 /******** End Public Function Declarations ********/
120 /*-------------------------------------------------------------
121 ** Forward Declarations
122 **-------------------------------------------------------------
125 /******** Static Function Declarations ********/
127 static void ClassInitialize(void);
128 static void Initialize(
132 Cardinal *num_args) ;
134 static void VariableInitialize(
137 static void ValidateResources(
139 DtEditorWidget request);
141 static Widget CreateText(
142 DtEditorWidget parent);
144 static void extractFontMetrics(
150 static void getFontMetrics(
156 static void SetStatusLine(
158 Boolean statusLineOn);
160 static Widget CreateStatusLine(
161 DtEditorWidget parent);
163 static Boolean SetValues(
168 static void _DtEditorGetCenterToggleLabel(
173 static void _DtEditorGetChangeAllButtonLabel(
178 static void _DtEditorGetChangeButtonLabel(
183 static void _DtEditorGetChangeFieldLabel(
188 static void _DtEditorGetColumns(
193 static void _DtEditorGetCurrentLineLabel(
198 static void _DtEditorGetCursorPosition(
203 static void _DtEditorGetFindButtonLabel(
208 static void _DtEditorGetFindFieldLabel(
213 static void _DtEditorGetFormatAllButtonLabel(
218 static void _DtEditorGetFormatParagraphButtonLabel(
223 static void _DtEditorGetJustifyToggleLabel(
228 static void _DtEditorGetLeftAlignToggleLabel(
233 static void _DtEditorGetLeftMarginFieldLabel(
238 static void _DtEditorGetMaxLength(
243 static void _DtEditorGetMisspelledListLabel(
248 static void _DtEditorGetRightAlignToggleLabel(
253 static void _DtEditorGetRightMarginFieldLabel(
258 static void _DtEditorGetRows(
263 static void _DtEditorGetScrollLeftSide(
268 static void _DtEditorGetScrollTopSide(
273 static void _DtEditorGetTextBackground(
278 static void _DtEditorGetTextForeground(
283 static void _DtEditorGetTopCharacter(
288 static void _DtEditorGetLineCountLabel(
293 static void FixWordWrap( /* XXX Word Wrap workaround */
294 Widget w, /* XXX Word Wrap workaround */
295 Boolean wrapOn); /* XXX Word Wrap workaround */
297 static void BackwardChar(
301 Cardinal *num_params);
303 static void BackwardPara(
307 Cardinal *num_params);
309 static void BackwardWord(
313 Cardinal *num_params);
315 static void BeginningOfFile(
319 Cardinal *num_params);
321 static void BeginningOfLine(
325 Cardinal *num_params);
327 static void ClearSelection(
331 Cardinal *num_params);
333 static void CopyClipboard(
337 Cardinal *num_params);
339 static void CutClipboard(
343 Cardinal *num_params);
345 static void DeleteNextChar(
349 Cardinal *num_params);
351 static void DeleteNextWord(
355 Cardinal *num_params);
357 static void DeletePrevChar(
361 Cardinal *num_params);
363 static void DeletePrevWord(
367 Cardinal *num_params);
369 static void DeleteToEOL(
373 Cardinal *num_params);
375 static void DeleteToSOL(
379 Cardinal *num_params);
381 static void DeselectAll(
385 Cardinal *num_params);
387 static void EndOfFile(
391 Cardinal *num_params);
393 static void EndOfLine(
397 Cardinal *num_params);
399 static void ForwardChar(
403 Cardinal *num_params);
405 static void ForwardPara(
409 Cardinal *num_params);
411 static void ForwardWord(
415 Cardinal *num_params);
417 static void GoToLine(
421 Cardinal *num_params);
423 static void GoToLine_I(
427 Cardinal *num_params);
433 Cardinal *num_params);
435 static void InsertString(
439 Cardinal *num_params);
441 static void KeySelect(
445 Cardinal *num_params);
447 static void NewlineAndBackup(
451 Cardinal *num_params);
453 static void NewlineAndIndent(
457 Cardinal *num_params);
459 static void NextPage(
463 Cardinal *num_params);
465 static void PageLeft(
469 Cardinal *num_params);
471 static void PageRight(
475 Cardinal *num_params);
477 static void PasteClipboard(
481 Cardinal *num_params);
483 static void PreviousPage(
487 Cardinal *num_params);
489 static void ProcessCancel(
493 Cardinal *num_params);
495 static void ProcessDown(
499 Cardinal *num_params);
501 static void ProcessShiftDown(
505 Cardinal *num_params);
507 static void ProcessShiftUp(
511 Cardinal *num_params);
513 static void ProcessUp(
517 Cardinal *num_params);
519 static void QuoteNextChar(
523 Cardinal *num_params);
525 static void QuoteNextChar_I(
529 Cardinal *num_params);
531 static void SelectAll(
535 Cardinal *num_params);
537 static void ToggleInsertMode(
541 Cardinal *num_params);
543 static void ToggleInsertMode_I(
547 Cardinal *num_params);
549 static void UndoEdit(
553 Cardinal *num_params);
555 static void UndoEdit_I(
559 Cardinal *num_params);
561 static void Call_TextSelectCallback(
562 DtEditorWidget editor);
564 static void Call_TextDeselectCallback(
565 DtEditorWidget editor);
567 static void Editor_SetSelectionProc(
570 XmTextPosition right,
573 static void CallHelpCallback(
574 DtEditorWidget editor,
577 static void HelpEditWindowCB(
582 static void HelpStatusCurrentLineCB(
587 static void HelpStatusTotalLinesCB(
592 static void HelpStatusMessageCB(
597 static void HelpStatusOverstrikeCB(
602 static void RegisterDropZone(
605 static void UnregisterDropZone(
608 static void SetInfoDialogTitle(
609 DtEditorWidget editor );
611 static int FormatText (
614 static void AdjustParaCB(
619 static void AdjustAllCB(
624 static DtEditorErrorCode DoAdjust(
625 DtEditorWidget editor,
628 unsigned int alignment,
629 XmTextPosition start,
632 static void SetFormatDialogTitle(
633 DtEditorWidget editor);
635 static void ResetFormatDialog(
636 DtEditorWidget editor);
638 static void CreateFormatDialog(
639 DtEditorWidget editor);
641 static void GetAdjustSettings(
643 DtEditorFormatSettings *formatSettings);
645 static void UpdateOverstrikeIndicator(
646 DtEditorWidget widget,
647 Boolean overstrikeOn );
649 /******** End Static Function Declarations ********/
652 /****************************************************************
654 * Compatability routines
656 ****************************************************************/
657 #if defined(NO_putwc)
658 static wint_t putwc(wint_t wc, FILE *stream)
660 int rc = putc((int) wc, stream);
664 static wint_t getwc(FILE *stream)
666 int rc = getc(stream);
669 #endif /* NO_putwc */
671 /****************************************************************
673 * Translations and Actions
675 ****************************************************************/
678 * The following are the translations which DtEditor places (overrides)
679 * on the scrolled text widget. If the DtNtextTranslations resource is
680 * set, it will also be added (in override mode) to the text widget.
682 static char EditorTranslationTable[] = "\
683 ~s ~c ~m ~a <Key>Return: newline-and-indent()\n\
684 ~s m<Key>osfBackSpace: I-undo-edit()\n\
685 ~s c<Key>osfBackSpace: delete-previous-word()\n\
686 s<Key>osfBackSpace: delete-to-start-of-line()\n\
687 ~s ~c <Key>osfInsert: I-toggle-insert-mode()\n\
688 <Key>osfUndo: I-undo-edit()\n\
689 c<Key>g: I-go-to-line()\n\
690 c<Key>q: I-quote-next-character()\n\
691 c<Key>z: I-undo-edit()";
694 * The following are DtEditor's actions. A few are internal only (_I
695 * suffix) and will be called by the default translations DtEditor places
696 * on the text widget (see previous comment). The rest will only be called
697 * from an application with XtCallActionProc(). The main difference is
698 * the internal ones will be passed a text widget ID, while the public
699 * ones will be passed a DtEditor ID.
701 static XtActionsRec EditorActionTable[] = {
702 {"I-go-to-line", (XtActionProc)GoToLine_I},
703 {"I-toggle-insert-mode", (XtActionProc)ToggleInsertMode_I},
704 {"I-undo-edit", (XtActionProc)UndoEdit_I},
705 {"I-quote-next-character", (XtActionProc)QuoteNextChar_I},
706 {"backward-character", (XtActionProc)BackwardChar},
707 {"backward-paragraph", (XtActionProc)BackwardPara},
708 {"backward-word", (XtActionProc)BackwardWord},
709 {"beginning-of-file", (XtActionProc)BeginningOfFile},
710 {"beginning-of-line", (XtActionProc)BeginningOfLine},
711 {"clear-selection", (XtActionProc)ClearSelection},
712 {"copy-clipboard", (XtActionProc)CopyClipboard},
713 {"cut-clipboard", (XtActionProc)CutClipboard},
714 {"delete-next-character", (XtActionProc)DeleteNextChar},
715 {"delete-next-word", (XtActionProc)DeleteNextWord},
716 {"delete-previous-character", (XtActionProc)DeletePrevChar},
717 {"delete-previous-word", (XtActionProc)DeletePrevWord},
718 {"delete-to-end-of-line", (XtActionProc)DeleteToEOL},
719 {"delete-to-start-of-line", (XtActionProc)DeleteToSOL},
720 {"deselect-all", (XtActionProc)DeselectAll},
721 {"end-of-file", (XtActionProc)EndOfFile},
722 {"end-of-line", (XtActionProc)EndOfLine},
723 {"forward-character", (XtActionProc)ForwardChar},
724 {"forward-paragraph", (XtActionProc)ForwardPara},
725 {"forward-word", (XtActionProc)ForwardWord},
726 {"go-to-line", (XtActionProc)GoToLine},
727 {"Help", (XtActionProc)Help},
728 {"insert-string", (XtActionProc)InsertString},
729 {"key-select", (XtActionProc)KeySelect},
730 {"newline-and-backup", (XtActionProc)NewlineAndBackup},
731 {"newline-and-indent", (XtActionProc)NewlineAndIndent},
732 {"next-page", (XtActionProc)NextPage},
733 {"page-left", (XtActionProc)PageLeft},
734 {"page-right", (XtActionProc)PageRight},
735 {"paste-clipboard", (XtActionProc)PasteClipboard},
736 {"previous-page", (XtActionProc)PreviousPage},
737 {"process-cancel", (XtActionProc)ProcessCancel},
738 {"process-down", (XtActionProc)ProcessDown},
739 {"process-shift-down", (XtActionProc)ProcessShiftDown},
740 {"process-shift-up", (XtActionProc)ProcessShiftUp},
741 {"process-up", (XtActionProc)ProcessUp},
742 {"quote-next-character", (XtActionProc)QuoteNextChar},
743 {"select-all", (XtActionProc)SelectAll},
744 {"toggle-insert-mode", (XtActionProc)ToggleInsertMode},
745 {"undo-edit", (XtActionProc)UndoEdit},
749 /****************************************************************
753 ****************************************************************/
758 #define iswctype(a,b) is_wctype(a,b)
759 #define wctype(a) get_wctype(a)
762 #if !(defined(sun) && (_XOPEN_VERSION==3))
763 # define iswblank(wc) iswctype((wc),blnkclass)
764 # undef getwc /* Use the libc function */
765 #if defined(__osf__) || defined(_AIX) /* __osf__ || _AIX */
766 /* function prototype for wctype() was changed to meet spec1170 */
767 /* digital compiler flagged warning */
768 /* IBM defines wctype to get_wctype above - don't use const. */
769 static char *blankString = "space";
771 # define wctype_t int
772 #else /* __osf__ || _AIX */
773 static const char *blankString = "space";
774 #endif /* __osf__ || _AIX */
775 static wctype_t _DtEditor_blankClass;
777 # define wctype_t int
778 # if defined(__uxp__)
779 # if (OSMAJORVERSION < 2)
780 typedef long wint_t ;
785 # define iswblank(a) iswspace(a)
786 # if !defined(__uxp__)
787 # define iswctype(a,b) _iswctype(a,b)
789 # if defined(__uxp__)
790 # define wcwidth(a) scrwidth(a)
792 # define wcwidth(a) sun_wcwidth(a)
794 #endif /* not sun and not uxp */
796 #define MAXTABSIZE 100 /* max legal tabsize */
799 /****************************************************************
801 * Define misc data structures
803 ****************************************************************/
805 static wctype_t ekinclass = 0; /* Prop value for "ekinsoku" class */
806 static wctype_t bekinclass = 0; /* Prop value for "bekinsoku" class */
807 static wctype_t blnkclass = 0; /* Prop value for "Blank" Class */
809 /****************************************************************
813 ****************************************************************/
815 static XmSyntheticResource syn_resources[] =
819 DtNcolumns, sizeof(short),
820 XtOffset (DtEditorWidget, editor.editStuff.columns),
821 _DtEditorGetColumns, NULL
824 DtNcenterToggleLabel, sizeof (XmString),
825 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
826 _DtEditorGetCenterToggleLabel, NULL
829 DtNchangeAllButtonLabel, sizeof (XmString),
830 XtOffset (DtEditorWidget,
831 editor.searchStuff.changeAllButtonLabel),
832 _DtEditorGetChangeAllButtonLabel, NULL
835 DtNchangeButtonLabel, sizeof (XmString),
836 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
837 _DtEditorGetChangeButtonLabel, NULL
840 DtNchangeFieldLabel, sizeof (XmString),
841 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
842 _DtEditorGetChangeFieldLabel, NULL
845 DtNcurrentLineLabel, sizeof (XmString),
846 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
847 _DtEditorGetCurrentLineLabel, NULL
850 DtNcursorPosition, sizeof (XmTextPosition),
851 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
852 _DtEditorGetCursorPosition, NULL
855 DtNfindButtonLabel, sizeof (XmString),
856 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
857 _DtEditorGetFindButtonLabel, NULL
860 DtNfindFieldLabel, sizeof (XmString),
861 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
862 _DtEditorGetFindFieldLabel, NULL
865 DtNformatAllButtonLabel, sizeof (XmString),
866 XtOffset(DtEditorWidget,
867 editor.formatStuff.formatAllButtonLabel),
868 _DtEditorGetFormatAllButtonLabel, NULL
871 DtNformatParagraphButtonLabel, sizeof (XmString),
872 XtOffset(DtEditorWidget,
873 editor.formatStuff.formatParaButtonLabel),
874 _DtEditorGetFormatParagraphButtonLabel, NULL
877 DtNjustifyToggleLabel, sizeof (XmString),
878 XtOffset (DtEditorWidget,
879 editor.formatStuff.justifyToggleLabel),
880 _DtEditorGetJustifyToggleLabel, NULL
883 DtNleftAlignToggleLabel, sizeof (XmString),
884 XtOffset (DtEditorWidget,
885 editor.formatStuff.leftAlignToggleLabel),
886 _DtEditorGetLeftAlignToggleLabel, NULL
889 DtNleftMarginFieldLabel, sizeof (XmString),
890 XtOffset (DtEditorWidget,
891 editor.formatStuff.leftMarginFieldLabel),
892 _DtEditorGetLeftMarginFieldLabel, NULL
895 DtNmaxLength, sizeof(int),
896 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
897 _DtEditorGetMaxLength, NULL
900 DtNmisspelledListLabel, sizeof (XmString),
901 XtOffset (DtEditorWidget,
902 editor.searchStuff.misspelledListLabel),
903 _DtEditorGetMisspelledListLabel, NULL
906 DtNrightAlignToggleLabel, sizeof (XmString),
907 XtOffset (DtEditorWidget,
908 editor.formatStuff.rightAlignToggleLabel),
909 _DtEditorGetRightAlignToggleLabel, NULL
912 DtNrightMarginFieldLabel, sizeof (XmString),
913 XtOffset (DtEditorWidget,
914 editor.formatStuff.rightMarginFieldLabel),
915 _DtEditorGetRightMarginFieldLabel, NULL
918 DtNrows, sizeof(short),
919 XtOffset (DtEditorWidget, editor.editStuff.rows),
920 _DtEditorGetRows, NULL
923 DtNscrollLeftSide, sizeof (Boolean),
924 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
925 _DtEditorGetScrollLeftSide, NULL
928 DtNscrollTopSide, sizeof (Boolean),
929 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
930 _DtEditorGetScrollTopSide, NULL
933 DtNtextBackground, sizeof(Pixel),
934 XtOffset (DtEditorWidget, editor.editStuff.background),
935 _DtEditorGetTextBackground, NULL
938 DtNtextForeground, sizeof(Pixel),
939 XtOffset (DtEditorWidget, editor.editStuff.foreground),
940 _DtEditorGetTextForeground, NULL
943 DtNtopCharacter, sizeof(XmTextPosition),
944 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
945 _DtEditorGetTopCharacter, NULL
948 DtNtotalLineCountLabel, sizeof (XmString),
949 XtOffset (DtEditorWidget, editor.statusStuff.totalLineLabel),
950 _DtEditorGetLineCountLabel, NULL
954 static XtResource resources[] =
957 DtNautoShowCursorPosition,
958 DtCAutoShowCursorPosition, XmRBoolean, sizeof (Boolean),
959 XtOffset(DtEditorWidget,
960 editor.editStuff.autoShowCursorPos),
961 XmRImmediate, (XtPointer) True
964 DtNbuttonFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
965 XtOffsetOf(struct _XmBulletinBoardRec,
966 bulletin_board.button_font_list),
967 XmRFontList, (XtPointer) NULL
970 DtNblinkRate, DtCBlinkRate, XmRInt, sizeof(int),
971 XtOffset(DtEditorWidget, editor.editStuff.blinkRate),
972 XmRImmediate, (XtPointer) 500
975 DtNcenterToggleLabel, DtCCenterToggleLabel,
976 XmRXmString, sizeof (XmString),
977 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
978 XmRImmediate, (XtPointer) DtUNSPECIFIED
981 DtNchangeAllButtonLabel, DtCChangeAllButtonLabel,
982 XmRXmString, sizeof (XmString),
983 XtOffset (DtEditorWidget,
984 editor.searchStuff.changeAllButtonLabel),
985 XmRImmediate, (XtPointer) DtUNSPECIFIED
988 DtNchangeButtonLabel, DtCChangeButtonLabel,
989 XmRXmString, sizeof (XmString),
990 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
991 XmRImmediate, (XtPointer) DtUNSPECIFIED
994 DtNchangeFieldLabel, DtCChangeFieldLabel,
995 XmRXmString, sizeof (XmString),
996 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
997 XmRImmediate, (XtPointer) DtUNSPECIFIED
1000 DtNcolumns, DtCColumns, XmRShort, sizeof(short),
1001 XtOffset (DtEditorWidget, editor.editStuff.columns),
1002 XmRImmediate, (XtPointer) DtUNSPECIFIED
1005 DtNcurrentLineLabel, DtCCurrentLineLabel,
1006 XmRXmString, sizeof (XmString),
1007 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
1008 XmRImmediate, (XtPointer) DtUNSPECIFIED
1011 DtNcursorPosition, DtCCursorPosition, XmRTextPosition,
1012 sizeof (XmTextPosition),
1013 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
1014 XmRImmediate, (XtPointer) DtUNSPECIFIED
1017 DtNcursorPositionVisible, DtCCursorPositionVisible,
1018 XmRBoolean, sizeof (Boolean),
1019 XtOffset(DtEditorWidget,
1020 editor.editStuff.cursorPosVisible),
1021 XmRImmediate, (XtPointer) True
1024 DtNdialogTitle, DtCDialogTitle, XmRXmString, sizeof (XmString),
1025 XtOffsetOf(struct _XmBulletinBoardRec,
1026 bulletin_board.dialog_title),
1027 XmRString, (XtPointer) NULL
1030 DtNeditable, DtCEditable, XmRBoolean, sizeof (Boolean),
1031 XtOffset (DtEditorWidget, editor.editStuff.editable),
1032 XmRImmediate, (XtPointer) True
1035 DtNfindButtonLabel, DtCFindButtonLabel,
1036 XmRXmString, sizeof (XmString),
1037 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
1038 XmRImmediate, (XtPointer) DtUNSPECIFIED
1041 DtNfindChangeDialogTitle, DtCFindChangeDialogTitle,
1042 XmRXmString, sizeof (XmString),
1043 XtOffset(DtEditorWidget, editor.searchStuff.fndChngTitle),
1044 XmRString, (XtPointer) NULL
1047 DtNfindFieldLabel, DtCFindFieldLabel,
1048 XmRXmString, sizeof (XmString),
1049 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
1050 XmRImmediate, (XtPointer) DtUNSPECIFIED
1053 DtNformatAllButtonLabel, DtCFormatAllButtonLabel,
1054 XmRXmString, sizeof (XmString),
1055 XtOffset(DtEditorWidget,
1056 editor.formatStuff.formatAllButtonLabel),
1057 XmRImmediate, (XtPointer) DtUNSPECIFIED
1060 DtNformatParagraphButtonLabel, DtCFormatParagraphButtonLabel,
1061 XmRXmString, sizeof (XmString),
1062 XtOffset(DtEditorWidget,
1063 editor.formatStuff.formatParaButtonLabel),
1064 XmRImmediate, (XtPointer) DtUNSPECIFIED
1067 DtNformatSettingsDialogTitle, DtCFormatSettingsDialogTitle,
1068 XmRXmString, sizeof (XmString),
1069 XtOffset(DtEditorWidget, editor.formatStuff.formatDialogTitle),
1070 XmRString, (XtPointer) NULL
1073 DtNinformationDialogTitle, DtCInformationDialogTitle,
1074 XmRXmString, sizeof (XmString),
1075 XtOffset(DtEditorWidget, editor.warningStuff.infoDialogTitle),
1076 XmRString, (XtPointer) NULL
1079 DtNinsertLabel, DtCInsertLabel, XmRXmString, sizeof (XmString),
1080 XtOffset (DtEditorWidget, editor.statusStuff.ins),
1081 XmRImmediate, (XtPointer) DtUNSPECIFIED
1084 DtNjustifyToggleLabel, DtCJustifyToggleLabel,
1085 XmRXmString, sizeof (XmString),
1086 XtOffset(DtEditorWidget, editor.formatStuff.justifyToggleLabel),
1087 XmRImmediate, (XtPointer) DtUNSPECIFIED
1090 DtNlabelFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1091 XtOffsetOf(struct _XmBulletinBoardRec,
1092 bulletin_board.label_font_list),
1093 XmRFontList, (XtPointer) NULL
1096 DtNleftAlignToggleLabel, DtCLeftAlignToggleLabel,
1097 XmRXmString, sizeof (XmString),
1098 XtOffset(DtEditorWidget,
1099 editor.formatStuff.leftAlignToggleLabel),
1100 XmRImmediate, (XtPointer) DtUNSPECIFIED
1103 DtNleftMarginFieldLabel, DtCLeftMarginFieldLabel,
1104 XmRXmString, sizeof (XmString),
1105 XtOffset(DtEditorWidget,
1106 editor.formatStuff.leftMarginFieldLabel),
1107 XmRImmediate, (XtPointer) DtUNSPECIFIED
1110 DtNmaxLength, DtCMaxLength, XmRInt, sizeof(int),
1111 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
1112 XmRImmediate, (XtPointer) DtUNSPECIFIED
1115 DtNmisspelledListLabel, DtCMisspelledListLabel,
1116 XmRXmString, sizeof (XmString),
1117 XtOffset (DtEditorWidget,
1118 editor.searchStuff.misspelledListLabel),
1119 XmRImmediate, (XtPointer) DtUNSPECIFIED
1122 DtNoverstrike, DtCOverstrike, XmRBoolean, sizeof (Boolean),
1123 XtOffset(DtEditorWidget, editor.editStuff.overstrikeMode),
1124 XmRImmediate, (XtPointer) False
1127 DtNoverstrikeLabel, DtCOverstrikeLabel,
1128 XmRXmString, sizeof (XmString),
1129 XtOffset (DtEditorWidget, editor.statusStuff.ovr),
1130 XmRImmediate, (XtPointer) DtUNSPECIFIED
1133 DtNrightAlignToggleLabel, DtCRightAlignToggleLabel,
1134 XmRXmString, sizeof (XmString),
1135 XtOffset(DtEditorWidget,
1136 editor.formatStuff.rightAlignToggleLabel),
1137 XmRImmediate, (XtPointer) DtUNSPECIFIED
1140 DtNrightMarginFieldLabel, DtCRightMarginFieldLabel,
1141 XmRXmString, sizeof (XmString),
1142 XtOffset(DtEditorWidget,
1143 editor.formatStuff.rightMarginFieldLabel),
1144 XmRImmediate, (XtPointer) DtUNSPECIFIED
1147 DtNrows, DtCRows, XmRShort, sizeof(short),
1148 XtOffset (DtEditorWidget, editor.editStuff.rows),
1149 XmRImmediate, (XtPointer) DtUNSPECIFIED
1152 DtNscrollHorizontal, DtCScroll, XmRBoolean, sizeof (Boolean),
1153 XtOffset (DtEditorWidget, editor.editStuff.scrollHorizontal),
1154 XmRImmediate, (XtPointer) True
1157 DtNscrollLeftSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1158 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
1159 XmRImmediate, (XtPointer) DtUNSPECIFIED
1162 DtNscrollTopSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1163 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
1164 XmRImmediate, (XtPointer) DtUNSPECIFIED
1167 DtNscrollVertical, DtCScroll, XmRBoolean, sizeof (Boolean),
1168 XtOffset (DtEditorWidget, editor.editStuff.scrollVertical),
1169 XmRImmediate, (XtPointer) True
1173 DtCShowStatusLine, XmRBoolean, sizeof (Boolean),
1174 XtOffset (DtEditorWidget, editor.statusStuff.showStatusLine),
1175 XmRImmediate, (XtPointer) False
1178 DtNspellDialogTitle, DtCSpellDialogTitle,
1179 XmRXmString, sizeof (XmString),
1180 XtOffset(DtEditorWidget, editor.searchStuff.spellTitle),
1181 XmRString, (XtPointer) NULL
1184 DtNspellFilter, DtCSpellFilter, XmRString, sizeof(XmRString),
1185 XtOffset (DtEditorWidget, editor.searchStuff.spellFilter),
1189 DtNtextBackground, DtCBackground,
1190 XmRPixel, sizeof(Pixel),
1191 XtOffset (DtEditorWidget, editor.editStuff.background),
1192 XmRImmediate, (XtPointer) DtUNSPECIFIED
1195 DtNtextDeselectCallback,
1196 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1197 XtOffset (DtEditorWidget, editor.textDeselect),
1198 XtRCallback, (XtPointer) NULL
1201 DtNtextForeground, DtCForeground,
1202 XmRPixel, sizeof(Pixel),
1203 XtOffset (DtEditorWidget, editor.editStuff.foreground),
1204 XmRImmediate, (XtPointer) DtUNSPECIFIED
1207 DtNtextFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1208 XtOffsetOf(struct _XmBulletinBoardRec,
1209 bulletin_board.text_font_list),
1210 XmRFontList, (XtPointer) NULL
1213 DtNtextSelectCallback,
1214 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1215 XtOffset (DtEditorWidget, editor.textSelect),
1216 XtRCallback, (XtPointer) NULL
1219 DtNtextTranslations, DtCTranslations,
1220 XmRTranslationTable, sizeof (XtTranslations),
1221 XtOffsetOf(struct _XmBulletinBoardRec,
1222 bulletin_board.text_translations),
1223 XmRImmediate, (XtPointer) NULL
1226 DtNtopCharacter, DtCTopCharacter,
1227 XmRTextPosition, sizeof(XmTextPosition),
1228 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
1229 XmRImmediate, (XtPointer) DtUNSPECIFIED
1232 DtNtotalLineCountLabel, DtCTotalLineCountLabel,
1233 XmRXmString, sizeof (XmString),
1234 XtOffset (DtEditorWidget,
1235 editor.statusStuff.totalLineLabel),
1236 XmRImmediate, (XtPointer) DtUNSPECIFIED
1240 DtCWordWrap, XmRBoolean, sizeof (Boolean),
1241 XtOffset (DtEditorWidget, editor.editStuff.wordWrap),
1242 XmRImmediate, (XtPointer) False
1246 /****************************************************************
1248 * Public Function Declarations
1250 ****************************************************************/
1252 /****************************************************************
1256 ****************************************************************/
1258 externaldef( dteditorclassrec ) DtEditorClassRec
1264 (WidgetClass) &xmFormClassRec, /* superclass */
1265 "DtEditor", /* class_name */
1266 sizeof (DtEditorRec), /* widget_size */
1267 ClassInitialize, /* class_initialize */
1268 NULL, /* class_part_initialize*/
1269 False, /* class_inited */
1270 (XtInitProc) Initialize, /* initialize */
1271 NULL, /* initialize_hook */
1272 XtInheritRealize, /* realize */
1273 (XtActionList)EditorActionTable,/* actions */
1274 (Cardinal)XtNumber(EditorActionTable), /* num_actions */
1275 resources, /* resources */
1276 XtNumber (resources), /* num_resources */
1277 NULLQUARK, /* xrm_class */
1278 True, /* compress_motion */
1279 XtExposeCompressMaximal, /* compress_exposure */
1280 False, /* compress_enterleave */
1281 False, /* visible_interest */
1282 (XtWidgetProc) Destroy, /* destroy */
1283 XtInheritResize, /* resize */
1284 XtInheritExpose, /* expose */
1285 (XtSetValuesFunc) SetValues, /* set_values */
1286 NULL, /* set_values_hook */
1287 XtInheritSetValuesAlmost, /* set_values_almost */
1288 NULL, /* get_values_hook */
1289 XtInheritAcceptFocus, /* accept_focus */
1290 XtVersion, /* version */
1291 NULL, /* callback private */
1292 XtInheritTranslations, /* tm_table */
1293 XtInheritQueryGeometry, /* query_geometry */
1294 (XtStringProc)NULL, /* display_accelerator */
1295 NULL, /* extension */
1301 XtInheritGeometryManager, /* geometry_manager */
1302 XtInheritChangeManaged, /* change_managed */
1303 XtInheritInsertChild, /* insert_child */
1304 XtInheritDeleteChild, /* delete_child */
1305 NULL, /* extension */
1312 NULL, /* constraint_resources */
1313 0, /* num_constraint_resource */
1314 sizeof(XmFormConstraintRec), /* size of constraint */
1315 NULL, /* initialization */
1316 NULL, /* constraint_destroy */
1317 NULL, /* constraint_set_values */
1318 NULL, /* extension */
1324 XmInheritTranslations, /* default_translations */
1325 syn_resources, /* syn_resources */
1326 XtNumber(syn_resources), /* num_syn_resources */
1327 NULL, /* syn_cont_resources */
1328 0, /* num_syn_cont_resources */
1329 XmInheritParentProcess, /* parent_process */
1330 NULL, /* extension */
1333 /* XmbulletinBoard Part
1336 FALSE, /* always_install_accelerators */
1337 (XmGeoCreateProc)NULL, /* geo_matrix_create */
1338 XmInheritFocusMovedProc, /* focus_moved_proc */
1339 NULL, /* extension */
1345 (int) NULL, /* extension */
1351 (int) NULL, /* extension */
1355 WidgetClass dtEditorWidgetClass = (WidgetClass) &dtEditorClassRec;
1357 /*-------------------------------------------------------------
1359 **-------------------------------------------------------------
1362 /****************************************************************
1366 ****************************************************************/
1369 /*-------------------------------------------------------------
1370 ** Function: static void ClassInitialize (void);
1374 ** Purpose: This is the Editor class initializzation routine.
1375 ** It is called once, before the first instance
1379 ClassInitialize(void)
1381 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
1382 _DtEditor_blankClass = wctype(blankString);
1385 ** These calls determine if the particular value is True for
1386 ** the current locale. A value of -1 is returned if the locale
1387 ** does not support the charclass. If the locale supports the
1388 ** charclass, the return value is passed as a parameter to the
1391 ekinclass = wctype("ekinsoku");
1392 bekinclass = wctype("bkinsoku");
1393 blnkclass = wctype("blank");
1394 #endif /* end not Sun */
1398 /*-------------------------------------------------------------
1399 ** Function: static void Initialize (
1402 ** ArgList arg_list,
1403 ** Cardinal *num_args)
1407 ** Purpose: This is the Editor widget initialize routine.
1408 ** It is responsible for the following:
1409 ** 1) Validate all resources the user passed in,
1410 ** 2) Override any invalid resources,
1411 ** 3) Initialize the internal data structures,
1412 ** 4) Create the edit area widget
1413 ** 5) Create the status area widget, if requested
1414 ** 6) Add any callbacks and actions
1424 DtEditorWidget request = (DtEditorWidget) rw,
1425 new = (DtEditorWidget) nw;
1427 /* Initialize non-resource portion of the instance structure */
1428 VariableInitialize (new);
1430 /* Validate the incoming arguments to make sure they are OK */
1431 ValidateResources (new, request);
1434 * Create & customize the scrolled text widget
1436 M_text(new) = CreateText (new);
1437 XtManageChild( M_text(new)) ;
1440 * If the widget is not "read only" then register it as a drop zone
1442 if ( M_editable(new) == True )
1443 RegisterDropZone( new );
1446 * Compute the width & height of the scrolled text's font. These values
1447 * will be used when formatting and in calculating the window manager
1450 getFontMetrics(new);
1453 * Create the status line
1455 SetStatusLine( new, M_status_showStatusLine(request) );
1458 } /* end Initialize */
1461 /*-------------------------------------------------------------
1462 ** Function: static void VariableInitialize (
1463 ** DtEditorWidget new )
1465 ** Parameters: The Editor widget being created
1467 ** Purpose: This routine:
1468 ** 1) Initializes the widget's instance structure
1477 * Initialize the non-resource instance fields
1480 M_display(new) = XtDisplayOfObject( (Widget)new->core.parent );
1481 M_app_context(new) = XtDisplayToApplicationContext(M_display(new));
1484 * Empty 'for' walks up the widget tree to find a shell.
1486 for (thisParent = new->core.parent;
1487 thisParent != (Widget)NULL && XtIsShell(thisParent) == False;
1488 thisParent = XtParent(thisParent));
1489 M_topLevelShell(new) = thisParent;
1491 /* Initialize edit area fields */
1492 M_loadingAllNewData(new) = False;
1493 M_unreadChanges(new) = False; /* There have not been any changes since */
1494 /* the app requested the data */
1495 M_deletionStart(new) = NO_DELETION_IN_PROGRESS;
1496 M_deletedText(new) = (char *)NULL;
1497 M_insertStart(new) = 0;
1498 M_insertionLength(new) = 0;
1499 M_textSelectCbCalled(new) = False;
1500 M_fontWidth(new) = -1;
1502 /* Initialize status line fields */
1503 M_status_statusArea(new) = (Widget)NULL;
1504 M_status_messageText(new) = (Widget)NULL;
1505 M_status_currentLine(new) = -1;
1506 M_status_lastLine(new) = -1;
1508 /* Initialize search function data */
1509 M_search_dialog(new) = (Widget) NULL;
1510 M_search_dialogMode(new) = SPELL;
1511 M_search_string(new) = (char *)NULL;
1512 M_replace_string(new) = (char *)NULL;
1513 M_misspelled_string(new) = (char *)NULL;
1514 M_misspelled_found(new) = False;
1516 /* Initialize format function data */
1517 M_format_dialog(new) = (Widget)NULL;
1519 /* Initialize warning dialogs data */
1520 M_gen_warning(new) = (Widget)NULL;
1522 } /* end VariableInitialize */
1525 /*-------------------------------------------------------------
1526 ** Function: static void ValidateResources (
1527 ** DtEditorWidget new,
1528 ** DtEditorWidget request )
1530 ** Parameters: The Editor widget being created & its requested
1533 ** Purpose: This routine:
1534 ** 1) Validates the widget's requested resources
1539 DtEditorWidget request)
1542 * Validate the requested values for the editor's resources
1546 * Make local copies of all resource strings assigned by the application.
1549 if (M_spellFilter(request) != (char *) NULL)
1550 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
1553 * Copy the dialog titles if the application set them, otherwise,
1554 * get their values from the message catalog.
1557 if (M_spellTitle(request) != (XmString) NULL)
1558 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
1560 M_spellTitle(new) = XmStringCreateLocalized(SPELL_TITLE);
1562 if (M_fndChngTitle(request) != (XmString) NULL)
1563 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
1565 M_fndChngTitle(new) = XmStringCreateLocalized(FIND_TITLE);
1567 if (E_format_dialogTitle(request) != (XmString) NULL)
1568 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
1570 E_format_dialogTitle(new) = XmStringCreateLocalized(FORMAT_SETTINGS);
1572 if (E_infoDialogTitle(request) != (XmString) NULL)
1573 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
1575 E_infoDialogTitle(new) = XmStringCreateLocalized(INFO_TITLE);
1578 * Copy the insert & overstrike label indicators if the appli-
1579 * cation set them, otherwise, get their value from the message
1581 * Check for DtUNSPECIFIED because NULL is a valid value.
1584 if (M_status_insertLabel(request) != (XmString) DtUNSPECIFIED)
1585 M_status_insertLabel(new) =
1586 XmStringCopy( M_status_insertLabel(request) );
1588 M_status_insertLabel(new) = XmStringCreateLocalized(INS);
1590 if (M_status_overstrikeLabel(request) != (XmString) DtUNSPECIFIED)
1591 M_status_overstrikeLabel(new) =
1592 XmStringCopy( M_status_overstrikeLabel(request) );
1594 M_status_overstrikeLabel(new) = XmStringCreateLocalized(OVR);
1596 } /* end ValidateResources */
1599 /*-------------------------------------------------------------
1600 ** Function: static Widget CreateText (
1601 ** DtEditorWidget parent)
1603 ** Parameters: The parent of the text widget
1605 ** Purpose: This routine creates the scrolled text widget which
1606 ** lives inside the editor widget.
1607 ** It is responsible for the following:
1608 ** 1) Creating the scrolled text widget,
1609 ** 2) Adding specific translations,
1610 ** 3) Adding our own callbacks,
1611 ** 4) Substituting our own set selection routine.
1615 DtEditorWidget parent)
1617 register int ac; /* arg count */
1618 Arg al[21]; /* arg list */
1622 * First, set up the hardwired scrolled text widget resource values.
1623 * (Change these and you die! Aha! Ha! Ha! Ha! [evil laugh])
1627 XtSetArg (al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
1628 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1629 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1630 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1631 XtSetArg(al[ac], XmNpendingDelete, True); ac++;
1634 * Now, set up the resource values which can vary (passed in from
1635 * application or default values).
1637 * If a synthetic resource is DtUNSPECIFIED don't set it, but let
1638 * it default to the scrolled text default value.
1639 * If it is specified, clear the data field after setting the
1640 * resource because the value in the field will be out of sync
1641 * with the real value.
1643 XtSetArg(al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(parent));
1646 XtSetArg(al[ac], XmNblinkRate, M_blinkRate(parent)); ac++;
1648 if ( M_columns(parent) != DtUNSPECIFIED) {
1649 XtSetArg (al[ac], XmNcolumns, M_columns(parent) ); ac++;
1650 M_columns(parent) = (short) DtUNSPECIFIED;
1653 if ( M_cursorPos(parent) != DtUNSPECIFIED) {
1654 XtSetArg (al[ac], XmNcursorPosition, M_cursorPos(parent)); ac++;
1655 M_cursorPos(parent) = (XmTextPosition) DtUNSPECIFIED;
1658 XtSetArg(al[ac], XmNcursorPositionVisible, M_cursorPosVisible(parent));
1661 XtSetArg(al[ac], XmNeditable, M_editable(parent)); ac++;
1663 if ( E_textFontList(parent) != (XmFontList) NULL) {
1664 XtSetArg (al[ac], XmNfontList, E_textFontList(parent)); ac++;
1667 if ( M_maxLength(parent) != DtUNSPECIFIED) {
1668 XtSetArg (al[ac], XmNmaxLength, M_maxLength(parent) ); ac++;
1669 M_maxLength(parent) = (int) DtUNSPECIFIED;
1672 if ( M_rows(parent) != DtUNSPECIFIED) {
1673 XtSetArg (al[ac], XmNrows, M_rows(parent) ); ac++;
1674 M_rows(parent) = (short) DtUNSPECIFIED;
1677 XtSetArg (al[ac], XmNscrollHorizontal, M_scrollHorizontal(parent) ); ac++;
1679 if ( M_scrollLeftSide(parent) != (Boolean)DtUNSPECIFIED) {
1680 XtSetArg (al[ac], XmNscrollLeftSide, M_scrollLeftSide(parent) ); ac++;
1681 M_scrollLeftSide(parent) = (Boolean)DtUNSPECIFIED;
1684 if ( M_scrollTopSide(parent) != (Boolean)DtUNSPECIFIED) {
1685 XtSetArg (al[ac], XmNscrollTopSide, M_scrollTopSide(parent) ); ac++;
1686 M_scrollTopSide(parent) = (Boolean)DtUNSPECIFIED;
1689 XtSetArg (al[ac], XmNscrollVertical, M_scrollVertical(parent) ); ac++;
1691 if ( M_topCharacter(parent) != DtUNSPECIFIED) {
1692 XtSetArg (al[ac], XmNtopCharacter, M_topCharacter(parent) ); ac++;
1693 M_topCharacter(parent) = (XmTextPosition) DtUNSPECIFIED;
1696 XtSetArg (al[ac], XmNwordWrap, M_wordWrap(parent) ); ac++;
1698 /* Create text widget */
1699 text = XmCreateScrolledText ( (Widget) parent, "text", al, ac );
1703 * Now, set the foreground & background of the text widget. Could not
1704 * set it at create time because the scrolled window would have
1705 * picked it up, too.
1709 if ( M_textBackground(parent) != DtUNSPECIFIED) {
1710 XtSetArg (al[ac], XmNbackground, M_textBackground(parent) ); ac++;
1711 M_textBackground(parent) = (Pixel) DtUNSPECIFIED;
1714 if ( M_textForeground(parent) != DtUNSPECIFIED) {
1715 XtSetArg (al[ac], XmNforeground, M_textForeground(parent) ); ac++;
1716 M_textForeground(parent) = (Pixel) DtUNSPECIFIED;
1720 XtSetValues( text, al, ac);
1723 /* XXX Word Wrap workaround. See comments for FixWordWrap() */
1724 if ( M_scrollHorizontal(parent) ) /* XXX Word Wrap workaround */
1725 FixWordWrap(text, M_wordWrap(parent)); /* XXX Word Wrap workaround */
1728 /* Put the editor-specific translation routines in place. */
1729 XtOverrideTranslations(text,
1730 XtParseTranslationTable(EditorTranslationTable));
1732 /* Add any translations set by the application. */
1733 if ( E_textTranslations(parent) != (XtTranslations)NULL ) {
1734 XtOverrideTranslations(text, E_textTranslations(parent));
1739 * Add modify verify callback
1741 XtAddCallback(text, XmNmodifyVerifyCallback,
1742 (XtCallbackProc) _DtEditorModifyVerifyCB,
1743 (XtPointer) parent);
1746 * Add the Help callback
1748 XtAddCallback( text, XmNhelpCallback, (XtCallbackProc) HelpEditWindowCB,
1749 (XtPointer) parent );
1753 * Substitute our own Set Selection routine which can
1754 * call the textSelect and textDeselect callback procs
1756 if(((XmTextWidget)(text))->text.source->SetSelection !=
1757 Editor_SetSelectionProc) {
1758 M_setSelection(parent) =
1759 ((XmTextWidget)(text))->text.source->SetSelection;
1760 ((XmTextWidget)(text))->text.source->SetSelection =
1761 Editor_SetSelectionProc;
1765 XtSetSensitive (text, True);
1768 } /* end CreateText */
1771 /*-------------------------------------------------------------
1772 ** Function: static int extractFontMetrics (
1773 ** XmFontList fontlist )
1775 ** Purpose: Given a font list, determine the width & height
1776 ** of the characters.
1778 ** This routine is lifted almost straight out of
1779 ** lib/Xm/TextOut.c (see LoadFontMetrics() ) so the editor will
1780 ** select the same font the text widget is working with.
1785 XmFontList fontlist,
1789 XmFontContext context;
1790 XmFontListEntry next_entry;
1791 XmFontType type_return = XmFONT_IS_FONT;
1794 Boolean have_font_struct = False;
1795 Boolean have_font_set = False;
1796 Boolean use_font_set = False;
1797 XFontSetExtents *fs_extents;
1798 unsigned long tmp_width = 0;
1799 int font_descent, font_ascent;
1800 char* font_tag = NULL;
1803 *width = *height = 0;
1804 if (XmFontListInitFontContext(&context, fontlist)) {
1807 * Look through the font list for a fontset with the default tag.
1808 * If we do not find it, use the first font set we came to, otherwise,
1809 * use the first font struct we came to.
1812 Boolean do_break = False;
1814 next_entry = XmFontListNextEntry(context);
1817 tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
1818 if (type_return == XmFONT_IS_FONTSET) {
1823 font_tag = XmFontListEntryGetTag(next_entry);
1825 if (!have_font_set){
1828 * Save the first fontset found in case we don't find
1829 * a default tag font set.
1831 have_font_set = True; /* we have a font set. */
1832 use_font_set = True;
1833 font = (XFontStruct *)tmp_font;
1836 * We have a font set, so no need to consider future font
1839 have_font_struct = True;
1842 * If this is the default font set break out, we've
1843 * found the one we want.
1845 if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
1849 else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)) {
1851 * If this is the default font set save it & break out,
1852 * we've found the one we want.
1854 font = (XFontStruct *)tmp_font;
1855 have_font_set = True;
1859 if (NULL != font_tag)
1865 else if (!have_font_struct){
1870 use_font_set = False;
1873 * Save the first one in case no font set is found
1875 font = (XFontStruct *)tmp_font;
1876 use_font_set = False;
1877 have_font_struct = True;
1882 } while (next_entry != NULL);
1884 XmFontListFreeFontContext(context);
1887 * Now, extract the font metrics from the font set or font that
1895 fs_extents = XExtentsOfFontSet((XFontSet)font);
1897 if (XmDirectionMatch(w->manager.string_direction,
1898 XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
1899 tmp_width = (unsigned long)fs_extents->max_ink_extent.width;
1901 tmp_width = (unsigned long)fs_extents->max_logical_extent.width;
1903 /* max_logical_extent.y is number of pixels from origin to top of
1904 * rectangle (i.e. y is negative) */
1905 font_ascent = -fs_extents->max_logical_extent.y;
1906 font_descent = fs_extents->max_logical_extent.height +
1907 fs_extents->max_logical_extent.y;
1912 * Chose a font struct
1914 font_ascent = font->max_bounds.ascent;
1915 font_descent = font->max_bounds.descent;
1916 if ( (!XGetFontProperty(font, XA_QUAD_WIDTH, &tmp_width)) ||
1919 if ( font->per_char && font->min_char_or_byte2 <= '0' &&
1920 font->max_char_or_byte2 >= '0' )
1921 tmp_width = font->per_char['0' - font->min_char_or_byte2].width;
1923 tmp_width = font->max_bounds.width;
1928 if (tmp_width <= 0) tmp_width = 1;
1929 *width = (int)tmp_width; /* This assumes there will be no truncation */
1930 *height = font_descent + font_ascent;
1934 } /* end extractFontMetrics */
1938 /*-------------------------------------------------------------
1939 ** Function: static void getFontMetrics (
1940 ** DtEditorWidget w )
1942 ** Parameters: An Editor widget
1944 ** Purpose: Determine the height & width of the scrolled text
1952 Arg al[10]; /* arg list */
1953 XmFontList fontlist;
1957 * Get the text widget's font list
1959 * Note, have to retrieve the fontList from the text widget rather
1960 * than use the DtNtextFontList resource because the text widget may
1961 * have rejected the font specified with DtNtextFontList. This way
1962 * we will get the fontList actually used by the text widget.
1965 XtSetArg(al[0], XmNfontList, &fontlist);
1966 XtGetValues(M_text(w), al, 1);
1969 * Now, extract the height and width
1971 extractFontMetrics( w, fontlist, &height, &width );
1972 M_fontWidth(w) = width;
1973 M_fontHeight(w) = height;
1975 } /* end getFontMetrics */
1978 /*-------------------------------------------------------------
1980 ** Release resources allocated for a widget instance.
1986 DtEditorWidget editor = (DtEditorWidget) widget;
1989 * Cleanup the edit window
1993 * (Nothing to be done. Unregistering it as a drop site is handled
1994 * automatically by the DnD library.)
1998 * Cleanup the status line
2001 if (M_status_insertLabel(editor) != (XmString)DtUNSPECIFIED)
2002 XmStringFree(M_status_insertLabel(editor));
2004 if (M_status_overstrikeLabel(editor) != (XmString)DtUNSPECIFIED)
2005 XmStringFree(M_status_overstrikeLabel(editor));
2007 if (E_status_currentLineLabel(editor) != (XmString)DtUNSPECIFIED)
2008 XmStringFree(E_status_currentLineLabel(editor));
2010 if (E_status_totalLineCountLabel(editor) != (XmString)DtUNSPECIFIED)
2011 XmStringFree(E_status_totalLineCountLabel(editor));
2014 * Cleanup the Find/Change & Spell dialogs
2017 if (M_search_string(editor))
2018 XtFree(M_search_string(editor));
2020 if (M_replace_string(editor))
2021 XtFree(M_replace_string(editor));
2023 if (M_misspelled_string(editor))
2024 XtFree(M_misspelled_string(editor));
2026 if (M_spellFilter(editor))
2027 XtFree(M_spellFilter(editor));
2029 if (M_spellTitle(editor) != (XmString)NULL)
2030 XmStringFree(M_spellTitle(editor));
2032 if (E_misspelledListLabel(editor) != (XmString)DtUNSPECIFIED)
2033 XmStringFree(E_misspelledListLabel(editor));
2035 if (M_fndChngTitle(editor) != (XmString)NULL)
2036 XmStringFree(M_fndChngTitle(editor));
2038 if (E_findFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2039 XmStringFree(E_findFieldLabel(editor));
2041 if (E_changeFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2042 XmStringFree(E_changeFieldLabel(editor));
2044 if (E_findButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2045 XmStringFree(E_findButtonLabel(editor));
2047 if (E_changeButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2048 XmStringFree(E_changeButtonLabel(editor));
2050 if (E_changeAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2051 XmStringFree(E_changeAllButtonLabel(editor));
2054 * Cleanup the Format Settings dialog
2056 if (E_format_dialogTitle(editor) != (XmString)NULL)
2057 XmStringFree(E_format_dialogTitle(editor));
2059 if (E_format_leftMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2060 XmStringFree(E_format_leftMarginFieldLabel(editor));
2062 if (E_format_rightMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2063 XmStringFree(E_format_rightMarginFieldLabel(editor));
2065 if (E_format_leftAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2066 XmStringFree(E_format_leftAlignToggleLabel(editor));
2068 if (E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2069 XmStringFree(E_format_rightAlignToggleLabel(editor));
2071 if (E_format_justifyToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2072 XmStringFree(E_format_justifyToggleLabel(editor));
2074 if (E_format_centerToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2075 XmStringFree(E_format_centerToggleLabel(editor));
2077 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2078 XmStringFree(E_format_formatAllButtonLabel(editor));
2080 if (E_format_formatParagraphButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2081 XmStringFree(E_format_formatParagraphButtonLabel(editor));
2084 * Cleanup the Information dialog
2086 if (E_infoDialogTitle(editor) != (XmString)NULL)
2087 XmStringFree(E_infoDialogTitle(editor));
2090 * Cleanup the Undo deletion context
2093 _DtEditorResetUndo(editor);
2098 /*-------------------------------------------------------------
2100 ** Handle changes in resource data.
2110 Boolean redisplay_flag = False;
2111 Arg al[10]; /* arg list */
2112 register int ac; /* arg count */
2114 Boolean resetSpellTitle = False,
2115 resetFormatTitle = False,
2116 resetInfoTitle = False,
2117 newButtonFontList = False,
2118 newLabelFontList = False,
2119 newTextFontList = False,
2120 NeedToFixWordWrap = False; /* XXX Word Wrap workaround*/
2122 DtEditorWidget current = (DtEditorWidget) cw;
2123 DtEditorWidget request = (DtEditorWidget) rw;
2124 DtEditorWidget new = (DtEditorWidget) nw;
2127 * XXX Need to propagate changes to Core resources, like XmNbackground,
2132 * If a synthetic resource is specified, clear the data field
2133 * after setting the resource because the value in the field
2134 * will be out of sync with the real value (contained in the
2139 * General changes, not directly affecting a child
2142 /* Check for a new spell filter */
2144 if ( strcmp(M_spellFilter(request), M_spellFilter(current)) != 0 )
2146 XtFree( M_spellFilter(current) );
2147 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
2150 /* Check for new font lists */
2152 if ( E_buttonFontList(request) != E_buttonFontList(current) )
2153 newButtonFontList = True;
2155 if ( E_labelFontList(request) != E_labelFontList(current) )
2156 newLabelFontList = True;
2158 if ( E_textFontList(request) != E_textFontList(current) )
2159 newTextFontList = True;
2162 * Check for any changes which affect the dialog titles
2165 if (XmStringCompare(E_dialogTitle(request),E_dialogTitle(current)) == False) {
2166 resetSpellTitle = resetFormatTitle = resetInfoTitle = True;
2169 if (XmStringCompare(M_spellTitle(request),M_spellTitle(current)) == False) {
2170 XmStringFree( M_spellTitle(current) );
2171 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
2172 resetSpellTitle = True;
2175 if (XmStringCompare(M_fndChngTitle(request),M_fndChngTitle(current)) == False)
2177 XmStringFree( M_fndChngTitle(current) );
2178 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
2179 resetSpellTitle = True;
2182 if (XmStringCompare(E_format_dialogTitle(request),
2183 E_format_dialogTitle(current) ) == False)
2185 XmStringFree( E_format_dialogTitle(current) );
2186 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
2187 resetFormatTitle = True;
2190 if (XmStringCompare(E_infoDialogTitle(request),
2191 E_infoDialogTitle(current) ) == False)
2193 XmStringFree( E_infoDialogTitle(current) );
2194 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
2195 resetInfoTitle = True;
2199 * Calculate new titles for the dialogs depending upon which resources
2202 if ( resetSpellTitle == True ) {
2204 * No need to do anything because the Spell and Find/Change dialog
2205 * titles are recomputed every time.
2207 redisplay_flag = True;
2210 if ( resetFormatTitle == True ) {
2211 SetFormatDialogTitle( new );
2212 redisplay_flag = True;
2215 if ( resetInfoTitle == True ) {
2216 SetInfoDialogTitle( new );
2217 redisplay_flag = True;
2222 * Check for any changes which affect the status line
2224 if (M_status_showStatusLine(request) != M_status_showStatusLine(current)) {
2225 SetStatusLine( new, M_status_showStatusLine(request) );
2226 redisplay_flag = True;
2229 if ( M_overstrikeMode(request) != M_overstrikeMode(current) ) {
2231 UpdateOverstrikeIndicator( new, M_overstrikeMode(request) );
2232 XtCallActionProc( (Widget) M_text(current), "toggle-overstrike",
2233 (XEvent *)NULL, (String *)NULL, 0 );
2234 redisplay_flag = True;
2237 if ( M_status_statusArea(current) != (Widget)NULL ) {
2239 if (newLabelFontList == True) {
2240 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2241 XtSetValues( (Widget) M_status_lineLabel(current), al, 1);
2242 XtSetValues( (Widget) M_status_totalLabel(current), al, 1);
2243 XtSetValues( (Widget) M_status_totalText(current), al, 1);
2244 XtSetValues( (Widget) M_status_overstrikeWidget(current), al, 1);
2248 if (newTextFontList == True) {
2249 XtSetArg( al[ac], XmNfontList, E_textFontList(request) ); ac++;
2252 if ( M_textBackground(request) != DtUNSPECIFIED) {
2253 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2256 if ( M_textForeground(request) != DtUNSPECIFIED) {
2257 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2261 XtSetValues( (Widget) M_status_lineText(current), al, ac);
2262 XtSetValues( (Widget) M_status_messageText(current), al, ac);
2269 * Check for any changes which affect the dialog boxes
2272 /* Information dialog */
2274 if ( M_gen_warning(current) != (Widget)NULL ) {
2276 if ( newButtonFontList == True ) {
2277 XtSetArg (al[0], XmNfontList, E_buttonFontList(request) );
2279 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_OK_BUTTON),
2283 if ( newLabelFontList == True ) {
2284 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2286 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_MESSAGE_LABEL),
2292 /* Find/Change dialog */
2293 if ( M_search_dialog(current) != (Widget)NULL )
2295 if ( newButtonFontList == True ) {
2296 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2297 XtSetValues( (Widget)M_search_findBtn(current), al, 1 );
2298 XtSetValues( (Widget)M_search_replaceBtn(current), al, 1 );
2299 XtSetValues( (Widget)M_search_replaceAllBtn(current), al, 1 );
2300 XtSetValues( (Widget)M_search_closeBtn(current), al, 1 );
2301 XtSetValues( (Widget)M_search_helpBtn(current), al, 1 );
2304 if ( newLabelFontList == True ) {
2305 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2306 XtSetValues( (Widget)M_search_listLbl(current), al, 1 );
2307 XtSetValues( (Widget)M_search_findLbl(current), al, 1 );
2308 XtSetValues( (Widget)M_search_replaceLbl(current), al, 1);
2311 if ( newTextFontList == True ) {
2312 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2313 XtSetValues( (Widget)M_search_spellList(current), al, 1);
2314 XtSetValues( (Widget)M_findText(current), al, 1 );
2315 XtSetValues( (Widget)M_replaceText(current), al, 1 );
2319 if ( M_textBackground(request) != DtUNSPECIFIED) {
2320 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2323 if ( M_textForeground(request) != DtUNSPECIFIED) {
2324 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2328 XtSetValues( (Widget) M_findText(current), al, ac);
2329 XtSetValues( (Widget) M_replaceText(current), al, ac);
2334 /* Format Settings dialog */
2335 if ( M_format_dialog(current) != (Widget)NULL )
2337 if ( newButtonFontList == True ) {
2338 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2339 XtSetValues( (Widget)M_format_leftJust(current), al, 1 );
2340 XtSetValues( (Widget)M_format_rightJust(current), al, 1);
2341 XtSetValues( (Widget)M_format_bothJust(current), al, 1 );
2342 XtSetValues( (Widget)M_format_center(current), al, 1 );
2343 XtSetValues( (Widget)M_format_paragraph(current), al, 1);
2344 XtSetValues( (Widget)M_format_all(current), al, 1 );
2345 XtSetValues( (Widget)M_format_close(current), al, 1 );
2346 XtSetValues( (Widget)M_format_help(current), al, 1 );
2349 if ( newLabelFontList == True ) {
2350 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2351 XtSetValues( (Widget)M_format_leftLabel(current), al, 1 );
2352 XtSetValues( (Widget)M_format_rightLabel(current), al, 1);
2355 if ( newTextFontList == True ) {
2356 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2357 XtSetValues( (Widget)M_format_leftMarginField(current), al, 1 );
2358 XtSetValues( (Widget)M_format_rightMarginField(current), al, 1);
2362 if ( M_textBackground(request) != DtUNSPECIFIED) {
2363 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2366 if ( M_textForeground(request) != DtUNSPECIFIED) {
2367 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2371 XtSetValues( (Widget) M_format_leftMarginField(current), al, ac);
2372 XtSetValues( (Widget) M_format_rightMarginField(current), al, ac);
2379 * Check for any changes which affect the edit area (scrolled text widget)
2383 if ( M_autoShowCursorPos(request) != M_autoShowCursorPos(current) ) {
2384 XtSetArg( al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(request));
2388 if ( M_blinkRate(request) != M_blinkRate(current) ) {
2389 XtSetArg( al[ac], XmNblinkRate, M_blinkRate(request)); ac++;
2392 if ( M_columns(request) != DtUNSPECIFIED) {
2393 XtSetArg (al[ac], XmNcolumns, M_columns(request) ); ac++;
2394 M_columns(new) = (short) DtUNSPECIFIED;
2395 redisplay_flag = True;
2398 /* PERF - disable redisplay for all SetValues */
2399 if ( M_cursorPos(request) != DtUNSPECIFIED) {
2400 XmTextSetCursorPosition( M_text(new), M_topCharacter(request) );
2401 M_cursorPos(new) = (XmTextPosition) DtUNSPECIFIED;
2404 if ( M_cursorPosVisible(request) != M_cursorPosVisible(current) ) {
2405 XtSetArg( al[ac], XmNcursorPositionVisible, M_cursorPosVisible(request));
2409 if ( M_editable(request) != M_editable(current) ) {
2410 XtSetArg( al[ac], XmNeditable, M_editable(request)); ac++;
2412 if( M_editable(request) ) {
2415 * If the widget is becoming editable, register it as a
2418 RegisterDropZone( new );
2421 * ...turn back on the Change To field in the Find/Change dialog
2423 if ( M_search_dialog(current) != (Widget)NULL ) {
2424 XtSetSensitive(M_search_replaceLbl(current), True);
2425 XtSetSensitive(M_replaceText(current), True);
2431 * It's no longer available as a drop site.
2433 UnregisterDropZone( current );
2436 if ( M_maxLength(request) != DtUNSPECIFIED) {
2437 XtSetArg (al[ac], XmNmaxLength, M_maxLength(request) ); ac++;
2438 M_maxLength(new) = (int) DtUNSPECIFIED;
2441 if ( M_rows(request) != DtUNSPECIFIED) {
2442 XtSetArg (al[ac], XmNrows, M_rows(request) ); ac++;
2443 M_rows(new) = (short) DtUNSPECIFIED;
2444 redisplay_flag = True;
2447 if ( M_textBackground(request) != DtUNSPECIFIED) {
2448 XtSetArg (al[ac], XmNbackground, M_textBackground(request) ); ac++;
2449 M_textBackground(new) = (XmTextPosition) DtUNSPECIFIED;
2450 redisplay_flag = True;
2453 if ( newTextFontList == True ) {
2454 XtSetArg (al[ac], XmNfontList, E_textFontList(request) ); ac++;
2455 redisplay_flag = True;
2458 if ( M_textForeground(request) != DtUNSPECIFIED) {
2459 XtSetArg (al[ac], XmNforeground, M_textForeground(request) ); ac++;
2460 M_textForeground(new) = (XmTextPosition) DtUNSPECIFIED;
2461 redisplay_flag = True;
2464 /* PERF - disable redisplay for all SetValues */
2465 if ( M_topCharacter(request) != DtUNSPECIFIED) {
2466 XmTextSetTopCharacter( M_text(new), M_topCharacter(request) );
2467 M_topCharacter(new) = (XmTextPosition) DtUNSPECIFIED;
2470 if ( M_wordWrap(request) != M_wordWrap(current) ) {
2471 XtSetArg( al[ac], XmNwordWrap, M_wordWrap(request)); ac++;
2472 NeedToFixWordWrap=M_scrollHorizontal(current);/*XXX Word Wrap workaround*/
2475 if ( NeedToFixWordWrap ) /*XXX Word Wrap workaround*/
2476 FixWordWrap(M_text(new), M_wordWrap(request));/*XXX Word Wrap workaround*/
2479 XtSetValues( (Widget) M_text(new), al, ac);
2481 if ( E_textTranslations(request) != E_textTranslations(current) ) {
2482 XtOverrideTranslations(M_text(new), E_textTranslations(request));
2485 if ( newTextFontList == True ) {
2486 getFontMetrics(new);
2489 return (redisplay_flag);
2491 } /* end Set values */
2494 /**************************************************************
2496 ** Get values routines for synthetic resources
2501 _DtEditorGetCenterToggleLabel(
2503 int resource_offset,
2506 DtEditorWidget editor = (DtEditorWidget) wid;
2511 * Get the value directly from the field in the instance structure.
2512 * If it is DtUNSPECIFIED then either:
2513 * 1) the value has been assigned to the widget (so get it from
2515 * 2) the value has never been set (so return the default value).
2518 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2519 data = XmStringCopy( E_format_centerToggleLabel(editor) );
2520 else if (M_format_dialog(editor) != (Widget)NULL)
2522 XtSetArg( al[0], XmNlabelString, &data) ;
2523 XtGetValues( (Widget) M_format_center(editor), al, 1) ;
2526 data = XmStringCreateLocalized(CENTER);
2527 *value = (XtArgVal) data ;
2530 } /* end _DtEditorGetCenterToggleLabel */
2533 _DtEditorGetChangeAllButtonLabel(
2535 int resource_offset,
2538 DtEditorWidget editor = (DtEditorWidget) wid;
2543 * Get the value directly from the field in the instance structure.
2544 * If it is DtUNSPECIFIED then either:
2545 * 1) the value has been assigned to the widget (so get it from
2547 * 2) the value has never been set (so return the default value).
2550 if (E_changeAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2551 data = XmStringCopy( E_changeAllButtonLabel(editor) );
2552 else if (M_search_dialog(editor) != (Widget) NULL)
2554 XtSetArg( al[0], XmNlabelString, &data) ;
2555 XtGetValues( (Widget) M_search_replaceAllBtn(editor), al, 1) ;
2558 data = XmStringCreateLocalized(CHNG_ALL_BUTTON);
2559 *value = (XtArgVal) data ;
2562 } /* end _DtEditorGetChangeAllButtonLabel */
2565 _DtEditorGetChangeButtonLabel(
2567 int resource_offset,
2570 DtEditorWidget editor = (DtEditorWidget) wid;
2575 * Get the value directly from the field in the instance structure.
2576 * If it is DtUNSPECIFIED then either:
2577 * 1) the value has been assigned to the widget (so get it from
2579 * 2) the value has never been set (so return the default value).
2582 if (E_changeButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2583 data = XmStringCopy( E_changeButtonLabel(editor) );
2584 else if (M_search_dialog(editor) != (Widget) NULL)
2586 XtSetArg( al[0], XmNlabelString, &data) ;
2587 XtGetValues( (Widget) M_search_replaceBtn(editor), al, 1) ;
2590 data = XmStringCreateLocalized(CHANGE_BUTTON);
2591 *value = (XtArgVal) data ;
2594 } /* end _DtEditorGetChangeButtonLabel */
2597 _DtEditorGetChangeFieldLabel(
2599 int resource_offset,
2602 DtEditorWidget editor = (DtEditorWidget) wid;
2607 * Get the value directly from the field in the instance structure.
2608 * If it is DtUNSPECIFIED then either:
2609 * 1) the value has been assigned to the widget (so get it from
2611 * 2) the value has never been set (so return the default value).
2614 if (E_changeFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2615 data = XmStringCopy( E_changeFieldLabel(editor) );
2616 else if (M_search_dialog(editor) != (Widget) NULL)
2618 XtSetArg( al[0], XmNlabelString, &data) ;
2619 XtGetValues( (Widget) M_search_replaceLbl(editor), al, 1) ;
2622 data = XmStringCreateLocalized(CHANGE_LABEL);
2623 *value = (XtArgVal) data ;
2626 } /* end _DtEditorGetChangeFieldLabel */
2629 _DtEditorGetColumns(
2631 int resource_offset,
2634 DtEditorWidget editor = (DtEditorWidget) wid;
2638 XtSetArg( al[0], XmNcolumns, &data) ;
2639 XtGetValues( (Widget) M_text(editor), al, 1) ;
2640 *value = (XtArgVal) data ;
2643 } /* end _DtEditorGetColumns */
2646 _DtEditorGetCurrentLineLabel(
2648 int resource_offset,
2651 DtEditorWidget editor = (DtEditorWidget) wid;
2656 * Get the value directly from the field in the instance structure.
2657 * If it is DtUNSPECIFIED then either:
2658 * 1) the value has been assigned to the widget (so get it from
2660 * 2) the value has never been set (so return the default value).
2663 if (E_status_currentLineLabel(editor) != (XmString) DtUNSPECIFIED)
2664 data = XmStringCopy( E_status_currentLineLabel(editor) );
2665 else if (M_status_statusArea(editor) != (Widget) NULL)
2667 XtSetArg( al[0], XmNlabelString, &data) ;
2668 XtGetValues( (Widget) M_status_lineLabel(editor), al, 1) ;
2671 data = XmStringCreateLocalized(LINE);
2672 *value = (XtArgVal) data ;
2675 } /* end _DtEditorGetCurrentLineLabel */
2678 _DtEditorGetCursorPosition(
2680 int resource_offset,
2683 DtEditorWidget editor = (DtEditorWidget) wid;
2684 XmTextPosition data;
2687 XtSetArg( al[0], XmNcursorPosition, &data) ;
2688 XtGetValues( (Widget) M_text(editor), al, 1) ;
2689 *value = (XtArgVal) data ;
2692 } /* end _DtEditorGetCursorPosition */
2695 _DtEditorGetFindButtonLabel(
2697 int resource_offset,
2700 DtEditorWidget editor = (DtEditorWidget) wid;
2705 * Get the value directly from the field in the instance structure.
2706 * If it is DtUNSPECIFIED then either:
2707 * 1) the value has been assigned to the widget (so get it from
2709 * 2) the value has never been set (so return the default value).
2712 if (E_findButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2713 data = XmStringCopy( E_findButtonLabel(editor) );
2714 else if (M_search_dialog(editor) != (Widget) NULL)
2716 XtSetArg( al[0], XmNlabelString, &data) ;
2717 XtGetValues( (Widget) M_search_findBtn(editor), al, 1) ;
2720 data = XmStringCreateLocalized(FIND_BUTTON);
2721 *value = (XtArgVal) data ;
2724 } /* end _DtEditorGetFindButtonLabel */
2727 _DtEditorGetFindFieldLabel(
2729 int resource_offset,
2732 DtEditorWidget editor = (DtEditorWidget) wid;
2737 * Get the value directly from the field in the instance structure.
2738 * If it is DtUNSPECIFIED then either:
2739 * 1) the value has been assigned to the widget (so get it from
2741 * 2) the value has never been set (so return the default value).
2744 if (E_findFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2745 data = XmStringCopy( E_findFieldLabel(editor) );
2746 else if (M_search_dialog(editor) != (Widget) NULL)
2748 XtSetArg( al[0], XmNlabelString, &data) ;
2749 XtGetValues( (Widget) M_search_findLbl(editor), al, 1) ;
2752 data = XmStringCreateLocalized(FIND_LABEL);
2753 *value = (XtArgVal) data ;
2756 } /* end _DtEditorGetFindFieldLabel */
2759 _DtEditorGetFormatAllButtonLabel(
2761 int resource_offset,
2764 DtEditorWidget editor = (DtEditorWidget) wid;
2769 * Get the value directly from the field in the instance structure.
2770 * If it is DtUNSPECIFIED then either:
2771 * 1) the value has been assigned to the widget (so get it from
2773 * 2) the value has never been set (so return the default value).
2776 if (E_format_formatAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2777 data = XmStringCopy( E_format_formatAllButtonLabel(editor) );
2778 else if (M_format_dialog(editor) != (Widget)NULL)
2780 XtSetArg( al[0], XmNlabelString, &data) ;
2781 XtGetValues( (Widget) M_format_all(editor), al, 1) ;
2784 data = XmStringCreateLocalized(ALL);
2785 *value = (XtArgVal) data ;
2788 } /* end _DtEditorGetFormatAllButtonLabel */
2791 _DtEditorGetFormatParagraphButtonLabel(
2793 int resource_offset,
2796 DtEditorWidget editor = (DtEditorWidget) wid;
2801 * Get the value directly from the field in the instance structure.
2802 * If it is DtUNSPECIFIED then either:
2803 * 1) the value has been assigned to the widget (so get it from
2805 * 2) the value has never been set (so return the default value).
2808 if(E_format_formatParagraphButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2809 data = XmStringCopy( E_format_formatParagraphButtonLabel(editor) );
2810 else if (M_format_dialog(editor) != (Widget)NULL)
2812 XtSetArg( al[0], XmNlabelString, &data) ;
2813 XtGetValues( (Widget) M_format_paragraph(editor), al, 1) ;
2816 data = XmStringCreateLocalized(PARAGRAPH);
2817 *value = (XtArgVal) data ;
2820 } /* end _DtEditorGetFormatParagraphButtonLabel */
2823 _DtEditorGetJustifyToggleLabel(
2825 int resource_offset,
2828 DtEditorWidget editor = (DtEditorWidget) wid;
2833 * Get the value directly from the field in the instance structure.
2834 * If it is DtUNSPECIFIED then either:
2835 * 1) the value has been assigned to the widget (so get it from
2837 * 2) the value has never been set (so return the default value).
2840 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2841 data = XmStringCopy( E_format_justifyToggleLabel(editor) );
2842 else if (M_format_dialog(editor) != (Widget)NULL)
2844 XtSetArg( al[0], XmNlabelString, &data) ;
2845 XtGetValues( (Widget) M_format_bothJust(editor), al, 1) ;
2848 data = XmStringCreateLocalized(JUSTIFY);
2849 *value = (XtArgVal) data ;
2852 } /* end _DtEditorGetJustifyToggleLabel */
2855 _DtEditorGetLeftAlignToggleLabel(
2857 int resource_offset,
2860 DtEditorWidget editor = (DtEditorWidget) wid;
2865 * Get the value directly from the field in the instance structure.
2866 * If it is DtUNSPECIFIED then either:
2867 * 1) the value has been assigned to the widget (so get it from
2869 * 2) the value has never been set (so return the default value).
2872 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2873 data = XmStringCopy( E_format_leftAlignToggleLabel(editor) );
2874 else if (M_format_dialog(editor) != (Widget)NULL)
2876 XtSetArg( al[0], XmNlabelString, &data) ;
2877 XtGetValues( (Widget) M_format_leftJust(editor), al, 1) ;
2880 data = XmStringCreateLocalized(LEFT_ALIGN);
2881 *value = (XtArgVal) data ;
2884 } /* end _DtEditorGetLeftAlignToggleLabel */
2887 _DtEditorGetLeftMarginFieldLabel(
2889 int resource_offset,
2892 DtEditorWidget editor = (DtEditorWidget) wid;
2897 * Get the value directly from the field in the instance structure.
2898 * If it is DtUNSPECIFIED then either:
2899 * 1) the value has been assigned to the widget (so get it from
2901 * 2) the value has never been set (so return the default value).
2904 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2905 data = XmStringCopy( E_format_leftMarginFieldLabel(editor) );
2906 else if (M_format_dialog(editor) != (Widget)NULL)
2908 XtSetArg( al[0], XmNlabelString, &data) ;
2909 XtGetValues( (Widget) M_format_leftLabel(editor), al, 1) ;
2912 data = XmStringCreateLocalized(LEFT_MARGIN);
2913 *value = (XtArgVal) data ;
2916 } /* end _DtEditorGetLeftMarginFieldLabel */
2919 _DtEditorGetMaxLength(
2921 int resource_offset,
2924 DtEditorWidget editor = (DtEditorWidget) wid;
2928 XtSetArg( al[0], XmNmaxLength, &data) ;
2929 XtGetValues( (Widget) M_text(editor), al, 1) ;
2930 *value = (XtArgVal) data ;
2933 } /* end _DtEditorGetMaxLength */
2936 _DtEditorGetMisspelledListLabel(
2938 int resource_offset,
2941 DtEditorWidget editor = (DtEditorWidget) wid;
2946 * Get the value directly from the field in the instance structure.
2947 * If it is DtUNSPECIFIED then either:
2948 * 1) the value has been assigned to the widget (so get it from
2950 * 2) the value has never been set (so return the default value).
2953 if (E_misspelledListLabel(editor) != (XmString) DtUNSPECIFIED)
2954 data = XmStringCopy( E_misspelledListLabel(editor) );
2955 else if (M_search_dialog(editor) != (Widget) NULL)
2957 XtSetArg( al[0], XmNlabelString, &data) ;
2958 XtGetValues( (Widget) M_search_listLbl(editor), al, 1) ;
2961 data = XmStringCreateLocalized(MISSPELLED);
2962 *value = (XtArgVal) data ;
2965 } /* end _DtEditorGetMisspelledListLabel */
2968 _DtEditorGetRightAlignToggleLabel(
2970 int resource_offset,
2973 DtEditorWidget editor = (DtEditorWidget) wid;
2978 * Get the value directly from the field in the instance structure.
2979 * If it is DtUNSPECIFIED then either:
2980 * 1) the value has been assigned to the widget (so get it from
2982 * 2) the value has never been set (so return the default value).
2985 if (E_format_rightAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2986 data = XmStringCopy( E_format_rightAlignToggleLabel(editor) );
2987 else if (M_format_dialog(editor) != (Widget)NULL)
2989 XtSetArg( al[0], XmNlabelString, &data) ;
2990 XtGetValues( (Widget) M_format_rightJust(editor), al, 1) ;
2993 data = XmStringCreateLocalized(RIGHT_ALIGN);
2994 *value = (XtArgVal) data ;
2997 } /* end _DtEditorGetRightAlignToggleLabel */
3000 _DtEditorGetRightMarginFieldLabel(
3002 int resource_offset,
3005 DtEditorWidget editor = (DtEditorWidget) wid;
3010 * Get the value directly from the field in the instance structure.
3011 * If it is DtUNSPECIFIED then either:
3012 * 1) the value has been assigned to the widget (so get it from
3014 * 2) the value has never been set (so return the default value).
3017 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
3018 data = XmStringCopy( E_format_rightMarginFieldLabel(editor) );
3019 else if (M_format_dialog(editor) != (Widget)NULL)
3021 XtSetArg( al[0], XmNlabelString, &data) ;
3022 XtGetValues( (Widget) M_format_rightLabel(editor), al, 1) ;
3025 data = XmStringCreateLocalized(RIGHT_MARGIN);
3026 *value = (XtArgVal) data ;
3029 } /* end _DtEditorGetRightMarginFieldLabel */
3034 int resource_offset,
3037 DtEditorWidget editor = (DtEditorWidget) wid;
3041 XtSetArg( al[0], XmNrows, &data) ;
3042 XtGetValues( (Widget) M_text(editor), al, 1) ;
3043 *value = (XtArgVal) data ;
3046 } /* end _DtEditorGetRows */
3049 _DtEditorGetScrollLeftSide(
3051 int resource_offset,
3054 DtEditorWidget editor = (DtEditorWidget) wid;
3058 XtSetArg( al[0], XmNscrollLeftSide, &data) ;
3059 XtGetValues( (Widget) M_text(editor), al, 1) ;
3060 *value = (XtArgVal) data ;
3063 } /* end _DtEditorGetScrollLeftSide */
3066 _DtEditorGetScrollTopSide(
3068 int resource_offset,
3071 DtEditorWidget editor = (DtEditorWidget) wid;
3075 XtSetArg( al[0], XmNscrollTopSide, &data) ;
3076 XtGetValues( (Widget) M_text(editor), al, 1) ;
3077 *value = (XtArgVal) data ;
3080 } /* end _DtEditorGetScrollTopSide */
3083 _DtEditorGetTextBackground(
3085 int resource_offset,
3088 DtEditorWidget editor = (DtEditorWidget) wid;
3092 XtSetArg( al[0], XmNbackground, &data) ;
3093 XtGetValues( (Widget) M_text(editor), al, 1) ;
3094 *value = (XtArgVal) data ;
3097 } /* end _DtEditorGetTextBackground */
3100 _DtEditorGetTextForeground(
3102 int resource_offset,
3105 DtEditorWidget editor = (DtEditorWidget) wid;
3109 XtSetArg( al[0], XmNforeground, &data) ;
3110 XtGetValues( (Widget) M_text(editor), al, 1) ;
3111 *value = (XtArgVal) data ;
3114 } /* end _DtEditorGetTextForeground */
3117 _DtEditorGetTopCharacter(
3119 int resource_offset,
3122 DtEditorWidget editor = (DtEditorWidget) wid;
3123 XmTextPosition data;
3126 XtSetArg( al[0], XmNtopCharacter, &data) ;
3127 XtGetValues( (Widget) M_text(editor), al, 1) ;
3128 *value = (XtArgVal) data ;
3131 } /* end _DtEditorGetTopCharacter */
3134 _DtEditorGetLineCountLabel(
3136 int resource_offset,
3139 DtEditorWidget editor = (DtEditorWidget) wid;
3144 * Get the value directly from the field in the instance structure.
3145 * If it is DtUNSPECIFIED then either:
3146 * 1) the value has been assigned to the widget (so get it from
3148 * 2) the value has never been set (so return the default value).
3151 if (E_status_totalLineCountLabel(editor) != (XmString) DtUNSPECIFIED)
3152 data = XmStringCopy( E_status_totalLineCountLabel(editor) );
3153 else if (M_status_statusArea(editor) != (Widget) NULL)
3155 XtSetArg( al[0], XmNlabelString, &data) ;
3156 XtGetValues( (Widget) M_status_totalLabel(editor), al, 1) ;
3159 data = XmStringCreateLocalized(TOTAL);
3160 *value = (XtArgVal) data ;
3163 } /* end _DtEditorGetLineCountLabel */
3166 /**************************************************************
3168 ** Action Procedures
3173 * The following are DtEditor's actions. A few are internal only (_I
3174 * suffix) and will be called by the default translations DtEditor places
3175 * on the text widget. The rest will be called from an application with
3176 * XtCallActionProc(). The main difference is the internal ones will be
3177 * passed a text widget ID, while the public ones will be passed a DtEditor ID.
3185 Cardinal *num_params)
3188 DtEditorWidget editor = (DtEditorWidget)w;
3190 XtCallActionProc( M_text(editor), "backward-character", event,
3191 params, *num_params );
3199 Cardinal *num_params)
3202 DtEditorWidget editor = (DtEditorWidget)w;
3204 XtCallActionProc( M_text(editor), "backward-paragraph", event,
3205 params, *num_params );
3213 Cardinal *num_params)
3216 DtEditorWidget editor = (DtEditorWidget)w;
3218 XtCallActionProc( M_text(editor), "backward-word", event,
3219 params, *num_params );
3227 Cardinal *num_params)
3230 DtEditorWidget editor = (DtEditorWidget)w;
3232 XtCallActionProc( M_text(editor), "beginning-of-file", event,
3233 params, *num_params );
3241 Cardinal *num_params)
3244 DtEditorWidget editor = (DtEditorWidget)w;
3246 XtCallActionProc( M_text(editor), "beginning-of-line", event,
3247 params, *num_params );
3255 Cardinal *num_params)
3258 DtEditorWidget editor = (DtEditorWidget)w;
3260 XtCallActionProc( M_text(editor), "clear-selection", event,
3261 params, *num_params );
3264 * Clearing selected text also deselects the selection, but for some
3265 * reason the selection proc (Editor_SetSelectionProc) does not get
3266 * called, therefore, we need to call the DtNtextDeselectCallback
3269 Call_TextDeselectCallback(editor);
3278 Cardinal *num_params)
3281 DtEditorWidget editor = (DtEditorWidget)w;
3283 XtCallActionProc( M_text(editor), "copy-clipboard", event,
3284 params, *num_params );
3292 Cardinal *num_params)
3295 DtEditorWidget editor = (DtEditorWidget)w;
3297 XtCallActionProc( M_text(editor), "cut-clipboard", event,
3298 params, *num_params );
3306 Cardinal *num_params)
3309 DtEditorWidget editor = (DtEditorWidget)w;
3311 XtCallActionProc( M_text(editor), "delete-next-character", event,
3312 params, *num_params );
3320 Cardinal *num_params)
3323 DtEditorWidget editor = (DtEditorWidget)w;
3325 XtCallActionProc( M_text(editor), "delete-next-word", event,
3326 params, *num_params );
3334 Cardinal *num_params)
3337 DtEditorWidget editor = (DtEditorWidget)w;
3339 XtCallActionProc( M_text(editor), "delete-previous-character", event,
3340 params, *num_params );
3348 Cardinal *num_params)
3351 DtEditorWidget editor = (DtEditorWidget)w;
3353 XtCallActionProc( M_text(editor), "delete-previous-word", event,
3354 params, *num_params );
3362 Cardinal *num_params)
3365 DtEditorWidget editor = (DtEditorWidget)w;
3367 XtCallActionProc( M_text(editor), "delete-to-end-of-line", event,
3368 params, *num_params );
3376 Cardinal *num_params)
3379 DtEditorWidget editor = (DtEditorWidget)w;
3381 XtCallActionProc( M_text(editor), "delete-to-start-of-line", event,
3382 params, *num_params );
3390 Cardinal *num_params)
3393 DtEditorWidget editor = (DtEditorWidget)w;
3395 XtCallActionProc( M_text(editor), "deselect-all", event,
3396 params, *num_params );
3404 Cardinal *num_params)
3407 DtEditorWidget editor = (DtEditorWidget)w;
3409 XtCallActionProc( M_text(editor), "end-of-file", event,
3410 params, *num_params );
3418 Cardinal *num_params)
3421 DtEditorWidget editor = (DtEditorWidget)w;
3423 XtCallActionProc( M_text(editor), "end-of-line", event,
3424 params, *num_params );
3432 Cardinal *num_params)
3435 DtEditorWidget editor = (DtEditorWidget)w;
3437 XtCallActionProc( M_text(editor), "forward-character", event,
3438 params, *num_params );
3446 Cardinal *num_params)
3449 DtEditorWidget editor = (DtEditorWidget)w;
3451 XtCallActionProc( M_text(editor), "forward-paragraph", event,
3452 params, *num_params );
3460 Cardinal *num_params)
3463 DtEditorWidget editor = (DtEditorWidget)w;
3465 XtCallActionProc( M_text(editor), "forward-word", event,
3466 params, *num_params );
3474 Cardinal *num_params)
3476 DtEditorWidget editor = (DtEditorWidget)w;
3478 if( M_status_statusArea(editor) != (Widget)NULL &&
3479 XtIsManaged(M_status_statusArea(editor)) == True )
3483 * Set the input focus to the "Line" text field.
3486 XmProcessTraversal(M_status_lineText(editor), XmTRAVERSE_CURRENT);
3489 * Select the current contents to allow easy modification.
3492 XtCallActionProc( (Widget)M_status_lineText(editor), "select-all",
3493 event, (String *)NULL, 0 );
3496 } /* end GoToLine */
3499 * Internal action called only from the scrolled text widget
3506 Cardinal *num_params)
3508 XmTextWidget tw = (XmTextWidget)w;
3509 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3511 GoToLine( (Widget)editor, event, params, num_params );
3513 } /* end GoToLine_I */
3520 Cardinal *num_params)
3523 CallHelpCallback((DtEditorWidget)w, DtEDITOR_HELP_EDIT_WINDOW);
3532 Cardinal *num_params)
3535 DtEditorWidget editor = (DtEditorWidget)w;
3537 XtCallActionProc( M_text(editor), "insert-string", event,
3538 params, *num_params );
3546 Cardinal *num_params)
3549 DtEditorWidget editor = (DtEditorWidget)w;
3551 XtCallActionProc( M_text(editor), "key-select", event,
3552 params, *num_params );
3560 Cardinal *num_params)
3563 DtEditorWidget editor = (DtEditorWidget)w;
3565 XtCallActionProc( M_text(editor), "newline-and-backup", event,
3566 params, *num_params );
3574 Cardinal *num_params)
3577 DtEditorWidget editor = (DtEditorWidget)w;
3579 XtCallActionProc( M_text(editor), "newline-and-indent", event,
3580 params, *num_params );
3588 Cardinal *num_params)
3591 DtEditorWidget editor = (DtEditorWidget)w;
3593 XtCallActionProc( M_text(editor), "next-page", event,
3594 params, *num_params );
3602 Cardinal *num_params)
3605 DtEditorWidget editor = (DtEditorWidget)w;
3607 XtCallActionProc( M_text(editor), "page-left", event,
3608 params, *num_params );
3616 Cardinal *num_params)
3619 DtEditorWidget editor = (DtEditorWidget)w;
3621 XtCallActionProc( M_text(editor), "page-right", event,
3622 params, *num_params );
3630 Cardinal *num_params)
3633 DtEditorWidget editor = (DtEditorWidget)w;
3635 XtCallActionProc( M_text(editor), "paste-clipboard", event,
3636 params, *num_params );
3644 Cardinal *num_params)
3647 DtEditorWidget editor = (DtEditorWidget)w;
3649 XtCallActionProc( M_text(editor), "previous-page", event,
3650 params, *num_params );
3658 Cardinal *num_params)
3661 DtEditorWidget editor = (DtEditorWidget)w;
3663 XtCallActionProc( M_text(editor), "process-cancel", event,
3664 params, *num_params );
3672 Cardinal *num_params)
3675 DtEditorWidget editor = (DtEditorWidget)w;
3677 XtCallActionProc( M_text(editor), "process-down", event,
3678 params, *num_params );
3686 Cardinal *num_params)
3689 DtEditorWidget editor = (DtEditorWidget)w;
3691 XtCallActionProc( M_text(editor), "process-shift-down", event,
3692 params, *num_params );
3700 Cardinal *num_params)
3703 DtEditorWidget editor = (DtEditorWidget)w;
3705 XtCallActionProc( M_text(editor), "process-shift-up", event,
3706 params, *num_params );
3714 Cardinal *num_params)
3717 DtEditorWidget editor = (DtEditorWidget)w;
3719 XtCallActionProc( M_text(editor), "process-up", event,
3720 params, *num_params );
3723 /************************************************************************
3724 * GetModeSwitchModifier
3725 * Find if any Mod<n> modifier is acting as the Group modifier - you
3726 * can't assume Mod1Mask is always it.
3727 * Returns the mask of the modifier key to which the Mode_switch
3728 * keysym is attached.
3730 ************************************************************************/
3733 GetModeSwitchModifier(
3736 register XModifierKeymap *pMap;
3737 register int mapIndex, keyCol, mapSize;
3739 unsigned int modeSwitchModMask = 0;
3740 pMap = XGetModifierMapping(dpy);
3741 mapSize = 8*pMap->max_keypermod;
3743 for (mapIndex = 3*pMap->max_keypermod; mapIndex < mapSize; mapIndex++) {
3744 /* look only at the first 4 columns of key map */
3745 for (keyCol = 0; keyCol < 4; keyCol++) {
3746 keySym = XKeycodeToKeysym(dpy, pMap->modifiermap[mapIndex], keyCol);
3747 if (keySym == XK_Mode_switch)
3748 modeSwitchModMask |= 1 << (mapIndex / pMap->max_keypermod);
3752 XFreeModifiermap(pMap);
3753 return modeSwitchModMask;
3756 /************************************************************************
3758 * DtEditorQuoteNextChar
3759 * This action routine circumvents the normal XtDispatchEvent
3760 * mechanism, inserting the next control or extended character
3761 * directly into text without processed by event handlers or the
3762 * translation manager. This means, for
3763 * example, that the next control or extended character will be
3764 * inserted into text without being intrepreted as a Motif menu
3765 * or text widget accelerator.
3767 ************************************************************************/
3774 Cardinal *num_params)
3776 DtEditorWidget editor = (DtEditorWidget)widget;
3777 static unsigned int ExtendcharMask = 0;
3779 /* NOTE: ExtendcharMask could be a global set via a MappingNotify
3780 * event handler. But it isn't...
3783 if (! ExtendcharMask)
3786 if (! ExtendcharMask)
3787 ExtendcharMask = GetModeSwitchModifier( M_display(editor) );
3797 * We cannot let XtAppNextEvent bloc, because the intrinsics
3798 * will release locks and some other thread might dispatch
3799 * the event we want to trap.
3802 XtAppContext app = XtWidgetToApplicationContext(widget);
3803 while ((mask = XtAppPending(app)) == 0)
3805 if (XtAppGetExitFlag(app))
3809 if (mask & XtIMXEvent)
3812 XtAppNextEvent(M_app_context(editor), &next);
3813 if ((next.type == KeyPress) &&
3814 (! IsModifierKey(XLookupKeysym((XKeyEvent *) &next, 0))) )
3816 if (next.xkey.state & (ControlMask|ExtendcharMask))
3817 XtCallActionProc(M_text(editor), "self-insert", &next, NULL, 0);
3819 XtDispatchEvent(&next);
3823 XtDispatchEvent(&next);
3828 /* Some (non-X) event is pending, so this should not block. */
3829 XtAppProcessEvent(app, mask);
3834 } /* end QuoteNextChar */
3837 * Internal action called only from the scrolled text widget
3844 Cardinal *num_params)
3846 XmTextWidget tw = (XmTextWidget)w;
3847 DtEditorWidget editor = (DtEditorWidget) M_editor(tw);
3849 QuoteNextChar( (Widget)editor, event, params, num_params );
3851 } /* end QuoteNextChar_I */
3858 Cardinal *num_params)
3861 DtEditorWidget editor = (DtEditorWidget)w;
3863 XtCallActionProc( M_text(editor), "select-all", event,
3864 params, *num_params );
3872 Cardinal *num_params)
3874 DtEditorWidget editor = (DtEditorWidget)w;
3877 * Toggle the state of the DtNoverstrike resource
3879 XtVaSetValues(w, DtNoverstrike, !M_overstrikeMode(editor), NULL);
3881 } /* end ToggleInsertMode */
3888 Cardinal *num_params)
3890 XmTextWidget tw = (XmTextWidget)w;
3891 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3893 ToggleInsertMode( (Widget)editor, event, params, num_params );
3895 } /* end ToggleInsertMode_I */
3903 Cardinal *num_params)
3906 DtEditorUndoEdit(w);
3908 } /* end UndoEdit */
3915 Cardinal *num_params)
3917 XmTextWidget tw = (XmTextWidget)w;
3919 UndoEdit( (Widget)M_editor(tw), event, params, num_params );
3921 } /* end UndoEdit_I */
3925 * XXX All lines in this file marked "XXX Word Wrap workaround"
3926 * XXX are related to a Motif 1.2 Text widget design defect regarding
3927 * XXX word wrap. For Motif 1.2, the Text widget was designed so word
3928 * XXX wrap will not function if the scrolled text widget has a
3929 * XXX horizontal scroll bar ("a hscrollbar means the paper is infinite
3930 * XXX so there is no edge to wrap at"). This change was made in
3931 * XXX Xm/TextOut.c RCS version 1.71 checked in July, 1991. A
3932 * XXX CMVC report was filed 9/8/94 & assigned number 4772.
3934 #include <Xm/TextOutP.h> /* XXX Word Wrap workaround */
3935 static void /* XXX Word Wrap workaround */
3936 FixWordWrap( /* XXX Word Wrap workaround */
3937 Widget w, /* XXX Word Wrap workaround */
3938 Boolean wrapOn) /* XXX Word Wrap workaround */
3939 { /* XXX Word Wrap workaround */
3940 XmTextWidget tw = (XmTextWidget)w; /* XXX Word Wrap workaround */
3941 OutputData data = tw->text.output->data; /* XXX Word Wrap workaround */
3943 data->scrollhorizontal = !wrapOn; /* XXX Word Wrap workaround */
3944 } /* XXX Word Wrap workaround */
3947 Call_TextSelectCallback(
3948 DtEditorWidget editor)
3951 DtEditorSelectCallbackStruct select_cb;
3954 * Call the Editor widget's DtNtextSelectCallback proc
3955 * if it hasn't been called since the last select.
3958 if ( !M_textSelectCbCalled(editor) ) {
3960 M_textSelectCbCalled(editor) = True;
3961 select_cb.reason = DtEDITOR_TEXT_SELECT;
3962 select_cb.event = (XEvent *)NULL;
3963 XtCallCallbackList ((Widget)editor, M_textSelect(editor),
3964 (XtPointer) &select_cb);
3967 } /* end Call_TextSelectCallback */
3970 Call_TextDeselectCallback(
3971 DtEditorWidget editor)
3974 DtEditorSelectCallbackStruct select_cb;
3977 * Call the Editor widget's DtNtextDeselectCallback proc
3978 * if it hasn't been called since the last deselect.
3981 if ( M_textSelectCbCalled(editor) ) {
3983 M_textSelectCbCalled(editor) = False;
3984 select_cb.reason = DtEDITOR_TEXT_DESELECT;
3985 select_cb.event = (XEvent *)NULL;
3986 XtCallCallbackList ((Widget)editor, M_textDeselect(editor),
3987 (XtPointer) &select_cb);
3990 } /* end Call_TextDeselectCallback */
3993 * Editor_SetSelectionProc
3994 * is put into the widget->text.source->SetSelection.
3995 * Used to call the DtEditor's select/unselect callbacks
3998 Editor_SetSelectionProc(
3999 XmTextSource source,
4000 XmTextPosition left,
4001 XmTextPosition right,
4004 XmSourceData data = source->data;
4008 DtEditorWidget editor;
4009 DtEditorSelectCallbackStruct select_cb;
4015 if (!XtIsRealized((Widget)data->widgets[0]) ||
4016 data->numwidgets <= 0)
4019 if (left < 0) left = right = 0;
4021 widget = (Widget) data->widgets[0];
4022 tw = (XmTextWidget)widget;
4023 editor = M_editor(tw);
4025 if (!editor->core.being_destroyed) {
4029 * There is a selected area if left < right so call the
4030 * DtNtextSelectCallback.
4033 Call_TextSelectCallback( editor );
4038 * Left = Right so nothing is selected; call the
4039 * DtNtextDeselectCallback.
4042 Call_TextDeselectCallback( editor );
4048 * Now, call the text widget's real Set Selection proc
4050 (*M_setSelection(editor))(source, left, right, set_time);
4052 } /* end Editor_SetSelectionProc */
4055 /**************************************************************
4057 ** Drag and drop routines
4063 * Handles drops of a file into the text editor, after validation in the
4064 * transfer callback. Files are handled by reading their contents.
4065 * Text is handled by Motif.
4067 * Changing the contents of the text widget occurs here, rather than in
4068 * the transfer callback, because of the visual changes which occur when
4069 * changing the text widget.
4075 XtPointer client_data,
4076 XtPointer call_data )
4079 DtEditorErrorCode error;
4081 DtDndDropAnimateCallbackStruct *animateInfo =
4082 (DtDndDropAnimateCallbackStruct *) call_data;
4083 DtEditorWidget editor = (DtEditorWidget) client_data;
4086 * XXX Only really needed if # of items is > 1
4088 _DtTurnOnHourGlass( M_topLevelShell(editor) );
4091 * How many items are being dropped on us?
4093 numItems = animateInfo->dropData->numItems;
4095 switch (animateInfo->dropData->protocol)
4097 case DtDND_FILENAME_TRANSFER:
4100 * OK, insert each file we are given
4102 for (ii = 0; ii < numItems; ii++)
4104 error = DtEditorInsertFromFile( (Widget)editor,
4105 animateInfo->dropData->data.files[ii] );
4108 * If the file was not inserted successfully, then quit
4109 * (don't care if the file is read only or if it contained
4110 * nulls that were stripped out).
4112 if( error != DtEDITOR_NO_ERRORS &&
4113 error != DtEDITOR_READ_ONLY_FILE &&
4114 error != DtEDITOR_NULLS_REMOVED )
4116 ii = numItems; /* break out of loop */
4123 } /* end file transfer case */
4125 case DtDND_BUFFER_TRANSFER:
4128 * OK, insert each buffer we are given
4131 DtDndBuffer *buffers = animateInfo->dropData->data.buffers;
4132 DtEditorContentRec cr;
4133 cr.type = DtEDITOR_DATA;
4135 for (ii = 0; ii < numItems; ii++)
4137 cr.value.data.buf = buffers[ii].bp;
4138 cr.value.data.length = buffers[ii].size;
4140 error = DtEditorInsert( (Widget)editor, &cr );
4143 * If the buffer was not inserted successfully, then quit
4144 * (don't care if the file contained nulls that were stripped out).
4146 if( error != DtEDITOR_NO_ERRORS && error != DtEDITOR_NULLS_REMOVED )
4148 ii = numItems; /* break out of loop */
4155 } /* end buffer transfer case */
4157 case DtDND_TEXT_TRANSFER:
4160 * Receiving a text drop.
4162 * Text drag and drop is handled by Motif so this switch
4163 * will never be called.
4168 } /* end text transfer case */
4177 * XXX Only really needed if # of items is > 1
4179 _DtTurnOffHourGlass( M_topLevelShell(editor) );
4181 } /* end AnimateCallback */
4185 * Validates a drop of a file into the text widget.
4187 * Changing the contents of the text widget occurs in the animate
4188 * callback, rather than here, because of the visual changes which
4189 * occur when changing the text widget.
4196 XtPointer client_data,
4197 XtPointer call_data)
4200 DtEditorErrorCode error;
4202 DtDndTransferCallbackStruct *transferInfo =
4203 (DtDndTransferCallbackStruct *) call_data;
4204 DtEditorWidget editor = (DtEditorWidget) client_data;
4206 transferInfo->status = DtDND_SUCCESS;
4209 * How many items are being dropped on us?
4211 numItems = transferInfo->dropData->numItems;
4213 switch (transferInfo->dropData->protocol)
4215 case DtDND_FILENAME_TRANSFER:
4219 * Check to see if we can read each file we are given
4221 for (ii = 0; ii < numItems; ii++)
4223 error = _DtEditorValidateFileAccess(
4224 transferInfo->dropData->data.files[ii],
4228 * Can't access it for reading so reject drop
4230 if ( error != DtEDITOR_NO_ERRORS ) {
4231 transferInfo->status = DtDND_FAILURE;
4232 ii = numItems; /* break out of loop */
4235 } /* end for each file */
4239 } /* end file transfer case */
4241 case DtDND_BUFFER_TRANSFER:
4244 * Receiving a buffer drop.
4245 * -- do nothing in transfer
4249 } /* end buffer transfer case */
4251 case DtDND_TEXT_TRANSFER:
4254 * Receiving a text drop.
4256 * Text drag and drop is handled by Motif so this switch
4257 * will never be called.
4262 } /* end text transfer case */
4266 transferInfo->status = DtDND_FAILURE;
4272 } /* end TransferCallback */
4275 /*-------------------------------------------------------------
4276 ** Function: static void RegisterDropZone (
4277 ** DtEditorWidget w)
4279 ** Parameters: A DtEditor widget
4281 ** Purpose: This routine registers the edit window's text widget
4282 ** as a drop site for file & buffer drops. Because it
4283 ** is a text widget it will automatically accept text
4293 XtCallbackRec transferCB[] = { {TransferCallback, NULL}, {NULL, NULL} };
4294 XtCallbackRec animateCB[] = { {AnimateCallback, NULL}, {NULL, NULL} };
4295 transferCB[0].closure = (XtPointer) w;
4296 animateCB[0].closure = (XtPointer) w;
4299 * Register file & buffer transfers... let Motif handle text DnD
4302 XtSetArg( al[ac], DtNdropAnimateCallback, animateCB ); ac++;
4304 DtDndDropRegister( M_text(w),
4305 DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER,
4306 XmDROP_COPY, transferCB, al, ac );
4308 } /* end RegisterDropZone */
4310 /*-------------------------------------------------------------
4311 ** Function: static void UnregisterDropZone (
4312 ** DtEditorWidget w)
4314 ** Parameters: A DtEditor widget
4316 ** Purpose: This routine unregisters the edit window
4323 DtDndDropUnregister( M_text(w) );
4325 } /* end UnregisterDropZone */
4327 /************************************************************************
4329 * SetInfoDialogTitle - Change the title for the Information dialog
4331 ************************************************************************/
4335 DtEditorWidget editor)
4341 * If the Information dialog has been created, change its title
4343 if( M_gen_warning(editor) != (Widget)NULL )
4347 * Prepend the DialogTitle resource, if it has been set
4349 if( E_dialogTitle(editor) != (XmString)NULL ) {
4353 * Add the "functional title" to the DialogTitle
4355 titleStr = XmStringConcat( E_dialogTitle(editor),
4356 E_infoDialogTitle(editor) );
4358 XtSetArg( al[0], XmNdialogTitle, titleStr );
4359 XtSetValues(M_gen_warning(editor), al, 1);
4361 XmStringFree( titleStr );
4365 XtSetArg( al[0], XmNdialogTitle, E_infoDialogTitle(editor) );
4366 XtSetValues(M_gen_warning(editor), al, 1);
4370 } /* end SetInfoDialogTitle */
4372 /************************************************************************
4374 * _DtEditorWarning - get a message to the user
4376 ************************************************************************/
4380 DtEditorWidget editor,
4382 unsigned char dialogType)
4389 tmpMess = strdup(mess);
4391 /* create the dialog if it is the first time */
4392 if(M_gen_warning(editor) == (Widget) NULL)
4394 XmString titleStr = (XmString) NULL;
4400 * First, create the dialog's title, prepending the
4401 * DtNdialogTitle resource, if it is set
4404 if( E_dialogTitle(editor) != (XmString)NULL ) {
4407 * Add the "functional title" to the DialogTitle
4409 titleStr = XmStringConcat( E_dialogTitle(editor),
4410 E_infoDialogTitle(editor) );
4412 XtSetArg (al[ac], XmNdialogTitle, titleStr ); ac++;
4416 XtSetArg (al[ac], XmNdialogTitle, E_infoDialogTitle(editor)); ac++;
4419 okStr = XmStringCreateLocalized((char*) _DtOkString);
4420 XtSetArg (al[ac], XmNokLabelString, okStr); ac++;
4421 M_gen_warning(editor) = (Widget) XmCreateMessageDialog(
4422 M_topLevelShell(editor), "Warn",
4425 if (titleStr != (XmString) NULL)
4426 XmStringFree( titleStr );
4427 XmStringFree(okStr);
4429 /* Set the correct font lists for the message & OK button. */
4430 XtSetArg (al[0], XmNfontList, E_buttonFontList(editor));
4432 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_OK_BUTTON),
4435 XtSetArg (al[0], XmNfontList, E_labelFontList(editor));
4437 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_MESSAGE_LABEL),
4440 /* Unmanage unneeded children. */
4441 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4442 XmDIALOG_CANCEL_BUTTON) );
4443 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4444 XmDIALOG_HELP_BUTTON) );
4446 XtRealizeWidget (M_gen_warning(editor));
4448 XtSetArg(al[ac], XmNmwmInputMode,
4449 MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
4450 XtSetValues(XtParent(M_gen_warning(editor)), al, ac);
4453 tmpStr = XmStringCreateLocalized(tmpMess);
4455 XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
4456 XtSetArg(al[ac], XmNmessageString, tmpStr); ac++;
4457 XtSetValues(M_gen_warning(editor), al, ac);
4458 XmStringFree(tmpStr);
4460 XtFree( (char *) tmpMess );
4462 XtManageChild (M_gen_warning(editor));
4464 } /* end _DtEditorWarning */
4467 /*********************************************************************
4469 * The following section contains the procedures related to the staus
4472 *********************************************************************/
4475 #define DONT_FORCE False
4478 * PositionActivateCB is invoked when the user presses [Return] after
4479 * (presumably) modifying the current line text field. It retrieves
4480 * the user specified line number and calls DtEditorGoToLine().
4487 caddr_t client_data,
4490 DtEditorWidget editor = (DtEditorWidget)client_data;
4491 char *lineStr = XmTextFieldGetString(M_status_lineText(editor));
4492 int newLineNum = atoi(lineStr);
4495 DtEditorGoToLine ((Widget)editor, newLineNum);
4496 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
4498 } /* PositionActivateCB */
4501 * _DtEditorUpdateLineDisplay updates the current & total line displays
4502 * in the status line, if needed. Normally, the displays are not changed
4503 * if the correct numbers are (supposedly) displayed. Setting forceUpdate
4504 * will cause the numbers to be updated anyways. This is primarily used
4505 * when the user enters a number into the current line display to force
4506 * display of the correct number.
4509 _DtEditorUpdateLineDisplay(
4510 DtEditorWidget editor,
4512 Boolean forceUpdate )
4514 XmTextWidget tw = (XmTextWidget) M_text(editor);
4521 * Only change the current & total lines displays if the status
4524 if ( M_status_showStatusLine(editor) == True )
4529 if (M_status_currentLine(editor) != currentLine || forceUpdate)
4531 sprintf(tmpChars, "%d", currentLine);
4532 XmTextFieldSetString(M_status_lineText(editor), tmpChars);
4533 M_status_currentLine(editor) = currentLine;
4539 lastLine = tw->text.total_lines;
4540 if(M_status_lastLine(editor) != lastLine )
4543 sprintf(tmpChars, "%d", lastLine);
4544 tmpXmStr = XmStringCreateLocalized(tmpChars);
4545 XtSetArg(al[0], XmNlabelString, tmpXmStr);
4546 XtSetValues( M_status_totalText(editor), al, 1 );
4548 XmStringFree(tmpXmStr);
4549 M_status_lastLine(editor) = lastLine;
4553 } /* end _DtEditorUpdateLineDisplay */
4557 UpdateOverstrikeIndicator(
4558 DtEditorWidget widget,
4559 Boolean overstrikeOn )
4563 DtEditorWidget ew = (DtEditorWidget) widget;
4566 * Only change the overstrike indicator if the status line is visible
4568 if ( M_status_showStatusLine(ew) == True &&
4569 M_status_overstrikeWidget(ew) != (Widget) NULL )
4573 if ( overstrikeOn == True ) {
4574 XtSetArg(al[ac], XmNlabelString, M_status_overstrikeLabel(ew)); ac++;
4577 XtSetArg(al[ac], XmNlabelString, M_status_insertLabel(ew)); ac++;
4580 XtSetValues( M_status_overstrikeWidget(ew), al, ac );
4583 } /* end UpdateOverstrikeIndicator */
4587 _DtEditorGetLineIndex(
4591 int startLine, lastLine, middleLine;
4592 XmTextLineTable lineTab = tw->text.line_table;
4595 lastLine = tw->text.total_lines - 1;
4597 while(startLine != lastLine)
4599 middleLine = (startLine + lastLine)/2;
4600 if(middleLine == startLine || middleLine == lastLine)
4603 * We're down to 2 lines. It's gotta be on one of these
4606 if(pos < (XmTextPosition) lineTab[lastLine].start_pos)
4607 lastLine = startLine;
4609 startLine = lastLine;
4613 if (pos < (XmTextPosition) lineTab[middleLine].start_pos)
4614 lastLine = middleLine;
4616 startLine = middleLine;
4620 } /* end _DtEditorGetLineIndex */
4624 * SetCursorPosStatus is called as an XmNmotionVerifyCallback on the
4625 * text widget when the statusLine is turned on. It computes and
4626 * displays the new line of the insert cursor.
4631 caddr_t client_data,
4634 DtEditorWidget editor = (DtEditorWidget)client_data;
4635 XmTextWidget tw = (XmTextWidget)w;
4636 XmTextVerifyCallbackStruct * cb = (XmTextVerifyCallbackStruct *) call_data;
4639 startLine = _DtEditorGetLineIndex(tw, cb->newInsert) + 1;
4641 _DtEditorUpdateLineDisplay( editor, startLine, FORCE );
4643 } /* end SetCursorPosStatus */
4649 Boolean statusLineOn)
4654 XmTextPosition cursorPos;
4656 M_status_showStatusLine(ew) = statusLineOn;
4658 if( statusLineOn == True )
4660 if( M_status_statusArea(ew) == (Widget)NULL )
4661 M_status_statusArea(ew) = CreateStatusLine( ew );
4664 * Update the line counts
4667 cursorPos = (XmTextPosition)DtEditorGetInsertionPosition( (Widget)ew );
4668 currentLine = _DtEditorGetLineIndex( (XmTextWidget) M_text(ew),
4670 _DtEditorUpdateLineDisplay( ew, currentLine, DONT_FORCE );
4673 * Update the overstrike indicator
4675 UpdateOverstrikeIndicator( ew, M_overstrikeMode(ew) );
4678 * Show the status line
4681 XtManageChild( M_status_statusArea(ew) );
4684 * Hook the scrolled text widget to the status line
4687 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_WIDGET ); ac++;
4688 XtSetArg( al[ac], XmNbottomWidget, M_status_statusArea(ew) ); ac++;
4689 XtSetValues( XtParent(M_text(ew)), al, ac );
4691 XtAddCallback( M_text(ew), XmNmotionVerifyCallback,
4692 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4698 * Hook the scrolled text widget to the bottom of the form
4701 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4702 XtSetValues( XtParent(M_text(ew)), al, ac );
4704 XtRemoveCallback( M_text(ew), XmNmotionVerifyCallback,
4705 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4708 * Hide the status line
4710 if( M_status_statusArea(ew) != (Widget)NULL )
4711 XtUnmanageChild( M_status_statusArea(ew) );
4715 } /* SetStatusLine */
4718 /************************************************************************
4720 * CreateStatusLine - Creates the status line
4722 ************************************************************************/
4726 DtEditorWidget parent)
4732 Pixel background, foreground;
4735 * Match the background & foreground colors of the edit window
4736 * Don't use DtNtextBackground/Foreground directly because they
4737 * will be DtUNSPECIFIED.
4740 XtSetArg(al[ac], XmNforeground, &foreground); ac++;
4741 XtSetArg(al[ac], XmNbackground, &background); ac++;
4742 XtGetValues(M_text(parent), al, ac);
4745 * Create the status line container
4748 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4749 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4750 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4751 XtSetArg( al[ac], XmNverticalSpacing, 3 ); ac++;
4752 XtSetArg( al[ac], XmNhorizontalSpacing, 3 ); ac++;
4753 container = (Widget) XmCreateForm( (Widget)parent, "statusLine",
4757 * Create the current line label and text field
4760 if (E_status_currentLineLabel(parent) != (XmString)DtUNSPECIFIED)
4763 * Use the resource value & clear it (to save space).
4765 tmpStr = XmStringCopy(E_status_currentLineLabel(parent));
4766 E_status_currentLineLabel(parent) = (XmString)DtUNSPECIFIED;
4770 * The resource has not been set so use its default value
4772 tmpStr = XmStringCreateLocalized(LINE);
4775 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4776 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4777 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4779 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4780 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4781 M_status_lineLabel(parent) = (Widget) XmCreateLabelGadget( container,
4782 "lineLabel", al, ac);
4783 XtManageChild(M_status_lineLabel(parent));
4784 XtAddCallback(M_status_lineLabel(parent), XmNhelpCallback,
4785 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4786 XmStringFree(tmpStr);
4789 XtSetArg(al[ac], XmNcolumns, 6); ac++;
4790 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4791 XtSetArg(al[ac], XmNbackground, background); ac++;
4792 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4793 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4794 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4795 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4796 XtSetArg( al[ac], XmNleftWidget, M_status_lineLabel(parent) ); ac++;
4797 M_status_lineText(parent) = XmCreateTextField( container, "lineText",
4799 XtManageChild(M_status_lineText(parent));
4800 XtAddCallback(M_status_lineText(parent), XmNactivateCallback,
4801 (XtCallbackProc)PositionActivateCB, parent);
4802 XtAddCallback(M_status_lineText(parent), XmNhelpCallback,
4803 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4806 * Create the total lines labels
4809 if (E_status_totalLineCountLabel(parent) != (XmString)DtUNSPECIFIED)
4812 * Use the resource value & clear it (to save space).
4814 tmpStr = XmStringCopy(E_status_totalLineCountLabel(parent));
4815 E_status_totalLineCountLabel(parent) = (XmString)DtUNSPECIFIED;
4819 * The resource has not been set so use its default value
4821 tmpStr = XmStringCreateLocalized(TOTAL);
4824 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4825 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4826 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4827 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4828 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4829 XtSetArg( al[ac], XmNleftWidget, M_status_lineText(parent) ); ac++;
4830 M_status_totalLabel(parent) = (Widget) XmCreateLabelGadget( container,
4831 "totalLabel", al, ac);
4832 XtManageChild(M_status_totalLabel(parent));
4833 XtAddCallback(M_status_totalLabel(parent), XmNhelpCallback,
4834 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4835 XmStringFree(tmpStr);
4838 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4839 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4840 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4841 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4842 XtSetArg( al[ac], XmNleftWidget, M_status_totalLabel(parent) ); ac++;
4843 M_status_totalText(parent) = (Widget) XmCreateLabelGadget( container,
4844 "totalText", al, ac);
4845 XtManageChild(M_status_totalText(parent));
4846 XtAddCallback(M_status_totalText(parent), XmNhelpCallback,
4847 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4850 * Create the overstrike indicator
4854 XtSetArg(al[ac], XmNrecomputeSize, False); ac++;
4856 XtSetArg(al[ac], XmNmarginLeft, 0); ac++;
4857 XtSetArg(al[ac], XmNmarginRight, 0); ac++;
4858 XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
4859 XtSetArg( al[ac], XmNrightOffset, 3 ); ac++;
4860 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4861 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4862 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4863 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4864 M_status_overstrikeWidget(parent) =
4865 (Widget) XmCreateLabelGadget( container, "overstrikeLabel", al, ac);
4866 XtManageChild(M_status_overstrikeWidget(parent));
4867 XtAddCallback(M_status_overstrikeWidget(parent), XmNhelpCallback,
4868 (XtCallbackProc)HelpStatusOverstrikeCB, parent);
4871 * Create the application message area
4874 XtSetArg(al[ac], XmNbackground, parent->core.background_pixel); ac++;
4875 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4876 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4877 XtSetArg(al[ac], XmNeditable, False); ac++;
4878 XtSetArg(al[ac], XmNcursorPositionVisible, False); ac++;
4879 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
4880 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4881 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4882 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4883 XtSetArg( al[ac], XmNleftWidget, M_status_totalText(parent) ); ac++;
4884 XtSetArg( al[ac], XmNleftOffset, 17 ); ac++;
4885 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_WIDGET ); ac++;
4886 XtSetArg(al[ac], XmNrightWidget, M_status_overstrikeWidget(parent)); ac++;
4887 M_status_messageText(parent) =
4888 XmCreateTextField( container, "messageText", al, ac );
4890 XtManageChild(M_status_messageText(parent));
4891 XtAddCallback(M_status_messageText(parent), XmNhelpCallback,
4892 (XtCallbackProc)HelpStatusMessageCB, parent);
4894 return( container );
4896 } /* end CreateStatusLine */
4899 /*********************************************************************
4901 * The following section contains the procedures related to help
4903 *********************************************************************/
4908 DtEditorWidget editor,
4911 DtEditorHelpCallbackStruct help_cb;
4913 help_cb.reason = reason;
4914 help_cb.event = (XEvent *) NULL;
4915 XtCallCallbackList( (Widget)editor, M_HelpCB(editor),
4916 (XtPointer) &help_cb );
4918 } /* end CallHelpCallback */
4921 * Edit window help callbacks
4928 caddr_t client_data,
4931 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_EDIT_WINDOW);
4935 * Status Line help callbacks
4946 caddr_t client_data,
4949 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_STATUS_LINE);
4954 HelpStatusCurrentLineCB(
4956 caddr_t client_data,
4959 CallHelpCallback( (DtEditorWidget)client_data,
4960 DtEDITOR_HELP_STATUS_CURRENT_LINE );
4965 HelpStatusTotalLinesCB(
4967 caddr_t client_data,
4970 CallHelpCallback( (DtEditorWidget)client_data,
4971 DtEDITOR_HELP_STATUS_TOTAL_LINES );
4976 HelpStatusMessageCB(
4978 caddr_t client_data,
4981 CallHelpCallback( (DtEditorWidget)client_data,
4982 DtEDITOR_HELP_STATUS_MESSAGE );
4987 HelpStatusOverstrikeCB(
4989 caddr_t client_data,
4992 CallHelpCallback( (DtEditorWidget)client_data,
4993 DtEDITOR_HELP_STATUS_OVERSTRIKE );
4997 * Format Settings dialog help callbacks
5004 caddr_t client_data,
5007 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_FORMAT_DIALOG);
5012 HelpFormatRightMarginCB(
5014 caddr_t client_data,
5017 CallHelpCallback( (DtEditorWidget)client_data,
5018 DtEDITOR_HELP_FORMAT_RIGHT_MARGIN);
5023 HelpFormatLeftMarginCB(
5025 caddr_t client_data,
5028 CallHelpCallback( (DtEditorWidget)client_data,
5029 DtEDITOR_HELP_FORMAT_LEFT_MARGIN);
5034 HelpFormatJustifyButtonsCB(
5036 caddr_t client_data,
5039 CallHelpCallback( (DtEditorWidget)client_data,
5040 DtEDITOR_HELP_FORMAT_ALIGNMENT);
5044 * Find/Change & Spell dialogs help callbacks
5049 _DtEditorHelpSearchCB(
5051 caddr_t client_data,
5054 DtEditorWidget editor = (DtEditorWidget)client_data;
5056 switch (M_search_dialogMode(editor))
5059 CallHelpCallback( (DtEditorWidget)client_data,
5060 DtEDITOR_HELP_SPELL_DIALOG);
5064 CallHelpCallback( (DtEditorWidget)client_data,
5065 DtEDITOR_HELP_CHANGE_DIALOG);
5068 } /* _DtEditorHelpSearchCB */
5072 _DtEditorHelpSearchFindCB(
5074 caddr_t client_data,
5077 CallHelpCallback( (DtEditorWidget)client_data,
5078 DtEDITOR_HELP_CHANGE_FIND);
5082 _DtEditorHelpSearchChangeCB(
5084 caddr_t client_data,
5087 DtEditorWidget editor = (DtEditorWidget)client_data;
5089 switch (M_search_dialogMode(editor))
5092 CallHelpCallback( (DtEditorWidget)client_data,
5093 DtEDITOR_HELP_SPELL_CHANGE);
5097 CallHelpCallback( (DtEditorWidget)client_data,
5098 DtEDITOR_HELP_CHANGE_CHANGE);
5101 } /* _DtEditorHelpSearchChangeCB */
5105 _DtEditorHelpSearchSpellCB(
5107 caddr_t client_data,
5110 CallHelpCallback( (DtEditorWidget)client_data,
5111 DtEDITOR_HELP_SPELL_MISSPELLED_WORDS);
5114 /*********************************************************************
5116 * The following section contains the procedures related to formating
5117 * text and the Format Settings dialog.
5119 *********************************************************************/
5122 * Do simple formatting of paragraphs of text.
5123 * Designed for speed, at some cost in complexity and redundancy.
5125 * There is a minor undocumented bug in Dump(). It calls Justify() in the
5126 * case where the last word of the last line of a paragraph is an end-of-
5127 * sentence word (typical) and ends just one blank before the margin
5128 * (rare). This results in one blank being inserted in the line when it's
5129 * not necessary. It happens because the two trailing blanks after the
5130 * word cause an "ordinary" line dump before Fill() sees the next line and
5131 * knows it has an end of paragraph. WARNING: The situation would be
5132 * aggravated if FillWord() ever set blanks to an even larger number.
5136 ** This section contains changes for EUC_4B compatibility.
5137 ** WPI interface is used.
5140 /* Global Variables and extern declarations */
5142 typedef struct _WORD{ /* describe one word */
5143 wint_t *cp; /* word location in buffer */
5144 int inlinenum; /* word start line in input */
5145 int incolumn; /* word start column in input */
5146 int length; /* size of word */
5147 int score; /* word + next for jflag */
5148 int blanks; /* output trailing blanks need */
5149 int wclen; /* Length of wide character word */
5157 /* FORMATTING CONTROL */
5161 int tabsize; /* tab size in use */
5162 int centerstartpara; /* expect para. start? in "Center" */
5164 /* Global/static vars used in "Fill" */
5165 wint_t *wordbuf; /* see comments for "Fill" for discussion */
5182 int indent1, indent2;
5185 #define isekinsoku(wc) iswctype((wc),ekinclass)
5186 #define isbekinsoku(wc) iswctype((wc),bekinclass)
5188 #define LINESIZE BUFSIZ /* how big a line can be */
5189 #define WORDMAX LINESIZE /* see above for discussion */
5191 #define WORDNEXT(d,at) { if (++at == d->wordlimit) at = d->wordbase; } /* statement */
5192 #define WORDPREV(d,at) (((at == d->wordbase) ? d->wordlimit : at) - 1) /* function */
5195 extern int _nl_space_alt;
5199 * Forward declarations
5201 static int DoLine (FormatData *data, register FILE *filep);
5202 static void Center (FormatData *data,
5203 wint_t *in_line, register wint_t *inlinelim);
5204 static void Fill (FormatData *data, wint_t *in_line, register wint_t *inlinelim);
5205 static void FillWord (FormatData *data);
5206 static void Dump (FormatData *data, int endpara);
5207 static void PrintIndent (FormatData *data, int indent);
5208 static void PrintTag (FormatData *data, WORD *wordpast);
5209 static void PrintWords (FormatData *data, WORD *wordpast);
5210 static void Justify (FormatData *data, register int blanks, WORD *wordpast);
5211 static int CompareWords (const void *, const void *);
5212 static int EkinBekinProc(FormatData *data, WORD **wordpast);
5213 static void postEkinBekinProc(FormatData *data, int *poutchars, WORD *wordpast);
5217 * A small workaround for systems that don't have wcwidth...
5224 char mbstr[MB_LEN_MAX + 1];
5226 status = wctomb(mbstr, wc);
5229 return(euccol(mbstr));
5236 * The following utilities: lineBlank, findNonBlank, and countBlanks all
5237 * require the lineLen parameter to specify the number of characters, not
5238 * bytes, in the line.
5246 int byteNum, charNum;
5248 size_t mbCurMax = MB_CUR_MAX;
5250 for(byteNum = charNum = 0; charNum < lineLen;
5251 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5253 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5254 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5255 if( !iswctype(wc, _DtEditor_blankClass) )
5260 #endif /* not sun */
5270 int byteNum, charNum;
5272 size_t mbCurMax = MB_CUR_MAX;
5274 for(byteNum = charNum = 0; charNum < lineLen;
5275 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5277 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5278 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5279 if( !iswctype(wc, _DtEditor_blankClass) )
5280 return &pLine[byteNum];
5283 return &pLine[byteNum];
5284 #endif /* not sun */
5286 return &pLine[byteNum];
5294 int byteNum, charNum, count;
5296 size_t mbCurMax = MB_CUR_MAX;
5298 for(byteNum = charNum = 0, count = 0; charNum < lineLen;
5299 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5301 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5304 if(mblen(&pLine[byteNum], mbCurMax) == 1)
5306 switch((int) pLine[byteNum])
5309 * I don't really know what to do with weird embedded chars.
5310 * This is just a guess. In non-ascii locales this could
5311 * screw up, but I don't know how else to deal with
5312 * weird embedded control characters.
5314 case '\n': /* newline */
5315 case '\f': /* form feed */
5318 case '\t': /* horizontal tab */
5321 case '\b': /* backspace */
5324 case '\r': /* carriage return */
5332 count++; /* multibyte control chars??? */
5335 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5336 if(!iswctype(wc, _DtEditor_blankClass))
5341 #endif /* not sun */
5349 * fixLeftMarginAndNewlines - writes out a substring from the text widget,
5350 * inserting leading blanks as needed to set the left margin, and adding
5351 * newlines at all "virtual" (i.e. word-wrapped) lines. It assumes that the
5352 * specified substring is an integer number of lines - i.e. the substring
5353 * cannot begin or end in the middle of a line. Non-complying substrings
5354 * are expanded to encompass whole lines.
5357 fixLeftMarginAndNewlines(
5358 DtEditorWidget editor,
5365 Widget widget = M_text(editor);
5366 register XmTextLineTable lineTable;
5368 int lineIndex, lineLen, nextLen, lineIndent, lastIndex,
5369 lineByteLen, total_lines;
5370 Boolean newPara = True;
5371 char *pLine, *pNext, *pFirstNonBlank, *pLastChar;
5372 size_t mbCurMax = MB_CUR_MAX;
5374 lineTable = _XmTextGetLineTable(widget, &total_lines);
5376 if (leftMargin > rightMargin || leftMargin < 0)
5379 lineIndent = leftMargin;
5382 * calculate the starting line number and ending line number
5383 * for the [sub]string we're operating upon.
5385 lineIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), startPos);
5387 lastIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), endPos);
5390 * This loop terminates with one line unwritten. This is correct
5391 * if we're not formatting the last line of the file, as that means
5392 * that we must be formatting a paragraph, and the paragraph adjust
5393 * code has trouble locating the end of a paragraph (as opposed to the
5394 * beginning of the next paragraph. If the last line of the text is
5395 * to be formatted, it is handled after this loop terminates.
5397 for(; lineIndex < lastIndex; lineIndex++)
5400 * if the current line was word-wrapped, put out a nl.
5402 if(lineTable[lineIndex].virt_line)
5403 fwrite("\n", sizeof(char), 1, fp);
5405 lineLen = lineTable[lineIndex + 1].start_pos -
5406 lineTable[lineIndex].start_pos;
5407 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5408 lineTable[lineIndex].start_pos,
5409 lineTable[lineIndex + 1].start_pos, False);
5410 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5411 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5413 if(lineBlank(pLine, lineLen))
5416 * Blank lines indicate the start of a new paragraph.
5417 * They also don't require any indent adjustment so are
5418 * quick/easy to write out.
5420 fwrite( pLine, sizeof(char),
5421 _DtEditorGetPointer(pLine, lineLen) - pLine, fp );
5430 * Calc the proper indent for the first line, and
5431 * the indent for the rest of the lines
5432 * in the paragraph. If there's only one line in the
5433 * paragraph, then the proper indent is adjustStuff.left_margin.
5437 * Get the next line.
5439 if((total_lines - lineIndex) > 2)
5440 nextLen = lineTable[lineIndex + 2].start_pos -
5441 lineTable[lineIndex + 1].start_pos;
5443 nextLen = XmTextGetLastPosition(widget) -
5444 lineTable[lineIndex + 1].start_pos;
5445 pNext = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5446 lineTable[lineIndex + 1].start_pos,
5447 lineTable[lineIndex + 1].start_pos + nextLen, False);
5449 if(lineBlank(pNext, nextLen)) /* single line paragraph */
5450 firstIndent = lineIndent = leftMargin;
5453 int curFirstIndent, curSecondIndent, offset;
5455 curFirstIndent = countBlanks(pLine, lineLen);
5456 curSecondIndent = countBlanks(pNext, nextLen);
5458 offset = curFirstIndent - curSecondIndent;
5461 /* second line is closer to the left margin */
5464 * Note, the first line will still be indented even
5465 * if the remaining words in the paragraph can
5466 * all fit on the first line. The end result is a
5467 * one line indented paragraph. I am mentioning
5468 * this because some may think this is a defect.
5471 firstIndent = leftMargin + offset;
5472 lineIndent = leftMargin;
5476 firstIndent = leftMargin;
5477 lineIndent = leftMargin - offset;
5480 for(i = firstIndent; 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);
5490 for(i = lineIndent; i-- > 0;)
5491 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5492 pFirstNonBlank = findNonBlank(pLine, lineLen);
5493 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5494 (pFirstNonBlank - pLine), fp);
5498 if((total_lines - lineIndex) == 1)
5501 * Now we have to handle the last line.
5503 if(lineTable[lineIndex].virt_line)
5504 fwrite("\n", sizeof(char), 1, fp);
5506 if((total_lines - lineIndex) > 2)
5507 lineLen = lineTable[lineIndex + 1].start_pos -
5508 lineTable[lineIndex].start_pos;
5510 lineLen = XmTextGetLastPosition(widget) -
5511 lineTable[lineIndex].start_pos;
5515 for(i = lineIndent; i-- > 0;)
5516 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5518 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5519 lineTable[lineIndex].start_pos,
5520 lineTable[lineIndex].start_pos + lineLen, False);
5521 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5522 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5523 if(lineBlank(pLine, lineLen))
5525 fwrite(pLine, sizeof(char), lineByteLen, fp);
5529 pFirstNonBlank = findNonBlank(pLine, lineLen);
5530 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5531 (pFirstNonBlank - pLine), fp);
5536 XtFree((XtPointer)lineTable);
5540 /************************************************************************
5543 * Initialize, check arguments embedded in AdjRec, open and read files,
5544 * and pass a series of lines to lower-level routines.
5553 long maxmargin; /* max allowed */
5554 register FILE *filep; /* file to read */
5559 * INITIALIZE FOR NLS
5561 mbtowc(&data.Blank," ",1);
5564 * Initialize global/statics.
5566 if((data.wordbuf = malloc(sizeof(wint_t) * LINESIZE * 3)) == (wint_t *)NULL)
5568 if((data.word = malloc(sizeof(WORD) * WORDMAX)) == (WORD *)NULL)
5573 data.tabsize = 8; /* default tab size */
5574 data.centerstartpara = True;
5576 data.fillmargin = data.centermiddle = pAdjRec->margin;
5577 data.m0flag = (data.fillmargin == 0L);
5580 * Initialize global/statics for "Fill".
5582 data.wordcp = data.wordbuf;
5583 data.wordcpwrap = data.wordbuf + (LINESIZE * 2);
5584 data.wordbase = & data.word [0];
5585 data.wordlimit = & data.word [WORDMAX];
5586 data.wordfirst = & data.word [0];
5587 data.wordnext = & data.word [0];
5589 data.outlinenum = 1;
5596 if (pAdjRec->cflag + pAdjRec->jflag + pAdjRec->rflag > 1)
5602 maxmargin = pAdjRec->cflag? (LINESIZE / 2) : LINESIZE;
5603 if ((data.fillmargin < 0L) || (data.fillmargin > maxmargin))
5609 if ((pAdjRec->tabsize > 0) && (pAdjRec->tabsize <= MAXTABSIZE))
5610 data.tabsize = pAdjRec->tabsize;
5613 * OPEN AND READ INPUT FILE:
5616 filep = pAdjRec->infp;
5617 data.pAdj = pAdjRec; /* set (file) global var to passed in rec */
5619 while (DoLine (&data, filep))
5623 * DUMP LAST LINE AND EXIT:
5626 if (! data.pAdj->cflag) /* not centering */
5628 Dump (&data, True); /* force end paragraph */
5634 if(data.wordbuf != (wint_t *)NULL)
5638 if(data.word != (WORD *)NULL)
5647 /************************************************************************
5650 * Read one input line and do generic processing (read chars from input
5651 * to in_line, crunching backspaces). Return True if successful, else
5652 * false at end of input file. This must be done before expanding tabs;
5653 * pass half-processed line to Center() or Fill() for more work.
5655 * Assumes getc() is efficient.
5656 * in_line[] is static so it is only allocated once.
5660 DoLine (FormatData *data,
5661 register FILE *filep) /* open file to read */
5663 wint_t in_line [LINESIZE]; /* after reading in */
5664 register wint_t *incp = in_line; /* place in in_line */
5665 register wint_t *incplim = in_line + LINESIZE; /* limit of in_line */
5669 * READ LINE WITH BACKSPACE CRUNCHING:
5672 while (incp < incplim) /* buffer not full */
5674 c = getwc (filep); /* get and save wide char */
5679 if (incp == in_line) /* nothing read yet */
5682 case L'\0': /* fall through */
5683 case L'\n': /* end of line */
5684 incplim = incp; /* set limit (quit loop) */
5687 case L'\b': /* backspace */
5688 if (incp > in_line) /* not at start */
5689 incp--; /* just back up */
5692 default: /* any other char */
5697 /* now incplim is correctly set to last char + 1 */
5700 * PASS LINE ON FOR MORE WORK:
5703 if (data->pAdj->cflag) Center (data, in_line, incplim);
5704 else Fill (data, in_line, incplim);
5706 return (True); /* maybe more to read */
5711 /************************************************************************
5714 * Center text (starting at in_line, ending before inlinelim). First copy
5715 * chars from in_line to outline skipping nonprintables and expanding tabs.
5716 * For efficiency (at the cost of simplicity), note and skip indentation
5717 * at the same time. Then, print outline with indentation to center it.
5719 * outline[] is static so it is only allocated once; startpara so it is
5720 * used for successive lines.
5724 Center (FormatData *data,
5725 wint_t *in_line, /* start of input line */
5726 register wint_t *inlinelim) /* end of line + 1 */
5728 register wint_t *incp; /* pointer in in_line */
5729 wint_t outline [LINESIZE + MAXTABSIZE]; /* after generic work */
5730 register wint_t *outcp = outline; /* place in outline */
5731 register wint_t *outlinelim = outline + LINESIZE; /* limit of outline*/
5733 int haveword = False; /* hit word in in_line? */
5734 register wint_t ch; /* current working char */
5735 register int needsp; /* spaces need for tab */
5736 register int indent = 0; /* size of indentation */
5737 int textwidth; /* size of text part */
5738 int extwidth = 0; /* additional width for MBCS */
5745 for (incp = in_line; (incp < inlinelim) && (outcp < outlinelim); incp++)
5756 needsp = ((ch != L'\t') && (iswblank(ch))) ?
5757 1 : data->tabsize - ((indent + outcp - outline) % data->tabsize);
5759 if (! haveword) /* indentation */
5761 else /* past text */
5762 for ( ; needsp > 0; needsp--)
5763 *outcp++ = data->Blank;
5767 * CARRY OVER PRINTABLE CHARS AND NOTE INDENTATION:
5770 else if (iswprint (ch)) /* note: ch != ' ' */
5772 *outcp++ = ch; /* just copy it over */
5774 if(MB_CUR_MAX > 1 && wcwidth(ch) > 1)
5775 extwidth += wcwidth(ch) - 1;
5778 /* else do nothing, which tosses other chars */
5782 /* Now outcp is the new outlinelim */
5785 * HANDLE BLANK LINE (no text):
5790 putc ('\n', data->pAdj->outfp); /* "eat" any whitespace */
5791 data->centerstartpara = True; /* expect new paragraph */
5795 * EAT TRAILING BLANKS, SET TEXTWIDTH:
5800 /* note that outcp > outline */
5801 while ((outcp[-1] != L'\t') && iswblank(outcp [-1]))
5804 textwidth = (outcp - outline); /* thus textwidth > 0 */
5807 * SET AUTOMARGIN AND PRINT CENTERED LINE:
5809 * The equations used depend on truncating division:
5812 * Margin Middle Width Results
5813 * odd exact odd exact centering
5814 * odd exact even extra char to right
5815 * even left odd extra char to left
5816 * even left even exact centering (due to "extra" char to right)
5818 * When centermiddle is default or given by user, it is the same as the
5819 * first two lines above (middle exactly specified).
5822 if (data->centerstartpara) /* start of paragraph */
5824 data->centerstartpara = False;
5826 if (data->m0flag) /* set automargin */
5827 /* 1 */ data->centermiddle = (indent + textwidth + extwidth + 1) / 2;
5830 /* 2 */ PrintIndent (data, data->centermiddle - ((textwidth + extwidth + 1) / 2));
5833 for(i = 0; i < textwidth; i++)
5835 putwc(outline[i], data->pAdj->outfp);
5837 putc('\n', data->pAdj->outfp);
5845 /************************************************************************
5846 * WORD DATA STRUCTURES USED TO TRACK WORDS WHILE FILLING:
5848 * This complicated scheme is used to minimize the actual data moving
5849 * and manipulation needed to do the job.
5851 * Words are kept in wordbuf[] without trailing nulls. It is large enough
5852 * to accomodate two lines' worth of words plus wrap around to start a new
5853 * word (which might be as big as a line) without overwriting old words
5854 * not yet dumped. wordcp -> next free location in wordbuf[];
5855 * wordcpwrap -> last place a new word is allowed to start.
5857 * Words are pointed to and described by word[] structures. The array is
5858 * big enough to accomodate two lines' worth of words, assuming each word
5859 * takes at least two characters (including separator). wordbase and
5860 * wordlimit are the bounds of the array. wordfirst remembers the first
5861 * word in the array not yet printed. wordat is the word being worked on
5862 * after wordnext is advanced (and maybe wrapped around). New elements
5863 * are "allocated" using wordnext, a pointer that is wrapped around as
5866 * inlinenum and incolumn track the current input line and column per
5867 * paragraph. outlinenum tracks the next line to print. All are base 1,
5868 * but inlinenum is preset to zero at the start of each paragraph.
5870 * pendchars tracks the number of dumpable characters accrued so far, to
5871 * trigger dumping. indent1 and indent2 remember the indentations seen
5872 * for the first two lines of each paragraph.
5875 /************************************************************************
5878 * Parse an input line (in_line to inlinelim) into words and trigger
5879 * FillWord() as needed to finish each word, which in turn can call
5880 * Dump() to dump output lines. This routine sacrifices simplicity and
5881 * clarity for efficiency. It uses shared global word data except
5882 * outlinenum and pendchars.
5886 Fill (FormatData *data,
5887 wint_t *in_line, /* start of input line */
5888 register wint_t *inlinelim) /* end of line + 1 */
5890 register wint_t *incp; /* place in in_line */
5891 register wint_t ch; /* current working char */
5892 int haveword = False; /* hit word in in_line? */
5893 register int inword = False; /* currently in a word? */
5899 data->incolumn = 1; /* starting a line */
5901 for (incp = in_line; incp < inlinelim; incp++)
5906 * AT WHITE SPACE; FINISH PREVIOUS WORD if any, then skip white space:
5911 if (inword) /* was skipping a word */
5917 data->incolumn += ((ch != L'\t') && (iswblank(ch))) ?
5918 1 : data->tabsize - ((data->incolumn - 1) % data->tabsize);
5922 * AT PART OF WORD; START NEW ONE IF NEEDED:
5925 else if (iswprint (ch))
5927 if (! inword) /* start new word */
5931 if (data->wordcp > data->wordcpwrap)/* past wrap point */
5932 data->wordcp = data->wordbuf;/* wraparound buffer */
5934 data->wordat = data->wordnext;
5935 WORDNEXT (data,data->wordnext);
5937 data->wordat->cp = data->wordcp; /* note start of word */
5938 data->wordat->inlinenum = data->inlinenum; /* note input line */
5939 data->wordat->incolumn = data->incolumn; /* note input column */
5940 data->wordat->wclen = 0;
5946 switch (data->inlinenum)/* note indentations */
5949 data->indent1 = data->incolumn - 1;
5952 data->indent2 = data->incolumn - 1;
5959 * SAVE ONE CHAR OF WORD:
5961 *(data->wordcp++) = ch;
5963 int n = wcwidth(ch);
5966 { /* == 0 for a null char */
5967 data->incolumn += n;
5968 data->wordat->wclen++;
5974 /* else skip other chars by doing nothing */
5979 * END OF LINE; HANDLE BLANK LINE, OR FINISH WORD AND AUTOMARGIN:
5982 if (! haveword) /* no text on line */
5984 data->inlinenum--; /* don't count empty lines */
5985 Dump (data, True); /* force end paragraph */
5986 fputc ('\n', data->pAdj->outfp); /* put this empty line */
5987 data->inlinenum = 0; /* start new paragraph */
5989 else /* have text on line */
5991 if (inword) /* line ends in word */
5993 if (data->pendchars > data->fillmargin)
5994 { /* time to dump line */
5995 Dump (data, False); /* not end of paragraph */
5998 if (data->m0flag && (data->inlinenum == 1)) /* need to note right margin */
5999 data->fillmargin = data->wordat->incolumn + data->wordat->length - 1;
6004 /************************************************************************
6007 * Save values for the word just finished and dump the output line if
6008 * needed. Uses shared global word values, but does not touch outlinenum,
6009 * and only increments pendchars.
6011 * Trailing blanks (1 or 2) needed after a word are figured here.
6012 * wordlen is the total length (nonzero) and wordcp points to the char
6013 * past the end of the word. Two blanks are needed after words ending in:
6015 * <terminal>[<quote>][<close>]
6017 * where <terminal> is any of . : ? !
6018 * <quote> is any of ' "
6019 * <close> is any of ) ] }
6021 * For efficiency, this routine avoids calling others to do character
6022 * matching; it does them in line.
6026 FillWord (FormatData *data)
6028 int wordlen; /* length of word to fill */
6029 int blanks = 1; /* trailing blanks needed */
6030 register wint_t ch1, ch2, ch3; /* last chars of word */
6032 data->wordat->length = (data->incolumn - data->wordat->incolumn);
6033 wordlen = data->wordat->wclen;
6036 * CHECK FOR SPECIAL END OF WORD:
6039 ch3 = data->wordcp [-1];
6041 if ((ch3 == L'.') || (ch3 == L':') || (ch3 == L'?') || (ch3 ==L'!'))
6043 blanks = 2; /* <terminal> */
6046 else if (wordlen >= 2)
6048 ch2 = data->wordcp [-2];
6050 if( ((ch2 == L'.') || (ch2 == L':') || (ch2 ==L'?') || (ch2 == L'!')) &&
6051 ((ch3 == L'\'') || (ch3 == L'"') || (ch3 ==L')') || (ch3 == L']')
6055 blanks = 2; /* <terminal><quote or close> */
6057 else if (wordlen >= 3)
6059 ch1 = data->wordcp [-3];
6061 if( ((ch1 == L'.') || (ch1 == L':') || (ch1 == L'?') || (ch1 == L'!'))
6062 && ((ch2 == L'\'') || (ch2 == L'"'))
6063 && ((ch3 == L')') || (ch3 == L']') || (ch3 == L'}')) )
6065 blanks = 2; /* <terminal><quote><close> */
6075 data->pendchars += wordlen + (data->wordat->blanks = blanks);
6080 /************************************************************************
6083 * Print output line(s), with all necessary indentation and formatting,
6084 * if required (at end of paragraph) or if permissible. If required,
6085 * indent1 is used if indent2 is not set yet (not on second line of
6086 * input). Otherwise, if not at end of paragraph, dumping is only
6087 * permissible after beginning the second input line, so fillmargin and
6088 * indent2 are known, so tagged paragraphs are done right.
6090 * Whenever dumping, all "full" lines are dumped, which means more than
6091 * just one may be printed per call. jflag or rflag formatting is
6092 * applied to all lines, except that jflag is ignored for the last line
6093 * of each paragraph.
6095 * Uses shared global word data, but does not touch inlinenum, incolumn,
6096 * indent1, or indent2.
6100 Dump (FormatData *data,
6101 int endpara) /* end of paragraph? */
6103 int haveindent2 = (data->inlinenum >= 2); /* indent2 known? */
6104 int startpara; /* start of paragraph? */
6105 int normal; /* non-tagged line? */
6106 WORD *wordpast = data->wordfirst; /* past last to dump */
6107 register int wordlen; /* length of one word */
6108 int indent; /* local value */
6109 register int outneed; /* chars need to dump */
6110 int outchars; /* chars found to dump */
6113 * IF DUMPING NEEDED, DUMP LINES TILL DONE:
6116 if (! (endpara || haveindent2)) /* not time to dump */
6119 while ( (data->pendchars > data->fillmargin) /* line is full */
6120 || (endpara && (data->wordfirst != data->wordnext)) ) /* more to dump */
6122 startpara = (data->outlinenum < 2);
6123 indent = (startpara || (! haveindent2)) ? data->indent1 : data->indent2;
6126 * CHECK FOR TAGGED PARAGRAPH if needed:
6129 normal = True; /* default == no tag */
6131 if (startpara && haveindent2 && (data->indent1 < data->indent2))
6133 int incol2 = data->indent2 + 1; /* column needed */
6135 while ( (wordpast != data->wordnext) /* more words */
6136 && (wordpast->inlinenum == 1)) /* from line 1 */
6138 if (wordpast->incolumn == incol2) /* bingo */
6143 WORDNEXT (data,wordpast);
6147 wordpast = data->wordfirst; /* reset value */
6150 * PRINT TAG PART OF TAGGED PARAGRAPH:
6155 WORD *wordat = data->wordfirst; /* local value */
6157 while (wordat != wordpast) /* decrement pendchars */
6159 data->pendchars -= wordat->length + wordat->blanks;
6160 WORDNEXT (data,wordat);
6163 PrintIndent (data, indent);
6164 PrintTag (data, wordpast); /* preceding words */
6165 data->wordfirst = wordpast; /* do rest of line */
6166 indent = data->indent2; /* as if second line */
6171 * FIND WORDS WHICH FIT ON [REST OF] LINE:
6174 if (indent >= data->fillmargin) /* don't over indent */
6175 indent = data->fillmargin - 1;
6177 outneed = data->fillmargin - indent; /* always greater than zero */
6179 wordlen = wordpast->length;
6181 do { /* always consume one */
6182 outchars += wordlen + wordpast->blanks;
6183 WORDNEXT (data,wordpast);
6184 } while ( (wordpast != data->wordnext) /* not last word */
6185 && (outchars + (wordlen = wordpast->length) <= outneed)
6191 ** BEKINSOKU/EKINSOKU PROCESSING
6193 if( EkinBekinProc(data, &wordpast) )
6194 postEkinBekinProc(data, &outchars,wordpast);
6195 data->pendchars -= outchars; /* pendchars to consume */
6197 /* from now on, don't include trailing blanks on last word */
6198 outchars -= (WORDPREV (data,wordpast) -> blanks);
6200 /* now wordfirst and wordpast specify the words to dump */
6202 * PRINT INDENTATION AND PREPARE JUSTIFICATION:
6205 if (data->pAdj->rflag) /* right-justify only */
6207 if (normal) /* nothing printed yet */
6208 PrintIndent (data, data->fillmargin - outchars);
6209 else /* indent + tag printed */
6211 int blanks = data->fillmargin - outchars - indent;
6213 while (blanks-- > 0) /* can't use PrintIndent()*/
6214 putwc(data->Blank, data->pAdj->outfp);
6219 if (normal) /* not already done */
6220 PrintIndent (data, indent);
6222 if (data->pAdj->jflag && ! (endpara && (wordpast == data->wordnext)))
6223 Justify (data, outneed - outchars, wordpast);
6227 * PRINT REST OF LINE:
6230 PrintWords (data, wordpast);
6231 putwc('\n', data->pAdj->outfp);
6232 data->wordfirst = wordpast;
6233 data->outlinenum++; /* affects startpara */
6238 data->outlinenum = 1;
6243 /************************************************************************
6244 * P R I N T I N D E N T
6246 * Print line indentation (if > 0), optionally using tabs where possible.
6247 * Does not print a newline.
6251 PrintIndent (FormatData *data,
6252 int indent) /* leading indentation */
6254 if (indent > 0) /* indentation needed */
6256 if (! data->pAdj->bflag) /* unexpand leading blanks */
6258 while (indent >= data->tabsize)
6260 putc ('\t', data->pAdj->outfp);
6261 indent -= data->tabsize;
6264 fprintf (data->pAdj->outfp, "%*s", indent, "");/*[remaining] blanks */
6269 /************************************************************************
6272 * Print paragraph tag words from word[] array beginning with (global)
6273 * wordfirst and ending before (parameter) wordpast, using input column
6274 * positions in each word's data. Assumes indentation of indent1 was
6275 * already printed on the line. Assumes *wordpast is the next word on
6276 * the line and its column position is valid, and appends spaces up to
6277 * the start of that word. Doesn't print a newline.
6279 * Line indentation must already be done, as this routine doesn't know
6280 * how to print leading tabs, only blanks.
6284 PrintTag (FormatData *data,
6285 WORD *wordpast) /* past last to print */
6287 register WORD *wordat = data->wordfirst; /* local value */
6288 register int outcol = data->indent1 + 1; /* next column */
6289 int wordcol; /* desired column */
6290 register wint_t *wordcp; /* place in word */
6291 wint_t *wordcplim; /* limit of word */
6293 while (True) /* till break */
6295 wordcol = wordat->incolumn;
6297 while (outcol < wordcol)/* space over to word */
6299 putwc(data->Blank, data->pAdj->outfp);
6303 if (wordat == wordpast) /* past last word */
6304 break; /* quit the loop */
6306 wordcp = wordat->cp;
6308 wordcplim = wordcp + wordat->wclen;
6310 while (wordcp < wordcplim) /* print word */
6311 putwc(*wordcp++, data->pAdj->outfp);
6313 outcol += wordat->length;
6314 WORDNEXT (data,wordat);
6319 /************************************************************************
6320 * P R I N T W O R D S
6322 * Print words from word[] array beginning with (global) wordfirst and
6323 * ending before (parameter) wordpast, using word sizes and trailing
6324 * blanks (except for last word on line). Doesn't print a newline.
6328 PrintWords (FormatData *data,
6329 WORD *wordpast) /* past last to print */
6331 register WORD *wordat = data->wordfirst; /* local value */
6332 register wint_t *wordcp; /* place in word */
6333 wint_t *wordcplim; /* limit of word */
6334 register int blanks; /* after a word */
6336 while (True) /* till break */
6338 wordcp = wordat->cp;
6339 wordcplim = wordcp + wordat->wclen;
6340 blanks = wordat->blanks; /* set before do WORDNEXT() */
6342 while (wordcp < wordcplim) /* print word */
6344 putwc(*wordcp++, data->pAdj->outfp);
6348 WORDNEXT (data,wordat);
6350 if (wordat == wordpast) /* just did last word */
6353 while (blanks-- > 0) /* print trailing blanks */
6354 putwc(data->Blank, data->pAdj->outfp);
6360 /************************************************************************
6363 * Do left/right justification of [part of] a line in the word[] array
6364 * beginning with (global) wordfirst and ending before (parameter)
6365 * wordpast, by figuring where to insert blanks.
6367 * Gives each word (except the last on the line) a score based on its
6368 * size plus the size of the next word. Quicksorts word indices into
6369 * order of current trailing blanks (least first), then score (most
6370 * first). Cycles through this list adding trailing blanks to word[]
6371 * entries such that words will space out nicely when printed.
6375 Justify (FormatData *data,
6376 register int blanks, /* blanks to insert */
6377 WORD *wordpast) /* past last to print */
6379 register WORD *wordat; /* local value */
6380 register int sortat; /* place in sort[] */
6381 register int wordlen; /* size of this word */
6382 register int nextlen; /* size of next word */
6383 int level; /* current blanks level */
6385 WORD *sort [WORDMAX]; /* sorted pointers */
6386 int words; /* words in sort[] */
6388 wordat = WORDPREV (data,wordpast); /* last word on line */
6390 if ((blanks < 1) || (wordat == data->wordfirst))
6391 return; /* can't do anything */
6394 * COMPUTE SCORES FOR WORDS AND SORT INDICES:
6396 * March backwards through the words on line, starting with next to last.
6400 nextlen = wordat->length; /* length of last word */
6402 do { /* always at least one */
6403 wordat = WORDPREV (data,wordat);
6404 wordlen = wordat->length;
6405 wordat->score = wordlen + nextlen; /* this plus next */
6407 sort [words++] = wordat; /* prepare for sorting */
6408 } while (wordat != data->wordfirst);
6410 qsort ((wint_t *) sort, words, sizeof (WORD *), CompareWords);
6413 * ADD TRAILING BLANKS TO PAD OUT WORDS:
6415 * Each pass through the sorted list adds one trailing blank to each word
6416 * not already past the current level. Thus all one-blank words are brought
6417 * up to two; then all twos up to three; etc.
6422 while (True) /* till return */
6426 for (sortat = 0; sortat < words; sortat++)
6428 wordat = sort [sortat];
6429 if (wordat->blanks > level) /* end of this level */
6430 break; /* start next level */
6433 if (--blanks <= 0) /* no more needed */
6441 /************************************************************************
6442 * C O M P A R E W O R D S
6444 * Compare two word[] entries based on pointers to (WORD *), as called
6445 * from qsort(3). Tell which entry has priority for receiving inserted
6446 * blanks (least trailing blanks first, then highest scores), by returning
6447 * -1 for the first entry, +1 for second entry, or 0 if no difference.
6448 * (-1 literally means first entry < second entry, so it sorts first.)
6452 CompareWords (const void *p1, const void *p2)
6454 WORD *word1 = *((WORD **)p1); /* (WORD *) pointers */
6455 WORD *word2 = *((WORD **)p2);
6456 int blanks1 = word1->blanks; /* trailing blanks */
6457 int blanks2 = word2->blanks;
6459 if (blanks1 == blanks2) /* commonest case */
6461 int score1 = word1->score; /* word scores */
6462 int score2 = word2->score;
6464 if (score1 > score2) return (-1); /* word1 has priority */
6465 else if (score1 < score2) return ( 1);
6468 else if (blanks1 < blanks2) return (-1); /* word1 has priority */
6471 } /* CompareWords */
6475 ** BKINSOKU and EKINSOKU processing for Japanese text
6477 ** The function scans the wordlist that are ready for printing
6478 ** and updates the "wordpast" pointer based on the rules of
6479 ** BKINSOKU and EKINSOKU characters.
6481 ** The code does not split a line just after a "gyomatu kinsoku"
6482 ** character and just before a "gyoto kinsoku" character.
6483 ** "Gyomatsu kinsoku" (e-kinsoku) are characters which cannot be
6484 ** placed at the end of a line. "Gyoto kinsoku" (b-kinsoku) are
6485 ** characters which can not be placed at the top of a line.
6487 ** Global variables used:
6488 ** wordfirst - beginning the word list (buffer of pending lines)
6489 ** wordnext - next available spot in the pending buffer (i.e.
6490 ** end of the buffer).
6492 ** Global variables modified:
6496 ** 0 - No Post processing is required.
6497 ** 1 - Post processing is required
6500 #if !(defined(sun) && (_XOPEN_VERSION==3))
6502 EkinBekinProc(FormatData *data,
6505 WORD *curword,*compword,*prevword;
6506 int ekinflag = False, margin;
6509 * curword points to the last word of the first line.
6510 * compword points to the first word of the next line or to the next
6511 * available spot if there is no next line.
6513 compword = *wordpast;
6514 curword = WORDPREV(data,compword);
6517 * If the length of the current word is > fillmargin
6518 * or it is the only word then return.
6520 if (curword->length > data->fillmargin || (curword == data->wordfirst))
6524 * EKINSOKU processing
6525 * If this character set supports ekinclass (can't end a line) char,
6526 * start at the end of the line and search back until
6527 * 1) we find a non-ekinsoku character, or
6528 * 2) come to the beginning of the pending buffer.
6532 while (isekinsoku(*(curword->cp+curword->wclen-1)))
6535 if (curword == data->wordfirst) /* Boundary Condition */
6537 curword = WORDPREV(data,curword);
6541 * Post EKIN processing (i.e. we found an ekinsoku character in
6542 * the line before finding an non-ekinsoku).
6546 if (curword != data->wordfirst) {
6548 * We found a non-ekinsoku after we found the ekinsoku.
6549 * Move the end of line to just after the non-ekinsoku.
6551 WORDNEXT(data,curword);
6552 *wordpast = curword;
6555 else { /* Boundary condition */
6557 * Reached the beginning of the buffer without finding a
6558 * non-ekinsoku. If the last word in the line can begin
6559 * a line (i.e. non-bkinsoku) make it the first word of
6562 curword = WORDPREV(data,compword);
6563 if (!isbekinsoku(*curword->cp)) {
6564 *wordpast = curword;
6573 * If we reached this point then:
6574 * 1) the character set does not support ekinclass characters, or
6575 * 2) the last character in the line is non-ekinsoku.
6576 * Now, need to see if we can begin the next line with the first
6577 * character on that line.
6581 * BEKINSOKU processing
6582 * If this character set supports bekinclass (can't begin a line) char,
6583 * search forward from the begining of the next line (curword) to the
6584 * end of the buffer (wordnext) until:
6585 * 1) A non-bekinsoku word is found,
6586 * 2) if the line limit exceeds the set value, or
6587 * 3) we reach the end of the buffer.
6593 * compword points to the first word of the next line.
6596 margin = data->indent2;
6598 while (curword != data->wordnext)
6600 if (!isbekinsoku(*curword->cp))
6602 margin += (curword->length + curword->blanks);
6603 if (margin >= data->fillmargin)
6605 WORDNEXT(data,curword);
6608 if (curword != data->wordnext && curword != compword)
6611 * The first word of the second line is bekinsoku so search
6612 * backwards from end of first line until we are:
6613 * 1) not at the first word of the buffer, and
6614 * 2) not in between either an ekinsoku or bekinsoku character.
6618 * compword points to the first word of the next line.
6619 * curword points to the last word of the first line.
6621 curword = WORDPREV(data,compword);
6622 prevword = WORDPREV(data,curword);
6623 while ( (curword != data->wordfirst) &&
6624 (isbekinsoku(*curword->cp) ||
6625 isekinsoku(*(prevword->cp+prevword->wclen-1)))
6628 margin += curword->length + curword->blanks;
6629 if (margin >= data->fillmargin)
6632 prevword = WORDPREV(data,curword);
6635 if (curword != data->wordfirst) {
6637 * Did not reach the beginning of the buffer so we are between
6638 * two non-ekinsoku & non-bekinsoku characters. Move the end
6639 * of the first line here.
6642 *wordpast = curword;
6652 } /* end EkinBekinProc */
6657 EkinBekinProc(FormatData *data,
6660 WORD *curword,*compword,*prevword,*nextword;
6661 int margin = data->indent2;
6664 * prevword points to the last word of the first line.
6665 * compword & curword point to the first word of the next line or
6666 * to the next available spot in the buffer if there is no next line.
6668 compword = *wordpast;
6670 prevword = WORDPREV(data,curword);
6673 * If the length of the previous word is > fillmargin
6674 * or it is the only word in the line then return.
6675 * wordfirst points to the beginning of the buffer of pending lines.
6677 if (prevword->length > data->fillmargin || (prevword == data->wordfirst))
6681 * Starting at the beginning of the next line, search backwards
6683 * 1) we find two words we can split between lines, or
6684 * 2) we reach the beginning of the buffer.
6686 * If there is no next line start with the last two words of this line
6687 * (wordnext points to the next available space in the buffer (i.e
6688 * the end of the buffer).
6691 if (curword == data->wordnext) {
6693 prevword = WORDPREV(data,curword);
6696 while ( (curword != data->wordfirst) &&
6697 (wdbindf(*(prevword->cp+prevword->wclen-1), *curword->cp, 1) >4)
6701 prevword = WORDPREV(data,curword);
6704 if (curword != data->wordfirst) {
6707 * Did not reach the beginning of the buffer so we are between
6708 * two non-ekinsoku & non-bekinsoku characters. Move the end
6709 * of the first line here.
6712 *wordpast = curword;
6719 * Reached the beginning of the buffer so search forward
6720 * from the beginning of the second line until:
6721 * 1) we find two words we can split between lines,
6722 * 2) we reach the end of the buffer, or
6723 * 3) the line becomes too long.
6725 * If there is no next line then just exit.
6729 * compword points to the first word of the next line or to the
6730 * next available spot in the buffer if there is no next line.
6731 * nextword points to the second word of the next line.
6732 * wordnext points to the next available space in the buffer (i.e
6733 * the end of the buffer)
6736 nextword = compword;
6737 WORDNEXT(data,nextword);
6739 if (curword == data->wordnext)
6742 while (nextword != data->wordnext)
6745 if (wdbindf(*(curword->cp+curword->wclen-1), *nextword->cp, 1) < 5)
6747 margin += (curword->length + curword->blanks);
6748 if (margin >= data->fillmargin)
6751 WORDNEXT(data,nextword);
6754 if (nextword != data->wordnext) {
6757 * Did not reach the end of the buffer so we are between
6758 * two non-ekinsoku & non-bekinsoku characters. Move the end
6759 * of the first line here.
6761 *wordpast = nextword;
6769 } /* end EkinBekinProc */
6771 #endif /* not sun */
6774 postEkinBekinProc(FormatData *data,
6779 int colvalue,curlineno;
6782 * Recompute the value of *poutchars
6787 curword = data->wordfirst;
6788 while (curword != wordpast)
6790 (*poutchars) += curword->length + curword->blanks;
6791 WORDNEXT(data,curword);
6795 ** Adjust the word parameters -
6796 ** inlinenum,incolumn of all the words
6797 ** from 'curword' till 'wordnext'
6801 curlineno = curword->inlinenum+1;
6802 colvalue = data->indent2;
6803 while (curword != data->wordnext)
6805 curword->inlinenum = curlineno;
6806 curword->incolumn = colvalue;
6807 colvalue += curword->length + curword->blanks;
6808 if (colvalue > data->fillmargin)
6810 colvalue = data->indent2;
6813 WORDNEXT(data,curword);
6815 data->incolumn = colvalue;
6816 data->inlinenum = curlineno;
6829 for (i=0; i < pword->wclen; i++)
6830 fprintf(stderr,(const char *)"%c",(char)*(pword->cp+i));
6831 fprintf(stderr,"Word Length :%d\n",pword->wclen);
6840 caddr_t client_data,
6844 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6845 DtEDITOR_FORMAT_PARAGRAPH );
6847 } /* AdjustParaCB */
6853 caddr_t client_data,
6857 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6858 DtEDITOR_FORMAT_ALL );
6865 * DoAdjust - given left & right margin values & an alignment style, formats
6866 * the text from one specified text position to another.
6869 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
6870 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
6872 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
6874 * DtEDITOR_INVALID_TYPE if specified alignment is
6878 static DtEditorErrorCode
6880 DtEditorWidget editor,
6883 unsigned int alignment,
6884 XmTextPosition start,
6887 char tempName1[L_tmpnam], tempName2[L_tmpnam];
6888 DtEditorErrorCode returnVal;
6892 * Check that valid margin values were passed in
6894 if( leftMargin >= 0 &&
6896 rightMargin < 1025 &&
6897 leftMargin <= rightMargin )
6902 _DtTurnOnHourGlass(M_topLevelShell(editor));
6903 if (M_format_dialog(editor) != (Widget)NULL)
6904 _DtTurnOnHourGlass(M_format_dialog(editor));
6906 memset(&adjRec, 0, sizeof(AdjRec));
6908 /* The adjust text formatting code works with a data
6909 representation to the screen of 1 byte per column for
6910 multibyte environment. The Motif text Widget has a data
6911 representation of 2 bytes per column in multibyte, so we must
6912 fool the adjust code into thinking the margins are twice the
6913 size in a multibyte environment.
6918 rightMargin = rightMargin * 2;
6919 leftMargin = leftMargin * 2;
6924 case DtEDITOR_ALIGN_CENTER:
6927 adjRec.margin = (rightMargin + leftMargin) / 2;
6931 case DtEDITOR_ALIGN_JUSTIFY:
6934 adjRec.margin = rightMargin;
6938 case DtEDITOR_ALIGN_RIGHT:
6941 adjRec.margin = rightMargin;
6945 case DtEDITOR_ALIGN_LEFT:
6947 adjRec.margin = rightMargin;
6953 returnVal = DtEDITOR_INVALID_TYPE;
6959 * Turn off converting leading spaces into tabs if we are
6960 * working in a multi-byte locale. This is necessary
6961 * because a tab may not equal (be as wide as) 8 spaces in
6962 * a multi-byte locale.
6967 adjRec.bflag = True;
6969 adjRec.bflag = False;
6973 * Create the two temp files
6975 (void)tmpnam(tempName1);
6976 (void)tmpnam(tempName2);
6977 if ((adjRec.infp = fopen(tempName1, "w+")) != (FILE *)NULL) {
6980 * Successfully opened the first temporary file
6983 if((adjRec.outfp = fopen(tempName2, "w")) != (FILE *)NULL) {
6986 * Successfully opened the second temporary file, so do the
6989 returnVal = DtEDITOR_NO_ERRORS;
6991 fixLeftMarginAndNewlines( editor, adjRec.infp, leftMargin,
6992 rightMargin, (int)start, (int)end );
6993 fflush(adjRec.infp);
6994 rewind(adjRec.infp);
6996 FormatText(&adjRec);
6998 fclose(adjRec.infp);
7001 fclose(adjRec.outfp);
7003 DtEditorReplaceFromFile( (Widget)editor, start, end, tempName2 );
7009 * Could not open second temporary file, so clean up first one
7011 fclose(adjRec.infp);
7013 returnVal = DtEDITOR_NO_TMP_FILE;
7016 } /* end creating temporary files */
7018 returnVal = DtEDITOR_NO_TMP_FILE;
7023 _DtTurnOffHourGlass(M_topLevelShell(editor));
7024 if (M_format_dialog(editor) != (Widget)NULL)
7025 _DtTurnOffHourGlass(M_format_dialog(editor));
7027 } /* end check for valid margins */
7029 returnVal = DtEDITOR_ILLEGAL_SIZE;
7038 caddr_t client_data,
7041 DtEditorWidget editor = (DtEditorWidget )client_data;
7042 XtUnmanageChild (M_format_dialog(editor));
7048 DtEditorWidget editor)
7050 Dimension text_width, highlight_thickness, shadow_thickness,
7053 Arg al[5]; /* arg list */
7054 register int ac; /* arg count */
7057 XtSetArg(al[ac], XmNwidth, &text_width); ac++;
7058 XtSetArg(al[ac], XmNhighlightThickness, &highlight_thickness); ac++;
7059 XtSetArg(al[ac], XmNshadowThickness, &shadow_thickness); ac++;
7060 XtSetArg(al[ac], XmNmarginWidth, &margin_width); ac++;
7061 XtGetValues(M_text(editor), al, ac);
7063 if (M_fontWidth(editor) != 0)
7064 rightMargin = ( (int)text_width -
7065 (2 * ((int)highlight_thickness +
7066 (int)shadow_thickness + (int)margin_width))
7067 ) / M_fontWidth(editor);
7069 rightMargin = (int)text_width -
7070 (2 * ((int)highlight_thickness +
7071 (int)shadow_thickness + (int)margin_width));
7073 return( rightMargin );
7075 } /* end ComputeRightMargin */
7081 XtPointer *client_data,
7082 XConfigureEvent *event )
7085 DtEditorWidget editor = (DtEditorWidget) client_data;
7086 char orgnum[20]; /* original margin size string */
7089 XtSetArg(al[0], XmNwidth, &width);
7090 XtGetValues(M_text(editor), al, 1);
7092 if (width == M_textWidth(editor))
7095 M_textWidth(editor) = width;
7097 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7098 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7101 /************************************************************************
7103 * SetFormatDialogTitle - Change the title for the Format Settings dialog
7105 ************************************************************************/
7108 SetFormatDialogTitle(
7109 DtEditorWidget editor)
7114 * If the Format Settings dialog has been created, change its title
7116 if( M_format_dialog(editor) != (Widget)NULL )
7120 * Prepend the DialogTitle resource, if it has been set
7122 if( E_dialogTitle(editor) != (XmString)NULL ) {
7126 * Add the "functional title" to the DialogTitle
7128 titleStr = XmStringConcat( E_dialogTitle(editor),
7129 E_format_dialogTitle(editor) );
7131 XtSetArg( al[0], XmNdialogTitle, titleStr );
7132 XtSetValues(M_format_dialog(editor), al, 1);
7134 XmStringFree( titleStr );
7138 XtSetArg( al[0], XmNdialogTitle, E_format_dialogTitle(editor) );
7139 XtSetValues(M_format_dialog(editor), al, 1);
7144 } /* end SetFormatDialogTitle */
7146 /************************************************************************
7148 * ResetFormatDialog - Reset margins & alignment of the Format Settings
7151 ************************************************************************/
7155 DtEditorWidget editor)
7157 char orgnum[20]; /* original margin size string */
7160 * Reset the margins to default values
7163 /* Right margin default value */
7164 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7165 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7167 /* Left margin default value */
7168 sprintf(orgnum, "%d", 0);
7169 XmTextFieldSetString(M_format_leftMarginField(editor), orgnum);
7172 * Reset the alignment style to default value
7174 XmToggleButtonGadgetSetState(M_format_leftJust(editor), True, True);
7176 } /* end ResetFormatDialog */
7179 /************************************************************************
7181 * CreateFormatDialog - Create & initialize the Format Settings dialog
7183 ************************************************************************/
7187 DtEditorWidget editor)
7189 Arg al[15]; /* arg list */
7190 register int ac; /* arg count */
7191 Pixel textBackground, textForeground;
7192 XmString tempString = (XmString)NULL;
7195 * Match the background & foreground colors of the edit window
7196 * Don't use DtNtextBackground/Foreground directly because they
7197 * will be DtUNSPECIFIED.
7200 XtSetArg(al[ac], XmNforeground, &textForeground); ac++;
7201 XtSetArg(al[ac], XmNbackground, &textBackground); ac++;
7202 XtGetValues(M_text(editor), al, ac);
7207 * First, create the dialog's title, prepending the
7208 * DtNdialogTitle resource, if it is set
7210 if( E_dialogTitle(editor) != (XmString)NULL ) {
7213 * Add the "functional title" to the DialogTitle
7215 tempString = XmStringConcat( E_dialogTitle(editor),
7216 E_format_dialogTitle(editor) );
7217 XtSetArg (al[ac], XmNdialogTitle, tempString ); ac++;
7221 XtSetArg(al[ac], XmNdialogTitle, E_format_dialogTitle(editor)); ac++;
7224 XtSetArg (al[ac], XmNautoUnmanage, False); ac++;
7225 XtSetArg (al[ac], XmNmarginWidth, 5); ac++;
7226 XtSetArg (al[ac], XmNmarginHeight, 5); ac++;
7227 XtSetArg (al[ac], XmNshadowThickness, 1); ac++;
7228 XtSetArg (al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
7229 XtSetArg (al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
7230 M_format_dialog(editor) = XmCreateFormDialog(
7231 M_topLevelShell(editor), "ad_dial", al, ac);
7232 if (tempString != (XmString)NULL)
7233 XmStringFree( tempString );
7235 XtAddCallback(M_format_dialog(editor), XmNhelpCallback,
7236 (XtCallbackProc)HelpFormatDialogCB, (XtPointer)editor);
7240 * When creating the fields & buttons use the appropriate label
7241 * resource (e.g. DtNcenterToggleLabel), if it has been set, then
7242 * clear the resource to save space. The field or button widget
7243 * will contain the actual value & it can be gotten from there,
7246 * If the appropriate resource has not been set, use its default
7247 * value from the message catalog.
7251 * create the left margin label and text field
7255 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED) {
7257 * Use the resource value & clear it (to save space).
7259 tempString = XmStringCopy(E_format_leftMarginFieldLabel(editor));
7260 E_format_leftMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7264 * The resource has not been set so use its default value
7266 tempString = XmStringCreateLocalized(LEFT_MARGIN);
7269 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7270 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7271 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7272 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7273 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7274 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7275 M_format_leftLabel(editor) = (Widget) XmCreateLabelGadget (
7276 M_format_dialog(editor), "left_label", al, ac);
7277 XtManageChild (M_format_leftLabel(editor));
7278 XmStringFree (tempString);
7280 XtAddCallback(M_format_leftLabel(editor), XmNhelpCallback,
7281 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7284 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7285 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7286 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7287 XtSetArg (al[ac], XmNleftWidget, M_format_leftLabel(editor)); ac++;
7288 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7289 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7290 XtSetArg (al[ac], XmNrightPosition, 45); ac++;
7291 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7292 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7293 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7294 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7295 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7296 M_format_leftMarginField(editor) = (Widget) XmCreateTextField (
7297 M_format_dialog(editor), "left_text", al, ac);
7298 XtManageChild (M_format_leftMarginField(editor));
7299 XtAddCallback(M_format_leftMarginField(editor), XmNhelpCallback,
7300 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7302 * create the right margin label and text field
7305 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
7308 * Use the resource value & clear it (to save space).
7310 tempString = XmStringCopy(E_format_rightMarginFieldLabel(editor));
7311 E_format_rightMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7316 * The resource has not been set so use its default value
7318 tempString = XmStringCreateLocalized(RIGHT_MARGIN);
7320 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7321 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7322 XtSetArg (al[ac], XmNleftPosition, 55); ac++;
7323 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7324 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7325 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7326 M_format_rightLabel(editor)= (Widget) XmCreateLabelGadget (
7327 M_format_dialog(editor), "right_label", al, ac);
7328 XtManageChild (M_format_rightLabel(editor));
7329 XmStringFree (tempString);
7330 XtAddCallback(M_format_rightLabel(editor), XmNhelpCallback,
7331 (XtCallbackProc)HelpFormatRightMarginCB,
7334 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7335 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7336 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7337 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7338 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7339 XtSetArg (al[ac], XmNleftWidget, M_format_rightLabel(editor)); ac++;
7340 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7341 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7342 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7343 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7344 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7345 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7346 M_format_rightMarginField(editor) = (Widget) XmCreateTextField (
7347 M_format_dialog(editor),
7348 "right_text", al, ac);
7349 XtManageChild (M_format_rightMarginField(editor));
7350 XtAddCallback(M_format_rightMarginField(editor), XmNhelpCallback,
7351 (XtCallbackProc)HelpFormatRightMarginCB,
7355 * create the radio box for justification choices
7358 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7359 XtSetArg (al[ac], XmNleftOffset, 5); ac++;
7360 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7361 XtSetArg (al[ac], XmNtopWidget, M_format_leftMarginField(editor)); ac++;
7362 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7363 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7364 XtSetArg (al[ac], XmNrightOffset, 5); ac++;
7365 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7366 M_format_radioBox(editor) = (Widget) XmCreateRadioBox(
7367 M_format_dialog(editor), "radioBox", al, ac);
7368 XtAddCallback(M_format_radioBox(editor), XmNhelpCallback,
7369 (XtCallbackProc)HelpFormatJustifyButtonsCB,
7371 XtManageChild(M_format_radioBox(editor));
7373 /* Create Left Align toggle */
7375 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7377 * Use the resource value & clear it (to save space).
7379 tempString = XmStringCopy(E_format_leftAlignToggleLabel(editor));
7380 E_format_leftAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7384 * The resource has not been set so use its default value
7386 tempString = XmStringCreateLocalized(LEFT_ALIGN);
7388 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7389 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7390 M_format_leftJust(editor) = (Widget) XmCreateToggleButtonGadget(
7391 M_format_radioBox(editor), "left_just", al, ac);
7392 XmStringFree (tempString);
7393 XtManageChild(M_format_leftJust(editor));
7395 /* Create Right Align toggle */
7397 if(E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED) {
7399 * Use the resource value & clear it (to save space).
7401 tempString = XmStringCopy(E_format_rightAlignToggleLabel(editor));
7402 E_format_rightAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7406 * The resource has not been set so use its default value
7408 tempString = XmStringCreateLocalized(RIGHT_ALIGN);
7410 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7411 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7412 M_format_rightJust(editor) = (Widget) XmCreateToggleButtonGadget(
7413 M_format_radioBox(editor), "right_just", al, ac);
7414 XmStringFree (tempString);
7415 XtManageChild(M_format_rightJust(editor));
7417 /* Create Justify toggle */
7419 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7421 * Use the resource value & clear it (to save space).
7423 tempString = XmStringCopy(E_format_justifyToggleLabel(editor));
7424 E_format_justifyToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7428 * The resource has not been set so use its default value
7430 tempString = XmStringCreateLocalized( JUSTIFY );
7432 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7433 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7434 M_format_bothJust(editor) = (Widget) XmCreateToggleButtonGadget(
7435 M_format_radioBox(editor), "both_just", al, ac);
7436 XmStringFree (tempString);
7437 XtManageChild(M_format_bothJust(editor));
7439 /* Create Center align toggle */
7441 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7443 * Use the resource value & clear it (to save space).
7445 tempString = XmStringCopy(E_format_centerToggleLabel(editor));
7446 E_format_centerToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7450 * The resource has not been set so use its default value
7452 tempString = XmStringCreateLocalized(CENTER);
7454 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7455 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7456 M_format_center(editor) = (Widget) XmCreateToggleButtonGadget(
7457 M_format_radioBox(editor), "center", al, ac);
7458 XmStringFree(tempString);
7459 XtManageChild(M_format_center(editor));
7461 /* Create a separator between the radio box and buttons */
7464 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7465 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7466 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7467 XtSetArg (al[ac], XmNtopWidget, M_format_radioBox(editor)); ac++;
7468 XtSetArg (al[ac], XmNtopOffset, 15); ac++;
7469 M_format_separator(editor) = (Widget) XmCreateSeparatorGadget (
7470 M_format_dialog(editor), "separator", al, ac);
7471 XtManageChild (M_format_separator(editor));
7473 /* Create Format Paragraph button */
7475 if ( E_format_formatParagraphButtonLabel(editor) !=
7476 (XmString) DtUNSPECIFIED ) {
7478 * Use the resource value & clear it (to save space).
7480 tempString = XmStringCopy(E_format_formatParagraphButtonLabel(editor));
7481 E_format_formatParagraphButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7485 * The resource has not been set so use its default value
7487 tempString = XmStringCreateLocalized(PARAGRAPH);
7489 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7490 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7491 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7492 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7493 XtSetArg (al[ac], XmNrightPosition, 25); ac++;
7494 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7495 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7496 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7497 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7498 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7499 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7500 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7501 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7502 M_format_paragraph(editor) = (Widget) XmCreatePushButtonGadget (
7503 M_format_dialog(editor), "para", al, ac);
7504 XtManageChild (M_format_paragraph(editor));
7505 XmStringFree (tempString);
7506 XtAddCallback (M_format_paragraph(editor), XmNactivateCallback,
7507 (XtCallbackProc) AdjustParaCB, (XtPointer) editor);
7509 /* Create Format All button */
7511 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED) {
7513 * Use the resource value & clear it (to save space).
7515 tempString = XmStringCopy(E_format_formatAllButtonLabel(editor));
7516 E_format_formatAllButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7520 * The resource has not been set so use its default value
7522 tempString = XmStringCreateLocalized(ALL);
7524 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7525 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7526 XtSetArg (al[ac], XmNleftPosition, 27); ac++;
7527 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7528 XtSetArg (al[ac], XmNrightPosition, 49); ac++;
7529 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7530 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7531 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7532 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7533 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7534 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7535 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7536 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7537 M_format_all(editor) = (Widget) XmCreatePushButtonGadget(
7538 M_format_dialog(editor), "all", al, ac);
7539 XtManageChild (M_format_all(editor));
7540 XmStringFree (tempString);
7541 XtAddCallback (M_format_all(editor), XmNactivateCallback,
7542 (XtCallbackProc) AdjustAllCB, (XtPointer) editor);
7544 /* Create Close button */
7545 tempString = XmStringCreateLocalized(CLOSE_BUTTON);
7547 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7548 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7549 XtSetArg (al[ac], XmNleftPosition, 51); ac++;
7550 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7551 XtSetArg (al[ac], XmNrightPosition, 73); ac++;
7552 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7553 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7554 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7555 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7556 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7557 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7558 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7559 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7560 M_format_close(editor) = (Widget) XmCreatePushButtonGadget (
7561 M_format_dialog(editor), "close", al, ac);
7562 XtManageChild (M_format_close(editor));
7563 XmStringFree (tempString);
7564 XtAddCallback (M_format_close(editor), XmNactivateCallback,
7565 (XtCallbackProc) AdjustCloseCB, (XtPointer) editor);
7567 tempString = XmStringCreateLocalized(HELP_BUTTON);
7569 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7570 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7571 XtSetArg (al[ac], XmNleftPosition, 75); ac++;
7572 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7573 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7574 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7575 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7576 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7577 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7578 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7579 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7580 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7581 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7582 M_format_help(editor) = (Widget) XmCreatePushButtonGadget(
7583 M_format_dialog(editor), "help", al, ac);
7584 XtManageChild (M_format_help(editor));
7585 XmStringFree (tempString);
7586 XtAddCallback( M_format_help(editor), XmNactivateCallback,
7587 (XtCallbackProc) HelpFormatDialogCB, (XtPointer) editor);
7590 * set the default/activation button.
7592 XtSetArg(al[0], XmNdefaultButton, M_format_close(editor));
7593 XtSetValues(M_format_dialog(editor), al, 1);
7595 XtRealizeWidget (M_format_dialog(editor));
7598 * Initialize the margins & alignment toggles
7600 ResetFormatDialog(editor);
7602 XtSetArg(al[0], XmNwidth, &(M_textWidth(editor)));
7603 XtGetValues(M_text(editor), al, 1);
7605 XtAddEventHandler(M_text(editor), StructureNotifyMask, False,
7606 (XtEventHandler) UpdateAdjust, (XtPointer) editor);
7608 } /* end CreateFormatDialog */
7610 /************************************************************************
7612 * GetAdjustSettings - Read the alignment settings from the Format
7615 ************************************************************************/
7619 DtEditorWidget editor,
7620 DtEditorFormatSettings *formatSettings)
7623 if( M_format_dialog(editor)!= (Widget)NULL ) {
7626 * Read the current alignment settings from the Format Settings
7632 * Get current type of alignment
7634 if (XmToggleButtonGadgetGetState(M_format_leftJust(editor)))
7635 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7636 else if (XmToggleButtonGadgetGetState(M_format_rightJust(editor)))
7637 formatSettings->alignment = DtEDITOR_ALIGN_RIGHT;
7638 else if (XmToggleButtonGadgetGetState(M_format_bothJust(editor)))
7639 formatSettings->alignment = DtEDITOR_ALIGN_JUSTIFY;
7641 formatSettings->alignment = DtEDITOR_ALIGN_CENTER;
7644 * Get current margin settings
7646 num = (char *) XmTextFieldGetString(
7647 (Widget)M_format_rightMarginField(editor) );
7648 formatSettings->rightMargin = atoi(num);
7650 num = (char *) XmTextFieldGetString(
7651 (Widget)M_format_leftMarginField(editor) );
7652 formatSettings->leftMargin = atoi(num);
7659 * The Format Settings dialog box has not been created so use the
7662 formatSettings->leftMargin = 0;
7663 formatSettings->rightMargin = ComputeRightMargin(editor);
7664 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7669 /****************************************************************
7673 ****************************************************************/
7677 /*********************************************************
7680 * Create an instance of an editor and return the widget id.
7690 return( XtCreateWidget(name,dtEditorWidgetClass,parent,arglist,argcount) );
7694 DtEditorCheckForUnsavedChanges(
7697 DtEditorWidget editor = (DtEditorWidget) widget;
7699 _DtWidgetToAppContext(widget);
7702 result = M_unreadChanges( editor );
7706 } /* end DtEditorCheckForUnsavedChanges */
7710 DtEditorDeleteSelection(
7713 XmTextPosition first, last;
7714 DtEditorWidget editor = (DtEditorWidget) widget;
7716 _DtWidgetToAppContext(widget);
7720 * Check for a non-null selection
7722 if ( XmTextGetSelectionPosition(M_text(editor), &first, &last) &&
7725 XmTextRemove(M_text(editor));
7733 } /* end DtEditorDeleteSelection */
7737 * DtEditorClearSelection replaces the currently selected text with
7738 * spaces. It requires an event because the underlying text widget
7739 * routines require one to look at the time stamp within.
7742 DtEditorClearSelection(
7745 DtEditorWidget editor = (DtEditorWidget) widget;
7746 char *params=(char *)NULL;
7747 Cardinal num_params = 0;
7749 _DtWidgetToAppContext(widget);
7753 * Create an event with a correct timestamp
7755 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7758 * Call routine to clear primary selection
7760 ClearSelection( widget, &event, ¶ms, &num_params );
7764 } /* end DtEditorClearSelection */
7769 * DtEditorDeselect - Unselects any selected text of an Editor widget
7776 DtEditorWidget editor = (DtEditorWidget) widget;
7777 char *params=(char *)NULL;
7778 Cardinal num_params = 0;
7780 _DtWidgetToAppContext(widget);
7784 * Create an event with a correct timestamp
7786 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7788 DeselectAll( widget, &event, ¶ms, &num_params );
7793 } /* end DtEditorDeselect */
7798 * DtEditorDisableRedisplay - Temporarily prevent visual update of a
7803 DtEditorDisableRedisplay(
7806 DtEditorWidget editor = (DtEditorWidget) widget;
7807 _DtWidgetToAppContext(widget);
7810 XmTextDisableRedisplay( M_text(editor) );
7812 } /* end DtEditorDisableRedisplay */
7816 * DtEditorEnableRedisplay - Force visual update of an Editor widget
7820 DtEditorEnableRedisplay(
7823 DtEditorWidget editor = (DtEditorWidget) widget;
7824 _DtWidgetToAppContext(widget);
7827 XmTextEnableRedisplay( M_text(editor) );
7829 } /* end DtEditorEnableRedisplay */
7835 * Given left & right margin values & an alignment style,
7836 * formats either the current paragraph or the entire document,
7837 * as specified. If margin values & alignment style are not
7838 * provided, DtEditorFormat will use the current values from
7839 * the Format Settings dialog.
7842 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
7843 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
7845 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
7847 * DtEDITOR_INVALID_RANGE if specified amount to format is
7849 * DtEDITOR_INVALID_TYPE if specified alignment is
7856 DtEditorFormatSettings *formatSettings,
7857 unsigned int amountToFormat )
7860 DtEditorWidget editor = (DtEditorWidget) widget;
7861 DtEditorErrorCode error;
7862 int leftMargin, rightMargin, alignment;
7863 _DtWidgetToAppContext(widget);
7867 * Check to see if we should use the format settings from the
7868 * Format Settings dialog.
7870 if( formatSettings == (DtEditorFormatSettings *) NULL )
7873 DtEditorFormatSettings tmpFormatSettings;
7876 * Get the format settings from the Format Settings dialog
7878 GetAdjustSettings(editor, &tmpFormatSettings);
7881 * Set up the correct format settings
7883 leftMargin = tmpFormatSettings.leftMargin;
7884 rightMargin = tmpFormatSettings.rightMargin;
7885 alignment = tmpFormatSettings.alignment;
7889 leftMargin = formatSettings->leftMargin;
7890 rightMargin = formatSettings->rightMargin;
7891 alignment = formatSettings->alignment;
7895 * Now, do the formatting
7898 switch (amountToFormat)
7900 case DtEDITOR_FORMAT_ALL:
7902 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7903 0, XmTextGetLastPosition(M_text(editor)) );
7907 case DtEDITOR_FORMAT_PARAGRAPH:
7909 XmTextPosition start, end;
7910 char *params=(char *)NULL;
7911 Cardinal num_params = 0;
7914 * Create an event with a correct timestamp
7917 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7920 * Get the beginning & ending positions of the current paragraph
7922 ForwardPara( widget, &event, ¶ms, &num_params );
7923 end = XmTextGetInsertionPosition(M_text(editor));
7924 if( end != XmTextGetLastPosition(M_text(editor)) ) {
7926 * If we're not at the end, then we need to back up to the
7927 * start of this line, otherwise we'll disturb the first line
7928 * of the following paragraph. If we are at the end, then "end"
7929 * must point to the end of the line, or we'll leave the last
7930 * line along with the formatted text.
7932 BeginningOfLine( widget, &event, ¶ms, &num_params );
7933 end = XmTextGetInsertionPosition(M_text(editor));
7936 BackwardPara( widget, &event, ¶ms, &num_params );
7937 BeginningOfLine( widget, &event, ¶ms, &num_params );
7938 start = XmTextGetInsertionPosition(M_text(editor));
7941 * Pass in beginning & ending positions to adjust the current
7944 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7950 error = DtEDITOR_INVALID_RANGE;
7958 } /* DtEditorFormat */
7963 * DtEditorGetMessageTextFieldID - Returns the widget ID of the Text
7964 * Field used to display application status messages.
7968 DtEditorGetMessageTextFieldID(
7971 DtEditorWidget editor = (DtEditorWidget) widget;
7973 _DtWidgetToAppContext(widget);
7977 * Create the status line if is does not exist
7979 if( M_status_statusArea(editor) == (Widget) NULL )
7980 M_status_statusArea(editor) = CreateStatusLine( editor );
7982 result = M_status_messageText(editor);
7987 } /* end DtEditorGetMessageTextFieldID */
7990 * DtEditorGoToLine moves the insert cursor to the beginning of the
7991 * line specified by lineNumber. It figures out the text character
7992 * position corresponding to the specified line and sets the text
7993 * widget's insertionPosition to that location. If this new
7994 * insertionPosition is not currently on-screen, then the
7995 * text widget's contents are scrolled to display the new position.
7997 * The cursor can be moved to last line by specifying DtEDITOR_LAST_LINE
7998 * as the line number.
7999 * If lineNumber is less than one, the insert cursor will be placed
8000 * at the beginning of the first line. If it is greater than the total
8001 * number of lines, the cursor will be placed at the last line of text.
8005 void DtEditorGoToLine(
8009 DtEditorWidget editor = (DtEditorWidget)widget;
8011 XmTextLineTable lineTab;
8012 XmTextPosition newPos;
8013 _DtWidgetToAppContext(widget);
8016 tw = (XmTextWidget)M_text(editor);
8017 lineTab = tw->text.line_table;
8020 * Validate the specified line number, check it is in range.
8021 * If we adjust the line number, then update the current line display
8022 * in the status line so it reflects where we are really going. This
8023 * is only a problem if lineNumber is less/greater than the first/last
8024 * line becausee we won't be moving the cursor so the status line will
8027 if (lineNumber > tw->text.total_lines || lineNumber == DtEDITOR_LAST_LINE)
8029 lineNumber = tw->text.total_lines;
8030 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8032 else if(lineNumber < 1)
8035 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8040 * Move the insertion cursor
8042 newPos = lineTab[lineNumber - 1].start_pos;
8043 XmTextSetInsertionPosition(M_text(editor), newPos);
8046 * Scroll the widget, if necessary
8048 if (newPos < tw->text.top_character || newPos >= tw->text.bottom_position)
8057 XtSetArg(al[ac], XmNheight, &height); ac++;
8058 XtSetArg(al[ac], XmNrows, &rows); ac++;
8059 XtGetValues(M_text(editor), al, ac);
8061 if(XmTextPosToXY(M_text(editor), newPos, &x, &y) == True)
8063 int offset = (y - height/2) * rows;
8064 XmTextScroll(M_text(editor), offset/(int) height);
8069 } /* end DtEditorGoToLine */
8072 * DtEditorGetEditorSizeHints - Set the resize increment, minimum window
8073 * size, and base dimension properties in the supplied XSizeHints
8074 * struct for the editor as a whole.
8076 * NOTE: This routine returns data in the struct pointed to by pHints.
8080 DtEditorGetSizeHints(
8082 XSizeHints *pHints) /* Return */
8084 Arg al[10]; /* arg list */
8085 register int ac; /* arg count */
8086 Dimension FormWidth, FormHeight,
8087 Twidth, Theight, statusHeight,
8088 highlightThickness, shadowThickness,
8089 marginWidth, marginHeight,
8090 textRegionWidth, textRegionHeight;
8092 DtEditorWidget editor = (DtEditorWidget) widget;
8093 _DtWidgetToAppContext(widget);
8097 * Window manager should resize in increments of a character or line.
8099 pHints->width_inc = M_fontWidth(editor);
8100 pHints->height_inc = M_fontHeight(editor);
8103 * Size of the Editor (Form)
8106 FormWidth = editor->core.width + (2 * editor->core.border_width);
8107 FormHeight = editor->core.height + (2 * editor->core.border_width);
8110 * Size of the Edit window (text widget)
8113 XtSetArg(al[ac], XmNwidth, &Twidth); ac++;
8114 XtSetArg(al[ac], XmNheight, &Theight); ac++;
8115 XtSetArg(al[ac], XmNhighlightThickness, &highlightThickness); ac++;
8116 XtSetArg(al[ac], XmNshadowThickness, &shadowThickness); ac++;
8117 XtSetArg(al[ac], XmNmarginWidth, &marginWidth); ac++;
8118 XtSetArg(al[ac], XmNmarginHeight, &marginHeight); ac++;
8119 XtGetValues(M_text(editor), al, ac);
8122 * Calculate the width & height of the area within the text widget
8123 * which can actually display characters.
8125 textRegionWidth = (int)Twidth -
8126 (2 * ((int)highlightThickness +
8127 (int)shadowThickness + (int)marginWidth));
8128 textRegionHeight = (int)Theight -
8129 (2 * ((int)highlightThickness +
8130 (int)shadowThickness + (int)marginHeight));
8133 * Set the base width/height to the size of the area which will not
8134 * display characters.
8136 * The base width/height is used by the window manager in concert
8137 * with the height & width increments to display the current size
8138 * (rows & columns) of edit window (text widget) while resizing the
8141 pHints->base_width = FormWidth - textRegionWidth;
8142 pHints->base_height = FormHeight - textRegionHeight;
8145 * Get the height of the status line, if it is turned on.
8146 * Remember, the border width is not included in the height of the
8147 * status line so add it in to account for the border between the
8148 * edit window (text widget) and the status line.
8151 /* XXX Actually, the statusHeight should already be included in the
8152 * FormHeight, so it should not be necessary to add it in again.
8153 * However, the numbers don't come out right otherwise. Hmmm? */
8155 if( M_status_showStatusLine(editor) == True )
8157 XtSetArg( al[0], XmNheight, &statusHeight );
8158 XtGetValues( M_status_statusArea(editor), al, 1 );
8159 statusHeight = statusHeight + editor->core.border_width;
8165 * What is being returned here is the minimum width & height of the
8166 * editor. Leave room for the scrollbars, shadows, etc., plus one
8169 pHints->min_width = pHints->base_width + pHints->width_inc;
8170 pHints->min_height = pHints->base_width + pHints->height_inc +
8173 pHints->flags = PMinSize | PResizeInc | PBaseSize;
8176 } /* end DtEditorGetSizeHints */
8180 DtEditorInvokeFormatDialog(
8183 DtEditorWidget editor = (DtEditorWidget) widget;
8184 _DtWidgetToAppContext(widget);
8188 * Create the dialog if it is the first time
8190 if (M_format_dialog(editor) == (Widget)NULL)
8191 CreateFormatDialog( editor );
8196 XtUnmanageChild (M_format_dialog(editor));
8197 XtManageChild (M_format_dialog(editor));
8198 XmProcessTraversal(M_format_paragraph(editor), XmTRAVERSE_CURRENT);
8201 } /* DtEditorInvokeFormatDialog */
8208 DtEditorContentRec cr;
8209 DtEditorWidget editor = (DtEditorWidget) widget;
8210 _DtWidgetToAppContext(widget);
8214 * Reset the edit window (includes the Undo context)
8216 cr.type = DtEDITOR_TEXT;
8217 cr.value.string = "";
8218 DtEditorSetContents( widget, &cr );
8221 * Reset the status line
8222 * Note, the current & total line displays are reset by DtEditorSetContents()
8224 if( M_status_statusArea(editor) != (Widget) NULL ) {
8226 XmTextFieldSetString( M_status_messageText(editor), "" );
8231 * Reset the Find/Change & Spell dialogs
8233 if ( M_search_string(editor) )
8234 XtFree(M_search_string(editor));
8235 M_search_string(editor) = (char *)NULL;
8237 if ( M_replace_string(editor) )
8238 XtFree(M_replace_string(editor));
8239 M_replace_string(editor) = (char *)NULL;
8241 if (M_misspelled_string(editor))
8242 XtFree(M_misspelled_string(editor));
8243 M_misspelled_string(editor) = (char *)NULL;
8246 * Reset the Format Settings dialog
8248 if (M_format_dialog(editor) != (Widget)NULL)
8249 ResetFormatDialog(editor);
8252 } /* end DtEditorReset */
8257 * DtEditorSelectAll - Selects the contents of an Editor widget
8264 DtEditorWidget editor = (DtEditorWidget) widget;
8265 char *params=(char *)NULL;
8266 Cardinal num_params = 0;
8268 _DtWidgetToAppContext(widget);
8272 * Create an event with a correct timestamp
8274 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
8276 SelectAll( widget, &event, ¶ms, &num_params );
8280 } /* end DtEditorSelectAll */
8284 DtEditorTraverseToEditor(
8287 DtEditorWidget editor = (DtEditorWidget) widget;
8288 _DtWidgetToAppContext(widget);
8291 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
8294 } /* end DtEditorTraverseToEditor */