3 * Rob Zimmermann. All rights reserved.
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
13 static const char sccsid
[] = "$Id: m_search.c,v 8.6 1996/12/11 20:58:25 bostic Exp $ (Berkeley) $Date: 1996/12/11 20:58:25 $";
16 #include <sys/queue.h>
20 #include <X11/Intrinsic.h>
21 #include <Xm/DialogS.h>
24 #include <Xm/PushBG.h>
26 #include <Xm/ToggleB.h>
27 #include <Xm/RowColumn.h>
29 #include <bitstring.h>
33 #include "../common/common.h"
35 #include "ipc_extern.h"
45 static save_dialog
*dialogs
= NULL
;
62 static ToggleData toggle_data
[] = {
63 { "Ignore Case", 0, VI_SEARCH_IC
},
64 { "Incremental", 0, VI_SEARCH_INCR
}
65 { "Literal", 0, VI_SEARCH_LIT
},
66 { "Wrap End Of File", 0, VI_SEARCH_WR
},
72 /* globals and constants */
74 static String PatternWidget
= "text";
76 static void done_func
__P((Widget
));
77 static void next_func
__P((Widget
));
78 static void prev_func
__P((Widget
));
79 static void search
__P((Widget
, int));
81 static ButtonData button_data
[] = {
82 { "Next", True
, next_func
},
83 { "Previous", False
, prev_func
},
84 { "Cancel", False
, done_func
}
87 static String pattern
= NULL
;
93 static Widget
get_child_widget( Widget parent
, String name
)
95 static Widget
get_child_widget( parent
, name
)
102 strcpy( buffer
, "*" );
103 strcat( buffer
, name
);
104 return XtNameToWidget( parent
, buffer
);
108 #if defined(__STDC__)
109 static String
get_widget_string( Widget w
, String resource
)
111 static String
get_widget_string( w
, resource
)
119 XtVaGetValues( w
, resource
, &xmstr
, 0 );
120 XmStringGetLtoR( xmstr
, XmSTRING_DEFAULT_CHARSET
, &str
);
121 XmStringFree( xmstr
);
127 /* sync the global state */
129 #if defined(__STDC__)
130 static void get_state( Widget w
)
132 static void get_state( w
)
140 /* get all the data from the root of the widget tree */
141 while ( ! XtIsShell(shell
) ) shell
= XtParent(shell
);
143 #if defined(SelfTest)
145 for (i
=0; i
<XtNumber(toggle_data
); i
++) {
146 if (( w
= get_child_widget( shell
, toggle_data
[i
].name
)) != NULL
) {
147 XtVaGetValues( w
, XmNset
, &toggle_data
[i
].value
, 0 );
152 /* what's the pattern? */
153 if (( w
= get_child_widget( shell
, PatternWidget
)) != NULL
) {
154 if ( pattern
!= NULL
) XtFree( pattern
);
155 pattern
= XmTextFieldGetString( w
);
160 /* Translate the user's actions into nvi commands */
163 * Action for next button.
174 * Action for previous button.
180 search(w
, VI_SEARCH_REV
);
185 * Perform the search.
195 /* get current data from the root of the widget tree? */
196 if ( w
!= NULL
) get_state( w
);
199 ipb
.len
= strlen(pattern
);
201 #if defined(SelfTest)
202 /* initialize the search flags based on the buttons. */
204 for (i
=0; i
<XtNumber(toggle_data
); i
++) {
205 if (toggle_data
[i
].value
)
206 ipb
.val1
|= toggle_data
[i
].flag
;
210 ipb
.code
= VI_C_SEARCH
;
211 __vi_send("1s", &ipb
);
214 #if defined(__STDC__)
215 static void done_func( Widget w
)
217 static void done_func( w
)
223 #if defined(SelfTest)
227 while ( ! XtIsShell(w
) ) w
= XtParent(w
);
230 /* save it for later */
231 ptr
= (save_dialog
*) malloc( sizeof(save_dialog
) );
238 /* create a set of push buttons */
240 #define SpacingRatio 4 /* 3:1 button to spaces */
242 #if defined(__STDC__)
243 static Widget
create_push_buttons( Widget parent
,
248 static Widget
create_push_buttons( parent
, data
, count
)
257 base
= SpacingRatio
*count
+ 1;
258 form
= XtVaCreateManagedWidget( "buttons",
261 XmNleftAttachment
, XmATTACH_FORM
,
262 XmNrightAttachment
, XmATTACH_FORM
,
263 XmNfractionBase
, base
,
264 XmNshadowType
, XmSHADOW_ETCHED_IN
,
265 XmNshadowThickness
, 2,
266 XmNverticalSpacing
, 4,
270 while ( count
-- > 0 ) {
271 w
= XtVaCreateManagedWidget(data
->name
,
272 xmPushButtonGadgetClass
,
274 XmNtopAttachment
, XmATTACH_FORM
,
275 XmNbottomAttachment
,XmATTACH_FORM
,
276 XmNleftAttachment
, XmATTACH_POSITION
,
277 XmNleftPosition
, pos
,
278 XmNshowAsDefault
, data
->is_default
,
279 XmNdefaultButtonShadowThickness
, data
->is_default
,
280 XmNrightAttachment
, XmATTACH_POSITION
,
281 XmNrightPosition
, pos
+SpacingRatio
-1,
284 if ( data
->is_default
)
285 XtVaSetValues( form
, XmNdefaultButton
, w
, 0 );
286 XtAddCallback( w
, XmNactivateCallback
, data
->cb
, 0 );
295 /* create a set of check boxes */
297 #if defined(SelfTest)
299 #if defined(__STDC__)
300 static Widget
create_check_boxes( Widget parent
,
305 static Widget
create_check_boxes( parent
, toggles
, count
)
314 base
= SpacingRatio
*count
+1;
315 form
= XtVaCreateManagedWidget( "toggles",
318 XmNleftAttachment
, XmATTACH_FORM
,
319 XmNrightAttachment
, XmATTACH_FORM
,
320 XmNfractionBase
, base
,
321 XmNverticalSpacing
, 4,
325 while ( count
-- > 0 ) {
326 XtVaCreateManagedWidget(toggles
->name
,
327 xmToggleButtonWidgetClass
,
329 XmNtopAttachment
, XmATTACH_FORM
,
330 XmNbottomAttachment
, XmATTACH_FORM
,
331 XmNleftAttachment
, XmATTACH_POSITION
,
332 XmNleftPosition
, pos
,
333 XmNrightAttachment
, XmATTACH_POSITION
,
334 XmNrightPosition
, pos
+SpacingRatio
-1,
347 /* Routines to handle the text field widget */
349 /* when the user hits 'CR' in a text widget, fire the default pushbutton */
350 #if defined(__STDC__)
351 static void text_cr( Widget w
, void *ptr
, void *ptr2
)
353 static void text_cr( w
, ptr
, ptr2
)
365 * when the user hits any other character, if we are doing incremental
366 * search, send the updated string to nvi
369 * I don't currently see any way to make this work -- incremental search
370 * is going to be really nasty. What makes it worse is that the dialog
371 * box almost certainly obscured a chunk of the text file, so there's no
372 * way to use it even if it works.
374 #if defined(__STDC__)
375 static void value_changed( Widget w
, void *ptr
, void *ptr2
)
377 static void value_changed( w
, ptr
, ptr2
)
383 /* get all the data from the root of the widget tree */
387 #if defined(SelfTest)
388 if ( incremental_search
) send_command( w
);
390 if ( __vi_incremental_search() ) send_command( w
);
396 /* Draw and display a dialog the describes nvi search capability */
398 #if defined(__STDC__)
399 static Widget
create_search_dialog( Widget parent
, String title
)
401 static Widget
create_search_dialog( parent
, title
)
406 Widget box
, form
, label
, text
, checks
, buttons
, form2
;
409 /* use an existing one? */
410 if ( dialogs
!= NULL
) {
411 box
= dialogs
->shell
;
418 box
= XtVaCreatePopupShell( title
,
419 xmDialogShellWidgetClass
,
422 XmNallowShellResize
, False
,
426 form
= XtVaCreateWidget( "form",
429 XmNverticalSpacing
, 4,
430 XmNhorizontalSpacing
, 4,
434 form2
= XtVaCreateManagedWidget( "form",
437 XmNtopAttachment
, XmATTACH_FORM
,
438 XmNleftAttachment
, XmATTACH_FORM
,
439 XmNrightAttachment
, XmATTACH_FORM
,
443 label
= XtVaCreateManagedWidget( "Pattern:",
446 XmNtopAttachment
, XmATTACH_FORM
,
447 XmNbottomAttachment
,XmATTACH_FORM
,
448 XmNleftAttachment
, XmATTACH_FORM
,
452 text
= XtVaCreateManagedWidget( PatternWidget
,
453 xmTextFieldWidgetClass
,
455 XmNtopAttachment
, XmATTACH_FORM
,
456 XmNbottomAttachment
,XmATTACH_FORM
,
457 XmNleftAttachment
, XmATTACH_WIDGET
,
458 XmNleftWidget
, label
,
459 XmNrightAttachment
, XmATTACH_FORM
,
463 XtAddCallback( text
, XmNvalueChangedCallback
, value_changed
, 0 );
465 XtAddCallback( text
, XmNactivateCallback
, text_cr
, 0 );
467 buttons
= create_push_buttons( form
, button_data
, XtNumber(button_data
) );
468 XtVaSetValues( buttons
,
469 XmNbottomAttachment
, XmATTACH_FORM
,
473 #if defined(SelfTest)
474 checks
= create_check_boxes( form
, toggle_data
, XtNumber(toggle_data
) );
476 checks
= (Widget
) __vi_create_search_toggles( form
);
478 XtVaSetValues( checks
,
479 XmNtopAttachment
, XmATTACH_WIDGET
,
481 XmNbottomAttachment
, XmATTACH_WIDGET
,
482 XmNbottomWidget
, buttons
,
486 XtManageChild( form
);
491 /* Module interface to the outside world
493 * xip_show_search_dialog( parent, title )
494 * pops up a search dialog
497 * simulates a 'next' assuming that a search has been done
500 #if defined(__STDC__)
501 void __vi_show_search_dialog( Widget parent
, String title
)
503 void __vi_show_search_dialog( parent
, data
, cbs
)
508 Widget db
= create_search_dialog( parent
, title
);
511 /* we can handle getting taller and wider or narrower, but not shorter */
512 XtVaGetValues( db
, XmNheight
, &height
, 0 );
513 XtVaSetValues( db
, XmNmaxHeight
, height
, XmNminHeight
, height
, 0 );
515 /* post the dialog */
516 XtPopup( db
, XtGrabNone
);
518 /* request initial focus to the text widget */
519 XmProcessTraversal( get_child_widget( db
, PatternWidget
),
528 * PUBLIC: void __vi_search __P((void));
537 #if defined(SelfTest)
539 #if defined(__STDC__)
540 static void show_search( Widget w
, XtPointer data
, XtPointer cbs
)
542 static void show_search( w
, data
, cbs
)
548 __vi_show_search_dialog( data
, "Search" );
551 main( int argc
, char *argv
[] )
554 Widget top_level
, rc
, button
;
557 /* create a top-level shell for the window manager */
558 top_level
= XtVaAppInitialize( &ctx
,
560 NULL
, 0, /* options */
562 argv
, /* might get modified */
567 rc
= XtVaCreateManagedWidget( "rc",
568 xmRowColumnWidgetClass
,
573 button
= XtVaCreateManagedWidget( "Pop up search dialog",
574 xmPushButtonGadgetClass
,
578 XtAddCallback( button
, XmNactivateCallback
, show_search
, rc
);
580 button
= XtVaCreateManagedWidget( "Quit",
581 xmPushButtonGadgetClass
,
585 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
587 XtRealizeWidget(top_level
);