3 * Rob Zimmermann. All rights reserved.
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
12 #include <sys/cdefs.h>
15 static const char sccsid
[] = "Id: m_search.c,v 8.14 2003/11/05 17:10:00 skimo Exp (Berkeley) Date: 2003/11/05 17:10:00 ";
18 __RCSID("$NetBSD: m_search.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
21 #include <sys/queue.h>
25 #include <X11/Intrinsic.h>
26 #include <Xm/DialogS.h>
29 #include <Xm/PushBG.h>
31 #include <Xm/ToggleB.h>
32 #include <Xm/RowColumn.h>
34 #include <bitstring.h>
39 #include "../common/common.h"
40 #include "../ipc/ip.h"
53 static save_dialog
*dialogs
= NULL
;
61 /* globals and constants */
63 static String PatternWidget
= "text";
64 static String pattern
= NULL
;
66 static optData search_toggles
[] = {
67 { optToggle
, "extended", NULL
, VI_SEARCH_EXT
},
68 { optToggle
, "iclower", NULL
, VI_SEARCH_ICL
},
69 { optToggle
, "ignorecase", NULL
, VI_SEARCH_IC
},
70 { optToggle
, "literal", NULL
, VI_SEARCH_LIT
},
71 { optToggle
, "searchincr", NULL
, VI_SEARCH_INCR
},
72 { optToggle
, "wrapscan", NULL
, VI_SEARCH_WR
},
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", next_func
},
83 { "Previous", prev_func
},
84 { "Cancel", done_func
} /* always last */
91 static Widget
get_child_widget( Widget parent
, String name
)
93 static Widget
get_child_widget( parent
, name
)
100 strcpy( buffer
, "*" );
101 strcat( buffer
, name
);
102 return XtNameToWidget( parent
, buffer
);
106 /* sync the global state */
108 #if defined(__STDC__)
109 static void get_state( Widget w
)
111 static void get_state( w
)
115 #if defined(SelfTest)
120 /* get all the data from the root of the widget tree */
121 while ( ! XtIsShell(shell
) ) shell
= XtParent(shell
);
123 #if defined(SelfTest)
125 for (i
=0; i
<XtNumber(toggle_data
); i
++) {
126 if (( w
= get_child_widget( shell
, toggle_data
[i
].name
)) != NULL
) {
127 XtVaGetValues( w
, XmNset
, &toggle_data
[i
].value
, 0 );
132 /* what's the pattern? */
133 if (( w
= get_child_widget( shell
, PatternWidget
)) != NULL
) {
134 if ( pattern
!= NULL
) XtFree( pattern
);
135 pattern
= XmTextFieldGetString( w
);
140 /* Translate the user's actions into nvi commands */
143 * Action for next button.
153 * Action for previous button.
158 search(w
, VI_SEARCH_REV
);
163 * Perform the search.
166 search(Widget w
, int flags
)
173 while ( ! XtIsShell(shell
) ) shell
= XtParent(shell
);
175 /* Get current data from the root of the widget tree?
176 * Do it if we are a child of a dialog shell (assume we
177 * are a 'Find' dialog). Otherwise don't (we are the child
178 * of a menu and being invoked via accelerator)
180 if (XmIsDialogShell(shell
))
183 /* no pattern? probably, we haven't posted a search dialog yet.
184 * there ought to be a better thing to do here.
186 if ( pattern
== NULL
) {
187 vi_info_message( w
, "No previous string specified" );
192 ipb
.len1
= strlen(pattern
);
194 /* Initialize the search flags based on the buttons. */
196 for (opt
= search_toggles
; opt
->kind
!= optTerminator
; ++opt
)
197 if (opt
->value
!= NULL
)
198 ipb
.val1
|= opt
->flags
;
200 ipb
.code
= VI_C_SEARCH
;
201 vi_send(vi_ofd
, "a1", &ipb
);
204 #if defined(__STDC__)
205 static void done_func( Widget w
)
207 static void done_func( w
)
213 #if defined(SelfTest)
217 while ( ! XtIsShell(w
) ) w
= XtParent(w
);
220 /* save it for later */
221 ptr
= (save_dialog
*) malloc( sizeof(save_dialog
) );
228 /* create a set of push buttons */
230 #define SpacingRatio 4 /* 3:1 button to spaces */
232 #if defined(__STDC__)
233 static Widget
create_push_buttons( Widget parent
,
238 static Widget
create_push_buttons( parent
, data
, count
)
247 base
= SpacingRatio
*count
+ 1;
248 form
= XtVaCreateManagedWidget( "buttons",
251 XmNleftAttachment
, XmATTACH_FORM
,
252 XmNrightAttachment
, XmATTACH_FORM
,
253 XmNfractionBase
, base
,
254 XmNshadowType
, XmSHADOW_ETCHED_IN
,
255 XmNshadowThickness
, 2,
256 XmNverticalSpacing
, 4,
260 while ( count
-- > 0 ) {
261 w
= XtVaCreateManagedWidget(data
->name
,
262 xmPushButtonGadgetClass
,
264 XmNtopAttachment
, XmATTACH_FORM
,
265 XmNbottomAttachment
,XmATTACH_FORM
,
266 XmNleftAttachment
, XmATTACH_POSITION
,
267 XmNleftPosition
, pos
,
268 XmNshowAsDefault
, False
,
269 XmNrightAttachment
, XmATTACH_POSITION
,
270 XmNrightPosition
, pos
+SpacingRatio
-1,
273 XtAddCallback( w
, XmNactivateCallback
, data
->cb
, 0 );
278 /* last button is 'cancel' */
279 XtVaSetValues( XtParent(form
), XmNcancelButton
, w
, 0 );
285 /* create a set of check boxes */
287 #if defined(SelfTest)
289 #if defined(__STDC__)
290 static Widget
create_check_boxes( Widget parent
,
295 static Widget
create_check_boxes( parent
, toggles
, count
)
304 base
= SpacingRatio
*count
+1;
305 form
= XtVaCreateManagedWidget( "toggles",
308 XmNleftAttachment
, XmATTACH_FORM
,
309 XmNrightAttachment
, XmATTACH_FORM
,
310 XmNfractionBase
, base
,
311 XmNverticalSpacing
, 4,
315 while ( count
-- > 0 ) {
316 XtVaCreateManagedWidget(toggles
->name
,
317 xmToggleButtonWidgetClass
,
319 XmNtopAttachment
, XmATTACH_FORM
,
320 XmNbottomAttachment
, XmATTACH_FORM
,
321 XmNleftAttachment
, XmATTACH_POSITION
,
322 XmNleftPosition
, pos
,
323 XmNrightAttachment
, XmATTACH_POSITION
,
324 XmNrightPosition
, pos
+SpacingRatio
-1,
337 /* Routines to handle the text field widget */
339 /* when the user hits 'CR' in a text widget, fire the default pushbutton */
340 #if defined(__STDC__)
341 static void text_cr( Widget w
, void *ptr
, void *ptr2
)
343 static void text_cr( w
, ptr
, ptr2
)
355 * when the user hits any other character, if we are doing incremental
356 * search, send the updated string to nvi
359 * I don't currently see any way to make this work -- incremental search
360 * is going to be really nasty. What makes it worse is that the dialog
361 * box almost certainly obscured a chunk of the text file, so there's no
362 * way to use it even if it works.
364 #if defined(__STDC__)
365 static void value_changed( Widget w
, void *ptr
, void *ptr2
)
367 static void value_changed( w
, ptr
, ptr2
)
373 /* get all the data from the root of the widget tree */
377 #if defined(SelfTest)
378 if ( incremental_search
) send_command( w
);
380 if ( __vi_incremental_search() ) send_command( w
);
386 /* Draw and display a dialog the describes nvi search capability */
388 #if defined(__STDC__)
389 static Widget
create_search_dialog( Widget parent
, String title
)
391 static Widget
create_search_dialog( parent
, title
)
396 Widget box
, form
, label
, text
, checks
, buttons
, form2
;
399 /* use an existing one? */
400 if ( dialogs
!= NULL
) {
401 box
= dialogs
->shell
;
408 box
= XtVaCreatePopupShell( title
,
409 xmDialogShellWidgetClass
,
412 XmNallowShellResize
, False
,
416 form
= XtVaCreateWidget( "form",
419 XmNverticalSpacing
, 4,
420 XmNhorizontalSpacing
, 4,
424 form2
= XtVaCreateManagedWidget( "form",
427 XmNtopAttachment
, XmATTACH_FORM
,
428 XmNleftAttachment
, XmATTACH_FORM
,
429 XmNrightAttachment
, XmATTACH_FORM
,
433 label
= XtVaCreateManagedWidget( "Pattern:",
436 XmNtopAttachment
, XmATTACH_FORM
,
437 XmNbottomAttachment
,XmATTACH_FORM
,
438 XmNleftAttachment
, XmATTACH_FORM
,
442 text
= XtVaCreateManagedWidget( PatternWidget
,
443 xmTextFieldWidgetClass
,
445 XmNtopAttachment
, XmATTACH_FORM
,
446 XmNbottomAttachment
,XmATTACH_FORM
,
447 XmNleftAttachment
, XmATTACH_WIDGET
,
448 XmNleftWidget
, label
,
449 XmNrightAttachment
, XmATTACH_FORM
,
453 XtAddCallback( text
, XmNvalueChangedCallback
, value_changed
, 0 );
455 XtAddCallback( text
, XmNactivateCallback
, text_cr
, 0 );
457 buttons
= create_push_buttons( form
, button_data
, XtNumber(button_data
) );
458 XtVaSetValues( buttons
,
459 XmNbottomAttachment
, XmATTACH_FORM
,
463 #if defined(SelfTest)
464 checks
= create_check_boxes( form
, toggle_data
, XtNumber(toggle_data
) );
466 checks
= (Widget
) __vi_create_search_toggles( form
, search_toggles
);
468 XtVaSetValues( checks
,
469 XmNtopAttachment
, XmATTACH_WIDGET
,
471 XmNbottomAttachment
, XmATTACH_WIDGET
,
472 XmNbottomWidget
, buttons
,
476 XtManageChild( form
);
481 /* Module interface to the outside world
483 * xip_show_search_dialog( parent, title )
484 * pops up a search dialog
487 * simulates a 'next' assuming that a search has been done
490 #if defined(__STDC__)
491 void __vi_show_search_dialog( Widget parent
, String title
)
493 void __vi_show_search_dialog( parent
, data
, cbs
)
498 Widget db
= create_search_dialog( parent
, title
);
501 /* we can handle getting taller and wider or narrower, but not shorter */
502 XtVaGetValues( db
, XmNheight
, &height
, 0 );
503 XtVaSetValues( db
, XmNmaxHeight
, height
, XmNminHeight
, height
, 0 );
505 /* post the dialog */
506 XtPopup( db
, XtGrabNone
);
508 /* request initial focus to the text widget */
509 XmProcessTraversal( get_child_widget( db
, PatternWidget
),
518 * PUBLIC: void __vi_search __P((Widget));
521 __vi_search(Widget w
)
527 #if defined(SelfTest)
529 #if defined(__STDC__)
530 static void show_search( Widget w
, XtPointer data
, XtPointer cbs
)
532 static void show_search( w
, data
, cbs
)
538 __vi_show_search_dialog( data
, "Search" );
541 main( int argc
, char *argv
[] )
544 Widget top_level
, rc
, button
;
547 /* create a top-level shell for the window manager */
548 top_level
= XtVaAppInitialize( &ctx
,
550 NULL
, 0, /* options */
552 argv
, /* might get modified */
557 rc
= XtVaCreateManagedWidget( "rc",
558 xmRowColumnWidgetClass
,
563 button
= XtVaCreateManagedWidget( "Pop up search dialog",
564 xmPushButtonGadgetClass
,
568 XtAddCallback( button
, XmNactivateCallback
, show_search
, rc
);
570 button
= XtVaCreateManagedWidget( "Quit",
571 xmPushButtonGadgetClass
,
575 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
577 XtRealizeWidget(top_level
);