3 Copyright 1989, 1994, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
28 * This file is broken up into three sections one dealing with
29 * each of the three popups created here:
31 * FileInsert, Search, and Replace.
33 * There is also a section at the end for utility functions
34 * used by all more than one of these dialogs.
36 * The following functions are the only non-static ones defined
37 * in this module. They are located at the begining of the
38 * section that contains this dialog box that uses them.
40 * void _XawTextInsertFileAction(w, event, params, num_params);
41 * void _XawTextDoSearchAction(w, event, params, num_params);
42 * void _XawTextDoReplaceAction(w, event, params, num_params);
43 * void _XawTextInsertFile(w, event, params, num_params);
51 #include <X11/IntrinsicP.h>
52 #include <X11/StringDefs.h>
53 #include <X11/Shell.h>
55 #include <X11/Xmu/CharSet.h>
56 #include <X11/Xaw/TextP.h>
57 #include <X11/Xaw/AsciiText.h>
58 #include <X11/Xaw/Cardinals.h>
59 #include <X11/Xaw/Command.h>
60 #include <X11/Xaw/Form.h>
61 #include <X11/Xaw/Toggle.h>
64 static char* INSERT_FILE = "Enter Filename:";
65 static char* SEARCH_LABEL_1 = "Use <Tab> to change fields.";
66 static char* SEARCH_LABEL_2 = "Use ^q<Tab> for <Tab>.";
67 static char* DISMISS_NAME = "cancel";
68 #define DISMISS_NAME_LEN 6
69 static char* FORM_NAME = "form";
70 static char* LABEL_NAME = "label";
71 static char* TEXT_NAME = "text";
75 typedef void (*AddFunc)(Widget, char*, Widget);
80 static void _SetField(Widget, Widget);
81 static void AddSearchChildren(Widget, char*, Widget);
82 static void AddInsertFileChildren(Widget, char*, Widget);
83 static void CenterWidgetOnPoint(Widget, XEvent*);
84 static Widget CreateDialog(Widget, String, String, AddFunc);
85 static void DoInsert(Widget, XtPointer, XtPointer);
86 static void DoReplaceAll(Widget, XtPointer, XtPointer);
87 static void DoReplaceOne(Widget, XtPointer, XtPointer);
88 static Bool DoSearch(struct SearchAndReplace*);
89 static Widget GetShell(Widget);
90 static String GetString(Widget);
91 static String GetStringRaw(Widget);
92 static void InitializeSearchWidget(struct SearchAndReplace*,
93 XawTextScanDirection, Bool);
94 static Bool InParams(String, String*, unsigned int);
95 static Bool InsertFileNamed(Widget, char*);
96 static void PopdownFileInsert(Widget, XtPointer, XtPointer);
97 static void PopdownSearch(Widget, XtPointer, XtPointer);
98 static Bool Replace(struct SearchAndReplace*, Bool, Bool);
99 static void SearchButton(Widget, XtPointer, XtPointer);
100 static void SetResource(Widget, char*, XtArgVal);
101 static Bool SetResourceByName(Widget, char*, char*, XtArgVal);
102 static void SetSearchLabels(struct SearchAndReplace*, String, String, Bool);
103 static void SetWMProtocolTranslations(Widget);
108 static void WMProtocols(Widget, XEvent*, String*, Cardinal*);
113 void _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*);
114 void _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*);
115 void _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*);
116 void _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*);
117 void _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*);
118 void _XawTextSearch(Widget, XEvent*, String*, Cardinal*);
119 void _XawTextSetField(Widget, XEvent*, String*, Cardinal*);
124 char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
125 void _XawTextShowPosition(TextWidget);
130 static char radio_trans_string[] =
131 "<Btn1Down>,<Btn1Up>:" "set() notify()\n"
134 static char search_text_trans[] =
135 "~s<Key>Return:" "DoSearchAction(Popdown)\n"
136 "s<Key>Return:" "DoSearchAction() SetField(Replace)\n"
137 "c<Key>c:" "PopdownSearchAction()\n"
138 "<Btn1Down>:" "select-start() SetField(Search)\n"
139 "<Key>Tab:" "DoSearchAction() SetField(Replace)\n"
142 static char rep_text_trans[] =
143 "~s<Key>Return:" "DoReplaceAction(Popdown)\n"
144 "s<Key>Return:" "SetField(Search)\n"
145 "c<Key>c:" "PopdownSearchAction()\n"
146 "<Btn1Down>:" "select-start() DoSearchAction() SetField(Replace)\n"
147 "<Key>Tab:" "SetField(Search)\n"
154 * This section of the file contains all the functions that
155 * the file insert dialog box uses
160 * _XawTextInsertFileAction
163 * Action routine that can be bound to dialog box's Text Widget
164 * that will insert a file into the main Text Widget.
168 _XawTextInsertFileAction(Widget w, XEvent *event,
169 String *params, Cardinal *num_params)
171 DoInsert(w, (XtPointer)XtParent(XtParent(XtParent(w))), NULL);
180 * event - X Event (used to get x and y location)
181 * params - parameter list
185 * Action routine that can be bound to the text widget
186 * it will popup the insert file dialog box.
189 * The parameter list may contain one entry
192 * This entry is optional and contains the value of the default
196 _XawTextInsertFile(Widget w, XEvent *event,
197 String *params, Cardinal *num_params)
199 TextWidget ctx = (TextWidget)w;
201 XawTextEditType edit_mode;
204 XtSetArg(args[0], XtNeditType, &edit_mode);
205 XtGetValues(ctx->text.source, args, 1);
207 if (edit_mode != XawtextEdit) {
208 XBell(XtDisplay(w), 0);
212 if (*num_params == 0)
217 if (!ctx->text.file_insert) {
218 ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
219 AddInsertFileChildren);
220 XtRealizeWidget(ctx->text.file_insert);
221 SetWMProtocolTranslations(ctx->text.file_insert);
224 CenterWidgetOnPoint(ctx->text.file_insert, event);
225 XtPopup(ctx->text.file_insert, XtGrabNone);
233 * w - widget that caused this action
234 * closure - pointer to the main text widget that popped up this dialog
235 * call_data - (not used)
238 * Pops down the file insert button
242 PopdownFileInsert(Widget w, XtPointer closure, XtPointer call_data)
244 TextWidget ctx = (TextWidget)closure;
246 XtPopdown(ctx->text.file_insert);
247 (void)SetResourceByName(ctx->text.file_insert, LABEL_NAME,
248 XtNlabel, (XtArgVal)INSERT_FILE);
256 * w - widget that activated this callback
257 * closure - pointer to the text widget to insert the file into
260 * Actually insert the file named in the text widget of the file dialog
264 DoInsert(Widget w, XtPointer closure, XtPointer call_data)
266 TextWidget ctx = (TextWidget)closure;
267 char buf[BUFSIZ], msg[BUFSIZ];
270 snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, TEXT_NAME);
271 if ((temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL) {
273 "Error: Could not get text widget from file insert popup");
275 else if (InsertFileNamed((Widget)ctx, GetString(temp_widget))) {
276 PopdownFileInsert(w, closure, call_data);
280 snprintf(msg, sizeof(msg), "Error: %s", strerror(errno));
282 (void)SetResourceByName(ctx->text.file_insert,
283 LABEL_NAME, XtNlabel, (XtArgVal)msg);
284 XBell(XtDisplay(w), 0);
292 * tw - text widget to insert this file into
293 * str - name of the file to insert
296 * Inserts a file into the text widget.
299 * True if the insert was sucessful, False otherwise.
302 InsertFileNamed(Widget tw, char *str)
308 if (str == NULL || strlen(str) == 0 || (file = fopen(str, "r")) == NULL)
311 pos = XawTextGetInsertionPoint(tw);
316 text.length = ftell(file);
317 text.ptr = XtMalloc(text.length + 1);
318 text.format = XawFmt8Bit;
321 if (fread(text.ptr, 1, text.length, file) != text.length)
322 XtErrorMsg("readError", "insertFileNamed", "XawError",
323 "fread returned error", NULL, NULL);
325 if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
333 XawTextSetInsertionPoint(tw, pos);
334 _XawTextShowPosition((TextWidget)tw);
341 * AddInsertFileChildren
344 * form - form widget for the insert dialog widget
345 * ptr - pointer to the initial string for the Text Widget
346 * tw - main text widget
349 * Adds all children to the InsertFile dialog widget.
352 AddInsertFileChildren(Widget form, char *ptr, Widget tw)
356 Widget label, text, cancel, insert;
357 XtTranslations trans;
360 XtSetArg(args[num_args], XtNlabel, INSERT_FILE); num_args++;
361 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
362 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
363 XtSetArg(args[num_args], XtNresizable, True); num_args++;
364 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
365 label = XtCreateManagedWidget(LABEL_NAME, labelWidgetClass, form,
369 XtSetArg(args[num_args], XtNfromVert, label); num_args++;
370 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
371 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
372 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
373 XtSetArg(args[num_args], XtNresizable, True); num_args++;
374 XtSetArg(args[num_args], XtNstring, ptr); num_args++;
375 text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
379 XtSetArg(args[num_args], XtNlabel, "Insert File"); num_args++;
380 XtSetArg(args[num_args], XtNfromVert, text); num_args++;
381 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
382 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
383 insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
387 XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
388 XtSetArg(args[num_args], XtNfromVert, text); num_args++;
389 XtSetArg(args[num_args], XtNfromHoriz, insert); num_args++;
390 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
391 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
392 cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
395 XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer)tw);
396 XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer)tw);
398 XtSetKeyboardFocus(form, text);
401 * Bind <CR> to insert file
403 trans = XtParseTranslationTable("<Key>Return:InsertFileAction()");
404 XtOverrideTranslations(text, trans);
408 * This section of the file contains all the functions that
409 * the search dialog box uses
413 * _XawTextDoSearchAction
416 * Action routine that can be bound to dialog box's Text Widget that
417 * will search for a string in the main Text Widget.
420 * If the search was sucessful and the argument popdown is passed to
421 * this action routine then the widget will automatically popdown the
426 _XawTextDoSearchAction(Widget w, XEvent *event,
427 String *params, Cardinal *num_params)
429 TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
430 Bool popdown = False;
432 if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
435 if (DoSearch(tw->text.search) && popdown)
436 PopdownSearch(w, (XtPointer)tw->text.search, NULL);
441 * _XawTextPopdownSearchAction
444 * Action routine that can be bound to dialog box's Text Widget that
445 * will popdown the search widget.
449 _XawTextPopdownSearchAction(Widget w, XEvent *event,
450 String *params, Cardinal *num_params)
452 TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
454 PopdownSearch(w, (XtPointer)tw->text.search, NULL);
463 * closure - pointer to the search structure
464 * call_data - (not used)
467 * Pops down the search widget and resets it
471 PopdownSearch(Widget w, XtPointer closure, XtPointer call_data)
473 struct SearchAndReplace *search = (struct SearchAndReplace *)closure;
475 XtPopdown(search->search_popup);
476 SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
485 * closure - pointer to the search info
486 * call_data - (not used)
489 * Performs a search when the button is clicked.
493 SearchButton(Widget w, XtPointer closure, XtPointer call_data)
495 (void)DoSearch((struct SearchAndReplace *)closure);
504 * event - X Event (used to get x and y location)
505 * params - parameter list
509 * Action routine that can be bound to the text widget
510 * it will popup the search dialog box.
513 * The parameter list contains one or two entries that may be
517 * The first entry is the direction to search by default.
518 * This arguement must be specified and may have a value of
522 * This entry is optional and contains the value of the default
523 * string to search for.
526 #define SEARCH_HEADER "Text Widget - Search():"
528 _XawTextSearch(Widget w, XEvent *event, String *params, Cardinal *num_params)
530 TextWidget ctx = (TextWidget)w;
531 XawTextScanDirection dir;
532 char *ptr, buf[BUFSIZ];
533 XawTextEditType edit_mode;
537 if (*num_params < 1 || *num_params > 2) {
538 snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
539 "This action must have only",
540 "one or two parameters");
541 XtAppWarning(XtWidgetToApplicationContext(w), buf);
545 if (*num_params == 2)
547 else if (XawTextFormat(ctx, XawFmtWide)) {
548 /* This just does the equivalent of
549 ptr = ""L, a waste because params[1] isnt W aligned */
556 switch(params[0][0]) {
561 case 'f': /* Right */
566 snprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
567 "The first parameter must be",
568 "Either 'backward' or 'forward'");
569 XtAppWarning(XtWidgetToApplicationContext(w), buf);
573 if (ctx->text.search== NULL) {
574 ctx->text.search = XtNew(struct SearchAndReplace);
575 ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
577 XtRealizeWidget(ctx->text.search->search_popup);
578 SetWMProtocolTranslations(ctx->text.search->search_popup);
580 else if (*num_params > 1)
581 XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
583 XtSetArg(args[0], XtNeditType,&edit_mode);
584 XtGetValues(ctx->text.source, args, 1);
586 InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
588 CenterWidgetOnPoint(ctx->text.search->search_popup, event);
589 XtPopup(ctx->text.search->search_popup, XtGrabNone);
594 * InitializeSearchWidget
597 * search - search widget structure
598 * dir - direction to search
599 * replace_active - state of the sensitivity for the replace button
602 * This function initializes the search widget and
603 * is called each time the search widget is poped up.
606 InitializeSearchWidget(struct SearchAndReplace *search,
607 XawTextScanDirection dir, Bool replace_active)
609 SetResource(search->rep_one, XtNsensitive, (XtArgVal)replace_active);
610 SetResource(search->rep_all, XtNsensitive, (XtArgVal)replace_active);
611 SetResource(search->rep_label, XtNsensitive, (XtArgVal)replace_active);
612 SetResource(search->rep_text, XtNsensitive, (XtArgVal)replace_active);
616 SetResource(search->left_toggle, XtNstate, (XtArgVal)True);
619 SetResource(search->right_toggle, XtNstate, (XtArgVal)True);
629 * form - form widget for the search widget
630 * ptr - pointer to the initial string for the Text Widget
631 * tw - main text widget
634 * Adds all children to the Search Dialog Widget.
637 AddSearchChildren(Widget form, char *ptr, Widget tw)
641 Widget cancel, search_button, s_label, s_text, r_text;
642 XtTranslations trans;
643 struct SearchAndReplace *search = ((TextWidget)tw)->text.search;
646 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
647 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
648 XtSetArg(args[num_args], XtNresizable, True); num_args++;
649 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
650 search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
654 XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
655 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
656 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
657 XtSetArg(args[num_args], XtNresizable, True); num_args++;
658 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
659 search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
663 * We need to add R_OFFSET to the radio_data, because the value zero (0)
664 * has special meaning
667 XtSetArg(args[num_args], XtNlabel, "Backward"); num_args++;
668 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
669 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
670 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
671 XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdLeft + R_OFFSET);
673 search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
674 form, args, num_args);
677 XtSetArg(args[num_args], XtNlabel, "Forward"); num_args++;
678 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
679 XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
680 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
681 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
682 XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
683 XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdRight + R_OFFSET);
685 search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
686 form, args, num_args);
689 XtTranslations radio_translations;
691 radio_translations = XtParseTranslationTable(radio_trans_string);
692 XtOverrideTranslations(search->left_toggle, radio_translations);
693 XtOverrideTranslations(search->right_toggle, radio_translations);
697 if (XawTextFormat((TextWidget)tw, XawFmt8Bit)) {
699 XtSetArg(args[num_args], XtNlabel, "Case Sensitive"); num_args++;
700 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
701 XtSetArg(args[num_args], XtNfromHoriz, search->right_toggle); num_args++;
702 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
703 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
704 XtSetArg(args[num_args], XtNstate, True); num_args++;
705 search->case_sensitive = XtCreateManagedWidget("case", toggleWidgetClass,
706 form, args, num_args);
709 search->case_sensitive = NULL;
713 XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
714 XtSetArg(args[num_args], XtNlabel, "Search for: "); num_args++;
715 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
716 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
717 XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
718 s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
722 XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
723 XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
724 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
725 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
726 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
727 XtSetArg(args[num_args], XtNresizable, True); num_args++;
728 XtSetArg(args[num_args], XtNstring, ptr); num_args++;
729 s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
731 search->search_text = s_text;
734 XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
735 XtSetArg(args[num_args], XtNlabel, "Replace with:"); num_args++;
736 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
737 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
738 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
739 search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
740 form, args, num_args);
743 XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
744 XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
745 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
746 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
747 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
748 XtSetArg(args[num_args], XtNresizable, True); num_args++;
749 XtSetArg(args[num_args], XtNstring, ""); num_args++;
750 r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
751 form, args, num_args);
752 search->rep_text = r_text;
755 XtSetArg(args[num_args], XtNlabel, "Search"); num_args++;
756 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
757 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
758 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
759 search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
763 XtSetArg(args[num_args], XtNlabel, "Replace"); num_args++;
764 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
765 XtSetArg(args[num_args], XtNfromHoriz, search_button); num_args++;
766 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
767 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
768 search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
769 form, args, num_args);
772 XtSetArg(args[num_args], XtNlabel, "Replace All"); num_args++;
773 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
774 XtSetArg(args[num_args], XtNfromHoriz, search->rep_one); num_args++;
775 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
776 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
777 search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
778 form, args, num_args);
781 XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
782 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
783 XtSetArg(args[num_args], XtNfromHoriz, search->rep_all); num_args++;
784 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
785 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
786 cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
789 XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer)search);
790 XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer)search);
791 XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer)search);
792 XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer)search);
795 * Initialize the text entry fields
801 XtSetArg(args[num_args], XtNbackground, &color); num_args++;
802 XtGetValues(search->rep_text, args, num_args);
804 XtSetArg(args[num_args], XtNborderColor, color); num_args++;
805 XtSetValues(search->rep_text, args, num_args);
806 XtSetKeyboardFocus(form, search->search_text);
809 SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
812 * Bind Extra translations
814 trans = XtParseTranslationTable(search_text_trans);
815 XtOverrideTranslations(search->search_text, trans);
817 trans = XtParseTranslationTable(rep_text_trans);
818 XtOverrideTranslations(search->rep_text, trans);
826 * search - search structure
836 DoSearch(struct SearchAndReplace *search)
839 Widget tw = XtParent(search->search_popup);
841 XawTextScanDirection dir;
843 TextWidget ctx = (TextWidget)tw;
846 text.ptr = GetStringRaw(search->search_text);
847 if ((text.format = _XawTextFormat(ctx)) == XawFmtWide)
848 text.length = wcslen((wchar_t*)text.ptr);
850 text.length = strlen(text.ptr);
853 if (search->case_sensitive) {
854 /* text.firstPos isn't useful here, so I'll use it as an
858 Boolean case_sensitive;
860 XtSetArg(args[0], XtNstate, &case_sensitive);
861 XtGetValues(search->case_sensitive, args, 1);
862 text.firstPos = !case_sensitive;
867 dir = (XawTextScanDirection)(unsigned long)
868 ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
870 pos = XawTextSearch(tw, dir, &text);
872 /* The Raw string in find.ptr may be WC I can't use here, so I re - call
873 GetString to get a tame version */
875 if (pos == XawTextSearchError) {
879 ptr = GetString(search->search_text);
881 snprintf(msg, sizeof(msg), "%s", ptr);
883 ptr = strchr(msg, '\n');
884 if (ptr != NULL || sizeof(msg) - 1 < len) {
893 strcpy(msg + len - 4, "...");
895 XawTextUnsetSelection(tw);
896 SetSearchLabels(search, "Could not find string", msg, True);
900 XawTextDisableRedisplay(tw);
901 XawTextSetSelection(tw, pos, pos + text.length);
902 search->selection_changed = False; /* selection is good */
904 if (dir == XawsdRight)
905 XawTextSetInsertionPoint(tw, pos + text.length);
907 XawTextSetInsertionPoint(tw, pos);
908 _XawTextShowPosition(ctx);
909 XawTextEnableRedisplay(tw);
915 * This section of the file contains all the functions that
916 * the replace dialog box uses
920 * _XawTextDoReplaceAction
923 * Action routine that can be bound to dialog box's
924 * Text Widget that will replace a string in the main Text Widget.
928 _XawTextDoReplaceAction(Widget w, XEvent *event,
929 String *params, Cardinal *num_params)
931 TextWidget ctx = (TextWidget)XtParent(XtParent(XtParent(w)));
932 Bool popdown = False;
934 if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
937 if (Replace( ctx->text.search, True, popdown) && popdown)
938 PopdownSearch(w, (XtPointer)ctx->text.search, NULL);
946 * w - *** Not Used ***
947 * closure - a pointer to the search structure
948 * call_data - *** Not Used ***
951 * Replaces the first instance of the string in the search
952 * dialog's text widget with the one in the replace dialog's text widget.
956 DoReplaceOne(Widget w, XtPointer closure, XtPointer call_data)
958 Replace((struct SearchAndReplace *)closure, True, False);
967 * closure - pointer to the search structure
968 * call_data - (not used)
971 * Replaces every instance of the string in the search dialog's
972 * text widget with the one in the replace dialog's text widget.
976 DoReplaceAll(Widget w, XtPointer closure, XtPointer call_data)
978 Replace((struct SearchAndReplace *)closure, False, False);
986 * tw - Text Widget to replce the string in
987 * once_only - if True then only replace the first one found,
988 * else replace all of them
989 * show_current - if true then leave the selection on the
990 * string that was just replaced, otherwise
991 * move it onto the next one
994 * This is the function that does the real work of
995 * replacing strings in the main text widget.
998 Replace(struct SearchAndReplace *search, Bool once_only, Bool show_current)
1000 XawTextPosition pos, new_pos, end_pos, ipos;
1001 XawTextScanDirection dir;
1002 XawTextBlock find, replace;
1003 Widget tw = XtParent(search->search_popup);
1005 TextWidget ctx = (TextWidget)tw;
1008 find.ptr = GetStringRaw(search->search_text);
1009 if ((find.format = _XawTextFormat(ctx)) == XawFmtWide)
1010 find.length = (XawTextPosition)wcslen((wchar_t*)find.ptr);
1012 find.length = (XawTextPosition)strlen(find.ptr);
1015 replace.ptr = GetStringRaw(search->rep_text);
1016 replace.firstPos = 0;
1017 if ((replace.format = _XawTextFormat(ctx)) == XawFmtWide)
1018 replace.length = wcslen((wchar_t*)replace.ptr);
1020 replace.length = strlen(replace.ptr);
1022 dir = (XawTextScanDirection)(unsigned long)
1023 ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
1025 redisplay = !once_only || (once_only && !show_current);
1026 ipos = XawTextGetInsertionPoint(tw);
1028 XawTextDisableRedisplay(tw);
1032 new_pos = XawTextSearch(tw, dir, &find);
1034 if (new_pos == XawTextSearchError) {
1040 ptr = GetString(search->search_text);
1042 snprintf(msg, sizeof(msg), "%s", ptr);
1043 ptr = strchr(msg, '\n');
1044 if (ptr != NULL || sizeof(msg) - 1 < len) {
1046 len = ptr - msg + 4;
1053 strcpy(msg + len - 4, "...");
1055 SetSearchLabels(search, "Could not find string", msg, True);
1058 XawTextSetInsertionPoint(tw, ipos);
1059 _XawTextShowPosition(ctx);
1060 XawTextEnableRedisplay(tw);
1069 end_pos = pos + find.length;
1072 XawTextGetSelectionPos(tw, &pos, &end_pos);
1074 if (search->selection_changed) {
1075 SetSearchLabels(search, "Selection modified, aborting.",
1078 XawTextSetInsertionPoint(tw, ipos);
1079 XawTextEnableRedisplay(tw);
1084 if (pos == end_pos) {
1086 XawTextSetInsertionPoint(tw, ipos);
1087 XawTextEnableRedisplay(tw);
1094 if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
1095 SetSearchLabels(search, "Error while replacing.", "", True);
1097 XawTextSetInsertionPoint(tw, ipos);
1098 XawTextEnableRedisplay(tw);
1104 if (dir == XawsdRight)
1105 ipos = pos + replace.length;
1114 XawTextEnableRedisplay(tw);
1120 ctx->text.insertPos = ipos;
1124 if (replace.length == 0)
1125 XawTextUnsetSelection(tw);
1127 XawTextSetSelection(tw, pos, pos + replace.length);
1129 XawTextSetInsertionPoint(tw, ipos);
1130 _XawTextShowPosition(ctx);
1131 XawTextEnableRedisplay(tw);
1141 * search - search structure
1142 * msg1 - message to put in each search label
1144 * bell - if True then ring bell
1147 * Sets both the search labels, and also rings the bell.
1150 SetSearchLabels(struct SearchAndReplace *search, String msg1, String msg2,
1153 (void)SetResource(search->label1, XtNlabel, (XtArgVal)msg1);
1154 (void)SetResource(search->label2, XtNlabel, (XtArgVal)msg2);
1156 XBell(XtDisplay(search->search_popup), 0);
1160 * This section of the file contains utility routines used by
1161 * other functions in this file
1168 * Action routine that can be bound to dialog box's
1169 * Text Widget that will send input to the field specified.
1173 _XawTextSetField(Widget w, XEvent *event, String *params, Cardinal *num_params)
1175 struct SearchAndReplace *search;
1178 search = ((TextWidget)XtParent(XtParent(XtParent(w))))->text.search;
1180 if (*num_params != 1) {
1181 SetSearchLabels(search, "Error: SetField Action must have",
1182 "exactly one argument", True);
1185 switch (params[0][0]) {
1188 cnew = search->search_text;
1189 old = search->rep_text;
1193 old = search->search_text;
1194 cnew = search->rep_text;
1197 SetSearchLabels(search,
1198 "Error: SetField Action's first Argument must",
1199 "be either 'Search' or 'Replace'", True);
1202 _SetField(cnew, old);
1210 * cnew - new and old text fields
1214 * Sets the current text field.
1217 _SetField(Widget cnew, Widget old)
1220 Pixel new_border, old_border, old_bg;
1222 if (!XtIsSensitive(cnew)) {
1223 XBell(XtDisplay(old), 0); /* Don't set field to an inactive Widget */
1227 XtSetKeyboardFocus(XtParent(cnew), cnew);
1229 XtSetArg(args[0], XtNborderColor, &old_border);
1230 XtSetArg(args[1], XtNbackground, &old_bg);
1231 XtGetValues(cnew, args, 2);
1233 XtSetArg(args[0], XtNborderColor, &new_border);
1234 XtGetValues(old, args, 1);
1236 if (old_border != old_bg) /* Colors are already correct, return */
1239 SetResource(old, XtNborderColor, (XtArgVal)old_border);
1240 SetResource(cnew, XtNborderColor, (XtArgVal)new_border);
1248 * shell - shell widget of the popup
1249 * name - name of the child
1250 * res_name - name of the resource
1251 * value - value of the resource
1254 * Sets a resource in any of the dialog children given
1255 * name of the child and the shell widget of the dialog.
1261 SetResourceByName(Widget shell, char *name, char *res_name, XtArgVal value)
1266 snprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, name);
1268 if ((temp_widget = XtNameToWidget(shell, buf)) != NULL) {
1269 SetResource(temp_widget, res_name, value);
1281 * res_name - name of the resource
1282 * value - value of the resource
1285 * Sets a resource in a widget
1288 SetResource(Widget w, char *res_name, XtArgVal value)
1292 XtSetArg(args[0], res_name, value);
1293 XtSetValues( w, args, 1);
1301 * text - text widget whose string we will get
1304 * Gets the value for the string in the popup.
1307 * GetString: the string as a MB
1308 * GetStringRaw: the exact buffer contents suitable for a search
1311 GetString(Widget text)
1316 XtSetArg(args[0], XtNstring, &string);
1317 XtGetValues(text, args, 1);
1323 GetStringRaw(Widget tw)
1325 TextWidget ctx = (TextWidget)tw;
1326 XawTextPosition last;
1328 last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
1329 ctx->text.mult, True);
1330 return (_XawTextGetText(ctx, 0, last));
1335 * CenterWidgetOnPoint
1339 * event - event containing the location of the point
1342 * Centers a shell widget on a point relative to the root window.
1345 * The widget is not allowed to go off the screen
1348 CenterWidgetOnPoint(Widget w, XEvent *event)
1352 Dimension width, height, b_width;
1353 Position x, y, max_x, max_y;
1355 if (event != NULL) {
1356 switch (event->type) {
1359 x = event->xbutton.x_root;
1360 y = event->xbutton.y_root;
1364 x = event->xkey.x_root;
1365 y = event->xkey.y_root;
1375 XtSetArg(args[num_args], XtNwidth, &width); num_args++;
1376 XtSetArg(args[num_args], XtNheight, &height); num_args++;
1377 XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
1378 XtGetValues(w, args, num_args);
1380 width += b_width << 1;
1381 height += b_width << 1;
1383 x -= (Position)(width >> 1);
1386 if (x > (max_x = (Position)(XtScreen(w)->width - width)))
1389 y -= (Position)(height >> 1);
1392 if (y > (max_y = (Position)(XtScreen(w)->height - height)))
1396 XtSetArg(args[num_args], XtNx, x); num_args++;
1397 XtSetArg(args[num_args], XtNy, y); num_args++;
1398 XtSetValues(w, args, num_args);
1406 * parent - parent of the dialog - the main text widget
1407 * ptr - initial_string for the dialog
1408 * name - name of the dialog
1409 * func - function to create the children of the dialog
1412 * Popup shell of the dialog
1415 * The function argument is passed the following arguments:
1416 * form - from widget that is the dialog
1417 * ptr - initial string for the dialog's text widget
1418 * parent - parent of the dialog - the main text widget
1421 CreateDialog(Widget parent, String ptr, String name, AddFunc func)
1428 XtSetArg(args[num_args], XtNiconName, name); num_args++;
1429 XtSetArg(args[num_args], XtNgeometry, NULL); num_args++;
1430 XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
1431 XtSetArg(args[num_args], XtNtransientFor, GetShell(parent));num_args++;
1432 popup = XtCreatePopupShell(name, transientShellWidgetClass,
1433 parent, args, num_args);
1435 form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup, NULL, 0);
1436 XtManageChild (form);
1438 (*func)(form, ptr, parent);
1446 * nearest shell widget.
1449 * w - widget whose parent shell should be returned
1452 * The shell widget among the ancestors of w that is the
1453 * fewest levels up in the widget hierarchy.
1456 * Walks up the widget hierarchy to find the topmost shell widget.
1461 while (w != NULL && !XtIsShell(w))
1468 InParams(String str, String *p, unsigned int n)
1472 for (i = 0; i < n; p++, i++)
1473 if (!XmuCompareISOLatin1(*p, str))
1478 static char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
1481 WMProtocols(Widget w, XEvent *event, String *params, Cardinal *num_params)
1483 Atom wm_delete_window;
1486 wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
1487 wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
1489 /* Respond to a recognized WM protocol request if
1490 * event type is ClientMessage and no parameters are passed, or
1491 * event type is ClientMessage and event data is matched to parameters, or
1492 * event type isn't ClientMessage and parameters make a request
1494 #define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
1496 if ((event->type == ClientMessage
1497 && event->xclient.message_type == wm_protocols
1498 && event->xclient.data.l[0] == wm_delete_window
1499 && (*num_params == 0 || DO_DELETE_WINDOW))
1500 || (event->type != ClientMessage && DO_DELETE_WINDOW)) {
1501 #undef DO_DELETE_WINDOW
1503 char descendant[DISMISS_NAME_LEN + 2];
1505 snprintf(descendant, sizeof(descendant), "*%s", DISMISS_NAME);
1506 cancel = XtNameToWidget(w, descendant);
1508 XtCallCallbacks(cancel, XtNcallback, NULL);
1513 SetWMProtocolTranslations(Widget w)
1515 static XtTranslations compiled_table;
1516 static XtAppContext *app_context_list;
1517 static Cardinal list_size;
1520 XtAppContext app_context;
1521 Atom wm_delete_window;
1523 app_context = XtWidgetToApplicationContext(w);
1525 /* parse translation table once */
1526 if (!compiled_table)
1528 XtParseTranslationTable("<Message>WM_PROTOCOLS:XawWMProtocols()\n");
1530 /* add actions once per application context */
1531 for (i = 0; i < list_size && app_context_list[i] != app_context; i++)
1533 if (i == list_size) {
1534 XtActionsRec actions[1];
1536 actions[0].string = "XawWMProtocols";
1537 actions[0].proc = WMProtocols;
1539 app_context_list = (XtAppContext *)XtRealloc
1540 ((char *)app_context_list, list_size * sizeof(XtAppContext));
1541 XtAppAddActions(app_context, actions, 1);
1542 app_context_list[i] = app_context;
1545 /* establish communication between the window manager and each shell */
1546 XtAugmentTranslations(w, compiled_table);
1547 wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
1548 (void)XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);