protoize most of the function prototypes
[nvi.git] / motif_l / m_search.c
blob321a79395106bf24dac4808740f97b0333189247
1 /*-
2 * Copyright (c) 1996
3 * Rob Zimmermann. All rights reserved.
4 * Copyright (c) 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: m_search.c,v 8.13 2001/06/25 15:19:28 skimo Exp $ (Berkeley) $Date: 2001/06/25 15:19:28 $";
14 #endif /* not lint */
16 #include <sys/queue.h>
18 /* context */
19 #include <X11/X.h>
20 #include <X11/Intrinsic.h>
21 #include <Xm/DialogS.h>
22 #include <Xm/Form.h>
23 #include <Xm/Label.h>
24 #include <Xm/PushBG.h>
25 #include <Xm/TextF.h>
26 #include <Xm/ToggleB.h>
27 #include <Xm/RowColumn.h>
29 #include <bitstring.h>
30 #include <stdio.h>
31 #include <stdlib.h>
33 #include "../common/common.h"
34 #include "../ipc/ip.h"
35 #include "m_motif.h"
37 extern int vi_ofd;
40 /* types */
42 typedef struct sds {
43 struct sds *next;
44 Widget shell;
45 } save_dialog;
47 static save_dialog *dialogs = NULL;
49 typedef struct {
50 String name;
51 void (*cb)();
52 } ButtonData;
55 /* globals and constants */
57 static String PatternWidget = "text";
58 static String pattern = NULL;
60 static optData search_toggles[] = {
61 { optToggle, "extended", NULL, VI_SEARCH_EXT },
62 { optToggle, "iclower", NULL, VI_SEARCH_ICL },
63 { optToggle, "ignorecase", NULL, VI_SEARCH_IC },
64 { optToggle, "literal", NULL, VI_SEARCH_LIT },
65 { optToggle, "searchincr", NULL, VI_SEARCH_INCR },
66 { optToggle, "wrapscan", NULL, VI_SEARCH_WR },
67 { optTerminator, },
70 static void done_func __P((Widget));
71 static void next_func __P((Widget));
72 static void prev_func __P((Widget));
73 static void search __P((Widget, int));
75 static ButtonData button_data[] = {
76 { "Next", next_func },
77 { "Previous", prev_func },
78 { "Cancel", done_func } /* always last */
82 /* Xt utilities */
84 #if defined(__STDC__)
85 static Widget get_child_widget( Widget parent, String name )
86 #else
87 static Widget get_child_widget( parent, name )
88 Widget parent;
89 String name;
90 #endif
92 char buffer[1024];
94 strcpy( buffer, "*" );
95 strcat( buffer, name );
96 return XtNameToWidget( parent, buffer );
100 /* sync the global state */
102 #if defined(__STDC__)
103 static void get_state( Widget w )
104 #else
105 static void get_state( w )
106 Widget w;
107 #endif
109 #if defined(SelfTest)
110 int i;
111 #endif
112 Widget shell = w;
114 /* get all the data from the root of the widget tree */
115 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
117 #if defined(SelfTest)
118 /* which flags? */
119 for (i=0; i<XtNumber(toggle_data); i++) {
120 if (( w = get_child_widget( shell, toggle_data[i].name )) != NULL ) {
121 XtVaGetValues( w, XmNset, &toggle_data[i].value, 0 );
124 #endif
126 /* what's the pattern? */
127 if (( w = get_child_widget( shell, PatternWidget )) != NULL ) {
128 if ( pattern != NULL ) XtFree( pattern );
129 pattern = XmTextFieldGetString( w );
134 /* Translate the user's actions into nvi commands */
136 * next_func --
137 * Action for next button.
139 static void
140 next_func(Widget w)
142 search(w, 0);
146 * prev_func --
147 * Action for previous button.
149 static void
150 prev_func(Widget w)
152 search(w, VI_SEARCH_REV);
156 * search --
157 * Perform the search.
159 static void
160 search(Widget w, int flags)
162 IP_BUF ipb;
163 optData *opt;
164 Widget shell;
166 shell = w;
167 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
169 /* Get current data from the root of the widget tree?
170 * Do it if we are a child of a dialog shell (assume we
171 * are a 'Find' dialog). Otherwise don't (we are the child
172 * of a menu and being invoked via accelerator)
174 if (XmIsDialogShell(shell))
175 get_state(w);
177 /* no pattern? probably, we haven't posted a search dialog yet.
178 * there ought to be a better thing to do here.
180 if ( pattern == NULL ) {
181 vi_info_message( w, "No previous string specified" );
182 return;
185 ipb.str1 = pattern;
186 ipb.len1 = strlen(pattern);
188 /* Initialize the search flags based on the buttons. */
189 ipb.val1 = flags;
190 for (opt = search_toggles; opt->kind != optTerminator; ++opt)
191 if (opt->value != NULL)
192 ipb.val1 |= opt->flags;
194 ipb.code = VI_C_SEARCH;
195 vi_send(vi_ofd, "a1", &ipb);
198 #if defined(__STDC__)
199 static void done_func( Widget w )
200 #else
201 static void done_func( w )
202 Widget w;
203 #endif
205 save_dialog *ptr;
207 #if defined(SelfTest)
208 puts( XtName(w) );
209 #endif
211 while ( ! XtIsShell(w) ) w = XtParent(w);
212 XtPopdown( w );
214 /* save it for later */
215 ptr = (save_dialog *) malloc( sizeof(save_dialog) );
216 ptr->next = dialogs;
217 ptr->shell = w;
218 dialogs = ptr;
222 /* create a set of push buttons */
224 #define SpacingRatio 4 /* 3:1 button to spaces */
226 #if defined(__STDC__)
227 static Widget create_push_buttons( Widget parent,
228 ButtonData *data,
229 int count
231 #else
232 static Widget create_push_buttons( parent, data, count )
233 Widget parent;
234 ButtonData *data;
235 int count;
236 #endif
238 Widget w, form;
239 int pos = 1, base;
241 base = SpacingRatio*count + 1;
242 form = XtVaCreateManagedWidget( "buttons",
243 xmFormWidgetClass,
244 parent,
245 XmNleftAttachment, XmATTACH_FORM,
246 XmNrightAttachment, XmATTACH_FORM,
247 XmNfractionBase, base,
248 XmNshadowType, XmSHADOW_ETCHED_IN,
249 XmNshadowThickness, 2,
250 XmNverticalSpacing, 4,
254 while ( count-- > 0 ) {
255 w = XtVaCreateManagedWidget(data->name,
256 xmPushButtonGadgetClass,
257 form,
258 XmNtopAttachment, XmATTACH_FORM,
259 XmNbottomAttachment,XmATTACH_FORM,
260 XmNleftAttachment, XmATTACH_POSITION,
261 XmNleftPosition, pos,
262 XmNshowAsDefault, False,
263 XmNrightAttachment, XmATTACH_POSITION,
264 XmNrightPosition, pos+SpacingRatio-1,
267 XtAddCallback( w, XmNactivateCallback, data->cb, 0 );
268 pos += SpacingRatio;
269 data++;
272 /* last button is 'cancel' */
273 XtVaSetValues( XtParent(form), XmNcancelButton, w, 0 );
275 return form;
279 /* create a set of check boxes */
281 #if defined(SelfTest)
283 #if defined(__STDC__)
284 static Widget create_check_boxes( Widget parent,
285 ToggleData *toggles,
286 int count
288 #else
289 static Widget create_check_boxes( parent, toggles, count )
290 Widget parent;
291 ToggleData *toggles;
292 int count;
293 #endif
295 Widget form;
296 int pos = 1, base;
298 base = SpacingRatio*count +1;
299 form = XtVaCreateManagedWidget( "toggles",
300 xmFormWidgetClass,
301 parent,
302 XmNleftAttachment, XmATTACH_FORM,
303 XmNrightAttachment, XmATTACH_FORM,
304 XmNfractionBase, base,
305 XmNverticalSpacing, 4,
309 while ( count-- > 0 ) {
310 XtVaCreateManagedWidget(toggles->name,
311 xmToggleButtonWidgetClass,
312 form,
313 XmNtopAttachment, XmATTACH_FORM,
314 XmNbottomAttachment, XmATTACH_FORM,
315 XmNleftAttachment, XmATTACH_POSITION,
316 XmNleftPosition, pos,
317 XmNrightAttachment, XmATTACH_POSITION,
318 XmNrightPosition, pos+SpacingRatio-1,
321 pos += SpacingRatio;
322 ++toggles;
325 return form;
328 #endif
331 /* Routines to handle the text field widget */
333 /* when the user hits 'CR' in a text widget, fire the default pushbutton */
334 #if defined(__STDC__)
335 static void text_cr( Widget w, void *ptr, void *ptr2 )
336 #else
337 static void text_cr( w, ptr, ptr2 )
338 Widget w;
339 void *ptr;
340 void *ptr2;
341 #endif
343 next_func( w );
347 #ifdef notdef
349 * when the user hits any other character, if we are doing incremental
350 * search, send the updated string to nvi
352 * XXX
353 * I don't currently see any way to make this work -- incremental search
354 * is going to be really nasty. What makes it worse is that the dialog
355 * box almost certainly obscured a chunk of the text file, so there's no
356 * way to use it even if it works.
358 #if defined(__STDC__)
359 static void value_changed( Widget w, void *ptr, void *ptr2 )
360 #else
361 static void value_changed( w, ptr, ptr2 )
362 Widget w;
363 void *ptr;
364 void *ptr2;
365 #endif
367 /* get all the data from the root of the widget tree */
368 get_state( w );
370 /* send it along? */
371 #if defined(SelfTest)
372 if ( incremental_search ) send_command( w );
373 #else
374 if ( __vi_incremental_search() ) send_command( w );
375 #endif
377 #endif /* notdef */
380 /* Draw and display a dialog the describes nvi search capability */
382 #if defined(__STDC__)
383 static Widget create_search_dialog( Widget parent, String title )
384 #else
385 static Widget create_search_dialog( parent, title )
386 Widget parent;
387 String title;
388 #endif
390 Widget box, form, label, text, checks, buttons, form2;
391 save_dialog *ptr;
393 /* use an existing one? */
394 if ( dialogs != NULL ) {
395 box = dialogs->shell;
396 ptr = dialogs->next;
397 free( dialogs );
398 dialogs = ptr;
399 return box;
402 box = XtVaCreatePopupShell( title,
403 xmDialogShellWidgetClass,
404 parent,
405 XmNtitle, title,
406 XmNallowShellResize, False,
410 form = XtVaCreateWidget( "form",
411 xmFormWidgetClass,
412 box,
413 XmNverticalSpacing, 4,
414 XmNhorizontalSpacing, 4,
418 form2 = XtVaCreateManagedWidget( "form",
419 xmFormWidgetClass,
420 form,
421 XmNtopAttachment, XmATTACH_FORM,
422 XmNleftAttachment, XmATTACH_FORM,
423 XmNrightAttachment, XmATTACH_FORM,
427 label = XtVaCreateManagedWidget( "Pattern:",
428 xmLabelWidgetClass,
429 form2,
430 XmNtopAttachment, XmATTACH_FORM,
431 XmNbottomAttachment,XmATTACH_FORM,
432 XmNleftAttachment, XmATTACH_FORM,
436 text = XtVaCreateManagedWidget( PatternWidget,
437 xmTextFieldWidgetClass,
438 form2,
439 XmNtopAttachment, XmATTACH_FORM,
440 XmNbottomAttachment,XmATTACH_FORM,
441 XmNleftAttachment, XmATTACH_WIDGET,
442 XmNleftWidget, label,
443 XmNrightAttachment, XmATTACH_FORM,
446 #ifdef notdef
447 XtAddCallback( text, XmNvalueChangedCallback, value_changed, 0 );
448 #endif
449 XtAddCallback( text, XmNactivateCallback, text_cr, 0 );
451 buttons = create_push_buttons( form, button_data, XtNumber(button_data) );
452 XtVaSetValues( buttons,
453 XmNbottomAttachment, XmATTACH_FORM,
457 #if defined(SelfTest)
458 checks = create_check_boxes( form, toggle_data, XtNumber(toggle_data) );
459 #else
460 checks = (Widget) __vi_create_search_toggles( form, search_toggles );
461 #endif
462 XtVaSetValues( checks,
463 XmNtopAttachment, XmATTACH_WIDGET,
464 XmNtopWidget, form2,
465 XmNbottomAttachment, XmATTACH_WIDGET,
466 XmNbottomWidget, buttons,
470 XtManageChild( form );
471 return box;
475 /* Module interface to the outside world
477 * xip_show_search_dialog( parent, title )
478 * pops up a search dialog
480 * xip_next_search()
481 * simulates a 'next' assuming that a search has been done
484 #if defined(__STDC__)
485 void __vi_show_search_dialog( Widget parent, String title )
486 #else
487 void __vi_show_search_dialog( parent, data, cbs )
488 Widget parent;
489 String title;
490 #endif
492 Widget db = create_search_dialog( parent, title );
493 Dimension height;
495 /* we can handle getting taller and wider or narrower, but not shorter */
496 XtVaGetValues( db, XmNheight, &height, 0 );
497 XtVaSetValues( db, XmNmaxHeight, height, XmNminHeight, height, 0 );
499 /* post the dialog */
500 XtPopup( db, XtGrabNone );
502 /* request initial focus to the text widget */
503 XmProcessTraversal( get_child_widget( db, PatternWidget ),
504 XmTRAVERSE_CURRENT
510 * __vi_search --
512 * PUBLIC: void __vi_search __P((Widget));
514 void
515 __vi_search(Widget w)
517 next_func( w );
521 #if defined(SelfTest)
523 #if defined(__STDC__)
524 static void show_search( Widget w, XtPointer data, XtPointer cbs )
525 #else
526 static void show_search( w, data, cbs )
527 Widget w;
528 XtPointer data;
529 XtPointer cbs;
530 #endif
532 __vi_show_search_dialog( data, "Search" );
535 main( int argc, char *argv[] )
537 XtAppContext ctx;
538 Widget top_level, rc, button;
539 extern exit();
541 /* create a top-level shell for the window manager */
542 top_level = XtVaAppInitialize( &ctx,
543 argv[0],
544 NULL, 0, /* options */
545 (ArgcType) &argc,
546 argv, /* might get modified */
547 NULL,
548 NULL
551 rc = XtVaCreateManagedWidget( "rc",
552 xmRowColumnWidgetClass,
553 top_level,
557 button = XtVaCreateManagedWidget( "Pop up search dialog",
558 xmPushButtonGadgetClass,
562 XtAddCallback( button, XmNactivateCallback, show_search, rc );
564 button = XtVaCreateManagedWidget( "Quit",
565 xmPushButtonGadgetClass,
569 XtAddCallback( button, XmNactivateCallback, exit, 0 );
571 XtRealizeWidget(top_level);
572 XtAppMainLoop(ctx);
574 #endif