tell DB it's DB_UNKNOWN rather than DB_BTREE
[nvi.git] / motif_l / m_tags.c
blob2105a06682164d164284d4870a281a4fff9f0c8e
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_tags.c,v 8.8 2001/06/25 15:19:28 skimo Exp $ (Berkeley) $Date: 2001/06/25 15:19:28 $";
14 #endif /* not lint */
17 * This module implements a dialog for navigating the tag stack
19 * Interface:
20 * void __vi_show_tags_dialog( Widget parent, String title )
21 * Pops up a Tags dialog. We allow one per session. It is not modal.
23 * void __vi_push_tag( String text )
24 * void __vi_pop_tag()
25 * void __vi_clear_tag()
26 * When core changes the tag stack we will change our representation
27 * of it. When this dialog appears, we need core to send a slew of
28 * messages so we can display the current tag stack.
30 * void __vi_set_tag_text( String text )
31 * the text field in the dialog is set to the string. ideally,
32 * this should be kept in sync with the word following the caret
33 * in the current editor window
35 * To Do:
36 * The push-buttons should activate and deactivate according to
37 * the state of the tag stack and the text field.
39 * Need to send VI commands rather than strings
41 * Need IPO command to start/stop asking for the current tag stack
45 /* context */
46 #include <X11/X.h>
47 #include <X11/Intrinsic.h>
48 #include <Xm/DialogS.h>
49 #include <Xm/Form.h>
50 #include <Xm/LabelG.h>
51 #include <Xm/TextF.h>
52 #include <Xm/List.h>
53 #include <Xm/RowColumn.h>
54 #include <Xm/PushBG.h>
56 #if ! defined(SelfTest)
57 #include <sys/types.h>
58 #include <sys/queue.h>
60 #include <bitstring.h>
61 #include <stdio.h>
62 #include <string.h>
64 #include "../common/common.h"
65 #include "../ipc/ip.h"
66 #include "m_motif.h"
67 #endif
69 extern int vi_ofd;
72 /* globals */
74 static Widget db_tabs = NULL,
75 db_text,
76 db_list;
78 static Boolean active = False;
80 typedef struct {
81 String name;
82 Boolean is_default;
83 void (*cb)();
84 } ButtonData;
86 static void go_to_tag(Widget w);
87 static void split_to_tag(Widget w);
88 static void pop_tag(Widget w);
90 static ButtonData button_data[] = {
91 { "Go To Tag", True, go_to_tag },
92 { "Split To Tag", False, split_to_tag },
93 { "Pop Tag", False, pop_tag },
97 /* manage the tags stack list */
99 void __vi_pop_tag(void)
101 if ( ! active ) return;
103 XmListDeletePos( db_list, 1 );
107 void __vi_clear_tag(void)
109 if ( ! active ) return;
111 XmListDeleteAllItems( db_list );
115 void __vi_push_tag(String text)
117 XmString str;
119 if ( ! active ) return;
121 str = XmStringCreateSimple( text );
122 XmListAddItem( db_list, str, 1 );
123 XmStringFree( str );
127 /* create a set of push buttons */
129 #define SpacingRatio 4 /* 3:1 button to spaces */
131 #if defined(__STDC__)
132 static Widget create_push_buttons( Widget parent,
133 ButtonData *data,
134 int count
136 #else
137 static Widget create_push_buttons( parent, data, count )
138 Widget parent;
139 ButtonData *data;
140 int count;
141 #endif
143 Widget w, form;
144 int pos = 1, base;
146 base = SpacingRatio*count + 1;
147 form = XtVaCreateManagedWidget( "buttons",
148 xmFormWidgetClass,
149 parent,
150 XmNleftAttachment, XmATTACH_FORM,
151 XmNrightAttachment, XmATTACH_FORM,
152 XmNfractionBase, base,
153 XmNshadowType, XmSHADOW_ETCHED_IN,
154 XmNshadowThickness, 2,
155 XmNverticalSpacing, 4,
159 while ( count-- > 0 ) {
160 w = XtVaCreateManagedWidget(data->name,
161 xmPushButtonGadgetClass,
162 form,
163 XmNtopAttachment, XmATTACH_FORM,
164 XmNbottomAttachment,XmATTACH_FORM,
165 XmNleftAttachment, XmATTACH_POSITION,
166 XmNleftPosition, pos,
167 XmNshowAsDefault, data->is_default,
168 XmNdefaultButtonShadowThickness, data->is_default,
169 XmNrightAttachment, XmATTACH_POSITION,
170 XmNrightPosition, pos+SpacingRatio-1,
173 if ( data->is_default )
174 XtVaSetValues( form, XmNdefaultButton, w, 0 );
175 XtAddCallback( w, XmNactivateCallback, data->cb, 0 );
176 pos += SpacingRatio;
177 data++;
180 return form;
184 /* callbacks */
186 static void
187 cancel_cb(void)
189 #if defined(SelfTest)
190 puts( "cancelled" );
191 #endif
192 active = False;
196 static void set_text_field(Widget w, XtPointer ptr, XmListCallbackStruct *cbs)
198 String str;
200 XmStringGetLtoR( cbs->item, XmSTRING_DEFAULT_CHARSET, &str );
201 XmTextFieldSetString( db_text, str );
202 XtFree( str );
206 void __vi_set_tag_text(String text)
208 if ( active ) XmTextFieldSetString( db_text, text );
212 static void destroyed(void)
214 #if defined(SelfTest)
215 puts( "destroyed" );
216 #endif
218 /* some window managers destroy us upon popdown */
219 db_tabs = NULL;
220 active = False;
224 #if defined(__STDC__)
225 static void pop_tag( Widget w )
226 #else
227 static void pop_tag( w )
228 Widget w;
229 #endif
231 static String buffer = ":tagpop";
233 #if defined(SelfTest)
234 printf( "sending command <<%s>>\n", buffer );
235 __vi_pop_tag();
236 #else
237 __vi_send_command_string( buffer );
238 #endif
242 #if defined(__STDC__)
243 static void split_to_tag( Widget w )
244 #else
245 static void split_to_tag( w )
246 Widget w;
247 #endif
249 IP_BUF ipb;
250 String str;
252 str = XmTextFieldGetString( db_text );
254 #if defined(SelfTest)
255 printf( "sending command <<:Tag %s>>\n", str );
256 #else
258 * XXX
259 * This is REALLY sleazy. We pass the nul along with the
260 * string so that the core editor doesn't have to copy the
261 * string to get a nul termination. This should be fixed
262 * as part of making the editor fully 8-bit clean.
264 ipb.code = VI_TAGSPLIT;
265 ipb.str1 = str;
266 ipb.len1 = strlen(str) + 1;
267 vi_send(vi_ofd, "a", &ipb);
268 #endif
270 XtFree( str );
274 #if defined(__STDC__)
275 static void go_to_tag( Widget w )
276 #else
277 static void go_to_tag( w )
278 Widget w;
279 #endif
281 IP_BUF ipb;
282 String str;
284 str = XmTextFieldGetString( db_text );
286 #if defined(SelfTest)
287 printf( "sending command <<:tag %s>>\n", str );
288 #else
290 * XXX
291 * This is REALLY sleazy. We pass the nul along with the
292 * string so that the core editor doesn't have to copy the
293 * string to get a nul termination. This should be fixed
294 * as part of making the editor fully 8-bit clean.
296 ipb.code = VI_TAGAS;
297 ipb.str1 = str;
298 ipb.len1 = strlen(str) + 1;
299 vi_send(vi_ofd, "a", &ipb);
300 #endif
302 XtFree( str );
307 /* Draw and display a dialog the describes nvi options */
309 #if defined(__STDC__)
310 static Widget create_tags_dialog( Widget parent, String title )
311 #else
312 static Widget create_tags_dialog( parent, title )
313 Widget parent;
314 String title;
315 #endif
317 Widget box, form, form2, form3, buttons;
319 /* already built? */
320 if ( db_tabs != NULL ) return db_tabs;
322 box = XtVaCreatePopupShell( title,
323 xmDialogShellWidgetClass,
324 parent,
325 XmNtitle, title,
326 XmNallowShellResize, False,
329 XtAddCallback( box, XmNpopdownCallback, cancel_cb, 0 );
330 XtAddCallback( box, XmNdestroyCallback, destroyed, 0 );
332 form = XtVaCreateWidget( "Tags",
333 xmFormWidgetClass,
334 box,
338 buttons = create_push_buttons( form, button_data, XtNumber(button_data) );
339 XtVaSetValues( buttons,
340 XmNbottomAttachment, XmATTACH_FORM,
344 form3 = XtVaCreateWidget( "form",
345 xmFormWidgetClass,
346 form,
347 XmNleftAttachment, XmATTACH_FORM,
348 XmNrightAttachment, XmATTACH_FORM,
349 XmNbottomAttachment, XmATTACH_WIDGET,
350 XmNbottomWidget, buttons,
354 form2 = XtVaCreateWidget( "form",
355 xmFormWidgetClass,
356 form,
357 XmNtopAttachment, XmATTACH_FORM,
358 XmNleftAttachment, XmATTACH_FORM,
359 XmNrightAttachment, XmATTACH_FORM,
360 XmNbottomAttachment, XmATTACH_WIDGET,
361 XmNbottomWidget, form3,
365 db_list = XtVaCreateManagedWidget( "list",
366 xmListWidgetClass,
367 form2,
368 XmNtopAttachment, XmATTACH_FORM,
369 XmNleftAttachment, XmATTACH_POSITION,
370 XmNleftPosition, 20,
371 XmNrightAttachment, XmATTACH_FORM,
372 XmNbottomAttachment, XmATTACH_FORM,
373 #if defined(SelfTest)
374 XmNvisibleItemCount, 5,
375 #endif
376 XmNselectionPolicy, XmSINGLE_SELECT,
379 XtAddCallback( db_list, XmNsingleSelectionCallback, set_text_field, 0 );
380 XtAddCallback( db_list, XmNdefaultActionCallback, go_to_tag, 0 );
382 XtVaCreateManagedWidget( "Tag Stack",
383 xmLabelGadgetClass,
384 form2,
385 XmNtopAttachment, XmATTACH_FORM,
386 XmNbottomAttachment, XmATTACH_FORM,
387 XmNleftAttachment, XmATTACH_FORM,
388 XmNrightAttachment, XmATTACH_POSITION,
389 XmNrightPosition, 20,
390 XmNalignment, XmALIGNMENT_END,
394 XtVaCreateManagedWidget( "Tag",
395 xmLabelGadgetClass,
396 form3,
397 XmNtopAttachment, XmATTACH_FORM,
398 XmNbottomAttachment, XmATTACH_FORM,
399 XmNleftAttachment, XmATTACH_FORM,
400 XmNrightAttachment, XmATTACH_POSITION,
401 XmNrightPosition, 20,
402 XmNalignment, XmALIGNMENT_END,
406 db_text = XtVaCreateManagedWidget( "text",
407 xmTextFieldWidgetClass,
408 form3,
409 XmNtopAttachment, XmATTACH_FORM,
410 XmNbottomAttachment, XmATTACH_FORM,
411 XmNrightAttachment, XmATTACH_FORM,
412 XmNleftAttachment, XmATTACH_POSITION,
413 XmNleftPosition, 20,
416 XtAddCallback( db_text, XmNactivateCallback, go_to_tag, 0 );
418 /* keep this global, we might destroy it later */
419 db_tabs = form;
421 /* done */
422 XtManageChild( form3 );
423 XtManageChild( form2 );
424 return form;
429 /* module entry point
430 * __vi_show_tags_dialog( parent, title )
433 #if defined(__STDC__)
434 void __vi_show_tags_dialog( Widget parent, String title )
435 #else
436 void __vi_show_tags_dialog( parent, title )
437 Widget parent;
438 String title;
439 #endif
441 Widget db = create_tags_dialog( parent, title ),
442 shell = XtParent(db);
444 XtManageChild( db );
446 /* get the current window's text */
447 __vi_set_tag_text( (String) __vi_get_word_at_caret( NULL ) );
449 /* TODO: ask vi core for the current tag stack now */
451 /* leave this guy up (or just raise it) */
452 XtPopup( shell, XtGrabNone );
453 XMapRaised( XtDisplay( shell ), XtWindow( shell ) );
455 active = True;
460 #if defined(SelfTest)
462 #if XtSpecificationRelease == 4
463 #define ArgcType Cardinal *
464 #else
465 #define ArgcType int *
466 #endif
468 static void add_a_tag( Widget w )
470 static String tags[] = { "first", "second", "this is the third" };
471 static int i = 0;
473 __vi_push_tag( tags[i] );
474 i = (i+1) % XtNumber(tags);
477 #if defined(__STDC__)
478 static void show_tags( Widget w, XtPointer data, XtPointer cbs )
479 #else
480 static void show_tags( w, data, cbs )
481 Widget w;
482 XtPointer data;
483 XtPointer cbs;
484 #endif
486 __vi_show_tags_dialog( data, "Tags" );
489 main( int argc, char *argv[] )
491 XtAppContext ctx;
492 Widget top_level, rc, button;
493 extern exit();
495 /* create a top-level shell for the window manager */
496 top_level = XtVaAppInitialize( &ctx,
497 argv[0],
498 NULL, 0, /* options */
499 (ArgcType) &argc,
500 argv, /* might get modified */
501 NULL,
502 NULL
505 rc = XtVaCreateManagedWidget( "rc",
506 xmRowColumnWidgetClass,
507 top_level,
511 button = XtVaCreateManagedWidget( "Pop up tags dialog",
512 xmPushButtonGadgetClass,
516 XtAddCallback( button, XmNactivateCallback, show_tags, rc );
518 button = XtVaCreateManagedWidget( "Add a tag",
519 xmPushButtonGadgetClass,
523 XtAddCallback( button, XmNactivateCallback, add_a_tag, rc );
525 button = XtVaCreateManagedWidget( "Quit",
526 xmPushButtonGadgetClass,
530 XtAddCallback( button, XmNactivateCallback, exit, 0 );
532 XtRealizeWidget(top_level);
533 XtAppMainLoop(ctx);
535 #endif