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 /*-------------------------------------------------------------
56 #if defined(__hpux) || defined(__osf__) || defined(USL)
58 #elif defined(__uxp__)
62 # if (_XOPEN_VERSION==3)
71 #elif defined(CSRG_BASED)
81 #include <limits.h> /* For LINE_MAX definition */
82 #include <sys/errno.h> /* For Error handling */
86 #include "X11/Xutil.h"
87 #include <X11/StringDefs.h>
88 #include <X11/keysymdef.h>
90 #include <Xm/MessageB.h>
91 #include <Xm/MwmUtil.h>
93 #include <Xm/LabelG.h>
94 #include <Xm/SeparatoG.h>
95 #include <Xm/PushBG.h>
96 #include <Xm/ToggleBG.h>
97 #include <Xm/RowColumn.h>
99 /* Need the following for _DtOkString */
102 #include <Dt/DtMsgsP.h>
103 #include <Dt/HourGlass.h>
105 #include "DtWidgetI.h"
108 * Private functions borrowed from Motif.
110 extern XmTextLineTable _XmTextGetLineTable(Widget widget, int *total_lines);
111 extern char * _XmStringSourceGetString(XmTextWidget tw,
114 #if NeedWidePrototypes
118 #endif /* NeedWidePrototypes */
121 /*-------------------------------------------------------------
123 **-------------------------------------------------------------
126 /******** Public Function Declarations ********/
128 /******** End Public Function Declarations ********/
130 /*-------------------------------------------------------------
131 ** Forward Declarations
132 **-------------------------------------------------------------
135 /******** Static Function Declarations ********/
137 static void ClassInitialize(void);
138 static void Initialize(
142 Cardinal *num_args) ;
144 static void VariableInitialize(
147 static void ValidateResources(
149 DtEditorWidget request);
151 static Widget CreateText(
152 DtEditorWidget parent);
154 static void extractFontMetrics(
160 static void getFontMetrics(
166 static void SetStatusLine(
168 Boolean statusLineOn);
170 static Widget CreateStatusLine(
171 DtEditorWidget parent);
173 static Boolean SetValues(
178 static void _DtEditorGetCenterToggleLabel(
183 static void _DtEditorGetChangeAllButtonLabel(
188 static void _DtEditorGetChangeButtonLabel(
193 static void _DtEditorGetChangeFieldLabel(
198 static void _DtEditorGetColumns(
203 static void _DtEditorGetCurrentLineLabel(
208 static void _DtEditorGetCursorPosition(
213 static void _DtEditorGetFindButtonLabel(
218 static void _DtEditorGetFindFieldLabel(
223 static void _DtEditorGetFormatAllButtonLabel(
228 static void _DtEditorGetFormatParagraphButtonLabel(
233 static void _DtEditorGetJustifyToggleLabel(
238 static void _DtEditorGetLeftAlignToggleLabel(
243 static void _DtEditorGetLeftMarginFieldLabel(
248 static void _DtEditorGetMaxLength(
253 static void _DtEditorGetMisspelledListLabel(
258 static void _DtEditorGetRightAlignToggleLabel(
263 static void _DtEditorGetRightMarginFieldLabel(
268 static void _DtEditorGetRows(
273 static void _DtEditorGetScrollLeftSide(
278 static void _DtEditorGetScrollTopSide(
283 static void _DtEditorGetTextBackground(
288 static void _DtEditorGetTextForeground(
293 static void _DtEditorGetTopCharacter(
298 static void _DtEditorGetLineCountLabel(
303 static void FixWordWrap( /* XXX Word Wrap workaround */
304 Widget w, /* XXX Word Wrap workaround */
305 Boolean wrapOn); /* XXX Word Wrap workaround */
307 static void BackwardChar(
311 Cardinal *num_params);
313 static void BackwardPara(
317 Cardinal *num_params);
319 static void BackwardWord(
323 Cardinal *num_params);
325 static void BeginningOfFile(
329 Cardinal *num_params);
331 static void BeginningOfLine(
335 Cardinal *num_params);
337 static void ClearSelection(
341 Cardinal *num_params);
343 static void CopyClipboard(
347 Cardinal *num_params);
349 static void CutClipboard(
353 Cardinal *num_params);
355 static void DeleteNextChar(
359 Cardinal *num_params);
361 static void DeleteNextWord(
365 Cardinal *num_params);
367 static void DeletePrevChar(
371 Cardinal *num_params);
373 static void DeletePrevWord(
377 Cardinal *num_params);
379 static void DeleteToEOL(
383 Cardinal *num_params);
385 static void DeleteToSOL(
389 Cardinal *num_params);
391 static void DeselectAll(
395 Cardinal *num_params);
397 static void EndOfFile(
401 Cardinal *num_params);
403 static void EndOfLine(
407 Cardinal *num_params);
409 static void ForwardChar(
413 Cardinal *num_params);
415 static void ForwardPara(
419 Cardinal *num_params);
421 static void ForwardWord(
425 Cardinal *num_params);
427 static void GoToLine(
431 Cardinal *num_params);
433 static void GoToLine_I(
437 Cardinal *num_params);
443 Cardinal *num_params);
445 static void InsertString(
449 Cardinal *num_params);
451 static void KeySelect(
455 Cardinal *num_params);
457 static void NewlineAndBackup(
461 Cardinal *num_params);
463 static void NewlineAndIndent(
467 Cardinal *num_params);
469 static void NextPage(
473 Cardinal *num_params);
475 static void PageLeft(
479 Cardinal *num_params);
481 static void PageRight(
485 Cardinal *num_params);
487 static void PasteClipboard(
491 Cardinal *num_params);
493 static void PreviousPage(
497 Cardinal *num_params);
499 static void ProcessCancel(
503 Cardinal *num_params);
505 static void ProcessDown(
509 Cardinal *num_params);
511 static void ProcessShiftDown(
515 Cardinal *num_params);
517 static void ProcessShiftUp(
521 Cardinal *num_params);
523 static void ProcessUp(
527 Cardinal *num_params);
529 static void QuoteNextChar(
533 Cardinal *num_params);
535 static void QuoteNextChar_I(
539 Cardinal *num_params);
541 static void SelectAll(
545 Cardinal *num_params);
547 static void ToggleInsertMode(
551 Cardinal *num_params);
553 static void ToggleInsertMode_I(
557 Cardinal *num_params);
559 static void UndoEdit(
563 Cardinal *num_params);
565 static void UndoEdit_I(
569 Cardinal *num_params);
571 static void Call_TextSelectCallback(
572 DtEditorWidget editor);
574 static void Call_TextDeselectCallback(
575 DtEditorWidget editor);
577 static void Editor_SetSelectionProc(
580 XmTextPosition right,
583 static void CallHelpCallback(
584 DtEditorWidget editor,
587 static void HelpEditWindowCB(
592 static void HelpStatusCurrentLineCB(
597 static void HelpStatusTotalLinesCB(
602 static void HelpStatusMessageCB(
607 static void HelpStatusOverstrikeCB(
612 static void RegisterDropZone(
615 static void UnregisterDropZone(
618 static void SetInfoDialogTitle(
619 DtEditorWidget editor );
621 static int FormatText (
624 static void AdjustParaCB(
629 static void AdjustAllCB(
634 static DtEditorErrorCode DoAdjust(
635 DtEditorWidget editor,
638 unsigned int alignment,
639 XmTextPosition start,
642 static void SetFormatDialogTitle(
643 DtEditorWidget editor);
645 static void ResetFormatDialog(
646 DtEditorWidget editor);
648 static void CreateFormatDialog(
649 DtEditorWidget editor);
651 static void GetAdjustSettings(
653 DtEditorFormatSettings *formatSettings);
655 static void UpdateOverstrikeIndicator(
656 DtEditorWidget widget,
657 Boolean overstrikeOn );
659 /******** End Static Function Declarations ********/
662 /****************************************************************
664 * Compatability routines
666 ****************************************************************/
667 #if defined(NO_putwc)
668 static wint_t putwc(wint_t wc, FILE *stream)
670 int rc = putc((int) wc, stream);
674 static wint_t getwc(FILE *stream)
676 int rc = getc(stream);
679 #endif /* NO_putwc */
681 /****************************************************************
683 * Translations and Actions
685 ****************************************************************/
688 * The following are the translations which DtEditor places (overrides)
689 * on the scrolled text widget. If the DtNtextTranslations resource is
690 * set, it will also be added (in override mode) to the text widget.
692 static char EditorTranslationTable[] = "\
693 ~s ~c ~m ~a <Key>Return: newline-and-indent()\n\
694 ~s m<Key>osfBackSpace: I-undo-edit()\n\
695 ~s c<Key>osfBackSpace: delete-previous-word()\n\
696 s<Key>osfBackSpace: delete-to-start-of-line()\n\
697 ~s ~c <Key>osfInsert: I-toggle-insert-mode()\n\
698 <Key>osfUndo: I-undo-edit()\n\
699 c<Key>g: I-go-to-line()\n\
700 c<Key>q: I-quote-next-character()\n\
701 c<Key>z: I-undo-edit()";
704 * The following are DtEditor's actions. A few are internal only (_I
705 * suffix) and will be called by the default translations DtEditor places
706 * on the text widget (see previous comment). The rest will only be called
707 * from an application with XtCallActionProc(). The main difference is
708 * the internal ones will be passed a text widget ID, while the public
709 * ones will be passed a DtEditor ID.
711 static XtActionsRec EditorActionTable[] = {
712 {"I-go-to-line", (XtActionProc)GoToLine_I},
713 {"I-toggle-insert-mode", (XtActionProc)ToggleInsertMode_I},
714 {"I-undo-edit", (XtActionProc)UndoEdit_I},
715 {"I-quote-next-character", (XtActionProc)QuoteNextChar_I},
716 {"backward-character", (XtActionProc)BackwardChar},
717 {"backward-paragraph", (XtActionProc)BackwardPara},
718 {"backward-word", (XtActionProc)BackwardWord},
719 {"beginning-of-file", (XtActionProc)BeginningOfFile},
720 {"beginning-of-line", (XtActionProc)BeginningOfLine},
721 {"clear-selection", (XtActionProc)ClearSelection},
722 {"copy-clipboard", (XtActionProc)CopyClipboard},
723 {"cut-clipboard", (XtActionProc)CutClipboard},
724 {"delete-next-character", (XtActionProc)DeleteNextChar},
725 {"delete-next-word", (XtActionProc)DeleteNextWord},
726 {"delete-previous-character", (XtActionProc)DeletePrevChar},
727 {"delete-previous-word", (XtActionProc)DeletePrevWord},
728 {"delete-to-end-of-line", (XtActionProc)DeleteToEOL},
729 {"delete-to-start-of-line", (XtActionProc)DeleteToSOL},
730 {"deselect-all", (XtActionProc)DeselectAll},
731 {"end-of-file", (XtActionProc)EndOfFile},
732 {"end-of-line", (XtActionProc)EndOfLine},
733 {"forward-character", (XtActionProc)ForwardChar},
734 {"forward-paragraph", (XtActionProc)ForwardPara},
735 {"forward-word", (XtActionProc)ForwardWord},
736 {"go-to-line", (XtActionProc)GoToLine},
737 {"Help", (XtActionProc)Help},
738 {"insert-string", (XtActionProc)InsertString},
739 {"key-select", (XtActionProc)KeySelect},
740 {"newline-and-backup", (XtActionProc)NewlineAndBackup},
741 {"newline-and-indent", (XtActionProc)NewlineAndIndent},
742 {"next-page", (XtActionProc)NextPage},
743 {"page-left", (XtActionProc)PageLeft},
744 {"page-right", (XtActionProc)PageRight},
745 {"paste-clipboard", (XtActionProc)PasteClipboard},
746 {"previous-page", (XtActionProc)PreviousPage},
747 {"process-cancel", (XtActionProc)ProcessCancel},
748 {"process-down", (XtActionProc)ProcessDown},
749 {"process-shift-down", (XtActionProc)ProcessShiftDown},
750 {"process-shift-up", (XtActionProc)ProcessShiftUp},
751 {"process-up", (XtActionProc)ProcessUp},
752 {"quote-next-character", (XtActionProc)QuoteNextChar},
753 {"select-all", (XtActionProc)SelectAll},
754 {"toggle-insert-mode", (XtActionProc)ToggleInsertMode},
755 {"undo-edit", (XtActionProc)UndoEdit},
759 /****************************************************************
763 ****************************************************************/
768 #define iswctype(a,b) is_wctype(a,b)
769 #define wctype(a) get_wctype(a)
772 #if !(defined(sun) && (_XOPEN_VERSION==3))
773 #if !(defined(__FreeBSD__))
774 # define iswblank(wc) iswctype((wc),blnkclass)
775 # undef getwc /* Use the libc function */
777 #if defined(__osf__) || defined(_AIX) /* __osf__ || _AIX */
778 /* function prototype for wctype() was changed to meet spec1170 */
779 /* digital compiler flagged warning */
780 /* IBM defines wctype to get_wctype above - don't use const. */
781 static char *blankString = "space";
783 # define wctype_t int
784 #else /* __osf__ || _AIX */
785 static const char *blankString = "space";
786 #endif /* __osf__ || _AIX */
787 static wctype_t _DtEditor_blankClass;
789 # define wctype_t int
790 # if defined(__uxp__)
791 # if (OSMAJORVERSION < 2)
792 typedef long wint_t ;
797 # define iswblank(a) iswspace(a)
798 # if !defined(__uxp__)
799 # define iswctype(a,b) _iswctype(a,b)
801 # if defined(__uxp__)
802 # define wcwidth(a) scrwidth(a)
804 # define wcwidth(a) sun_wcwidth(a)
806 #endif /* not sun and not uxp */
808 #define MAXTABSIZE 100 /* max legal tabsize */
811 /****************************************************************
813 * Define misc data structures
815 ****************************************************************/
817 static wctype_t ekinclass = 0; /* Prop value for "ekinsoku" class */
818 static wctype_t bekinclass = 0; /* Prop value for "bekinsoku" class */
819 static wctype_t blnkclass = 0; /* Prop value for "Blank" Class */
821 /****************************************************************
825 ****************************************************************/
827 static XmSyntheticResource syn_resources[] =
831 DtNcolumns, sizeof(short),
832 XtOffset (DtEditorWidget, editor.editStuff.columns),
833 _DtEditorGetColumns, NULL
836 DtNcenterToggleLabel, sizeof (XmString),
837 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
838 _DtEditorGetCenterToggleLabel, NULL
841 DtNchangeAllButtonLabel, sizeof (XmString),
842 XtOffset (DtEditorWidget,
843 editor.searchStuff.changeAllButtonLabel),
844 _DtEditorGetChangeAllButtonLabel, NULL
847 DtNchangeButtonLabel, sizeof (XmString),
848 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
849 _DtEditorGetChangeButtonLabel, NULL
852 DtNchangeFieldLabel, sizeof (XmString),
853 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
854 _DtEditorGetChangeFieldLabel, NULL
857 DtNcurrentLineLabel, sizeof (XmString),
858 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
859 _DtEditorGetCurrentLineLabel, NULL
862 DtNcursorPosition, sizeof (XmTextPosition),
863 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
864 _DtEditorGetCursorPosition, NULL
867 DtNfindButtonLabel, sizeof (XmString),
868 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
869 _DtEditorGetFindButtonLabel, NULL
872 DtNfindFieldLabel, sizeof (XmString),
873 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
874 _DtEditorGetFindFieldLabel, NULL
877 DtNformatAllButtonLabel, sizeof (XmString),
878 XtOffset(DtEditorWidget,
879 editor.formatStuff.formatAllButtonLabel),
880 _DtEditorGetFormatAllButtonLabel, NULL
883 DtNformatParagraphButtonLabel, sizeof (XmString),
884 XtOffset(DtEditorWidget,
885 editor.formatStuff.formatParaButtonLabel),
886 _DtEditorGetFormatParagraphButtonLabel, NULL
889 DtNjustifyToggleLabel, sizeof (XmString),
890 XtOffset (DtEditorWidget,
891 editor.formatStuff.justifyToggleLabel),
892 _DtEditorGetJustifyToggleLabel, NULL
895 DtNleftAlignToggleLabel, sizeof (XmString),
896 XtOffset (DtEditorWidget,
897 editor.formatStuff.leftAlignToggleLabel),
898 _DtEditorGetLeftAlignToggleLabel, NULL
901 DtNleftMarginFieldLabel, sizeof (XmString),
902 XtOffset (DtEditorWidget,
903 editor.formatStuff.leftMarginFieldLabel),
904 _DtEditorGetLeftMarginFieldLabel, NULL
907 DtNmaxLength, sizeof(int),
908 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
909 _DtEditorGetMaxLength, NULL
912 DtNmisspelledListLabel, sizeof (XmString),
913 XtOffset (DtEditorWidget,
914 editor.searchStuff.misspelledListLabel),
915 _DtEditorGetMisspelledListLabel, NULL
918 DtNrightAlignToggleLabel, sizeof (XmString),
919 XtOffset (DtEditorWidget,
920 editor.formatStuff.rightAlignToggleLabel),
921 _DtEditorGetRightAlignToggleLabel, NULL
924 DtNrightMarginFieldLabel, sizeof (XmString),
925 XtOffset (DtEditorWidget,
926 editor.formatStuff.rightMarginFieldLabel),
927 _DtEditorGetRightMarginFieldLabel, NULL
930 DtNrows, sizeof(short),
931 XtOffset (DtEditorWidget, editor.editStuff.rows),
932 _DtEditorGetRows, NULL
935 DtNscrollLeftSide, sizeof (Boolean),
936 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
937 _DtEditorGetScrollLeftSide, NULL
940 DtNscrollTopSide, sizeof (Boolean),
941 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
942 _DtEditorGetScrollTopSide, NULL
945 DtNtextBackground, sizeof(Pixel),
946 XtOffset (DtEditorWidget, editor.editStuff.background),
947 _DtEditorGetTextBackground, NULL
950 DtNtextForeground, sizeof(Pixel),
951 XtOffset (DtEditorWidget, editor.editStuff.foreground),
952 _DtEditorGetTextForeground, NULL
955 DtNtopCharacter, sizeof(XmTextPosition),
956 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
957 _DtEditorGetTopCharacter, NULL
960 DtNtotalLineCountLabel, sizeof (XmString),
961 XtOffset (DtEditorWidget, editor.statusStuff.totalLineLabel),
962 _DtEditorGetLineCountLabel, NULL
966 static XtResource resources[] =
969 DtNautoShowCursorPosition,
970 DtCAutoShowCursorPosition, XmRBoolean, sizeof (Boolean),
971 XtOffset(DtEditorWidget,
972 editor.editStuff.autoShowCursorPos),
973 XmRImmediate, (XtPointer) True
976 DtNbuttonFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
977 XtOffsetOf(struct _XmBulletinBoardRec,
978 bulletin_board.button_font_list),
979 XmRFontList, (XtPointer) NULL
982 DtNblinkRate, DtCBlinkRate, XmRInt, sizeof(int),
983 XtOffset(DtEditorWidget, editor.editStuff.blinkRate),
984 XmRImmediate, (XtPointer) 500
987 DtNcenterToggleLabel, DtCCenterToggleLabel,
988 XmRXmString, sizeof (XmString),
989 XtOffset (DtEditorWidget, editor.formatStuff.centerToggleLabel),
990 XmRImmediate, (XtPointer) DtUNSPECIFIED
993 DtNchangeAllButtonLabel, DtCChangeAllButtonLabel,
994 XmRXmString, sizeof (XmString),
995 XtOffset (DtEditorWidget,
996 editor.searchStuff.changeAllButtonLabel),
997 XmRImmediate, (XtPointer) DtUNSPECIFIED
1000 DtNchangeButtonLabel, DtCChangeButtonLabel,
1001 XmRXmString, sizeof (XmString),
1002 XtOffset(DtEditorWidget, editor.searchStuff.changeButtonLabel),
1003 XmRImmediate, (XtPointer) DtUNSPECIFIED
1006 DtNchangeFieldLabel, DtCChangeFieldLabel,
1007 XmRXmString, sizeof (XmString),
1008 XtOffset(DtEditorWidget, editor.searchStuff.changeFieldLabel),
1009 XmRImmediate, (XtPointer) DtUNSPECIFIED
1012 DtNcolumns, DtCColumns, XmRShort, sizeof(short),
1013 XtOffset (DtEditorWidget, editor.editStuff.columns),
1014 XmRImmediate, (XtPointer) DtUNSPECIFIED
1017 DtNcurrentLineLabel, DtCCurrentLineLabel,
1018 XmRXmString, sizeof (XmString),
1019 XtOffset(DtEditorWidget, editor.statusStuff.currentLineLabel),
1020 XmRImmediate, (XtPointer) DtUNSPECIFIED
1023 DtNcursorPosition, DtCCursorPosition, XmRTextPosition,
1024 sizeof (XmTextPosition),
1025 XtOffset(DtEditorWidget, editor.editStuff.cursorPos),
1026 XmRImmediate, (XtPointer) DtUNSPECIFIED
1029 DtNcursorPositionVisible, DtCCursorPositionVisible,
1030 XmRBoolean, sizeof (Boolean),
1031 XtOffset(DtEditorWidget,
1032 editor.editStuff.cursorPosVisible),
1033 XmRImmediate, (XtPointer) True
1036 DtNdialogTitle, DtCDialogTitle, XmRXmString, sizeof (XmString),
1037 XtOffsetOf(struct _XmBulletinBoardRec,
1038 bulletin_board.dialog_title),
1039 XmRString, (XtPointer) NULL
1042 DtNeditable, DtCEditable, XmRBoolean, sizeof (Boolean),
1043 XtOffset (DtEditorWidget, editor.editStuff.editable),
1044 XmRImmediate, (XtPointer) True
1047 DtNfindButtonLabel, DtCFindButtonLabel,
1048 XmRXmString, sizeof (XmString),
1049 XtOffset(DtEditorWidget, editor.searchStuff.findButtonLabel),
1050 XmRImmediate, (XtPointer) DtUNSPECIFIED
1053 DtNfindChangeDialogTitle, DtCFindChangeDialogTitle,
1054 XmRXmString, sizeof (XmString),
1055 XtOffset(DtEditorWidget, editor.searchStuff.fndChngTitle),
1056 XmRString, (XtPointer) NULL
1059 DtNfindFieldLabel, DtCFindFieldLabel,
1060 XmRXmString, sizeof (XmString),
1061 XtOffset(DtEditorWidget, editor.searchStuff.findFieldLabel),
1062 XmRImmediate, (XtPointer) DtUNSPECIFIED
1065 DtNformatAllButtonLabel, DtCFormatAllButtonLabel,
1066 XmRXmString, sizeof (XmString),
1067 XtOffset(DtEditorWidget,
1068 editor.formatStuff.formatAllButtonLabel),
1069 XmRImmediate, (XtPointer) DtUNSPECIFIED
1072 DtNformatParagraphButtonLabel, DtCFormatParagraphButtonLabel,
1073 XmRXmString, sizeof (XmString),
1074 XtOffset(DtEditorWidget,
1075 editor.formatStuff.formatParaButtonLabel),
1076 XmRImmediate, (XtPointer) DtUNSPECIFIED
1079 DtNformatSettingsDialogTitle, DtCFormatSettingsDialogTitle,
1080 XmRXmString, sizeof (XmString),
1081 XtOffset(DtEditorWidget, editor.formatStuff.formatDialogTitle),
1082 XmRString, (XtPointer) NULL
1085 DtNinformationDialogTitle, DtCInformationDialogTitle,
1086 XmRXmString, sizeof (XmString),
1087 XtOffset(DtEditorWidget, editor.warningStuff.infoDialogTitle),
1088 XmRString, (XtPointer) NULL
1091 DtNinsertLabel, DtCInsertLabel, XmRXmString, sizeof (XmString),
1092 XtOffset (DtEditorWidget, editor.statusStuff.ins),
1093 XmRImmediate, (XtPointer) DtUNSPECIFIED
1096 DtNjustifyToggleLabel, DtCJustifyToggleLabel,
1097 XmRXmString, sizeof (XmString),
1098 XtOffset(DtEditorWidget, editor.formatStuff.justifyToggleLabel),
1099 XmRImmediate, (XtPointer) DtUNSPECIFIED
1102 DtNlabelFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1103 XtOffsetOf(struct _XmBulletinBoardRec,
1104 bulletin_board.label_font_list),
1105 XmRFontList, (XtPointer) NULL
1108 DtNleftAlignToggleLabel, DtCLeftAlignToggleLabel,
1109 XmRXmString, sizeof (XmString),
1110 XtOffset(DtEditorWidget,
1111 editor.formatStuff.leftAlignToggleLabel),
1112 XmRImmediate, (XtPointer) DtUNSPECIFIED
1115 DtNleftMarginFieldLabel, DtCLeftMarginFieldLabel,
1116 XmRXmString, sizeof (XmString),
1117 XtOffset(DtEditorWidget,
1118 editor.formatStuff.leftMarginFieldLabel),
1119 XmRImmediate, (XtPointer) DtUNSPECIFIED
1122 DtNmaxLength, DtCMaxLength, XmRInt, sizeof(int),
1123 XtOffset(DtEditorWidget, editor.editStuff.maxLength),
1124 XmRImmediate, (XtPointer) DtUNSPECIFIED
1127 DtNmisspelledListLabel, DtCMisspelledListLabel,
1128 XmRXmString, sizeof (XmString),
1129 XtOffset (DtEditorWidget,
1130 editor.searchStuff.misspelledListLabel),
1131 XmRImmediate, (XtPointer) DtUNSPECIFIED
1134 DtNoverstrike, DtCOverstrike, XmRBoolean, sizeof (Boolean),
1135 XtOffset(DtEditorWidget, editor.editStuff.overstrikeMode),
1136 XmRImmediate, (XtPointer) False
1139 DtNoverstrikeLabel, DtCOverstrikeLabel,
1140 XmRXmString, sizeof (XmString),
1141 XtOffset (DtEditorWidget, editor.statusStuff.ovr),
1142 XmRImmediate, (XtPointer) DtUNSPECIFIED
1145 DtNrightAlignToggleLabel, DtCRightAlignToggleLabel,
1146 XmRXmString, sizeof (XmString),
1147 XtOffset(DtEditorWidget,
1148 editor.formatStuff.rightAlignToggleLabel),
1149 XmRImmediate, (XtPointer) DtUNSPECIFIED
1152 DtNrightMarginFieldLabel, DtCRightMarginFieldLabel,
1153 XmRXmString, sizeof (XmString),
1154 XtOffset(DtEditorWidget,
1155 editor.formatStuff.rightMarginFieldLabel),
1156 XmRImmediate, (XtPointer) DtUNSPECIFIED
1159 DtNrows, DtCRows, XmRShort, sizeof(short),
1160 XtOffset (DtEditorWidget, editor.editStuff.rows),
1161 XmRImmediate, (XtPointer) DtUNSPECIFIED
1164 DtNscrollHorizontal, DtCScroll, XmRBoolean, sizeof (Boolean),
1165 XtOffset (DtEditorWidget, editor.editStuff.scrollHorizontal),
1166 XmRImmediate, (XtPointer) True
1169 DtNscrollLeftSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1170 XtOffset (DtEditorWidget, editor.editStuff.scrollLeft),
1171 XmRImmediate, (XtPointer) DtUNSPECIFIED
1174 DtNscrollTopSide, DtCScrollSide, XmRBoolean, sizeof (Boolean),
1175 XtOffset (DtEditorWidget, editor.editStuff.scrollTop),
1176 XmRImmediate, (XtPointer) DtUNSPECIFIED
1179 DtNscrollVertical, DtCScroll, XmRBoolean, sizeof (Boolean),
1180 XtOffset (DtEditorWidget, editor.editStuff.scrollVertical),
1181 XmRImmediate, (XtPointer) True
1185 DtCShowStatusLine, XmRBoolean, sizeof (Boolean),
1186 XtOffset (DtEditorWidget, editor.statusStuff.showStatusLine),
1187 XmRImmediate, (XtPointer) False
1190 DtNspellDialogTitle, DtCSpellDialogTitle,
1191 XmRXmString, sizeof (XmString),
1192 XtOffset(DtEditorWidget, editor.searchStuff.spellTitle),
1193 XmRString, (XtPointer) NULL
1196 DtNspellFilter, DtCSpellFilter, XmRString, sizeof(XmRString),
1197 XtOffset (DtEditorWidget, editor.searchStuff.spellFilter),
1201 DtNtextBackground, DtCBackground,
1202 XmRPixel, sizeof(Pixel),
1203 XtOffset (DtEditorWidget, editor.editStuff.background),
1204 XmRImmediate, (XtPointer) DtUNSPECIFIED
1207 DtNtextDeselectCallback,
1208 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1209 XtOffset (DtEditorWidget, editor.textDeselect),
1210 XtRCallback, (XtPointer) NULL
1213 DtNtextForeground, DtCForeground,
1214 XmRPixel, sizeof(Pixel),
1215 XtOffset (DtEditorWidget, editor.editStuff.foreground),
1216 XmRImmediate, (XtPointer) DtUNSPECIFIED
1219 DtNtextFontList, DtCFontList, XmRFontList, sizeof(XmFontList),
1220 XtOffsetOf(struct _XmBulletinBoardRec,
1221 bulletin_board.text_font_list),
1222 XmRFontList, (XtPointer) NULL
1225 DtNtextSelectCallback,
1226 DtCCallback, XtRCallback, sizeof (XtCallbackList),
1227 XtOffset (DtEditorWidget, editor.textSelect),
1228 XtRCallback, (XtPointer) NULL
1231 DtNtextTranslations, DtCTranslations,
1232 XmRTranslationTable, sizeof (XtTranslations),
1233 XtOffsetOf(struct _XmBulletinBoardRec,
1234 bulletin_board.text_translations),
1235 XmRImmediate, (XtPointer) NULL
1238 DtNtopCharacter, DtCTopCharacter,
1239 XmRTextPosition, sizeof(XmTextPosition),
1240 XtOffset (DtEditorWidget, editor.editStuff.topCharacter),
1241 XmRImmediate, (XtPointer) DtUNSPECIFIED
1244 DtNtotalLineCountLabel, DtCTotalLineCountLabel,
1245 XmRXmString, sizeof (XmString),
1246 XtOffset (DtEditorWidget,
1247 editor.statusStuff.totalLineLabel),
1248 XmRImmediate, (XtPointer) DtUNSPECIFIED
1252 DtCWordWrap, XmRBoolean, sizeof (Boolean),
1253 XtOffset (DtEditorWidget, editor.editStuff.wordWrap),
1254 XmRImmediate, (XtPointer) False
1258 /****************************************************************
1260 * Public Function Declarations
1262 ****************************************************************/
1264 /****************************************************************
1268 ****************************************************************/
1270 externaldef( dteditorclassrec ) DtEditorClassRec
1276 (WidgetClass) &xmFormClassRec, /* superclass */
1277 "DtEditor", /* class_name */
1278 sizeof (DtEditorRec), /* widget_size */
1279 ClassInitialize, /* class_initialize */
1280 NULL, /* class_part_initialize*/
1281 False, /* class_inited */
1282 (XtInitProc) Initialize, /* initialize */
1283 NULL, /* initialize_hook */
1284 XtInheritRealize, /* realize */
1285 (XtActionList)EditorActionTable,/* actions */
1286 (Cardinal)XtNumber(EditorActionTable), /* num_actions */
1287 resources, /* resources */
1288 XtNumber (resources), /* num_resources */
1289 NULLQUARK, /* xrm_class */
1290 True, /* compress_motion */
1291 XtExposeCompressMaximal, /* compress_exposure */
1292 False, /* compress_enterleave */
1293 False, /* visible_interest */
1294 (XtWidgetProc) Destroy, /* destroy */
1295 XtInheritResize, /* resize */
1296 XtInheritExpose, /* expose */
1297 (XtSetValuesFunc) SetValues, /* set_values */
1298 NULL, /* set_values_hook */
1299 XtInheritSetValuesAlmost, /* set_values_almost */
1300 NULL, /* get_values_hook */
1301 XtInheritAcceptFocus, /* accept_focus */
1302 XtVersion, /* version */
1303 NULL, /* callback private */
1304 XtInheritTranslations, /* tm_table */
1305 XtInheritQueryGeometry, /* query_geometry */
1306 (XtStringProc)NULL, /* display_accelerator */
1307 NULL, /* extension */
1313 XtInheritGeometryManager, /* geometry_manager */
1314 XtInheritChangeManaged, /* change_managed */
1315 XtInheritInsertChild, /* insert_child */
1316 XtInheritDeleteChild, /* delete_child */
1317 NULL, /* extension */
1324 NULL, /* constraint_resources */
1325 0, /* num_constraint_resource */
1326 sizeof(XmFormConstraintRec), /* size of constraint */
1327 NULL, /* initialization */
1328 NULL, /* constraint_destroy */
1329 NULL, /* constraint_set_values */
1330 NULL, /* extension */
1336 XmInheritTranslations, /* default_translations */
1337 syn_resources, /* syn_resources */
1338 XtNumber(syn_resources), /* num_syn_resources */
1339 NULL, /* syn_cont_resources */
1340 0, /* num_syn_cont_resources */
1341 XmInheritParentProcess, /* parent_process */
1342 NULL, /* extension */
1345 /* XmbulletinBoard Part
1348 FALSE, /* always_install_accelerators */
1349 (XmGeoCreateProc)NULL, /* geo_matrix_create */
1350 XmInheritFocusMovedProc, /* focus_moved_proc */
1351 NULL, /* extension */
1357 NULL, /* extension */
1367 WidgetClass dtEditorWidgetClass = (WidgetClass) &dtEditorClassRec;
1369 /*-------------------------------------------------------------
1371 **-------------------------------------------------------------
1374 /****************************************************************
1378 ****************************************************************/
1381 /*-------------------------------------------------------------
1382 ** Function: static void ClassInitialize (void);
1386 ** Purpose: This is the Editor class initializzation routine.
1387 ** It is called once, before the first instance
1391 ClassInitialize(void)
1393 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
1394 _DtEditor_blankClass = wctype(blankString);
1397 ** These calls determine if the particular value is True for
1398 ** the current locale. A value of -1 is returned if the locale
1399 ** does not support the charclass. If the locale supports the
1400 ** charclass, the return value is passed as a parameter to the
1403 ekinclass = wctype("ekinsoku");
1404 bekinclass = wctype("bkinsoku");
1405 blnkclass = wctype("blank");
1406 #endif /* end not Sun */
1410 /*-------------------------------------------------------------
1411 ** Function: static void Initialize (
1414 ** ArgList arg_list,
1415 ** Cardinal *num_args)
1419 ** Purpose: This is the Editor widget initialize routine.
1420 ** It is responsible for the following:
1421 ** 1) Validate all resources the user passed in,
1422 ** 2) Override any invalid resources,
1423 ** 3) Initialize the internal data structures,
1424 ** 4) Create the edit area widget
1425 ** 5) Create the status area widget, if requested
1426 ** 6) Add any callbacks and actions
1436 DtEditorWidget request = (DtEditorWidget) rw,
1437 new = (DtEditorWidget) nw;
1439 /* Initialize non-resource portion of the instance structure */
1440 VariableInitialize (new);
1442 /* Validate the incoming arguments to make sure they are OK */
1443 ValidateResources (new, request);
1446 * Create & customize the scrolled text widget
1448 M_text(new) = CreateText (new);
1449 XtManageChild( M_text(new)) ;
1452 * If the widget is not "read only" then register it as a drop zone
1454 if ( M_editable(new) == True )
1455 RegisterDropZone( new );
1458 * Compute the width & height of the scrolled text's font. These values
1459 * will be used when formatting and in calculating the window manager
1462 getFontMetrics(new);
1465 * Create the status line
1467 SetStatusLine( new, M_status_showStatusLine(request) );
1470 } /* end Initialize */
1473 /*-------------------------------------------------------------
1474 ** Function: static void VariableInitialize (
1475 ** DtEditorWidget new )
1477 ** Parameters: The Editor widget being created
1479 ** Purpose: This routine:
1480 ** 1) Initializes the widget's instance structure
1489 * Initialize the non-resource instance fields
1492 M_display(new) = XtDisplayOfObject( (Widget)new->core.parent );
1493 M_app_context(new) = XtDisplayToApplicationContext(M_display(new));
1496 * Empty 'for' walks up the widget tree to find a shell.
1498 for (thisParent = new->core.parent;
1499 thisParent != (Widget)NULL && XtIsShell(thisParent) == False;
1500 thisParent = XtParent(thisParent));
1501 M_topLevelShell(new) = thisParent;
1503 /* Initialize edit area fields */
1504 M_loadingAllNewData(new) = False;
1505 M_unreadChanges(new) = False; /* There have not been any changes since */
1506 /* the app requested the data */
1507 M_deletionStart(new) = NO_DELETION_IN_PROGRESS;
1508 M_deletedText(new) = (char *)NULL;
1509 M_insertStart(new) = 0;
1510 M_insertionLength(new) = 0;
1511 M_textSelectCbCalled(new) = False;
1512 M_fontWidth(new) = -1;
1514 /* Initialize status line fields */
1515 M_status_statusArea(new) = (Widget)NULL;
1516 M_status_messageText(new) = (Widget)NULL;
1517 M_status_currentLine(new) = -1;
1518 M_status_lastLine(new) = -1;
1520 /* Initialize search function data */
1521 M_search_dialog(new) = (Widget) NULL;
1522 M_search_dialogMode(new) = SPELL;
1523 M_search_string(new) = (char *)NULL;
1524 M_replace_string(new) = (char *)NULL;
1525 M_misspelled_string(new) = (char *)NULL;
1526 M_misspelled_found(new) = False;
1528 /* Initialize format function data */
1529 M_format_dialog(new) = (Widget)NULL;
1531 /* Initialize warning dialogs data */
1532 M_gen_warning(new) = (Widget)NULL;
1534 } /* end VariableInitialize */
1537 /*-------------------------------------------------------------
1538 ** Function: static void ValidateResources (
1539 ** DtEditorWidget new,
1540 ** DtEditorWidget request )
1542 ** Parameters: The Editor widget being created & its requested
1545 ** Purpose: This routine:
1546 ** 1) Validates the widget's requested resources
1551 DtEditorWidget request)
1554 * Validate the requested values for the editor's resources
1558 * Make local copies of all resource strings assigned by the application.
1561 if (M_spellFilter(request) != (char *) NULL)
1562 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
1565 * Copy the dialog titles if the application set them, otherwise,
1566 * get their values from the message catalog.
1569 if (M_spellTitle(request) != (XmString) NULL)
1570 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
1572 M_spellTitle(new) = XmStringCreateLocalized(SPELL_TITLE);
1574 if (M_fndChngTitle(request) != (XmString) NULL)
1575 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
1577 M_fndChngTitle(new) = XmStringCreateLocalized(FIND_TITLE);
1579 if (E_format_dialogTitle(request) != (XmString) NULL)
1580 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
1582 E_format_dialogTitle(new) = XmStringCreateLocalized(FORMAT_SETTINGS);
1584 if (E_infoDialogTitle(request) != (XmString) NULL)
1585 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
1587 E_infoDialogTitle(new) = XmStringCreateLocalized(INFO_TITLE);
1590 * Copy the insert & overstrike label indicators if the appli-
1591 * cation set them, otherwise, get their value from the message
1593 * Check for DtUNSPECIFIED because NULL is a valid value.
1596 if (M_status_insertLabel(request) != (XmString) DtUNSPECIFIED)
1597 M_status_insertLabel(new) =
1598 XmStringCopy( M_status_insertLabel(request) );
1600 M_status_insertLabel(new) = XmStringCreateLocalized(INS);
1602 if (M_status_overstrikeLabel(request) != (XmString) DtUNSPECIFIED)
1603 M_status_overstrikeLabel(new) =
1604 XmStringCopy( M_status_overstrikeLabel(request) );
1606 M_status_overstrikeLabel(new) = XmStringCreateLocalized(OVR);
1608 } /* end ValidateResources */
1611 /*-------------------------------------------------------------
1612 ** Function: static Widget CreateText (
1613 ** DtEditorWidget parent)
1615 ** Parameters: The parent of the text widget
1617 ** Purpose: This routine creates the scrolled text widget which
1618 ** lives inside the editor widget.
1619 ** It is responsible for the following:
1620 ** 1) Creating the scrolled text widget,
1621 ** 2) Adding specific translations,
1622 ** 3) Adding our own callbacks,
1623 ** 4) Substituting our own set selection routine.
1627 DtEditorWidget parent)
1629 register int ac; /* arg count */
1630 Arg al[21]; /* arg list */
1634 * First, set up the hardwired scrolled text widget resource values.
1635 * (Change these and you die! Aha! Ha! Ha! Ha! [evil laugh])
1639 XtSetArg (al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
1640 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1641 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1642 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1643 XtSetArg(al[ac], XmNpendingDelete, True); ac++;
1646 * Now, set up the resource values which can vary (passed in from
1647 * application or default values).
1649 * If a synthetic resource is DtUNSPECIFIED don't set it, but let
1650 * it default to the scrolled text default value.
1651 * If it is specified, clear the data field after setting the
1652 * resource because the value in the field will be out of sync
1653 * with the real value.
1655 XtSetArg(al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(parent));
1658 XtSetArg(al[ac], XmNblinkRate, M_blinkRate(parent)); ac++;
1660 if ( M_columns(parent) != DtUNSPECIFIED) {
1661 XtSetArg (al[ac], XmNcolumns, M_columns(parent) ); ac++;
1662 M_columns(parent) = (short) DtUNSPECIFIED;
1665 if ( M_cursorPos(parent) != DtUNSPECIFIED) {
1666 XtSetArg (al[ac], XmNcursorPosition, M_cursorPos(parent)); ac++;
1667 M_cursorPos(parent) = (XmTextPosition) DtUNSPECIFIED;
1670 XtSetArg(al[ac], XmNcursorPositionVisible, M_cursorPosVisible(parent));
1673 XtSetArg(al[ac], XmNeditable, M_editable(parent)); ac++;
1675 if ( E_textFontList(parent) != (XmFontList) NULL) {
1676 XtSetArg (al[ac], XmNfontList, E_textFontList(parent)); ac++;
1679 if ( M_maxLength(parent) != DtUNSPECIFIED) {
1680 XtSetArg (al[ac], XmNmaxLength, M_maxLength(parent) ); ac++;
1681 M_maxLength(parent) = (int) DtUNSPECIFIED;
1684 if ( M_rows(parent) != DtUNSPECIFIED) {
1685 XtSetArg (al[ac], XmNrows, M_rows(parent) ); ac++;
1686 M_rows(parent) = (short) DtUNSPECIFIED;
1689 XtSetArg (al[ac], XmNscrollHorizontal, M_scrollHorizontal(parent) ); ac++;
1691 if ( M_scrollLeftSide(parent) != (Boolean)DtUNSPECIFIED) {
1692 XtSetArg (al[ac], XmNscrollLeftSide, M_scrollLeftSide(parent) ); ac++;
1693 M_scrollLeftSide(parent) = (Boolean)DtUNSPECIFIED;
1696 if ( M_scrollTopSide(parent) != (Boolean)DtUNSPECIFIED) {
1697 XtSetArg (al[ac], XmNscrollTopSide, M_scrollTopSide(parent) ); ac++;
1698 M_scrollTopSide(parent) = (Boolean)DtUNSPECIFIED;
1701 XtSetArg (al[ac], XmNscrollVertical, M_scrollVertical(parent) ); ac++;
1703 if ( M_topCharacter(parent) != DtUNSPECIFIED) {
1704 XtSetArg (al[ac], XmNtopCharacter, M_topCharacter(parent) ); ac++;
1705 M_topCharacter(parent) = (XmTextPosition) DtUNSPECIFIED;
1708 XtSetArg (al[ac], XmNwordWrap, M_wordWrap(parent) ); ac++;
1710 /* Create text widget */
1711 text = XmCreateScrolledText ( (Widget) parent, "text", al, ac );
1715 * Now, set the foreground & background of the text widget. Could not
1716 * set it at create time because the scrolled window would have
1717 * picked it up, too.
1721 if ( M_textBackground(parent) != DtUNSPECIFIED) {
1722 XtSetArg (al[ac], XmNbackground, M_textBackground(parent) ); ac++;
1723 M_textBackground(parent) = (Pixel) DtUNSPECIFIED;
1726 if ( M_textForeground(parent) != DtUNSPECIFIED) {
1727 XtSetArg (al[ac], XmNforeground, M_textForeground(parent) ); ac++;
1728 M_textForeground(parent) = (Pixel) DtUNSPECIFIED;
1732 XtSetValues( text, al, ac);
1735 /* XXX Word Wrap workaround. See comments for FixWordWrap() */
1736 if ( M_scrollHorizontal(parent) ) /* XXX Word Wrap workaround */
1737 FixWordWrap(text, M_wordWrap(parent)); /* XXX Word Wrap workaround */
1740 /* Put the editor-specific translation routines in place. */
1741 XtOverrideTranslations(text,
1742 XtParseTranslationTable(EditorTranslationTable));
1744 /* Add any translations set by the application. */
1745 if ( E_textTranslations(parent) != (XtTranslations)NULL ) {
1746 XtOverrideTranslations(text, E_textTranslations(parent));
1751 * Add modify verify callback
1753 XtAddCallback(text, XmNmodifyVerifyCallback,
1754 (XtCallbackProc) _DtEditorModifyVerifyCB,
1755 (XtPointer) parent);
1758 * Add the Help callback
1760 XtAddCallback( text, XmNhelpCallback, (XtCallbackProc) HelpEditWindowCB,
1761 (XtPointer) parent );
1765 * Substitute our own Set Selection routine which can
1766 * call the textSelect and textDeselect callback procs
1768 if(((XmTextWidget)(text))->text.source->SetSelection !=
1769 Editor_SetSelectionProc) {
1770 M_setSelection(parent) =
1771 ((XmTextWidget)(text))->text.source->SetSelection;
1772 ((XmTextWidget)(text))->text.source->SetSelection =
1773 Editor_SetSelectionProc;
1777 XtSetSensitive (text, True);
1780 } /* end CreateText */
1783 /*-------------------------------------------------------------
1784 ** Function: static int extractFontMetrics (
1785 ** XmFontList fontlist )
1787 ** Purpose: Given a font list, determine the width & height
1788 ** of the characters.
1790 ** This routine is lifted almost straight out of
1791 ** lib/Xm/TextOut.c (see LoadFontMetrics() ) so the editor will
1792 ** select the same font the text widget is working with.
1797 XmFontList fontlist,
1801 XmFontContext context;
1802 XmFontListEntry next_entry;
1803 XmFontType type_return = XmFONT_IS_FONT;
1806 Boolean have_font_struct = False;
1807 Boolean have_font_set = False;
1808 Boolean use_font_set = False;
1809 XFontSetExtents *fs_extents;
1810 unsigned long tmp_width = 0;
1811 int font_descent, font_ascent;
1812 char* font_tag = NULL;
1815 *width = *height = 0;
1816 if (XmFontListInitFontContext(&context, fontlist)) {
1819 * Look through the font list for a fontset with the default tag.
1820 * If we do not find it, use the first font set we came to, otherwise,
1821 * use the first font struct we came to.
1824 Boolean do_break = False;
1826 next_entry = XmFontListNextEntry(context);
1829 tmp_font = XmFontListEntryGetFont(next_entry, &type_return);
1830 if (type_return == XmFONT_IS_FONTSET) {
1835 font_tag = XmFontListEntryGetTag(next_entry);
1837 if (!have_font_set){
1840 * Save the first fontset found in case we don't find
1841 * a default tag font set.
1843 have_font_set = True; /* we have a font set. */
1844 use_font_set = True;
1845 font = (XFontStruct *)tmp_font;
1848 * We have a font set, so no need to consider future font
1851 have_font_struct = True;
1854 * If this is the default font set break out, we've
1855 * found the one we want.
1857 if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag))
1861 else if (!strcmp(XmFONTLIST_DEFAULT_TAG, font_tag)) {
1863 * If this is the default font set save it & break out,
1864 * we've found the one we want.
1866 font = (XFontStruct *)tmp_font;
1867 have_font_set = True;
1871 if (NULL != font_tag)
1877 else if (!have_font_struct){
1882 use_font_set = False;
1885 * Save the first one in case no font set is found
1887 font = (XFontStruct *)tmp_font;
1888 use_font_set = False;
1889 have_font_struct = True;
1894 } while (next_entry != NULL);
1896 XmFontListFreeFontContext(context);
1899 * Now, extract the font metrics from the font set or font that
1907 fs_extents = XExtentsOfFontSet((XFontSet)font);
1909 if (XmDirectionMatch(w->manager.string_direction,
1910 XmTOP_TO_BOTTOM_RIGHT_TO_LEFT)) {
1911 tmp_width = (unsigned long)fs_extents->max_ink_extent.width;
1913 tmp_width = (unsigned long)fs_extents->max_logical_extent.width;
1915 /* max_logical_extent.y is number of pixels from origin to top of
1916 * rectangle (i.e. y is negative) */
1917 font_ascent = -fs_extents->max_logical_extent.y;
1918 font_descent = fs_extents->max_logical_extent.height +
1919 fs_extents->max_logical_extent.y;
1924 * Chose a font struct
1926 font_ascent = font->max_bounds.ascent;
1927 font_descent = font->max_bounds.descent;
1928 if ( (!XGetFontProperty(font, XA_QUAD_WIDTH, &tmp_width)) ||
1931 if ( font->per_char && font->min_char_or_byte2 <= '0' &&
1932 font->max_char_or_byte2 >= '0' )
1933 tmp_width = font->per_char['0' - font->min_char_or_byte2].width;
1935 tmp_width = font->max_bounds.width;
1940 if (tmp_width <= 0) tmp_width = 1;
1941 *width = (int)tmp_width; /* This assumes there will be no truncation */
1942 *height = font_descent + font_ascent;
1946 } /* end extractFontMetrics */
1950 /*-------------------------------------------------------------
1951 ** Function: static void getFontMetrics (
1952 ** DtEditorWidget w )
1954 ** Parameters: An Editor widget
1956 ** Purpose: Determine the height & width of the scrolled text
1964 Arg al[10]; /* arg list */
1965 XmFontList fontlist;
1969 * Get the text widget's font list
1971 * Note, have to retrieve the fontList from the text widget rather
1972 * than use the DtNtextFontList resource because the text widget may
1973 * have rejected the font specified with DtNtextFontList. This way
1974 * we will get the fontList actually used by the text widget.
1977 XtSetArg(al[0], XmNfontList, &fontlist);
1978 XtGetValues(M_text(w), al, 1);
1981 * Now, extract the height and width
1983 extractFontMetrics( w, fontlist, &height, &width );
1984 M_fontWidth(w) = width;
1985 M_fontHeight(w) = height;
1987 } /* end getFontMetrics */
1990 /*-------------------------------------------------------------
1992 ** Release resources allocated for a widget instance.
1998 DtEditorWidget editor = (DtEditorWidget) widget;
2001 * Cleanup the edit window
2005 * (Nothing to be done. Unregistering it as a drop site is handled
2006 * automatically by the DnD library.)
2010 * Cleanup the status line
2013 if (M_status_insertLabel(editor) != (XmString)DtUNSPECIFIED)
2014 XmStringFree(M_status_insertLabel(editor));
2016 if (M_status_overstrikeLabel(editor) != (XmString)DtUNSPECIFIED)
2017 XmStringFree(M_status_overstrikeLabel(editor));
2019 if (E_status_currentLineLabel(editor) != (XmString)DtUNSPECIFIED)
2020 XmStringFree(E_status_currentLineLabel(editor));
2022 if (E_status_totalLineCountLabel(editor) != (XmString)DtUNSPECIFIED)
2023 XmStringFree(E_status_totalLineCountLabel(editor));
2026 * Cleanup the Find/Change & Spell dialogs
2029 if (M_search_string(editor))
2030 XtFree(M_search_string(editor));
2032 if (M_replace_string(editor))
2033 XtFree(M_replace_string(editor));
2035 if (M_misspelled_string(editor))
2036 XtFree(M_misspelled_string(editor));
2038 if (M_spellFilter(editor))
2039 XtFree(M_spellFilter(editor));
2041 if (M_spellTitle(editor) != (XmString)NULL)
2042 XmStringFree(M_spellTitle(editor));
2044 if (E_misspelledListLabel(editor) != (XmString)DtUNSPECIFIED)
2045 XmStringFree(E_misspelledListLabel(editor));
2047 if (M_fndChngTitle(editor) != (XmString)NULL)
2048 XmStringFree(M_fndChngTitle(editor));
2050 if (E_findFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2051 XmStringFree(E_findFieldLabel(editor));
2053 if (E_changeFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2054 XmStringFree(E_changeFieldLabel(editor));
2056 if (E_findButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2057 XmStringFree(E_findButtonLabel(editor));
2059 if (E_changeButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2060 XmStringFree(E_changeButtonLabel(editor));
2062 if (E_changeAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2063 XmStringFree(E_changeAllButtonLabel(editor));
2066 * Cleanup the Format Settings dialog
2068 if (E_format_dialogTitle(editor) != (XmString)NULL)
2069 XmStringFree(E_format_dialogTitle(editor));
2071 if (E_format_leftMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2072 XmStringFree(E_format_leftMarginFieldLabel(editor));
2074 if (E_format_rightMarginFieldLabel(editor) != (XmString)DtUNSPECIFIED)
2075 XmStringFree(E_format_rightMarginFieldLabel(editor));
2077 if (E_format_leftAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2078 XmStringFree(E_format_leftAlignToggleLabel(editor));
2080 if (E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2081 XmStringFree(E_format_rightAlignToggleLabel(editor));
2083 if (E_format_justifyToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2084 XmStringFree(E_format_justifyToggleLabel(editor));
2086 if (E_format_centerToggleLabel(editor) != (XmString)DtUNSPECIFIED)
2087 XmStringFree(E_format_centerToggleLabel(editor));
2089 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2090 XmStringFree(E_format_formatAllButtonLabel(editor));
2092 if (E_format_formatParagraphButtonLabel(editor) != (XmString)DtUNSPECIFIED)
2093 XmStringFree(E_format_formatParagraphButtonLabel(editor));
2096 * Cleanup the Information dialog
2098 if (E_infoDialogTitle(editor) != (XmString)NULL)
2099 XmStringFree(E_infoDialogTitle(editor));
2102 * Cleanup the Undo deletion context
2105 _DtEditorResetUndo(editor);
2110 /*-------------------------------------------------------------
2112 ** Handle changes in resource data.
2122 Boolean redisplay_flag = False;
2123 Arg al[15]; /* arg list */
2124 register int ac; /* arg count */
2126 Boolean resetSpellTitle = False,
2127 resetFormatTitle = False,
2128 resetInfoTitle = False,
2129 newButtonFontList = False,
2130 newLabelFontList = False,
2131 newTextFontList = False,
2132 NeedToFixWordWrap = False; /* XXX Word Wrap workaround*/
2134 DtEditorWidget current = (DtEditorWidget) cw;
2135 DtEditorWidget request = (DtEditorWidget) rw;
2136 DtEditorWidget new = (DtEditorWidget) nw;
2139 * XXX Need to propagate changes to Core resources, like XmNbackground,
2144 * If a synthetic resource is specified, clear the data field
2145 * after setting the resource because the value in the field
2146 * will be out of sync with the real value (contained in the
2151 * General changes, not directly affecting a child
2154 /* Check for a new spell filter */
2156 if ( strcmp(M_spellFilter(request), M_spellFilter(current)) != 0 )
2158 XtFree( M_spellFilter(current) );
2159 M_spellFilter(new) = XtNewString( M_spellFilter(request) );
2162 /* Check for new font lists */
2164 if ( E_buttonFontList(request) != E_buttonFontList(current) )
2165 newButtonFontList = True;
2167 if ( E_labelFontList(request) != E_labelFontList(current) )
2168 newLabelFontList = True;
2170 if ( E_textFontList(request) != E_textFontList(current) )
2171 newTextFontList = True;
2174 * Check for any changes which affect the dialog titles
2177 if (XmStringCompare(E_dialogTitle(request),E_dialogTitle(current)) == False) {
2178 resetSpellTitle = resetFormatTitle = resetInfoTitle = True;
2181 if (XmStringCompare(M_spellTitle(request),M_spellTitle(current)) == False) {
2182 XmStringFree( M_spellTitle(current) );
2183 M_spellTitle(new) = XmStringCopy( M_spellTitle(request) );
2184 resetSpellTitle = True;
2187 if (XmStringCompare(M_fndChngTitle(request),M_fndChngTitle(current)) == False)
2189 XmStringFree( M_fndChngTitle(current) );
2190 M_fndChngTitle(new) = XmStringCopy( M_fndChngTitle(request) );
2191 resetSpellTitle = True;
2194 if (XmStringCompare(E_format_dialogTitle(request),
2195 E_format_dialogTitle(current) ) == False)
2197 XmStringFree( E_format_dialogTitle(current) );
2198 E_format_dialogTitle(new) = XmStringCopy( E_format_dialogTitle(request) );
2199 resetFormatTitle = True;
2202 if (XmStringCompare(E_infoDialogTitle(request),
2203 E_infoDialogTitle(current) ) == False)
2205 XmStringFree( E_infoDialogTitle(current) );
2206 E_infoDialogTitle(new) = XmStringCopy( E_infoDialogTitle(request) );
2207 resetInfoTitle = True;
2211 * Calculate new titles for the dialogs depending upon which resources
2214 if ( resetSpellTitle == True ) {
2216 * No need to do anything because the Spell and Find/Change dialog
2217 * titles are recomputed every time.
2219 redisplay_flag = True;
2222 if ( resetFormatTitle == True ) {
2223 SetFormatDialogTitle( new );
2224 redisplay_flag = True;
2227 if ( resetInfoTitle == True ) {
2228 SetInfoDialogTitle( new );
2229 redisplay_flag = True;
2234 * Check for any changes which affect the status line
2236 if (M_status_showStatusLine(request) != M_status_showStatusLine(current)) {
2237 SetStatusLine( new, M_status_showStatusLine(request) );
2238 redisplay_flag = True;
2241 if ( M_overstrikeMode(request) != M_overstrikeMode(current) ) {
2243 UpdateOverstrikeIndicator( new, M_overstrikeMode(request) );
2244 XtCallActionProc( (Widget) M_text(current), "toggle-overstrike",
2245 (XEvent *)NULL, (String *)NULL, 0 );
2246 redisplay_flag = True;
2249 if ( M_status_statusArea(current) != (Widget)NULL ) {
2251 if (newLabelFontList == True) {
2252 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2253 XtSetValues( (Widget) M_status_lineLabel(current), al, 1);
2254 XtSetValues( (Widget) M_status_totalLabel(current), al, 1);
2255 XtSetValues( (Widget) M_status_totalText(current), al, 1);
2256 XtSetValues( (Widget) M_status_overstrikeWidget(current), al, 1);
2260 if (newTextFontList == True) {
2261 XtSetArg( al[ac], XmNfontList, E_textFontList(request) ); ac++;
2264 if ( M_textBackground(request) != DtUNSPECIFIED) {
2265 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2268 if ( M_textForeground(request) != DtUNSPECIFIED) {
2269 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2273 XtSetValues( (Widget) M_status_lineText(current), al, ac);
2274 XtSetValues( (Widget) M_status_messageText(current), al, ac);
2281 * Check for any changes which affect the dialog boxes
2284 /* Information dialog */
2286 if ( M_gen_warning(current) != (Widget)NULL ) {
2288 if ( newButtonFontList == True ) {
2289 XtSetArg (al[0], XmNfontList, E_buttonFontList(request) );
2291 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_OK_BUTTON),
2295 if ( newLabelFontList == True ) {
2296 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2298 XmMessageBoxGetChild(M_gen_warning(current), XmDIALOG_MESSAGE_LABEL),
2304 /* Find/Change dialog */
2305 if ( M_search_dialog(current) != (Widget)NULL )
2307 if ( newButtonFontList == True ) {
2308 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2309 XtSetValues( (Widget)M_search_findBtn(current), al, 1 );
2310 XtSetValues( (Widget)M_search_replaceBtn(current), al, 1 );
2311 XtSetValues( (Widget)M_search_replaceAllBtn(current), al, 1 );
2312 XtSetValues( (Widget)M_search_closeBtn(current), al, 1 );
2313 XtSetValues( (Widget)M_search_helpBtn(current), al, 1 );
2316 if ( newLabelFontList == True ) {
2317 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2318 XtSetValues( (Widget)M_search_listLbl(current), al, 1 );
2319 XtSetValues( (Widget)M_search_findLbl(current), al, 1 );
2320 XtSetValues( (Widget)M_search_replaceLbl(current), al, 1);
2323 if ( newTextFontList == True ) {
2324 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2325 XtSetValues( (Widget)M_search_spellList(current), al, 1);
2326 XtSetValues( (Widget)M_findText(current), al, 1 );
2327 XtSetValues( (Widget)M_replaceText(current), al, 1 );
2331 if ( M_textBackground(request) != DtUNSPECIFIED) {
2332 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2335 if ( M_textForeground(request) != DtUNSPECIFIED) {
2336 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2340 XtSetValues( (Widget) M_findText(current), al, ac);
2341 XtSetValues( (Widget) M_replaceText(current), al, ac);
2346 /* Format Settings dialog */
2347 if ( M_format_dialog(current) != (Widget)NULL )
2349 if ( newButtonFontList == True ) {
2350 XtSetArg (al[0], XmNfontList, E_buttonFontList(request));
2351 XtSetValues( (Widget)M_format_leftJust(current), al, 1 );
2352 XtSetValues( (Widget)M_format_rightJust(current), al, 1);
2353 XtSetValues( (Widget)M_format_bothJust(current), al, 1 );
2354 XtSetValues( (Widget)M_format_center(current), al, 1 );
2355 XtSetValues( (Widget)M_format_paragraph(current), al, 1);
2356 XtSetValues( (Widget)M_format_all(current), al, 1 );
2357 XtSetValues( (Widget)M_format_close(current), al, 1 );
2358 XtSetValues( (Widget)M_format_help(current), al, 1 );
2361 if ( newLabelFontList == True ) {
2362 XtSetArg (al[0], XmNfontList, E_labelFontList(request) );
2363 XtSetValues( (Widget)M_format_leftLabel(current), al, 1 );
2364 XtSetValues( (Widget)M_format_rightLabel(current), al, 1);
2367 if ( newTextFontList == True ) {
2368 XtSetArg (al[0], XmNfontList, E_textFontList(request) );
2369 XtSetValues( (Widget)M_format_leftMarginField(current), al, 1 );
2370 XtSetValues( (Widget)M_format_rightMarginField(current), al, 1);
2374 if ( M_textBackground(request) != DtUNSPECIFIED) {
2375 XtSetArg( al[ac], XmNbackground, M_textBackground(request) ); ac++;
2378 if ( M_textForeground(request) != DtUNSPECIFIED) {
2379 XtSetArg( al[ac], XmNforeground, M_textForeground(request) ); ac++;
2383 XtSetValues( (Widget) M_format_leftMarginField(current), al, ac);
2384 XtSetValues( (Widget) M_format_rightMarginField(current), al, ac);
2391 * Check for any changes which affect the edit area (scrolled text widget)
2395 if ( M_autoShowCursorPos(request) != M_autoShowCursorPos(current) ) {
2396 XtSetArg( al[ac], XmNautoShowCursorPosition, M_autoShowCursorPos(request));
2400 if ( M_blinkRate(request) != M_blinkRate(current) ) {
2401 XtSetArg( al[ac], XmNblinkRate, M_blinkRate(request)); ac++;
2404 if ( M_columns(request) != DtUNSPECIFIED) {
2405 XtSetArg (al[ac], XmNcolumns, M_columns(request) ); ac++;
2406 M_columns(new) = (short) DtUNSPECIFIED;
2407 redisplay_flag = True;
2410 /* PERF - disable redisplay for all SetValues */
2411 if ( M_cursorPos(request) != DtUNSPECIFIED) {
2412 XmTextSetCursorPosition( M_text(new), M_topCharacter(request) );
2413 M_cursorPos(new) = (XmTextPosition) DtUNSPECIFIED;
2416 if ( M_cursorPosVisible(request) != M_cursorPosVisible(current) ) {
2417 XtSetArg( al[ac], XmNcursorPositionVisible, M_cursorPosVisible(request));
2421 if ( M_editable(request) != M_editable(current) ) {
2422 XtSetArg( al[ac], XmNeditable, M_editable(request)); ac++;
2424 if( M_editable(request) ) {
2427 * If the widget is becoming editable, register it as a
2430 RegisterDropZone( new );
2433 * ...turn back on the Change To field in the Find/Change dialog
2435 if ( M_search_dialog(current) != (Widget)NULL ) {
2436 XtSetSensitive(M_search_replaceLbl(current), True);
2437 XtSetSensitive(M_replaceText(current), True);
2443 * It's no longer available as a drop site.
2445 UnregisterDropZone( current );
2448 if ( M_maxLength(request) != DtUNSPECIFIED) {
2449 XtSetArg (al[ac], XmNmaxLength, M_maxLength(request) ); ac++;
2450 M_maxLength(new) = (int) DtUNSPECIFIED;
2453 if ( M_rows(request) != DtUNSPECIFIED) {
2454 XtSetArg (al[ac], XmNrows, M_rows(request) ); ac++;
2455 M_rows(new) = (short) DtUNSPECIFIED;
2456 redisplay_flag = True;
2459 if ( M_textBackground(request) != DtUNSPECIFIED) {
2460 XtSetArg (al[ac], XmNbackground, M_textBackground(request) ); ac++;
2461 M_textBackground(new) = (XmTextPosition) DtUNSPECIFIED;
2462 redisplay_flag = True;
2465 if ( newTextFontList == True ) {
2466 XtSetArg (al[ac], XmNfontList, E_textFontList(request) ); ac++;
2467 redisplay_flag = True;
2470 if ( M_textForeground(request) != DtUNSPECIFIED) {
2471 XtSetArg (al[ac], XmNforeground, M_textForeground(request) ); ac++;
2472 M_textForeground(new) = (XmTextPosition) DtUNSPECIFIED;
2473 redisplay_flag = True;
2476 /* PERF - disable redisplay for all SetValues */
2477 if ( M_topCharacter(request) != DtUNSPECIFIED) {
2478 XmTextSetTopCharacter( M_text(new), M_topCharacter(request) );
2479 M_topCharacter(new) = (XmTextPosition) DtUNSPECIFIED;
2482 if ( M_wordWrap(request) != M_wordWrap(current) ) {
2483 XtSetArg( al[ac], XmNwordWrap, M_wordWrap(request)); ac++;
2484 NeedToFixWordWrap=M_scrollHorizontal(current);/*XXX Word Wrap workaround*/
2487 if ( NeedToFixWordWrap ) /*XXX Word Wrap workaround*/
2488 FixWordWrap(M_text(new), M_wordWrap(request));/*XXX Word Wrap workaround*/
2491 XtSetValues( (Widget) M_text(new), al, ac);
2493 if ( E_textTranslations(request) != E_textTranslations(current) ) {
2494 XtOverrideTranslations(M_text(new), E_textTranslations(request));
2497 if ( newTextFontList == True ) {
2498 getFontMetrics(new);
2501 return (redisplay_flag);
2503 } /* end Set values */
2506 /**************************************************************
2508 ** Get values routines for synthetic resources
2513 _DtEditorGetCenterToggleLabel(
2515 int resource_offset,
2518 DtEditorWidget editor = (DtEditorWidget) wid;
2523 * Get the value directly from the field in the instance structure.
2524 * If it is DtUNSPECIFIED then either:
2525 * 1) the value has been assigned to the widget (so get it from
2527 * 2) the value has never been set (so return the default value).
2530 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2531 data = XmStringCopy( E_format_centerToggleLabel(editor) );
2532 else if (M_format_dialog(editor) != (Widget)NULL)
2534 XtSetArg( al[0], XmNlabelString, &data) ;
2535 XtGetValues( (Widget) M_format_center(editor), al, 1) ;
2538 data = XmStringCreateLocalized(CENTER);
2539 *value = (XtArgVal) data ;
2542 } /* end _DtEditorGetCenterToggleLabel */
2545 _DtEditorGetChangeAllButtonLabel(
2547 int resource_offset,
2550 DtEditorWidget editor = (DtEditorWidget) wid;
2555 * Get the value directly from the field in the instance structure.
2556 * If it is DtUNSPECIFIED then either:
2557 * 1) the value has been assigned to the widget (so get it from
2559 * 2) the value has never been set (so return the default value).
2562 if (E_changeAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2563 data = XmStringCopy( E_changeAllButtonLabel(editor) );
2564 else if (M_search_dialog(editor) != (Widget) NULL)
2566 XtSetArg( al[0], XmNlabelString, &data) ;
2567 XtGetValues( (Widget) M_search_replaceAllBtn(editor), al, 1) ;
2570 data = XmStringCreateLocalized(CHNG_ALL_BUTTON);
2571 *value = (XtArgVal) data ;
2574 } /* end _DtEditorGetChangeAllButtonLabel */
2577 _DtEditorGetChangeButtonLabel(
2579 int resource_offset,
2582 DtEditorWidget editor = (DtEditorWidget) wid;
2587 * Get the value directly from the field in the instance structure.
2588 * If it is DtUNSPECIFIED then either:
2589 * 1) the value has been assigned to the widget (so get it from
2591 * 2) the value has never been set (so return the default value).
2594 if (E_changeButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2595 data = XmStringCopy( E_changeButtonLabel(editor) );
2596 else if (M_search_dialog(editor) != (Widget) NULL)
2598 XtSetArg( al[0], XmNlabelString, &data) ;
2599 XtGetValues( (Widget) M_search_replaceBtn(editor), al, 1) ;
2602 data = XmStringCreateLocalized(CHANGE_BUTTON);
2603 *value = (XtArgVal) data ;
2606 } /* end _DtEditorGetChangeButtonLabel */
2609 _DtEditorGetChangeFieldLabel(
2611 int resource_offset,
2614 DtEditorWidget editor = (DtEditorWidget) wid;
2619 * Get the value directly from the field in the instance structure.
2620 * If it is DtUNSPECIFIED then either:
2621 * 1) the value has been assigned to the widget (so get it from
2623 * 2) the value has never been set (so return the default value).
2626 if (E_changeFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2627 data = XmStringCopy( E_changeFieldLabel(editor) );
2628 else if (M_search_dialog(editor) != (Widget) NULL)
2630 XtSetArg( al[0], XmNlabelString, &data) ;
2631 XtGetValues( (Widget) M_search_replaceLbl(editor), al, 1) ;
2634 data = XmStringCreateLocalized(CHANGE_LABEL);
2635 *value = (XtArgVal) data ;
2638 } /* end _DtEditorGetChangeFieldLabel */
2641 _DtEditorGetColumns(
2643 int resource_offset,
2646 DtEditorWidget editor = (DtEditorWidget) wid;
2650 XtSetArg( al[0], XmNcolumns, &data) ;
2651 XtGetValues( (Widget) M_text(editor), al, 1) ;
2652 *value = (XtArgVal) data ;
2655 } /* end _DtEditorGetColumns */
2658 _DtEditorGetCurrentLineLabel(
2660 int resource_offset,
2663 DtEditorWidget editor = (DtEditorWidget) wid;
2668 * Get the value directly from the field in the instance structure.
2669 * If it is DtUNSPECIFIED then either:
2670 * 1) the value has been assigned to the widget (so get it from
2672 * 2) the value has never been set (so return the default value).
2675 if (E_status_currentLineLabel(editor) != (XmString) DtUNSPECIFIED)
2676 data = XmStringCopy( E_status_currentLineLabel(editor) );
2677 else if (M_status_statusArea(editor) != (Widget) NULL)
2679 XtSetArg( al[0], XmNlabelString, &data) ;
2680 XtGetValues( (Widget) M_status_lineLabel(editor), al, 1) ;
2683 data = XmStringCreateLocalized(LINE);
2684 *value = (XtArgVal) data ;
2687 } /* end _DtEditorGetCurrentLineLabel */
2690 _DtEditorGetCursorPosition(
2692 int resource_offset,
2695 DtEditorWidget editor = (DtEditorWidget) wid;
2696 XmTextPosition data;
2699 XtSetArg( al[0], XmNcursorPosition, &data) ;
2700 XtGetValues( (Widget) M_text(editor), al, 1) ;
2701 *value = (XtArgVal) data ;
2704 } /* end _DtEditorGetCursorPosition */
2707 _DtEditorGetFindButtonLabel(
2709 int resource_offset,
2712 DtEditorWidget editor = (DtEditorWidget) wid;
2717 * Get the value directly from the field in the instance structure.
2718 * If it is DtUNSPECIFIED then either:
2719 * 1) the value has been assigned to the widget (so get it from
2721 * 2) the value has never been set (so return the default value).
2724 if (E_findButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2725 data = XmStringCopy( E_findButtonLabel(editor) );
2726 else if (M_search_dialog(editor) != (Widget) NULL)
2728 XtSetArg( al[0], XmNlabelString, &data) ;
2729 XtGetValues( (Widget) M_search_findBtn(editor), al, 1) ;
2732 data = XmStringCreateLocalized(FIND_BUTTON);
2733 *value = (XtArgVal) data ;
2736 } /* end _DtEditorGetFindButtonLabel */
2739 _DtEditorGetFindFieldLabel(
2741 int resource_offset,
2744 DtEditorWidget editor = (DtEditorWidget) wid;
2749 * Get the value directly from the field in the instance structure.
2750 * If it is DtUNSPECIFIED then either:
2751 * 1) the value has been assigned to the widget (so get it from
2753 * 2) the value has never been set (so return the default value).
2756 if (E_findFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2757 data = XmStringCopy( E_findFieldLabel(editor) );
2758 else if (M_search_dialog(editor) != (Widget) NULL)
2760 XtSetArg( al[0], XmNlabelString, &data) ;
2761 XtGetValues( (Widget) M_search_findLbl(editor), al, 1) ;
2764 data = XmStringCreateLocalized(FIND_LABEL);
2765 *value = (XtArgVal) data ;
2768 } /* end _DtEditorGetFindFieldLabel */
2771 _DtEditorGetFormatAllButtonLabel(
2773 int resource_offset,
2776 DtEditorWidget editor = (DtEditorWidget) wid;
2781 * Get the value directly from the field in the instance structure.
2782 * If it is DtUNSPECIFIED then either:
2783 * 1) the value has been assigned to the widget (so get it from
2785 * 2) the value has never been set (so return the default value).
2788 if (E_format_formatAllButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2789 data = XmStringCopy( E_format_formatAllButtonLabel(editor) );
2790 else if (M_format_dialog(editor) != (Widget)NULL)
2792 XtSetArg( al[0], XmNlabelString, &data) ;
2793 XtGetValues( (Widget) M_format_all(editor), al, 1) ;
2796 data = XmStringCreateLocalized(ALL);
2797 *value = (XtArgVal) data ;
2800 } /* end _DtEditorGetFormatAllButtonLabel */
2803 _DtEditorGetFormatParagraphButtonLabel(
2805 int resource_offset,
2808 DtEditorWidget editor = (DtEditorWidget) wid;
2813 * Get the value directly from the field in the instance structure.
2814 * If it is DtUNSPECIFIED then either:
2815 * 1) the value has been assigned to the widget (so get it from
2817 * 2) the value has never been set (so return the default value).
2820 if(E_format_formatParagraphButtonLabel(editor) != (XmString) DtUNSPECIFIED)
2821 data = XmStringCopy( E_format_formatParagraphButtonLabel(editor) );
2822 else if (M_format_dialog(editor) != (Widget)NULL)
2824 XtSetArg( al[0], XmNlabelString, &data) ;
2825 XtGetValues( (Widget) M_format_paragraph(editor), al, 1) ;
2828 data = XmStringCreateLocalized(PARAGRAPH);
2829 *value = (XtArgVal) data ;
2832 } /* end _DtEditorGetFormatParagraphButtonLabel */
2835 _DtEditorGetJustifyToggleLabel(
2837 int resource_offset,
2840 DtEditorWidget editor = (DtEditorWidget) wid;
2845 * Get the value directly from the field in the instance structure.
2846 * If it is DtUNSPECIFIED then either:
2847 * 1) the value has been assigned to the widget (so get it from
2849 * 2) the value has never been set (so return the default value).
2852 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2853 data = XmStringCopy( E_format_justifyToggleLabel(editor) );
2854 else if (M_format_dialog(editor) != (Widget)NULL)
2856 XtSetArg( al[0], XmNlabelString, &data) ;
2857 XtGetValues( (Widget) M_format_bothJust(editor), al, 1) ;
2860 data = XmStringCreateLocalized(JUSTIFY);
2861 *value = (XtArgVal) data ;
2864 } /* end _DtEditorGetJustifyToggleLabel */
2867 _DtEditorGetLeftAlignToggleLabel(
2869 int resource_offset,
2872 DtEditorWidget editor = (DtEditorWidget) wid;
2877 * Get the value directly from the field in the instance structure.
2878 * If it is DtUNSPECIFIED then either:
2879 * 1) the value has been assigned to the widget (so get it from
2881 * 2) the value has never been set (so return the default value).
2884 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2885 data = XmStringCopy( E_format_leftAlignToggleLabel(editor) );
2886 else if (M_format_dialog(editor) != (Widget)NULL)
2888 XtSetArg( al[0], XmNlabelString, &data) ;
2889 XtGetValues( (Widget) M_format_leftJust(editor), al, 1) ;
2892 data = XmStringCreateLocalized(LEFT_ALIGN);
2893 *value = (XtArgVal) data ;
2896 } /* end _DtEditorGetLeftAlignToggleLabel */
2899 _DtEditorGetLeftMarginFieldLabel(
2901 int resource_offset,
2904 DtEditorWidget editor = (DtEditorWidget) wid;
2909 * Get the value directly from the field in the instance structure.
2910 * If it is DtUNSPECIFIED then either:
2911 * 1) the value has been assigned to the widget (so get it from
2913 * 2) the value has never been set (so return the default value).
2916 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
2917 data = XmStringCopy( E_format_leftMarginFieldLabel(editor) );
2918 else if (M_format_dialog(editor) != (Widget)NULL)
2920 XtSetArg( al[0], XmNlabelString, &data) ;
2921 XtGetValues( (Widget) M_format_leftLabel(editor), al, 1) ;
2924 data = XmStringCreateLocalized(LEFT_MARGIN);
2925 *value = (XtArgVal) data ;
2928 } /* end _DtEditorGetLeftMarginFieldLabel */
2931 _DtEditorGetMaxLength(
2933 int resource_offset,
2936 DtEditorWidget editor = (DtEditorWidget) wid;
2940 XtSetArg( al[0], XmNmaxLength, &data) ;
2941 XtGetValues( (Widget) M_text(editor), al, 1) ;
2942 *value = (XtArgVal) data ;
2945 } /* end _DtEditorGetMaxLength */
2948 _DtEditorGetMisspelledListLabel(
2950 int resource_offset,
2953 DtEditorWidget editor = (DtEditorWidget) wid;
2958 * Get the value directly from the field in the instance structure.
2959 * If it is DtUNSPECIFIED then either:
2960 * 1) the value has been assigned to the widget (so get it from
2962 * 2) the value has never been set (so return the default value).
2965 if (E_misspelledListLabel(editor) != (XmString) DtUNSPECIFIED)
2966 data = XmStringCopy( E_misspelledListLabel(editor) );
2967 else if (M_search_dialog(editor) != (Widget) NULL)
2969 XtSetArg( al[0], XmNlabelString, &data) ;
2970 XtGetValues( (Widget) M_search_listLbl(editor), al, 1) ;
2973 data = XmStringCreateLocalized(MISSPELLED);
2974 *value = (XtArgVal) data ;
2977 } /* end _DtEditorGetMisspelledListLabel */
2980 _DtEditorGetRightAlignToggleLabel(
2982 int resource_offset,
2985 DtEditorWidget editor = (DtEditorWidget) wid;
2990 * Get the value directly from the field in the instance structure.
2991 * If it is DtUNSPECIFIED then either:
2992 * 1) the value has been assigned to the widget (so get it from
2994 * 2) the value has never been set (so return the default value).
2997 if (E_format_rightAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED)
2998 data = XmStringCopy( E_format_rightAlignToggleLabel(editor) );
2999 else if (M_format_dialog(editor) != (Widget)NULL)
3001 XtSetArg( al[0], XmNlabelString, &data) ;
3002 XtGetValues( (Widget) M_format_rightJust(editor), al, 1) ;
3005 data = XmStringCreateLocalized(RIGHT_ALIGN);
3006 *value = (XtArgVal) data ;
3009 } /* end _DtEditorGetRightAlignToggleLabel */
3012 _DtEditorGetRightMarginFieldLabel(
3014 int resource_offset,
3017 DtEditorWidget editor = (DtEditorWidget) wid;
3022 * Get the value directly from the field in the instance structure.
3023 * If it is DtUNSPECIFIED then either:
3024 * 1) the value has been assigned to the widget (so get it from
3026 * 2) the value has never been set (so return the default value).
3029 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
3030 data = XmStringCopy( E_format_rightMarginFieldLabel(editor) );
3031 else if (M_format_dialog(editor) != (Widget)NULL)
3033 XtSetArg( al[0], XmNlabelString, &data) ;
3034 XtGetValues( (Widget) M_format_rightLabel(editor), al, 1) ;
3037 data = XmStringCreateLocalized(RIGHT_MARGIN);
3038 *value = (XtArgVal) data ;
3041 } /* end _DtEditorGetRightMarginFieldLabel */
3046 int resource_offset,
3049 DtEditorWidget editor = (DtEditorWidget) wid;
3053 XtSetArg( al[0], XmNrows, &data) ;
3054 XtGetValues( (Widget) M_text(editor), al, 1) ;
3055 *value = (XtArgVal) data ;
3058 } /* end _DtEditorGetRows */
3061 _DtEditorGetScrollLeftSide(
3063 int resource_offset,
3066 DtEditorWidget editor = (DtEditorWidget) wid;
3070 XtSetArg( al[0], XmNscrollLeftSide, &data) ;
3071 XtGetValues( (Widget) M_text(editor), al, 1) ;
3072 *value = (XtArgVal) data ;
3075 } /* end _DtEditorGetScrollLeftSide */
3078 _DtEditorGetScrollTopSide(
3080 int resource_offset,
3083 DtEditorWidget editor = (DtEditorWidget) wid;
3087 XtSetArg( al[0], XmNscrollTopSide, &data) ;
3088 XtGetValues( (Widget) M_text(editor), al, 1) ;
3089 *value = (XtArgVal) data ;
3092 } /* end _DtEditorGetScrollTopSide */
3095 _DtEditorGetTextBackground(
3097 int resource_offset,
3100 DtEditorWidget editor = (DtEditorWidget) wid;
3104 XtSetArg( al[0], XmNbackground, &data) ;
3105 XtGetValues( (Widget) M_text(editor), al, 1) ;
3106 *value = (XtArgVal) data ;
3109 } /* end _DtEditorGetTextBackground */
3112 _DtEditorGetTextForeground(
3114 int resource_offset,
3117 DtEditorWidget editor = (DtEditorWidget) wid;
3121 XtSetArg( al[0], XmNforeground, &data) ;
3122 XtGetValues( (Widget) M_text(editor), al, 1) ;
3123 *value = (XtArgVal) data ;
3126 } /* end _DtEditorGetTextForeground */
3129 _DtEditorGetTopCharacter(
3131 int resource_offset,
3134 DtEditorWidget editor = (DtEditorWidget) wid;
3135 XmTextPosition data;
3138 XtSetArg( al[0], XmNtopCharacter, &data) ;
3139 XtGetValues( (Widget) M_text(editor), al, 1) ;
3140 *value = (XtArgVal) data ;
3143 } /* end _DtEditorGetTopCharacter */
3146 _DtEditorGetLineCountLabel(
3148 int resource_offset,
3151 DtEditorWidget editor = (DtEditorWidget) wid;
3156 * Get the value directly from the field in the instance structure.
3157 * If it is DtUNSPECIFIED then either:
3158 * 1) the value has been assigned to the widget (so get it from
3160 * 2) the value has never been set (so return the default value).
3163 if (E_status_totalLineCountLabel(editor) != (XmString) DtUNSPECIFIED)
3164 data = XmStringCopy( E_status_totalLineCountLabel(editor) );
3165 else if (M_status_statusArea(editor) != (Widget) NULL)
3167 XtSetArg( al[0], XmNlabelString, &data) ;
3168 XtGetValues( (Widget) M_status_totalLabel(editor), al, 1) ;
3171 data = XmStringCreateLocalized(TOTAL);
3172 *value = (XtArgVal) data ;
3175 } /* end _DtEditorGetLineCountLabel */
3178 /**************************************************************
3180 ** Action Procedures
3185 * The following are DtEditor's actions. A few are internal only (_I
3186 * suffix) and will be called by the default translations DtEditor places
3187 * on the text widget. The rest will be called from an application with
3188 * XtCallActionProc(). The main difference is the internal ones will be
3189 * passed a text widget ID, while the public ones will be passed a DtEditor ID.
3197 Cardinal *num_params)
3200 DtEditorWidget editor = (DtEditorWidget)w;
3202 XtCallActionProc( M_text(editor), "backward-character", event,
3203 params, *num_params );
3211 Cardinal *num_params)
3214 DtEditorWidget editor = (DtEditorWidget)w;
3216 XtCallActionProc( M_text(editor), "backward-paragraph", event,
3217 params, *num_params );
3225 Cardinal *num_params)
3228 DtEditorWidget editor = (DtEditorWidget)w;
3230 XtCallActionProc( M_text(editor), "backward-word", event,
3231 params, *num_params );
3239 Cardinal *num_params)
3242 DtEditorWidget editor = (DtEditorWidget)w;
3244 XtCallActionProc( M_text(editor), "beginning-of-file", event,
3245 params, *num_params );
3253 Cardinal *num_params)
3256 DtEditorWidget editor = (DtEditorWidget)w;
3258 XtCallActionProc( M_text(editor), "beginning-of-line", event,
3259 params, *num_params );
3267 Cardinal *num_params)
3270 DtEditorWidget editor = (DtEditorWidget)w;
3272 XtCallActionProc( M_text(editor), "clear-selection", event,
3273 params, *num_params );
3276 * Clearing selected text also deselects the selection, but for some
3277 * reason the selection proc (Editor_SetSelectionProc) does not get
3278 * called, therefore, we need to call the DtNtextDeselectCallback
3281 Call_TextDeselectCallback(editor);
3290 Cardinal *num_params)
3293 DtEditorWidget editor = (DtEditorWidget)w;
3295 XtCallActionProc( M_text(editor), "copy-clipboard", event,
3296 params, *num_params );
3304 Cardinal *num_params)
3307 DtEditorWidget editor = (DtEditorWidget)w;
3309 XtCallActionProc( M_text(editor), "cut-clipboard", event,
3310 params, *num_params );
3318 Cardinal *num_params)
3321 DtEditorWidget editor = (DtEditorWidget)w;
3323 XtCallActionProc( M_text(editor), "delete-next-character", event,
3324 params, *num_params );
3332 Cardinal *num_params)
3335 DtEditorWidget editor = (DtEditorWidget)w;
3337 XtCallActionProc( M_text(editor), "delete-next-word", event,
3338 params, *num_params );
3346 Cardinal *num_params)
3349 DtEditorWidget editor = (DtEditorWidget)w;
3351 XtCallActionProc( M_text(editor), "delete-previous-character", event,
3352 params, *num_params );
3360 Cardinal *num_params)
3363 DtEditorWidget editor = (DtEditorWidget)w;
3365 XtCallActionProc( M_text(editor), "delete-previous-word", event,
3366 params, *num_params );
3374 Cardinal *num_params)
3377 DtEditorWidget editor = (DtEditorWidget)w;
3379 XtCallActionProc( M_text(editor), "delete-to-end-of-line", event,
3380 params, *num_params );
3388 Cardinal *num_params)
3391 DtEditorWidget editor = (DtEditorWidget)w;
3393 XtCallActionProc( M_text(editor), "delete-to-start-of-line", event,
3394 params, *num_params );
3402 Cardinal *num_params)
3405 DtEditorWidget editor = (DtEditorWidget)w;
3407 XtCallActionProc( M_text(editor), "deselect-all", event,
3408 params, *num_params );
3416 Cardinal *num_params)
3419 DtEditorWidget editor = (DtEditorWidget)w;
3421 XtCallActionProc( M_text(editor), "end-of-file", event,
3422 params, *num_params );
3430 Cardinal *num_params)
3433 DtEditorWidget editor = (DtEditorWidget)w;
3435 XtCallActionProc( M_text(editor), "end-of-line", event,
3436 params, *num_params );
3444 Cardinal *num_params)
3447 DtEditorWidget editor = (DtEditorWidget)w;
3449 XtCallActionProc( M_text(editor), "forward-character", event,
3450 params, *num_params );
3458 Cardinal *num_params)
3461 DtEditorWidget editor = (DtEditorWidget)w;
3463 XtCallActionProc( M_text(editor), "forward-paragraph", event,
3464 params, *num_params );
3472 Cardinal *num_params)
3475 DtEditorWidget editor = (DtEditorWidget)w;
3477 XtCallActionProc( M_text(editor), "forward-word", event,
3478 params, *num_params );
3486 Cardinal *num_params)
3488 DtEditorWidget editor = (DtEditorWidget)w;
3490 if( M_status_statusArea(editor) != (Widget)NULL &&
3491 XtIsManaged(M_status_statusArea(editor)) == True )
3495 * Set the input focus to the "Line" text field.
3498 XmProcessTraversal(M_status_lineText(editor), XmTRAVERSE_CURRENT);
3501 * Select the current contents to allow easy modification.
3504 XtCallActionProc( (Widget)M_status_lineText(editor), "select-all",
3505 event, (String *)NULL, 0 );
3508 } /* end GoToLine */
3511 * Internal action called only from the scrolled text widget
3518 Cardinal *num_params)
3520 XmTextWidget tw = (XmTextWidget)w;
3521 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3523 GoToLine( (Widget)editor, event, params, num_params );
3525 } /* end GoToLine_I */
3532 Cardinal *num_params)
3535 CallHelpCallback((DtEditorWidget)w, DtEDITOR_HELP_EDIT_WINDOW);
3544 Cardinal *num_params)
3547 DtEditorWidget editor = (DtEditorWidget)w;
3549 XtCallActionProc( M_text(editor), "insert-string", event,
3550 params, *num_params );
3558 Cardinal *num_params)
3561 DtEditorWidget editor = (DtEditorWidget)w;
3563 XtCallActionProc( M_text(editor), "key-select", event,
3564 params, *num_params );
3572 Cardinal *num_params)
3575 DtEditorWidget editor = (DtEditorWidget)w;
3577 XtCallActionProc( M_text(editor), "newline-and-backup", event,
3578 params, *num_params );
3586 Cardinal *num_params)
3589 DtEditorWidget editor = (DtEditorWidget)w;
3591 XtCallActionProc( M_text(editor), "newline-and-indent", event,
3592 params, *num_params );
3600 Cardinal *num_params)
3603 DtEditorWidget editor = (DtEditorWidget)w;
3605 XtCallActionProc( M_text(editor), "next-page", event,
3606 params, *num_params );
3614 Cardinal *num_params)
3617 DtEditorWidget editor = (DtEditorWidget)w;
3619 XtCallActionProc( M_text(editor), "page-left", event,
3620 params, *num_params );
3628 Cardinal *num_params)
3631 DtEditorWidget editor = (DtEditorWidget)w;
3633 XtCallActionProc( M_text(editor), "page-right", event,
3634 params, *num_params );
3642 Cardinal *num_params)
3645 DtEditorWidget editor = (DtEditorWidget)w;
3647 XtCallActionProc( M_text(editor), "paste-clipboard", event,
3648 params, *num_params );
3656 Cardinal *num_params)
3659 DtEditorWidget editor = (DtEditorWidget)w;
3661 XtCallActionProc( M_text(editor), "previous-page", event,
3662 params, *num_params );
3670 Cardinal *num_params)
3673 DtEditorWidget editor = (DtEditorWidget)w;
3675 XtCallActionProc( M_text(editor), "process-cancel", event,
3676 params, *num_params );
3684 Cardinal *num_params)
3687 DtEditorWidget editor = (DtEditorWidget)w;
3689 XtCallActionProc( M_text(editor), "process-down", event,
3690 params, *num_params );
3698 Cardinal *num_params)
3701 DtEditorWidget editor = (DtEditorWidget)w;
3703 XtCallActionProc( M_text(editor), "process-shift-down", event,
3704 params, *num_params );
3712 Cardinal *num_params)
3715 DtEditorWidget editor = (DtEditorWidget)w;
3717 XtCallActionProc( M_text(editor), "process-shift-up", event,
3718 params, *num_params );
3726 Cardinal *num_params)
3729 DtEditorWidget editor = (DtEditorWidget)w;
3731 XtCallActionProc( M_text(editor), "process-up", event,
3732 params, *num_params );
3735 /************************************************************************
3736 * GetModeSwitchModifier
3737 * Find if any Mod<n> modifier is acting as the Group modifier - you
3738 * can't assume Mod1Mask is always it.
3739 * Returns the mask of the modifier key to which the Mode_switch
3740 * keysym is attached.
3742 ************************************************************************/
3745 GetModeSwitchModifier(
3748 register XModifierKeymap *pMap;
3749 register int mapIndex, keyCol, mapSize;
3751 unsigned int modeSwitchModMask = 0;
3752 pMap = XGetModifierMapping(dpy);
3753 mapSize = 8*pMap->max_keypermod;
3755 for (mapIndex = 3*pMap->max_keypermod; mapIndex < mapSize; mapIndex++) {
3756 /* look only at the first 4 columns of key map */
3757 for (keyCol = 0; keyCol < 4; keyCol++) {
3758 keySym = XKeycodeToKeysym(dpy, pMap->modifiermap[mapIndex], keyCol);
3759 if (keySym == XK_Mode_switch)
3760 modeSwitchModMask |= 1 << (mapIndex / pMap->max_keypermod);
3764 XFreeModifiermap(pMap);
3765 return modeSwitchModMask;
3768 /************************************************************************
3770 * DtEditorQuoteNextChar
3771 * This action routine circumvents the normal XtDispatchEvent
3772 * mechanism, inserting the next control or extended character
3773 * directly into text without processed by event handlers or the
3774 * translation manager. This means, for
3775 * example, that the next control or extended character will be
3776 * inserted into text without being intrepreted as a Motif menu
3777 * or text widget accelerator.
3779 ************************************************************************/
3786 Cardinal *num_params)
3788 DtEditorWidget editor = (DtEditorWidget)widget;
3789 static unsigned int ExtendcharMask = 0;
3791 /* NOTE: ExtendcharMask could be a global set via a MappingNotify
3792 * event handler. But it isn't...
3795 if (! ExtendcharMask)
3798 if (! ExtendcharMask)
3799 ExtendcharMask = GetModeSwitchModifier( M_display(editor) );
3809 * We cannot let XtAppNextEvent bloc, because the intrinsics
3810 * will release locks and some other thread might dispatch
3811 * the event we want to trap.
3814 XtAppContext app = XtWidgetToApplicationContext(widget);
3815 while ((mask = XtAppPending(app)) == 0)
3817 if (XtAppGetExitFlag(app))
3821 if (mask & XtIMXEvent)
3824 XtAppNextEvent(M_app_context(editor), &next);
3825 if ((next.type == KeyPress) &&
3826 (! IsModifierKey(XLookupKeysym((XKeyEvent *) &next, 0))) )
3828 if (next.xkey.state & (ControlMask|ExtendcharMask))
3829 XtCallActionProc(M_text(editor), "self-insert", &next, NULL, 0);
3831 XtDispatchEvent(&next);
3835 XtDispatchEvent(&next);
3840 /* Some (non-X) event is pending, so this should not block. */
3841 XtAppProcessEvent(app, mask);
3846 } /* end QuoteNextChar */
3849 * Internal action called only from the scrolled text widget
3856 Cardinal *num_params)
3858 XmTextWidget tw = (XmTextWidget)w;
3859 DtEditorWidget editor = (DtEditorWidget) M_editor(tw);
3861 QuoteNextChar( (Widget)editor, event, params, num_params );
3863 } /* end QuoteNextChar_I */
3870 Cardinal *num_params)
3873 DtEditorWidget editor = (DtEditorWidget)w;
3875 XtCallActionProc( M_text(editor), "select-all", event,
3876 params, *num_params );
3884 Cardinal *num_params)
3886 DtEditorWidget editor = (DtEditorWidget)w;
3889 * Toggle the state of the DtNoverstrike resource
3891 XtVaSetValues(w, DtNoverstrike, !M_overstrikeMode(editor), NULL);
3893 } /* end ToggleInsertMode */
3900 Cardinal *num_params)
3902 XmTextWidget tw = (XmTextWidget)w;
3903 DtEditorWidget editor = (DtEditorWidget)M_editor(tw);
3905 ToggleInsertMode( (Widget)editor, event, params, num_params );
3907 } /* end ToggleInsertMode_I */
3915 Cardinal *num_params)
3918 DtEditorUndoEdit(w);
3920 } /* end UndoEdit */
3927 Cardinal *num_params)
3929 XmTextWidget tw = (XmTextWidget)w;
3931 UndoEdit( (Widget)M_editor(tw), event, params, num_params );
3933 } /* end UndoEdit_I */
3937 * XXX All lines in this file marked "XXX Word Wrap workaround"
3938 * XXX are related to a Motif 1.2 Text widget design defect regarding
3939 * XXX word wrap. For Motif 1.2, the Text widget was designed so word
3940 * XXX wrap will not function if the scrolled text widget has a
3941 * XXX horizontal scroll bar ("a hscrollbar means the paper is infinite
3942 * XXX so there is no edge to wrap at"). This change was made in
3943 * XXX Xm/TextOut.c RCS version 1.71 checked in July, 1991. A
3944 * XXX CMVC report was filed 9/8/94 & assigned number 4772.
3946 #include <Xm/TextOutP.h> /* XXX Word Wrap workaround */
3947 static void /* XXX Word Wrap workaround */
3948 FixWordWrap( /* XXX Word Wrap workaround */
3949 Widget w, /* XXX Word Wrap workaround */
3950 Boolean wrapOn) /* XXX Word Wrap workaround */
3951 { /* XXX Word Wrap workaround */
3952 XmTextWidget tw = (XmTextWidget)w; /* XXX Word Wrap workaround */
3953 OutputData data = tw->text.output->data; /* XXX Word Wrap workaround */
3955 data->scrollhorizontal = !wrapOn; /* XXX Word Wrap workaround */
3956 } /* XXX Word Wrap workaround */
3959 Call_TextSelectCallback(
3960 DtEditorWidget editor)
3963 DtEditorSelectCallbackStruct select_cb;
3966 * Call the Editor widget's DtNtextSelectCallback proc
3967 * if it hasn't been called since the last select.
3970 if ( !M_textSelectCbCalled(editor) ) {
3972 M_textSelectCbCalled(editor) = True;
3973 select_cb.reason = DtEDITOR_TEXT_SELECT;
3974 select_cb.event = (XEvent *)NULL;
3975 XtCallCallbackList ((Widget)editor, M_textSelect(editor),
3976 (XtPointer) &select_cb);
3979 } /* end Call_TextSelectCallback */
3982 Call_TextDeselectCallback(
3983 DtEditorWidget editor)
3986 DtEditorSelectCallbackStruct select_cb;
3989 * Call the Editor widget's DtNtextDeselectCallback proc
3990 * if it hasn't been called since the last deselect.
3993 if ( M_textSelectCbCalled(editor) ) {
3995 M_textSelectCbCalled(editor) = False;
3996 select_cb.reason = DtEDITOR_TEXT_DESELECT;
3997 select_cb.event = (XEvent *)NULL;
3998 XtCallCallbackList ((Widget)editor, M_textDeselect(editor),
3999 (XtPointer) &select_cb);
4002 } /* end Call_TextDeselectCallback */
4005 * Editor_SetSelectionProc
4006 * is put into the widget->text.source->SetSelection.
4007 * Used to call the DtEditor's select/unselect callbacks
4010 Editor_SetSelectionProc(
4011 XmTextSource source,
4012 XmTextPosition left,
4013 XmTextPosition right,
4016 XmSourceData data = source->data;
4019 DtEditorWidget editor;
4025 if (!XtIsRealized((Widget)data->widgets[0]) ||
4026 data->numwidgets <= 0)
4029 if (left < 0) left = right = 0;
4031 widget = (Widget) data->widgets[0];
4032 tw = (XmTextWidget)widget;
4033 editor = M_editor(tw);
4035 if (!editor->core.being_destroyed) {
4039 * There is a selected area if left < right so call the
4040 * DtNtextSelectCallback.
4043 Call_TextSelectCallback( editor );
4048 * Left = Right so nothing is selected; call the
4049 * DtNtextDeselectCallback.
4052 Call_TextDeselectCallback( editor );
4058 * Now, call the text widget's real Set Selection proc
4060 (*M_setSelection(editor))(source, left, right, set_time);
4062 } /* end Editor_SetSelectionProc */
4065 /**************************************************************
4067 ** Drag and drop routines
4073 * Handles drops of a file into the text editor, after validation in the
4074 * transfer callback. Files are handled by reading their contents.
4075 * Text is handled by Motif.
4077 * Changing the contents of the text widget occurs here, rather than in
4078 * the transfer callback, because of the visual changes which occur when
4079 * changing the text widget.
4085 XtPointer client_data,
4086 XtPointer call_data )
4089 DtEditorErrorCode error;
4091 DtDndDropAnimateCallbackStruct *animateInfo =
4092 (DtDndDropAnimateCallbackStruct *) call_data;
4093 DtEditorWidget editor = (DtEditorWidget) client_data;
4096 * XXX Only really needed if # of items is > 1
4098 _DtTurnOnHourGlass( M_topLevelShell(editor) );
4101 * How many items are being dropped on us?
4103 numItems = animateInfo->dropData->numItems;
4105 switch (animateInfo->dropData->protocol)
4107 case DtDND_FILENAME_TRANSFER:
4110 * OK, insert each file we are given
4112 for (ii = 0; ii < numItems; ii++)
4114 error = DtEditorInsertFromFile( (Widget)editor,
4115 animateInfo->dropData->data.files[ii] );
4118 * If the file was not inserted successfully, then quit
4119 * (don't care if the file is read only or if it contained
4120 * nulls that were stripped out).
4122 if( error != DtEDITOR_NO_ERRORS &&
4123 error != DtEDITOR_READ_ONLY_FILE &&
4124 error != DtEDITOR_NULLS_REMOVED )
4126 ii = numItems; /* break out of loop */
4133 } /* end file transfer case */
4135 case DtDND_BUFFER_TRANSFER:
4138 * OK, insert each buffer we are given
4141 DtDndBuffer *buffers = animateInfo->dropData->data.buffers;
4142 DtEditorContentRec cr;
4143 cr.type = DtEDITOR_DATA;
4145 for (ii = 0; ii < numItems; ii++)
4147 cr.value.data.buf = buffers[ii].bp;
4148 cr.value.data.length = buffers[ii].size;
4150 error = DtEditorInsert( (Widget)editor, &cr );
4153 * If the buffer was not inserted successfully, then quit
4154 * (don't care if the file contained nulls that were stripped out).
4156 if( error != DtEDITOR_NO_ERRORS && error != DtEDITOR_NULLS_REMOVED )
4158 ii = numItems; /* break out of loop */
4165 } /* end buffer transfer case */
4167 case DtDND_TEXT_TRANSFER:
4170 * Receiving a text drop.
4172 * Text drag and drop is handled by Motif so this switch
4173 * will never be called.
4178 } /* end text transfer case */
4187 * XXX Only really needed if # of items is > 1
4189 _DtTurnOffHourGlass( M_topLevelShell(editor) );
4191 } /* end AnimateCallback */
4195 * Validates a drop of a file into the text widget.
4197 * Changing the contents of the text widget occurs in the animate
4198 * callback, rather than here, because of the visual changes which
4199 * occur when changing the text widget.
4206 XtPointer client_data,
4207 XtPointer call_data)
4210 DtEditorErrorCode error;
4212 DtDndTransferCallbackStruct *transferInfo =
4213 (DtDndTransferCallbackStruct *) call_data;
4215 transferInfo->status = DtDND_SUCCESS;
4218 * How many items are being dropped on us?
4220 numItems = transferInfo->dropData->numItems;
4222 switch (transferInfo->dropData->protocol)
4224 case DtDND_FILENAME_TRANSFER:
4228 * Check to see if we can read each file we are given
4230 for (ii = 0; ii < numItems; ii++)
4232 error = _DtEditorValidateFileAccess(
4233 transferInfo->dropData->data.files[ii],
4237 * Can't access it for reading so reject drop
4239 if ( error != DtEDITOR_NO_ERRORS ) {
4240 transferInfo->status = DtDND_FAILURE;
4241 ii = numItems; /* break out of loop */
4244 } /* end for each file */
4248 } /* end file transfer case */
4250 case DtDND_BUFFER_TRANSFER:
4253 * Receiving a buffer drop.
4254 * -- do nothing in transfer
4258 } /* end buffer transfer case */
4260 case DtDND_TEXT_TRANSFER:
4263 * Receiving a text drop.
4265 * Text drag and drop is handled by Motif so this switch
4266 * will never be called.
4271 } /* end text transfer case */
4275 transferInfo->status = DtDND_FAILURE;
4281 } /* end TransferCallback */
4284 /*-------------------------------------------------------------
4285 ** Function: static void RegisterDropZone (
4286 ** DtEditorWidget w)
4288 ** Parameters: A DtEditor widget
4290 ** Purpose: This routine registers the edit window's text widget
4291 ** as a drop site for file & buffer drops. Because it
4292 ** is a text widget it will automatically accept text
4302 XtCallbackRec transferCB[] = { {TransferCallback, NULL}, {NULL, NULL} };
4303 XtCallbackRec animateCB[] = { {AnimateCallback, NULL}, {NULL, NULL} };
4304 transferCB[0].closure = (XtPointer) w;
4305 animateCB[0].closure = (XtPointer) w;
4308 * Register file & buffer transfers... let Motif handle text DnD
4311 XtSetArg( al[ac], DtNdropAnimateCallback, animateCB ); ac++;
4313 DtDndDropRegister( M_text(w),
4314 DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER,
4315 XmDROP_COPY, transferCB, al, ac );
4317 } /* end RegisterDropZone */
4319 /*-------------------------------------------------------------
4320 ** Function: static void UnregisterDropZone (
4321 ** DtEditorWidget w)
4323 ** Parameters: A DtEditor widget
4325 ** Purpose: This routine unregisters the edit window
4332 DtDndDropUnregister( M_text(w) );
4334 } /* end UnregisterDropZone */
4336 /************************************************************************
4338 * SetInfoDialogTitle - Change the title for the Information dialog
4340 ************************************************************************/
4344 DtEditorWidget editor)
4350 * If the Information dialog has been created, change its title
4352 if( M_gen_warning(editor) != (Widget)NULL )
4356 * Prepend the DialogTitle resource, if it has been set
4358 if( E_dialogTitle(editor) != (XmString)NULL ) {
4362 * Add the "functional title" to the DialogTitle
4364 titleStr = XmStringConcat( E_dialogTitle(editor),
4365 E_infoDialogTitle(editor) );
4367 XtSetArg( al[0], XmNdialogTitle, titleStr );
4368 XtSetValues(M_gen_warning(editor), al, 1);
4370 XmStringFree( titleStr );
4374 XtSetArg( al[0], XmNdialogTitle, E_infoDialogTitle(editor) );
4375 XtSetValues(M_gen_warning(editor), al, 1);
4379 } /* end SetInfoDialogTitle */
4381 /************************************************************************
4383 * _DtEditorWarning - get a message to the user
4385 ************************************************************************/
4389 DtEditorWidget editor,
4391 unsigned char dialogType)
4398 tmpMess = strdup(mess);
4400 /* create the dialog if it is the first time */
4401 if(M_gen_warning(editor) == (Widget) NULL)
4403 XmString titleStr = (XmString) NULL;
4409 * First, create the dialog's title, prepending the
4410 * DtNdialogTitle resource, if it is set
4413 if( E_dialogTitle(editor) != (XmString)NULL ) {
4416 * Add the "functional title" to the DialogTitle
4418 titleStr = XmStringConcat( E_dialogTitle(editor),
4419 E_infoDialogTitle(editor) );
4421 XtSetArg (al[ac], XmNdialogTitle, titleStr ); ac++;
4425 XtSetArg (al[ac], XmNdialogTitle, E_infoDialogTitle(editor)); ac++;
4428 okStr = XmStringCreateLocalized((char*) _DtOkString);
4429 XtSetArg (al[ac], XmNokLabelString, okStr); ac++;
4430 M_gen_warning(editor) = (Widget) XmCreateMessageDialog(
4431 M_topLevelShell(editor), "Warn",
4434 if (titleStr != (XmString) NULL)
4435 XmStringFree( titleStr );
4436 XmStringFree(okStr);
4438 /* Set the correct font lists for the message & OK button. */
4439 XtSetArg (al[0], XmNfontList, E_buttonFontList(editor));
4441 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_OK_BUTTON),
4444 XtSetArg (al[0], XmNfontList, E_labelFontList(editor));
4446 XmMessageBoxGetChild(M_gen_warning(editor), XmDIALOG_MESSAGE_LABEL),
4449 /* Unmanage unneeded children. */
4450 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4451 XmDIALOG_CANCEL_BUTTON) );
4452 XtUnmanageChild ( XmMessageBoxGetChild(M_gen_warning(editor),
4453 XmDIALOG_HELP_BUTTON) );
4455 XtRealizeWidget (M_gen_warning(editor));
4457 XtSetArg(al[ac], XmNmwmInputMode,
4458 MWM_INPUT_PRIMARY_APPLICATION_MODAL);ac++;
4459 XtSetValues(XtParent(M_gen_warning(editor)), al, ac);
4462 tmpStr = XmStringCreateLocalized(tmpMess);
4464 XtSetArg(al[ac], XmNdialogType, dialogType); ac++;
4465 XtSetArg(al[ac], XmNmessageString, tmpStr); ac++;
4466 XtSetValues(M_gen_warning(editor), al, ac);
4467 XmStringFree(tmpStr);
4469 XtFree( (char *) tmpMess );
4471 XtManageChild (M_gen_warning(editor));
4473 } /* end _DtEditorWarning */
4476 /*********************************************************************
4478 * The following section contains the procedures related to the staus
4481 *********************************************************************/
4484 #define DONT_FORCE False
4487 * PositionActivateCB is invoked when the user presses [Return] after
4488 * (presumably) modifying the current line text field. It retrieves
4489 * the user specified line number and calls DtEditorGoToLine().
4496 caddr_t client_data,
4499 DtEditorWidget editor = (DtEditorWidget)client_data;
4500 char *lineStr = XmTextFieldGetString(M_status_lineText(editor));
4501 int newLineNum = atoi(lineStr);
4504 DtEditorGoToLine ((Widget)editor, newLineNum);
4505 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
4507 } /* PositionActivateCB */
4510 * _DtEditorUpdateLineDisplay updates the current & total line displays
4511 * in the status line, if needed. Normally, the displays are not changed
4512 * if the correct numbers are (supposedly) displayed. Setting forceUpdate
4513 * will cause the numbers to be updated anyways. This is primarily used
4514 * when the user enters a number into the current line display to force
4515 * display of the correct number.
4518 _DtEditorUpdateLineDisplay(
4519 DtEditorWidget editor,
4521 Boolean forceUpdate )
4523 XmTextWidget tw = (XmTextWidget) M_text(editor);
4530 * Only change the current & total lines displays if the status
4533 if ( M_status_showStatusLine(editor) == True )
4538 if (M_status_currentLine(editor) != currentLine || forceUpdate)
4540 sprintf(tmpChars, "%d", currentLine);
4541 XmTextFieldSetString(M_status_lineText(editor), tmpChars);
4542 M_status_currentLine(editor) = currentLine;
4548 lastLine = tw->text.total_lines;
4549 if(M_status_lastLine(editor) != lastLine )
4552 sprintf(tmpChars, "%d", lastLine);
4553 tmpXmStr = XmStringCreateLocalized(tmpChars);
4554 XtSetArg(al[0], XmNlabelString, tmpXmStr);
4555 XtSetValues( M_status_totalText(editor), al, 1 );
4557 XmStringFree(tmpXmStr);
4558 M_status_lastLine(editor) = lastLine;
4562 } /* end _DtEditorUpdateLineDisplay */
4566 UpdateOverstrikeIndicator(
4567 DtEditorWidget widget,
4568 Boolean overstrikeOn )
4572 DtEditorWidget ew = (DtEditorWidget) widget;
4575 * Only change the overstrike indicator if the status line is visible
4577 if ( M_status_showStatusLine(ew) == True &&
4578 M_status_overstrikeWidget(ew) != (Widget) NULL )
4582 if ( overstrikeOn == True ) {
4583 XtSetArg(al[ac], XmNlabelString, M_status_overstrikeLabel(ew)); ac++;
4586 XtSetArg(al[ac], XmNlabelString, M_status_insertLabel(ew)); ac++;
4589 XtSetValues( M_status_overstrikeWidget(ew), al, ac );
4592 } /* end UpdateOverstrikeIndicator */
4596 _DtEditorGetLineIndex(
4600 int startLine, lastLine, middleLine;
4601 XmTextLineTable lineTab = tw->text.line_table;
4604 lastLine = tw->text.total_lines - 1;
4606 while(startLine != lastLine)
4608 middleLine = (startLine + lastLine)/2;
4609 if(middleLine == startLine || middleLine == lastLine)
4612 * We're down to 2 lines. It's gotta be on one of these
4615 if(pos < (XmTextPosition) lineTab[lastLine].start_pos)
4616 lastLine = startLine;
4618 startLine = lastLine;
4622 if (pos < (XmTextPosition) lineTab[middleLine].start_pos)
4623 lastLine = middleLine;
4625 startLine = middleLine;
4629 } /* end _DtEditorGetLineIndex */
4633 * SetCursorPosStatus is called as an XmNmotionVerifyCallback on the
4634 * text widget when the statusLine is turned on. It computes and
4635 * displays the new line of the insert cursor.
4640 caddr_t client_data,
4643 DtEditorWidget editor = (DtEditorWidget)client_data;
4644 XmTextWidget tw = (XmTextWidget)w;
4645 XmTextVerifyCallbackStruct * cb = (XmTextVerifyCallbackStruct *) call_data;
4648 startLine = _DtEditorGetLineIndex(tw, cb->newInsert) + 1;
4650 _DtEditorUpdateLineDisplay( editor, startLine, FORCE );
4652 } /* end SetCursorPosStatus */
4658 Boolean statusLineOn)
4663 XmTextPosition cursorPos;
4665 M_status_showStatusLine(ew) = statusLineOn;
4667 if( statusLineOn == True )
4669 if( M_status_statusArea(ew) == (Widget)NULL )
4670 M_status_statusArea(ew) = CreateStatusLine( ew );
4673 * Update the line counts
4676 cursorPos = (XmTextPosition)DtEditorGetInsertionPosition( (Widget)ew );
4677 currentLine = _DtEditorGetLineIndex( (XmTextWidget) M_text(ew),
4679 _DtEditorUpdateLineDisplay( ew, currentLine, DONT_FORCE );
4682 * Update the overstrike indicator
4684 UpdateOverstrikeIndicator( ew, M_overstrikeMode(ew) );
4687 * Show the status line
4690 XtManageChild( M_status_statusArea(ew) );
4693 * Hook the scrolled text widget to the status line
4696 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_WIDGET ); ac++;
4697 XtSetArg( al[ac], XmNbottomWidget, M_status_statusArea(ew) ); ac++;
4698 XtSetValues( XtParent(M_text(ew)), al, ac );
4700 XtAddCallback( M_text(ew), XmNmotionVerifyCallback,
4701 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4707 * Hook the scrolled text widget to the bottom of the form
4710 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4711 XtSetValues( XtParent(M_text(ew)), al, ac );
4713 XtRemoveCallback( M_text(ew), XmNmotionVerifyCallback,
4714 (XtCallbackProc) SetCursorPosStatus, (XtPointer)ew);
4717 * Hide the status line
4719 if( M_status_statusArea(ew) != (Widget)NULL )
4720 XtUnmanageChild( M_status_statusArea(ew) );
4724 } /* SetStatusLine */
4727 /************************************************************************
4729 * CreateStatusLine - Creates the status line
4731 ************************************************************************/
4735 DtEditorWidget parent)
4741 Pixel background, foreground;
4744 * Match the background & foreground colors of the edit window
4745 * Don't use DtNtextBackground/Foreground directly because they
4746 * will be DtUNSPECIFIED.
4749 XtSetArg(al[ac], XmNforeground, &foreground); ac++;
4750 XtSetArg(al[ac], XmNbackground, &background); ac++;
4751 XtGetValues(M_text(parent), al, ac);
4754 * Create the status line container
4757 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4758 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4759 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4760 XtSetArg( al[ac], XmNverticalSpacing, 3 ); ac++;
4761 XtSetArg( al[ac], XmNhorizontalSpacing, 3 ); ac++;
4762 container = (Widget) XmCreateForm( (Widget)parent, "statusLine",
4766 * Create the current line label and text field
4769 if (E_status_currentLineLabel(parent) != (XmString)DtUNSPECIFIED)
4772 * Use the resource value & clear it (to save space).
4774 tmpStr = XmStringCopy(E_status_currentLineLabel(parent));
4775 E_status_currentLineLabel(parent) = (XmString)DtUNSPECIFIED;
4779 * The resource has not been set so use its default value
4781 tmpStr = XmStringCreateLocalized(LINE);
4784 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4785 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4786 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
4788 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4789 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4790 M_status_lineLabel(parent) = (Widget) XmCreateLabelGadget( container,
4791 "lineLabel", al, ac);
4792 XtManageChild(M_status_lineLabel(parent));
4793 XtAddCallback(M_status_lineLabel(parent), XmNhelpCallback,
4794 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4795 XmStringFree(tmpStr);
4798 XtSetArg(al[ac], XmNcolumns, 6); ac++;
4799 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4800 XtSetArg(al[ac], XmNbackground, background); ac++;
4801 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4802 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4803 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4804 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4805 XtSetArg( al[ac], XmNleftWidget, M_status_lineLabel(parent) ); ac++;
4806 M_status_lineText(parent) = XmCreateTextField( container, "lineText",
4808 XtManageChild(M_status_lineText(parent));
4809 XtAddCallback(M_status_lineText(parent), XmNactivateCallback,
4810 (XtCallbackProc)PositionActivateCB, parent);
4811 XtAddCallback(M_status_lineText(parent), XmNhelpCallback,
4812 (XtCallbackProc)HelpStatusCurrentLineCB, parent);
4815 * Create the total lines labels
4818 if (E_status_totalLineCountLabel(parent) != (XmString)DtUNSPECIFIED)
4821 * Use the resource value & clear it (to save space).
4823 tmpStr = XmStringCopy(E_status_totalLineCountLabel(parent));
4824 E_status_totalLineCountLabel(parent) = (XmString)DtUNSPECIFIED;
4828 * The resource has not been set so use its default value
4830 tmpStr = XmStringCreateLocalized(TOTAL);
4833 XtSetArg(al[ac], XmNlabelString, tmpStr); ac++;
4834 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4835 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4836 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4837 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4838 XtSetArg( al[ac], XmNleftWidget, M_status_lineText(parent) ); ac++;
4839 M_status_totalLabel(parent) = (Widget) XmCreateLabelGadget( container,
4840 "totalLabel", al, ac);
4841 XtManageChild(M_status_totalLabel(parent));
4842 XtAddCallback(M_status_totalLabel(parent), XmNhelpCallback,
4843 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4844 XmStringFree(tmpStr);
4847 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4848 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4849 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4850 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4851 XtSetArg( al[ac], XmNleftWidget, M_status_totalLabel(parent) ); ac++;
4852 M_status_totalText(parent) = (Widget) XmCreateLabelGadget( container,
4853 "totalText", al, ac);
4854 XtManageChild(M_status_totalText(parent));
4855 XtAddCallback(M_status_totalText(parent), XmNhelpCallback,
4856 (XtCallbackProc)HelpStatusTotalLinesCB, parent);
4859 * Create the overstrike indicator
4863 XtSetArg(al[ac], XmNrecomputeSize, False); ac++;
4865 XtSetArg(al[ac], XmNmarginLeft, 0); ac++;
4866 XtSetArg(al[ac], XmNmarginRight, 0); ac++;
4867 XtSetArg(al[ac], XmNmarginWidth, 0); ac++;
4868 XtSetArg( al[ac], XmNrightOffset, 3 ); ac++;
4869 XtSetArg(al[ac], XmNfontList, E_labelFontList(parent) ); ac++;
4870 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4871 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4872 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
4873 M_status_overstrikeWidget(parent) =
4874 (Widget) XmCreateLabelGadget( container, "overstrikeLabel", al, ac);
4875 XtManageChild(M_status_overstrikeWidget(parent));
4876 XtAddCallback(M_status_overstrikeWidget(parent), XmNhelpCallback,
4877 (XtCallbackProc)HelpStatusOverstrikeCB, parent);
4880 * Create the application message area
4883 XtSetArg(al[ac], XmNbackground, parent->core.background_pixel); ac++;
4884 XtSetArg(al[ac], XmNforeground, foreground); ac++;
4885 XtSetArg( al[ac], XmNfontList, E_textFontList(parent)); ac++;
4886 XtSetArg(al[ac], XmNeditable, False); ac++;
4887 XtSetArg(al[ac], XmNcursorPositionVisible, False); ac++;
4888 XtSetArg(al[ac], XmNtraversalOn, False); ac++;
4889 XtSetArg( al[ac], XmNbottomAttachment, XmATTACH_FORM ); ac++;
4890 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
4891 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_WIDGET ); ac++;
4892 XtSetArg( al[ac], XmNleftWidget, M_status_totalText(parent) ); ac++;
4893 XtSetArg( al[ac], XmNleftOffset, 17 ); ac++;
4894 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_WIDGET ); ac++;
4895 XtSetArg(al[ac], XmNrightWidget, M_status_overstrikeWidget(parent)); ac++;
4896 M_status_messageText(parent) =
4897 XmCreateTextField( container, "messageText", al, ac );
4899 XtManageChild(M_status_messageText(parent));
4900 XtAddCallback(M_status_messageText(parent), XmNhelpCallback,
4901 (XtCallbackProc)HelpStatusMessageCB, parent);
4903 return( container );
4905 } /* end CreateStatusLine */
4908 /*********************************************************************
4910 * The following section contains the procedures related to help
4912 *********************************************************************/
4917 DtEditorWidget editor,
4920 DtEditorHelpCallbackStruct help_cb;
4922 help_cb.reason = reason;
4923 help_cb.event = (XEvent *) NULL;
4924 XtCallCallbackList( (Widget)editor, M_HelpCB(editor),
4925 (XtPointer) &help_cb );
4927 } /* end CallHelpCallback */
4930 * Edit window help callbacks
4937 caddr_t client_data,
4940 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_EDIT_WINDOW);
4944 * Status Line help callbacks
4955 caddr_t client_data,
4958 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_STATUS_LINE);
4963 HelpStatusCurrentLineCB(
4965 caddr_t client_data,
4968 CallHelpCallback( (DtEditorWidget)client_data,
4969 DtEDITOR_HELP_STATUS_CURRENT_LINE );
4974 HelpStatusTotalLinesCB(
4976 caddr_t client_data,
4979 CallHelpCallback( (DtEditorWidget)client_data,
4980 DtEDITOR_HELP_STATUS_TOTAL_LINES );
4985 HelpStatusMessageCB(
4987 caddr_t client_data,
4990 CallHelpCallback( (DtEditorWidget)client_data,
4991 DtEDITOR_HELP_STATUS_MESSAGE );
4996 HelpStatusOverstrikeCB(
4998 caddr_t client_data,
5001 CallHelpCallback( (DtEditorWidget)client_data,
5002 DtEDITOR_HELP_STATUS_OVERSTRIKE );
5006 * Format Settings dialog help callbacks
5013 caddr_t client_data,
5016 CallHelpCallback((DtEditorWidget)client_data, DtEDITOR_HELP_FORMAT_DIALOG);
5021 HelpFormatRightMarginCB(
5023 caddr_t client_data,
5026 CallHelpCallback( (DtEditorWidget)client_data,
5027 DtEDITOR_HELP_FORMAT_RIGHT_MARGIN);
5032 HelpFormatLeftMarginCB(
5034 caddr_t client_data,
5037 CallHelpCallback( (DtEditorWidget)client_data,
5038 DtEDITOR_HELP_FORMAT_LEFT_MARGIN);
5043 HelpFormatJustifyButtonsCB(
5045 caddr_t client_data,
5048 CallHelpCallback( (DtEditorWidget)client_data,
5049 DtEDITOR_HELP_FORMAT_ALIGNMENT);
5053 * Find/Change & Spell dialogs help callbacks
5058 _DtEditorHelpSearchCB(
5060 caddr_t client_data,
5063 DtEditorWidget editor = (DtEditorWidget)client_data;
5065 switch (M_search_dialogMode(editor))
5068 CallHelpCallback( (DtEditorWidget)client_data,
5069 DtEDITOR_HELP_SPELL_DIALOG);
5073 CallHelpCallback( (DtEditorWidget)client_data,
5074 DtEDITOR_HELP_CHANGE_DIALOG);
5077 } /* _DtEditorHelpSearchCB */
5081 _DtEditorHelpSearchFindCB(
5083 caddr_t client_data,
5086 CallHelpCallback( (DtEditorWidget)client_data,
5087 DtEDITOR_HELP_CHANGE_FIND);
5091 _DtEditorHelpSearchChangeCB(
5093 caddr_t client_data,
5096 DtEditorWidget editor = (DtEditorWidget)client_data;
5098 switch (M_search_dialogMode(editor))
5101 CallHelpCallback( (DtEditorWidget)client_data,
5102 DtEDITOR_HELP_SPELL_CHANGE);
5106 CallHelpCallback( (DtEditorWidget)client_data,
5107 DtEDITOR_HELP_CHANGE_CHANGE);
5110 } /* _DtEditorHelpSearchChangeCB */
5114 _DtEditorHelpSearchSpellCB(
5116 caddr_t client_data,
5119 CallHelpCallback( (DtEditorWidget)client_data,
5120 DtEDITOR_HELP_SPELL_MISSPELLED_WORDS);
5123 /*********************************************************************
5125 * The following section contains the procedures related to formating
5126 * text and the Format Settings dialog.
5128 *********************************************************************/
5131 * Do simple formatting of paragraphs of text.
5132 * Designed for speed, at some cost in complexity and redundancy.
5134 * There is a minor undocumented bug in Dump(). It calls Justify() in the
5135 * case where the last word of the last line of a paragraph is an end-of-
5136 * sentence word (typical) and ends just one blank before the margin
5137 * (rare). This results in one blank being inserted in the line when it's
5138 * not necessary. It happens because the two trailing blanks after the
5139 * word cause an "ordinary" line dump before Fill() sees the next line and
5140 * knows it has an end of paragraph. WARNING: The situation would be
5141 * aggravated if FillWord() ever set blanks to an even larger number.
5145 ** This section contains changes for EUC_4B compatibility.
5146 ** WPI interface is used.
5149 /* Global Variables and extern declarations */
5151 typedef struct _WORD{ /* describe one word */
5152 wint_t *cp; /* word location in buffer */
5153 int inlinenum; /* word start line in input */
5154 int incolumn; /* word start column in input */
5155 int length; /* size of word */
5156 int score; /* word + next for jflag */
5157 int blanks; /* output trailing blanks need */
5158 int wclen; /* Length of wide character word */
5166 /* FORMATTING CONTROL */
5170 int tabsize; /* tab size in use */
5171 int centerstartpara; /* expect para. start? in "Center" */
5173 /* Global/static vars used in "Fill" */
5174 wint_t *wordbuf; /* see comments for "Fill" for discussion */
5191 int indent1, indent2;
5194 #define isekinsoku(wc) iswctype((wc),ekinclass)
5195 #define isbekinsoku(wc) iswctype((wc),bekinclass)
5197 #define LINESIZE BUFSIZ /* how big a line can be */
5198 #define WORDMAX LINESIZE /* see above for discussion */
5200 #define WORDNEXT(d,at) { if (++at == d->wordlimit) at = d->wordbase; } /* statement */
5201 #define WORDPREV(d,at) (((at == d->wordbase) ? d->wordlimit : at) - 1) /* function */
5204 extern int _nl_space_alt;
5208 * Forward declarations
5210 static int DoLine (FormatData *data, register FILE *filep);
5211 static void Center (FormatData *data,
5212 wint_t *in_line, register wint_t *inlinelim);
5213 static void Fill (FormatData *data, wint_t *in_line, register wint_t *inlinelim);
5214 static void FillWord (FormatData *data);
5215 static void Dump (FormatData *data, int endpara);
5216 static void PrintIndent (FormatData *data, int indent);
5217 static void PrintTag (FormatData *data, WORD *wordpast);
5218 static void PrintWords (FormatData *data, WORD *wordpast);
5219 static void Justify (FormatData *data, register int blanks, WORD *wordpast);
5220 static int CompareWords (const void *, const void *);
5221 static int EkinBekinProc(FormatData *data, WORD **wordpast);
5222 static void postEkinBekinProc(FormatData *data, int *poutchars, WORD *wordpast);
5226 * A small workaround for systems that don't have wcwidth...
5233 char mbstr[MB_LEN_MAX + 1];
5235 status = wctomb(mbstr, wc);
5238 return(euccol(mbstr));
5245 * The following utilities: lineBlank, findNonBlank, and countBlanks all
5246 * require the lineLen parameter to specify the number of characters, not
5247 * bytes, in the line.
5255 int byteNum, charNum;
5257 size_t mbCurMax = MB_CUR_MAX;
5259 for(byteNum = charNum = 0; charNum < lineLen;
5260 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5262 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5263 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5264 if( !iswctype(wc, _DtEditor_blankClass) )
5269 #endif /* not sun */
5279 int byteNum, charNum;
5281 size_t mbCurMax = MB_CUR_MAX;
5283 for(byteNum = charNum = 0; charNum < lineLen;
5284 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5286 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5287 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5288 if( !iswctype(wc, _DtEditor_blankClass) )
5289 return &pLine[byteNum];
5292 return &pLine[byteNum];
5293 #endif /* not sun */
5295 return &pLine[byteNum];
5303 int byteNum, charNum, count;
5305 size_t mbCurMax = MB_CUR_MAX;
5307 for(byteNum = charNum = 0, count = 0; charNum < lineLen;
5308 byteNum += mblen(&pLine[byteNum], mbCurMax), charNum++)
5310 (void) mbtowc(&wc, &pLine[byteNum], mbCurMax);
5313 if(mblen(&pLine[byteNum], mbCurMax) == 1)
5315 switch((int) pLine[byteNum])
5318 * I don't really know what to do with weird embedded chars.
5319 * This is just a guess. In non-ascii locales this could
5320 * screw up, but I don't know how else to deal with
5321 * weird embedded control characters.
5323 case '\n': /* newline */
5324 case '\f': /* form feed */
5327 case '\t': /* horizontal tab */
5330 case '\b': /* backspace */
5333 case '\r': /* carriage return */
5341 count++; /* multibyte control chars??? */
5344 #if !(defined(sun) && (_XOPEN_VERSION==3)) && !defined(USL) && !defined(__uxp__)
5345 if(!iswctype(wc, _DtEditor_blankClass))
5350 #endif /* not sun */
5358 * fixLeftMarginAndNewlines - writes out a substring from the text widget,
5359 * inserting leading blanks as needed to set the left margin, and adding
5360 * newlines at all "virtual" (i.e. word-wrapped) lines. It assumes that the
5361 * specified substring is an integer number of lines - i.e. the substring
5362 * cannot begin or end in the middle of a line. Non-complying substrings
5363 * are expanded to encompass whole lines.
5366 fixLeftMarginAndNewlines(
5367 DtEditorWidget editor,
5374 Widget widget = M_text(editor);
5375 register XmTextLineTable lineTable;
5377 int lineIndex, lineLen, nextLen, lineIndent, lastIndex,
5378 lineByteLen, total_lines;
5379 Boolean newPara = True;
5380 char *pLine, *pNext, *pFirstNonBlank, *pLastChar;
5381 size_t mbCurMax = MB_CUR_MAX;
5383 lineTable = _XmTextGetLineTable(widget, &total_lines);
5385 if (leftMargin > rightMargin || leftMargin < 0)
5388 lineIndent = leftMargin;
5391 * calculate the starting line number and ending line number
5392 * for the [sub]string we're operating upon.
5394 lineIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), startPos);
5396 lastIndex = _DtEditorGetLineIndex((XmTextWidget)M_text(editor), endPos);
5399 * This loop terminates with one line unwritten. This is correct
5400 * if we're not formatting the last line of the file, as that means
5401 * that we must be formatting a paragraph, and the paragraph adjust
5402 * code has trouble locating the end of a paragraph (as opposed to the
5403 * beginning of the next paragraph. If the last line of the text is
5404 * to be formatted, it is handled after this loop terminates.
5406 for(; lineIndex < lastIndex; lineIndex++)
5409 * if the current line was word-wrapped, put out a nl.
5411 if(lineTable[lineIndex].virt_line)
5412 fwrite("\n", sizeof(char), 1, fp);
5414 lineLen = lineTable[lineIndex + 1].start_pos -
5415 lineTable[lineIndex].start_pos;
5416 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5417 lineTable[lineIndex].start_pos,
5418 lineTable[lineIndex + 1].start_pos, False);
5419 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5420 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5422 if(lineBlank(pLine, lineLen))
5425 * Blank lines indicate the start of a new paragraph.
5426 * They also don't require any indent adjustment so are
5427 * quick/easy to write out.
5429 fwrite( pLine, sizeof(char),
5430 _DtEditorGetPointer(pLine, lineLen) - pLine, fp );
5439 * Calc the proper indent for the first line, and
5440 * the indent for the rest of the lines
5441 * in the paragraph. If there's only one line in the
5442 * paragraph, then the proper indent is adjustStuff.left_margin.
5446 * Get the next line.
5448 if((total_lines - lineIndex) > 2)
5449 nextLen = lineTable[lineIndex + 2].start_pos -
5450 lineTable[lineIndex + 1].start_pos;
5452 nextLen = XmTextGetLastPosition(widget) -
5453 lineTable[lineIndex + 1].start_pos;
5454 pNext = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5455 lineTable[lineIndex + 1].start_pos,
5456 lineTable[lineIndex + 1].start_pos + nextLen, False);
5458 if(lineBlank(pNext, nextLen)) /* single line paragraph */
5459 firstIndent = lineIndent = leftMargin;
5462 int curFirstIndent, curSecondIndent, offset;
5464 curFirstIndent = countBlanks(pLine, lineLen);
5465 curSecondIndent = countBlanks(pNext, nextLen);
5467 offset = curFirstIndent - curSecondIndent;
5470 /* second line is closer to the left margin */
5473 * Note, the first line will still be indented even
5474 * if the remaining words in the paragraph can
5475 * all fit on the first line. The end result is a
5476 * one line indented paragraph. I am mentioning
5477 * this because some may think this is a defect.
5480 firstIndent = leftMargin + offset;
5481 lineIndent = leftMargin;
5485 firstIndent = leftMargin;
5486 lineIndent = leftMargin - offset;
5489 for(i = firstIndent; i-- > 0;)
5490 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5491 pFirstNonBlank = findNonBlank(pLine, lineLen);
5492 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5493 (pFirstNonBlank - pLine), fp);
5499 for(i = lineIndent; i-- > 0;)
5500 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5501 pFirstNonBlank = findNonBlank(pLine, lineLen);
5502 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5503 (pFirstNonBlank - pLine), fp);
5507 if((total_lines - lineIndex) == 1)
5510 * Now we have to handle the last line.
5512 if(lineTable[lineIndex].virt_line)
5513 fwrite("\n", sizeof(char), 1, fp);
5515 if((total_lines - lineIndex) > 2)
5516 lineLen = lineTable[lineIndex + 1].start_pos -
5517 lineTable[lineIndex].start_pos;
5519 lineLen = XmTextGetLastPosition(widget) -
5520 lineTable[lineIndex].start_pos;
5524 for(i = lineIndent; i-- > 0;)
5525 fwrite(" ", sizeof(char), 1, fp); /* that's a _space_ */
5527 pLine = _XmStringSourceGetString((XmTextWidget)M_text(editor),
5528 lineTable[lineIndex].start_pos,
5529 lineTable[lineIndex].start_pos + lineLen, False);
5530 pLastChar = _DtEditorGetPointer(pLine, lineLen - 1);
5531 lineByteLen = pLastChar - pLine + mblen(pLastChar, mbCurMax);
5532 if(lineBlank(pLine, lineLen))
5534 fwrite(pLine, sizeof(char), lineByteLen, fp);
5538 pFirstNonBlank = findNonBlank(pLine, lineLen);
5539 fwrite(pFirstNonBlank, sizeof(char), lineByteLen -
5540 (pFirstNonBlank - pLine), fp);
5545 XtFree((XtPointer)lineTable);
5549 /************************************************************************
5552 * Initialize, check arguments embedded in AdjRec, open and read files,
5553 * and pass a series of lines to lower-level routines.
5562 long maxmargin; /* max allowed */
5563 register FILE *filep; /* file to read */
5568 * INITIALIZE FOR NLS
5570 mbtowc(&data.Blank," ",1);
5573 * Initialize global/statics.
5575 if((data.wordbuf = malloc(sizeof(wint_t) * LINESIZE * 3)) == (wint_t *)NULL)
5577 if((data.word = malloc(sizeof(WORD) * WORDMAX)) == (WORD *)NULL)
5582 data.tabsize = 8; /* default tab size */
5583 data.centerstartpara = True;
5585 data.fillmargin = data.centermiddle = pAdjRec->margin;
5586 data.m0flag = (data.fillmargin == 0L);
5589 * Initialize global/statics for "Fill".
5591 data.wordcp = data.wordbuf;
5592 data.wordcpwrap = data.wordbuf + (LINESIZE * 2);
5593 data.wordbase = & data.word [0];
5594 data.wordlimit = & data.word [WORDMAX];
5595 data.wordfirst = & data.word [0];
5596 data.wordnext = & data.word [0];
5598 data.outlinenum = 1;
5605 if (pAdjRec->cflag + pAdjRec->jflag + pAdjRec->rflag > 1)
5611 maxmargin = pAdjRec->cflag? (LINESIZE / 2) : LINESIZE;
5612 if ((data.fillmargin < 0L) || (data.fillmargin > maxmargin))
5618 if ((pAdjRec->tabsize > 0) && (pAdjRec->tabsize <= MAXTABSIZE))
5619 data.tabsize = pAdjRec->tabsize;
5622 * OPEN AND READ INPUT FILE:
5625 filep = pAdjRec->infp;
5626 data.pAdj = pAdjRec; /* set (file) global var to passed in rec */
5628 while (DoLine (&data, filep))
5632 * DUMP LAST LINE AND EXIT:
5635 if (! data.pAdj->cflag) /* not centering */
5637 Dump (&data, True); /* force end paragraph */
5643 if(data.wordbuf != (wint_t *)NULL)
5647 if(data.word != (WORD *)NULL)
5656 /************************************************************************
5659 * Read one input line and do generic processing (read chars from input
5660 * to in_line, crunching backspaces). Return True if successful, else
5661 * false at end of input file. This must be done before expanding tabs;
5662 * pass half-processed line to Center() or Fill() for more work.
5664 * Assumes getc() is efficient.
5665 * in_line[] is static so it is only allocated once.
5669 DoLine (FormatData *data,
5670 register FILE *filep) /* open file to read */
5672 wint_t in_line [LINESIZE]; /* after reading in */
5673 register wint_t *incp = in_line; /* place in in_line */
5674 register wint_t *incplim = in_line + LINESIZE; /* limit of in_line */
5678 * READ LINE WITH BACKSPACE CRUNCHING:
5681 while (incp < incplim) /* buffer not full */
5683 c = getwc (filep); /* get and save wide char */
5688 if (incp == in_line) /* nothing read yet */
5691 case L'\0': /* fall through */
5692 case L'\n': /* end of line */
5693 incplim = incp; /* set limit (quit loop) */
5696 case L'\b': /* backspace */
5697 if (incp > in_line) /* not at start */
5698 incp--; /* just back up */
5701 default: /* any other char */
5706 /* now incplim is correctly set to last char + 1 */
5709 * PASS LINE ON FOR MORE WORK:
5712 if (data->pAdj->cflag) Center (data, in_line, incplim);
5713 else Fill (data, in_line, incplim);
5715 return (True); /* maybe more to read */
5720 /************************************************************************
5723 * Center text (starting at in_line, ending before inlinelim). First copy
5724 * chars from in_line to outline skipping nonprintables and expanding tabs.
5725 * For efficiency (at the cost of simplicity), note and skip indentation
5726 * at the same time. Then, print outline with indentation to center it.
5728 * outline[] is static so it is only allocated once; startpara so it is
5729 * used for successive lines.
5733 Center (FormatData *data,
5734 wint_t *in_line, /* start of input line */
5735 register wint_t *inlinelim) /* end of line + 1 */
5737 register wint_t *incp; /* pointer in in_line */
5738 wint_t outline [LINESIZE + MAXTABSIZE]; /* after generic work */
5739 register wint_t *outcp = outline; /* place in outline */
5740 register wint_t *outlinelim = outline + LINESIZE; /* limit of outline*/
5742 int haveword = False; /* hit word in in_line? */
5743 register wint_t ch; /* current working char */
5744 register int needsp; /* spaces need for tab */
5745 register int indent = 0; /* size of indentation */
5746 int textwidth; /* size of text part */
5747 int extwidth = 0; /* additional width for MBCS */
5754 for (incp = in_line; (incp < inlinelim) && (outcp < outlinelim); incp++)
5765 needsp = ((ch != L'\t') && (iswblank(ch))) ?
5766 1 : data->tabsize - ((indent + outcp - outline) % data->tabsize);
5768 if (! haveword) /* indentation */
5770 else /* past text */
5771 for ( ; needsp > 0; needsp--)
5772 *outcp++ = data->Blank;
5776 * CARRY OVER PRINTABLE CHARS AND NOTE INDENTATION:
5779 else if (iswprint (ch)) /* note: ch != ' ' */
5781 *outcp++ = ch; /* just copy it over */
5783 if(MB_CUR_MAX > 1 && wcwidth(ch) > 1)
5784 extwidth += wcwidth(ch) - 1;
5787 /* else do nothing, which tosses other chars */
5791 /* Now outcp is the new outlinelim */
5794 * HANDLE BLANK LINE (no text):
5799 putc ('\n', data->pAdj->outfp); /* "eat" any whitespace */
5800 data->centerstartpara = True; /* expect new paragraph */
5804 * EAT TRAILING BLANKS, SET TEXTWIDTH:
5809 /* note that outcp > outline */
5810 while ((outcp[-1] != L'\t') && iswblank(outcp [-1]))
5813 textwidth = (outcp - outline); /* thus textwidth > 0 */
5816 * SET AUTOMARGIN AND PRINT CENTERED LINE:
5818 * The equations used depend on truncating division:
5821 * Margin Middle Width Results
5822 * odd exact odd exact centering
5823 * odd exact even extra char to right
5824 * even left odd extra char to left
5825 * even left even exact centering (due to "extra" char to right)
5827 * When centermiddle is default or given by user, it is the same as the
5828 * first two lines above (middle exactly specified).
5831 if (data->centerstartpara) /* start of paragraph */
5833 data->centerstartpara = False;
5835 if (data->m0flag) /* set automargin */
5836 /* 1 */ data->centermiddle = (indent + textwidth + extwidth + 1) / 2;
5839 /* 2 */ PrintIndent (data, data->centermiddle - ((textwidth + extwidth + 1) / 2));
5842 for(i = 0; i < textwidth; i++)
5844 putwc(outline[i], data->pAdj->outfp);
5846 putc('\n', data->pAdj->outfp);
5854 /************************************************************************
5855 * WORD DATA STRUCTURES USED TO TRACK WORDS WHILE FILLING:
5857 * This complicated scheme is used to minimize the actual data moving
5858 * and manipulation needed to do the job.
5860 * Words are kept in wordbuf[] without trailing nulls. It is large enough
5861 * to accomodate two lines' worth of words plus wrap around to start a new
5862 * word (which might be as big as a line) without overwriting old words
5863 * not yet dumped. wordcp -> next free location in wordbuf[];
5864 * wordcpwrap -> last place a new word is allowed to start.
5866 * Words are pointed to and described by word[] structures. The array is
5867 * big enough to accomodate two lines' worth of words, assuming each word
5868 * takes at least two characters (including separator). wordbase and
5869 * wordlimit are the bounds of the array. wordfirst remembers the first
5870 * word in the array not yet printed. wordat is the word being worked on
5871 * after wordnext is advanced (and maybe wrapped around). New elements
5872 * are "allocated" using wordnext, a pointer that is wrapped around as
5875 * inlinenum and incolumn track the current input line and column per
5876 * paragraph. outlinenum tracks the next line to print. All are base 1,
5877 * but inlinenum is preset to zero at the start of each paragraph.
5879 * pendchars tracks the number of dumpable characters accrued so far, to
5880 * trigger dumping. indent1 and indent2 remember the indentations seen
5881 * for the first two lines of each paragraph.
5884 /************************************************************************
5887 * Parse an input line (in_line to inlinelim) into words and trigger
5888 * FillWord() as needed to finish each word, which in turn can call
5889 * Dump() to dump output lines. This routine sacrifices simplicity and
5890 * clarity for efficiency. It uses shared global word data except
5891 * outlinenum and pendchars.
5895 Fill (FormatData *data,
5896 wint_t *in_line, /* start of input line */
5897 register wint_t *inlinelim) /* end of line + 1 */
5899 register wint_t *incp; /* place in in_line */
5900 register wint_t ch; /* current working char */
5901 int haveword = False; /* hit word in in_line? */
5902 register int inword = False; /* currently in a word? */
5908 data->incolumn = 1; /* starting a line */
5910 for (incp = in_line; incp < inlinelim; incp++)
5915 * AT WHITE SPACE; FINISH PREVIOUS WORD if any, then skip white space:
5920 if (inword) /* was skipping a word */
5926 data->incolumn += ((ch != L'\t') && (iswblank(ch))) ?
5927 1 : data->tabsize - ((data->incolumn - 1) % data->tabsize);
5931 * AT PART OF WORD; START NEW ONE IF NEEDED:
5934 else if (iswprint (ch))
5936 if (! inword) /* start new word */
5940 if (data->wordcp > data->wordcpwrap)/* past wrap point */
5941 data->wordcp = data->wordbuf;/* wraparound buffer */
5943 data->wordat = data->wordnext;
5944 WORDNEXT (data,data->wordnext);
5946 data->wordat->cp = data->wordcp; /* note start of word */
5947 data->wordat->inlinenum = data->inlinenum; /* note input line */
5948 data->wordat->incolumn = data->incolumn; /* note input column */
5949 data->wordat->wclen = 0;
5955 switch (data->inlinenum)/* note indentations */
5958 data->indent1 = data->incolumn - 1;
5961 data->indent2 = data->incolumn - 1;
5968 * SAVE ONE CHAR OF WORD:
5970 *(data->wordcp++) = ch;
5972 int n = wcwidth(ch);
5975 { /* == 0 for a null char */
5976 data->incolumn += n;
5977 data->wordat->wclen++;
5983 /* else skip other chars by doing nothing */
5988 * END OF LINE; HANDLE BLANK LINE, OR FINISH WORD AND AUTOMARGIN:
5991 if (! haveword) /* no text on line */
5993 data->inlinenum--; /* don't count empty lines */
5994 Dump (data, True); /* force end paragraph */
5995 fputc ('\n', data->pAdj->outfp); /* put this empty line */
5996 data->inlinenum = 0; /* start new paragraph */
5998 else /* have text on line */
6000 if (inword) /* line ends in word */
6002 if (data->pendchars > data->fillmargin)
6003 { /* time to dump line */
6004 Dump (data, False); /* not end of paragraph */
6007 if (data->m0flag && (data->inlinenum == 1)) /* need to note right margin */
6008 data->fillmargin = data->wordat->incolumn + data->wordat->length - 1;
6013 /************************************************************************
6016 * Save values for the word just finished and dump the output line if
6017 * needed. Uses shared global word values, but does not touch outlinenum,
6018 * and only increments pendchars.
6020 * Trailing blanks (1 or 2) needed after a word are figured here.
6021 * wordlen is the total length (nonzero) and wordcp points to the char
6022 * past the end of the word. Two blanks are needed after words ending in:
6024 * <terminal>[<quote>][<close>]
6026 * where <terminal> is any of . : ? !
6027 * <quote> is any of ' "
6028 * <close> is any of ) ] }
6030 * For efficiency, this routine avoids calling others to do character
6031 * matching; it does them in line.
6035 FillWord (FormatData *data)
6037 int wordlen; /* length of word to fill */
6038 int blanks = 1; /* trailing blanks needed */
6039 register wint_t ch1, ch2, ch3; /* last chars of word */
6041 data->wordat->length = (data->incolumn - data->wordat->incolumn);
6042 wordlen = data->wordat->wclen;
6045 * CHECK FOR SPECIAL END OF WORD:
6048 ch3 = data->wordcp [-1];
6050 if ((ch3 == L'.') || (ch3 == L':') || (ch3 == L'?') || (ch3 ==L'!'))
6052 blanks = 2; /* <terminal> */
6055 else if (wordlen >= 2)
6057 ch2 = data->wordcp [-2];
6059 if( ((ch2 == L'.') || (ch2 == L':') || (ch2 ==L'?') || (ch2 == L'!')) &&
6060 ((ch3 == L'\'') || (ch3 == L'"') || (ch3 ==L')') || (ch3 == L']')
6064 blanks = 2; /* <terminal><quote or close> */
6066 else if (wordlen >= 3)
6068 ch1 = data->wordcp [-3];
6070 if( ((ch1 == L'.') || (ch1 == L':') || (ch1 == L'?') || (ch1 == L'!'))
6071 && ((ch2 == L'\'') || (ch2 == L'"'))
6072 && ((ch3 == L')') || (ch3 == L']') || (ch3 == L'}')) )
6074 blanks = 2; /* <terminal><quote><close> */
6084 data->pendchars += wordlen + (data->wordat->blanks = blanks);
6089 /************************************************************************
6092 * Print output line(s), with all necessary indentation and formatting,
6093 * if required (at end of paragraph) or if permissible. If required,
6094 * indent1 is used if indent2 is not set yet (not on second line of
6095 * input). Otherwise, if not at end of paragraph, dumping is only
6096 * permissible after beginning the second input line, so fillmargin and
6097 * indent2 are known, so tagged paragraphs are done right.
6099 * Whenever dumping, all "full" lines are dumped, which means more than
6100 * just one may be printed per call. jflag or rflag formatting is
6101 * applied to all lines, except that jflag is ignored for the last line
6102 * of each paragraph.
6104 * Uses shared global word data, but does not touch inlinenum, incolumn,
6105 * indent1, or indent2.
6109 Dump (FormatData *data,
6110 int endpara) /* end of paragraph? */
6112 int haveindent2 = (data->inlinenum >= 2); /* indent2 known? */
6113 int startpara; /* start of paragraph? */
6114 int normal; /* non-tagged line? */
6115 WORD *wordpast = data->wordfirst; /* past last to dump */
6116 register int wordlen; /* length of one word */
6117 int indent; /* local value */
6118 register int outneed; /* chars need to dump */
6119 int outchars; /* chars found to dump */
6122 * IF DUMPING NEEDED, DUMP LINES TILL DONE:
6125 if (! (endpara || haveindent2)) /* not time to dump */
6128 while ( (data->pendchars > data->fillmargin) /* line is full */
6129 || (endpara && (data->wordfirst != data->wordnext)) ) /* more to dump */
6131 startpara = (data->outlinenum < 2);
6132 indent = (startpara || (! haveindent2)) ? data->indent1 : data->indent2;
6135 * CHECK FOR TAGGED PARAGRAPH if needed:
6138 normal = True; /* default == no tag */
6140 if (startpara && haveindent2 && (data->indent1 < data->indent2))
6142 int incol2 = data->indent2 + 1; /* column needed */
6144 while ( (wordpast != data->wordnext) /* more words */
6145 && (wordpast->inlinenum == 1)) /* from line 1 */
6147 if (wordpast->incolumn == incol2) /* bingo */
6152 WORDNEXT (data,wordpast);
6156 wordpast = data->wordfirst; /* reset value */
6159 * PRINT TAG PART OF TAGGED PARAGRAPH:
6164 WORD *wordat = data->wordfirst; /* local value */
6166 while (wordat != wordpast) /* decrement pendchars */
6168 data->pendchars -= wordat->length + wordat->blanks;
6169 WORDNEXT (data,wordat);
6172 PrintIndent (data, indent);
6173 PrintTag (data, wordpast); /* preceding words */
6174 data->wordfirst = wordpast; /* do rest of line */
6175 indent = data->indent2; /* as if second line */
6180 * FIND WORDS WHICH FIT ON [REST OF] LINE:
6183 if (indent >= data->fillmargin) /* don't over indent */
6184 indent = data->fillmargin - 1;
6186 outneed = data->fillmargin - indent; /* always greater than zero */
6188 wordlen = wordpast->length;
6190 do { /* always consume one */
6191 outchars += wordlen + wordpast->blanks;
6192 WORDNEXT (data,wordpast);
6193 } while ( (wordpast != data->wordnext) /* not last word */
6194 && (outchars + (wordlen = wordpast->length) <= outneed)
6200 ** BEKINSOKU/EKINSOKU PROCESSING
6202 if( EkinBekinProc(data, &wordpast) )
6203 postEkinBekinProc(data, &outchars,wordpast);
6204 data->pendchars -= outchars; /* pendchars to consume */
6206 /* from now on, don't include trailing blanks on last word */
6207 outchars -= (WORDPREV (data,wordpast) -> blanks);
6209 /* now wordfirst and wordpast specify the words to dump */
6211 * PRINT INDENTATION AND PREPARE JUSTIFICATION:
6214 if (data->pAdj->rflag) /* right-justify only */
6216 if (normal) /* nothing printed yet */
6217 PrintIndent (data, data->fillmargin - outchars);
6218 else /* indent + tag printed */
6220 int blanks = data->fillmargin - outchars - indent;
6222 while (blanks-- > 0) /* can't use PrintIndent()*/
6223 putwc(data->Blank, data->pAdj->outfp);
6228 if (normal) /* not already done */
6229 PrintIndent (data, indent);
6231 if (data->pAdj->jflag && ! (endpara && (wordpast == data->wordnext)))
6232 Justify (data, outneed - outchars, wordpast);
6236 * PRINT REST OF LINE:
6239 PrintWords (data, wordpast);
6240 putwc('\n', data->pAdj->outfp);
6241 data->wordfirst = wordpast;
6242 data->outlinenum++; /* affects startpara */
6247 data->outlinenum = 1;
6252 /************************************************************************
6253 * P R I N T I N D E N T
6255 * Print line indentation (if > 0), optionally using tabs where possible.
6256 * Does not print a newline.
6260 PrintIndent (FormatData *data,
6261 int indent) /* leading indentation */
6263 if (indent > 0) /* indentation needed */
6265 if (! data->pAdj->bflag) /* unexpand leading blanks */
6267 while (indent >= data->tabsize)
6269 putc ('\t', data->pAdj->outfp);
6270 indent -= data->tabsize;
6273 fprintf (data->pAdj->outfp, "%*s", indent, "");/*[remaining] blanks */
6278 /************************************************************************
6281 * Print paragraph tag words from word[] array beginning with (global)
6282 * wordfirst and ending before (parameter) wordpast, using input column
6283 * positions in each word's data. Assumes indentation of indent1 was
6284 * already printed on the line. Assumes *wordpast is the next word on
6285 * the line and its column position is valid, and appends spaces up to
6286 * the start of that word. Doesn't print a newline.
6288 * Line indentation must already be done, as this routine doesn't know
6289 * how to print leading tabs, only blanks.
6293 PrintTag (FormatData *data,
6294 WORD *wordpast) /* past last to print */
6296 register WORD *wordat = data->wordfirst; /* local value */
6297 register int outcol = data->indent1 + 1; /* next column */
6298 int wordcol; /* desired column */
6299 register wint_t *wordcp; /* place in word */
6300 wint_t *wordcplim; /* limit of word */
6302 while (True) /* till break */
6304 wordcol = wordat->incolumn;
6306 while (outcol < wordcol)/* space over to word */
6308 putwc(data->Blank, data->pAdj->outfp);
6312 if (wordat == wordpast) /* past last word */
6313 break; /* quit the loop */
6315 wordcp = wordat->cp;
6317 wordcplim = wordcp + wordat->wclen;
6319 while (wordcp < wordcplim) /* print word */
6320 putwc(*wordcp++, data->pAdj->outfp);
6322 outcol += wordat->length;
6323 WORDNEXT (data,wordat);
6328 /************************************************************************
6329 * P R I N T W O R D S
6331 * Print words from word[] array beginning with (global) wordfirst and
6332 * ending before (parameter) wordpast, using word sizes and trailing
6333 * blanks (except for last word on line). Doesn't print a newline.
6337 PrintWords (FormatData *data,
6338 WORD *wordpast) /* past last to print */
6340 register WORD *wordat = data->wordfirst; /* local value */
6341 register wint_t *wordcp; /* place in word */
6342 wint_t *wordcplim; /* limit of word */
6343 register int blanks; /* after a word */
6345 while (True) /* till break */
6347 wordcp = wordat->cp;
6348 wordcplim = wordcp + wordat->wclen;
6349 blanks = wordat->blanks; /* set before do WORDNEXT() */
6351 while (wordcp < wordcplim) /* print word */
6353 putwc(*wordcp++, data->pAdj->outfp);
6357 WORDNEXT (data,wordat);
6359 if (wordat == wordpast) /* just did last word */
6362 while (blanks-- > 0) /* print trailing blanks */
6363 putwc(data->Blank, data->pAdj->outfp);
6369 /************************************************************************
6372 * Do left/right justification of [part of] a line in the word[] array
6373 * beginning with (global) wordfirst and ending before (parameter)
6374 * wordpast, by figuring where to insert blanks.
6376 * Gives each word (except the last on the line) a score based on its
6377 * size plus the size of the next word. Quicksorts word indices into
6378 * order of current trailing blanks (least first), then score (most
6379 * first). Cycles through this list adding trailing blanks to word[]
6380 * entries such that words will space out nicely when printed.
6384 Justify (FormatData *data,
6385 register int blanks, /* blanks to insert */
6386 WORD *wordpast) /* past last to print */
6388 register WORD *wordat; /* local value */
6389 register int sortat; /* place in sort[] */
6390 register int wordlen; /* size of this word */
6391 register int nextlen; /* size of next word */
6392 int level; /* current blanks level */
6394 WORD *sort [WORDMAX]; /* sorted pointers */
6395 int words; /* words in sort[] */
6397 wordat = WORDPREV (data,wordpast); /* last word on line */
6399 if ((blanks < 1) || (wordat == data->wordfirst))
6400 return; /* can't do anything */
6403 * COMPUTE SCORES FOR WORDS AND SORT INDICES:
6405 * March backwards through the words on line, starting with next to last.
6409 nextlen = wordat->length; /* length of last word */
6411 do { /* always at least one */
6412 wordat = WORDPREV (data,wordat);
6413 wordlen = wordat->length;
6414 wordat->score = wordlen + nextlen; /* this plus next */
6416 sort [words++] = wordat; /* prepare for sorting */
6417 } while (wordat != data->wordfirst);
6419 qsort ((wint_t *) sort, words, sizeof (WORD *), CompareWords);
6422 * ADD TRAILING BLANKS TO PAD OUT WORDS:
6424 * Each pass through the sorted list adds one trailing blank to each word
6425 * not already past the current level. Thus all one-blank words are brought
6426 * up to two; then all twos up to three; etc.
6431 while (True) /* till return */
6435 for (sortat = 0; sortat < words; sortat++)
6437 wordat = sort [sortat];
6438 if (wordat->blanks > level) /* end of this level */
6439 break; /* start next level */
6442 if (--blanks <= 0) /* no more needed */
6450 /************************************************************************
6451 * C O M P A R E W O R D S
6453 * Compare two word[] entries based on pointers to (WORD *), as called
6454 * from qsort(3). Tell which entry has priority for receiving inserted
6455 * blanks (least trailing blanks first, then highest scores), by returning
6456 * -1 for the first entry, +1 for second entry, or 0 if no difference.
6457 * (-1 literally means first entry < second entry, so it sorts first.)
6461 CompareWords (const void *p1, const void *p2)
6463 WORD *word1 = *((WORD **)p1); /* (WORD *) pointers */
6464 WORD *word2 = *((WORD **)p2);
6465 int blanks1 = word1->blanks; /* trailing blanks */
6466 int blanks2 = word2->blanks;
6468 if (blanks1 == blanks2) /* commonest case */
6470 int score1 = word1->score; /* word scores */
6471 int score2 = word2->score;
6473 if (score1 > score2) return (-1); /* word1 has priority */
6474 else if (score1 < score2) return ( 1);
6477 else if (blanks1 < blanks2) return (-1); /* word1 has priority */
6480 } /* CompareWords */
6484 ** BKINSOKU and EKINSOKU processing for Japanese text
6486 ** The function scans the wordlist that are ready for printing
6487 ** and updates the "wordpast" pointer based on the rules of
6488 ** BKINSOKU and EKINSOKU characters.
6490 ** The code does not split a line just after a "gyomatu kinsoku"
6491 ** character and just before a "gyoto kinsoku" character.
6492 ** "Gyomatsu kinsoku" (e-kinsoku) are characters which cannot be
6493 ** placed at the end of a line. "Gyoto kinsoku" (b-kinsoku) are
6494 ** characters which can not be placed at the top of a line.
6496 ** Global variables used:
6497 ** wordfirst - beginning the word list (buffer of pending lines)
6498 ** wordnext - next available spot in the pending buffer (i.e.
6499 ** end of the buffer).
6501 ** Global variables modified:
6505 ** 0 - No Post processing is required.
6506 ** 1 - Post processing is required
6509 #if !(defined(sun) && (_XOPEN_VERSION==3))
6511 EkinBekinProc(FormatData *data,
6514 WORD *curword,*compword,*prevword;
6515 int ekinflag = False, margin;
6518 * curword points to the last word of the first line.
6519 * compword points to the first word of the next line or to the next
6520 * available spot if there is no next line.
6522 compword = *wordpast;
6523 curword = WORDPREV(data,compword);
6526 * If the length of the current word is > fillmargin
6527 * or it is the only word then return.
6529 if (curword->length > data->fillmargin || (curword == data->wordfirst))
6533 * EKINSOKU processing
6534 * If this character set supports ekinclass (can't end a line) char,
6535 * start at the end of the line and search back until
6536 * 1) we find a non-ekinsoku character, or
6537 * 2) come to the beginning of the pending buffer.
6541 while (isekinsoku(*(curword->cp+curword->wclen-1)))
6544 if (curword == data->wordfirst) /* Boundary Condition */
6546 curword = WORDPREV(data,curword);
6550 * Post EKIN processing (i.e. we found an ekinsoku character in
6551 * the line before finding an non-ekinsoku).
6555 if (curword != data->wordfirst) {
6557 * We found a non-ekinsoku after we found the ekinsoku.
6558 * Move the end of line to just after the non-ekinsoku.
6560 WORDNEXT(data,curword);
6561 *wordpast = curword;
6564 else { /* Boundary condition */
6566 * Reached the beginning of the buffer without finding a
6567 * non-ekinsoku. If the last word in the line can begin
6568 * a line (i.e. non-bkinsoku) make it the first word of
6571 curword = WORDPREV(data,compword);
6572 if (!isbekinsoku(*curword->cp)) {
6573 *wordpast = curword;
6582 * If we reached this point then:
6583 * 1) the character set does not support ekinclass characters, or
6584 * 2) the last character in the line is non-ekinsoku.
6585 * Now, need to see if we can begin the next line with the first
6586 * character on that line.
6590 * BEKINSOKU processing
6591 * If this character set supports bekinclass (can't begin a line) char,
6592 * search forward from the begining of the next line (curword) to the
6593 * end of the buffer (wordnext) until:
6594 * 1) A non-bekinsoku word is found,
6595 * 2) if the line limit exceeds the set value, or
6596 * 3) we reach the end of the buffer.
6602 * compword points to the first word of the next line.
6605 margin = data->indent2;
6607 while (curword != data->wordnext)
6609 if (!isbekinsoku(*curword->cp))
6611 margin += (curword->length + curword->blanks);
6612 if (margin >= data->fillmargin)
6614 WORDNEXT(data,curword);
6617 if (curword != data->wordnext && curword != compword)
6620 * The first word of the second line is bekinsoku so search
6621 * backwards from end of first line until we are:
6622 * 1) not at the first word of the buffer, and
6623 * 2) not in between either an ekinsoku or bekinsoku character.
6627 * compword points to the first word of the next line.
6628 * curword points to the last word of the first line.
6630 curword = WORDPREV(data,compword);
6631 prevword = WORDPREV(data,curword);
6632 while ( (curword != data->wordfirst) &&
6633 (isbekinsoku(*curword->cp) ||
6634 isekinsoku(*(prevword->cp+prevword->wclen-1)))
6637 margin += curword->length + curword->blanks;
6638 if (margin >= data->fillmargin)
6641 prevword = WORDPREV(data,curword);
6644 if (curword != data->wordfirst) {
6646 * Did not reach the beginning of the buffer so we are between
6647 * two non-ekinsoku & non-bekinsoku characters. Move the end
6648 * of the first line here.
6651 *wordpast = curword;
6661 } /* end EkinBekinProc */
6666 EkinBekinProc(FormatData *data,
6669 WORD *curword,*compword,*prevword,*nextword;
6670 int margin = data->indent2;
6673 * prevword points to the last word of the first line.
6674 * compword & curword point to the first word of the next line or
6675 * to the next available spot in the buffer if there is no next line.
6677 compword = *wordpast;
6679 prevword = WORDPREV(data,curword);
6682 * If the length of the previous word is > fillmargin
6683 * or it is the only word in the line then return.
6684 * wordfirst points to the beginning of the buffer of pending lines.
6686 if (prevword->length > data->fillmargin || (prevword == data->wordfirst))
6690 * Starting at the beginning of the next line, search backwards
6692 * 1) we find two words we can split between lines, or
6693 * 2) we reach the beginning of the buffer.
6695 * If there is no next line start with the last two words of this line
6696 * (wordnext points to the next available space in the buffer (i.e
6697 * the end of the buffer).
6700 if (curword == data->wordnext) {
6702 prevword = WORDPREV(data,curword);
6705 while ( (curword != data->wordfirst) &&
6706 (wdbindf(*(prevword->cp+prevword->wclen-1), *curword->cp, 1) >4)
6710 prevword = WORDPREV(data,curword);
6713 if (curword != data->wordfirst) {
6716 * Did not reach the beginning of the buffer so we are between
6717 * two non-ekinsoku & non-bekinsoku characters. Move the end
6718 * of the first line here.
6721 *wordpast = curword;
6728 * Reached the beginning of the buffer so search forward
6729 * from the beginning of the second line until:
6730 * 1) we find two words we can split between lines,
6731 * 2) we reach the end of the buffer, or
6732 * 3) the line becomes too long.
6734 * If there is no next line then just exit.
6738 * compword points to the first word of the next line or to the
6739 * next available spot in the buffer if there is no next line.
6740 * nextword points to the second word of the next line.
6741 * wordnext points to the next available space in the buffer (i.e
6742 * the end of the buffer)
6745 nextword = compword;
6746 WORDNEXT(data,nextword);
6748 if (curword == data->wordnext)
6751 while (nextword != data->wordnext)
6754 if (wdbindf(*(curword->cp+curword->wclen-1), *nextword->cp, 1) < 5)
6756 margin += (curword->length + curword->blanks);
6757 if (margin >= data->fillmargin)
6760 WORDNEXT(data,nextword);
6763 if (nextword != data->wordnext) {
6766 * Did not reach the end of the buffer so we are between
6767 * two non-ekinsoku & non-bekinsoku characters. Move the end
6768 * of the first line here.
6770 *wordpast = nextword;
6778 } /* end EkinBekinProc */
6780 #endif /* not sun */
6783 postEkinBekinProc(FormatData *data,
6788 int colvalue,curlineno;
6791 * Recompute the value of *poutchars
6796 curword = data->wordfirst;
6797 while (curword != wordpast)
6799 (*poutchars) += curword->length + curword->blanks;
6800 WORDNEXT(data,curword);
6804 ** Adjust the word parameters -
6805 ** inlinenum,incolumn of all the words
6806 ** from 'curword' till 'wordnext'
6810 curlineno = curword->inlinenum+1;
6811 colvalue = data->indent2;
6812 while (curword != data->wordnext)
6814 curword->inlinenum = curlineno;
6815 curword->incolumn = colvalue;
6816 colvalue += curword->length + curword->blanks;
6817 if (colvalue > data->fillmargin)
6819 colvalue = data->indent2;
6822 WORDNEXT(data,curword);
6824 data->incolumn = colvalue;
6825 data->inlinenum = curlineno;
6838 for (i=0; i < pword->wclen; i++)
6839 fprintf(stderr,(const char *)"%c",(char)*(pword->cp+i));
6840 fprintf(stderr,"Word Length :%d\n",pword->wclen);
6849 caddr_t client_data,
6853 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6854 DtEDITOR_FORMAT_PARAGRAPH );
6856 } /* AdjustParaCB */
6862 caddr_t client_data,
6866 DtEditorFormat( (Widget)client_data, (DtEditorFormatSettings *)NULL,
6867 DtEDITOR_FORMAT_ALL );
6874 * DoAdjust - given left & right margin values & an alignment style, formats
6875 * the text from one specified text position to another.
6878 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
6879 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
6881 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
6883 * DtEDITOR_INVALID_TYPE if specified alignment is
6887 static DtEditorErrorCode
6889 DtEditorWidget editor,
6892 unsigned int alignment,
6893 XmTextPosition start,
6896 char tempName1[L_tmpnam], tempName2[L_tmpnam];
6897 DtEditorErrorCode returnVal;
6901 * Check that valid margin values were passed in
6903 if( leftMargin >= 0 &&
6905 rightMargin < 1025 &&
6906 leftMargin <= rightMargin )
6911 _DtTurnOnHourGlass(M_topLevelShell(editor));
6912 if (M_format_dialog(editor) != (Widget)NULL)
6913 _DtTurnOnHourGlass(M_format_dialog(editor));
6915 memset(&adjRec, 0, sizeof(AdjRec));
6917 /* The adjust text formatting code works with a data
6918 representation to the screen of 1 byte per column for
6919 multibyte environment. The Motif text Widget has a data
6920 representation of 2 bytes per column in multibyte, so we must
6921 fool the adjust code into thinking the margins are twice the
6922 size in a multibyte environment.
6927 rightMargin = rightMargin * 2;
6928 leftMargin = leftMargin * 2;
6933 case DtEDITOR_ALIGN_CENTER:
6936 adjRec.margin = (rightMargin + leftMargin) / 2;
6940 case DtEDITOR_ALIGN_JUSTIFY:
6943 adjRec.margin = rightMargin;
6947 case DtEDITOR_ALIGN_RIGHT:
6950 adjRec.margin = rightMargin;
6954 case DtEDITOR_ALIGN_LEFT:
6956 adjRec.margin = rightMargin;
6962 returnVal = DtEDITOR_INVALID_TYPE;
6968 * Turn off converting leading spaces into tabs if we are
6969 * working in a multi-byte locale. This is necessary
6970 * because a tab may not equal (be as wide as) 8 spaces in
6971 * a multi-byte locale.
6976 adjRec.bflag = True;
6978 adjRec.bflag = False;
6982 * Create the two temp files
6984 (void)tmpnam(tempName1);
6985 (void)tmpnam(tempName2);
6986 if ((adjRec.infp = fopen(tempName1, "w+")) != (FILE *)NULL) {
6989 * Successfully opened the first temporary file
6992 if((adjRec.outfp = fopen(tempName2, "w")) != (FILE *)NULL) {
6995 * Successfully opened the second temporary file, so do the
6998 returnVal = DtEDITOR_NO_ERRORS;
7000 fixLeftMarginAndNewlines( editor, adjRec.infp, leftMargin,
7001 rightMargin, (int)start, (int)end );
7002 fflush(adjRec.infp);
7003 rewind(adjRec.infp);
7005 FormatText(&adjRec);
7007 fclose(adjRec.infp);
7010 fclose(adjRec.outfp);
7012 DtEditorReplaceFromFile( (Widget)editor, start, end, tempName2 );
7018 * Could not open second temporary file, so clean up first one
7020 fclose(adjRec.infp);
7022 returnVal = DtEDITOR_NO_TMP_FILE;
7025 } /* end creating temporary files */
7027 returnVal = DtEDITOR_NO_TMP_FILE;
7032 _DtTurnOffHourGlass(M_topLevelShell(editor));
7033 if (M_format_dialog(editor) != (Widget)NULL)
7034 _DtTurnOffHourGlass(M_format_dialog(editor));
7036 } /* end check for valid margins */
7038 returnVal = DtEDITOR_ILLEGAL_SIZE;
7047 caddr_t client_data,
7050 DtEditorWidget editor = (DtEditorWidget )client_data;
7051 XtUnmanageChild (M_format_dialog(editor));
7057 DtEditorWidget editor)
7059 Dimension text_width, highlight_thickness, shadow_thickness,
7062 Arg al[5]; /* arg list */
7063 register int ac; /* arg count */
7066 XtSetArg(al[ac], XmNwidth, &text_width); ac++;
7067 XtSetArg(al[ac], XmNhighlightThickness, &highlight_thickness); ac++;
7068 XtSetArg(al[ac], XmNshadowThickness, &shadow_thickness); ac++;
7069 XtSetArg(al[ac], XmNmarginWidth, &margin_width); ac++;
7070 XtGetValues(M_text(editor), al, ac);
7072 if (M_fontWidth(editor) != 0)
7073 rightMargin = ( (int)text_width -
7074 (2 * ((int)highlight_thickness +
7075 (int)shadow_thickness + (int)margin_width))
7076 ) / M_fontWidth(editor);
7078 rightMargin = (int)text_width -
7079 (2 * ((int)highlight_thickness +
7080 (int)shadow_thickness + (int)margin_width));
7082 return( rightMargin );
7084 } /* end ComputeRightMargin */
7090 XtPointer *client_data,
7091 XConfigureEvent *event )
7094 DtEditorWidget editor = (DtEditorWidget) client_data;
7095 char orgnum[20]; /* original margin size string */
7098 XtSetArg(al[0], XmNwidth, &width);
7099 XtGetValues(M_text(editor), al, 1);
7101 if (width == M_textWidth(editor))
7104 M_textWidth(editor) = width;
7106 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7107 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7110 /************************************************************************
7112 * SetFormatDialogTitle - Change the title for the Format Settings dialog
7114 ************************************************************************/
7117 SetFormatDialogTitle(
7118 DtEditorWidget editor)
7123 * If the Format Settings dialog has been created, change its title
7125 if( M_format_dialog(editor) != (Widget)NULL )
7129 * Prepend the DialogTitle resource, if it has been set
7131 if( E_dialogTitle(editor) != (XmString)NULL ) {
7135 * Add the "functional title" to the DialogTitle
7137 titleStr = XmStringConcat( E_dialogTitle(editor),
7138 E_format_dialogTitle(editor) );
7140 XtSetArg( al[0], XmNdialogTitle, titleStr );
7141 XtSetValues(M_format_dialog(editor), al, 1);
7143 XmStringFree( titleStr );
7147 XtSetArg( al[0], XmNdialogTitle, E_format_dialogTitle(editor) );
7148 XtSetValues(M_format_dialog(editor), al, 1);
7153 } /* end SetFormatDialogTitle */
7155 /************************************************************************
7157 * ResetFormatDialog - Reset margins & alignment of the Format Settings
7160 ************************************************************************/
7164 DtEditorWidget editor)
7166 char orgnum[20]; /* original margin size string */
7169 * Reset the margins to default values
7172 /* Right margin default value */
7173 sprintf( orgnum, "%d", ComputeRightMargin(editor) );
7174 XmTextFieldSetString(M_format_rightMarginField(editor), orgnum);
7176 /* Left margin default value */
7177 sprintf(orgnum, "%d", 0);
7178 XmTextFieldSetString(M_format_leftMarginField(editor), orgnum);
7181 * Reset the alignment style to default value
7183 XmToggleButtonGadgetSetState(M_format_leftJust(editor), True, True);
7185 } /* end ResetFormatDialog */
7188 /************************************************************************
7190 * CreateFormatDialog - Create & initialize the Format Settings dialog
7192 ************************************************************************/
7196 DtEditorWidget editor)
7198 Arg al[15]; /* arg list */
7199 register int ac; /* arg count */
7200 Pixel textBackground, textForeground;
7201 XmString tempString = (XmString)NULL;
7204 * Match the background & foreground colors of the edit window
7205 * Don't use DtNtextBackground/Foreground directly because they
7206 * will be DtUNSPECIFIED.
7209 XtSetArg(al[ac], XmNforeground, &textForeground); ac++;
7210 XtSetArg(al[ac], XmNbackground, &textBackground); ac++;
7211 XtGetValues(M_text(editor), al, ac);
7216 * First, create the dialog's title, prepending the
7217 * DtNdialogTitle resource, if it is set
7219 if( E_dialogTitle(editor) != (XmString)NULL ) {
7222 * Add the "functional title" to the DialogTitle
7224 tempString = XmStringConcat( E_dialogTitle(editor),
7225 E_format_dialogTitle(editor) );
7226 XtSetArg (al[ac], XmNdialogTitle, tempString ); ac++;
7230 XtSetArg(al[ac], XmNdialogTitle, E_format_dialogTitle(editor)); ac++;
7233 XtSetArg (al[ac], XmNautoUnmanage, False); ac++;
7234 XtSetArg (al[ac], XmNmarginWidth, 5); ac++;
7235 XtSetArg (al[ac], XmNmarginHeight, 5); ac++;
7236 XtSetArg (al[ac], XmNshadowThickness, 1); ac++;
7237 XtSetArg (al[ac], XmNshadowType, XmSHADOW_OUT); ac++;
7238 XtSetArg (al[ac], XmNnavigationType, XmTAB_GROUP); ac++;
7239 M_format_dialog(editor) = XmCreateFormDialog(
7240 M_topLevelShell(editor), "ad_dial", al, ac);
7241 if (tempString != (XmString)NULL)
7242 XmStringFree( tempString );
7244 XtAddCallback(M_format_dialog(editor), XmNhelpCallback,
7245 (XtCallbackProc)HelpFormatDialogCB, (XtPointer)editor);
7249 * When creating the fields & buttons use the appropriate label
7250 * resource (e.g. DtNcenterToggleLabel), if it has been set, then
7251 * clear the resource to save space. The field or button widget
7252 * will contain the actual value & it can be gotten from there,
7255 * If the appropriate resource has not been set, use its default
7256 * value from the message catalog.
7260 * create the left margin label and text field
7264 if (E_format_leftMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED) {
7266 * Use the resource value & clear it (to save space).
7268 tempString = XmStringCopy(E_format_leftMarginFieldLabel(editor));
7269 E_format_leftMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7273 * The resource has not been set so use its default value
7275 tempString = XmStringCreateLocalized(LEFT_MARGIN);
7278 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7279 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7280 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7281 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7282 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7283 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7284 M_format_leftLabel(editor) = (Widget) XmCreateLabelGadget (
7285 M_format_dialog(editor), "left_label", al, ac);
7286 XtManageChild (M_format_leftLabel(editor));
7287 XmStringFree (tempString);
7289 XtAddCallback(M_format_leftLabel(editor), XmNhelpCallback,
7290 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7293 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7294 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7295 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7296 XtSetArg (al[ac], XmNleftWidget, M_format_leftLabel(editor)); ac++;
7297 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7298 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7299 XtSetArg (al[ac], XmNrightPosition, 45); ac++;
7300 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7301 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7302 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7303 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7304 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7305 M_format_leftMarginField(editor) = (Widget) XmCreateTextField (
7306 M_format_dialog(editor), "left_text", al, ac);
7307 XtManageChild (M_format_leftMarginField(editor));
7308 XtAddCallback(M_format_leftMarginField(editor), XmNhelpCallback,
7309 (XtCallbackProc)HelpFormatLeftMarginCB, (XtPointer)editor);
7311 * create the right margin label and text field
7314 if (E_format_rightMarginFieldLabel(editor) != (XmString) DtUNSPECIFIED)
7317 * Use the resource value & clear it (to save space).
7319 tempString = XmStringCopy(E_format_rightMarginFieldLabel(editor));
7320 E_format_rightMarginFieldLabel(editor) = (XmString) DtUNSPECIFIED;
7325 * The resource has not been set so use its default value
7327 tempString = XmStringCreateLocalized(RIGHT_MARGIN);
7329 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7330 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7331 XtSetArg (al[ac], XmNleftPosition, 55); ac++;
7332 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7333 XtSetArg (al[ac], XmNtopOffset, 10); ac++;
7334 XtSetArg (al[ac], XmNfontList, E_labelFontList(editor)); ac++;
7335 M_format_rightLabel(editor)= (Widget) XmCreateLabelGadget (
7336 M_format_dialog(editor), "right_label", al, ac);
7337 XtManageChild (M_format_rightLabel(editor));
7338 XmStringFree (tempString);
7339 XtAddCallback(M_format_rightLabel(editor), XmNhelpCallback,
7340 (XtCallbackProc)HelpFormatRightMarginCB,
7343 XtSetArg (al[ac], XmNbackground, textBackground); ac++;
7344 XtSetArg (al[ac], XmNforeground, textForeground); ac++;
7345 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7346 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7347 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
7348 XtSetArg (al[ac], XmNleftWidget, M_format_rightLabel(editor)); ac++;
7349 XtSetArg (al[ac], XmNleftOffset, 3); ac++;
7350 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
7351 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7352 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7353 XtSetArg (al[ac], XmNcolumns, 3); ac++;
7354 XtSetArg (al[ac], XmNfontList, E_textFontList(editor)); ac++;
7355 M_format_rightMarginField(editor) = (Widget) XmCreateTextField (
7356 M_format_dialog(editor),
7357 "right_text", al, ac);
7358 XtManageChild (M_format_rightMarginField(editor));
7359 XtAddCallback(M_format_rightMarginField(editor), XmNhelpCallback,
7360 (XtCallbackProc)HelpFormatRightMarginCB,
7364 * create the radio box for justification choices
7367 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7368 XtSetArg (al[ac], XmNleftOffset, 5); ac++;
7369 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7370 XtSetArg (al[ac], XmNtopWidget, M_format_leftMarginField(editor)); ac++;
7371 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7372 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7373 XtSetArg (al[ac], XmNrightOffset, 5); ac++;
7374 XtSetArg (al[ac], XmNtraversalOn, True); ac++;
7375 M_format_radioBox(editor) = (Widget) XmCreateRadioBox(
7376 M_format_dialog(editor), "radioBox", al, ac);
7377 XtAddCallback(M_format_radioBox(editor), XmNhelpCallback,
7378 (XtCallbackProc)HelpFormatJustifyButtonsCB,
7380 XtManageChild(M_format_radioBox(editor));
7382 /* Create Left Align toggle */
7384 if (E_format_leftAlignToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7386 * Use the resource value & clear it (to save space).
7388 tempString = XmStringCopy(E_format_leftAlignToggleLabel(editor));
7389 E_format_leftAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7393 * The resource has not been set so use its default value
7395 tempString = XmStringCreateLocalized(LEFT_ALIGN);
7397 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7398 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7399 M_format_leftJust(editor) = (Widget) XmCreateToggleButtonGadget(
7400 M_format_radioBox(editor), "left_just", al, ac);
7401 XmStringFree (tempString);
7402 XtManageChild(M_format_leftJust(editor));
7404 /* Create Right Align toggle */
7406 if(E_format_rightAlignToggleLabel(editor) != (XmString)DtUNSPECIFIED) {
7408 * Use the resource value & clear it (to save space).
7410 tempString = XmStringCopy(E_format_rightAlignToggleLabel(editor));
7411 E_format_rightAlignToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7415 * The resource has not been set so use its default value
7417 tempString = XmStringCreateLocalized(RIGHT_ALIGN);
7419 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7420 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7421 M_format_rightJust(editor) = (Widget) XmCreateToggleButtonGadget(
7422 M_format_radioBox(editor), "right_just", al, ac);
7423 XmStringFree (tempString);
7424 XtManageChild(M_format_rightJust(editor));
7426 /* Create Justify toggle */
7428 if (E_format_justifyToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7430 * Use the resource value & clear it (to save space).
7432 tempString = XmStringCopy(E_format_justifyToggleLabel(editor));
7433 E_format_justifyToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7437 * The resource has not been set so use its default value
7439 tempString = XmStringCreateLocalized( JUSTIFY );
7441 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7442 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7443 M_format_bothJust(editor) = (Widget) XmCreateToggleButtonGadget(
7444 M_format_radioBox(editor), "both_just", al, ac);
7445 XmStringFree (tempString);
7446 XtManageChild(M_format_bothJust(editor));
7448 /* Create Center align toggle */
7450 if (E_format_centerToggleLabel(editor) != (XmString) DtUNSPECIFIED) {
7452 * Use the resource value & clear it (to save space).
7454 tempString = XmStringCopy(E_format_centerToggleLabel(editor));
7455 E_format_centerToggleLabel(editor) = (XmString) DtUNSPECIFIED;
7459 * The resource has not been set so use its default value
7461 tempString = XmStringCreateLocalized(CENTER);
7463 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7464 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7465 M_format_center(editor) = (Widget) XmCreateToggleButtonGadget(
7466 M_format_radioBox(editor), "center", al, ac);
7467 XmStringFree(tempString);
7468 XtManageChild(M_format_center(editor));
7470 /* Create a separator between the radio box and buttons */
7473 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
7474 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
7475 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7476 XtSetArg (al[ac], XmNtopWidget, M_format_radioBox(editor)); ac++;
7477 XtSetArg (al[ac], XmNtopOffset, 15); ac++;
7478 M_format_separator(editor) = (Widget) XmCreateSeparatorGadget (
7479 M_format_dialog(editor), "separator", al, ac);
7480 XtManageChild (M_format_separator(editor));
7482 /* Create Format Paragraph button */
7484 if ( E_format_formatParagraphButtonLabel(editor) !=
7485 (XmString) DtUNSPECIFIED ) {
7487 * Use the resource value & clear it (to save space).
7489 tempString = XmStringCopy(E_format_formatParagraphButtonLabel(editor));
7490 E_format_formatParagraphButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7494 * The resource has not been set so use its default value
7496 tempString = XmStringCreateLocalized(PARAGRAPH);
7498 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7499 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7500 XtSetArg (al[ac], XmNleftPosition, 2); ac++;
7501 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7502 XtSetArg (al[ac], XmNrightPosition, 25); ac++;
7503 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7504 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7505 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7506 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7507 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7508 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7509 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7510 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7511 M_format_paragraph(editor) = (Widget) XmCreatePushButtonGadget (
7512 M_format_dialog(editor), "para", al, ac);
7513 XtManageChild (M_format_paragraph(editor));
7514 XmStringFree (tempString);
7515 XtAddCallback (M_format_paragraph(editor), XmNactivateCallback,
7516 (XtCallbackProc) AdjustParaCB, (XtPointer) editor);
7518 /* Create Format All button */
7520 if (E_format_formatAllButtonLabel(editor) != (XmString)DtUNSPECIFIED) {
7522 * Use the resource value & clear it (to save space).
7524 tempString = XmStringCopy(E_format_formatAllButtonLabel(editor));
7525 E_format_formatAllButtonLabel(editor) = (XmString) DtUNSPECIFIED;
7529 * The resource has not been set so use its default value
7531 tempString = XmStringCreateLocalized(ALL);
7533 XtSetArg(al[ac], XmNlabelString, tempString); ac++;
7534 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7535 XtSetArg (al[ac], XmNleftPosition, 27); ac++;
7536 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7537 XtSetArg (al[ac], XmNrightPosition, 49); ac++;
7538 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7539 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7540 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7541 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7542 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7543 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7544 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7545 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7546 M_format_all(editor) = (Widget) XmCreatePushButtonGadget(
7547 M_format_dialog(editor), "all", al, ac);
7548 XtManageChild (M_format_all(editor));
7549 XmStringFree (tempString);
7550 XtAddCallback (M_format_all(editor), XmNactivateCallback,
7551 (XtCallbackProc) AdjustAllCB, (XtPointer) editor);
7553 /* Create Close button */
7554 tempString = XmStringCreateLocalized(CLOSE_BUTTON);
7556 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7557 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7558 XtSetArg (al[ac], XmNleftPosition, 51); ac++;
7559 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7560 XtSetArg (al[ac], XmNrightPosition, 73); ac++;
7561 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7562 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7563 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7564 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7565 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7566 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7567 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7568 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7569 M_format_close(editor) = (Widget) XmCreatePushButtonGadget (
7570 M_format_dialog(editor), "close", al, ac);
7571 XtManageChild (M_format_close(editor));
7572 XmStringFree (tempString);
7573 XtAddCallback (M_format_close(editor), XmNactivateCallback,
7574 (XtCallbackProc) AdjustCloseCB, (XtPointer) editor);
7576 tempString = XmStringCreateLocalized(HELP_BUTTON);
7578 XtSetArg (al[ac], XmNlabelString, tempString); ac++;
7579 XtSetArg (al[ac], XmNleftAttachment, XmATTACH_POSITION); ac++;
7580 XtSetArg (al[ac], XmNleftPosition, 75); ac++;
7581 XtSetArg (al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
7582 XtSetArg (al[ac], XmNrightPosition, 98); ac++;
7583 XtSetArg (al[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
7584 XtSetArg (al[ac], XmNtopWidget, M_format_separator(editor)); ac++;
7585 XtSetArg (al[ac], XmNtopOffset, 5); ac++;
7586 XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
7587 XtSetArg (al[ac], XmNbottomOffset, 5); ac++;
7588 XtSetArg (al[ac], XmNmarginWidth, 4); ac++;
7589 XtSetArg (al[ac], XmNmarginHeight, 4); ac++;
7590 XtSetArg (al[ac], XmNfontList, E_buttonFontList(editor)); ac++;
7591 M_format_help(editor) = (Widget) XmCreatePushButtonGadget(
7592 M_format_dialog(editor), "help", al, ac);
7593 XtManageChild (M_format_help(editor));
7594 XmStringFree (tempString);
7595 XtAddCallback( M_format_help(editor), XmNactivateCallback,
7596 (XtCallbackProc) HelpFormatDialogCB, (XtPointer) editor);
7599 * set the default/activation button.
7601 XtSetArg(al[0], XmNdefaultButton, M_format_close(editor));
7602 XtSetValues(M_format_dialog(editor), al, 1);
7604 XtRealizeWidget (M_format_dialog(editor));
7607 * Initialize the margins & alignment toggles
7609 ResetFormatDialog(editor);
7611 XtSetArg(al[0], XmNwidth, &(M_textWidth(editor)));
7612 XtGetValues(M_text(editor), al, 1);
7614 XtAddEventHandler(M_text(editor), StructureNotifyMask, False,
7615 (XtEventHandler) UpdateAdjust, (XtPointer) editor);
7617 } /* end CreateFormatDialog */
7619 /************************************************************************
7621 * GetAdjustSettings - Read the alignment settings from the Format
7624 ************************************************************************/
7628 DtEditorWidget editor,
7629 DtEditorFormatSettings *formatSettings)
7632 if( M_format_dialog(editor)!= (Widget)NULL ) {
7635 * Read the current alignment settings from the Format Settings
7641 * Get current type of alignment
7643 if (XmToggleButtonGadgetGetState(M_format_leftJust(editor)))
7644 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7645 else if (XmToggleButtonGadgetGetState(M_format_rightJust(editor)))
7646 formatSettings->alignment = DtEDITOR_ALIGN_RIGHT;
7647 else if (XmToggleButtonGadgetGetState(M_format_bothJust(editor)))
7648 formatSettings->alignment = DtEDITOR_ALIGN_JUSTIFY;
7650 formatSettings->alignment = DtEDITOR_ALIGN_CENTER;
7653 * Get current margin settings
7655 num = (char *) XmTextFieldGetString(
7656 (Widget)M_format_rightMarginField(editor) );
7657 formatSettings->rightMargin = atoi(num);
7659 num = (char *) XmTextFieldGetString(
7660 (Widget)M_format_leftMarginField(editor) );
7661 formatSettings->leftMargin = atoi(num);
7668 * The Format Settings dialog box has not been created so use the
7671 formatSettings->leftMargin = 0;
7672 formatSettings->rightMargin = ComputeRightMargin(editor);
7673 formatSettings->alignment = DtEDITOR_ALIGN_LEFT;
7678 /****************************************************************
7682 ****************************************************************/
7686 /*********************************************************
7689 * Create an instance of an editor and return the widget id.
7699 return( XtCreateWidget(name,dtEditorWidgetClass,parent,arglist,argcount) );
7703 DtEditorCheckForUnsavedChanges(
7706 DtEditorWidget editor = (DtEditorWidget) widget;
7708 _DtWidgetToAppContext(widget);
7711 result = M_unreadChanges( editor );
7715 } /* end DtEditorCheckForUnsavedChanges */
7719 DtEditorDeleteSelection(
7722 XmTextPosition first, last;
7723 DtEditorWidget editor = (DtEditorWidget) widget;
7725 _DtWidgetToAppContext(widget);
7729 * Check for a non-null selection
7731 if ( XmTextGetSelectionPosition(M_text(editor), &first, &last) &&
7734 XmTextRemove(M_text(editor));
7742 } /* end DtEditorDeleteSelection */
7746 * DtEditorClearSelection replaces the currently selected text with
7747 * spaces. It requires an event because the underlying text widget
7748 * routines require one to look at the time stamp within.
7751 DtEditorClearSelection(
7754 DtEditorWidget editor = (DtEditorWidget) widget;
7755 char *params=(char *)NULL;
7756 Cardinal num_params = 0;
7758 _DtWidgetToAppContext(widget);
7762 * Create an event with a correct timestamp
7764 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7767 * Call routine to clear primary selection
7769 ClearSelection( widget, &event, ¶ms, &num_params );
7773 } /* end DtEditorClearSelection */
7778 * DtEditorDeselect - Unselects any selected text of an Editor widget
7785 DtEditorWidget editor = (DtEditorWidget) widget;
7786 char *params=(char *)NULL;
7787 Cardinal num_params = 0;
7789 _DtWidgetToAppContext(widget);
7793 * Create an event with a correct timestamp
7795 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7797 DeselectAll( widget, &event, ¶ms, &num_params );
7802 } /* end DtEditorDeselect */
7807 * DtEditorDisableRedisplay - Temporarily prevent visual update of a
7812 DtEditorDisableRedisplay(
7815 DtEditorWidget editor = (DtEditorWidget) widget;
7816 _DtWidgetToAppContext(widget);
7819 XmTextDisableRedisplay( M_text(editor) );
7821 } /* end DtEditorDisableRedisplay */
7825 * DtEditorEnableRedisplay - Force visual update of an Editor widget
7829 DtEditorEnableRedisplay(
7832 DtEditorWidget editor = (DtEditorWidget) widget;
7833 _DtWidgetToAppContext(widget);
7836 XmTextEnableRedisplay( M_text(editor) );
7838 } /* end DtEditorEnableRedisplay */
7844 * Given left & right margin values & an alignment style,
7845 * formats either the current paragraph or the entire document,
7846 * as specified. If margin values & alignment style are not
7847 * provided, DtEditorFormat will use the current values from
7848 * the Format Settings dialog.
7851 * DtEDITOR_NO_ERRORS if the text was formatted successfully.
7852 * DtEDITOR_NO_TMP_FILE if the 2 temporary files cannot be
7854 * DtEDITOR_ILLEGAL_SIZE if the left & right margins don't make
7856 * DtEDITOR_INVALID_RANGE if specified amount to format is
7858 * DtEDITOR_INVALID_TYPE if specified alignment is
7865 DtEditorFormatSettings *formatSettings,
7866 unsigned int amountToFormat )
7869 DtEditorWidget editor = (DtEditorWidget) widget;
7870 DtEditorErrorCode error;
7871 int leftMargin, rightMargin, alignment;
7872 _DtWidgetToAppContext(widget);
7876 * Check to see if we should use the format settings from the
7877 * Format Settings dialog.
7879 if( formatSettings == (DtEditorFormatSettings *) NULL )
7882 DtEditorFormatSettings tmpFormatSettings;
7885 * Get the format settings from the Format Settings dialog
7887 GetAdjustSettings(editor, &tmpFormatSettings);
7890 * Set up the correct format settings
7892 leftMargin = tmpFormatSettings.leftMargin;
7893 rightMargin = tmpFormatSettings.rightMargin;
7894 alignment = tmpFormatSettings.alignment;
7898 leftMargin = formatSettings->leftMargin;
7899 rightMargin = formatSettings->rightMargin;
7900 alignment = formatSettings->alignment;
7904 * Now, do the formatting
7907 switch (amountToFormat)
7909 case DtEDITOR_FORMAT_ALL:
7911 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7912 0, XmTextGetLastPosition(M_text(editor)) );
7916 case DtEDITOR_FORMAT_PARAGRAPH:
7918 XmTextPosition start, end;
7919 char *params=(char *)NULL;
7920 Cardinal num_params = 0;
7923 * Create an event with a correct timestamp
7926 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
7929 * Get the beginning & ending positions of the current paragraph
7931 ForwardPara( widget, &event, ¶ms, &num_params );
7932 end = XmTextGetInsertionPosition(M_text(editor));
7933 if( end != XmTextGetLastPosition(M_text(editor)) ) {
7935 * If we're not at the end, then we need to back up to the
7936 * start of this line, otherwise we'll disturb the first line
7937 * of the following paragraph. If we are at the end, then "end"
7938 * must point to the end of the line, or we'll leave the last
7939 * line along with the formatted text.
7941 BeginningOfLine( widget, &event, ¶ms, &num_params );
7942 end = XmTextGetInsertionPosition(M_text(editor));
7945 BackwardPara( widget, &event, ¶ms, &num_params );
7946 BeginningOfLine( widget, &event, ¶ms, &num_params );
7947 start = XmTextGetInsertionPosition(M_text(editor));
7950 * Pass in beginning & ending positions to adjust the current
7953 error = DoAdjust( editor, leftMargin, rightMargin, alignment,
7959 error = DtEDITOR_INVALID_RANGE;
7967 } /* DtEditorFormat */
7972 * DtEditorGetMessageTextFieldID - Returns the widget ID of the Text
7973 * Field used to display application status messages.
7977 DtEditorGetMessageTextFieldID(
7980 DtEditorWidget editor = (DtEditorWidget) widget;
7982 _DtWidgetToAppContext(widget);
7986 * Create the status line if is does not exist
7988 if( M_status_statusArea(editor) == (Widget) NULL )
7989 M_status_statusArea(editor) = CreateStatusLine( editor );
7991 result = M_status_messageText(editor);
7996 } /* end DtEditorGetMessageTextFieldID */
7999 * DtEditorGoToLine moves the insert cursor to the beginning of the
8000 * line specified by lineNumber. It figures out the text character
8001 * position corresponding to the specified line and sets the text
8002 * widget's insertionPosition to that location. If this new
8003 * insertionPosition is not currently on-screen, then the
8004 * text widget's contents are scrolled to display the new position.
8006 * The cursor can be moved to last line by specifying DtEDITOR_LAST_LINE
8007 * as the line number.
8008 * If lineNumber is less than one, the insert cursor will be placed
8009 * at the beginning of the first line. If it is greater than the total
8010 * number of lines, the cursor will be placed at the last line of text.
8014 void DtEditorGoToLine(
8018 DtEditorWidget editor = (DtEditorWidget)widget;
8020 XmTextLineTable lineTab;
8021 XmTextPosition newPos;
8022 _DtWidgetToAppContext(widget);
8025 tw = (XmTextWidget)M_text(editor);
8026 lineTab = tw->text.line_table;
8029 * Validate the specified line number, check it is in range.
8030 * If we adjust the line number, then update the current line display
8031 * in the status line so it reflects where we are really going. This
8032 * is only a problem if lineNumber is less/greater than the first/last
8033 * line becausee we won't be moving the cursor so the status line will
8036 if (lineNumber > tw->text.total_lines || lineNumber == DtEDITOR_LAST_LINE)
8038 lineNumber = tw->text.total_lines;
8039 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8041 else if(lineNumber < 1)
8044 _DtEditorUpdateLineDisplay( editor, lineNumber, FORCE );
8049 * Move the insertion cursor
8051 newPos = lineTab[lineNumber - 1].start_pos;
8052 XmTextSetInsertionPosition(M_text(editor), newPos);
8055 * Scroll the widget, if necessary
8057 if (newPos < tw->text.top_character || newPos >= tw->text.bottom_position)
8066 XtSetArg(al[ac], XmNheight, &height); ac++;
8067 XtSetArg(al[ac], XmNrows, &rows); ac++;
8068 XtGetValues(M_text(editor), al, ac);
8070 if(XmTextPosToXY(M_text(editor), newPos, &x, &y) == True)
8072 int offset = (y - height/2) * rows;
8073 XmTextScroll(M_text(editor), offset/(int) height);
8078 } /* end DtEditorGoToLine */
8081 * DtEditorGetEditorSizeHints - Set the resize increment, minimum window
8082 * size, and base dimension properties in the supplied XSizeHints
8083 * struct for the editor as a whole.
8085 * NOTE: This routine returns data in the struct pointed to by pHints.
8089 DtEditorGetSizeHints(
8091 XSizeHints *pHints) /* Return */
8093 Arg al[10]; /* arg list */
8094 register int ac; /* arg count */
8095 Dimension FormWidth, FormHeight,
8096 Twidth, Theight, statusHeight,
8097 highlightThickness, shadowThickness,
8098 marginWidth, marginHeight,
8099 textRegionWidth, textRegionHeight;
8101 DtEditorWidget editor = (DtEditorWidget) widget;
8102 _DtWidgetToAppContext(widget);
8106 * Window manager should resize in increments of a character or line.
8108 pHints->width_inc = M_fontWidth(editor);
8109 pHints->height_inc = M_fontHeight(editor);
8112 * Size of the Editor (Form)
8115 FormWidth = editor->core.width + (2 * editor->core.border_width);
8116 FormHeight = editor->core.height + (2 * editor->core.border_width);
8119 * Size of the Edit window (text widget)
8122 XtSetArg(al[ac], XmNwidth, &Twidth); ac++;
8123 XtSetArg(al[ac], XmNheight, &Theight); ac++;
8124 XtSetArg(al[ac], XmNhighlightThickness, &highlightThickness); ac++;
8125 XtSetArg(al[ac], XmNshadowThickness, &shadowThickness); ac++;
8126 XtSetArg(al[ac], XmNmarginWidth, &marginWidth); ac++;
8127 XtSetArg(al[ac], XmNmarginHeight, &marginHeight); ac++;
8128 XtGetValues(M_text(editor), al, ac);
8131 * Calculate the width & height of the area within the text widget
8132 * which can actually display characters.
8134 textRegionWidth = (int)Twidth -
8135 (2 * ((int)highlightThickness +
8136 (int)shadowThickness + (int)marginWidth));
8137 textRegionHeight = (int)Theight -
8138 (2 * ((int)highlightThickness +
8139 (int)shadowThickness + (int)marginHeight));
8142 * Set the base width/height to the size of the area which will not
8143 * display characters.
8145 * The base width/height is used by the window manager in concert
8146 * with the height & width increments to display the current size
8147 * (rows & columns) of edit window (text widget) while resizing the
8150 pHints->base_width = FormWidth - textRegionWidth;
8151 pHints->base_height = FormHeight - textRegionHeight;
8154 * Get the height of the status line, if it is turned on.
8155 * Remember, the border width is not included in the height of the
8156 * status line so add it in to account for the border between the
8157 * edit window (text widget) and the status line.
8160 /* XXX Actually, the statusHeight should already be included in the
8161 * FormHeight, so it should not be necessary to add it in again.
8162 * However, the numbers don't come out right otherwise. Hmmm? */
8164 if( M_status_showStatusLine(editor) == True )
8166 XtSetArg( al[0], XmNheight, &statusHeight );
8167 XtGetValues( M_status_statusArea(editor), al, 1 );
8168 statusHeight = statusHeight + editor->core.border_width;
8174 * What is being returned here is the minimum width & height of the
8175 * editor. Leave room for the scrollbars, shadows, etc., plus one
8178 pHints->min_width = pHints->base_width + pHints->width_inc;
8179 pHints->min_height = pHints->base_width + pHints->height_inc +
8182 pHints->flags = PMinSize | PResizeInc | PBaseSize;
8185 } /* end DtEditorGetSizeHints */
8189 DtEditorInvokeFormatDialog(
8192 DtEditorWidget editor = (DtEditorWidget) widget;
8193 _DtWidgetToAppContext(widget);
8197 * Create the dialog if it is the first time
8199 if (M_format_dialog(editor) == (Widget)NULL)
8200 CreateFormatDialog( editor );
8205 XtUnmanageChild (M_format_dialog(editor));
8206 XtManageChild (M_format_dialog(editor));
8207 XmProcessTraversal(M_format_paragraph(editor), XmTRAVERSE_CURRENT);
8210 } /* DtEditorInvokeFormatDialog */
8217 DtEditorContentRec cr;
8218 DtEditorWidget editor = (DtEditorWidget) widget;
8219 _DtWidgetToAppContext(widget);
8223 * Reset the edit window (includes the Undo context)
8225 cr.type = DtEDITOR_TEXT;
8226 cr.value.string = "";
8227 DtEditorSetContents( widget, &cr );
8230 * Reset the status line
8231 * Note, the current & total line displays are reset by DtEditorSetContents()
8233 if( M_status_statusArea(editor) != (Widget) NULL ) {
8235 XmTextFieldSetString( M_status_messageText(editor), "" );
8240 * Reset the Find/Change & Spell dialogs
8242 if ( M_search_string(editor) )
8243 XtFree(M_search_string(editor));
8244 M_search_string(editor) = (char *)NULL;
8246 if ( M_replace_string(editor) )
8247 XtFree(M_replace_string(editor));
8248 M_replace_string(editor) = (char *)NULL;
8250 if (M_misspelled_string(editor))
8251 XtFree(M_misspelled_string(editor));
8252 M_misspelled_string(editor) = (char *)NULL;
8255 * Reset the Format Settings dialog
8257 if (M_format_dialog(editor) != (Widget)NULL)
8258 ResetFormatDialog(editor);
8261 } /* end DtEditorReset */
8266 * DtEditorSelectAll - Selects the contents of an Editor widget
8273 DtEditorWidget editor = (DtEditorWidget) widget;
8274 char *params=(char *)NULL;
8275 Cardinal num_params = 0;
8277 _DtWidgetToAppContext(widget);
8281 * Create an event with a correct timestamp
8283 event.xkey.time = XtLastTimestampProcessed( M_display(editor) );
8285 SelectAll( widget, &event, ¶ms, &num_params );
8289 } /* end DtEditorSelectAll */
8293 DtEditorTraverseToEditor(
8296 DtEditorWidget editor = (DtEditorWidget) widget;
8297 _DtWidgetToAppContext(widget);
8300 XmProcessTraversal(M_text(editor), XmTRAVERSE_CURRENT);
8303 } /* end DtEditorTraverseToEditor */