comparison pkg-src/tree-x/intf.c @ 163:0132846995bd r20-3b8

Import from CVS: tag r20-3b8
author cvs
date Mon, 13 Aug 2007 09:43:35 +0200
parents
children 85ec50267440
comparison
equal deleted inserted replaced
162:4de2936b4e77 163:0132846995bd
1 /* ----------------------------------------------------------------------------
2 * File : intf.c
3 * Purpose : X11/Athena interface code
4 * ----------------------------------------------------------------------------
5 */
6
7 #define GLOBALS 1
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <fcntl.h>
12
13 #include <X11/IntrinsicP.h>
14 #include <X11/ShellP.h>
15
16 #include <X11/Intrinsic.h>
17 #include <X11/StringDefs.h>
18
19 #ifdef XAW3D
20 #include <X11/Xaw3d/Box.h>
21 #include <X11/Xaw3d/Simple.h>
22 #include <X11/Xaw3d/MenuButton.h>
23 #include <X11/Xaw3d/SimpleMenu.h>
24 #include <X11/Xaw3d/SmeBSB.h>
25 #include <X11/Xaw3d/SmeLine.h>
26 #include <X11/Xaw3d/Form.h>
27 #include <X11/Xaw3d/Label.h>
28 #include <X11/Xaw3d/Dialog.h>
29 #include <X11/Xaw3d/AsciiText.h>
30 #include <X11/Xaw3d/AsciiSrc.h>
31 #include <X11/Xaw3d/Viewport.h>
32 #include <X11/Xaw3d/Scrollbar.h>
33 #include <X11/Xaw3d/Paned.h>
34 #include <X11/Xaw3d/Panner.h>
35 #include <X11/Xaw3d/Reports.h>
36 #else
37 #include <X11/Xaw/Box.h>
38 #include <X11/Xaw/Simple.h>
39 #include <X11/Xaw/MenuButton.h>
40 #include <X11/Xaw/SimpleMenu.h>
41 #include <X11/Xaw/SmeBSB.h>
42 #include <X11/Xaw/SmeLine.h>
43 #include <X11/Xaw/Form.h>
44 #include <X11/Xaw/Label.h>
45 #include <X11/Xaw/Dialog.h>
46 #include <X11/Xaw/AsciiText.h>
47 #include <X11/Xaw/AsciiSrc.h>
48 #include <X11/Xaw/Viewport.h>
49 #include <X11/Xaw/Scrollbar.h>
50 #include <X11/Xaw/Paned.h>
51 #include <X11/Xaw/Panner.h>
52 #include <X11/Xaw/Reports.h>
53 #endif
54
55 #include "defs.h"
56 #include "tree.h"
57 #include "dbl.h"
58 #include "intf.h"
59 #include "rsrc.h"
60 #include "input.h"
61 #include "help.h"
62
63 #include <X11/cursorfont.h>
64
65
66 /* ------------------------------------------------------------------------- */
67 /* Global Variables */
68 /* ------------------------------------------------------------------------- */
69
70 extern char *EnvNm; /* Stores name of current Envir file */
71
72 Atom wm_delete_window;
73 Widget TreeTopLevel;
74 Widget TreeDrawingArea;
75 Display *TreeDisplay;
76 XtAppContext app;
77 int TreeScreen;
78 int TreeContourWidth;
79 int TreeBorderSize = BORDER_SIZE;
80 int TreeParentDistance = PARENT_DISTANCE;
81 XFontStruct *TreeLabelFont;
82 DoubleBuffer *TreeDrawingAreaDB;
83 ContourOption TreeShowContourOption = NoContours;
84 DensityOption TreeLayoutDensity = Fixed;
85 char TreeShowSteps = FALSE;
86 char TreeAlignNodes = FALSE;
87 char PauseAfterStep = FALSE;
88
89 /* ------------------------------------------------------------------------- */
90 /* Local Variables */
91 /* ------------------------------------------------------------------------- */
92
93 static Tree *PopupNode; /* node selected for popup */
94 static NodePosition NodePos;
95
96 static Widget mainWindow;
97 static Widget topForm;
98
99 static Widget statusLabel;
100 static Widget statusText;
101
102 static Widget scrolledWindow;
103
104 static Widget helpShell;
105 static Widget helpForm;
106 static Widget helpScrollWindow;
107 static Widget helpText;
108 static Widget helpDoneButton;
109 static Widget helpTitle;
110 static Widget helpFrame;
111
112 static Widget treeMenubar;
113 static Widget treeMenus[NUM_MENUS];
114 static Widget treeMenuBtns[NUM_MENUS - 1]; /* don't need button for */
115 /* node popup menu */
116
117 static Widget treeMenuItems[TREE_MENU_ITEMS];
118 static Widget layoutMenuItems[LAYOUT_MENU_ITEMS];
119 static Widget nodeMenuItems[NODE_MENU_ITEMS];
120 static Widget helpBtn;
121
122 static String labelStr[NUM_MENU_STRS];
123 static String errStr[NUM_ERRS];
124
125 static Widget dialog[NUM_DLG];
126
127 /* globals used for state values */
128
129 static Widget dlgLevelScale, dlgLevelValuator,
130 dlgSiblingValuator, dlgSiblingScale;
131 static int dlgLevelValue;
132 static int dlgSiblingValue;
133 static int loading_file = 0;
134
135 static Pixmap check_pixmap, slider_pixmap;
136
137 static Boolean nodeFound;
138
139 static int PauseTime = ANIMATION_SPEED_FAST;
140 static Cursor PauseCursor;
141
142 static XtResource applRsrcsDesc[] = {
143 {
144 TrNbackgroundColor, TrCBackgroundColor,
145 XtRPixel, sizeof(Pixel),
146 XtOffset(ApplRsrcDataPtr, background_color),
147 XtRString, TrDefaultBackgroundColor
148 },
149 {
150 TrNtreeColor, TrCTreeColor,
151 XtRPixel, sizeof(Pixel),
152 XtOffset(ApplRsrcDataPtr, tree_color),
153 XtRString, TrDefaultTreeColor
154 },
155 {
156 TrNcontourColor, TrCContourColor,
157 XtRPixel, sizeof(Pixel),
158 XtOffset(ApplRsrcDataPtr, contour_color),
159 XtRString, TrDefaultContourColor
160 },
161 {
162 TrNsplitColor, TrCSplitColor,
163 XtRPixel, sizeof(Pixel),
164 XtOffset(ApplRsrcDataPtr, split_color),
165 XtRString, TrDefaultSplitColor
166 },
167 {
168 TrNhighlightColor, TrCHighlightColor,
169 XtRPixel, sizeof(Pixel),
170 XtOffset(ApplRsrcDataPtr, highlight_color),
171 XtRString, TrDefaultHighlightColor
172 },
173 {
174 TrNactionColor, TrCActionColor,
175 XtRPixel, sizeof(Pixel),
176 XtOffset(ApplRsrcDataPtr, action_color),
177 XtRString, TrDefaultActionColor
178 },
179 {
180 TrNcontourWidth, TrCContourWidth,
181 XtRInt, sizeof(int),
182 XtOffset(ApplRsrcDataPtr, contour_width),
183 XtRImmediate, (XtPointer) TrDefaultContourWidth
184 },
185 };
186
187 static void popdown_action();
188 static void activate_action();
189 static void quit_action();
190 static void Action();
191
192 static void select_action();
193 static void button_action();
194 static void menu_popup_action();
195
196 static void set_levelscale_CB();
197 static void levelscale_CB();
198 static void set_siblingscale_CB();
199 static void siblingscale_CB();
200 static void set_levelvalue_CB();
201 static void set_siblingvalue_CB();
202 static void levelvalue_CB();
203 static void siblingvalue_CB();
204
205 static void center_widget();
206
207 static XtActionsRec local_actions[] = {
208 {"wmpopdown", popdown_action},
209 {"dlg_activate", activate_action},
210 {"node_select", select_action},
211 {"node_menu_prepare", button_action},
212 {"maybe_menu_popup", menu_popup_action},
213 {"quit", quit_action},
214 };
215
216 String fallback_resources[] = {
217 "*statusText.width: 310",
218 "*treeDrawingArea.width: 310",
219 "*treeDrawingArea.height: 400",
220 "*Text.Font: -*-lucidatypewriter-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
221 "*Label.Font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-iso8859-1",
222 "*Command.Font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
223 "*SimpleMenu.Font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
224 "*SmeBSB.Font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
225 "*MenuButton.Font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
226 "*List.Font: -*-helvetica-bold-r-*-*-12-*-*-*-*-*-iso8859-1",
227 "*treeMenuBtn.label: Tree",
228 "*layoutMenuBtn.label: Layout",
229 "*helpBtn.label: Help...",
230 "*treeMenu*treeMenuNew.label: New Tree",
231 "*treeMenu*treeMenuLoad.label: Load Tree",
232 "*treeMenu*treeMenuSave.label: Save Tree",
233 "*treeMenu*treeMenuQuit.label: Quit",
234 "*layoutMenu*layoutMenuFixed.label: Fixed",
235 "*layoutMenu*layoutMenuVariable.label: Variable",
236 "*layoutMenu*layoutMenuSpacing.label: Spacing...",
237 "*layoutMenu*layoutMenuAlignNodes.label: Align Nodes on Level",
238 "*dlgNewTree.title: New Tree",
239 "*dlgNodeName.title: Node Name",
240 "*dlgInfo.title: Information",
241 "*dlgError.title: Error!",
242 "*dlgSpacing.title: Tree Node Spacing",
243 "*helpShell.title: Help",
244 "*dlgNewTreeForm.label: Enter name of root node:",
245 "*dlgNodeNameForm.label: Enter name of new node:",
246 "*dlgFileForm.label: Enter name of file:",
247 "*dlgInfoForm.label: Information:",
248 "*dlgErrorForm.label: Error:",
249 "*dlgSpacing.label: Spacing Dialog",
250 "*dlgLevelLabel.label: Level spacing:",
251 "*dlgSiblingLabel.label: Sibling spacing:",
252 "*dlgLevelValuator.width: 40",
253 "*dlgLevelValuator.width: 40",
254 "*dlgNewTreeOk.label: Ok",
255 "*dlgNewTreeCancel.label: Cancel",
256 "*dlgFileOk.label: Ok",
257 "*dlgFileCancel.label: Cancel",
258 "*dlgInfoButton.label: Acknowledged",
259 "*dlgErrorButton.label: Acknowledged",
260 "*dlgOkButton.label: Ok",
261 "*dlgCancelButton.label: Cancel",
262 "*dlgNodeNameOk.label: Ok",
263 "*dlgNodeNameCancel.label: Cancel",
264 "*helpDoneButton.label: Dismiss",
265 "*helpTitle.label: Help for Drawing Dynamic Trees",
266 "*treeDrawingArea.Translations: #override \\n\
267 <Btn1Down>: node_select(EDIT)\\n\
268 <Btn2Down>: node_select(VIEW)\\n\
269 <Btn3Down>: XawPositionSimpleMenu(nodeMenu)node_menu_prepare()XtMenuPopup(nodeMenu)\\n",
270 NULL,
271 };
272
273 static ApplRsrcData applRsrcs;
274 static ApplRsrcDataPtr applRsrcsPtr;
275
276 /* included bitmaps */
277
278 #define gray_width 8
279 #define gray_height 8
280 static unsigned char gray_bits[] = {
281 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa
282 };
283
284 /* This is a check mark stolen from the xmh application. :) */
285 #define check_width 9
286 #define check_height 8
287 static unsigned char check_bits[] = {
288 0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
289 0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
290 };
291
292 #define slider_pixmap_width 4
293 #define slider_pixmap_height 4
294 static char slider_pixmap_bits[] = {
295 0x05, 0x0a, 0x05, 0x0a
296 };
297
298 /* ------------------------------------------------------------------------- */
299 /* Forward Function Declarations */
300 /* ------------------------------------------------------------------------- */
301
302 static void popup_dialog();
303
304 static void Quit_CB();
305
306 static void Contours_CB();
307 static void ShowContours_CB();
308 static void Pause_CB();
309 static void Speed_CB();
310
311 static void Help_CB();
312 static void HelpDone_CB();
313 static void Scale_CB();
314
315 static void TreeMenu_CB();
316 static void LayoutMenu_CB();
317 static void NodeMenu_CB();
318
319 static void NodeLabel_CB();
320 static void NewTree_CB();
321 static void File_CB();
322
323 static void Popdown_CB();
324 static void ButtonHandler();
325
326 extern void ExposeHandler();
327
328 /* ------------------------------------------------------------------------- */
329 /* Functions */
330 /* ------------------------------------------------------------------------- */
331
332 /* ----------------------------------------------------------------------------
333 *
334 * Status() displays the specified text in the status area.
335 * 'urgent' overrides the value of TreeShowSteps.
336 *
337 * ----------------------------------------------------------------------------
338 */
339
340 void
341 StatusMsg(msg, urgent)
342 char *msg;
343 int urgent;
344 {
345 if (TreeShowSteps || urgent)
346 XtVaSetValues(statusText, XtNlabel, msg, NULL);
347 }
348
349
350 /* ----------------------------------------------------------------------------
351 *
352 * Pause is a trivial function, for the benefit of interface-dependent code
353 * inside tree.c. This avoids having to include X11 stuff inside that file.
354 * PauseTime is expected to contain an integer indicating 1/10ths of a sec.
355 *
356 * ----------------------------------------------------------------------------
357 */
358
359 void
360 Pause()
361 {
362 XEvent event;
363
364 if (PauseAfterStep) {
365 XGrabKeyboard(TreeDisplay, XtWindow(TreeTopLevel), False,
366 GrabModeAsync, GrabModeAsync, CurrentTime);
367 XGrabPointer(TreeDisplay, XtWindow(TreeTopLevel), False,
368 ButtonPressMask | ButtonReleaseMask,
369 GrabModeAsync, GrabModeAsync, None,
370 PauseCursor, CurrentTime);
371 XMaskEvent(TreeDisplay, ButtonPressMask | KeyPress, &event);
372 XUngrabPointer(TreeDisplay, CurrentTime);
373 XUngrabKeyboard(TreeDisplay, CurrentTime);
374 }
375 else if (TreeShowSteps) {
376 XSync(TreeDisplay, 0);
377 usleep(PauseTime * 100000);
378 }
379 }
380
381 /* ----------------------------------------------------------------------------
382 *
383 * BuildPopupMenus() builds the popup menus for use in the application
384 * window.
385 *
386 * ----------------------------------------------------------------------------
387 */
388
389 void
390 BuildPopupMenus(parent)
391 Widget parent;
392 {
393 Arg args[2];
394 String xstr;
395
396 labelStr[STR_NODE_COLLAPSE] = "Collapse Node";
397 labelStr[STR_NODE_EXPAND] = "Expand Node";
398
399 treeMenus[NODE_MENU] = XtVaCreatePopupShell("nodeMenu",
400 simpleMenuWidgetClass,
401 parent,
402 XtNlabel, " ",
403 NULL);
404
405 (void) XtVaCreateManagedWidget("nodeMenuAddChild", smeLineObjectClass,
406 treeMenus[NODE_MENU],
407 NULL);
408
409 nodeMenuItems[NODE_MENU_ADD_CHILD] =
410 XtVaCreateManagedWidget("nodeMenuAddChild", smeBSBObjectClass,
411 treeMenus[NODE_MENU],
412 XtNlabel, "Add Child",
413 NULL);
414 XtAddCallback(nodeMenuItems[NODE_MENU_ADD_CHILD],
415 XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_CHILD);
416
417 nodeMenuItems[NODE_MENU_ADD_BEFORE] =
418 XtVaCreateManagedWidget("nodeMenuAddSiblingBefore", smeBSBObjectClass,
419 treeMenus[NODE_MENU],
420 XtNlabel, "Add Sibling Before",
421 NULL);
422 XtAddCallback(nodeMenuItems[NODE_MENU_ADD_BEFORE],
423 XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_BEFORE);
424
425 nodeMenuItems[NODE_MENU_ADD_AFTER] =
426 XtVaCreateManagedWidget("nodeMenuAddSiblingAfter", smeBSBObjectClass,
427 treeMenus[NODE_MENU],
428 XtNlabel, "Add Sibling After",
429 NULL);
430 XtAddCallback(nodeMenuItems[NODE_MENU_ADD_AFTER],
431 XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ADD_AFTER);
432
433 nodeMenuItems[NODE_MENU_ELISION] =
434 XtVaCreateManagedWidget("nodeMenuElision", smeBSBObjectClass,
435 treeMenus[NODE_MENU],
436 XtNlabel, labelStr[STR_NODE_COLLAPSE],
437 NULL);
438 XtAddCallback(nodeMenuItems[NODE_MENU_ELISION],
439 XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_ELISION);
440
441
442 nodeMenuItems[NODE_MENU_DELETE] =
443 XtVaCreateManagedWidget("nodeMenuDeleteNode", smeBSBObjectClass,
444 treeMenus[NODE_MENU],
445 XtNlabel, "Delete Node",
446 NULL);
447 XtAddCallback(nodeMenuItems[NODE_MENU_DELETE],
448 XtNcallback, NodeMenu_CB, (XtPointer) NODE_MENU_DELETE);
449
450
451 }
452
453 /* ----------------------------------------------------------------------------
454 *
455 * BuildMenubar() builds the menubar that appears in the main window.
456 *
457 * ----------------------------------------------------------------------------
458 */
459
460
461 void
462 BuildMenubar(parent)
463 Widget parent;
464 {
465 Arg args[4];
466 int i;
467 Widget box;
468
469 box = XtVaCreateManagedWidget("menuBox",
470 boxWidgetClass,
471 parent,
472 XtNshowGrip, FALSE,
473 XtNborderWidth, 0,
474 NULL);
475
476
477 /* menu button widgets */
478 treeMenuBtns[TREE_MENU] =
479 XtVaCreateManagedWidget("treeMenuBtn",
480 menuButtonWidgetClass,
481 box,
482 XtNmenuName, "treeMenu",
483 NULL);
484 treeMenuBtns[LAYOUT_MENU] =
485 XtVaCreateManagedWidget("layoutMenuBtn",
486 menuButtonWidgetClass,
487 box,
488 XtNmenuName, "layoutMenu",
489 NULL);
490
491 helpBtn = XtVaCreateManagedWidget("helpBtn",
492 commandWidgetClass,
493 box,
494 NULL);
495
496 XtAddCallback(helpBtn, XtNcallback, Help_CB, NULL);
497
498 /* create pulldwon menus */
499
500 treeMenus[TREE_MENU] = XtVaCreatePopupShell("treeMenu",
501 simpleMenuWidgetClass,
502 treeMenuBtns[TREE_MENU],
503 NULL, 0);
504 treeMenus[LAYOUT_MENU] = XtVaCreatePopupShell("layoutMenu",
505 simpleMenuWidgetClass,
506 treeMenuBtns[LAYOUT_MENU],
507 NULL, 0);
508
509
510 /* adding menu entries */
511
512 /* Tree menu */
513
514 treeMenuItems[TREE_MENU_NEW] =
515 XtVaCreateManagedWidget("treeMenuNew", smeBSBObjectClass,
516 treeMenus[TREE_MENU],
517 NULL);
518 XtAddCallback(treeMenuItems[TREE_MENU_NEW],
519 XtNcallback, TreeMenu_CB, TREE_MENU_NEW);
520
521 treeMenuItems[TREE_MENU_LOAD] =
522 XtVaCreateManagedWidget("treeMenuLoad", smeBSBObjectClass,
523 treeMenus[TREE_MENU],
524 NULL);
525 XtAddCallback(treeMenuItems[TREE_MENU_LOAD],
526 XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_LOAD);
527
528 treeMenuItems[TREE_MENU_SAVE] =
529 XtVaCreateManagedWidget("treeMenuSave", smeBSBObjectClass,
530 treeMenus[TREE_MENU],
531 NULL);
532 XtAddCallback(treeMenuItems[TREE_MENU_SAVE],
533 XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_SAVE);
534
535 treeMenuItems[TREE_MENU_SEP1] =
536 XtVaCreateManagedWidget("treeMenuSep1", smeLineObjectClass,
537 treeMenus[TREE_MENU],
538 NULL);
539
540 #ifdef COMMENT
541 treeMenuItems[TREE_MENU_STATS] =
542 XtVaCreateManagedWidget("treeMenuStats", smeBSBObjectClass,
543 treeMenus[TREE_MENU],
544 XtNlabel, labelStr[STR_SHOW_STATS],
545 NULL);
546
547 XtAddCallback(treeMenuItems[TREE_MENU_STATS],
548 XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_STATS);
549
550 XtSetSensitive(treeMenuItems[TREE_MENU_STATS], FALSE);
551
552 treeMenuItems[TREE_MENU_SEP2] =
553 XtVaCreateManagedWidget("treeMenuSep2", smeLineObjectClass,
554 treeMenus[TREE_MENU],
555 NULL);
556 #endif /* COMMENT */
557
558 treeMenuItems[TREE_MENU_QUIT] =
559 XtVaCreateManagedWidget("treeMenuQuit", smeBSBObjectClass,
560 treeMenus[TREE_MENU],
561 NULL);
562 XtAddCallback(treeMenuItems[TREE_MENU_QUIT],
563 XtNcallback, TreeMenu_CB, (XtPointer) TREE_MENU_QUIT);
564
565
566
567 /* Layout menu */
568
569 #ifdef COMMENT
570 treeMenuItems[LAYOUT_MENU_FIXED] =
571 XtVaCreateManagedWidget("layoutMenuFixed", smeBSBObjectClass,
572 treeMenus[LAYOUT_MENU],
573 XtNleftMargin, 18,
574 NULL);
575
576 XtAddCallback(treeMenuItems[LAYOUT_MENU_FIXED],
577 XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_FIXED);
578
579 treeMenuItems[LAYOUT_MENU_VARIABLE] =
580 XtVaCreateManagedWidget("layoutMenuVariable", smeBSBObjectClass,
581 treeMenus[LAYOUT_MENU],
582 XtNleftMargin, 18,
583 NULL);
584
585 XtAddCallback(treeMenuItems[LAYOUT_MENU_VARIABLE],
586 XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_VARIABLE);
587
588
589 treeMenuItems[LAYOUT_MENU_SEP1] =
590 XtVaCreateManagedWidget("layoutSep1", smeLineObjectClass,
591 treeMenus[LAYOUT_MENU],
592 NULL);
593 #endif /* COMMENT */
594
595 treeMenuItems[LAYOUT_MENU_SPACING] =
596 XtVaCreateManagedWidget("layoutMenuSpacing", smeBSBObjectClass,
597 treeMenus[LAYOUT_MENU],
598 XtNleftMargin, 18,
599 NULL);
600 XtAddCallback(treeMenuItems[LAYOUT_MENU_SPACING],
601 XtNcallback, LayoutMenu_CB, (XtPointer) LAYOUT_MENU_SPACING);
602
603 treeMenuItems[LAYOUT_MENU_SEP2] =
604 XtVaCreateManagedWidget("layoutMenuSep2", smeLineObjectClass,
605 treeMenus[LAYOUT_MENU],
606 NULL);
607
608 /* the following is a toggle button - we hack it using a bitmap */
609 treeMenuItems[LAYOUT_MENU_ALIGN_NODES] =
610 XtVaCreateManagedWidget("layoutMenuAlignNodes", smeBSBObjectClass,
611 treeMenus[LAYOUT_MENU],
612 XtNleftMargin, 18,
613 NULL);
614 XtAddCallback(treeMenuItems[LAYOUT_MENU_ALIGN_NODES],
615 XtNcallback, LayoutMenu_CB,
616 (XtPointer) LAYOUT_MENU_ALIGN_NODES);
617
618 }
619
620 /* ----------------------------------------------------------------------------
621 *
622 * BuildDialogs() builds all the dialogs used in this application.
623 *
624 * ----------------------------------------------------------------------------
625 */
626
627
628 BuildDialogs(parent)
629 Widget parent;
630 {
631 int i;
632 Widget
633 tmpwidget, dlgForm, dlgValue,
634 dlgLevelLabel, dlgSiblingLabel,
635 dlgOkButton, dlgCancelButton;
636
637 labelStr[STR_LOAD_FILE] = "Name of file to load:";
638 labelStr[STR_SAVE_FILE] = "Name of file to save:";
639
640 errStr[ERR_OPENFAIL] = "Failed to open file.";
641 errStr[ERR_EMPTYFILE] = "Input file is empty.";
642 errStr[ERR_MEMALLOC] = "Memory allocation failed.";
643 errStr[ERR_NOBEGIN] = "End of list does not have a matching beginning.";
644 errStr[ERR_NOEND] = "Beginning of list does not have a matching end.";
645 errStr[ERR_NOROOT] = "Input file does not have a root label.";
646 errStr[ERR_MANYROOT] = "Input file has more than one root label.";
647
648
649 dialog[DLG_NEW] = XtVaCreatePopupShell("dlgNewTree",
650 transientShellWidgetClass,
651 parent,
652 XtNresizable, TRUE,
653 NULL);
654
655 tmpwidget = XtVaCreateManagedWidget("dlgNewTreeForm",
656 dialogWidgetClass,
657 dialog[DLG_NEW],
658 XtNresizable, TRUE,
659 XtNvalue, "",
660 NULL);
661
662 XawDialogAddButton(tmpwidget, "dlgNewTreeOk", NewTree_CB,
663 (XtPointer) TRUE);
664 XawDialogAddButton(tmpwidget, "dlgNewTreeCancel", NewTree_CB,
665 (XtPointer) FALSE);
666
667 dlgValue = XtNameToWidget(tmpwidget, "value");
668
669 XtOverrideTranslations
670 (dlgValue, XtParseTranslationTable
671 ("<Key>Return:dlg_activate(dlgNewTreeOk)\n"));
672
673
674 dialog[DLG_NODE_NAME] = XtVaCreatePopupShell("dlgNodeName",
675 transientShellWidgetClass,
676 TreeTopLevel,
677 XtNresizable, TRUE,
678 NULL);
679
680
681 tmpwidget= XtVaCreateManagedWidget("dlgNodeNameForm",
682 dialogWidgetClass,
683 dialog[DLG_NODE_NAME],
684 XtNresizable, TRUE,
685 XtNvalue, "",
686 NULL);
687
688 XawDialogAddButton(tmpwidget, "dlgNodeNameOk", NodeLabel_CB,
689 (XtPointer) TRUE);
690 XawDialogAddButton(tmpwidget, "dlgNodeNameCancel", NodeLabel_CB,
691 (XtPointer) FALSE);
692
693 dlgValue = XtNameToWidget(tmpwidget, "value");
694
695 XtOverrideTranslations
696 (dlgValue, XtParseTranslationTable
697 ("<Key>Return: dlg_activate(dlgNodeNameOk)\n"));
698
699
700 dialog[DLG_FILE] = XtVaCreatePopupShell("dlgFile",
701 transientShellWidgetClass,
702 TreeTopLevel,
703 XtNresizable, TRUE,
704 NULL);
705
706 tmpwidget = XtVaCreateManagedWidget("dlgFileForm",
707 dialogWidgetClass,
708 dialog[DLG_FILE],
709 XtNresizable, TRUE,
710 XtNvalue, "",
711 NULL);
712
713 XawDialogAddButton(tmpwidget, "dlgFileOk", File_CB, (XtPointer) TRUE);
714 XawDialogAddButton(tmpwidget, "dlgFileCancel", File_CB, (XtPointer) FALSE);
715
716 dlgValue = XtNameToWidget(tmpwidget, "value");
717
718 XtOverrideTranslations
719 (dlgValue, XtParseTranslationTable
720 ("<Key>Return:dlg_activate(dlgFileOk)\n"));
721
722
723 dialog[DLG_INFO] = XtVaCreatePopupShell("dlgInfo",
724 transientShellWidgetClass,
725 TreeTopLevel,
726 XtNresizable, TRUE,
727 NULL);
728
729 tmpwidget = XtVaCreatePopupShell("dlgInfoForm",
730 dialogWidgetClass,
731 dialog[DLG_INFO],
732 XtNresizable, TRUE,
733 XtNvalue, "",
734 NULL);
735
736 XawDialogAddButton(tmpwidget, "dlgInfoButton", Popdown_CB,
737 (XtPointer) dialog[DLG_INFO]);
738
739
740 dialog[DLG_ERROR] = XtVaCreatePopupShell("dlgError",
741 transientShellWidgetClass,
742 TreeTopLevel,
743 XtNresizable, TRUE,
744 NULL);
745
746 tmpwidget = XtVaCreateManagedWidget("dlgErrorForm",
747 dialogWidgetClass,
748 dialog[DLG_ERROR],
749 XtNresizable, TRUE,
750 XtNvalue, "",
751 NULL);
752
753 XawDialogAddButton(tmpwidget, "dlgErrorButton", Popdown_CB,
754 (XtPointer) dialog[DLG_ERROR]);
755
756
757 dialog[DLG_SPACING] = XtVaCreatePopupShell("dlgSpacing",
758 transientShellWidgetClass,
759 TreeTopLevel,
760 XtNresizable, FALSE,
761 NULL);
762 dlgForm = XtVaCreateManagedWidget("dlgSpacingForm",
763 formWidgetClass,
764 dialog[DLG_SPACING],
765 XtNresizable, FALSE,
766 NULL);
767
768 dlgLevelLabel = XtVaCreateManagedWidget("dlgLevelLabel",
769 labelWidgetClass,
770 dlgForm,
771 XtNfromVert, NULL,
772 XtNfromHoriz, NULL,
773 XtNtop, XawChainTop,
774 XtNbottom, XawChainTop,
775 XtNleft, XawChainLeft,
776 XtNright, XawChainLeft,
777 XtNborderWidth, 0,
778 NULL);
779
780 dlgLevelValuator = XtVaCreateManagedWidget("dlgLevelValuator",
781 labelWidgetClass,
782 dlgForm,
783 XtNfromVert, NULL,
784 XtNfromHoriz, dlgLevelLabel,
785 XtNtop, XawChainTop,
786 XtNbottom, XawChainTop,
787 XtNleft, XawChainLeft,
788 XtNright, XawChainLeft,
789 XtNlabel, " ",
790 NULL);
791
792
793 dlgLevelScale = XtVaCreateManagedWidget("dlgLevelScale",
794 pannerWidgetClass,
795 dlgForm,
796 XtNfromVert, dlgLevelLabel,
797 XtNfromHoriz, NULL,
798 XtNtop, XawChainTop,
799 XtNbottom, XawChainTop,
800 XtNleft, XawChainLeft,
801 XtNright, XawChainLeft,
802 XtNcanvasWidth, 110,
803 XtNdefaultScale, 1,
804 XtNinternalSpace, 1,
805 XtNrubberBand, FALSE,
806 XtNshadowThickness, 0,
807 XtNallowOff, FALSE,
808 XtNwidth, 200,
809 XtNsliderWidth, 10,
810 XtNheight, 15,
811 NULL);
812
813 XtOverrideTranslations(dlgLevelScale, XtParseTranslationTable("\
814 <Btn2Down>: start()\n\
815 <Btn2Motion>: move()\n\
816 <Btn2Up>: notify()stop()\n\
817 <Btn3Down>: abort()\n"));
818
819 XtAddCallback(dlgLevelScale, XtNreportCallback, levelscale_CB,
820 (XtPointer) dlgLevelValuator);
821 XtAddCallback(dlgLevelScale, XtNreportCallback, levelvalue_CB,
822 (XtPointer) &dlgLevelValue);
823
824 dlgSiblingLabel = XtVaCreateManagedWidget("dlgSiblingLabel",
825 labelWidgetClass,
826 dlgForm,
827 XtNfromVert, dlgLevelScale,
828 XtNfromHoriz, NULL,
829 XtNtop, XawChainTop,
830 XtNbottom, XawChainTop,
831 XtNleft, XawChainLeft,
832 XtNright, XawChainLeft,
833 XtNborderWidth, 0,
834 NULL);
835
836 dlgSiblingValuator = XtVaCreateManagedWidget("dlgLevelValuator",
837 labelWidgetClass,
838 dlgForm,
839 XtNfromVert, dlgLevelScale,
840 XtNfromHoriz, dlgSiblingLabel,
841 XtNtop, XawChainTop,
842 XtNbottom, XawChainTop,
843 XtNleft, XawChainLeft,
844 XtNright, XawChainLeft,
845 XtNlabel, " ",
846 NULL);
847 dlgSiblingScale = XtVaCreateManagedWidget("dlgSiblingScale",
848 pannerWidgetClass,
849 dlgForm,
850 XtNfromVert, dlgSiblingLabel,
851 XtNfromHoriz, NULL,
852 XtNtop, XawChainTop,
853 XtNbottom, XawChainTop,
854 XtNleft, XawChainLeft,
855 XtNright, XawChainLeft,
856 XtNcanvasWidth, 110,
857 XtNdefaultScale, 1,
858 XtNinternalSpace, 1,
859 XtNrubberBand, FALSE,
860 XtNshadowThickness, 0,
861 XtNallowOff, FALSE,
862 XtNwidth, 200,
863 XtNsliderWidth, 10,
864 XtNheight, 15,
865 NULL);
866
867 XtOverrideTranslations(dlgSiblingScale, XtParseTranslationTable("\
868 <Btn2Down>: start()\n\
869 <Btn2Motion>: move()\n\
870 <Btn2Up>: notify()stop()\n\
871 <Btn3Down>: abort()\n"));
872
873 XtAddCallback(dlgSiblingScale, XtNreportCallback, siblingscale_CB,
874 (XtPointer) dlgSiblingValuator);
875 XtAddCallback(dlgSiblingScale, XtNreportCallback, siblingvalue_CB,
876 (XtPointer) &dlgSiblingValue);
877
878 dlgOkButton = XtVaCreateManagedWidget("dlgOkButton",
879 commandWidgetClass,
880 dlgForm,
881 XtNfromVert, dlgSiblingScale,
882 XtNfromHoriz, NULL,
883 XtNtop, XawChainTop,
884 XtNbottom, XawChainTop,
885 XtNleft, XawChainLeft,
886 XtNright, XawChainLeft,
887 NULL);
888
889 dlgCancelButton = XtVaCreateManagedWidget("dlgCancelButton",
890 commandWidgetClass,
891 dlgForm,
892 XtNfromVert, dlgSiblingScale,
893 XtNfromHoriz, dlgOkButton,
894 XtNtop, XawChainTop,
895 XtNbottom, XawChainTop,
896 XtNleft, XawChainLeft,
897 XtNright, XawChainLeft,
898 NULL);
899
900 XtAddCallback(dlgOkButton, XtNcallback, Scale_CB, (XtPointer) TRUE);
901 XtAddCallback(dlgCancelButton, XtNcallback, Scale_CB, (XtPointer) FALSE);
902 }
903
904 /* ----------------------------------------------------------------------------
905 *
906 * BuildHelpWindow() builds the help window that is displayed when the
907 * Help button on the application main window is pressed.
908 *
909 * ----------------------------------------------------------------------------
910 */
911
912
913 static void
914 BuildHelpWindow(parent)
915 Widget parent;
916 {
917 int i;
918
919 helpShell = XtVaCreatePopupShell("helpShell", transientShellWidgetClass,
920 parent,
921 NULL);
922
923 helpForm = XtVaCreateManagedWidget("helpForm",
924 formWidgetClass,
925 helpShell,
926 NULL);
927
928 helpDoneButton = XtVaCreateManagedWidget("helpDoneButton",
929 commandWidgetClass,
930 helpForm,
931 XtNfromVert, NULL,
932 XtNfromHoriz, NULL,
933 XtNtop, XawChainTop,
934 XtNbottom, XawChainTop,
935 XtNleft, XawChainLeft,
936 XtNright, XawChainLeft,
937 NULL);
938
939 XtAddCallback(helpDoneButton, XtNcallback, Popdown_CB,
940 (XtPointer) helpShell);
941
942 helpTitle = XtVaCreateManagedWidget("helpTitle",
943 labelWidgetClass,
944 helpForm,
945 XtNfromVert, NULL,
946 XtNfromHoriz, helpDoneButton,
947 XtNtop, XawChainTop,
948 XtNbottom, XawChainTop,
949 XtNleft, XawChainLeft,
950 XtNright, XawChainLeft,
951 XtNborderWidth, 0,
952 XtNlabel, "",
953 NULL);
954
955 helpText = XtVaCreateManagedWidget("helpText",
956 asciiTextWidgetClass,
957 helpForm,
958 XtNfromVert, helpDoneButton,
959 XtNfromHoriz, NULL,
960 XtNtop, XawChainTop,
961 XtNbottom, XawChainBottom,
962 XtNleft, XawChainLeft,
963 XtNright, XawChainRight,
964 XtNeditType, XawtextRead,
965 XtNdisplayCaret, FALSE,
966 XtNscrollVertical, XawtextScrollAlways,
967 XtNscrollHorizontal,
968 XawtextScrollWhenNeeded,
969 XtNuseStringInPlace, TRUE,
970 XtNstring, help_text,
971 XtNwidth, 530,
972 XtNheight, 650,
973 NULL);
974 }
975
976 /* ----------------------------------------------------------------------------
977 *
978 * BuildApplicationWindow() assumes that TreeTopLevel has been initialized
979 * by XtInitialize(). TreeDrawingArea is set to the drawing area in this
980 * application window.
981 *
982 * ----------------------------------------------------------------------------
983 */
984
985
986 static void
987 BuildApplicationWindow(parent)
988 Widget parent;
989 {
990 Widget topPane, box;
991
992 topPane = XtVaCreateManagedWidget("topPane",
993 panedWidgetClass,
994 parent,
995 XtNorientation, XtorientVertical,
996 NULL);
997
998 BuildMenubar(topPane);
999
1000 statusText = XtVaCreateManagedWidget("statusText",
1001 labelWidgetClass,
1002 topPane,
1003 XtNborderWidth, 0,
1004 NULL);
1005
1006 scrolledWindow = XtVaCreateManagedWidget("scrolledWindow",
1007 viewportWidgetClass,
1008 topPane,
1009 XtNshowGrip, FALSE,
1010 XtNallowHoriz, TRUE,
1011 XtNallowVert, TRUE,
1012 XtNuseBottom, TRUE,
1013 XtNuseRight, TRUE,
1014 NULL);
1015
1016 TreeDrawingArea = XtVaCreateManagedWidget("treeDrawingArea",
1017 simpleWidgetClass,
1018 scrolledWindow,
1019 NULL);
1020 }
1021
1022 /* ----------------------------------------------------------------------------
1023 *
1024 * HandleError() is used when ReadTreeFromFile() or SaveTreeToFile() returns
1025 * an error.
1026 *
1027 * ----------------------------------------------------------------------------
1028 */
1029
1030 void
1031 HandleError(error, tree)
1032 ErrCode error;
1033 Tree *tree;
1034 {
1035 Widget dlg, text;
1036
1037 if (tree) {
1038 dlg = XtNameToWidget(dialog[DLG_INFO], "dlgInfoForm");
1039 if (dlg) {
1040 XtVaSetValues(dlg,
1041 XtNvalue, errStr[error],
1042 XtNwidth, 200,
1043 NULL);
1044 text = XtNameToWidget(dlg, "value");
1045 if (text) {
1046 XtVaSetValues(text, XtNdisplayCaret, FALSE, NULL);
1047 XtVaSetValues(XawTextGetSource(text), XtNeditType, XawtextRead, NULL);
1048 }
1049 }
1050 popup_dialog(dialog[DLG_INFO], XtGrabExclusive);
1051 } else {
1052 dlg = XtNameToWidget(dialog[DLG_ERROR], "dlgErrorForm");
1053 if (dlg) {
1054 XtVaSetValues(dlg,
1055 XtNvalue, errStr[error],
1056 XtNwidth, 200,
1057 NULL);
1058 text = XtNameToWidget(dlg, "value");
1059 if (text) {
1060 XtVaSetValues(text, XtNdisplayCaret, FALSE, NULL);
1061 XtVaSetValues(XawTextGetSource(text), XtNeditType, XawtextRead, NULL);
1062 }
1063 }
1064 popup_dialog(dialog[DLG_ERROR], XtGrabExclusive);
1065 }
1066 }
1067
1068
1069 /* ----------------------------------------------------------------------------
1070 *
1071 * InitializeInterface() initializes the environment for displaying
1072 * the tree and creates the necessary supporting structures for interaction
1073 * and display. This function should be called only once.
1074 *
1075 * ----------------------------------------------------------------------------
1076 */
1077
1078 void
1079 InitializeInterface(argc, argv)
1080 int *argc;
1081 char *argv[];
1082 {
1083 XrmValue rmvalue;
1084 char *rmtype;
1085 Window win;
1086 Pixel background;
1087 XColor colors[NUM_COLORS];
1088 Colormap cmap;
1089 Pixmap gray_pixmap;
1090 Atom wm_delete_window;
1091
1092 /* XtSetLanguageProc is broken on some systems.
1093 The symptom is an error of the form:
1094 Warning: X locale modifiers not supported, using default
1095 so don't use this call:
1096
1097 XtSetLanguageProc(NULL, NULL, NULL);
1098 */
1099
1100 TreeTopLevel = XtVaAppInitialize(&app, "Xoobr",
1101 NULL, 0,
1102 argc, argv,
1103 fallback_resources,
1104 NULL);
1105
1106 ASSERT(TreeTopLevel, "failed to open connection to X server");
1107
1108 TreeDisplay = XtDisplay(TreeTopLevel);
1109 TreeScreen = DefaultScreen(TreeDisplay);
1110
1111 /* set up color resources */
1112 applRsrcsPtr = &applRsrcs;
1113 XtGetApplicationResources(TreeTopLevel, applRsrcsPtr,
1114 applRsrcsDesc, XtNumber(applRsrcsDesc),
1115 NULL, 0);
1116
1117 /* add actions */
1118 XtAppAddActions(app, local_actions, 6);
1119 XawSimpleMenuAddGlobalActions(app);
1120
1121 TreeContourWidth = applRsrcsPtr->contour_width;
1122
1123 /* set up label font info */
1124 if (XrmGetResource(XtDatabase(TreeDisplay),
1125 X11_FONT_RESOURCE, X11_FONT_CLASS_RESOURCE,
1126 &rmtype, &rmvalue)) {
1127 if (! (TreeLabelFont = XLoadQueryFont(TreeDisplay, rmvalue.addr)) ) {
1128 WARN_4("cannot load user-specified font:", rmvalue.addr,
1129 "using font:", X11_DEFAULT_FONT);
1130 TreeLabelFont = XLoadQueryFont(TreeDisplay, X11_DEFAULT_FONT);
1131 }
1132 }
1133 else
1134 TreeLabelFont = XLoadQueryFont(TreeDisplay, X11_DEFAULT_FONT);
1135 TreeLabelFont = XLoadQueryFont(TreeDisplay, "fixed");
1136
1137 check_pixmap =
1138 XCreateBitmapFromData(TreeDisplay, RootWindow(TreeDisplay, TreeScreen),
1139 check_bits, check_width, check_height);
1140
1141 slider_pixmap =
1142 XCreateBitmapFromData(TreeDisplay, RootWindow(TreeDisplay, TreeScreen),
1143 slider_pixmap_bits, slider_pixmap_width,
1144 slider_pixmap_height);
1145
1146 BuildApplicationWindow(TreeTopLevel);
1147 BuildHelpWindow(TreeTopLevel);
1148 BuildPopupMenus(TreeTopLevel);
1149 BuildDialogs(TreeTopLevel);
1150
1151
1152 XtAddEventHandler(TreeDrawingArea, ExposureMask, FALSE,
1153 ExposeHandler, (XtPointer) NULL);
1154
1155 XtVaSetValues(TreeDrawingArea,
1156 XtNbackground, applRsrcsPtr->background_color,
1157 NULL);
1158
1159 XtRealizeWidget(TreeTopLevel);
1160
1161 XtOverrideTranslations
1162 (TreeTopLevel,
1163 XtParseTranslationTable("<Message>WM_PROTOCOLS: quit()"));
1164
1165 wm_delete_window = XInternAtom(TreeDisplay, "WM_DELETE_WINDOW", FALSE);
1166 (void) XSetWMProtocols(TreeDisplay, XtWindow(TreeTopLevel),
1167 &wm_delete_window, 1);
1168
1169
1170 win = XtWindow(TreeDrawingArea);
1171 cmap = DefaultColormap(TreeDisplay, TreeScreen);
1172
1173 /* set up double buffer */
1174 colors[BACKGROUND_COLOR].pixel = applRsrcsPtr->background_color;
1175 XQueryColor(TreeDisplay, cmap, &(colors[BACKGROUND_COLOR]));
1176 colors[TREE_COLOR].pixel = applRsrcsPtr->tree_color;
1177 XQueryColor(TreeDisplay, cmap, &(colors[TREE_COLOR]));
1178 colors[CONTOUR_COLOR].pixel = applRsrcsPtr->contour_color;
1179 XQueryColor(TreeDisplay, cmap, &(colors[CONTOUR_COLOR]));
1180 colors[HIGHLIGHT_COLOR].pixel = applRsrcsPtr->highlight_color;
1181 XQueryColor(TreeDisplay, cmap, &(colors[HIGHLIGHT_COLOR]));
1182 colors[SPLIT_COLOR].pixel = applRsrcsPtr->split_color;
1183 XQueryColor(TreeDisplay, cmap, &(colors[SPLIT_COLOR]));
1184 colors[ACTION_COLOR].pixel = applRsrcsPtr->action_color;
1185 XQueryColor(TreeDisplay, cmap, &(colors[ACTION_COLOR]));
1186
1187 TreeDrawingAreaDB =
1188 DBLcreate_double_buffer(TreeDisplay,
1189 XtWindow(TreeDrawingArea), TRUE,
1190 colors, NUM_COLORS);
1191
1192 ASSERT(TreeDrawingAreaDB, "could not create double buffer");
1193
1194 background = DBLinq_background(TreeDrawingAreaDB);
1195
1196
1197 XtVaSetValues(TreeDrawingArea, XtNbackground, background, NULL);
1198
1199 /* also set the scrolledWindow background to same color */
1200 XtVaSetValues(XtParent(TreeDrawingArea), XtNbackground, background, NULL);
1201
1202 XSetFont(TreeDrawingAreaDB->display, TreeDrawingAreaDB->gc,
1203 TreeLabelFont->fid);
1204
1205 gray_pixmap =
1206 XCreatePixmapFromBitmapData(TreeDisplay, XtWindow(TreeDrawingArea),
1207 gray_bits, gray_width, gray_height,
1208 TreeDrawingAreaDB->colors[TREE_COLOR],
1209 background,
1210 DefaultDepth(TreeDisplay, TreeScreen));
1211
1212 #ifdef COMMENT
1213 XtVaSetValues(treeMenuItems[LAYOUT_MENU_VARIABLE],
1214 XtNleftBitmap, check_pixmap,
1215 NULL);
1216 #endif
1217
1218 XSetTile(TreeDrawingAreaDB->display, TreeDrawingAreaDB->gc, gray_pixmap);
1219 SetDrawColor(TREE_COLOR);
1220
1221 InitializeDissolveEffect(TreeDisplay, XtWindow(TreeDrawingArea),
1222 TreeDrawingAreaDB->colors[TREE_COLOR], background);
1223
1224 PauseCursor = XCreateFontCursor(TreeDisplay, XC_watch);
1225
1226 StatusMsg("Ready", TRUE);
1227 }
1228
1229
1230 /* ----------------------------------------------------------------------------
1231 *
1232 * UserEventLoop() is called after InitializeInterface() to handle
1233 * processing of events.
1234 *
1235 * ----------------------------------------------------------------------------
1236 */
1237
1238 void
1239 UserEventLoop()
1240 {
1241 XtAppMainLoop(app);
1242 }
1243
1244
1245 /* ------------------------------------------------------------------------- */
1246 /* Callback Routines */
1247 /* ------------------------------------------------------------------------- */
1248
1249 static void
1250 TreeMenu_CB(w, client_data, call_data)
1251 Widget w;
1252 XtPointer client_data;
1253 XtPointer call_data;
1254 {
1255 long menuItem = (long) client_data;
1256 Widget dlgFileForm;
1257
1258 switch (menuItem) {
1259 case TREE_MENU_NEW:
1260 popup_dialog(dialog[DLG_NEW], XtGrabExclusive);
1261 break;
1262 case TREE_MENU_LOAD:
1263 loading_file = 1;
1264 XtVaSetValues(dialog[DLG_FILE], XtNtitle, "Load File", NULL);
1265 dlgFileForm = XtNameToWidget(dialog[DLG_FILE], "dlgFileForm");
1266 XtVaSetValues(dlgFileForm, XtNvalue, "", NULL);
1267 popup_dialog(dialog[DLG_FILE], XtGrabExclusive);
1268 break;
1269 case TREE_MENU_SAVE:
1270 loading_file = 0;
1271 XtVaSetValues(dialog[DLG_FILE], XtNtitle, "Save File", NULL);
1272 dlgFileForm = XtNameToWidget(dialog[DLG_FILE], "dlgFileForm");
1273 XtVaSetValues(dlgFileForm, XtNvalue, "", NULL);
1274 popup_dialog(dialog[DLG_FILE], XtGrabExclusive);
1275 break;
1276 case TREE_MENU_QUIT:
1277 exit(0);
1278 break;
1279
1280 default:
1281 WARN("unknown menu item in TreeMenu_CB");
1282 }
1283 }
1284
1285
1286 /* ------------------------------------------------------------------------- */
1287
1288 static void
1289 LayoutMenu_CB(w, client_data, call_data)
1290 Widget w;
1291 XtPointer client_data;
1292 XtPointer call_data;
1293 {
1294 long menuItem = (long) client_data;
1295 char tmpstr[10];
1296
1297 switch (menuItem) {
1298 #ifdef COMMENT
1299 case LAYOUT_MENU_FIXED:
1300 XtVaSetValues(layoutMenuItems[LAYOUT_MENU_VARIABLE],
1301 XtNleftBitmap, None, NULL);
1302 XtVaSetValues(layoutMenuItems[LAYOUT_MENU_FIXED],
1303 XtNleftBitmap, check_pixmap, NULL);
1304
1305 if (TreeLayoutDensity != Fixed) {
1306 TreeLayoutDensity = Fixed;
1307 DeleteTree(TheTree, TRUE);
1308 SetupTree(TheTree);
1309 }
1310 break;
1311 case LAYOUT_MENU_VARIABLE:
1312 XtVaSetValues(layoutMenuItems[LAYOUT_MENU_VARIABLE],
1313 XtNleftBitmap, check_pixmap, NULL);
1314 XtVaSetValues(layoutMenuItems[LAYOUT_MENU_FIXED],
1315 XtNleftBitmap, None, NULL);
1316
1317 if (TreeLayoutDensity != Variable) {
1318 TreeLayoutDensity = Variable;
1319 DeleteTree(TheTree, TRUE);
1320 SetupTree(TheTree);
1321 }
1322 break;
1323 #endif COMMENT
1324 case LAYOUT_MENU_SPACING:
1325 dlgLevelValue = TreeParentDistance;
1326 dlgSiblingValue = TreeBorderSize;
1327 sprintf(tmpstr, "%d ", dlgLevelValue);
1328 XtVaSetValues(dlgLevelValuator, XtNlabel, tmpstr, NULL);
1329
1330 /* These setvalues need some adjustments... */
1331 XtVaSetValues(dlgLevelScale,
1332 XtNsliderX, (dlgLevelValue * 2),
1333 NULL);
1334 sprintf(tmpstr, "%d ", dlgSiblingValue);
1335 XtVaSetValues(dlgSiblingValuator, XtNlabel, tmpstr, NULL);
1336 XtVaSetValues(dlgSiblingScale,
1337 XtNsliderX, (dlgSiblingValue * 4),
1338 NULL);
1339 popup_dialog(dialog[DLG_SPACING], XtGrabNone);
1340 break;
1341 case LAYOUT_MENU_ALIGN_NODES:
1342 TreeAlignNodes = !TreeAlignNodes;
1343 XtVaSetValues(treeMenuItems[LAYOUT_MENU_ALIGN_NODES],
1344 XtNleftBitmap, TreeAlignNodes ? check_pixmap : None,
1345 NULL);
1346 DeleteTree(TheTree, TRUE);
1347 ResetLabels(TheTree);
1348 SetupTree(TheTree);
1349 break;
1350 default:
1351 WARN("unknown menu item in LayoutMenu_CB");
1352 }
1353 }
1354
1355
1356 /* ------------------------------------------------------------------------- */
1357
1358 static void
1359 NodeMenu_CB(w, client_data, call_data)
1360 Widget w;
1361 XtPointer client_data;
1362 XtPointer call_data;
1363 {
1364 long menuItem = (long) client_data;
1365
1366 switch (menuItem) {
1367 case NODE_MENU_ADD_CHILD:
1368 NodePos = Child;
1369 popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
1370 break;
1371 case NODE_MENU_ADD_BEFORE:
1372 NodePos = Before;
1373 popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
1374 break;
1375 case NODE_MENU_ADD_AFTER:
1376 NodePos = After;
1377 popup_dialog(dialog[DLG_NODE_NAME], XtGrabExclusive);
1378 break;
1379 case NODE_MENU_ELISION:
1380 ExpandCollapseNode(PopupNode);
1381 break;
1382 case NODE_MENU_DELETE:
1383 DeleteNode(PopupNode);
1384 if (TheTree == NULL)
1385 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
1386 break;
1387 default:
1388 WARN("unknown menu item in NodeMenu_CB");
1389 }
1390 }
1391
1392
1393 /* ------------------------------------------------------------------------- */
1394
1395 static void
1396 Help_CB(w, client_data, call_data)
1397 Widget w;
1398 XtPointer client_data;
1399 XtPointer call_data;
1400 {
1401 popup_dialog(helpShell, XtGrabNone);
1402 }
1403
1404
1405 /* ------------------------------------------------------------------------- */
1406
1407 static void
1408 HelpDone_CB(w, client_data, call_data)
1409 Widget w;
1410 XtPointer client_data;
1411 XtPointer call_data;
1412 {
1413 XtPopdown(helpShell);
1414 }
1415
1416
1417 /* ------------------------------------------------------------------------- */
1418
1419 static void
1420 NodeLabel_CB(w, client_data, call_data)
1421 Widget w;
1422 XtPointer client_data;
1423 XtPointer call_data;
1424 {
1425 char *node_label;
1426
1427 XtPopdown(dialog[DLG_NODE_NAME]);
1428 if (client_data == (XtPointer) TRUE) {
1429 node_label = XtMalloc(strlen(XawDialogGetValueString(XtParent(w)))
1430 * sizeof(char));
1431 node_label = strcpy(node_label, XawDialogGetValueString(XtParent(w)));
1432 if (*node_label)
1433 InsertNode(PopupNode, NodePos, node_label);
1434 }
1435 }
1436
1437
1438 /* ------------------------------------------------------------------------- */
1439
1440 static void
1441 NewTree_CB(w, client_data, call_data)
1442 Widget w;
1443 XtPointer client_data;
1444 XtPointer call_data;
1445 {
1446 char *node_label;
1447 Tree *tree;
1448
1449 XtPopdown(dialog[DLG_NEW]);
1450 if (client_data == (XtPointer) TRUE) {
1451 node_label = XtMalloc((strlen(XawDialogGetValueString(XtParent(w))) + 1)
1452 * sizeof(char));
1453 node_label = strcpy(node_label, XawDialogGetValueString(XtParent(w)));
1454 if (*node_label) {
1455 if (TheTree) {
1456 Delete(TheTree);
1457 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
1458 }
1459 tree = MakeNode();
1460 SetNodeLabel(tree, node_label);
1461 SetupTree(tree);
1462 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
1463 }
1464 }
1465 XSync(TreeDisplay, FALSE);
1466 }
1467
1468
1469 /* ------------------------------------------------------------------------- */
1470
1471 static void
1472 File_CB(w, client_data, call_data)
1473 Widget w;
1474 XtPointer client_data;
1475 XtPointer call_data;
1476 {
1477 char *fname;
1478 Tree *tree;
1479 ErrCode error;
1480 Arg args[1];
1481 int menuItem;
1482
1483 if (client_data == (XtPointer) TRUE) {
1484 fname = XawDialogGetValueString(XtParent(w));
1485 if (*fname) {
1486
1487 if (loading_file == 1) {
1488 if (TheTree) {
1489 Delete(TheTree);
1490 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
1491 }
1492 tree = ReadTreeFromFile(fname, &error);
1493 XtPopdown(dialog[DLG_FILE]);
1494 if (error != ERR_NONE)
1495 HandleError(error, tree);
1496 XSync(TreeDisplay, 0);
1497 if (tree) {
1498 SetupTree(tree);
1499 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
1500 } else {
1501 SetDrawingTree(NULL);
1502 BeginFrame();
1503 EndFrame();
1504 }
1505 } else if (menuItem == TREE_MENU_SAVE) {
1506 if (!SaveTreeToFile(TheTree, fname)) {
1507 XtPopdown(dialog[DLG_FILE]);
1508 HandleError(ERR_OPENFAIL, NULL);
1509 } else
1510 XtPopdown(dialog[DLG_FILE]);
1511 }
1512 } else
1513 XtPopdown(dialog[DLG_FILE]);
1514 } else
1515 XtPopdown(dialog[DLG_FILE]);
1516 }
1517
1518
1519 /* ------------------------------------------------------------------------- */
1520
1521 static void
1522 Scale_CB(w, client_data, call_data)
1523 Widget w;
1524 XtPointer client_data;
1525 XtPointer call_data;
1526 {
1527 int level_value, sibling_value;
1528 float tmp;
1529
1530 XtPopdown(dialog[DLG_SPACING]);
1531
1532 /* check if OK button was selected */
1533 if (client_data) {
1534 level_value = dlgLevelValue;
1535
1536 sibling_value = dlgSiblingValue;
1537
1538 if (level_value != TreeParentDistance ||
1539 sibling_value != TreeBorderSize) {
1540
1541 TreeParentDistance = level_value;
1542 TreeBorderSize = sibling_value;
1543 XSync(TreeDisplay, 0);
1544 if (TheTree) {
1545 DeleteTree(TheTree, TRUE);
1546 if (TreeAlignNodes)
1547 ResetLabels(TheTree);
1548 SetupTree(TheTree);
1549 }
1550 }
1551 }
1552 }
1553
1554
1555 /* ------------------------------------------------------------------------- */
1556 /* */
1557 /* Auxilary actions and callback functions */
1558 /* */
1559 /* ------------------------------------------------------------------------- */
1560
1561 static void
1562 Popdown_CB(w, client_data, call_data)
1563 Widget w;
1564 XtPointer client_data;
1565 XtPointer call_data;
1566 {
1567 Widget widget = (Widget) client_data;
1568
1569 XtPopdown(widget);
1570 }
1571
1572 static void
1573 activate_action(w, event, params, num_params)
1574 Widget w;
1575 XButtonEvent *event;
1576 String *params;
1577 Cardinal *num_params;
1578 {
1579 Widget button;
1580
1581 if (*num_params == 1) {
1582 button = XtNameToWidget(XtParent(w), params[0]);
1583
1584 if (button)
1585 XtCallCallbacks(button, XtNcallback, (XtPointer) TRUE);
1586 }
1587 }
1588
1589 static void
1590 quit_action(w, event, params, num_params)
1591 Widget w;
1592 XButtonEvent *event;
1593 String *params;
1594 Cardinal *num_params;
1595 {
1596 exit(0);
1597 }
1598
1599
1600
1601 /* ------------------------------------------------------------------------- */
1602
1603 static void
1604 select_action(w, event, params, num_params)
1605 Widget w;
1606 XButtonEvent *event;
1607 String *params;
1608 Cardinal *num_params;
1609 {
1610 Tree *node;
1611 int height;
1612 Boolean edit = FALSE;
1613
1614 if ((*num_params > 0) &&
1615 (!strcmp(params[0], "EDIT") ||
1616 !strcmp(params[0], "edit")))
1617 edit = TRUE;
1618
1619 if (SearchTree(TheTree, event->x, event->y, &node)) {
1620 static Tree *PrevNode = NULL;
1621 Tree *ParNode = NULL;
1622
1623 PopupNode = node;
1624 if (PrevNode != NULL)
1625 DrawNode(PrevNode, New);
1626 PrevNode = PopupNode;
1627
1628 printf("%s^^%s^^%s\n",
1629 EnvNm,
1630 edit ? "br-edit" : "br-view",
1631 (PopupNode->value) ? PopupNode->value : PopupNode->label.text);
1632
1633 StatusMsg(PopupNode->label.text, 1);
1634
1635 ParNode = PopupNode->parent;
1636 PopupNode->parent = NULL;
1637 HiliteNode(PopupNode, New);
1638 PopupNode->parent = ParNode;
1639 }
1640 }
1641
1642 static void
1643 menu_popup_action(w, event, params, num_params)
1644 Widget w;
1645 XEvent *event;
1646 String *params;
1647 Cardinal *num_params;
1648 {
1649 Widget menu;
1650 Boolean popup;
1651 ShellWidget shell_widget;
1652
1653 char *strargs[] = {"nodeMenu", NULL};
1654
1655 menu = XtNameToWidget(TreeTopLevel, params[0]);
1656 shell_widget = (ShellWidget) menu;
1657
1658 if (nodeFound) {
1659
1660 /* This is giving me a headache.
1661 * Why does popup menus come up unselectable?
1662 */
1663
1664 XtCallActionProc(TreeDrawingArea,
1665 "XtMenuPopup",
1666 event,
1667 strargs,
1668 1);
1669
1670 /*
1671 XtSetSensitive(menu, TRUE);
1672 XtPopupSpringLoaded(menu);
1673 */
1674
1675 /* if (!XtIsShell(menu)) {
1676 printf("error: not shell widget!\n");
1677 } else {
1678 if (! shell_widget->shell.popped_up) {
1679
1680 XtGrabKind call_data = XtGrabExclusive;
1681
1682 XtCallCallbacks(menu, XtNpopupCallback, (XtPointer) &call_data);
1683
1684 shell_widget->shell.popped_up = TRUE;
1685 shell_widget->shell.grab_kind = XtGrabExclusive;
1686 shell_widget->shell.spring_loaded = TRUE;
1687
1688 if (shell_widget->shell.create_popup_child_proc != NULL) {
1689 (*(shell_widget->shell.create_popup_child_proc))(menu);
1690 }
1691
1692 XtAddGrab(menu, TRUE, TRUE);
1693
1694 XtRealizeWidget(menu);
1695
1696 XMapRaised(XtDisplay(menu), XtWindow(menu));
1697
1698 } else
1699 XRaiseWindow(XtDisplay(menu), XtWindow(menu));
1700 }
1701 */
1702 }
1703 }
1704
1705
1706 static void
1707 button_action(w, event, params, num_params)
1708 Widget w;
1709 XEvent *event;
1710 String *params;
1711 Cardinal *num_params;
1712 {
1713 Tree *node;
1714
1715 if (SearchTree(TheTree, event->xbutton.x, event->xbutton.y, &node)) {
1716
1717 nodeFound = TRUE;
1718
1719 XtSetSensitive(nodeMenuItems[NODE_MENU_DELETE], TRUE);
1720
1721 XtVaSetValues(treeMenus[NODE_MENU],
1722 XtNlabel, node->label.text,
1723 NULL);
1724 PopupNode = node;
1725 if (IS_LEAF(node)) {
1726
1727 XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], FALSE);
1728
1729 XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION],
1730 XtNlabel, labelStr[STR_NODE_COLLAPSE],
1731 NULL);
1732
1733 } else {
1734
1735 XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], TRUE);
1736 if (node->elision) {
1737 XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION],
1738 XtNlabel, labelStr[STR_NODE_EXPAND],
1739 NULL);
1740 } else {
1741 XtVaSetValues(nodeMenuItems[NODE_MENU_ELISION],
1742 XtNlabel, labelStr[STR_NODE_COLLAPSE],
1743 NULL);
1744 }
1745 }
1746
1747 if (node->parent) {
1748 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], TRUE);
1749 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], TRUE);
1750 } else {
1751 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], FALSE);
1752 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], FALSE);
1753 }
1754
1755 if (node->elision) {
1756 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], FALSE);
1757 } else {
1758 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], TRUE);
1759 }
1760
1761 } else {
1762 nodeFound = FALSE;
1763
1764 XtVaSetValues(treeMenus[NODE_MENU],
1765 XtNlabel, " ",
1766 NULL);
1767
1768 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_BEFORE], FALSE);
1769 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_AFTER], FALSE);
1770 XtSetSensitive(nodeMenuItems[NODE_MENU_ADD_CHILD], FALSE);
1771 XtSetSensitive(nodeMenuItems[NODE_MENU_ELISION], FALSE);
1772 XtSetSensitive(nodeMenuItems[NODE_MENU_DELETE], FALSE);
1773 }
1774 }
1775
1776
1777 /* ------------------------------------------------------------------------- */
1778 /* */
1779 /* General purpose popdown widget callback (for dialog popdown buttons) */
1780 /* */
1781 /* ------------------------------------------------------------------------- */
1782
1783 static void center_widget(w, x, y)
1784 Widget w;
1785 int x, y;
1786 {
1787 Dimension width, height, border;
1788 Position max_x, max_y;
1789
1790 XtVaGetValues(w,
1791 XtNwidth, &width,
1792 XtNheight, &height,
1793 XtNborderWidth, &border,
1794 NULL);
1795
1796 width += 2 * border;
1797 height += 2 * border;
1798
1799 x -= ((Position) width / 2);
1800 y -= ((Position) height / 2);
1801
1802 if (x < 0) x = 0;
1803 if (y < 0) y = 0;
1804
1805 if (x > (max_x = (Position) (XtScreen(w)->width - width)) )
1806 x = max_x;
1807
1808 if (y > (max_y = (Position) (XtScreen(w)->height - height)) )
1809 y = max_y;
1810
1811 XtVaSetValues(w,
1812 XtNx, x,
1813 XtNy, y,
1814 NULL);
1815 }
1816
1817 #define shell_translations "<Message>WM_PROTOCOLS: wmpopdown()\n"
1818
1819 static void
1820 popup_dialog(shell, grab_kind)
1821 Widget shell;
1822 XtGrabKind grab_kind;
1823 {
1824 int idummy, x, y;
1825 Window wdummy;
1826
1827 XtOverrideTranslations(shell, XtParseTranslationTable(shell_translations));
1828 XtRealizeWidget(shell);
1829 wm_delete_window = XInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW",
1830 FALSE);
1831 (void) XSetWMProtocols(XtDisplay(shell), XtWindow(shell),
1832 &wm_delete_window, 1);
1833
1834 XQueryPointer(TreeDisplay, DefaultRootWindow(TreeDisplay),
1835 &wdummy, &wdummy,
1836 &x, &y, &idummy, &idummy, &idummy);
1837
1838 center_widget(shell, x, y);
1839
1840 XtPopup(shell, grab_kind);
1841 }
1842
1843 static void
1844 popdown_action(widget, event, params, num_params)
1845 Widget widget;
1846 XEvent *event;
1847 String *params;
1848 Cardinal *num_params;
1849 {
1850 XtPopdown(widget);
1851 }
1852
1853 static void
1854 set_siblingscale_CB(widget, w, percent_ptr)
1855 Widget widget;
1856 XtPointer w;
1857 XtPointer percent_ptr;
1858 {
1859 char tmpstr[10];
1860
1861 sprintf(tmpstr, "%d ", (int) (*(float*) percent_ptr*MAX_BORDER_SIZE));
1862
1863 XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
1864 }
1865
1866 static void
1867 siblingscale_CB(widget, w, report)
1868 Widget widget;
1869 XtPointer w;
1870 XawPannerReport *report;
1871 {
1872 char tmpstr[10];
1873
1874 sprintf(tmpstr, "%d ", (int)
1875 ((float) report->slider_x / report->slider_width
1876 * MAX_BORDER_SIZE / 10));
1877
1878 XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
1879 }
1880
1881 static void
1882 set_levelscale_CB(widget, w, percent_ptr)
1883 Widget widget;
1884 XtPointer w;
1885 XtPointer percent_ptr;
1886 {
1887 char tmpstr[10];
1888
1889 sprintf(tmpstr, "%d ", (int) (*(float*) percent_ptr*MAX_PARENT_DISTANCE));
1890
1891 XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
1892 }
1893
1894 static void
1895 levelscale_CB(widget, w, report)
1896 Widget widget;
1897 XtPointer w;
1898 XawPannerReport *report;
1899 {
1900 char tmpstr[10];
1901
1902 sprintf(tmpstr, "%d ", (int)
1903 ((float) report->slider_x / report->slider_width
1904 * MAX_PARENT_DISTANCE / 10));
1905
1906 XtVaSetValues((Widget) w, XtNlabel, tmpstr, NULL);
1907 }
1908
1909 static void
1910 set_siblingvalue_CB(widget, var_ptr, percent_ptr)
1911 Widget widget;
1912 XtPointer var_ptr;
1913 XtPointer percent_ptr;
1914 {
1915 * (int *)var_ptr = (int) (*(float*) percent_ptr*MAX_BORDER_SIZE);
1916 }
1917
1918 static void
1919 set_levelvalue_CB(widget, var_ptr, percent_ptr)
1920 Widget widget;
1921 XtPointer var_ptr;
1922 XtPointer percent_ptr;
1923 {
1924 * (int *)var_ptr = (int) (*(float*) percent_ptr*MAX_PARENT_DISTANCE);
1925 }
1926
1927
1928 static void
1929 siblingvalue_CB(widget, var_ptr, report)
1930 Widget widget;
1931 XtPointer var_ptr;
1932 XawPannerReport *report;
1933 {
1934 * (int *) var_ptr = (int)
1935 ((float) report->slider_x / report->slider_width
1936 * MAX_BORDER_SIZE / 10);
1937 }
1938
1939 static void
1940 levelvalue_CB(widget, var_ptr, report)
1941 Widget widget;
1942 XtPointer var_ptr;
1943 XawPannerReport *report;
1944 {
1945 * (int *) var_ptr = (int)
1946 ((float) report->slider_x / report->slider_width
1947 * MAX_PARENT_DISTANCE / 10);
1948 }
1949
1950
1951 /* ----------------------------------------------------------------------------
1952 *
1953 * Main routine
1954 *
1955 * ----------------------------------------------------------------------------
1956 */
1957
1958 main(argc, argv)
1959 int argc;
1960 char *argv[];
1961 {
1962 Tree *tree = NULL;
1963 ErrCode error = ERR_NONE;
1964
1965 ProgramName = strdup(argv[0]);
1966 if (ProgramName == NULL) {
1967 fprintf(stderr, "%s: insufficient memory available\n", argv[0]);
1968 exit(0);
1969 }
1970
1971 InitializeInterface(&argc, argv);
1972 XSync(TreeDisplay, 0);
1973
1974 if (argc >= 2) {
1975 tree = ReadTreeFromFile(argv[1], &error);
1976 if (tree) StatusMsg(argv[1], TRUE);
1977 if (argc > 2)
1978 WARN("extraneous arguments ignored");
1979 }
1980
1981 if (tree) {
1982 SetupTree(tree);
1983 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], TRUE);
1984 } else {
1985 SetDrawingTree(NULL);
1986 XtSetSensitive(treeMenuItems[TREE_MENU_SAVE], FALSE);
1987 }
1988
1989 if (error != ERR_NONE)
1990 HandleError(error, tree);
1991
1992 StatusMsg("Left = Edit Node; Mid = View Node; Right = Node Menu", 1);
1993 UserEventLoop();
1994 }
1995
1996 /* ------------------------------------------------------------------------- */
1997 /* End of File */
1998 /* ------------------------------------------------------------------------- */
1999
2000
2001
2002
2003
2004