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_tags.c,v 8.9 2003/11/05 17:10:00 skimo Exp $ (Berkeley) $Date: 2003/11/05 17:10:00 $";
17 * This module implements a dialog for navigating the tag stack
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 )
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
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
47 #include <X11/Intrinsic.h>
48 #include <Xm/DialogS.h>
50 #include <Xm/LabelG.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>
65 #include "../common/common.h"
66 #include "../ipc/ip.h"
75 static Widget db_tabs
= NULL
,
79 static Boolean active
= False
;
87 static void go_to_tag(Widget w
);
88 static void split_to_tag(Widget w
);
89 static void pop_tag(Widget w
);
91 static ButtonData button_data
[] = {
92 { "Go To Tag", True
, go_to_tag
},
93 { "Split To Tag", False
, split_to_tag
},
94 { "Pop Tag", False
, pop_tag
},
98 /* manage the tags stack list */
100 void __vi_pop_tag(void)
102 if ( ! active
) return;
104 XmListDeletePos( db_list
, 1 );
108 void __vi_clear_tag(void)
110 if ( ! active
) return;
112 XmListDeleteAllItems( db_list
);
116 void __vi_push_tag(String text
)
120 if ( ! active
) return;
122 str
= XmStringCreateSimple( text
);
123 XmListAddItem( db_list
, str
, 1 );
128 /* create a set of push buttons */
130 #define SpacingRatio 4 /* 3:1 button to spaces */
132 #if defined(__STDC__)
133 static Widget
create_push_buttons( Widget parent
,
138 static Widget
create_push_buttons( parent
, data
, count
)
147 base
= SpacingRatio
*count
+ 1;
148 form
= XtVaCreateManagedWidget( "buttons",
151 XmNleftAttachment
, XmATTACH_FORM
,
152 XmNrightAttachment
, XmATTACH_FORM
,
153 XmNfractionBase
, base
,
154 XmNshadowType
, XmSHADOW_ETCHED_IN
,
155 XmNshadowThickness
, 2,
156 XmNverticalSpacing
, 4,
160 while ( count
-- > 0 ) {
161 w
= XtVaCreateManagedWidget(data
->name
,
162 xmPushButtonGadgetClass
,
164 XmNtopAttachment
, XmATTACH_FORM
,
165 XmNbottomAttachment
,XmATTACH_FORM
,
166 XmNleftAttachment
, XmATTACH_POSITION
,
167 XmNleftPosition
, pos
,
168 XmNshowAsDefault
, data
->is_default
,
169 XmNdefaultButtonShadowThickness
, data
->is_default
,
170 XmNrightAttachment
, XmATTACH_POSITION
,
171 XmNrightPosition
, pos
+SpacingRatio
-1,
174 if ( data
->is_default
)
175 XtVaSetValues( form
, XmNdefaultButton
, w
, 0 );
176 XtAddCallback( w
, XmNactivateCallback
, data
->cb
, 0 );
190 #if defined(SelfTest)
197 static void set_text_field(Widget w
, XtPointer ptr
, XmListCallbackStruct
*cbs
)
201 XmStringGetLtoR( cbs
->item
, XmSTRING_DEFAULT_CHARSET
, &str
);
202 XmTextFieldSetString( db_text
, str
);
207 void __vi_set_tag_text(String text
)
209 if ( active
) XmTextFieldSetString( db_text
, text
);
213 static void destroyed(void)
215 #if defined(SelfTest)
219 /* some window managers destroy us upon popdown */
225 #if defined(__STDC__)
226 static void pop_tag( Widget w
)
228 static void pop_tag( w
)
232 static String buffer
= ":tagpop";
234 #if defined(SelfTest)
235 printf( "sending command <<%s>>\n", buffer
);
238 __vi_send_command_string( buffer
);
243 #if defined(__STDC__)
244 static void split_to_tag( Widget w
)
246 static void split_to_tag( w
)
253 str
= XmTextFieldGetString( db_text
);
255 #if defined(SelfTest)
256 printf( "sending command <<:Tag %s>>\n", str
);
260 * This is REALLY sleazy. We pass the nul along with the
261 * string so that the core editor doesn't have to copy the
262 * string to get a nul termination. This should be fixed
263 * as part of making the editor fully 8-bit clean.
265 ipb
.code
= VI_TAGSPLIT
;
267 ipb
.len1
= strlen(str
) + 1;
268 vi_send(vi_ofd
, "a", &ipb
);
275 #if defined(__STDC__)
276 static void go_to_tag( Widget w
)
278 static void go_to_tag( w
)
285 str
= XmTextFieldGetString( db_text
);
287 #if defined(SelfTest)
288 printf( "sending command <<:tag %s>>\n", str
);
292 * This is REALLY sleazy. We pass the nul along with the
293 * string so that the core editor doesn't have to copy the
294 * string to get a nul termination. This should be fixed
295 * as part of making the editor fully 8-bit clean.
299 ipb
.len1
= strlen(str
) + 1;
300 vi_send(vi_ofd
, "a", &ipb
);
308 /* Draw and display a dialog the describes nvi options */
310 #if defined(__STDC__)
311 static Widget
create_tags_dialog( Widget parent
, String title
)
313 static Widget
create_tags_dialog( parent
, title
)
318 Widget box
, form
, form2
, form3
, buttons
;
321 if ( db_tabs
!= NULL
) return db_tabs
;
323 box
= XtVaCreatePopupShell( title
,
324 xmDialogShellWidgetClass
,
327 XmNallowShellResize
, False
,
330 XtAddCallback( box
, XmNpopdownCallback
, cancel_cb
, 0 );
331 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
333 form
= XtVaCreateWidget( "Tags",
339 buttons
= create_push_buttons( form
, button_data
, XtNumber(button_data
) );
340 XtVaSetValues( buttons
,
341 XmNbottomAttachment
, XmATTACH_FORM
,
345 form3
= XtVaCreateWidget( "form",
348 XmNleftAttachment
, XmATTACH_FORM
,
349 XmNrightAttachment
, XmATTACH_FORM
,
350 XmNbottomAttachment
, XmATTACH_WIDGET
,
351 XmNbottomWidget
, buttons
,
355 form2
= XtVaCreateWidget( "form",
358 XmNtopAttachment
, XmATTACH_FORM
,
359 XmNleftAttachment
, XmATTACH_FORM
,
360 XmNrightAttachment
, XmATTACH_FORM
,
361 XmNbottomAttachment
, XmATTACH_WIDGET
,
362 XmNbottomWidget
, form3
,
366 db_list
= XtVaCreateManagedWidget( "list",
369 XmNtopAttachment
, XmATTACH_FORM
,
370 XmNleftAttachment
, XmATTACH_POSITION
,
372 XmNrightAttachment
, XmATTACH_FORM
,
373 XmNbottomAttachment
, XmATTACH_FORM
,
374 #if defined(SelfTest)
375 XmNvisibleItemCount
, 5,
377 XmNselectionPolicy
, XmSINGLE_SELECT
,
380 XtAddCallback( db_list
, XmNsingleSelectionCallback
, set_text_field
, 0 );
381 XtAddCallback( db_list
, XmNdefaultActionCallback
, go_to_tag
, 0 );
383 XtVaCreateManagedWidget( "Tag Stack",
386 XmNtopAttachment
, XmATTACH_FORM
,
387 XmNbottomAttachment
, XmATTACH_FORM
,
388 XmNleftAttachment
, XmATTACH_FORM
,
389 XmNrightAttachment
, XmATTACH_POSITION
,
390 XmNrightPosition
, 20,
391 XmNalignment
, XmALIGNMENT_END
,
395 XtVaCreateManagedWidget( "Tag",
398 XmNtopAttachment
, XmATTACH_FORM
,
399 XmNbottomAttachment
, XmATTACH_FORM
,
400 XmNleftAttachment
, XmATTACH_FORM
,
401 XmNrightAttachment
, XmATTACH_POSITION
,
402 XmNrightPosition
, 20,
403 XmNalignment
, XmALIGNMENT_END
,
407 db_text
= XtVaCreateManagedWidget( "text",
408 xmTextFieldWidgetClass
,
410 XmNtopAttachment
, XmATTACH_FORM
,
411 XmNbottomAttachment
, XmATTACH_FORM
,
412 XmNrightAttachment
, XmATTACH_FORM
,
413 XmNleftAttachment
, XmATTACH_POSITION
,
417 XtAddCallback( db_text
, XmNactivateCallback
, go_to_tag
, 0 );
419 /* keep this global, we might destroy it later */
423 XtManageChild( form3
);
424 XtManageChild( form2
);
430 /* module entry point
431 * __vi_show_tags_dialog( parent, title )
434 #if defined(__STDC__)
435 void __vi_show_tags_dialog( Widget parent
, String title
)
437 void __vi_show_tags_dialog( parent
, title
)
442 Widget db
= create_tags_dialog( parent
, title
),
443 shell
= XtParent(db
);
447 /* get the current window's text */
448 __vi_set_tag_text( (String
) __vi_get_word_at_caret( NULL
) );
450 /* TODO: ask vi core for the current tag stack now */
452 /* leave this guy up (or just raise it) */
453 XtPopup( shell
, XtGrabNone
);
454 XMapRaised( XtDisplay( shell
), XtWindow( shell
) );
461 #if defined(SelfTest)
463 #if XtSpecificationRelease == 4
464 #define ArgcType Cardinal *
466 #define ArgcType int *
469 static void add_a_tag( Widget w
)
471 static String tags
[] = { "first", "second", "this is the third" };
474 __vi_push_tag( tags
[i
] );
475 i
= (i
+1) % XtNumber(tags
);
478 #if defined(__STDC__)
479 static void show_tags( Widget w
, XtPointer data
, XtPointer cbs
)
481 static void show_tags( w
, data
, cbs
)
487 __vi_show_tags_dialog( data
, "Tags" );
490 main( int argc
, char *argv
[] )
493 Widget top_level
, rc
, button
;
496 /* create a top-level shell for the window manager */
497 top_level
= XtVaAppInitialize( &ctx
,
499 NULL
, 0, /* options */
501 argv
, /* might get modified */
506 rc
= XtVaCreateManagedWidget( "rc",
507 xmRowColumnWidgetClass
,
512 button
= XtVaCreateManagedWidget( "Pop up tags dialog",
513 xmPushButtonGadgetClass
,
517 XtAddCallback( button
, XmNactivateCallback
, show_tags
, rc
);
519 button
= XtVaCreateManagedWidget( "Add a tag",
520 xmPushButtonGadgetClass
,
524 XtAddCallback( button
, XmNactivateCallback
, add_a_tag
, rc
);
526 button
= XtVaCreateManagedWidget( "Quit",
527 xmPushButtonGadgetClass
,
531 XtAddCallback( button
, XmNactivateCallback
, exit
, 0 );
533 XtRealizeWidget(top_level
);