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.8 2001/06/25 15:19:28 skimo Exp $ (Berkeley) $Date: 2001/06/25 15:19:28 $";
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>
64 #include "../common/common.h"
65 #include "../ipc/ip.h"
74 static Widget db_tabs
= NULL
,
78 static Boolean active
= False
;
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
)
119 if ( ! active
) return;
121 str
= XmStringCreateSimple( text
);
122 XmListAddItem( db_list
, str
, 1 );
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
,
137 static Widget
create_push_buttons( parent
, data
, count
)
146 base
= SpacingRatio
*count
+ 1;
147 form
= XtVaCreateManagedWidget( "buttons",
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
,
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 );
189 #if defined(SelfTest)
196 static void set_text_field(Widget w
, XtPointer ptr
, XmListCallbackStruct
*cbs
)
200 XmStringGetLtoR( cbs
->item
, XmSTRING_DEFAULT_CHARSET
, &str
);
201 XmTextFieldSetString( db_text
, 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)
218 /* some window managers destroy us upon popdown */
224 #if defined(__STDC__)
225 static void pop_tag( Widget w
)
227 static void pop_tag( w
)
231 static String buffer
= ":tagpop";
233 #if defined(SelfTest)
234 printf( "sending command <<%s>>\n", buffer
);
237 __vi_send_command_string( buffer
);
242 #if defined(__STDC__)
243 static void split_to_tag( Widget w
)
245 static void split_to_tag( w
)
252 str
= XmTextFieldGetString( db_text
);
254 #if defined(SelfTest)
255 printf( "sending command <<:Tag %s>>\n", str
);
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
;
266 ipb
.len1
= strlen(str
) + 1;
267 vi_send(vi_ofd
, "a", &ipb
);
274 #if defined(__STDC__)
275 static void go_to_tag( Widget w
)
277 static void go_to_tag( w
)
284 str
= XmTextFieldGetString( db_text
);
286 #if defined(SelfTest)
287 printf( "sending command <<:tag %s>>\n", str
);
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.
298 ipb
.len1
= strlen(str
) + 1;
299 vi_send(vi_ofd
, "a", &ipb
);
307 /* Draw and display a dialog the describes nvi options */
309 #if defined(__STDC__)
310 static Widget
create_tags_dialog( Widget parent
, String title
)
312 static Widget
create_tags_dialog( parent
, title
)
317 Widget box
, form
, form2
, form3
, buttons
;
320 if ( db_tabs
!= NULL
) return db_tabs
;
322 box
= XtVaCreatePopupShell( title
,
323 xmDialogShellWidgetClass
,
326 XmNallowShellResize
, False
,
329 XtAddCallback( box
, XmNpopdownCallback
, cancel_cb
, 0 );
330 XtAddCallback( box
, XmNdestroyCallback
, destroyed
, 0 );
332 form
= XtVaCreateWidget( "Tags",
338 buttons
= create_push_buttons( form
, button_data
, XtNumber(button_data
) );
339 XtVaSetValues( buttons
,
340 XmNbottomAttachment
, XmATTACH_FORM
,
344 form3
= XtVaCreateWidget( "form",
347 XmNleftAttachment
, XmATTACH_FORM
,
348 XmNrightAttachment
, XmATTACH_FORM
,
349 XmNbottomAttachment
, XmATTACH_WIDGET
,
350 XmNbottomWidget
, buttons
,
354 form2
= XtVaCreateWidget( "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",
368 XmNtopAttachment
, XmATTACH_FORM
,
369 XmNleftAttachment
, XmATTACH_POSITION
,
371 XmNrightAttachment
, XmATTACH_FORM
,
372 XmNbottomAttachment
, XmATTACH_FORM
,
373 #if defined(SelfTest)
374 XmNvisibleItemCount
, 5,
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",
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",
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
,
409 XmNtopAttachment
, XmATTACH_FORM
,
410 XmNbottomAttachment
, XmATTACH_FORM
,
411 XmNrightAttachment
, XmATTACH_FORM
,
412 XmNleftAttachment
, XmATTACH_POSITION
,
416 XtAddCallback( db_text
, XmNactivateCallback
, go_to_tag
, 0 );
418 /* keep this global, we might destroy it later */
422 XtManageChild( form3
);
423 XtManageChild( form2
);
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
)
436 void __vi_show_tags_dialog( parent
, title
)
441 Widget db
= create_tags_dialog( parent
, title
),
442 shell
= XtParent(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
) );
460 #if defined(SelfTest)
462 #if XtSpecificationRelease == 4
463 #define ArgcType Cardinal *
465 #define ArgcType int *
468 static void add_a_tag( Widget w
)
470 static String tags
[] = { "first", "second", "this is the third" };
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
)
480 static void show_tags( w
, data
, cbs
)
486 __vi_show_tags_dialog( data
, "Tags" );
489 main( int argc
, char *argv
[] )
492 Widget top_level
, rc
, button
;
495 /* create a top-level shell for the window manager */
496 top_level
= XtVaAppInitialize( &ctx
,
498 NULL
, 0, /* options */
500 argv
, /* might get modified */
505 rc
= XtVaCreateManagedWidget( "rc",
506 xmRowColumnWidgetClass
,
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
);