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/Xmu/SysUtil.h>
57 #include <X11/Xaw/TextP.h>
58 #include <X11/Xaw/AsciiText.h>
59 #include <X11/Xaw/Cardinals.h>
60 #include <X11/Xaw/Command.h>
61 #include <X11/Xaw/Form.h>
62 #include <X11/Xaw/Toggle.h>
65 static char* INSERT_FILE = "Enter Filename:";
66 static char* SEARCH_LABEL_1 = "Use <Tab> to change fields.";
67 static char* SEARCH_LABEL_2 = "Use ^q<Tab> for <Tab>.";
68 static char* DISMISS_NAME = "cancel";
69 #define DISMISS_NAME_LEN 6
70 static char* FORM_NAME = "form";
71 static char* LABEL_NAME = "label";
72 static char* TEXT_NAME = "text";
76 typedef void (*AddFunc)(Widget, char*, Widget);
81 static void _SetField(Widget, Widget);
82 static void AddSearchChildren(Widget, char*, Widget);
83 static void AddInsertFileChildren(Widget, char*, Widget);
84 static void CenterWidgetOnPoint(Widget, XEvent*);
85 static Widget CreateDialog(Widget, String, String, AddFunc);
86 static void DoInsert(Widget, XtPointer, XtPointer);
87 static void DoReplaceAll(Widget, XtPointer, XtPointer);
88 static void DoReplaceOne(Widget, XtPointer, XtPointer);
89 static Bool DoSearch(struct SearchAndReplace*);
90 static Widget GetShell(Widget);
91 static String GetString(Widget);
92 static String GetStringRaw(Widget);
93 static void InitializeSearchWidget(struct SearchAndReplace*,
94 XawTextScanDirection, Bool);
95 static Bool InParams(String, String*, unsigned int);
96 static Bool InsertFileNamed(Widget, char*);
97 static void PopdownFileInsert(Widget, XtPointer, XtPointer);
98 static void PopdownSearch(Widget, XtPointer, XtPointer);
99 static Bool Replace(struct SearchAndReplace*, Bool, Bool);
100 static void SearchButton(Widget, XtPointer, XtPointer);
101 static void SetResource(Widget, char*, XtArgVal);
102 static Bool SetResourceByName(Widget, char*, char*, XtArgVal);
103 static void SetSearchLabels(struct SearchAndReplace*, String, String, Bool);
104 static void SetWMProtocolTranslations(Widget);
109 static void WMProtocols(Widget, XEvent*, String*, Cardinal*);
114 void _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*);
115 void _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*);
116 void _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*);
117 void _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*);
118 void _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*);
119 void _XawTextSearch(Widget, XEvent*, String*, Cardinal*);
120 void _XawTextSetField(Widget, XEvent*, String*, Cardinal*);
125 char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
126 void _XawTextShowPosition(TextWidget);
131 static char radio_trans_string[] =
132 "<Btn1Down>,<Btn1Up>:" "set() notify()\n"
135 static char search_text_trans[] =
136 "~s<Key>Return:" "DoSearchAction(Popdown)\n"
137 "s<Key>Return:" "DoSearchAction() SetField(Replace)\n"
138 "c<Key>c:" "PopdownSearchAction()\n"
139 "<Btn1Down>:" "select-start() SetField(Search)\n"
140 "<Key>Tab:" "DoSearchAction() SetField(Replace)\n"
143 static char rep_text_trans[] =
144 "~s<Key>Return:" "DoReplaceAction(Popdown)\n"
145 "s<Key>Return:" "SetField(Search)\n"
146 "c<Key>c:" "PopdownSearchAction()\n"
147 "<Btn1Down>:" "select-start() DoSearchAction() SetField(Replace)\n"
148 "<Key>Tab:" "SetField(Search)\n"
155 * This section of the file contains all the functions that
156 * the file insert dialog box uses
161 * _XawTextInsertFileAction
164 * Action routine that can be bound to dialog box's Text Widget
165 * that will insert a file into the main Text Widget.
169 _XawTextInsertFileAction(Widget w, XEvent *event,
170 String *params, Cardinal *num_params)
172 DoInsert(w, (XtPointer)XtParent(XtParent(XtParent(w))), NULL);
181 * event - X Event (used to get x and y location)
182 * params - parameter list
186 * Action routine that can be bound to the text widget
187 * it will popup the insert file dialog box.
190 * The parameter list may contain one entry
193 * This entry is optional and contains the value of the default
197 _XawTextInsertFile(Widget w, XEvent *event,
198 String *params, Cardinal *num_params)
200 TextWidget ctx = (TextWidget)w;
202 XawTextEditType edit_mode;
205 XtSetArg(args[0], XtNeditType, &edit_mode);
206 XtGetValues(ctx->text.source, args, 1);
208 if (edit_mode != XawtextEdit) {
209 XBell(XtDisplay(w), 0);
213 if (*num_params == 0)
218 if (!ctx->text.file_insert) {
219 ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
220 AddInsertFileChildren);
221 XtRealizeWidget(ctx->text.file_insert);
222 SetWMProtocolTranslations(ctx->text.file_insert);
225 CenterWidgetOnPoint(ctx->text.file_insert, event);
226 XtPopup(ctx->text.file_insert, XtGrabNone);
234 * w - widget that caused this action
235 * closure - pointer to the main text widget that popped up this dialog
236 * call_data - (not used)
239 * Pops down the file insert button
243 PopdownFileInsert(Widget w, XtPointer closure, XtPointer call_data)
245 TextWidget ctx = (TextWidget)closure;
247 XtPopdown(ctx->text.file_insert);
248 (void)SetResourceByName(ctx->text.file_insert, LABEL_NAME,
249 XtNlabel, (XtArgVal)INSERT_FILE);
257 * w - widget that activated this callback
258 * closure - pointer to the text widget to insert the file into
261 * Actually insert the file named in the text widget of the file dialog
265 DoInsert(Widget w, XtPointer closure, XtPointer call_data)
267 TextWidget ctx = (TextWidget)closure;
268 char buf[BUFSIZ], msg[BUFSIZ];
271 (void)XmuSnprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, TEXT_NAME);
272 if ((temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL) {
274 "Error: Could not get text widget from file insert popup");
276 else if (InsertFileNamed((Widget)ctx, GetString(temp_widget))) {
277 PopdownFileInsert(w, closure, call_data);
281 (void)XmuSnprintf(msg, sizeof(msg), "Error: %s", strerror(errno));
283 (void)SetResourceByName(ctx->text.file_insert,
284 LABEL_NAME, XtNlabel, (XtArgVal)msg);
285 XBell(XtDisplay(w), 0);
293 * tw - text widget to insert this file into
294 * str - name of the file to insert
297 * Inserts a file into the text widget.
300 * True if the insert was sucessful, False otherwise.
303 InsertFileNamed(Widget tw, char *str)
309 if (str == NULL || strlen(str) == 0 || (file = fopen(str, "r")) == NULL)
312 pos = XawTextGetInsertionPoint(tw);
317 text.length = ftell(file);
318 text.ptr = XtMalloc(text.length + 1);
319 text.format = XawFmt8Bit;
322 if (fread(text.ptr, 1, text.length, file) != text.length)
323 XtErrorMsg("readError", "insertFileNamed", "XawError",
324 "fread returned error", NULL, NULL);
326 if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
334 XawTextSetInsertionPoint(tw, pos);
335 _XawTextShowPosition((TextWidget)tw);
342 * AddInsertFileChildren
345 * form - form widget for the insert dialog widget
346 * ptr - pointer to the initial string for the Text Widget
347 * tw - main text widget
350 * Adds all children to the InsertFile dialog widget.
353 AddInsertFileChildren(Widget form, char *ptr, Widget tw)
357 Widget label, text, cancel, insert;
358 XtTranslations trans;
361 XtSetArg(args[num_args], XtNlabel, INSERT_FILE); num_args++;
362 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
363 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
364 XtSetArg(args[num_args], XtNresizable, True); num_args++;
365 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
366 label = XtCreateManagedWidget(LABEL_NAME, labelWidgetClass, form,
370 XtSetArg(args[num_args], XtNfromVert, label); num_args++;
371 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
372 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
373 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
374 XtSetArg(args[num_args], XtNresizable, True); num_args++;
375 XtSetArg(args[num_args], XtNstring, ptr); num_args++;
376 text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
380 XtSetArg(args[num_args], XtNlabel, "Insert File"); num_args++;
381 XtSetArg(args[num_args], XtNfromVert, text); num_args++;
382 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
383 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
384 insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
388 XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
389 XtSetArg(args[num_args], XtNfromVert, text); num_args++;
390 XtSetArg(args[num_args], XtNfromHoriz, insert); num_args++;
391 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
392 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
393 cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
396 XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer)tw);
397 XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer)tw);
399 XtSetKeyboardFocus(form, text);
402 * Bind <CR> to insert file
404 trans = XtParseTranslationTable("<Key>Return:InsertFileAction()");
405 XtOverrideTranslations(text, trans);
409 * This section of the file contains all the functions that
410 * the search dialog box uses
414 * _XawTextDoSearchAction
417 * Action routine that can be bound to dialog box's Text Widget that
418 * will search for a string in the main Text Widget.
421 * If the search was sucessful and the argument popdown is passed to
422 * this action routine then the widget will automatically popdown the
427 _XawTextDoSearchAction(Widget w, XEvent *event,
428 String *params, Cardinal *num_params)
430 TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
431 Bool popdown = False;
433 if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
436 if (DoSearch(tw->text.search) && popdown)
437 PopdownSearch(w, (XtPointer)tw->text.search, NULL);
442 * _XawTextPopdownSearchAction
445 * Action routine that can be bound to dialog box's Text Widget that
446 * will popdown the search widget.
450 _XawTextPopdownSearchAction(Widget w, XEvent *event,
451 String *params, Cardinal *num_params)
453 TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
455 PopdownSearch(w, (XtPointer)tw->text.search, NULL);
464 * closure - pointer to the search structure
465 * call_data - (not used)
468 * Pops down the search widget and resets it
472 PopdownSearch(Widget w, XtPointer closure, XtPointer call_data)
474 struct SearchAndReplace *search = (struct SearchAndReplace *)closure;
476 XtPopdown(search->search_popup);
477 SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
486 * closure - pointer to the search info
487 * call_data - (not used)
490 * Performs a search when the button is clicked.
494 SearchButton(Widget w, XtPointer closure, XtPointer call_data)
496 (void)DoSearch((struct SearchAndReplace *)closure);
505 * event - X Event (used to get x and y location)
506 * params - parameter list
510 * Action routine that can be bound to the text widget
511 * it will popup the search dialog box.
514 * The parameter list contains one or two entries that may be
518 * The first entry is the direction to search by default.
519 * This arguement must be specified and may have a value of
523 * This entry is optional and contains the value of the default
524 * string to search for.
527 #define SEARCH_HEADER "Text Widget - Search():"
529 _XawTextSearch(Widget w, XEvent *event, String *params, Cardinal *num_params)
531 TextWidget ctx = (TextWidget)w;
532 XawTextScanDirection dir;
533 char *ptr, buf[BUFSIZ];
534 XawTextEditType edit_mode;
538 if (*num_params < 1 || *num_params > 2) {
539 (void)XmuSnprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
540 "This action must have only",
541 "one or two parameters");
542 XtAppWarning(XtWidgetToApplicationContext(w), buf);
546 if (*num_params == 2)
548 else if (XawTextFormat(ctx, XawFmtWide)) {
549 /* This just does the equivalent of
550 ptr = ""L, a waste because params[1] isnt W aligned */
557 switch(params[0][0]) {
562 case 'f': /* Right */
567 (void)XmuSnprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
568 "The first parameter must be",
569 "Either 'backward' or 'forward'");
570 XtAppWarning(XtWidgetToApplicationContext(w), buf);
574 if (ctx->text.search== NULL) {
575 ctx->text.search = XtNew(struct SearchAndReplace);
576 ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
578 XtRealizeWidget(ctx->text.search->search_popup);
579 SetWMProtocolTranslations(ctx->text.search->search_popup);
581 else if (*num_params > 1)
582 XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
584 XtSetArg(args[0], XtNeditType,&edit_mode);
585 XtGetValues(ctx->text.source, args, 1);
587 InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
589 CenterWidgetOnPoint(ctx->text.search->search_popup, event);
590 XtPopup(ctx->text.search->search_popup, XtGrabNone);
595 * InitializeSearchWidget
598 * search - search widget structure
599 * dir - direction to search
600 * replace_active - state of the sensitivity for the replace button
603 * This function initializes the search widget and
604 * is called each time the search widget is poped up.
607 InitializeSearchWidget(struct SearchAndReplace *search,
608 XawTextScanDirection dir, Bool replace_active)
610 SetResource(search->rep_one, XtNsensitive, (XtArgVal)replace_active);
611 SetResource(search->rep_all, XtNsensitive, (XtArgVal)replace_active);
612 SetResource(search->rep_label, XtNsensitive, (XtArgVal)replace_active);
613 SetResource(search->rep_text, XtNsensitive, (XtArgVal)replace_active);
617 SetResource(search->left_toggle, XtNstate, (XtArgVal)True);
620 SetResource(search->right_toggle, XtNstate, (XtArgVal)True);
630 * form - form widget for the search widget
631 * ptr - pointer to the initial string for the Text Widget
632 * tw - main text widget
635 * Adds all children to the Search Dialog Widget.
638 AddSearchChildren(Widget form, char *ptr, Widget tw)
642 Widget cancel, search_button, s_label, s_text, r_text;
643 XtTranslations trans;
644 struct SearchAndReplace *search = ((TextWidget)tw)->text.search;
647 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
648 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
649 XtSetArg(args[num_args], XtNresizable, True); num_args++;
650 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
651 search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
655 XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
656 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
657 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
658 XtSetArg(args[num_args], XtNresizable, True); num_args++;
659 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
660 search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
664 * We need to add R_OFFSET to the radio_data, because the value zero (0)
665 * has special meaning
668 XtSetArg(args[num_args], XtNlabel, "Backward"); num_args++;
669 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
670 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
671 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
672 XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdLeft + R_OFFSET);
674 search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
675 form, args, num_args);
678 XtSetArg(args[num_args], XtNlabel, "Forward"); num_args++;
679 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
680 XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
681 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
682 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
683 XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
684 XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdRight + R_OFFSET);
686 search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
687 form, args, num_args);
690 XtTranslations radio_translations;
692 radio_translations = XtParseTranslationTable(radio_trans_string);
693 XtOverrideTranslations(search->left_toggle, radio_translations);
694 XtOverrideTranslations(search->right_toggle, radio_translations);
698 if (XawTextFormat((TextWidget)tw, XawFmt8Bit)) {
700 XtSetArg(args[num_args], XtNlabel, "Case Sensitive"); num_args++;
701 XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
702 XtSetArg(args[num_args], XtNfromHoriz, search->right_toggle); num_args++;
703 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
704 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
705 XtSetArg(args[num_args], XtNstate, True); num_args++;
706 search->case_sensitive = XtCreateManagedWidget("case", toggleWidgetClass,
707 form, args, num_args);
710 search->case_sensitive = NULL;
714 XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
715 XtSetArg(args[num_args], XtNlabel, "Search for: "); num_args++;
716 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
717 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
718 XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
719 s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
723 XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
724 XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
725 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
726 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
727 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
728 XtSetArg(args[num_args], XtNresizable, True); num_args++;
729 XtSetArg(args[num_args], XtNstring, ptr); num_args++;
730 s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
732 search->search_text = s_text;
735 XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
736 XtSetArg(args[num_args], XtNlabel, "Replace with:"); num_args++;
737 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
738 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
739 XtSetArg(args[num_args], XtNborderWidth, 0); num_args++;
740 search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
741 form, args, num_args);
744 XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
745 XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
746 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
747 XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
748 XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
749 XtSetArg(args[num_args], XtNresizable, True); num_args++;
750 XtSetArg(args[num_args], XtNstring, ""); num_args++;
751 r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
752 form, args, num_args);
753 search->rep_text = r_text;
756 XtSetArg(args[num_args], XtNlabel, "Search"); num_args++;
757 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
758 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
759 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
760 search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
764 XtSetArg(args[num_args], XtNlabel, "Replace"); num_args++;
765 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
766 XtSetArg(args[num_args], XtNfromHoriz, search_button); num_args++;
767 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
768 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
769 search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
770 form, args, num_args);
773 XtSetArg(args[num_args], XtNlabel, "Replace All"); num_args++;
774 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
775 XtSetArg(args[num_args], XtNfromHoriz, search->rep_one); num_args++;
776 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
777 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
778 search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
779 form, args, num_args);
782 XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
783 XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
784 XtSetArg(args[num_args], XtNfromHoriz, search->rep_all); num_args++;
785 XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
786 XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
787 cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
790 XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer)search);
791 XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer)search);
792 XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer)search);
793 XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer)search);
796 * Initialize the text entry fields
802 XtSetArg(args[num_args], XtNbackground, &color); num_args++;
803 XtGetValues(search->rep_text, args, num_args);
805 XtSetArg(args[num_args], XtNborderColor, color); num_args++;
806 XtSetValues(search->rep_text, args, num_args);
807 XtSetKeyboardFocus(form, search->search_text);
810 SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
813 * Bind Extra translations
815 trans = XtParseTranslationTable(search_text_trans);
816 XtOverrideTranslations(search->search_text, trans);
818 trans = XtParseTranslationTable(rep_text_trans);
819 XtOverrideTranslations(search->rep_text, trans);
827 * search - search structure
837 DoSearch(struct SearchAndReplace *search)
840 Widget tw = XtParent(search->search_popup);
842 XawTextScanDirection dir;
844 TextWidget ctx = (TextWidget)tw;
847 text.ptr = GetStringRaw(search->search_text);
848 if ((text.format = _XawTextFormat(ctx)) == XawFmtWide)
849 text.length = wcslen((wchar_t*)text.ptr);
851 text.length = strlen(text.ptr);
854 if (search->case_sensitive) {
855 /* text.firstPos isn't useful here, so I'll use it as an
859 Boolean case_sensitive;
861 XtSetArg(args[0], XtNstate, &case_sensitive);
862 XtGetValues(search->case_sensitive, args, 1);
863 text.firstPos = !case_sensitive;
868 dir = (XawTextScanDirection)(unsigned long)
869 ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
871 pos = XawTextSearch(tw, dir, &text);
873 /* The Raw string in find.ptr may be WC I can't use here, so I re - call
874 GetString to get a tame version */
876 if (pos == XawTextSearchError) {
880 ptr = GetString(search->search_text);
882 (void)XmuSnprintf(msg, sizeof(msg), "%s", ptr);
884 ptr = strchr(msg, '\n');
885 if (ptr != NULL || sizeof(msg) - 1 < len) {
894 strcpy(msg + len - 4, "...");
896 XawTextUnsetSelection(tw);
897 SetSearchLabels(search, "Could not find string", msg, True);
901 XawTextDisableRedisplay(tw);
902 XawTextSetSelection(tw, pos, pos + text.length);
903 search->selection_changed = False; /* selection is good */
905 if (dir == XawsdRight)
906 XawTextSetInsertionPoint(tw, pos + text.length);
908 XawTextSetInsertionPoint(tw, pos);
909 _XawTextShowPosition(ctx);
910 XawTextEnableRedisplay(tw);
916 * This section of the file contains all the functions that
917 * the replace dialog box uses
921 * _XawTextDoReplaceAction
924 * Action routine that can be bound to dialog box's
925 * Text Widget that will replace a string in the main Text Widget.
929 _XawTextDoReplaceAction(Widget w, XEvent *event,
930 String *params, Cardinal *num_params)
932 TextWidget ctx = (TextWidget)XtParent(XtParent(XtParent(w)));
933 Bool popdown = False;
935 if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
938 if (Replace( ctx->text.search, True, popdown) && popdown)
939 PopdownSearch(w, (XtPointer)ctx->text.search, NULL);
947 * w - *** Not Used ***
948 * closure - a pointer to the search structure
949 * call_data - *** Not Used ***
952 * Replaces the first instance of the string in the search
953 * dialog's text widget with the one in the replace dialog's text widget.
957 DoReplaceOne(Widget w, XtPointer closure, XtPointer call_data)
959 Replace((struct SearchAndReplace *)closure, True, False);
968 * closure - pointer to the search structure
969 * call_data - (not used)
972 * Replaces every instance of the string in the search dialog's
973 * text widget with the one in the replace dialog's text widget.
977 DoReplaceAll(Widget w, XtPointer closure, XtPointer call_data)
979 Replace((struct SearchAndReplace *)closure, False, False);
987 * tw - Text Widget to replce the string in
988 * once_only - if True then only replace the first one found,
989 * else replace all of them
990 * show_current - if true then leave the selection on the
991 * string that was just replaced, otherwise
992 * move it onto the next one
995 * This is the function that does the real work of
996 * replacing strings in the main text widget.
999 Replace(struct SearchAndReplace *search, Bool once_only, Bool show_current)
1001 XawTextPosition pos, new_pos, end_pos, ipos;
1002 XawTextScanDirection dir;
1003 XawTextBlock find, replace;
1004 Widget tw = XtParent(search->search_popup);
1006 TextWidget ctx = (TextWidget)tw;
1009 find.ptr = GetStringRaw(search->search_text);
1010 if ((find.format = _XawTextFormat(ctx)) == XawFmtWide)
1011 find.length = (XawTextPosition)wcslen((wchar_t*)find.ptr);
1013 find.length = (XawTextPosition)strlen(find.ptr);
1016 replace.ptr = GetStringRaw(search->rep_text);
1017 replace.firstPos = 0;
1018 if ((replace.format = _XawTextFormat(ctx)) == XawFmtWide)
1019 replace.length = wcslen((wchar_t*)replace.ptr);
1021 replace.length = strlen(replace.ptr);
1023 dir = (XawTextScanDirection)(unsigned long)
1024 ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
1026 redisplay = !once_only || (once_only && !show_current);
1027 ipos = XawTextGetInsertionPoint(tw);
1029 XawTextDisableRedisplay(tw);
1033 new_pos = XawTextSearch(tw, dir, &find);
1035 if (new_pos == XawTextSearchError) {
1041 ptr = GetString(search->search_text);
1043 (void)XmuSnprintf(msg, sizeof(msg), "%s", ptr);
1044 ptr = strchr(msg, '\n');
1045 if (ptr != NULL || sizeof(msg) - 1 < len) {
1047 len = ptr - msg + 4;
1054 strcpy(msg + len - 4, "...");
1056 SetSearchLabels(search, "Could not find string", msg, True);
1059 XawTextSetInsertionPoint(tw, ipos);
1060 _XawTextShowPosition(ctx);
1061 XawTextEnableRedisplay(tw);
1070 end_pos = pos + find.length;
1073 XawTextGetSelectionPos(tw, &pos, &end_pos);
1075 if (search->selection_changed) {
1076 SetSearchLabels(search, "Selection modified, aborting.",
1079 XawTextSetInsertionPoint(tw, ipos);
1080 XawTextEnableRedisplay(tw);
1085 if (pos == end_pos) {
1087 XawTextSetInsertionPoint(tw, ipos);
1088 XawTextEnableRedisplay(tw);
1095 if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
1096 SetSearchLabels(search, "Error while replacing.", "", True);
1098 XawTextSetInsertionPoint(tw, ipos);
1099 XawTextEnableRedisplay(tw);
1105 if (dir == XawsdRight)
1106 ipos = pos + replace.length;
1115 XawTextEnableRedisplay(tw);
1121 ctx->text.insertPos = ipos;
1125 if (replace.length == 0)
1126 XawTextUnsetSelection(tw);
1128 XawTextSetSelection(tw, pos, pos + replace.length);
1130 XawTextSetInsertionPoint(tw, ipos);
1131 _XawTextShowPosition(ctx);
1132 XawTextEnableRedisplay(tw);
1142 * search - search structure
1143 * msg1 - message to put in each search label
1145 * bell - if True then ring bell
1148 * Sets both the search labels, and also rings the bell.
1151 SetSearchLabels(struct SearchAndReplace *search, String msg1, String msg2,
1154 (void)SetResource(search->label1, XtNlabel, (XtArgVal)msg1);
1155 (void)SetResource(search->label2, XtNlabel, (XtArgVal)msg2);
1157 XBell(XtDisplay(search->search_popup), 0);
1161 * This section of the file contains utility routines used by
1162 * other functions in this file
1169 * Action routine that can be bound to dialog box's
1170 * Text Widget that will send input to the field specified.
1174 _XawTextSetField(Widget w, XEvent *event, String *params, Cardinal *num_params)
1176 struct SearchAndReplace *search;
1179 search = ((TextWidget)XtParent(XtParent(XtParent(w))))->text.search;
1181 if (*num_params != 1) {
1182 SetSearchLabels(search, "Error: SetField Action must have",
1183 "exactly one argument", True);
1186 switch (params[0][0]) {
1189 cnew = search->search_text;
1190 old = search->rep_text;
1194 old = search->search_text;
1195 cnew = search->rep_text;
1198 SetSearchLabels(search,
1199 "Error: SetField Action's first Argument must",
1200 "be either 'Search' or 'Replace'", True);
1203 _SetField(cnew, old);
1211 * cnew - new and old text fields
1215 * Sets the current text field.
1218 _SetField(Widget cnew, Widget old)
1221 Pixel new_border, old_border, old_bg;
1223 if (!XtIsSensitive(cnew)) {
1224 XBell(XtDisplay(old), 0); /* Don't set field to an inactive Widget */
1228 XtSetKeyboardFocus(XtParent(cnew), cnew);
1230 XtSetArg(args[0], XtNborderColor, &old_border);
1231 XtSetArg(args[1], XtNbackground, &old_bg);
1232 XtGetValues(cnew, args, 2);
1234 XtSetArg(args[0], XtNborderColor, &new_border);
1235 XtGetValues(old, args, 1);
1237 if (old_border != old_bg) /* Colors are already correct, return */
1240 SetResource(old, XtNborderColor, (XtArgVal)old_border);
1241 SetResource(cnew, XtNborderColor, (XtArgVal)new_border);
1249 * shell - shell widget of the popup
1250 * name - name of the child
1251 * res_name - name of the resource
1252 * value - value of the resource
1255 * Sets a resource in any of the dialog children given
1256 * name of the child and the shell widget of the dialog.
1262 SetResourceByName(Widget shell, char *name, char *res_name, XtArgVal value)
1267 (void)XmuSnprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, name);
1269 if ((temp_widget = XtNameToWidget(shell, buf)) != NULL) {
1270 SetResource(temp_widget, res_name, value);
1282 * res_name - name of the resource
1283 * value - value of the resource
1286 * Sets a resource in a widget
1289 SetResource(Widget w, char *res_name, XtArgVal value)
1293 XtSetArg(args[0], res_name, value);
1294 XtSetValues( w, args, 1);
1302 * text - text widget whose string we will get
1305 * Gets the value for the string in the popup.
1308 * GetString: the string as a MB
1309 * GetStringRaw: the exact buffer contents suitable for a search
1312 GetString(Widget text)
1317 XtSetArg(args[0], XtNstring, &string);
1318 XtGetValues(text, args, 1);
1324 GetStringRaw(Widget tw)
1326 TextWidget ctx = (TextWidget)tw;
1327 XawTextPosition last;
1329 last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
1330 ctx->text.mult, True);
1331 return (_XawTextGetText(ctx, 0, last));
1336 * CenterWidgetOnPoint
1340 * event - event containing the location of the point
1343 * Centers a shell widget on a point relative to the root window.
1346 * The widget is not allowed to go off the screen
1349 CenterWidgetOnPoint(Widget w, XEvent *event)
1353 Dimension width, height, b_width;
1354 Position x, y, max_x, max_y;
1356 if (event != NULL) {
1357 switch (event->type) {
1360 x = event->xbutton.x_root;
1361 y = event->xbutton.y_root;
1365 x = event->xkey.x_root;
1366 y = event->xkey.y_root;
1376 XtSetArg(args[num_args], XtNwidth, &width); num_args++;
1377 XtSetArg(args[num_args], XtNheight, &height); num_args++;
1378 XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
1379 XtGetValues(w, args, num_args);
1381 width += b_width << 1;
1382 height += b_width << 1;
1384 x -= (Position)(width >> 1);
1387 if (x > (max_x = (Position)(XtScreen(w)->width - width)))
1390 y -= (Position)(height >> 1);
1393 if (y > (max_y = (Position)(XtScreen(w)->height - height)))
1397 XtSetArg(args[num_args], XtNx, x); num_args++;
1398 XtSetArg(args[num_args], XtNy, y); num_args++;
1399 XtSetValues(w, args, num_args);
1407 * parent - parent of the dialog - the main text widget
1408 * ptr - initial_string for the dialog
1409 * name - name of the dialog
1410 * func - function to create the children of the dialog
1413 * Popup shell of the dialog
1416 * The function argument is passed the following arguments:
1417 * form - from widget that is the dialog
1418 * ptr - initial string for the dialog's text widget
1419 * parent - parent of the dialog - the main text widget
1422 CreateDialog(Widget parent, String ptr, String name, AddFunc func)
1429 XtSetArg(args[num_args], XtNiconName, name); num_args++;
1430 XtSetArg(args[num_args], XtNgeometry, NULL); num_args++;
1431 XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
1432 XtSetArg(args[num_args], XtNtransientFor, GetShell(parent));num_args++;
1433 popup = XtCreatePopupShell(name, transientShellWidgetClass,
1434 parent, args, num_args);
1436 form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup, NULL, 0);
1437 XtManageChild (form);
1439 (*func)(form, ptr, parent);
1447 * nearest shell widget.
1450 * w - widget whose parent shell should be returned
1453 * The shell widget among the ancestors of w that is the
1454 * fewest levels up in the widget hierarchy.
1457 * Walks up the widget hierarchy to find the topmost shell widget.
1462 while (w != NULL && !XtIsShell(w))
1469 InParams(String str, String *p, unsigned int n)
1473 for (i = 0; i < n; p++, i++)
1474 if (!XmuCompareISOLatin1(*p, str))
1479 static char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
1482 WMProtocols(Widget w, XEvent *event, String *params, Cardinal *num_params)
1484 Atom wm_delete_window;
1487 wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
1488 wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
1490 /* Respond to a recognized WM protocol request if
1491 * event type is ClientMessage and no parameters are passed, or
1492 * event type is ClientMessage and event data is matched to parameters, or
1493 * event type isn't ClientMessage and parameters make a request
1495 #define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
1497 if ((event->type == ClientMessage
1498 && event->xclient.message_type == wm_protocols
1499 && event->xclient.data.l[0] == wm_delete_window
1500 && (*num_params == 0 || DO_DELETE_WINDOW))
1501 || (event->type != ClientMessage && DO_DELETE_WINDOW)) {
1502 #undef DO_DELETE_WINDOW
1504 char descendant[DISMISS_NAME_LEN + 2];
1506 (void)XmuSnprintf(descendant, sizeof(descendant), "*%s", DISMISS_NAME);
1507 cancel = XtNameToWidget(w, descendant);
1509 XtCallCallbacks(cancel, XtNcallback, NULL);
1514 SetWMProtocolTranslations(Widget w)
1516 static XtTranslations compiled_table;
1517 static XtAppContext *app_context_list;
1518 static Cardinal list_size;
1521 XtAppContext app_context;
1522 Atom wm_delete_window;
1524 app_context = XtWidgetToApplicationContext(w);
1526 /* parse translation table once */
1527 if (!compiled_table)
1529 XtParseTranslationTable("<Message>WM_PROTOCOLS:XawWMProtocols()\n");
1531 /* add actions once per application context */
1532 for (i = 0; i < list_size && app_context_list[i] != app_context; i++)
1534 if (i == list_size) {
1535 XtActionsRec actions[1];
1537 actions[0].string = "XawWMProtocols";
1538 actions[0].proc = WMProtocols;
1540 app_context_list = (XtAppContext *)XtRealloc
1541 ((char *)app_context_list, list_size * sizeof(XtAppContext));
1542 XtAppAddActions(app_context, actions, 1);
1543 app_context_list[i] = app_context;
1546 /* establish communication between the window manager and each shell */
1547 XtAugmentTranslations(w, compiled_table);
1548 wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
1549 (void)XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);