TextPop.c

Go to the documentation of this file.
00001 /* $XConsortium: TextPop.c,v 1.31 94/04/17 20:13:10 kaleb Exp $ */
00002 
00003 /*
00004 
00005 Copyright (c) 1989, 1994  X Consortium
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a copy
00008 of this software and associated documentation files (the "Software"), to deal
00009 in the Software without restriction, including without limitation the rights
00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011 copies of the Software, and to permit persons to whom the Software is
00012 furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00020 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023 
00024 Except as contained in this notice, the name of the X Consortium shall not be
00025 used in advertising or otherwise to promote the sale, use or other dealings
00026 in this Software without prior written authorization from the X Consortium.
00027 
00028 */
00029 
00030 /************************************************************
00031  *
00032  * This file is broken up into three sections one dealing with
00033  * each of the three popups created here:
00034  *
00035  * FileInsert, Search, and Replace.
00036  *
00037  * There is also a section at the end for utility functions 
00038  * used by all more than one of these dialogs.
00039  *
00040  * The following functions are the only non-static ones defined
00041  * in this module.  They are located at the begining of the
00042  * section that contains this dialog box that uses them.
00043  * 
00044  * void _XawTextInsertFileAction(w, event, params, num_params);
00045  * void _XawTextDoSearchAction(w, event, params, num_params);
00046  * void _XawTextDoReplaceAction(w, event, params, num_params);
00047  * void _XawTextInsertFile(w, event, params, num_params);
00048  *
00049  *************************************************************/
00050 
00051 #include <X11/IntrinsicP.h>
00052 #include <X11/StringDefs.h>
00053 #include <X11/Shell.h> 
00054 
00055 #include <X11/Xaw3d/TextP.h>
00056 #include <X11/Xaw3d/AsciiText.h>
00057 #include <X11/Xaw3d/Cardinals.h>
00058 #include <X11/Xaw3d/Command.h>
00059 #include <X11/Xaw3d/Form.h>
00060 #include <X11/Xaw3d/Toggle.h>
00061 #include <X11/Xmu/CharSet.h>
00062 #include "XawI18n.h"
00063 #include <stdio.h>
00064 #include <X11/Xos.h>            /* for O_RDONLY */
00065 #include <errno.h>
00066 
00067 #ifdef X_NOT_STDC_ENV
00068 extern int errno;
00069 #endif
00070 
00071 #define INSERT_FILE ("Enter Filename:")
00072 
00073 #define SEARCH_LABEL_1  ("Use <Tab> to change fields.")
00074 #define SEARCH_LABEL_2  ("Use ^q<Tab> for <Tab>.")
00075 #define DISMISS_NAME  ("cancel")
00076 #define DISMISS_NAME_LEN 6
00077 #define FORM_NAME     ("form")
00078 #define LABEL_NAME    ("label")
00079 #define TEXT_NAME     ("text")
00080 
00081 #define R_OFFSET      1
00082 
00083 static void CenterWidgetOnPoint(), PopdownSearch(), DoInsert(), _SetField();
00084 static void InitializeSearchWidget(), SetResource(), SetSearchLabels();
00085 static void DoReplaceOne(), DoReplaceAll();
00086 static Widget CreateDialog(), GetShell();
00087 static void SetWMProtocolTranslations();
00088 static Boolean DoSearch(), SetResourceByName(), Replace();
00089 static String GetString();
00090 
00091 static String GetStringRaw();
00092 
00093 static void AddInsertFileChildren();
00094 static Boolean InsertFileNamed();
00095 static void AddSearchChildren();
00096 
00097 static char radio_trans_string[] =
00098     "<Btn1Down>,<Btn1Up>:   set() notify()";
00099 
00100 static char search_text_trans[] = 
00101   "~Shift<Key>Return:      DoSearchAction(Popdown) \n\
00102    Shift<Key>Return:       DoSearchAction() SetField(Replace) \n\
00103    Ctrl<Key>q,<Key>Tab:    insert-char()    \n\
00104    Ctrl<Key>c:             PopdownSearchAction() \n\
00105    <Btn1Down>:             select-start() SetField(Search) \n\
00106    <Key>Tab:               DoSearchAction() SetField(Replace)";
00107 
00108 static char rep_text_trans[] = 
00109   "~Shift<Key>Return:      DoReplaceAction(Popdown) \n\
00110    Shift<Key>Return:       SetField(Search) \n\
00111    Ctrl<Key>q,<Key>Tab:    insert-char()     \n\
00112    Ctrl<Key>c:             PopdownSearchAction() \n\
00113    <Btn1Down>:             select-start() DoSearchAction() SetField(Replace)\n\
00114    <Key>Tab:               SetField(Search)";
00115 
00116 /************************************************************
00117  * 
00118  * This section of the file contains all the functions that 
00119  * the file insert dialog box uses.
00120  *
00121  ************************************************************/
00122 
00123 /*      Function Name: _XawTextInsertFileAction
00124  *      Description: Action routine that can be bound to dialog box's 
00125  *                   Text Widget that will insert a file into the main
00126  *                   Text Widget.
00127  *      Arguments:   (Standard Action Routine args) 
00128  *      Returns:     none.
00129  */
00130 
00131 /* ARGSUSED */
00132 void 
00133 _XawTextInsertFileAction(w, event, params, num_params)
00134 Widget w;
00135 XEvent *event;
00136 String * params;
00137 Cardinal * num_params;
00138 {
00139   DoInsert(w, (XtPointer) XtParent(XtParent(XtParent(w))), (XtPointer)NULL);
00140 }
00141 
00142 /*      Function Name: _XawTextInsertFile
00143  *      Description: Action routine that can be bound to the text widget
00144  *                   it will popup the insert file dialog box.
00145  *      Arguments:   w - the text widget.
00146  *                   event - X Event (used to get x and y location).
00147  *                   params, num_params - the parameter list.
00148  *      Returns:     none.
00149  *
00150  * NOTE:
00151  *
00152  * The parameter list may contain one entry.
00153  *
00154  *  Entry:  This entry is optional and contains the value of the default
00155  *          file to insert.
00156  */
00157 
00158 void 
00159 _XawTextInsertFile(w, event, params, num_params)
00160 Widget w;
00161 XEvent *event;
00162 String * params;
00163 Cardinal * num_params;
00164 {
00165   TextWidget ctx = (TextWidget)w;
00166   char * ptr;
00167   XawTextEditType edit_mode;
00168   Arg args[1];
00169 
00170   XtSetArg(args[0], XtNeditType,&edit_mode);
00171   XtGetValues(ctx->text.source, args, ONE);
00172   
00173   if (edit_mode != XawtextEdit) {
00174     XBell(XtDisplay(w), 0);
00175     return;
00176   }
00177 
00178   if (*num_params == 0) 
00179     ptr = "";
00180   else 
00181     ptr = params[0];
00182     
00183   if (!ctx->text.file_insert) {
00184     ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
00185                                          AddInsertFileChildren);
00186     XtRealizeWidget(ctx->text.file_insert);
00187     SetWMProtocolTranslations(ctx->text.file_insert);
00188   }
00189 
00190   CenterWidgetOnPoint(ctx->text.file_insert, event);
00191   XtPopup(ctx->text.file_insert, XtGrabNone);
00192 }
00193 
00194 /*      Function Name: PopdownFileInsert
00195  *      Description: Pops down the file insert button.
00196  *      Arguments: w - the widget that caused this action.
00197  *                 closure - a pointer to the main text widget that
00198  *                           popped up this dialog.
00199  *                 call_data - *** NOT USED ***.
00200  *      Returns: none.
00201  */
00202 
00203 /* ARGSUSED */
00204 static void 
00205 PopdownFileInsert(w, closure, call_data)
00206 Widget w;                       /* The Dialog Button Pressed. */
00207 XtPointer closure;              /* Text Widget. */
00208 XtPointer call_data;            /* unused */
00209 {
00210   TextWidget ctx = (TextWidget) closure;
00211 
00212   XtPopdown( ctx->text.file_insert );
00213   (void) SetResourceByName( ctx->text.file_insert, LABEL_NAME, 
00214                            XtNlabel, (XtArgVal) INSERT_FILE);
00215 }
00216 
00217 /*      Function Name: DoInsert
00218  *      Description: Actually insert the file named in the text widget
00219  *                   of the file dialog.
00220  *      Arguments:   w - the widget that activated this callback.
00221  *                   closure - a pointer to the text widget to insert the
00222  *                             file into.
00223  *      Returns: none.
00224  */
00225 
00226 /* ARGSUSED */
00227 static void 
00228 DoInsert(w, closure, call_data)
00229 Widget w;                       /* The Dialog Button Pressed. */
00230 XtPointer closure;              /* Text Widget */
00231 XtPointer call_data;            /* unused */
00232 {
00233   TextWidget ctx = (TextWidget) closure;
00234   char buf[BUFSIZ], msg[BUFSIZ];
00235   Widget temp_widget;
00236 
00237   (void) sprintf(buf, "%s.%s", FORM_NAME, TEXT_NAME);
00238   if ( (temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL ) {
00239     (void) strcpy(msg, 
00240            "*** Error: Could not get text widget from file insert popup");
00241   }
00242   else 
00243     if (InsertFileNamed( (Widget) ctx, GetString( temp_widget ))) {
00244       PopdownFileInsert(w, closure, call_data);
00245       return;
00246     }
00247     else
00248       (void) sprintf( msg, "*** Error: %s ***", strerror(errno));
00249 
00250   (void)SetResourceByName(ctx->text.file_insert, 
00251                           LABEL_NAME, XtNlabel, (XtArgVal) msg);
00252   XBell(XtDisplay(w), 0);
00253 }
00254 
00255 /*      Function Name: InsertFileNamed
00256  *      Description: Inserts a file into the text widget.
00257  *      Arguments: tw - The text widget to insert this file into.
00258  *                 str - name of the file to insert.
00259  *      Returns: TRUE if the insert was sucessful, FALSE otherwise.
00260  */
00261 
00262 
00263 static Boolean
00264 InsertFileNamed(tw, str)
00265 Widget tw;
00266 char *str;
00267 {
00268   FILE *file;
00269   XawTextBlock text;
00270   XawTextPosition pos;
00271 
00272   if ( (str == NULL) || (strlen(str) == 0) || 
00273        ((file = fopen(str, "r")) == NULL))
00274     return(FALSE);
00275 
00276   pos = XawTextGetInsertionPoint(tw);
00277 
00278   fseek(file, 0L, 2);
00279 
00280 
00281   text.firstPos = 0;
00282   text.length = (ftell(file))/sizeof(unsigned char);
00283   text.ptr = XtMalloc((text.length + 1) * sizeof(unsigned char));
00284   text.format = XawFmt8Bit;
00285 
00286   fseek(file, 0L, 0);
00287   if (fread(text.ptr, sizeof(unsigned char), text.length, file) != text.length)
00288       XtErrorMsg("readError", "insertFileNamed", "XawError",
00289                  "fread returned error.", NULL, NULL);
00290 
00291  /* DELETE if (text.format == XawFmtWide) {
00292      wchar_t* _XawTextMBToWC();
00293      wchar_t* wstr;
00294      wstr = _XawTextMBToWC(XtDisplay(tw), text.ptr, &(text.length));
00295      wstr[text.length] = NULL;
00296      XtFree(text.ptr);
00297      text.ptr = (char *)wstr;
00298   } else {
00299      (text.ptr)[text.length] = '\0';
00300   }*/
00301 
00302   if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
00303      XtFree(text.ptr);
00304      fclose(file);
00305      return(FALSE);
00306   }
00307   pos += text.length;
00308   XtFree(text.ptr);
00309   fclose(file);
00310   XawTextSetInsertionPoint(tw, pos);
00311   return(TRUE);
00312 }
00313 
00314 
00315 /*      Function Name: AddInsertFileChildren
00316  *      Description: Adds all children to the InsertFile dialog widget.
00317  *      Arguments: form - the form widget for the insert dialog widget.
00318  *                 ptr - a pointer to the initial string for the Text Widget.
00319  *                 tw - the main text widget.
00320  *      Returns: none
00321  */
00322 
00323 static void
00324 AddInsertFileChildren(form, ptr, tw)
00325 Widget form, tw;
00326 char * ptr;
00327 {
00328   Arg args[10];
00329   Cardinal num_args;
00330   Widget label, text, cancel, insert;
00331   XtTranslations trans;
00332 
00333   num_args = 0;
00334   XtSetArg(args[num_args], XtNlabel, INSERT_FILE);num_args++;
00335   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00336   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00337   XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
00338   XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
00339   label = XtCreateManagedWidget (LABEL_NAME, labelWidgetClass, form, 
00340                                  args, num_args);
00341   
00342   num_args = 0;
00343   XtSetArg(args[num_args], XtNfromVert, label); num_args++;
00344   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00345   XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
00346   XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
00347   XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
00348   XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
00349   XtSetArg(args[num_args], XtNstring, ptr); num_args++;
00350   text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
00351                                 args, num_args);
00352 
00353   num_args = 0;
00354   XtSetArg(args[num_args], XtNlabel, "Insert File"); num_args++;
00355   XtSetArg(args[num_args], XtNfromVert, text); num_args++;
00356   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00357   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00358   insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
00359                                  args, num_args);
00360 
00361   num_args = 0;
00362   XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
00363   XtSetArg(args[num_args], XtNfromVert, text); num_args++;
00364   XtSetArg(args[num_args], XtNfromHoriz, insert); num_args++;
00365   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00366   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00367   cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
00368                                  args, num_args);
00369 
00370   XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer) tw);
00371   XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer) tw);
00372 
00373   XtSetKeyboardFocus(form, text);
00374 
00375 /*
00376  * Bind <CR> to insert file.
00377  */
00378 
00379   trans = XtParseTranslationTable("<Key>Return: InsertFileAction()");
00380   XtOverrideTranslations(text, trans);
00381 
00382 }
00383 
00384 /************************************************************
00385  * 
00386  * This section of the file contains all the functions that 
00387  * the search dialog box uses.
00388  *
00389  ************************************************************/
00390 
00391 /*      Function Name: _XawTextDoSearchAction
00392  *      Description: Action routine that can be bound to dialog box's 
00393  *                   Text Widget that will search for a string in the main 
00394  *                   Text Widget.
00395  *      Arguments:   (Standard Action Routine args) 
00396  *      Returns:     none.
00397  *
00398  * Note:
00399  * 
00400  * If the search was sucessful and the argument popdown is passed to
00401  * this action routine then the widget will automatically popdown the 
00402  * search widget.
00403  */
00404 
00405 /* ARGSUSED */
00406 void 
00407 _XawTextDoSearchAction(w, event, params, num_params)
00408 Widget w;
00409 XEvent *event;
00410 String * params;
00411 Cardinal * num_params;
00412 {
00413   TextWidget tw = (TextWidget) XtParent(XtParent(XtParent(w)));
00414   Boolean popdown = FALSE;
00415 
00416   if ( (*num_params == 1) &&
00417        ((params[0][0] == 'p') || (params[0][0] == 'P')) )
00418       popdown = TRUE;
00419     
00420   if (DoSearch(tw->text.search) && popdown)
00421     PopdownSearch(w, (XtPointer) tw->text.search, (XtPointer)NULL);
00422 }
00423 
00424 /*      Function Name: _XawTextPopdownSearchAction
00425  *      Description: Action routine that can be bound to dialog box's 
00426  *                   Text Widget that will popdown the search widget.
00427  *      Arguments:   (Standard Action Routine args) 
00428  *      Returns:     none.
00429  */
00430 
00431 /* ARGSUSED */
00432 void 
00433 _XawTextPopdownSearchAction(w, event, params, num_params)
00434 Widget w;
00435 XEvent *event;
00436 String * params;
00437 Cardinal * num_params;
00438 {
00439   TextWidget tw = (TextWidget) XtParent(XtParent(XtParent(w)));
00440 
00441   PopdownSearch(w, (XtPointer) tw->text.search, (XtPointer)NULL);
00442 }
00443 
00444 /*      Function Name: PopdownSeach
00445  *      Description: Pops down the search widget and resets it.
00446  *      Arguments: w - *** NOT USED ***.
00447  *                 closure - a pointer to the search structure.
00448  *                 call_data - *** NOT USED ***.
00449  *      Returns: none
00450  */
00451 
00452 /* ARGSUSED */
00453 static void 
00454 PopdownSearch(w, closure, call_data)
00455 Widget w;                       
00456 XtPointer closure;              
00457 XtPointer call_data;            
00458 {
00459   struct SearchAndReplace * search = (struct SearchAndReplace *) closure;
00460 
00461   XtPopdown( search->search_popup );
00462   SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, FALSE);
00463 }
00464 
00465 /*      Function Name: SearchButton
00466  *      Description: Performs a search when the button is clicked.
00467  *      Arguments: w - *** NOT USED **.
00468  *                 closure - a pointer to the search info.
00469  *                 call_data - *** NOT USED ***.
00470  *      Returns: 
00471  */
00472 
00473 /* ARGSUSED */
00474 static void 
00475 SearchButton(w, closure, call_data)
00476 Widget w;                       
00477 XtPointer closure;              
00478 XtPointer call_data;
00479 {
00480   (void) DoSearch( (struct SearchAndReplace *) closure );
00481 }
00482 
00483 /*      Function Name: _XawTextSearch
00484  *      Description: Action routine that can be bound to the text widget
00485  *                   it will popup the search dialog box.
00486  *      Arguments:   w - the text widget.
00487  *                   event - X Event (used to get x and y location).
00488  *                   params, num_params - the parameter list.
00489  *      Returns:     none.
00490  *
00491  * NOTE:
00492  *
00493  * The parameter list contains one or two entries that may be the following.
00494  *
00495  * First Entry:   The first entry is the direction to search by default.
00496  *                This arguement must be specified and may have a value of
00497  *                "left" or "right".
00498  *
00499  * Second Entry:  This entry is optional and contains the value of the default
00500  *                string to search for.
00501  */
00502 
00503 #define SEARCH_HEADER ("Text Widget - Search():")
00504 
00505 void 
00506 _XawTextSearch(w, event, params, num_params)
00507 Widget w;
00508 XEvent *event;
00509 String * params;
00510 Cardinal * num_params;
00511 {
00512   TextWidget ctx = (TextWidget)w;
00513   XawTextScanDirection dir;
00514   char * ptr, buf[BUFSIZ];
00515   XawTextEditType edit_mode;
00516   Arg args[1];
00517 
00518 #ifdef notdef
00519   if (ctx->text.source->Search == NULL) {
00520       XBell(XtDisplay(w), 0);
00521       return;
00522   }
00523 #endif
00524 
00525   if ( (*num_params < 1) || (*num_params > 2) ) {
00526     (void) sprintf(buf, "%s %s\n%s", SEARCH_HEADER, 
00527             "This action must have only", 
00528             "one or two parameters");
00529     XtAppWarning(XtWidgetToApplicationContext(w), buf);
00530     return;
00531   }
00532 
00533   if (*num_params == 2 )
00534       ptr = params[1];
00535   else
00536       if (_XawTextFormat(ctx) == XawFmtWide) {
00537           /*This just does the equivalent of ptr = ""L, a waste because params[1] isnt W aligned.*/
00538           ptr = (char *)XtMalloc(sizeof(wchar_t));
00539           *((wchar_t*)ptr) = (wchar_t)0;
00540       } else
00541           ptr = "";
00542 
00543   switch(params[0][0]) {
00544   case 'b':                     /* Left. */
00545   case 'B':
00546     dir = XawsdLeft;
00547     break;
00548   case 'f':                     /* Right. */
00549   case 'F':
00550     dir = XawsdRight;
00551     break;
00552   default:
00553     (void) sprintf(buf, "%s %s\n%s", SEARCH_HEADER, 
00554             "The first parameter must be",
00555             "Either 'backward' or 'forward'");
00556     XtAppWarning(XtWidgetToApplicationContext(w), buf);
00557     return;
00558   }
00559 
00560   if (ctx->text.search== NULL) {
00561     ctx->text.search = XtNew(struct SearchAndReplace);
00562     ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
00563                                                   AddSearchChildren);
00564     XtRealizeWidget(ctx->text.search->search_popup);
00565     SetWMProtocolTranslations(ctx->text.search->search_popup);
00566   }
00567   else if (*num_params > 1) {
00568     XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
00569   }
00570 
00571   XtSetArg(args[0], XtNeditType,&edit_mode);
00572   XtGetValues(ctx->text.source, args, ONE);
00573 
00574   InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
00575 
00576   CenterWidgetOnPoint(ctx->text.search->search_popup, event);
00577   XtPopup(ctx->text.search->search_popup, XtGrabNone);
00578 }
00579 
00580 /*      Function Name: InitializeSearchWidget
00581  *      Description: This function initializes the search widget and
00582  *                   is called each time the search widget is poped up.
00583  *      Arguments: search - the search widget structure.
00584  *                 dir - direction to search. 
00585  *                 replace_active - state of the sensitivity for the 
00586  *                                  replace button.
00587  *      Returns: none.
00588  */
00589 
00590 static void
00591 InitializeSearchWidget(search, dir, replace_active)
00592 struct SearchAndReplace * search;
00593 XawTextScanDirection dir;
00594 Boolean replace_active;
00595 {
00596   SetResource(search->rep_one, XtNsensitive, (XtArgVal) replace_active);
00597   SetResource(search->rep_all, XtNsensitive, (XtArgVal) replace_active);
00598   SetResource(search->rep_label, XtNsensitive, (XtArgVal) replace_active);
00599   SetResource(search->rep_text, XtNsensitive, (XtArgVal) replace_active);
00600 
00601   switch (dir) {
00602   case XawsdLeft:
00603     SetResource(search->left_toggle, XtNstate, (XtArgVal) TRUE);
00604     break;
00605   case XawsdRight:
00606     SetResource(search->right_toggle, XtNstate, (XtArgVal) TRUE);
00607     break;
00608   default:
00609     break;
00610   }
00611 }  
00612 
00613 /*      Function Name: AddSearchChildren
00614  *      Description: Adds all children to the Search Dialog Widget.
00615  *      Arguments: form - the form widget for the search widget.
00616  *                 ptr - a pointer to the initial string for the Text Widget.
00617  *                 tw - the main text widget.
00618  *      Returns: none.
00619  */
00620 
00621 static void
00622 AddSearchChildren(form, ptr, tw)
00623 Widget form, tw;
00624 char * ptr;
00625 {
00626   Arg args[10];
00627   Cardinal num_args;
00628   Widget cancel, search_button, s_label, s_text, r_text;
00629   XtTranslations trans;
00630   struct SearchAndReplace * search = ((TextWidget) tw)->text.search;
00631 
00632   num_args = 0;
00633   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00634   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00635   XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
00636   XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
00637   search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
00638                                          args, num_args);
00639 
00640   num_args = 0;
00641   XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
00642   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00643   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00644   XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
00645   XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
00646   search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
00647                                          args, num_args);
00648   
00649 /* 
00650  * We need to add R_OFFSET to the radio_data, because the value zero (0)
00651  * has special meaning.
00652  */
00653 
00654   num_args = 0;
00655   XtSetArg(args[num_args], XtNlabel, "Backward"); num_args++;
00656   XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
00657   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00658   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00659   XtSetArg(args[num_args], XtNradioData, (XPointer) XawsdLeft + R_OFFSET);
00660   num_args++;
00661   search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
00662                                               form, args, num_args);
00663 
00664   num_args = 0;
00665   XtSetArg(args[num_args], XtNlabel, "Forward"); num_args++;
00666   XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
00667   XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
00668   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00669   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00670   XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
00671   XtSetArg(args[num_args], XtNradioData, (XPointer) XawsdRight + R_OFFSET);
00672   num_args++;
00673   search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
00674                                                form, args, num_args);
00675 
00676   {
00677     XtTranslations radio_translations;
00678 
00679     radio_translations = XtParseTranslationTable(radio_trans_string);
00680     XtOverrideTranslations(search->left_toggle, radio_translations);
00681     XtOverrideTranslations(search->right_toggle, radio_translations);
00682   }
00683 
00684   num_args = 0;
00685   XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
00686   XtSetArg(args[num_args], XtNlabel, "Search for:  ");num_args++;
00687   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00688   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00689   XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
00690   s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
00691                                   args, num_args);
00692 
00693   num_args = 0;
00694   XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
00695   XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
00696   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00697   XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
00698   XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
00699   XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
00700   XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
00701   XtSetArg(args[num_args], XtNstring, ptr); num_args++;
00702   s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
00703                                  args, num_args);
00704   search->search_text = s_text;
00705 
00706   num_args = 0;
00707   XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
00708   XtSetArg(args[num_args], XtNlabel, "Replace with:");num_args++;
00709   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00710   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00711   XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
00712   search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
00713                                             form, args, num_args);
00714 
00715   num_args = 0;
00716   XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
00717   XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
00718   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00719   XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
00720   XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
00721   XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
00722   XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
00723   XtSetArg(args[num_args], XtNstring, ""); num_args++;
00724   r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
00725                                  form, args, num_args);
00726   search->rep_text = r_text;
00727   
00728   num_args = 0;
00729   XtSetArg(args[num_args], XtNlabel, "Search"); num_args++;
00730   XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
00731   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00732   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00733   search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
00734                                         args, num_args);
00735 
00736   num_args = 0;
00737   XtSetArg(args[num_args], XtNlabel, "Replace"); num_args++;
00738   XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
00739   XtSetArg(args[num_args], XtNfromHoriz, search_button); num_args++;
00740   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00741   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00742   search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
00743                                           form, args, num_args);
00744 
00745   num_args = 0;
00746   XtSetArg(args[num_args], XtNlabel, "Replace All"); num_args++;
00747   XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
00748   XtSetArg(args[num_args], XtNfromHoriz, search->rep_one); num_args++;
00749   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00750   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00751   search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
00752                                           form, args, num_args);
00753 
00754   num_args = 0;
00755   XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
00756   XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
00757   XtSetArg(args[num_args], XtNfromHoriz, search->rep_all); num_args++;
00758   XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
00759   XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
00760   cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
00761                                  args, num_args);
00762 
00763   XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer) search);
00764   XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer) search);
00765   XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer) search);
00766   XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer) search);
00767 
00768 /*
00769  * Initialize the text entry fields.
00770  */
00771 
00772   {
00773     Pixel color;
00774     num_args = 0;
00775     XtSetArg(args[num_args], XtNbackground, &color); num_args++;
00776     XtGetValues(search->rep_text, args, num_args);
00777     num_args = 0;
00778     XtSetArg(args[num_args], XtNborderColor, color); num_args++;
00779     XtSetValues(search->rep_text, args, num_args);
00780     XtSetKeyboardFocus(form, search->search_text);
00781   }
00782 
00783   SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, FALSE);
00784 
00785 /*
00786  * Bind Extra translations.
00787  */
00788 
00789   trans = XtParseTranslationTable(search_text_trans);
00790   XtOverrideTranslations(search->search_text, trans);
00791 
00792   trans = XtParseTranslationTable(rep_text_trans);
00793   XtOverrideTranslations(search->rep_text, trans);
00794 }
00795 
00796 /*      Function Name: DoSearch
00797  *      Description: Performs a search.
00798  *      Arguments: search - the serach structure.
00799  *      Returns: TRUE if sucessful.
00800  */
00801 
00802 /* ARGSUSED */
00803 static Boolean
00804 DoSearch(search)
00805 struct SearchAndReplace * search;
00806 {
00807   char msg[BUFSIZ];
00808   Widget tw = XtParent(search->search_popup);
00809   XawTextPosition pos;
00810   XawTextScanDirection dir;
00811   XawTextBlock text;
00812 
00813   TextWidget ctx = (TextWidget)tw;
00814 
00815   text.ptr = GetStringRaw(search->search_text);
00816   if ((text.format = _XawTextFormat(ctx)) == XawFmtWide)
00817       text.length = wcslen((wchar_t*)text.ptr);
00818   else
00819       text.length = strlen(text.ptr);
00820   text.firstPos = 0;
00821   
00822   dir = (XawTextScanDirection)(int) ((XPointer)XawToggleGetCurrent(search->left_toggle) -
00823                                 R_OFFSET);
00824   
00825   pos = XawTextSearch( tw, dir, &text);
00826 
00827 
00828    /* The Raw string in find.ptr may be WC I can't use here, so I re - call 
00829    GetString to get a tame version. */
00830 
00831   if (pos == XawTextSearchError) 
00832     (void) sprintf( msg, "Could not find string ``%s''.", GetString( search->search_text ) );
00833   else {
00834     if (dir == XawsdRight)
00835       XawTextSetInsertionPoint( tw, pos + text.length);
00836     else
00837       XawTextSetInsertionPoint( tw, pos);
00838     
00839     XawTextSetSelection( tw, pos, pos + text.length);
00840     search->selection_changed = FALSE; /* selection is good. */
00841     return(TRUE);
00842   }
00843   
00844   XawTextUnsetSelection(tw);
00845   SetSearchLabels(search, msg, "", TRUE);
00846   return(FALSE);
00847 }
00848 
00849 /************************************************************
00850  * 
00851  * This section of the file contains all the functions that 
00852  * the replace dialog box uses.
00853  *
00854  ************************************************************/
00855 
00856 /*      Function Name: _XawTextDoReplaceAction
00857  *      Description: Action routine that can be bound to dialog box's 
00858  *                   Text Widget that will replace a string in the main 
00859  *                   Text Widget.
00860  *      Arguments:   (Standard Action Routine args) 
00861  *      Returns:     none.
00862  */
00863 
00864 /* ARGSUSED */
00865 void 
00866 _XawTextDoReplaceAction(w, event, params, num_params)
00867 Widget w;
00868 XEvent *event;
00869 String * params;
00870 Cardinal * num_params;
00871 {
00872   TextWidget ctx = (TextWidget) XtParent(XtParent(XtParent(w)));
00873   Boolean popdown = FALSE;
00874 
00875   if ( (*num_params == 1) &&
00876        ((params[0][0] == 'p') || (params[0][0] == 'P')) )
00877     popdown = TRUE;
00878 
00879   if (Replace( ctx->text.search, TRUE, popdown) && popdown)
00880     PopdownSearch(w, (XtPointer) ctx->text.search, (XtPointer)NULL);
00881 }
00882 
00883 /*      Function Name: DoReplaceOne
00884  *      Description:  Replaces the first instance of the string
00885  *                     in the search dialog's text widget
00886  *                    with the one in the replace dialog's text widget.
00887  *      Arguments: w - *** Not Used ***.
00888  *                 closure - a pointer to the search structure.
00889  *                 call_data - *** Not Used ***.
00890  *      Returns: none.
00891  */
00892 
00893 /* ARGSUSED */
00894 static void 
00895 DoReplaceOne(w, closure, call_data)
00896 Widget w;                       /* The Button Pressed. */
00897 XtPointer closure;              /* Text Widget. */
00898 XtPointer call_data;            /* unused */
00899 {
00900   Replace( (struct SearchAndReplace *) closure, TRUE, FALSE);
00901 }
00902 
00903 /*      Function Name: DoReplaceOne
00904  *      Description:  Replaces every instance of the string
00905  *                    in the search dialog's text widget
00906  *                    with the one in the replace dialog's text widget.
00907  *      Arguments: w - *** Not Used ***.
00908  *                 closure - a pointer to the search structure.
00909  *                 call_data - *** Not Used ***.
00910  *      Returns: none.
00911  */
00912 
00913 /* ARGSUSED */
00914 static void 
00915 DoReplaceAll(w, closure, call_data)
00916 Widget w;                       /* The Button Pressed. */
00917 XtPointer closure;              /* Text Widget. */
00918 XtPointer call_data;            /* unused */
00919 {
00920   Replace( (struct SearchAndReplace *) closure, FALSE, FALSE);
00921 }
00922 
00923 /*      Function Name: Replace
00924  *      Description: This is the function that does the real work of
00925  *                   replacing strings in the main text widget.
00926  *      Arguments: tw - the Text Widget to replce the string in.
00927  *                 once_only - If TRUE then only replace the first one found.
00928  *                             other replace all of them.
00929  *                 show_current - If true then leave the selection on the 
00930  *                                string that was just replaced, otherwise
00931  *                                move it onto the next one.
00932  *      Returns: none.
00933  */
00934 
00935 static Boolean
00936 Replace(search, once_only, show_current)
00937 struct SearchAndReplace * search;
00938 Boolean once_only, show_current;
00939 {
00940   XawTextPosition pos, new_pos, end_pos;
00941   XawTextScanDirection dir;
00942   XawTextBlock find, replace;
00943   Widget tw = XtParent(search->search_popup);
00944   int count = 0;
00945 
00946   TextWidget ctx = (TextWidget)tw;
00947 
00948   find.ptr = GetStringRaw( search->search_text);
00949   if ((find.format = _XawTextFormat(ctx)) == XawFmtWide)
00950       find.length = wcslen((wchar_t*)find.ptr);
00951   else
00952       find.length = strlen(find.ptr);
00953   find.firstPos = 0;
00954 
00955   replace.ptr = GetStringRaw(search->rep_text);
00956   replace.firstPos = 0;
00957   if ((replace.format = _XawTextFormat(ctx)) == XawFmtWide)
00958       replace.length = wcslen((wchar_t*)replace.ptr);
00959   else
00960       replace.length = strlen(replace.ptr);
00961     
00962   dir = (XawTextScanDirection)(int) ((XPointer)XawToggleGetCurrent(search->left_toggle) -
00963                                 R_OFFSET);
00964   /* CONSTCOND */
00965   while (TRUE) {
00966     if (count != 0) {
00967       new_pos = XawTextSearch( tw, dir, &find);
00968       
00969       if ( (new_pos == XawTextSearchError) ) {
00970         if (count == 0) {
00971           char msg[BUFSIZ];
00972 
00973              /* The Raw string in find.ptr may be WC I can't use here, 
00974                 so I call GetString to get a tame version.*/
00975 
00976           (void) sprintf( msg, "%s %s %s", "*** Error: Could not find string ``",
00977                   GetString( search->search_text ), "''. ***");
00978           SetSearchLabels(search, msg, "", TRUE);
00979           return(FALSE);
00980         }
00981         else
00982           break;
00983       }
00984       pos = new_pos;
00985       end_pos = pos + find.length;
00986     }
00987     else {
00988       XawTextGetSelectionPos(tw, &pos, &end_pos);
00989 
00990       if (search->selection_changed) {
00991         SetSearchLabels(search, "Selection has been modified, aborting.",
00992                         "", TRUE);
00993         return(FALSE);
00994       }
00995       if (pos == end_pos) 
00996           return(FALSE);
00997     }
00998 
00999     if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
01000       char msg[BUFSIZ];
01001       
01002       (void) sprintf( msg, "'%s' with '%s'. ***", find.ptr, replace.ptr);
01003       SetSearchLabels(search, "*** Error while replacing", msg, TRUE);
01004       return(FALSE);
01005     }      
01006 
01007     if (dir == XawsdRight)
01008       XawTextSetInsertionPoint( tw, pos + replace.length);
01009     else
01010       XawTextSetInsertionPoint( tw, pos);
01011 
01012     if (once_only) 
01013       if (show_current)
01014         break;
01015       else {
01016         DoSearch(search);
01017         return(TRUE);
01018       }
01019     count++;
01020   }
01021 
01022   if (replace.length == 0)
01023     XawTextUnsetSelection(tw);
01024   else
01025     XawTextSetSelection( tw, pos, pos + replace.length);
01026 
01027   return(TRUE);
01028 }
01029 
01030 /*      Function Name: SetSearchLabels
01031  *      Description: Sets both the search labels, and also rings the bell
01032  *      Arguments: search - the search structure.
01033  *                 msg1, msg2 - message to put in each search label.
01034  *                 bell - if TRUE then ring bell.
01035  *      Returns: none.
01036  */
01037 
01038 static void
01039 SetSearchLabels(search, msg1, msg2, bell)
01040 struct SearchAndReplace * search;
01041 String msg1, msg2;
01042 Boolean bell;
01043 {
01044   (void) SetResource( search->label1, XtNlabel, (XtArgVal) msg1);
01045   (void) SetResource( search->label2, XtNlabel, (XtArgVal) msg2);
01046   if (bell) 
01047     XBell(XtDisplay(search->search_popup), 0);
01048 }
01049 
01050 /************************************************************
01051  * 
01052  * This section of the file contains utility routines used by
01053  * other functions in this file.
01054  *
01055  ************************************************************/
01056 
01057 
01058 /*      Function Name: _XawTextSetField
01059  *      Description: Action routine that can be bound to dialog box's 
01060  *                   Text Widget that will send input to the field specified.
01061  *      Arguments:   (Standard Action Routine args) 
01062  *      Returns:     none.
01063  */
01064 
01065 /* ARGSUSED */
01066 void 
01067 _XawTextSetField(w, event, params, num_params)
01068 Widget w;
01069 XEvent *event;
01070 String * params;
01071 Cardinal * num_params;
01072 {
01073   struct SearchAndReplace * search;
01074   Widget new, old;
01075 
01076   search = ((TextWidget) XtParent(XtParent(XtParent(w))))->text.search;
01077 
01078   if (*num_params != 1) {
01079     SetSearchLabels(search, "*** Error: SetField Action must have",
01080                     "exactly one argument. ***", TRUE);
01081     return;
01082   }
01083   switch (params[0][0]) {
01084   case 's':
01085   case 'S':
01086     new = search->search_text;
01087     old = search->rep_text;
01088     break;
01089   case 'r':
01090   case 'R':
01091     old = search->search_text;
01092     new = search->rep_text;
01093     break;
01094   default:
01095     SetSearchLabels(search, "*** Error: SetField Action's first Argument must",
01096                     "be either 'Search' or 'Replace'. ***", TRUE);
01097     return;
01098   }
01099   _SetField(new, old);
01100 }
01101 
01102 /*      Function Name: SetField
01103  *      Description: Sets the current text field.
01104  *      Arguments: new, old - new and old text fields.
01105  *      Returns: none
01106  */
01107 
01108 static void
01109 _SetField(new, old)
01110 Widget new, old;
01111 {
01112   Arg args[2];
01113   Pixel new_border, old_border, old_bg;
01114 
01115   if (!XtIsSensitive(new)) {
01116     XBell(XtDisplay(old), 0);   /* Don't set field to an inactive Widget. */
01117     return;
01118   }
01119 
01120   XtSetKeyboardFocus(XtParent(new), new); 
01121                                                 
01122   XtSetArg(args[0], XtNborderColor, &old_border);
01123   XtSetArg(args[1], XtNbackground, &old_bg);
01124   XtGetValues(new, args, TWO);
01125 
01126   XtSetArg(args[0], XtNborderColor, &new_border);
01127   XtGetValues(old, args, ONE);
01128 
01129   if (old_border != old_bg)     /* Colors are already correct, return. */
01130       return;
01131 
01132   SetResource(old, XtNborderColor, (XtArgVal) old_border);
01133   SetResource(new, XtNborderColor, (XtArgVal) new_border);
01134 }
01135 
01136 /*      Function Name: SetResourceByName
01137  *      Description: Sets a resource in any of the dialog children given
01138  *                   name of the child and the shell widget of the dialog.
01139  *      Arguments: shell - shell widget of the popup.
01140  *                 name - name of the child.
01141  *                 res_name - name of the resource.
01142  *                 value - the value of the resource.
01143  *      Returns: TRUE if sucessful.
01144  */
01145 
01146 static Boolean
01147 SetResourceByName(shell, name, res_name, value)
01148 Widget shell;
01149 char * name, * res_name;
01150 XtArgVal value;
01151 {
01152   Widget temp_widget;
01153   char buf[BUFSIZ];
01154 
01155   (void) sprintf(buf, "%s.%s", FORM_NAME, name);
01156 
01157   if ( (temp_widget = XtNameToWidget(shell, buf)) != NULL) {
01158     SetResource(temp_widget, res_name, value);
01159     return(TRUE);
01160   }
01161   return(FALSE);
01162 }
01163 
01164 /*      Function Name: SetResource
01165  *      Description: Sets a resource in a widget
01166  *      Arguments: w - the widget.
01167  *                 res_name - name of the resource.
01168  *                 value - the value of the resource.
01169  *      Returns: none.
01170  */
01171 
01172 static void
01173 SetResource(w, res_name, value)
01174 Widget w;
01175 char * res_name;
01176 XtArgVal value;
01177 {
01178   Arg args[1];
01179   
01180   XtSetArg(args[0], res_name, value);
01181   XtSetValues( w, args, ONE );
01182 }
01183 
01184 /*      Function Name: GetString{Raw}
01185  *      Description:   Gets the value for the string in the popup.
01186  *      Arguments:     text - the text widget whose string we will get.
01187  * 
01188  *      GetString returns the string as a MB.
01189  *      GetStringRaw returns the exact buffer contents suitable for a search.
01190  *
01191  */
01192 
01193 static String
01194 GetString(text)
01195 Widget text;
01196 {
01197   String string;
01198   Arg args[1];
01199 
01200   XtSetArg( args[0], XtNstring, &string );
01201   XtGetValues( text, args, ONE );
01202   return(string);
01203 }
01204 
01205 static String
01206 GetStringRaw(tw)
01207 Widget tw;
01208 {
01209   TextWidget ctx = (TextWidget)tw;
01210   XawTextPosition last;
01211   char *_XawTextGetText();
01212 
01213   last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
01214                              ctx->text.mult, TRUE);
01215   return (_XawTextGetText(ctx, 0, last));
01216 }
01217 
01218 /*      Function Name: CenterWidgetOnPoint.
01219  *      Description: Centers a shell widget on a point relative to
01220  *                   the root window.
01221  *      Arguments: w - the shell widget.
01222  *                 event - event containing the location of the point
01223  *      Returns: none.
01224  *
01225  * NOTE: The widget is not allowed to go off the screen.
01226  */
01227 
01228 static void
01229 CenterWidgetOnPoint(w, event)
01230 Widget w;
01231 XEvent *event;
01232 {
01233   Arg args[3];
01234   Cardinal num_args;
01235   Dimension width, height, b_width;
01236   Position x = 0, y = 0, max_x, max_y;
01237   
01238   if (event != NULL) {
01239     switch (event->type) {
01240     case ButtonPress:
01241     case ButtonRelease:
01242       x = event->xbutton.x_root;
01243       y = event->xbutton.y_root;
01244       break;
01245     case KeyPress:
01246     case KeyRelease:
01247       x = event->xkey.x_root;
01248       y = event->xkey.y_root;
01249       break;
01250     default:
01251       return;
01252     }
01253   }
01254   
01255   num_args = 0;
01256   XtSetArg(args[num_args], XtNwidth, &width); num_args++;
01257   XtSetArg(args[num_args], XtNheight, &height); num_args++;
01258   XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
01259   XtGetValues(w, args, num_args);
01260 
01261   width += 2 * b_width;
01262   height += 2 * b_width;
01263 
01264   x -= ( (Position) width/2 );
01265   if (x < 0) x = 0;
01266   if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
01267 
01268   y -= ( (Position) height/2 );
01269   if (y < 0) y = 0;
01270   if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
01271   
01272   num_args = 0;
01273   XtSetArg(args[num_args], XtNx, x); num_args++;
01274   XtSetArg(args[num_args], XtNy, y); num_args++;
01275   XtSetValues(w, args, num_args);
01276 }
01277 
01278 /*      Function Name: CreateDialog
01279  *      Description: Actually creates a dialog.
01280  *      Arguments: parent - the parent of the dialog - the main text widget.
01281  *                 ptr - initial_string for the dialog.
01282  *                 name - name of the dialog.
01283  *                 func - function to create the children of the dialog.
01284  *      Returns: the popup shell of the dialog.
01285  * 
01286  * NOTE:
01287  *
01288  * The function argument is passed the following arguements.
01289  *
01290  * form - the from widget that is the dialog.
01291  * ptr - the initial string for the dialog's text widget.
01292  * parent - the parent of the dialog - the main text widget.
01293  */
01294 
01295 static Widget
01296 CreateDialog(parent, ptr, name, func)
01297 Widget parent;
01298 String ptr, name;
01299 void (*func)();
01300 {
01301   Widget popup, form;
01302   Arg args[5];
01303   Cardinal num_args;
01304 
01305   num_args = 0;
01306   XtSetArg(args[num_args], XtNiconName, name); num_args++;
01307   XtSetArg(args[num_args], XtNgeometry, NULL); num_args++;
01308   XtSetArg(args[num_args], XtNallowShellResize, TRUE); num_args++;
01309   XtSetArg(args[num_args], XtNtransientFor, GetShell(parent)); num_args++;
01310   popup = XtCreatePopupShell(name, transientShellWidgetClass, 
01311                              parent, args, num_args);
01312   
01313   form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup,
01314                                (ArgList)NULL, ZERO);
01315   XtManageChild (form);
01316 
01317   (*func) (form, ptr, parent);
01318   return(popup);
01319 }
01320 
01321  /*     Function Name: GetShell
01322   *     Description: Walks up the widget hierarchy to find the
01323   *             nearest shell widget.
01324   *     Arguments: w - the widget whose parent shell should be returned.
01325   *     Returns: The shell widget among the ancestors of w that is the
01326   *             fewest levels up in the widget hierarchy.
01327   */
01328  
01329 static Widget
01330 GetShell(w)
01331 Widget w;
01332 {
01333     while ((w != NULL) && !XtIsShell(w))
01334         w = XtParent(w);
01335     
01336     return (w);
01337 }
01338 
01339 static Boolean InParams(str, p, n)
01340     String str;
01341     String *p;
01342     Cardinal n;
01343 {
01344     int i;
01345     for (i=0; i < n; p++, i++)
01346         if (! XmuCompareISOLatin1(*p, str)) return True;
01347     return False;
01348 }
01349 
01350 static char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
01351 
01352 static void WMProtocols(w, event, params, num_params)
01353     Widget w;           /* popup shell */
01354     XEvent *event;
01355     String *params;
01356     Cardinal *num_params;
01357 {
01358     Atom wm_delete_window;
01359     Atom wm_protocols;
01360 
01361     wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
01362     wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
01363 
01364     /* Respond to a recognized WM protocol request iff 
01365      * event type is ClientMessage and no parameters are passed, or
01366      * event type is ClientMessage and event data is matched to parameters, or
01367      * event type isn't ClientMessage and parameters make a request.
01368      */
01369 #define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
01370 
01371     if ((event->type == ClientMessage &&
01372          event->xclient.message_type == wm_protocols &&
01373          event->xclient.data.l[0] == wm_delete_window &&
01374          (*num_params == 0 || DO_DELETE_WINDOW))
01375         || 
01376         (event->type != ClientMessage && DO_DELETE_WINDOW)) {
01377 
01378 #undef DO_DELETE_WINDOW
01379 
01380         Widget cancel;
01381         char descendant[DISMISS_NAME_LEN + 2];
01382         (void) sprintf(descendant, "*%s", DISMISS_NAME);
01383         cancel = XtNameToWidget(w, descendant);
01384         if (cancel) XtCallCallbacks(cancel, XtNcallback, (XtPointer)NULL);
01385     }
01386 }
01387 
01388 static void SetWMProtocolTranslations(w)
01389     Widget      w;      /* realized popup shell */
01390 {
01391     int i;
01392     XtAppContext app_context;
01393     Atom wm_delete_window;
01394     static XtTranslations compiled_table;       /* initially 0 */
01395     static XtAppContext *app_context_list;      /* initially 0 */
01396     static Cardinal list_size;                  /* initially 0 */
01397 
01398     app_context = XtWidgetToApplicationContext(w);
01399 
01400     /* parse translation table once */
01401     if (! compiled_table) compiled_table = XtParseTranslationTable
01402         ("<Message>WM_PROTOCOLS: XawWMProtocols()\n");
01403 
01404     /* add actions once per application context */
01405     for (i=0; i < list_size && app_context_list[i] != app_context; i++) ;
01406     if (i == list_size) {
01407         XtActionsRec actions[1];
01408         actions[0].string = "XawWMProtocols";
01409         actions[0].proc = WMProtocols;
01410         list_size++;
01411         app_context_list = (XtAppContext *) XtRealloc
01412             ((char *)app_context_list, list_size * sizeof(XtAppContext));
01413         XtAppAddActions(app_context, actions, 1);
01414         app_context_list[i] = app_context;
01415     }
01416 
01417     /* establish communication between the window manager and each shell */
01418     XtAugmentTranslations(w, compiled_table);
01419     wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
01420     (void) XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);
01421 }

Generated on Sun Mar 4 15:03:55 2007 for Scilab [trunk] by  doxygen 1.5.1