add --enable-trace, removing TR #defines from everywhere
[nvi.git] / motif_l / m_search.c
blobb8cb35cbe75d5ed3fbafbe702c6aa15daf664e28
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.3 1996/12/10 21:07:46 bostic Exp $ (Berkeley) $Date: 1996/12/10 21:07:46 $";
14 #endif /* not lint */
16 /* context */
17 #include <X11/X.h>
18 #include <X11/Intrinsic.h>
19 #include <Xm/DialogS.h>
20 #include <Xm/Form.h>
21 #include <Xm/Label.h>
22 #include <Xm/PushBG.h>
23 #include <Xm/TextF.h>
24 #include <Xm/ToggleB.h>
25 #include <Xm/RowColumn.h>
28 /* types */
30 typedef struct sds {
31 struct sds *next;
32 Widget shell;
33 } save_dialog;
35 static save_dialog *dialogs = NULL;
37 typedef struct {
38 String name;
39 Boolean is_default;
40 void (*cb)();
41 } ButtonData;
43 typedef struct {
44 String name;
45 Boolean *value;
46 } ToggleData;
48 typedef enum {
49 ExprStandard,
50 ExprExtended,
51 ExprNone
52 } ExpressionKind;
54 static String expr_image[] = {
55 "Standard",
56 "Extended",
57 "None"
61 /* globals and constants */
63 static String ExpressionWidget = "option",
64 PatternWidget = "text";
66 static Boolean ignore_case,
67 wrap_search,
68 incremental_search;
70 static ToggleData toggle_data[] = {
71 { "Ignore Case", &ignore_case },
72 { "Wrap End Of File", &wrap_search },
73 { "Incremental", &incremental_search }
76 static void next_func(),
77 prev_func(),
78 done_func();
80 static ButtonData button_data[] = {
81 { "Next", True, next_func },
82 { "Previous", False, prev_func },
83 { "Cancel", False, done_func }
86 ExpressionKind expr_kind;
88 String pattern = NULL;
91 /* Xt utilities */
93 #if defined(__STDC__)
94 static Widget get_child_widget( Widget parent, String name )
95 #else
96 static Widget get_child_widget( parent, name )
97 Widget parent;
98 String name;
99 #endif
101 char buffer[1024];
103 strcpy( buffer, "*" );
104 strcat( buffer, name );
105 return XtNameToWidget( parent, buffer );
109 #if defined(__STDC__)
110 static String get_widget_string( Widget w, String resource )
111 #else
112 static String get_widget_string( w, resource )
113 Widget w;
114 String resource;
115 #endif
117 XmString xmstr;
118 String str;
120 XtVaGetValues( w, resource, &xmstr, 0 );
121 XmStringGetLtoR( xmstr, XmSTRING_DEFAULT_CHARSET, &str );
122 XmStringFree( xmstr );
124 return str;
128 /* sync the global state */
130 #if defined(__STDC__)
131 static void get_state( Widget w )
132 #else
133 static void get_state( w )
134 Widget w;
135 #endif
137 int i;
138 String str;
139 Widget shell = w;
141 /* get all the data from the root of the widget tree */
142 while ( ! XtIsShell(shell) ) shell = XtParent(shell);
144 /* which regular expression kind? */
145 if (( w = get_child_widget( shell, ExpressionWidget )) != NULL ) {
146 w = XmOptionButtonGadget( w );
147 str = get_widget_string( w, XmNlabelString );
148 for (i=0; i<XtNumber(expr_image); i++) {
149 if ( strcmp( str, expr_image[i] ) == 0 ) {
150 expr_kind = (ExpressionKind) i;
151 break;
154 XtFree( str );
157 /* which flags? */
158 for (i=0; i<XtNumber(toggle_data); i++) {
159 if (( w = get_child_widget( shell, toggle_data[i].name )) != NULL ) {
160 XtVaGetValues( w, XmNset, toggle_data[i].value, 0 );
164 /* what's the pattern? */
165 if (( w = get_child_widget( shell, PatternWidget )) != NULL ) {
166 if ( pattern != NULL ) XtFree( pattern );
167 pattern = XmTextFieldGetString( w );
172 /* Translate the user's actions into nvi commands */
174 #if defined(__STDC__)
175 static void send_command( Widget w )
176 #else
177 static void send_command( w )
178 Widget w;
179 #endif
181 String safe_pattern = (pattern) ? pattern : "";
182 int i;
184 #if defined(SelfTest)
185 printf( "%s [\n", (w == NULL) ? "Find Next" : XtName(w) );
186 printf( "\tPattern\t\t%s\n", safe_pattern );
187 printf( "\tExpression Kind\t%s\n", expr_image[(int)expr_kind] );
188 for( i=0; i<XtNumber(toggle_data); i++ )
189 printf( "\t%s\t%d\n", toggle_data[i].name, *toggle_data[i].value );
190 printf( "]\n" );
191 #else
193 char buffer[1024];
195 strcpy( buffer, "/" );
196 strcat( buffer, pattern );
197 __vi_send_command_string( buffer );
199 #endif
203 #if defined(__STDC__)
204 static void next_func( Widget w )
205 #else
206 static void next_func( w )
207 Widget w;
208 #endif
210 /* get current data from the root of the widget tree? */
211 if ( w != NULL ) get_state( w );
213 /* format it */
214 send_command( w );
218 #if defined(__STDC__)
219 static void prev_func( Widget w )
220 #else
221 static void prev_func( w )
222 Widget w;
223 #endif
225 /* get current data from the root of the widget tree */
226 get_state( w );
228 /* format it */
229 send_command( w );
233 #if defined(__STDC__)
234 static void done_func( Widget w )
235 #else
236 static void done_func( w )
237 Widget w;
238 #endif
240 save_dialog *ptr;
242 #if defined(SelfTest)
243 puts( XtName(w) );
244 #endif
246 while ( ! XtIsShell(w) ) w = XtParent(w);
247 XtPopdown( w );
249 /* save it for later */
250 ptr = (save_dialog *) malloc( sizeof(save_dialog) );
251 ptr->next = dialogs;
252 ptr->shell = w;
253 dialogs = ptr;
257 /* create a set of push buttons */
259 #define SpacingRatio 4 /* 3:1 button to spaces */
261 #if defined(__STDC__)
262 static Widget create_push_buttons( Widget parent,
263 ButtonData *data,
264 int count
266 #else
267 static Widget create_push_buttons( parent, data, count )
268 Widget parent;
269 ButtonData *data;
270 int count;
271 #endif
273 Widget w, form;
274 int pos = 1, base;
276 base = SpacingRatio*count + 1;
277 form = XtVaCreateManagedWidget( "buttons",
278 xmFormWidgetClass,
279 parent,
280 XmNleftAttachment, XmATTACH_FORM,
281 XmNrightAttachment, XmATTACH_FORM,
282 XmNfractionBase, base,
283 XmNshadowType, XmSHADOW_ETCHED_IN,
284 XmNshadowThickness, 2,
285 XmNverticalSpacing, 4,
289 while ( count-- > 0 ) {
290 w = XtVaCreateManagedWidget(data->name,
291 xmPushButtonGadgetClass,
292 form,
293 XmNtopAttachment, XmATTACH_FORM,
294 XmNbottomAttachment,XmATTACH_FORM,
295 XmNleftAttachment, XmATTACH_POSITION,
296 XmNleftPosition, pos,
297 XmNshowAsDefault, data->is_default,
298 XmNdefaultButtonShadowThickness, data->is_default,
299 XmNrightAttachment, XmATTACH_POSITION,
300 XmNrightPosition, pos+SpacingRatio-1,
303 if ( data->is_default )
304 XtVaSetValues( form, XmNdefaultButton, w, 0 );
305 XtAddCallback( w, XmNactivateCallback, data->cb, 0 );
306 pos += SpacingRatio;
307 data++;
310 return form;
314 /* create a set of check boxes */
316 #if defined(__STDC__)
317 static Widget create_check_boxes( Widget parent,
318 ToggleData *toggles,
319 int count
321 #else
322 static Widget create_check_boxes( parent, toggles, count )
323 Widget parent;
324 ToggleData *toggles;
325 int count;
326 #endif
328 Widget form;
329 int pos = 1, base;
331 base = SpacingRatio*count +1;
332 form = XtVaCreateManagedWidget( "toggles",
333 xmFormWidgetClass,
334 parent,
335 XmNleftAttachment, XmATTACH_FORM,
336 XmNrightAttachment, XmATTACH_FORM,
337 XmNfractionBase, base,
338 XmNverticalSpacing, 4,
342 while ( count-- > 0 ) {
343 XtVaCreateManagedWidget(toggles->name,
344 xmToggleButtonWidgetClass,
345 form,
346 XmNtopAttachment, XmATTACH_FORM,
347 XmNbottomAttachment, XmATTACH_FORM,
348 XmNleftAttachment, XmATTACH_POSITION,
349 XmNleftPosition, pos,
350 XmNrightAttachment, XmATTACH_POSITION,
351 XmNrightPosition, pos+SpacingRatio-1,
354 pos += SpacingRatio;
355 ++toggles;
358 return form;
362 /* Routines to handle the text field widget */
364 /* when the user hits 'CR' in a text widget, fire the default pushbutton */
365 #if defined(__STDC__)
366 static void text_cr( Widget w, void *ptr, void *ptr2 )
367 #else
368 static void text_cr( w, ptr, ptr2 )
369 Widget w;
370 void *ptr;
371 void *ptr2;
372 #endif
374 next_func( w );
378 /* when the user hits any other character, if we are doing incremental
379 * search, send the updated string to nvi
381 #if defined(__STDC__)
382 static void value_changed( Widget w, void *ptr, void *ptr2 )
383 #else
384 static void value_changed( w, ptr, ptr2 )
385 Widget w;
386 void *ptr;
387 void *ptr2;
388 #endif
390 /* get all the data from the root of the widget tree */
391 get_state( w );
393 /* send it along? */
394 if ( incremental_search ) send_command( w );
398 /* Draw and display a dialog the describes nvi search capability */
400 #if defined(__STDC__)
401 static Widget create_search_dialog( Widget parent, String title )
402 #else
403 static Widget create_search_dialog( parent, title )
404 Widget parent;
405 String title;
406 #endif
408 Widget box, form, label, text, checks, options, buttons, form2;
409 XmString opt_str, reg_str, xtd_str, non_str;
410 save_dialog *ptr;
412 /* use an existing one? */
413 if ( dialogs != NULL ) {
414 box = dialogs->shell;
415 ptr = dialogs->next;
416 free( dialogs );
417 dialogs = ptr;
418 return box;
421 box = XtVaCreatePopupShell( title,
422 xmDialogShellWidgetClass,
423 parent,
424 XmNtitle, title,
425 XmNallowShellResize, False,
429 form = XtVaCreateWidget( "form",
430 xmFormWidgetClass,
431 box,
432 XmNverticalSpacing, 4,
433 XmNhorizontalSpacing, 4,
437 form2 = XtVaCreateManagedWidget( "form",
438 xmFormWidgetClass,
439 form,
440 XmNtopAttachment, XmATTACH_FORM,
441 XmNleftAttachment, XmATTACH_FORM,
442 XmNrightAttachment, XmATTACH_FORM,
446 label = XtVaCreateManagedWidget( "Pattern:",
447 xmLabelWidgetClass,
448 form2,
449 XmNalignment, XmALIGNMENT_END,
450 XmNtopAttachment, XmATTACH_FORM,
451 XmNbottomAttachment,XmATTACH_FORM,
452 XmNrightAttachment, XmATTACH_POSITION,
453 XmNrightPosition, 25,
457 text = XtVaCreateManagedWidget( PatternWidget,
458 xmTextFieldWidgetClass,
459 form2,
460 XmNtopAttachment, XmATTACH_FORM,
461 XmNbottomAttachment,XmATTACH_FORM,
462 XmNleftAttachment, XmATTACH_POSITION,
463 XmNleftPosition, 25,
464 XmNrightAttachment, XmATTACH_FORM,
467 XtAddCallback( text, XmNvalueChangedCallback, value_changed, 0 );
468 XtAddCallback( text, XmNactivateCallback, text_cr, 0 );
470 opt_str = XmStringCreateSimple( "Regular Expression Type" );
471 reg_str = XmStringCreateSimple( expr_image[(int)ExprStandard] );
472 xtd_str = XmStringCreateSimple( expr_image[(int)ExprExtended] );
473 non_str = XmStringCreateSimple( expr_image[(int)ExprNone] );
474 options = XmVaCreateSimpleOptionMenu( form,
475 ExpressionWidget,
476 opt_str,
479 NULL,
480 XmVaPUSHBUTTON, reg_str, 0, 0, 0,
481 XmVaPUSHBUTTON, xtd_str, 0, 0, 0,
482 XmVaPUSHBUTTON, non_str, 0, 0, 0,
483 XmNtopAttachment, XmATTACH_WIDGET,
484 XmNtopWidget, form2,
485 XmNleftAttachment, XmATTACH_POSITION,
486 XmNleftPosition, 25,
487 XmNrightAttachment, XmATTACH_FORM,
490 XmStringFree( opt_str );
491 XmStringFree( reg_str );
492 XmStringFree( xtd_str );
493 XmStringFree( non_str );
494 XtManageChild( options );
496 buttons = create_push_buttons( form, button_data, XtNumber(button_data) );
497 XtVaSetValues( buttons,
498 XmNbottomAttachment, XmATTACH_FORM,
502 checks = create_check_boxes( form, toggle_data, XtNumber(toggle_data) );
503 XtVaSetValues( checks,
504 XmNtopAttachment, XmATTACH_WIDGET,
505 XmNtopWidget, options,
506 XmNbottomAttachment, XmATTACH_WIDGET,
507 XmNbottomWidget, buttons,
511 XtManageChild( form );
512 return box;
516 /* Module interface to the outside world
518 * xip_show_search_dialog( parent, title )
519 * pops up a search dialog
521 * xip_next_search()
522 * simulates a 'next' assuming that a search has been done
525 #if defined(__STDC__)
526 void __vi_show_search_dialog( Widget parent, String title )
527 #else
528 void __vi_show_search_dialog( parent, data, cbs )
529 Widget parent;
530 String title;
531 #endif
533 Widget db = create_search_dialog( parent, title );
534 Dimension height;
536 /* we can handle getting taller and wider or narrower, but not shorter */
537 XtVaGetValues( db, XmNheight, &height, 0 );
538 XtVaSetValues( db, XmNminHeight, height, 0 );
540 /* post the dialog */
541 XtPopup( db, XtGrabNone );
543 /* request initial focus to the text widget */
544 XmProcessTraversal( get_child_widget( db, PatternWidget ),
545 XmTRAVERSE_CURRENT
550 void __vi_next_search()
552 next_func( NULL );
556 #if defined(SelfTest)
558 #if defined(__STDC__)
559 static void show_search( Widget w, XtPointer data, XtPointer cbs )
560 #else
561 static void show_search( w, data, cbs )
562 Widget w;
563 XtPointer data;
564 XtPointer cbs;
565 #endif
567 __vi_show_search_dialog( data, "Search" );
570 main( int argc, char *argv[] )
572 XtAppContext ctx;
573 Widget top_level, rc, button;
574 extern exit();
576 /* create a top-level shell for the window manager */
577 top_level = XtVaAppInitialize( &ctx,
578 argv[0],
579 NULL, 0, /* options */
580 (ArgcType) &argc,
581 argv, /* might get modified */
582 NULL,
583 NULL
586 rc = XtVaCreateManagedWidget( "rc",
587 xmRowColumnWidgetClass,
588 top_level,
592 button = XtVaCreateManagedWidget( "Pop up search dialog",
593 xmPushButtonGadgetClass,
597 XtAddCallback( button, XmNactivateCallback, show_search, rc );
599 button = XtVaCreateManagedWidget( "Quit",
600 xmPushButtonGadgetClass,
604 XtAddCallback( button, XmNactivateCallback, exit, 0 );
606 XtRealizeWidget(top_level);
607 XtAppMainLoop(ctx);
610 #endif