TextPop.c revision 7a84e134
17a84e134Smrg/* $Xorg: TextPop.c,v 1.4 2001/02/09 02:03:46 xorgcvs Exp $ */
27a84e134Smrg
37a84e134Smrg/*
47a84e134Smrg
57a84e134SmrgCopyright 1989, 1994, 1998  The Open Group
67a84e134Smrg
77a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its
87a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that
97a84e134Smrgthe above copyright notice appear in all copies and that both that
107a84e134Smrgcopyright notice and this permission notice appear in supporting
117a84e134Smrgdocumentation.
127a84e134Smrg
137a84e134SmrgThe above copyright notice and this permission notice shall be included in
147a84e134Smrgall copies or substantial portions of the Software.
157a84e134Smrg
167a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
197a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
207a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
217a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
227a84e134Smrg
237a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be
247a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings
257a84e134Smrgin this Software without prior written authorization from The Open Group.
267a84e134Smrg
277a84e134Smrg*/
287a84e134Smrg
297a84e134Smrg/* $XFree86: xc/lib/Xaw/TextPop.c,v 1.20tsi Exp $ */
307a84e134Smrg
317a84e134Smrg/*
327a84e134Smrg * This file is broken up into three sections one dealing with
337a84e134Smrg * each of the three popups created here:
347a84e134Smrg *
357a84e134Smrg * FileInsert, Search, and Replace.
367a84e134Smrg *
377a84e134Smrg * There is also a section at the end for utility functions
387a84e134Smrg * used by all more than one of these dialogs.
397a84e134Smrg *
407a84e134Smrg * The following functions are the only non-static ones defined
417a84e134Smrg * in this module.  They are located at the begining of the
427a84e134Smrg * section that contains this dialog box that uses them.
437a84e134Smrg *
447a84e134Smrg * void _XawTextInsertFileAction(w, event, params, num_params);
457a84e134Smrg * void _XawTextDoSearchAction(w, event, params, num_params);
467a84e134Smrg * void _XawTextDoReplaceAction(w, event, params, num_params);
477a84e134Smrg * void _XawTextInsertFile(w, event, params, num_params);
487a84e134Smrg */
497a84e134Smrg
507a84e134Smrg#ifdef HAVE_CONFIG_H
517a84e134Smrg#include <config.h>
527a84e134Smrg#endif
537a84e134Smrg#include <stdio.h>
547a84e134Smrg#include <errno.h>
557a84e134Smrg#include <X11/IntrinsicP.h>
567a84e134Smrg#include <X11/StringDefs.h>
577a84e134Smrg#include <X11/Shell.h>
587a84e134Smrg#include <X11/Xos.h>
597a84e134Smrg#include <X11/Xmu/CharSet.h>
607a84e134Smrg#include <X11/Xmu/SysUtil.h>
617a84e134Smrg#include <X11/Xaw/TextP.h>
627a84e134Smrg#include <X11/Xaw/AsciiText.h>
637a84e134Smrg#include <X11/Xaw/Cardinals.h>
647a84e134Smrg#include <X11/Xaw/Command.h>
657a84e134Smrg#include <X11/Xaw/Form.h>
667a84e134Smrg#include <X11/Xaw/Toggle.h>
677a84e134Smrg#include "XawI18n.h"
687a84e134Smrg
697a84e134Smrgstatic char* INSERT_FILE = "Enter Filename:";
707a84e134Smrgstatic char* SEARCH_LABEL_1 = "Use <Tab> to change fields.";
717a84e134Smrgstatic char* SEARCH_LABEL_2 = "Use ^q<Tab> for <Tab>.";
727a84e134Smrgstatic char* DISMISS_NAME = "cancel";
737a84e134Smrg#define DISMISS_NAME_LEN 6
747a84e134Smrgstatic char* FORM_NAME = "form";
757a84e134Smrgstatic char* LABEL_NAME = "label";
767a84e134Smrgstatic char* TEXT_NAME = "text";
777a84e134Smrg
787a84e134Smrg#define R_OFFSET      1
797a84e134Smrg
807a84e134Smrgtypedef void (*AddFunc)(Widget, char*, Widget);
817a84e134Smrg
827a84e134Smrg/*
837a84e134Smrg * Prototypes
847a84e134Smrg */
857a84e134Smrgstatic void _SetField(Widget, Widget);
867a84e134Smrgstatic void AddSearchChildren(Widget, char*, Widget);
877a84e134Smrgstatic void AddInsertFileChildren(Widget, char*, Widget);
887a84e134Smrgstatic void CenterWidgetOnPoint(Widget, XEvent*);
897a84e134Smrgstatic Widget CreateDialog(Widget, String, String, AddFunc);
907a84e134Smrgstatic void DoInsert(Widget, XtPointer, XtPointer);
917a84e134Smrgstatic void DoReplaceAll(Widget, XtPointer, XtPointer);
927a84e134Smrgstatic void DoReplaceOne(Widget, XtPointer, XtPointer);
937a84e134Smrgstatic Bool DoSearch(struct SearchAndReplace*);
947a84e134Smrgstatic Widget GetShell(Widget);
957a84e134Smrgstatic String GetString(Widget);
967a84e134Smrgstatic String GetStringRaw(Widget);
977a84e134Smrgstatic void InitializeSearchWidget(struct SearchAndReplace*,
987a84e134Smrg				   XawTextScanDirection, Bool);
997a84e134Smrgstatic Bool InParams(String, String*, unsigned int);
1007a84e134Smrgstatic Bool InsertFileNamed(Widget, char*);
1017a84e134Smrgstatic void PopdownFileInsert(Widget, XtPointer, XtPointer);
1027a84e134Smrgstatic void PopdownSearch(Widget, XtPointer, XtPointer);
1037a84e134Smrgstatic Bool Replace(struct SearchAndReplace*, Bool, Bool);
1047a84e134Smrgstatic void SearchButton(Widget, XtPointer, XtPointer);
1057a84e134Smrgstatic void SetResource(Widget, char*, XtArgVal);
1067a84e134Smrgstatic Bool SetResourceByName(Widget, char*, char*, XtArgVal);
1077a84e134Smrgstatic void SetSearchLabels(struct SearchAndReplace*, String, String, Bool);
1087a84e134Smrgstatic void SetWMProtocolTranslations(Widget);
1097a84e134Smrg
1107a84e134Smrg/*
1117a84e134Smrg * Actions
1127a84e134Smrg */
1137a84e134Smrgstatic void WMProtocols(Widget, XEvent*, String*, Cardinal*);
1147a84e134Smrg
1157a84e134Smrg/*
1167a84e134Smrg * External Actions
1177a84e134Smrg */
1187a84e134Smrgvoid _XawTextDoReplaceAction(Widget, XEvent*, String*, Cardinal*);
1197a84e134Smrgvoid _XawTextDoSearchAction(Widget, XEvent*, String*, Cardinal*);
1207a84e134Smrgvoid _XawTextInsertFile(Widget, XEvent*, String*, Cardinal*);
1217a84e134Smrgvoid _XawTextInsertFileAction(Widget, XEvent*, String*, Cardinal*);
1227a84e134Smrgvoid _XawTextPopdownSearchAction(Widget, XEvent*, String*, Cardinal*);
1237a84e134Smrgvoid _XawTextSearch(Widget, XEvent*, String*, Cardinal*);
1247a84e134Smrgvoid _XawTextSetField(Widget, XEvent*, String*, Cardinal*);
1257a84e134Smrg
1267a84e134Smrg/*
1277a84e134Smrg * From Text.c
1287a84e134Smrg */
1297a84e134Smrgchar *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
1307a84e134Smrgvoid _XawTextShowPosition(TextWidget);
1317a84e134Smrg
1327a84e134Smrg/*
1337a84e134Smrg * Initialization
1347a84e134Smrg */
1357a84e134Smrgstatic char radio_trans_string[] =
1367a84e134Smrg"<Btn1Down>,<Btn1Up>:"	"set() notify()\n"
1377a84e134Smrg;
1387a84e134Smrg
1397a84e134Smrgstatic char search_text_trans[] =
1407a84e134Smrg"~s<Key>Return:"	"DoSearchAction(Popdown)\n"
1417a84e134Smrg"s<Key>Return:"		"DoSearchAction() SetField(Replace)\n"
1427a84e134Smrg"c<Key>c:"		"PopdownSearchAction()\n"
1437a84e134Smrg"<Btn1Down>:"		"select-start() SetField(Search)\n"
1447a84e134Smrg"<Key>Tab:"		"DoSearchAction() SetField(Replace)\n"
1457a84e134Smrg;
1467a84e134Smrg
1477a84e134Smrgstatic char rep_text_trans[] =
1487a84e134Smrg"~s<Key>Return:"	"DoReplaceAction(Popdown)\n"
1497a84e134Smrg"s<Key>Return:"		"SetField(Search)\n"
1507a84e134Smrg"c<Key>c:"		"PopdownSearchAction()\n"
1517a84e134Smrg"<Btn1Down>:"		"select-start() DoSearchAction() SetField(Replace)\n"
1527a84e134Smrg"<Key>Tab:"		"SetField(Search)\n"
1537a84e134Smrg;
1547a84e134Smrg
1557a84e134Smrg/*
1567a84e134Smrg * Implementation
1577a84e134Smrg */
1587a84e134Smrg/*
1597a84e134Smrg * This section of the file contains all the functions that
1607a84e134Smrg * the file insert dialog box uses
1617a84e134Smrg */
1627a84e134Smrg
1637a84e134Smrg/*
1647a84e134Smrg * Function:
1657a84e134Smrg *	_XawTextInsertFileAction
1667a84e134Smrg *
1677a84e134Smrg * Description:
1687a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget
1697a84e134Smrg *	that will insert a file into the main Text Widget.
1707a84e134Smrg */
1717a84e134Smrg/*ARGSUSED*/
1727a84e134Smrgvoid
1737a84e134Smrg_XawTextInsertFileAction(Widget w, XEvent *event,
1747a84e134Smrg			 String *params, Cardinal *num_params)
1757a84e134Smrg{
1767a84e134Smrg    DoInsert(w, (XtPointer)XtParent(XtParent(XtParent(w))), NULL);
1777a84e134Smrg}
1787a84e134Smrg
1797a84e134Smrg/*
1807a84e134Smrg * Function:
1817a84e134Smrg *	_XawTextInsertFile
1827a84e134Smrg *
1837a84e134Smrg * Parameters:
1847a84e134Smrg *	w	   - text widget
1857a84e134Smrg *	event	   - X Event (used to get x and y location)
1867a84e134Smrg *	params	   - parameter list
1877a84e134Smrg *	num_params - ""
1887a84e134Smrg *
1897a84e134Smrg * Description:
1907a84e134Smrg *	  Action routine that can be bound to the text widget
1917a84e134Smrg *	it will popup the insert file dialog box.
1927a84e134Smrg *
1937a84e134Smrg * Note:
1947a84e134Smrg *	The parameter list may contain one entry
1957a84e134Smrg *
1967a84e134Smrg *  Entry:
1977a84e134Smrg *	  This entry is optional and contains the value of the default
1987a84e134Smrg *	file to insert
1997a84e134Smrg */
2007a84e134Smrgvoid
2017a84e134Smrg_XawTextInsertFile(Widget w, XEvent *event,
2027a84e134Smrg		   String *params, Cardinal *num_params)
2037a84e134Smrg{
2047a84e134Smrg    TextWidget ctx = (TextWidget)w;
2057a84e134Smrg    char *ptr;
2067a84e134Smrg    XawTextEditType edit_mode;
2077a84e134Smrg    Arg args[1];
2087a84e134Smrg
2097a84e134Smrg    XtSetArg(args[0], XtNeditType, &edit_mode);
2107a84e134Smrg    XtGetValues(ctx->text.source, args, 1);
2117a84e134Smrg
2127a84e134Smrg    if (edit_mode != XawtextEdit) {
2137a84e134Smrg	XBell(XtDisplay(w), 0);
2147a84e134Smrg	return;
2157a84e134Smrg    }
2167a84e134Smrg
2177a84e134Smrg    if (*num_params == 0)
2187a84e134Smrg	ptr = "";
2197a84e134Smrg    else
2207a84e134Smrg	ptr = params[0];
2217a84e134Smrg
2227a84e134Smrg    if (!ctx->text.file_insert) {
2237a84e134Smrg	ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
2247a84e134Smrg					     AddInsertFileChildren);
2257a84e134Smrg	XtRealizeWidget(ctx->text.file_insert);
2267a84e134Smrg	SetWMProtocolTranslations(ctx->text.file_insert);
2277a84e134Smrg    }
2287a84e134Smrg
2297a84e134Smrg    CenterWidgetOnPoint(ctx->text.file_insert, event);
2307a84e134Smrg    XtPopup(ctx->text.file_insert, XtGrabNone);
2317a84e134Smrg}
2327a84e134Smrg
2337a84e134Smrg/*
2347a84e134Smrg * Function:
2357a84e134Smrg *	PopdownFileInsert
2367a84e134Smrg *
2377a84e134Smrg * Parameters:
2387a84e134Smrg *	w	  - widget that caused this action
2397a84e134Smrg *	closure	  - pointer to the main text widget that popped up this dialog
2407a84e134Smrg *	call_data - (not used)
2417a84e134Smrg *
2427a84e134Smrg * Description:
2437a84e134Smrg *	Pops down the file insert button
2447a84e134Smrg */
2457a84e134Smrg/*ARGSUSED*/
2467a84e134Smrgstatic void
2477a84e134SmrgPopdownFileInsert(Widget w, XtPointer closure, XtPointer call_data)
2487a84e134Smrg{
2497a84e134Smrg    TextWidget ctx = (TextWidget)closure;
2507a84e134Smrg
2517a84e134Smrg    XtPopdown(ctx->text.file_insert);
2527a84e134Smrg    (void)SetResourceByName(ctx->text.file_insert, LABEL_NAME,
2537a84e134Smrg			    XtNlabel, (XtArgVal)INSERT_FILE);
2547a84e134Smrg}
2557a84e134Smrg
2567a84e134Smrg/*
2577a84e134Smrg * Function:
2587a84e134Smrg *	DoInsert
2597a84e134Smrg *
2607a84e134Smrg * Parameters:
2617a84e134Smrg *	w	- widget that activated this callback
2627a84e134Smrg *	closure - pointer to the text widget to insert the file into
2637a84e134Smrg *
2647a84e134Smrg * Description:
2657a84e134Smrg *	Actually insert the file named in the text widget of the file dialog
2667a84e134Smrg */
2677a84e134Smrg/*ARGSUSED*/
2687a84e134Smrgstatic void
2697a84e134SmrgDoInsert(Widget w, XtPointer closure, XtPointer call_data)
2707a84e134Smrg{
2717a84e134Smrg    TextWidget ctx = (TextWidget)closure;
2727a84e134Smrg    char buf[BUFSIZ], msg[BUFSIZ];
2737a84e134Smrg    Widget temp_widget;
2747a84e134Smrg
2757a84e134Smrg    (void)XmuSnprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, TEXT_NAME);
2767a84e134Smrg    if ((temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL) {
2777a84e134Smrg	(void)strcpy(msg,
2787a84e134Smrg		     "Error: Could not get text widget from file insert popup");
2797a84e134Smrg    }
2807a84e134Smrg    else if (InsertFileNamed((Widget)ctx, GetString(temp_widget))) {
2817a84e134Smrg	PopdownFileInsert(w, closure, call_data);
2827a84e134Smrg	return;
2837a84e134Smrg    }
2847a84e134Smrg    else
2857a84e134Smrg	(void)XmuSnprintf(msg, sizeof(msg), "Error: %s", strerror(errno));
2867a84e134Smrg
2877a84e134Smrg    (void)SetResourceByName(ctx->text.file_insert,
2887a84e134Smrg			    LABEL_NAME, XtNlabel, (XtArgVal)msg);
2897a84e134Smrg    XBell(XtDisplay(w), 0);
2907a84e134Smrg}
2917a84e134Smrg
2927a84e134Smrg/*
2937a84e134Smrg * Function:
2947a84e134Smrg *	InsertFileNamed
2957a84e134Smrg *
2967a84e134Smrg * Parameters:
2977a84e134Smrg *	tw  - text widget to insert this file into
2987a84e134Smrg *	str - name of the file to insert
2997a84e134Smrg *
3007a84e134Smrg * Description:
3017a84e134Smrg *	Inserts a file into the text widget.
3027a84e134Smrg *
3037a84e134Smrg * Returns:
3047a84e134Smrg *	True if the insert was sucessful, False otherwise.
3057a84e134Smrg */
3067a84e134Smrgstatic Bool
3077a84e134SmrgInsertFileNamed(Widget tw, char *str)
3087a84e134Smrg{
3097a84e134Smrg    FILE *file;
3107a84e134Smrg    XawTextBlock text;
3117a84e134Smrg    XawTextPosition pos;
3127a84e134Smrg
3137a84e134Smrg    if (str == NULL || strlen(str) == 0 || (file = fopen(str, "r")) == NULL)
3147a84e134Smrg	return (False);
3157a84e134Smrg
3167a84e134Smrg    pos = XawTextGetInsertionPoint(tw);
3177a84e134Smrg
3187a84e134Smrg    fseek(file, 0L, 2);
3197a84e134Smrg
3207a84e134Smrg    text.firstPos = 0;
3217a84e134Smrg    text.length = ftell(file);
3227a84e134Smrg    text.ptr = XtMalloc(text.length + 1);
3237a84e134Smrg    text.format = XawFmt8Bit;
3247a84e134Smrg
3257a84e134Smrg    fseek(file, 0L, 0);
3267a84e134Smrg    if (fread(text.ptr, 1, text.length, file) != text.length)
3277a84e134Smrg	XtErrorMsg("readError", "insertFileNamed", "XawError",
3287a84e134Smrg		   "fread returned error", NULL, NULL);
3297a84e134Smrg
3307a84e134Smrg    if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
3317a84e134Smrg	XtFree(text.ptr);
3327a84e134Smrg	fclose(file);
3337a84e134Smrg	return (False);
3347a84e134Smrg    }
3357a84e134Smrg    pos += text.length;
3367a84e134Smrg    XtFree(text.ptr);
3377a84e134Smrg    fclose(file);
3387a84e134Smrg    XawTextSetInsertionPoint(tw, pos);
3397a84e134Smrg    _XawTextShowPosition((TextWidget)tw);
3407a84e134Smrg
3417a84e134Smrg    return (True);
3427a84e134Smrg}
3437a84e134Smrg
3447a84e134Smrg/*
3457a84e134Smrg * Function:
3467a84e134Smrg *	AddInsertFileChildren
3477a84e134Smrg *
3487a84e134Smrg * Parameters:
3497a84e134Smrg *	form - form widget for the insert dialog widget
3507a84e134Smrg *	ptr  - pointer to the initial string for the Text Widget
3517a84e134Smrg *	tw   - main text widget
3527a84e134Smrg *
3537a84e134Smrg * Description:
3547a84e134Smrg *	Adds all children to the InsertFile dialog widget.
3557a84e134Smrg */
3567a84e134Smrgstatic void
3577a84e134SmrgAddInsertFileChildren(Widget form, char *ptr, Widget tw)
3587a84e134Smrg{
3597a84e134Smrg    Arg args[10];
3607a84e134Smrg    Cardinal num_args;
3617a84e134Smrg    Widget label, text, cancel, insert;
3627a84e134Smrg    XtTranslations trans;
3637a84e134Smrg
3647a84e134Smrg    num_args = 0;
3657a84e134Smrg    XtSetArg(args[num_args], XtNlabel, INSERT_FILE);	num_args++;
3667a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3677a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3687a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
3697a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	num_args++;
3707a84e134Smrg    label = XtCreateManagedWidget(LABEL_NAME, labelWidgetClass, form,
3717a84e134Smrg				  args, num_args);
3727a84e134Smrg
3737a84e134Smrg    num_args = 0;
3747a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, label);	num_args++;
3757a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3767a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);	num_args++;
3777a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);	num_args++;
3787a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
3797a84e134Smrg    XtSetArg(args[num_args], XtNstring, ptr);		num_args++;
3807a84e134Smrg    text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
3817a84e134Smrg				 args, num_args);
3827a84e134Smrg
3837a84e134Smrg    num_args = 0;
3847a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Insert File");	num_args++;
3857a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, text);	num_args++;
3867a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3877a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3887a84e134Smrg    insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
3897a84e134Smrg				   args, num_args);
3907a84e134Smrg
3917a84e134Smrg    num_args = 0;
3927a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Cancel");	num_args++;
3937a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, text);	num_args++;
3947a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, insert);	num_args++;
3957a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
3967a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
3977a84e134Smrg    cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
3987a84e134Smrg				   args, num_args);
3997a84e134Smrg
4007a84e134Smrg    XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer)tw);
4017a84e134Smrg    XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer)tw);
4027a84e134Smrg
4037a84e134Smrg    XtSetKeyboardFocus(form, text);
4047a84e134Smrg
4057a84e134Smrg    /*
4067a84e134Smrg     * Bind <CR> to insert file
4077a84e134Smrg     */
4087a84e134Smrg    trans = XtParseTranslationTable("<Key>Return:InsertFileAction()");
4097a84e134Smrg    XtOverrideTranslations(text, trans);
4107a84e134Smrg}
4117a84e134Smrg
4127a84e134Smrg/*
4137a84e134Smrg * This section of the file contains all the functions that
4147a84e134Smrg * the search dialog box uses
4157a84e134Smrg */
4167a84e134Smrg/*
4177a84e134Smrg * Function:
4187a84e134Smrg *	_XawTextDoSearchAction
4197a84e134Smrg *
4207a84e134Smrg * Description:
4217a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget that
4227a84e134Smrg *	will search for a string in the main Text Widget.
4237a84e134Smrg *
4247a84e134Smrg * Note:
4257a84e134Smrg * If the search was sucessful and the argument popdown is passed to
4267a84e134Smrg * this action routine then the widget will automatically popdown the
4277a84e134Smrg *	search widget
4287a84e134Smrg */
4297a84e134Smrg/*ARGSUSED*/
4307a84e134Smrgvoid
4317a84e134Smrg_XawTextDoSearchAction(Widget w, XEvent *event,
4327a84e134Smrg		       String *params, Cardinal *num_params)
4337a84e134Smrg{
4347a84e134Smrg    TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
4357a84e134Smrg    Bool popdown = False;
4367a84e134Smrg
4377a84e134Smrg    if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
4387a84e134Smrg	popdown = True;
4397a84e134Smrg
4407a84e134Smrg    if (DoSearch(tw->text.search) && popdown)
4417a84e134Smrg	PopdownSearch(w, (XtPointer)tw->text.search, NULL);
4427a84e134Smrg}
4437a84e134Smrg
4447a84e134Smrg/*
4457a84e134Smrg * Function:
4467a84e134Smrg *	_XawTextPopdownSearchAction
4477a84e134Smrg *
4487a84e134Smrg * Description:
4497a84e134Smrg *	  Action routine that can be bound to dialog box's Text Widget that
4507a84e134Smrg *	will popdown the search widget.
4517a84e134Smrg */
4527a84e134Smrg/*ARGSUSED*/
4537a84e134Smrgvoid
4547a84e134Smrg_XawTextPopdownSearchAction(Widget w, XEvent *event,
4557a84e134Smrg			    String *params, Cardinal *num_params)
4567a84e134Smrg{
4577a84e134Smrg    TextWidget tw = (TextWidget)XtParent(XtParent(XtParent(w)));
4587a84e134Smrg
4597a84e134Smrg    PopdownSearch(w, (XtPointer)tw->text.search, NULL);
4607a84e134Smrg}
4617a84e134Smrg
4627a84e134Smrg/*
4637a84e134Smrg * Function:
4647a84e134Smrg *	PopdownSearch
4657a84e134Smrg *
4667a84e134Smrg * Parameters:
4677a84e134Smrg *	w	  - (not used)
4687a84e134Smrg *	closure	  - pointer to the search structure
4697a84e134Smrg *	call_data - (not used)
4707a84e134Smrg *
4717a84e134Smrg * Description:
4727a84e134Smrg *	Pops down the search widget and resets it
4737a84e134Smrg */
4747a84e134Smrg/*ARGSUSED*/
4757a84e134Smrgstatic void
4767a84e134SmrgPopdownSearch(Widget w, XtPointer closure, XtPointer call_data)
4777a84e134Smrg{
4787a84e134Smrg    struct SearchAndReplace *search = (struct SearchAndReplace *)closure;
4797a84e134Smrg
4807a84e134Smrg    XtPopdown(search->search_popup);
4817a84e134Smrg    SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
4827a84e134Smrg}
4837a84e134Smrg
4847a84e134Smrg/*
4857a84e134Smrg * Function:
4867a84e134Smrg *	SearchButton
4877a84e134Smrg *
4887a84e134Smrg * Arguments:
4897a84e134Smrg *	w	  - (not used)
4907a84e134Smrg *	closure	  - pointer to the search info
4917a84e134Smrg *	call_data - (not used)
4927a84e134Smrg *
4937a84e134Smrg * Description:
4947a84e134Smrg *	Performs a search when the button is clicked.
4957a84e134Smrg */
4967a84e134Smrg/*ARGSUSED*/
4977a84e134Smrgstatic void
4987a84e134SmrgSearchButton(Widget w, XtPointer closure, XtPointer call_data)
4997a84e134Smrg{
5007a84e134Smrg    (void)DoSearch((struct SearchAndReplace *)closure);
5017a84e134Smrg}
5027a84e134Smrg
5037a84e134Smrg/*
5047a84e134Smrg * Function:
5057a84e134Smrg *	_XawTextSearch
5067a84e134Smrg *
5077a84e134Smrg * Parameters:
5087a84e134Smrg *	w	   - text widget
5097a84e134Smrg *	event	   - X Event (used to get x and y location)
5107a84e134Smrg *	params	   - parameter list
5117a84e134Smrg *	num_params - ""
5127a84e134Smrg *
5137a84e134Smrg * Description:
5147a84e134Smrg *	  Action routine that can be bound to the text widget
5157a84e134Smrg *	it will popup the search dialog box.
5167a84e134Smrg *
5177a84e134Smrg * Note:
5187a84e134Smrg *	  The parameter list contains one or two entries that may be
5197a84e134Smrg *	the following.
5207a84e134Smrg *
5217a84e134Smrg * First Entry:
5227a84e134Smrg *	  The first entry is the direction to search by default.
5237a84e134Smrg *	This arguement must be specified and may have a value of
5247a84e134Smrg *	"left" or "right".
5257a84e134Smrg *
5267a84e134Smrg * Second Entry:
5277a84e134Smrg *	  This entry is optional and contains the value of the default
5287a84e134Smrg *	string to search for.
5297a84e134Smrg */
5307a84e134Smrg
5317a84e134Smrg#define SEARCH_HEADER	"Text Widget - Search():"
5327a84e134Smrgvoid
5337a84e134Smrg_XawTextSearch(Widget w, XEvent *event, String *params, Cardinal *num_params)
5347a84e134Smrg{
5357a84e134Smrg    TextWidget ctx = (TextWidget)w;
5367a84e134Smrg    XawTextScanDirection dir;
5377a84e134Smrg    char *ptr, buf[BUFSIZ];
5387a84e134Smrg    XawTextEditType edit_mode;
5397a84e134Smrg    Arg args[1];
5407a84e134Smrg    wchar_t wcs[1];
5417a84e134Smrg
5427a84e134Smrg    if (*num_params < 1 || *num_params > 2) {
5437a84e134Smrg	(void)XmuSnprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
5447a84e134Smrg			  "This action must have only",
5457a84e134Smrg			  "one or two parameters");
5467a84e134Smrg	XtAppWarning(XtWidgetToApplicationContext(w), buf);
5477a84e134Smrg	return;
5487a84e134Smrg    }
5497a84e134Smrg
5507a84e134Smrg    if (*num_params == 2)
5517a84e134Smrg	ptr = params[1];
5527a84e134Smrg    else if (XawTextFormat(ctx, XawFmtWide)) {
5537a84e134Smrg	/* This just does the equivalent of
5547a84e134Smrg	   ptr = ""L, a waste because params[1] isnt W aligned */
5557a84e134Smrg	ptr = (char *)wcs;
5567a84e134Smrg	wcs[0] = 0;
5577a84e134Smrg    }
5587a84e134Smrg    else
5597a84e134Smrg	ptr = "";
5607a84e134Smrg
5617a84e134Smrg    switch(params[0][0]) {
5627a84e134Smrg	case 'b': 		  /* Left */
5637a84e134Smrg	case 'B':
5647a84e134Smrg	    dir = XawsdLeft;
5657a84e134Smrg	    break;
5667a84e134Smrg	case 'f': 		  /* Right */
5677a84e134Smrg	case 'F':
5687a84e134Smrg	    dir = XawsdRight;
5697a84e134Smrg	    break;
5707a84e134Smrg	default:
5717a84e134Smrg	    (void)XmuSnprintf(buf, sizeof(buf), "%s %s\n%s", SEARCH_HEADER,
5727a84e134Smrg			      "The first parameter must be",
5737a84e134Smrg			      "Either 'backward' or 'forward'");
5747a84e134Smrg	    XtAppWarning(XtWidgetToApplicationContext(w), buf);
5757a84e134Smrg	    return;
5767a84e134Smrg    }
5777a84e134Smrg
5787a84e134Smrg    if (ctx->text.search== NULL) {
5797a84e134Smrg	ctx->text.search = XtNew(struct SearchAndReplace);
5807a84e134Smrg	ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
5817a84e134Smrg						      AddSearchChildren);
5827a84e134Smrg	XtRealizeWidget(ctx->text.search->search_popup);
5837a84e134Smrg	SetWMProtocolTranslations(ctx->text.search->search_popup);
5847a84e134Smrg    }
5857a84e134Smrg    else if (*num_params > 1)
5867a84e134Smrg	XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
5877a84e134Smrg
5887a84e134Smrg    XtSetArg(args[0], XtNeditType,&edit_mode);
5897a84e134Smrg    XtGetValues(ctx->text.source, args, 1);
5907a84e134Smrg
5917a84e134Smrg    InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
5927a84e134Smrg
5937a84e134Smrg    CenterWidgetOnPoint(ctx->text.search->search_popup, event);
5947a84e134Smrg    XtPopup(ctx->text.search->search_popup, XtGrabNone);
5957a84e134Smrg}
5967a84e134Smrg
5977a84e134Smrg/*
5987a84e134Smrg * Function:
5997a84e134Smrg *	InitializeSearchWidget
6007a84e134Smrg *
6017a84e134Smrg * Parameters:
6027a84e134Smrg *	search	       - search widget structure
6037a84e134Smrg *	dir	       - direction to search
6047a84e134Smrg *	replace_active - state of the sensitivity for the replace button
6057a84e134Smrg *
6067a84e134Smrg * Description:
6077a84e134Smrg *	  This function initializes the search widget and
6087a84e134Smrg *		   is called each time the search widget is poped up.
6097a84e134Smrg */
6107a84e134Smrgstatic void
6117a84e134SmrgInitializeSearchWidget(struct SearchAndReplace *search,
6127a84e134Smrg		       XawTextScanDirection dir, Bool replace_active)
6137a84e134Smrg{
6147a84e134Smrg    SetResource(search->rep_one, XtNsensitive, (XtArgVal)replace_active);
6157a84e134Smrg    SetResource(search->rep_all, XtNsensitive, (XtArgVal)replace_active);
6167a84e134Smrg    SetResource(search->rep_label, XtNsensitive, (XtArgVal)replace_active);
6177a84e134Smrg    SetResource(search->rep_text, XtNsensitive, (XtArgVal)replace_active);
6187a84e134Smrg
6197a84e134Smrg    switch (dir) {
6207a84e134Smrg	case XawsdLeft:
6217a84e134Smrg	    SetResource(search->left_toggle, XtNstate, (XtArgVal)True);
6227a84e134Smrg	    break;
6237a84e134Smrg	case XawsdRight:
6247a84e134Smrg	    SetResource(search->right_toggle, XtNstate, (XtArgVal)True);
6257a84e134Smrg	    break;
6267a84e134Smrg    }
6277a84e134Smrg}
6287a84e134Smrg
6297a84e134Smrg/*
6307a84e134Smrg * Function:
6317a84e134Smrg *	AddSearchChildren
6327a84e134Smrg *
6337a84e134Smrg * Parameters:
6347a84e134Smrg *	form - form widget for the search widget
6357a84e134Smrg *	ptr  - pointer to the initial string for the Text Widget
6367a84e134Smrg *	tw   - main text widget
6377a84e134Smrg *
6387a84e134Smrg * Description:
6397a84e134Smrg *	Adds all children to the Search Dialog Widget.
6407a84e134Smrg */
6417a84e134Smrgstatic void
6427a84e134SmrgAddSearchChildren(Widget form, char *ptr, Widget tw)
6437a84e134Smrg{
6447a84e134Smrg    Arg args[10];
6457a84e134Smrg    Cardinal num_args;
6467a84e134Smrg    Widget cancel, search_button, s_label, s_text, r_text;
6477a84e134Smrg    XtTranslations trans;
6487a84e134Smrg    struct SearchAndReplace *search = ((TextWidget)tw)->text.search;
6497a84e134Smrg
6507a84e134Smrg    num_args = 0;
6517a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	num_args++;
6527a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
6537a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	num_args++;
6547a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	num_args++;
6557a84e134Smrg    search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
6567a84e134Smrg					   args, num_args);
6577a84e134Smrg
6587a84e134Smrg    num_args = 0;
6597a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
6607a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6617a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6627a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);	   num_args++;
6637a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);	   num_args++;
6647a84e134Smrg    search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
6657a84e134Smrg					   args, num_args);
6667a84e134Smrg
6677a84e134Smrg    /*
6687a84e134Smrg     * We need to add R_OFFSET to the radio_data, because the value zero (0)
6697a84e134Smrg     * has special meaning
6707a84e134Smrg     */
6717a84e134Smrg    num_args = 0;
6727a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Backward");	   num_args++;
6737a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
6747a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6757a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6767a84e134Smrg    XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdLeft + R_OFFSET);
6777a84e134Smrg    num_args++;
6787a84e134Smrg    search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
6797a84e134Smrg						form, args, num_args);
6807a84e134Smrg
6817a84e134Smrg    num_args = 0;
6827a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Forward");	   num_args++;
6837a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
6847a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
6857a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);	   num_args++;
6867a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);	   num_args++;
6877a84e134Smrg    XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
6887a84e134Smrg    XtSetArg(args[num_args], XtNradioData, (XPointer)XawsdRight + R_OFFSET);
6897a84e134Smrg    num_args++;
6907a84e134Smrg    search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
6917a84e134Smrg						 form, args, num_args);
6927a84e134Smrg
6937a84e134Smrg    {
6947a84e134Smrg	XtTranslations radio_translations;
6957a84e134Smrg
6967a84e134Smrg	radio_translations = XtParseTranslationTable(radio_trans_string);
6977a84e134Smrg	XtOverrideTranslations(search->left_toggle, radio_translations);
6987a84e134Smrg	XtOverrideTranslations(search->right_toggle, radio_translations);
6997a84e134Smrg    }
7007a84e134Smrg
7017a84e134Smrg#ifndef OLDXAW
7027a84e134Smrg    if (XawTextFormat((TextWidget)tw, XawFmt8Bit)) {
7037a84e134Smrg	num_args = 0;
7047a84e134Smrg	XtSetArg(args[num_args], XtNlabel, "Case Sensitive");	num_args++;
7057a84e134Smrg	XtSetArg(args[num_args], XtNfromVert, search->label2);	num_args++;
7067a84e134Smrg	XtSetArg(args[num_args], XtNfromHoriz, search->right_toggle); num_args++;
7077a84e134Smrg	XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7087a84e134Smrg	XtSetArg(args[num_args], XtNright, XtChainLeft);	num_args++;
7097a84e134Smrg	XtSetArg(args[num_args], XtNstate, True);		num_args++;
7107a84e134Smrg	search->case_sensitive = XtCreateManagedWidget("case", toggleWidgetClass,
7117a84e134Smrg						       form, args, num_args);
7127a84e134Smrg    }
7137a84e134Smrg    else
7147a84e134Smrg	search->case_sensitive = NULL;
7157a84e134Smrg#endif
7167a84e134Smrg
7177a84e134Smrg    num_args = 0;
7187a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->left_toggle);	num_args++;
7197a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Search for:  ");	num_args++;
7207a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7217a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7227a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0 );		num_args++;
7237a84e134Smrg    s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
7247a84e134Smrg				    args, num_args);
7257a84e134Smrg
7267a84e134Smrg    num_args = 0;
7277a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
7287a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, s_label);		num_args++;
7297a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7307a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);		num_args++;
7317a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);		num_args++;
7327a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);		num_args++;
7337a84e134Smrg    XtSetArg(args[num_args], XtNstring, ptr);			num_args++;
7347a84e134Smrg    s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
7357a84e134Smrg				   args, num_args);
7367a84e134Smrg    search->search_text = s_text;
7377a84e134Smrg
7387a84e134Smrg    num_args = 0;
7397a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, s_text);		num_args++;
7407a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace with:");	num_args++;
7417a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7427a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7437a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, 0);		num_args++;
7447a84e134Smrg    search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
7457a84e134Smrg					      form, args, num_args);
7467a84e134Smrg
7477a84e134Smrg    num_args = 0;
7487a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, s_label);		num_args++;
7497a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, s_text);		num_args++;
7507a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7517a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainRight);		num_args++;
7527a84e134Smrg    XtSetArg(args[num_args], XtNeditType, XawtextEdit);		num_args++;
7537a84e134Smrg    XtSetArg(args[num_args], XtNresizable, True);		num_args++;
7547a84e134Smrg    XtSetArg(args[num_args], XtNstring, ""); num_args++;
7557a84e134Smrg    r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
7567a84e134Smrg				   form, args, num_args);
7577a84e134Smrg    search->rep_text = r_text;
7587a84e134Smrg
7597a84e134Smrg    num_args = 0;
7607a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Search");		num_args++;
7617a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7627a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7637a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7647a84e134Smrg    search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
7657a84e134Smrg					  args, num_args);
7667a84e134Smrg
7677a84e134Smrg    num_args = 0;
7687a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace");		num_args++;
7697a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7707a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search_button);	num_args++;
7717a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7727a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7737a84e134Smrg    search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
7747a84e134Smrg					    form, args, num_args);
7757a84e134Smrg
7767a84e134Smrg    num_args = 0;
7777a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Replace All");		num_args++;
7787a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7797a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->rep_one);	num_args++;
7807a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7817a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7827a84e134Smrg    search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
7837a84e134Smrg					    form, args, num_args);
7847a84e134Smrg
7857a84e134Smrg    num_args = 0;
7867a84e134Smrg    XtSetArg(args[num_args], XtNlabel, "Cancel");		num_args++;
7877a84e134Smrg    XtSetArg(args[num_args], XtNfromVert, r_text);		num_args++;
7887a84e134Smrg    XtSetArg(args[num_args], XtNfromHoriz, search->rep_all);	num_args++;
7897a84e134Smrg    XtSetArg(args[num_args], XtNleft, XtChainLeft);		num_args++;
7907a84e134Smrg    XtSetArg(args[num_args], XtNright, XtChainLeft);		num_args++;
7917a84e134Smrg    cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
7927a84e134Smrg				   args, num_args);
7937a84e134Smrg
7947a84e134Smrg    XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer)search);
7957a84e134Smrg    XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer)search);
7967a84e134Smrg    XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer)search);
7977a84e134Smrg    XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer)search);
7987a84e134Smrg
7997a84e134Smrg    /*
8007a84e134Smrg     * Initialize the text entry fields
8017a84e134Smrg     */
8027a84e134Smrg    {
8037a84e134Smrg	Pixel color;
8047a84e134Smrg
8057a84e134Smrg	num_args = 0;
8067a84e134Smrg	XtSetArg(args[num_args], XtNbackground, &color); num_args++;
8077a84e134Smrg	XtGetValues(search->rep_text, args, num_args);
8087a84e134Smrg	num_args = 0;
8097a84e134Smrg	XtSetArg(args[num_args], XtNborderColor, color); num_args++;
8107a84e134Smrg	XtSetValues(search->rep_text, args, num_args);
8117a84e134Smrg	XtSetKeyboardFocus(form, search->search_text);
8127a84e134Smrg    }
8137a84e134Smrg
8147a84e134Smrg    SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, False);
8157a84e134Smrg
8167a84e134Smrg    /*
8177a84e134Smrg     * Bind Extra translations
8187a84e134Smrg     */
8197a84e134Smrg    trans = XtParseTranslationTable(search_text_trans);
8207a84e134Smrg    XtOverrideTranslations(search->search_text, trans);
8217a84e134Smrg
8227a84e134Smrg    trans = XtParseTranslationTable(rep_text_trans);
8237a84e134Smrg    XtOverrideTranslations(search->rep_text, trans);
8247a84e134Smrg}
8257a84e134Smrg
8267a84e134Smrg/*
8277a84e134Smrg * Function:
8287a84e134Smrg *	DoSearch
8297a84e134Smrg *
8307a84e134Smrg * Parameters:
8317a84e134Smrg *	search - search structure
8327a84e134Smrg *
8337a84e134Smrg * Description:
8347a84e134Smrg *	Performs a search
8357a84e134Smrg *
8367a84e134Smrg * Returns:
8377a84e134Smrg *	True if sucessful
8387a84e134Smrg */
8397a84e134Smrg/*ARGSUSED*/
8407a84e134Smrgstatic Bool
8417a84e134SmrgDoSearch(struct SearchAndReplace *search)
8427a84e134Smrg{
8437a84e134Smrg    char msg[37];
8447a84e134Smrg    Widget tw = XtParent(search->search_popup);
8457a84e134Smrg    XawTextPosition pos;
8467a84e134Smrg    XawTextScanDirection dir;
8477a84e134Smrg    XawTextBlock text;
8487a84e134Smrg    TextWidget ctx = (TextWidget)tw;
8497a84e134Smrg
8507a84e134Smrg    text.firstPos = 0;
8517a84e134Smrg    text.ptr = GetStringRaw(search->search_text);
8527a84e134Smrg    if ((text.format = _XawTextFormat(ctx)) == XawFmtWide)
8537a84e134Smrg	text.length = wcslen((wchar_t*)text.ptr);
8547a84e134Smrg    else {
8557a84e134Smrg	text.length = strlen(text.ptr);
8567a84e134Smrg
8577a84e134Smrg#ifndef OLDXAW
8587a84e134Smrg	if (search->case_sensitive) {
8597a84e134Smrg	  /* text.firstPos isn't useful here, so I'll use it as an
8607a84e134Smrg	   * options flag.
8617a84e134Smrg	   */
8627a84e134Smrg	    Arg args[1];
8637a84e134Smrg	    Boolean case_sensitive;
8647a84e134Smrg
8657a84e134Smrg	    XtSetArg(args[0], XtNstate, &case_sensitive);
8667a84e134Smrg	    XtGetValues(search->case_sensitive, args, 1);
8677a84e134Smrg	    text.firstPos = !case_sensitive;
8687a84e134Smrg	}
8697a84e134Smrg#endif /* OLDXAW */
8707a84e134Smrg    }
8717a84e134Smrg
8727a84e134Smrg    dir = (XawTextScanDirection)(unsigned long)
8737a84e134Smrg      ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
8747a84e134Smrg
8757a84e134Smrg    pos = XawTextSearch(tw, dir, &text);
8767a84e134Smrg
8777a84e134Smrg   /* The Raw string in find.ptr may be WC I can't use here, so I re - call
8787a84e134Smrg     GetString to get a tame version */
8797a84e134Smrg
8807a84e134Smrg    if (pos == XawTextSearchError) {
8817a84e134Smrg	char *ptr;
8827a84e134Smrg	int len;
8837a84e134Smrg
8847a84e134Smrg	ptr = GetString(search->search_text);
8857a84e134Smrg	len = strlen(ptr);
8867a84e134Smrg	(void)XmuSnprintf(msg, sizeof(msg), "%s", ptr);
8877a84e134Smrg
8887a84e134Smrg	ptr = strchr(msg, '\n');
8897a84e134Smrg	if (ptr != NULL || sizeof(msg) - 1 < len) {
8907a84e134Smrg	    if (ptr != NULL)
8917a84e134Smrg		len = ptr - msg + 4;
8927a84e134Smrg	    else
8937a84e134Smrg		len = strlen(msg);
8947a84e134Smrg
8957a84e134Smrg	    if (len < 4)
8967a84e134Smrg		strcpy(msg, "...");
8977a84e134Smrg	    else
8987a84e134Smrg		strcpy(msg + len - 4, "...");
8997a84e134Smrg	}
9007a84e134Smrg	XawTextUnsetSelection(tw);
9017a84e134Smrg	SetSearchLabels(search, "Could not find string", msg, True);
9027a84e134Smrg
9037a84e134Smrg	return (False);
9047a84e134Smrg    }
9057a84e134Smrg    XawTextDisableRedisplay(tw);
9067a84e134Smrg    XawTextSetSelection(tw, pos, pos + text.length);
9077a84e134Smrg    search->selection_changed = False;	/* selection is good */
9087a84e134Smrg
9097a84e134Smrg    if (dir == XawsdRight)
9107a84e134Smrg	XawTextSetInsertionPoint(tw, pos + text.length);
9117a84e134Smrg    else
9127a84e134Smrg	XawTextSetInsertionPoint(tw, pos);
9137a84e134Smrg    _XawTextShowPosition(ctx);
9147a84e134Smrg    XawTextEnableRedisplay(tw);
9157a84e134Smrg
9167a84e134Smrg    return (True);
9177a84e134Smrg}
9187a84e134Smrg
9197a84e134Smrg/*
9207a84e134Smrg * This section of the file contains all the functions that
9217a84e134Smrg * the replace dialog box uses
9227a84e134Smrg */
9237a84e134Smrg/*
9247a84e134Smrg * Function:
9257a84e134Smrg *	_XawTextDoReplaceAction
9267a84e134Smrg *
9277a84e134Smrg * Description:
9287a84e134Smrg *	Action routine that can be bound to dialog box's
9297a84e134Smrg *	Text Widget that will replace a string in the main Text Widget.
9307a84e134Smrg */
9317a84e134Smrg/*ARGSUSED*/
9327a84e134Smrgvoid
9337a84e134Smrg_XawTextDoReplaceAction(Widget w, XEvent *event,
9347a84e134Smrg			String *params, Cardinal *num_params)
9357a84e134Smrg{
9367a84e134Smrg    TextWidget ctx = (TextWidget)XtParent(XtParent(XtParent(w)));
9377a84e134Smrg    Bool popdown = False;
9387a84e134Smrg
9397a84e134Smrg    if (*num_params == 1 && (params[0][0] == 'p' || params[0][0] == 'P'))
9407a84e134Smrg	popdown = True;
9417a84e134Smrg
9427a84e134Smrg    if (Replace( ctx->text.search, True, popdown) && popdown)
9437a84e134Smrg	PopdownSearch(w, (XtPointer)ctx->text.search, NULL);
9447a84e134Smrg}
9457a84e134Smrg
9467a84e134Smrg/*
9477a84e134Smrg * Function:
9487a84e134Smrg *	DoReplaceOne
9497a84e134Smrg *
9507a84e134Smrg * Arguments:
9517a84e134Smrg *	w	  - *** Not Used ***
9527a84e134Smrg *	closure   - a pointer to the search structure
9537a84e134Smrg *	call_data - *** Not Used ***
9547a84e134Smrg *
9557a84e134Smrg * Description:
9567a84e134Smrg *	  Replaces the first instance of the string in the search
9577a84e134Smrg *	dialog's text widget with the one in the replace dialog's text widget.
9587a84e134Smrg */
9597a84e134Smrg/*ARGSUSED*/
9607a84e134Smrgstatic void
9617a84e134SmrgDoReplaceOne(Widget w, XtPointer closure, XtPointer call_data)
9627a84e134Smrg{
9637a84e134Smrg    Replace((struct SearchAndReplace *)closure, True, False);
9647a84e134Smrg}
9657a84e134Smrg
9667a84e134Smrg/*
9677a84e134Smrg * Function:
9687a84e134Smrg *	DoReplaceAll
9697a84e134Smrg *
9707a84e134Smrg * Parameters:
9717a84e134Smrg *	w	  - (not used)
9727a84e134Smrg *	closure	  - pointer to the search structure
9737a84e134Smrg *	call_data - (not used)
9747a84e134Smrg *
9757a84e134Smrg * Description:
9767a84e134Smrg *	  Replaces every instance of the string in the search dialog's
9777a84e134Smrg *	text widget with the one in the replace dialog's text widget.
9787a84e134Smrg */
9797a84e134Smrg/*ARGSUSED*/
9807a84e134Smrgstatic void
9817a84e134SmrgDoReplaceAll(Widget w, XtPointer closure, XtPointer call_data)
9827a84e134Smrg{
9837a84e134Smrg    Replace((struct SearchAndReplace *)closure, False, False);
9847a84e134Smrg}
9857a84e134Smrg
9867a84e134Smrg/*
9877a84e134Smrg * Function:
9887a84e134Smrg *	Replace
9897a84e134Smrg *
9907a84e134Smrg * Parameters:
9917a84e134Smrg *	tw	      - Text Widget to replce the string in
9927a84e134Smrg *	once_only     - if True then only replace the first one found,
9937a84e134Smrg *			else replace all of them
9947a84e134Smrg *	show_current  - if true then leave the selection on the
9957a84e134Smrg *		        string that was just replaced, otherwise
9967a84e134Smrg *		        move it onto the next one
9977a84e134Smrg *
9987a84e134Smrg * Description:
9997a84e134Smrg *	  This is the function that does the real work of
10007a84e134Smrg *	replacing strings in the main text widget.
10017a84e134Smrg */
10027a84e134Smrgstatic Bool
10037a84e134SmrgReplace(struct SearchAndReplace *search, Bool once_only, Bool show_current)
10047a84e134Smrg{
10057a84e134Smrg    XawTextPosition pos, new_pos, end_pos, ipos;
10067a84e134Smrg    XawTextScanDirection dir;
10077a84e134Smrg    XawTextBlock find, replace;
10087a84e134Smrg    Widget tw = XtParent(search->search_popup);
10097a84e134Smrg    int count = 0;
10107a84e134Smrg    TextWidget ctx = (TextWidget)tw;
10117a84e134Smrg    Bool redisplay;
10127a84e134Smrg
10137a84e134Smrg    find.ptr = GetStringRaw(search->search_text);
10147a84e134Smrg    if ((find.format = _XawTextFormat(ctx)) == XawFmtWide)
10157a84e134Smrg	find.length = (XawTextPosition)wcslen((wchar_t*)find.ptr);
10167a84e134Smrg    else
10177a84e134Smrg	find.length = (XawTextPosition)strlen(find.ptr);
10187a84e134Smrg    find.firstPos = 0;
10197a84e134Smrg
10207a84e134Smrg    replace.ptr = GetStringRaw(search->rep_text);
10217a84e134Smrg    replace.firstPos = 0;
10227a84e134Smrg    if ((replace.format = _XawTextFormat(ctx)) == XawFmtWide)
10237a84e134Smrg	replace.length = wcslen((wchar_t*)replace.ptr);
10247a84e134Smrg    else
10257a84e134Smrg	replace.length = strlen(replace.ptr);
10267a84e134Smrg
10277a84e134Smrg    dir = (XawTextScanDirection)(unsigned long)
10287a84e134Smrg      ((XPointer)XawToggleGetCurrent(search->left_toggle) - R_OFFSET);
10297a84e134Smrg
10307a84e134Smrg    redisplay = !once_only || (once_only && !show_current);
10317a84e134Smrg    ipos = XawTextGetInsertionPoint(tw);
10327a84e134Smrg    if (redisplay)
10337a84e134Smrg	XawTextDisableRedisplay(tw);
10347a84e134Smrg    /*CONSTCOND*/
10357a84e134Smrg    while (True) {
10367a84e134Smrg	if (count != 0)	{
10377a84e134Smrg	    new_pos = XawTextSearch(tw, dir, &find);
10387a84e134Smrg
10397a84e134Smrg	    if (new_pos == XawTextSearchError) {
10407a84e134Smrg		if (count == 0) {
10417a84e134Smrg		    char msg[37];
10427a84e134Smrg		    char *ptr;
10437a84e134Smrg		    int len;
10447a84e134Smrg
10457a84e134Smrg		    ptr = GetString(search->search_text);
10467a84e134Smrg		    len = strlen(ptr);
10477a84e134Smrg		    (void)XmuSnprintf(msg, sizeof(msg), "%s", ptr);
10487a84e134Smrg		    ptr = strchr(msg, '\n');
10497a84e134Smrg		    if (ptr != NULL || sizeof(msg) - 1 < len) {
10507a84e134Smrg			if (ptr != NULL)
10517a84e134Smrg			    len = ptr - msg + 4;
10527a84e134Smrg			else
10537a84e134Smrg			    len = strlen(msg);
10547a84e134Smrg
10557a84e134Smrg			if (len < 4)
10567a84e134Smrg			    strcpy(msg, "...");
10577a84e134Smrg			else
10587a84e134Smrg			    strcpy(msg + len - 4, "...");
10597a84e134Smrg		    }
10607a84e134Smrg		    SetSearchLabels(search, "Could not find string", msg, True);
10617a84e134Smrg
10627a84e134Smrg		    if (redisplay) {
10637a84e134Smrg			XawTextSetInsertionPoint(tw, ipos);
10647a84e134Smrg			_XawTextShowPosition(ctx);
10657a84e134Smrg			XawTextEnableRedisplay(tw);
10667a84e134Smrg		    }
10677a84e134Smrg
10687a84e134Smrg		    return (False);
10697a84e134Smrg		}
10707a84e134Smrg		else
10717a84e134Smrg		    break;
10727a84e134Smrg	    }
10737a84e134Smrg	    pos = new_pos;
10747a84e134Smrg	    end_pos = pos + find.length;
10757a84e134Smrg	}
10767a84e134Smrg	else {
10777a84e134Smrg	    XawTextGetSelectionPos(tw, &pos, &end_pos);
10787a84e134Smrg
10797a84e134Smrg	    if (search->selection_changed) {
10807a84e134Smrg		SetSearchLabels(search, "Selection modified, aborting.",
10817a84e134Smrg				"", True);
10827a84e134Smrg		if (redisplay) {
10837a84e134Smrg		    XawTextSetInsertionPoint(tw, ipos);
10847a84e134Smrg		    XawTextEnableRedisplay(tw);
10857a84e134Smrg		}
10867a84e134Smrg
10877a84e134Smrg		return (False);
10887a84e134Smrg	    }
10897a84e134Smrg	    if (pos == end_pos) {
10907a84e134Smrg		if (redisplay) {
10917a84e134Smrg		    XawTextSetInsertionPoint(tw, ipos);
10927a84e134Smrg		    XawTextEnableRedisplay(tw);
10937a84e134Smrg		}
10947a84e134Smrg
10957a84e134Smrg		return (False);
10967a84e134Smrg	    }
10977a84e134Smrg	}
10987a84e134Smrg
10997a84e134Smrg	if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
11007a84e134Smrg	    SetSearchLabels(search, "Error while replacing.", "", True);
11017a84e134Smrg	    if (redisplay) {
11027a84e134Smrg		XawTextSetInsertionPoint(tw, ipos);
11037a84e134Smrg		XawTextEnableRedisplay(tw);
11047a84e134Smrg	    }
11057a84e134Smrg
11067a84e134Smrg	    return (False);
11077a84e134Smrg	}
11087a84e134Smrg
11097a84e134Smrg	if (dir == XawsdRight)
11107a84e134Smrg	    ipos = pos + replace.length;
11117a84e134Smrg	else
11127a84e134Smrg	    ipos = pos;
11137a84e134Smrg
11147a84e134Smrg	if (once_only) {
11157a84e134Smrg	    if (show_current)
11167a84e134Smrg		break;
11177a84e134Smrg	    else {
11187a84e134Smrg		DoSearch(search);
11197a84e134Smrg		XawTextEnableRedisplay(tw);
11207a84e134Smrg
11217a84e134Smrg		return (True);
11227a84e134Smrg	    }
11237a84e134Smrg	}
11247a84e134Smrg	else
11257a84e134Smrg	    ctx->text.insertPos = ipos;
11267a84e134Smrg	count++;
11277a84e134Smrg    }
11287a84e134Smrg
11297a84e134Smrg    if (replace.length == 0)
11307a84e134Smrg	XawTextUnsetSelection(tw);
11317a84e134Smrg    else
11327a84e134Smrg	XawTextSetSelection(tw, pos, pos + replace.length);
11337a84e134Smrg
11347a84e134Smrg    XawTextSetInsertionPoint(tw, ipos);
11357a84e134Smrg    _XawTextShowPosition(ctx);
11367a84e134Smrg    XawTextEnableRedisplay(tw);
11377a84e134Smrg
11387a84e134Smrg    return (True);
11397a84e134Smrg}
11407a84e134Smrg
11417a84e134Smrg/*
11427a84e134Smrg * Function:
11437a84e134Smrg *	SetSearchLabels
11447a84e134Smrg *
11457a84e134Smrg * Parameters:
11467a84e134Smrg *	search - search structure
11477a84e134Smrg *	msg1   - message to put in each search label
11487a84e134Smrg *	msg2   - ""
11497a84e134Smrg *	bell   - if True then ring bell
11507a84e134Smrg *
11517a84e134Smrg * Description:
11527a84e134Smrg *	Sets both the search labels, and also rings the bell.
11537a84e134Smrg */
11547a84e134Smrgstatic void
11557a84e134SmrgSetSearchLabels(struct SearchAndReplace *search, String msg1, String msg2,
11567a84e134Smrg		Bool bell)
11577a84e134Smrg{
11587a84e134Smrg    (void)SetResource(search->label1, XtNlabel, (XtArgVal)msg1);
11597a84e134Smrg    (void)SetResource(search->label2, XtNlabel, (XtArgVal)msg2);
11607a84e134Smrg    if (bell)
11617a84e134Smrg	XBell(XtDisplay(search->search_popup), 0);
11627a84e134Smrg}
11637a84e134Smrg
11647a84e134Smrg/*
11657a84e134Smrg * This section of the file contains utility routines used by
11667a84e134Smrg * other functions in this file
11677a84e134Smrg */
11687a84e134Smrg/*
11697a84e134Smrg * Function:
11707a84e134Smrg *	_XawTextSetField
11717a84e134Smrg *
11727a84e134Smrg * Description:
11737a84e134Smrg *	  Action routine that can be bound to dialog box's
11747a84e134Smrg *		   Text Widget that will send input to the field specified.
11757a84e134Smrg */
11767a84e134Smrg/*ARGSUSED*/
11777a84e134Smrgvoid
11787a84e134Smrg_XawTextSetField(Widget w, XEvent *event, String *params, Cardinal *num_params)
11797a84e134Smrg{
11807a84e134Smrg    struct SearchAndReplace *search;
11817a84e134Smrg    Widget cnew, old;
11827a84e134Smrg
11837a84e134Smrg    search = ((TextWidget)XtParent(XtParent(XtParent(w))))->text.search;
11847a84e134Smrg
11857a84e134Smrg    if (*num_params != 1) {
11867a84e134Smrg	SetSearchLabels(search, "Error: SetField Action must have",
11877a84e134Smrg			"exactly one argument", True);
11887a84e134Smrg	return;
11897a84e134Smrg    }
11907a84e134Smrg    switch (params[0][0])  {
11917a84e134Smrg	case 's':
11927a84e134Smrg	case 'S':
11937a84e134Smrg	    cnew = search->search_text;
11947a84e134Smrg	    old = search->rep_text;
11957a84e134Smrg	    break;
11967a84e134Smrg	case 'r':
11977a84e134Smrg	case 'R':
11987a84e134Smrg	    old = search->search_text;
11997a84e134Smrg	    cnew = search->rep_text;
12007a84e134Smrg	    break;
12017a84e134Smrg	default:
12027a84e134Smrg	    SetSearchLabels(search,
12037a84e134Smrg			    "Error: SetField Action's first Argument must",
12047a84e134Smrg			    "be either 'Search' or 'Replace'", True);
12057a84e134Smrg	    return;
12067a84e134Smrg    }
12077a84e134Smrg    _SetField(cnew, old);
12087a84e134Smrg}
12097a84e134Smrg
12107a84e134Smrg/*
12117a84e134Smrg * Function:
12127a84e134Smrg *	_SetField
12137a84e134Smrg *
12147a84e134Smrg * Parameters:
12157a84e134Smrg *	cnew - new and old text fields
12167a84e134Smrg *	old  - ""
12177a84e134Smrg *
12187a84e134Smrg * Description:
12197a84e134Smrg *	Sets the current text field.
12207a84e134Smrg */
12217a84e134Smrgstatic void
12227a84e134Smrg_SetField(Widget cnew, Widget old)
12237a84e134Smrg{
12247a84e134Smrg    Arg args[2];
12257a84e134Smrg    Pixel new_border, old_border, old_bg;
12267a84e134Smrg
12277a84e134Smrg    if (!XtIsSensitive(cnew)) {
12287a84e134Smrg	XBell(XtDisplay(old), 0);	/* Don't set field to an inactive Widget */
12297a84e134Smrg	return;
12307a84e134Smrg    }
12317a84e134Smrg
12327a84e134Smrg    XtSetKeyboardFocus(XtParent(cnew), cnew);
12337a84e134Smrg
12347a84e134Smrg    XtSetArg(args[0], XtNborderColor, &old_border);
12357a84e134Smrg    XtSetArg(args[1], XtNbackground, &old_bg);
12367a84e134Smrg    XtGetValues(cnew, args, 2);
12377a84e134Smrg
12387a84e134Smrg    XtSetArg(args[0], XtNborderColor, &new_border);
12397a84e134Smrg    XtGetValues(old, args, 1);
12407a84e134Smrg
12417a84e134Smrg    if (old_border != old_bg)	/* Colors are already correct, return */
12427a84e134Smrg	return;
12437a84e134Smrg
12447a84e134Smrg    SetResource(old, XtNborderColor, (XtArgVal)old_border);
12457a84e134Smrg    SetResource(cnew, XtNborderColor, (XtArgVal)new_border);
12467a84e134Smrg}
12477a84e134Smrg
12487a84e134Smrg/*
12497a84e134Smrg * Function:
12507a84e134Smrg *	SetResourceByName
12517a84e134Smrg *
12527a84e134Smrg * Parameters:
12537a84e134Smrg *	shell	 - shell widget of the popup
12547a84e134Smrg *	name	 - name of the child
12557a84e134Smrg *	res_name - name of the resource
12567a84e134Smrg *	value	 - value of the resource
12577a84e134Smrg *
12587a84e134Smrg * Description:
12597a84e134Smrg *	  Sets a resource in any of the dialog children given
12607a84e134Smrg *	name of the child and the shell widget of the dialog.
12617a84e134Smrg *
12627a84e134Smrg * Returns:
12637a84e134Smrg *	True if sucessful
12647a84e134Smrg */
12657a84e134Smrgstatic Bool
12667a84e134SmrgSetResourceByName(Widget shell, char *name, char *res_name, XtArgVal value)
12677a84e134Smrg{
12687a84e134Smrg    Widget temp_widget;
12697a84e134Smrg    char buf[BUFSIZ];
12707a84e134Smrg
12717a84e134Smrg    (void)XmuSnprintf(buf, sizeof(buf), "%s.%s", FORM_NAME, name);
12727a84e134Smrg
12737a84e134Smrg    if ((temp_widget = XtNameToWidget(shell, buf)) != NULL) {
12747a84e134Smrg	SetResource(temp_widget, res_name, value);
12757a84e134Smrg	return (True);
12767a84e134Smrg    }
12777a84e134Smrg    return (False);
12787a84e134Smrg}
12797a84e134Smrg
12807a84e134Smrg/*
12817a84e134Smrg * Function:
12827a84e134Smrg *	SetResource
12837a84e134Smrg *
12847a84e134Smrg * Parameters:
12857a84e134Smrg *	w	 - widget
12867a84e134Smrg *	res_name - name of the resource
12877a84e134Smrg *	value	 - value of the resource
12887a84e134Smrg *
12897a84e134Smrg * Description:
12907a84e134Smrg *	Sets a resource in a widget
12917a84e134Smrg */
12927a84e134Smrgstatic void
12937a84e134SmrgSetResource(Widget w, char *res_name, XtArgVal value)
12947a84e134Smrg{
12957a84e134Smrg    Arg args[1];
12967a84e134Smrg
12977a84e134Smrg    XtSetArg(args[0], res_name, value);
12987a84e134Smrg    XtSetValues( w, args, 1);
12997a84e134Smrg}
13007a84e134Smrg
13017a84e134Smrg/*
13027a84e134Smrg * Function:
13037a84e134Smrg *	GetString{Raw}
13047a84e134Smrg *
13057a84e134Smrg * Parameters:
13067a84e134Smrg *	text - text widget whose string we will get
13077a84e134Smrg *
13087a84e134Smrg * Description:
13097a84e134Smrg *	Gets the value for the string in the popup.
13107a84e134Smrg *
13117a84e134Smrg * Returns:
13127a84e134Smrg *	GetString:	the string as a MB
13137a84e134Smrg *	GetStringRaw:	the exact buffer contents suitable for a search
13147a84e134Smrg */
13157a84e134Smrgstatic String
13167a84e134SmrgGetString(Widget text)
13177a84e134Smrg{
13187a84e134Smrg    String string;
13197a84e134Smrg    Arg args[1];
13207a84e134Smrg
13217a84e134Smrg    XtSetArg(args[0], XtNstring, &string);
13227a84e134Smrg    XtGetValues(text, args, 1);
13237a84e134Smrg
13247a84e134Smrg    return (string);
13257a84e134Smrg}
13267a84e134Smrg
13277a84e134Smrgstatic String
13287a84e134SmrgGetStringRaw(Widget tw)
13297a84e134Smrg{
13307a84e134Smrg    TextWidget ctx = (TextWidget)tw;
13317a84e134Smrg    XawTextPosition last;
13327a84e134Smrg
13337a84e134Smrg    last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
13347a84e134Smrg			     ctx->text.mult, True);
13357a84e134Smrg    return (_XawTextGetText(ctx, 0, last));
13367a84e134Smrg}
13377a84e134Smrg
13387a84e134Smrg/*
13397a84e134Smrg * Function:
13407a84e134Smrg *	CenterWidgetOnPoint
13417a84e134Smrg *
13427a84e134Smrg * Parameters:
13437a84e134Smrg *	w     - shell widget
13447a84e134Smrg *		 event - event containing the location of the point
13457a84e134Smrg *
13467a84e134Smrg * Description:
13477a84e134Smrg *	Centers a shell widget on a point relative to the root window.
13487a84e134Smrg *
13497a84e134Smrg * Note:
13507a84e134Smrg *	The widget is not allowed to go off the screen
13517a84e134Smrg */
13527a84e134Smrgstatic void
13537a84e134SmrgCenterWidgetOnPoint(Widget w, XEvent *event)
13547a84e134Smrg{
13557a84e134Smrg    Arg args[3];
13567a84e134Smrg    Cardinal num_args;
13577a84e134Smrg    Dimension width, height, b_width;
13587a84e134Smrg    Position x, y, max_x, max_y;
13597a84e134Smrg
13607a84e134Smrg    if (event != NULL) {
13617a84e134Smrg	switch (event->type) {
13627a84e134Smrg	    case ButtonPress:
13637a84e134Smrg	    case ButtonRelease:
13647a84e134Smrg		x = event->xbutton.x_root;
13657a84e134Smrg		y = event->xbutton.y_root;
13667a84e134Smrg		break;
13677a84e134Smrg	    case KeyPress:
13687a84e134Smrg	    case KeyRelease:
13697a84e134Smrg		x = event->xkey.x_root;
13707a84e134Smrg		y = event->xkey.y_root;
13717a84e134Smrg		break;
13727a84e134Smrg	    default:
13737a84e134Smrg		return;
13747a84e134Smrg	}
13757a84e134Smrg    }
13767a84e134Smrg    else
13777a84e134Smrg	return;
13787a84e134Smrg
13797a84e134Smrg    num_args = 0;
13807a84e134Smrg    XtSetArg(args[num_args], XtNwidth, &width); num_args++;
13817a84e134Smrg    XtSetArg(args[num_args], XtNheight, &height); num_args++;
13827a84e134Smrg    XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
13837a84e134Smrg    XtGetValues(w, args, num_args);
13847a84e134Smrg
13857a84e134Smrg    width += b_width << 1;
13867a84e134Smrg    height += b_width << 1;
13877a84e134Smrg
13887a84e134Smrg    x -= (Position)(width >> 1);
13897a84e134Smrg    if (x < 0)
13907a84e134Smrg	x = 0;
13917a84e134Smrg    if (x > (max_x = (Position)(XtScreen(w)->width - width)))
13927a84e134Smrg	x = max_x;
13937a84e134Smrg
13947a84e134Smrg    y -= (Position)(height >> 1);
13957a84e134Smrg    if (y < 0)
13967a84e134Smrg	y = 0;
13977a84e134Smrg    if (y > (max_y = (Position)(XtScreen(w)->height - height)))
13987a84e134Smrg	y = max_y;
13997a84e134Smrg
14007a84e134Smrg    num_args = 0;
14017a84e134Smrg    XtSetArg(args[num_args], XtNx, x); num_args++;
14027a84e134Smrg    XtSetArg(args[num_args], XtNy, y); num_args++;
14037a84e134Smrg    XtSetValues(w, args, num_args);
14047a84e134Smrg}
14057a84e134Smrg
14067a84e134Smrg/*
14077a84e134Smrg * Function:
14087a84e134Smrg *	CreateDialog
14097a84e134Smrg *
14107a84e134Smrg * Parameters:
14117a84e134Smrg *	parent - parent of the dialog - the main text widget
14127a84e134Smrg *	ptr    - initial_string for the dialog
14137a84e134Smrg *	name   - name of the dialog
14147a84e134Smrg *	func   - function to create the children of the dialog
14157a84e134Smrg *
14167a84e134Smrg * Returns:
14177a84e134Smrg *	Popup shell of the dialog
14187a84e134Smrg *
14197a84e134Smrg * Note:
14207a84e134Smrg *	The function argument is passed the following arguments:
14217a84e134Smrg *	form   - from widget that is the dialog
14227a84e134Smrg *	ptr    - initial string for the dialog's text widget
14237a84e134Smrg *	parent - parent of the dialog - the main text widget
14247a84e134Smrg */
14257a84e134Smrgstatic Widget
14267a84e134SmrgCreateDialog(Widget parent, String ptr, String name, AddFunc func)
14277a84e134Smrg{
14287a84e134Smrg    Widget popup, form;
14297a84e134Smrg    Arg args[5];
14307a84e134Smrg    Cardinal num_args;
14317a84e134Smrg
14327a84e134Smrg    num_args = 0;
14337a84e134Smrg    XtSetArg(args[num_args], XtNiconName, name);		num_args++;
14347a84e134Smrg    XtSetArg(args[num_args], XtNgeometry, NULL);		num_args++;
14357a84e134Smrg    XtSetArg(args[num_args], XtNallowShellResize, True);	num_args++;
14367a84e134Smrg    XtSetArg(args[num_args], XtNtransientFor, GetShell(parent));num_args++;
14377a84e134Smrg    popup = XtCreatePopupShell(name, transientShellWidgetClass,
14387a84e134Smrg			       parent, args, num_args);
14397a84e134Smrg
14407a84e134Smrg    form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup, NULL, 0);
14417a84e134Smrg    XtManageChild (form);
14427a84e134Smrg
14437a84e134Smrg    (*func)(form, ptr, parent);
14447a84e134Smrg
14457a84e134Smrg    return (popup);
14467a84e134Smrg}
14477a84e134Smrg
14487a84e134Smrg/*
14497a84e134Smrg * Function
14507a84e134Smrg *	GetShell
14517a84e134Smrg *	nearest shell widget.
14527a84e134Smrg *
14537a84e134Smrg * Parameters:
14547a84e134Smrg *	w - widget whose parent shell should be returned
14557a84e134Smrg *
14567a84e134Smrg * Returns:
14577a84e134Smrg *	  The shell widget among the ancestors of w that is the
14587a84e134Smrg * 	fewest levels up in the widget hierarchy.
14597a84e134Smrg *
14607a84e134Smrg * Description:
14617a84e134Smrg *	Walks up the widget hierarchy to find the topmost shell widget.
14627a84e134Smrg */
14637a84e134Smrgstatic Widget
14647a84e134SmrgGetShell(Widget w)
14657a84e134Smrg{
14667a84e134Smrg    while (w != NULL && !XtIsShell(w))
14677a84e134Smrg	w = XtParent(w);
14687a84e134Smrg
14697a84e134Smrg    return (w);
14707a84e134Smrg}
14717a84e134Smrg
14727a84e134Smrgstatic Bool
14737a84e134SmrgInParams(String str, String *p, unsigned int n)
14747a84e134Smrg{
14757a84e134Smrg    unsigned int i;
14767a84e134Smrg
14777a84e134Smrg    for (i = 0; i < n; p++, i++)
14787a84e134Smrg	if (!XmuCompareISOLatin1(*p, str))
14797a84e134Smrg	    return (True);
14807a84e134Smrg    return (False);
14817a84e134Smrg}
14827a84e134Smrg
14837a84e134Smrgstatic char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
14847a84e134Smrg
14857a84e134Smrgstatic void
14867a84e134SmrgWMProtocols(Widget w, XEvent *event, String *params, Cardinal *num_params)
14877a84e134Smrg{
14887a84e134Smrg    Atom wm_delete_window;
14897a84e134Smrg    Atom wm_protocols;
14907a84e134Smrg
14917a84e134Smrg    wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
14927a84e134Smrg    wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
14937a84e134Smrg
14947a84e134Smrg    /* Respond to a recognized WM protocol request if
14957a84e134Smrg     * event type is ClientMessage and no parameters are passed, or
14967a84e134Smrg     * event type is ClientMessage and event data is matched to parameters, or
14977a84e134Smrg     * event type isn't ClientMessage and parameters make a request
14987a84e134Smrg     */
14997a84e134Smrg#define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
15007a84e134Smrg
15017a84e134Smrg    if ((event->type == ClientMessage
15027a84e134Smrg	 && event->xclient.message_type == wm_protocols
15037a84e134Smrg	 && event->xclient.data.l[0] == wm_delete_window
15047a84e134Smrg	 && (*num_params == 0 || DO_DELETE_WINDOW))
15057a84e134Smrg	|| (event->type != ClientMessage && DO_DELETE_WINDOW)) {
15067a84e134Smrg#undef DO_DELETE_WINDOW
15077a84e134Smrg	Widget cancel;
15087a84e134Smrg	char descendant[DISMISS_NAME_LEN + 2];
15097a84e134Smrg
15107a84e134Smrg	(void)XmuSnprintf(descendant, sizeof(descendant), "*%s", DISMISS_NAME);
15117a84e134Smrg	cancel = XtNameToWidget(w, descendant);
15127a84e134Smrg	if (cancel)
15137a84e134Smrg	    XtCallCallbacks(cancel, XtNcallback, NULL);
15147a84e134Smrg    }
15157a84e134Smrg}
15167a84e134Smrg
15177a84e134Smrgstatic void
15187a84e134SmrgSetWMProtocolTranslations(Widget w)
15197a84e134Smrg{
15207a84e134Smrg    static XtTranslations compiled_table;
15217a84e134Smrg    static XtAppContext *app_context_list;
15227a84e134Smrg    static Cardinal list_size;
15237a84e134Smrg
15247a84e134Smrg    unsigned int i;
15257a84e134Smrg    XtAppContext app_context;
15267a84e134Smrg    Atom wm_delete_window;
15277a84e134Smrg
15287a84e134Smrg    app_context = XtWidgetToApplicationContext(w);
15297a84e134Smrg
15307a84e134Smrg    /* parse translation table once */
15317a84e134Smrg    if (!compiled_table)
15327a84e134Smrg	compiled_table =
15337a84e134Smrg	    XtParseTranslationTable("<Message>WM_PROTOCOLS:XawWMProtocols()\n");
15347a84e134Smrg
15357a84e134Smrg    /* add actions once per application context */
15367a84e134Smrg    for (i = 0; i < list_size && app_context_list[i] != app_context; i++)
15377a84e134Smrg	;
15387a84e134Smrg    if (i == list_size) {
15397a84e134Smrg	XtActionsRec actions[1];
15407a84e134Smrg
15417a84e134Smrg	actions[0].string = "XawWMProtocols";
15427a84e134Smrg	actions[0].proc = WMProtocols;
15437a84e134Smrg	list_size++;
15447a84e134Smrg	app_context_list = (XtAppContext *)XtRealloc
15457a84e134Smrg	    ((char *)app_context_list, list_size * sizeof(XtAppContext));
15467a84e134Smrg	XtAppAddActions(app_context, actions, 1);
15477a84e134Smrg	app_context_list[i] = app_context;
15487a84e134Smrg    }
15497a84e134Smrg
15507a84e134Smrg    /* establish communication between the window manager and each shell */
15517a84e134Smrg    XtAugmentTranslations(w, compiled_table);
15527a84e134Smrg    wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
15537a84e134Smrg    (void)XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);
15547a84e134Smrg}
1555