comparison lisp/oobr/tree-x/intf.c @ 0:376386a54a3c r19-14

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