]> andersk Git - moira.git/blob - clients/mmoira/formup.c
added access_host() and access_ahal()
[moira.git] / clients / mmoira / formup.c
1 /* $Header$ */
2
3 #include        <stdio.h>
4 #include        <string.h>
5 #include        <X11/StringDefs.h>
6 #include        <X11/IntrinsicP.h>
7 #include        <X11/Shell.h>
8 #include        <X11/Core.h>
9 #include        <X11/CoreP.h>
10 #include        <X11/CompositeP.h>
11 #include        <Xm/Xm.h>
12 #include        <Xm/BulletinB.h>
13 #include        <Xm/Label.h>
14 #include        <Xm/Text.h>
15 #include        <Xm/TextP.h>
16 #include        <Xm/PushB.h>
17 #include        <Xm/PushBG.h>
18 #include        <Xm/CascadeB.h>
19 #include        <Xm/ToggleB.h>
20 #include        <Xm/ToggleBG.h>
21 #include        <Xm/RowColumn.h>
22 #include        <Xm/Separator.h>
23 #include        <Xm/Traversal.h>
24 #include        "mmoira.h"
25
26 static char rcsid[] = "$Header$";
27
28 #ifndef MAX
29 #define MAX(a,b)        ((a > b) ? a : b)
30 #endif
31 #ifndef MIN
32 #define MIN(a,b)        ((a < b) ? a : b)
33 #endif
34
35 int     hpad = 10;
36 int     vpad = 5;
37
38 void    manage_widget();
39 Widget  CreateForm();
40 Widget  CreateMenu();
41 Widget  BuildMenuTree();
42 Widget  MakeRadioField();
43 int     button_callback();
44 void    radio_callback();
45 void    string_callback();
46 void    boolean_callback();
47 void    menu_callback();
48 void    newvalue();
49 void    MoiraFocusOut();
50 EntryForm *WidgetToForm();
51
52 extern void     UpdateForm();
53 extern int      PopupErrorMessage();
54 extern void     PopupHelpWindow();
55 extern int      AppendToLog();
56 extern void     MakeWatchCursor();
57 extern void     MakeNormalCursor();
58 extern Widget   SetupLogWidget();
59
60 static XtActionsRec myactions[] = {
61     { "MoiraFocusOut", MoiraFocusOut },
62 };
63
64
65 void
66 manage_widget(w, widget, call_data)
67 Widget  w, widget;
68 XmAnyCallbackStruct     *call_data;
69 {
70         XtManageChild(widget);  
71 }
72
73 int
74 button_callback(w, client_data, call_data)
75 Widget          w;
76 EntryForm       *client_data;
77 XmAnyCallbackStruct     *call_data;
78 {
79         XtUnmanageChild(client_data->formpointer);
80 }
81
82
83 Widget
84 BuildMenuTree(topW, spec)
85 Widget          topW;
86 MenuItem        *spec;
87 {
88         return (CreateMenu(topW, spec->submenu, XmHORIZONTAL));
89 }
90
91 /*
92 ** Read the specification and put up a menu to match...
93 */
94
95 Widget
96 CreateMenu(parent, spec, orientation)
97 Widget          parent;
98 MenuItem        **spec;
99 int             orientation;
100 {
101         Widget          menuparent;
102         MenuItem        *curmenuitem;
103         Widget          childbutton, childmenu;
104         Arg             wargs[10];
105         int             n;
106         XmString        label;          /* !@#$%^ compound string required */
107
108         label = XmStringCreate( "Complete junk", XmSTRING_DEFAULT_CHARSET);
109
110         n = 0;
111         XtSetArg(wargs[n], XmNlabelString, label);      n++;
112
113         if (orientation == XmHORIZONTAL) {
114                 XtSetArg(wargs[n], XmNspacing, 5);      n++;
115                 menuparent = XmCreateMenuBar(   parent, "randommenu", 
116                                         wargs, n);
117                 XtManageChild(menuparent);
118         }
119         else
120                 menuparent = XmCreatePulldownMenu(parent, "randommenu", 
121                                                 wargs, n);
122
123         for (   curmenuitem = (*spec);
124                 curmenuitem;
125                 spec++, curmenuitem = (*spec)) {
126
127 #ifdef  DEBUG
128                 printf ("Making entry:  %s\n", curmenuitem->label);
129 #endif
130                 label = XmStringCreate( curmenuitem->label,
131                                         XmSTRING_DEFAULT_CHARSET);
132                 n = 0;
133                 XtSetArg(wargs[n], XmNlabelString, label);      n++;
134                 if (curmenuitem->accel) {
135                     XtSetArg(wargs[n], XmNmnemonic, *(curmenuitem->accel)); n++;
136                 }
137
138                 if (curmenuitem->submenu) {
139 #ifdef  DEBUG
140                         printf ("It has a submenu, which I'm recursing on...\n");
141 #endif
142                         childmenu = CreateMenu( menuparent, 
143                                                 curmenuitem->submenu,
144                                                 XmVERTICAL);
145                         XtSetArg(wargs[n], XmNsubMenuId, childmenu);    n++;
146
147                         childbutton = XtCreateManagedWidget(    "child",
148                                         xmCascadeButtonWidgetClass,
149                                         menuparent, wargs, n);
150
151                 }
152
153                 else {
154                         childbutton = XtCreateManagedWidget(    "child",
155                                         xmPushButtonGadgetClass,
156                                         menuparent, wargs, n);
157
158                         XtAddCallback(  childbutton, 
159                                         XmNactivateCallback, 
160                                         menu_callback, curmenuitem);
161                 }
162         }
163
164         return (menuparent);
165 }
166
167 /*
168 ** Read the specification and put up a form to match...
169 */
170
171 Widget
172 CreateForm(parent, spec)
173 Widget          parent;
174 EntryForm       *spec;
175 {
176         Widget          bb;
177         Arg             wargs[10];
178         int             n;
179         XmString        label;          /* compound string required */
180         Dimension       height_so_far = 0, width_so_far = 0;
181         Dimension       height, width;
182         Widget          titleW, instructionW;
183         Position        x, y;
184         Widget          shellparent;
185
186         if (spec->formpointer) {
187                 UpdateForm(spec);
188                 return(spec->formpointer);
189         }
190
191         height_so_far = vpad;
192
193 #define GETSIZE(foo)    n = 0; \
194                         XtSetArg(wargs[n], XtNwidth, &width);   n++; \
195                         XtSetArg(wargs[n], XtNheight, &height); n++; \
196                         XtGetValues (foo, wargs, n); \
197
198 #define STORESIZE       if (width > width_so_far) width_so_far = width;\
199                         height_so_far += height + vpad;
200
201
202         n = 0;
203         XtSetArg(wargs[n], XmNautoUnmanage, False);             n++;
204         bb = XmCreateBulletinBoardDialog(parent, spec->formname, wargs, n);
205         MapWidgetToForm(bb, spec);
206
207         spec->formpointer = bb;
208
209 #ifdef FORMTITLES
210         label = XmStringCreate(spec->formname, XmSTRING_DEFAULT_CHARSET);
211         n = 0;
212         XtSetArg(wargs[n], XmNlabelString, label);              n++;
213         XtSetArg(wargs[n], XtNx, 0);                            n++;
214         XtSetArg(wargs[n], XtNy, 0);                            n++;
215         titleW = XtCreateManagedWidget( "title",
216                                 xmLabelWidgetClass,
217                                 bb, wargs, n);
218         GETSIZE(titleW);
219         STORESIZE;
220 #endif
221
222         label = XmStringCreate(spec->instructions, XmSTRING_DEFAULT_CHARSET);
223         n = 0;
224         XtSetArg(wargs[n], XmNlabelString, label);              n++;
225         XtSetArg(wargs[n], XtNx, 0);                            n++;
226         XtSetArg(wargs[n], XtNy, height_so_far);                n++;
227         instructionW = XtCreateManagedWidget(   "instructions",
228                                 xmLabelWidgetClass,
229                                 bb, wargs, n);
230         GETSIZE(instructionW);
231         STORESIZE;
232
233         height = height_so_far;
234         width = width_so_far;
235         MakeInputLines(bb, &height, &width, spec);
236         STORESIZE;
237
238         height = height_so_far;
239         width = width_so_far;
240         MakeButtons(bb, &height, &width, spec);
241         STORESIZE;
242
243 /*
244 ** Center the title of the form
245 */
246 #ifdef FORMTITLES
247         n = 0;
248         XtSetArg(wargs[n], XtNwidth, &width);                   n++;
249         XtGetValues (titleW, wargs, n);
250
251         x = (width_so_far - width) / 2;
252
253         n = 0;
254         XtSetArg(wargs[n], XtNx, x);                            n++;
255         XtSetValues (titleW, wargs, n);
256 #endif
257         n = 0;
258         XtSetArg(wargs[n], XtNwidth, &width);                   n++;
259         XtGetValues (instructionW, wargs, n);
260
261         x = (width_so_far - width) / 2;
262
263         n = 0;
264         XtSetArg(wargs[n], XtNx, x);                            n++;
265         XtSetValues (instructionW, wargs, n);
266
267         return((Widget) bb);
268 }
269
270 /*
271 ** Pheight and pwidth start with the values-to-date of the bboard so far.
272 ** Return your height and width in them when you're done.
273 **
274 ** Positioning the widgets happens in two phases: 
275 **      First, we set their y-positions as we create them.
276 **      After they're created, we go back and adjust the x-positions
277 **      according to the widest left side noted.
278 */
279
280 MakeInputLines(parent, pheight, pwidth, spec)
281 Widget          parent;
282 Dimension       *pheight;
283 Dimension       *pwidth;
284 EntryForm       *spec;
285 {
286         UserPrompt      *current;
287         XmString        label;          /* compound string required */
288         Arg             wargs[10];
289         int             i, n;
290         Widget          child;
291         Dimension       width, height, maxleftwidth = 0, maxrightwidth = 0;
292         Dimension       localy, leftheight = 0, rightheight = 0;
293         UserPrompt      **myinputlines = spec->inputlines;
294         int             foo = 30;
295         Widget          children[20];
296         static XtTranslations trans = NULL;
297
298         for (   current = (*myinputlines), localy = 0,  i = 0;
299                 current; 
300                 myinputlines++, current = (*myinputlines), i++) {
301
302
303 #ifdef  DEBUG
304                 printf ("Making entry %d: %s of type %d\n", 
305                                 i, current->prompt, current->type);
306 #endif
307 /*
308 ** First, make the prompt
309 */
310                 if (current->type == FT_KEYWORD) {
311                     char *p;
312
313                     p = strchr(current->prompt, '|');
314                     if (p) {
315                         *p++ = 0;
316                         current->keyword_name = p;
317                     }
318                 }
319
320                 label = XmStringCreate( current->prompt, 
321                                         XmSTRING_DEFAULT_CHARSET);
322                 n = 0;
323                 XtSetArg(wargs[n], XmNlabelString, label);      n++;
324                 XtSetArg(wargs[n], XtNy, localy + *pheight);    n++;
325                 child = XtCreateManagedWidget(  "prompt",
326                                 xmLabelWidgetClass,
327                                 parent, wargs, n);
328
329                 GETSIZE(child);
330                 leftheight = height;
331                 if (width > maxleftwidth)
332                         maxleftwidth = width;
333
334                 if (current->type == FT_KEYWORD && current->keyword_name) {
335                     label = XmStringCreate("add new value",
336                                            XmSTRING_DEFAULT_CHARSET);
337                     n = 0;
338                     XtSetArg(wargs[n], XmNlabelString, label);  n++;
339                     XtSetArg(wargs[n], XtNy, localy + *pheight + height); n++;
340                     XtSetArg(wargs[n], XtNx, height); n++;
341                     child = XtCreateManagedWidget("newvalue",
342                                                   xmPushButtonWidgetClass,
343                                                   parent, wargs, n);
344                     XtAddCallback(child, XmNactivateCallback,
345                                   newvalue, current);
346
347                     GETSIZE(child);
348                     leftheight += height;
349                     if (width + height > maxleftwidth)
350                       maxleftwidth = width + height;
351                 }
352 /*
353 ** Second, make the input widget
354 */
355                 n = 0;
356                 XtSetArg(wargs[n], XtNy, localy + *pheight);    n++;
357                 XtSetArg(wargs[n], XmNtraversalOn, True);       n++;
358                 XtSetArg(wargs[n], XtNsensitive, 
359                         !(current->insensitive));               n++;
360                 switch (current->type) {
361                 case FT_STRING:
362                         children[i] = XtCreateManagedWidget(    "textwidget",
363                                                 xmTextWidgetClass,
364                                                 parent, wargs, n);
365                         XtAddCallback(  children[i], XmNvalueChangedCallback,
366                                 string_callback, current);
367                         if (trans == NULL) {
368                             XtAppAddActions(XtWidgetToApplicationContext(children[i]),
369                                             myactions, XtNumber(myactions));
370
371                             trans = XtParseTranslationTable(resources.text_trans);
372                         }
373                         XtOverrideTranslations(children[i], trans);
374                         if (current->returnvalue.stringvalue) {
375                                 XmTextSetString (children[i], current->returnvalue.stringvalue);
376                         }
377                         GETSIZE (children[i]);
378                         rightheight = height;
379                         if (width > maxrightwidth)
380                                 maxrightwidth = width;
381                         break;
382
383                 case FT_BOOLEAN:
384                         XtSetArg(wargs[n], XmNset,
385                                  current->returnvalue.booleanvalue ? True : False);     n++;
386
387                         if (current->returnvalue.booleanvalue)
388                                 label = XmStringCreate( "(True)", XmSTRING_DEFAULT_CHARSET);
389                         else
390                                 label = XmStringCreate( "(False)", XmSTRING_DEFAULT_CHARSET);
391                         XtSetArg(wargs[n], XmNlabelString, label);      n++;
392
393                         children[i] = XtCreateManagedWidget(    "ignore this",
394                                                 xmToggleButtonWidgetClass,
395                                                 parent, wargs, n);
396
397                         XtAddCallback(  children[i], XmNvalueChangedCallback,
398                                 boolean_callback, current);
399
400                         GETSIZE (children[i]);
401                         rightheight = height;
402                         if (width > maxrightwidth)
403                                 maxrightwidth = width;
404                         break;
405
406                 case FT_KEYWORD:
407                         children[i] = 
408                                 MakeRadioField(parent, current,
409                                                &rightheight, spec);
410                         XtManageChild(children[i]);
411                         XtSetValues(children[i], wargs, n);
412                         GETSIZE (children[i]);
413                         if (width > maxrightwidth)
414                                 maxrightwidth = width;
415                         break;
416
417                 default:
418                         printf ("Sorry, don't recognize that type\n");
419                         break;
420                 }
421                 XmAddTabGroup(children[i]);
422                 MapWidgetToForm(children[i], spec);
423                 current->parent = (caddr_t) spec;
424
425                 current->mywidget = children[i];
426
427                 localy += MAX(rightheight, leftheight) + vpad;
428         }
429
430 /*
431 ** Now slide the input widgets right as far as the widest prompt.
432 */
433         n = 0;
434         XtSetArg(wargs[n], XtNx, maxleftwidth + hpad);  n++;
435         for (; i; i--)
436                 XtSetValues (children[i - 1], wargs, n);
437
438         *pheight = localy - vpad;
439         *pwidth = maxleftwidth + maxrightwidth + hpad;
440 }
441
442 /*
443 ** All the junk about keeping track of the sum of the children's heights
444 ** is because the !#$% RowColumn widget doesn't sum them for us, NOR
445 ** does it accept SetValues on its XtNHeight!  Thanks, Motif!
446 */
447
448 Widget
449 MakeRadioField(parent, prompt, pheight, spec)
450 Widget          parent;
451 UserPrompt      *prompt;
452 Dimension       *pheight;
453 EntryForm       *spec;
454 {
455         Widget  radioparent, child = NULL;
456         char    *current;
457         Arg     wargs[10];
458         int     count, n;
459         XmString        label;  /* accursed compound string required */
460         Dimension       height, width;
461         char    **keywords, *null[2];
462
463         if (!prompt->keywords) {
464                 fprintf (stderr, "Warning:  No list of keywords for widget\n");
465                 prompt->keywords = null;
466                 null[0] = NULL;
467         }
468         for (   count = 0, keywords = prompt->keywords;
469                 *keywords; 
470                 keywords++, count++);
471
472 /*
473 ** Although the XmNnumColumns resource is documented as actually
474 ** representing the number of _rows_ when XmNorientation is set to XmVERTICAL,
475 ** it doesn't.  So I need to count the items myself and manually set the
476 ** number of columns to get a maximum of five rows.  There's no XmNnumRows
477 ** resource.  Thanks, Motif!
478 */
479
480         n = 0;
481         XtSetArg(wargs[n], XmNspacing, 0);      n++;
482
483         if (count > 5) {
484                 XtSetArg(wargs[n], XmNnumColumns, 1 + (count-1) / 5);           n++;
485                 XtSetArg(wargs[n], XmNorientation, XmVERTICAL); n++;
486                 XtSetArg(wargs[n], XmNpacking, XmPACK_COLUMN);  n++;
487         }
488         radioparent = XmCreateRadioBox(parent, "radio", wargs, n);
489
490         keywords = prompt->keywords;
491         for (current=(*keywords); current; keywords++, current=(*keywords)) {
492                 n = 0;
493                 label = XmStringCreate(current, XmSTRING_DEFAULT_CHARSET);
494                 XtSetArg(wargs[n], XmNlabelString, label);      n++;
495                 if ((prompt->returnvalue.stringvalue) &&
496                         (!strcmp (current, prompt->returnvalue.stringvalue))) {
497                         XtSetArg(wargs[n], XmNset, True);       n++;
498                 }
499                 else {
500                         XtSetArg(wargs[n], XmNset, False);      n++;
501                 }
502                 child = XtCreateManagedWidget(  current,
503                                                 xmToggleButtonWidgetClass,
504                                                 radioparent, wargs, n);
505                 MapWidgetToForm(child, spec);
506
507                 XtAddCallback(  child, XmNvalueChangedCallback,
508                                 radio_callback, prompt);
509
510         }
511 /*
512 ** Assume all child widgets are the same height.  Increase height by
513 ** five times this, or the actual number of children, whichever is lesser.
514 */
515
516         if (child) {
517             GETSIZE (child);
518         } else
519           height = 10;
520         *pheight = (height * MIN(5, count)) + vpad; 
521
522         return(radioparent);
523 }
524
525
526 /* This is called when the list of keywords changes.  The old radio box
527  * will be destroyed and a new one created.
528  */
529
530 RemakeRadioField(form, field)
531 EntryForm *form;
532 int field;
533 {
534     Dimension x, y, parent_y, oldheight, newheight;
535     Arg wargs[4];
536     Widget w;
537     static XtTranslations trans = NULL;
538     extern char form_override_table[];
539     int i;
540
541     XtSetArg(wargs[0], XtNx, &x);
542     XtSetArg(wargs[1], XtNy, &y);
543     XtSetArg(wargs[2], XtNheight, &oldheight);
544     XtGetValues(form->inputlines[field]->mywidget, wargs, 3);
545     XtUnmanageChild(form->inputlines[field]->mywidget);
546     form->inputlines[field]->mywidget = w =
547       MakeRadioField(form->formpointer, form->inputlines[field],
548                      &newheight, form);
549     XtSetArg(wargs[0], XtNx, x);
550     XtSetArg(wargs[1], XtNy, y);
551     XtSetValues(w, wargs, 2);
552     MapWidgetToForm(w, form);
553     XmAddTabGroup(w);
554     if (newheight > oldheight) {
555         parent_y = y;
556         for (i = 0; i < NumChildren(form->formpointer); i++) {
557             XtSetArg(wargs[0], XtNy, &y);
558             XtGetValues(NthChild(form->formpointer, i), wargs, 1);
559             if (y > parent_y) {
560                 y = (y + newheight) - oldheight;
561                 XtSetArg(wargs[0], XtNy, y);
562                 XtSetValues(NthChild(form->formpointer, i), wargs, 1);
563             }
564         }
565     }
566
567     if (trans == NULL)
568       trans = XtParseTranslationTable(resources.form_trans);
569     XtOverrideTranslations(w, trans);
570     for (i = 0; i < NumChildren(w); i++)
571       XtOverrideTranslations(NthChild(w, i), trans);
572
573     XtManageChild(w);
574 }
575
576
577 MakeButtons(parent, pheight, pwidth, spec)
578 Widget          parent;
579 Dimension       *pheight;
580 Dimension       *pwidth;
581 EntryForm       *spec;
582 {
583         BottomButton    *current;
584         XmString        label;          /* compound string required */
585         Arg             wargs[10];
586         int             i, n;
587         Dimension       newwidth, width = 25;
588         Widget          newbutton;
589         BottomButton    **buttons = spec->buttons;
590
591         *pheight += vpad;
592
593         n = 0;
594         XtSetArg(wargs[n], XtNy, *pheight);                     n++;
595         XtSetArg(wargs[n], XtNx, 0);                            n++;
596         XtSetArg(wargs[n], XtNwidth, *pwidth);                  n++;
597         XtCreateManagedWidget(  "separator",
598                                 xmSeparatorWidgetClass,
599                                 parent, wargs, n);
600         *pheight += vpad;
601
602         for (   current=(*buttons); 
603                 current; 
604                 buttons++, current=(*buttons)) {
605
606 #ifdef  DEBUG
607                 printf ("Making a button labeled %s\n", current->label);
608 #endif
609                 label = XmStringCreate( current->label, 
610                                         XmSTRING_DEFAULT_CHARSET);
611                 n = 0;
612                 XtSetArg(wargs[n], XtNy, (*pheight));                   n++;
613                 XtSetArg(wargs[n], XtNx, width);                        n++;
614                 XtSetArg(wargs[n], XmNlabelString, label);              n++;
615
616                 newbutton = XtCreateManagedWidget(      current->label,
617                                                 xmPushButtonWidgetClass,
618                                                 parent, wargs, n);
619
620                 XtAddCallback(newbutton, XmNactivateCallback,
621                               (XtCallbackProc) current->returnfunction,
622                               spec);
623                 n = 0;
624                 XtSetArg(wargs[n], XtNwidth, &newwidth);                n++;
625                 XtGetValues (newbutton, wargs, n);
626
627                 width += (newwidth + hpad);
628         }
629
630         (*pheight) += 100;
631 }
632
633 void
634 radio_callback(w, client_data, call_data)
635 Widget  w;
636 XmAnyCallbackStruct     *client_data;
637 XmAnyCallbackStruct     *call_data;
638 {
639         Arg             wargs[10];
640         int             n;
641         Boolean         is_set;
642
643         UserPrompt      *prompt = (UserPrompt *) client_data;
644
645         n = 0;
646         XtSetArg(wargs[n], XmNset, &is_set);    n++;
647         XtGetValues (w, wargs, n);
648
649         if (!is_set)
650                 return;
651
652 /*
653 ** Since Motif insists on using !@#$% Compound Strings as the text for
654 ** its label widgets, but doesn't provide a way of getting a char* back
655 ** from a !@#$% Compound String, I can't retrieve the label of the button 
656 ** that was hit. 
657 **
658 ** Fortunately, I was smart enough to use the button label as the name 
659 ** of the widget, and I can extract it via XtName().  Thanks, Motif!
660 */
661         if (prompt->returnvalue.stringvalue &&
662                         (strcmp(prompt->returnvalue.stringvalue, XtName(w)))) {
663                 strcpy(prompt->returnvalue.stringvalue, XtName(w));
664                 if (prompt->valuechanged)
665                   (*prompt->valuechanged)(WidgetToForm(w), prompt);
666         }
667
668 }
669
670 void
671 boolean_callback(w, client_data, call_data)
672 Widget  w;
673 XmAnyCallbackStruct     *client_data;
674 XmAnyCallbackStruct     *call_data;
675 {
676         Arg             wargs[10];
677         int             n;
678         Boolean         is_set;
679         UserPrompt      *current = (UserPrompt *)client_data;
680         XmString        label;
681
682         n = 0;
683         XtSetArg(wargs[n], XmNset, &is_set);                    n++;
684         XtGetValues (w, wargs, n);
685
686         current->returnvalue.booleanvalue = is_set;
687
688         if (is_set)
689                 label = XmStringCreate( "(True)", XmSTRING_DEFAULT_CHARSET);
690         else
691                 label = XmStringCreate( "(False)", XmSTRING_DEFAULT_CHARSET);
692         n = 0;
693         XtSetArg(wargs[n], XmNlabelString, label);              n++;
694         XtSetValues (w, wargs, n);
695
696         if (current->valuechanged)
697           (*current->valuechanged)(WidgetToForm(w), current);
698
699 #if DEBUG
700         printf ("boolean_callback:  button %x is %s\n", 
701                         w, (is_set ? "True" : "False"));
702 #endif
703 }
704
705 void
706 menu_callback(w, client_data, call_data)
707 Widget  w;
708 XmAnyCallbackStruct     *client_data;
709 XmAnyCallbackStruct     *call_data;
710 {
711         MenuItem        *itemhit = (MenuItem *) client_data;
712
713 /*      printf  ("menu_callback: item '%s', op %d and string '%s'\n", 
714                         itemhit->label, 
715                         itemhit->operation, 
716                         itemhit->form);
717         XtManageChild(entryformwidget); 
718 */
719         MoiraMenuRequest(itemhit);
720 }
721
722
723 void
724 string_callback(w, client_data, call_data)
725 Widget  w;
726 XmAnyCallbackStruct     *client_data;
727 XmAnyCallbackStruct     *call_data;
728 {
729         UserPrompt      *current = (UserPrompt *)client_data;
730         char            *newvalue;
731
732         newvalue = XmTextGetString(w);
733
734         if (strcmp(current->returnvalue.stringvalue, newvalue)) {
735 /*              printf ("Replacing old value of selection, '%s', with '%s'\n",
736                                 current->returnvalue.stringvalue,
737                                 newvalue);
738                 strcpy(current->returnvalue.stringvalue, newvalue);
739                 if (current->valuechanged)
740                   (*current->valuechanged)(WidgetToForm(w), current);
741 */      }
742         XtFree(newvalue);
743 }
744
745
746 void MoiraFocusOut(w, event, p, n)
747 Widget w;
748 XEvent *event;
749 String *p;
750 Cardinal *n;
751 {
752     char  *newvalue;
753     UserPrompt *current = NULL;
754     EntryForm *f;
755     XmTextRec *tr = (XmTextRec *)w;
756     int i;
757
758     if (!tr || tr->core.self != w || tr->core.widget_class != xmTextWidgetClass)
759       return;
760     newvalue = XmTextGetString(w);
761     f = WidgetToForm(w);
762     for (i = 0; f->inputlines[i]; i++)
763       if (f->inputlines[i]->mywidget == w) 
764         current = f->inputlines[i];
765     if (current == NULL) {
766         fprintf(stderr, "Couldn't find prompt structure!\n");
767         return;
768     }
769
770     if (strcmp(current->returnvalue.stringvalue, newvalue)) {
771         strcpy(current->returnvalue.stringvalue, newvalue);
772         if (current->valuechanged)
773           (*current->valuechanged)(f, current);
774     }
775     XtFree(newvalue);
776 }
777
778
779 void
780 newvalue(w, client_data, call_data)
781 Widget  w;
782 XmAnyCallbackStruct     *client_data;
783 XmAnyCallbackStruct     *call_data;
784 {
785     UserPrompt  *current = (UserPrompt *)client_data;
786     EntryForm   *form, *f;
787     int i;
788     static MenuItem mi;
789
790     if (current->keyword_name == NULL) {
791         PopupErrorMessage("Sorry, that keyword cannot be changed.", NULL);
792         return;
793     }
794     form = (EntryForm *)current->parent;
795     for (i = 0; form->inputlines[i]; i++)
796       if (form->inputlines[i] == current)
797         break;
798     f = GetAndClearForm("add_new_value");
799     mi.operation = MM_NEW_VALUE;
800     mi.query = "add_alias";
801     mi.argc = 3;
802     mi.form = form->formname;
803     mi.accel = (char *) i;
804     f->menu = &mi;
805     f->extrastuff = current->keyword_name;
806     DisplayForm(f);
807 }
808
809
810 /* WARNING: This routine uses Motif internal undocumented routines.
811  * It was the only way to get carriage return to Do The Right Thing.
812  * If you are in a single-item tab group, this routine will call
813  * MoiraFormComplete() (same as pressing OK on the bottom of the form).
814  * otherwise, it advances the focus the same as pressing TAB.
815  */
816
817 void EnterPressed(w, event, argv, count)
818 Widget w;
819 XEvent *event;
820 char **argv;
821 Cardinal *count;
822 {
823     Widget next;
824     EntryForm *form;
825
826     next = _XmFindNextTabGroup(w);
827     if (next == w) {
828         MoiraFocusOut(w, event, argv, count);
829         form = WidgetToForm(w);
830         MoiraFormComplete(NULL, form);
831     } else {
832         _XmMgrTraversal(w, XmTRAVERSE_NEXT_TAB_GROUP);
833     }
834 }
835
836
837 void CancelForm(w, event, argv, count)
838 Widget w;
839 XEvent *event;
840 char **argv;
841 Cardinal *count;
842 {
843     EntryForm *form;
844
845     form = WidgetToForm(w);
846     if (form)
847       XtUnmanageChild(form->formpointer);    
848 }
849
850
851 void ExecuteForm(w, event, argv, count)
852 Widget w;
853 XEvent *event;
854 char **argv;
855 Cardinal *count;
856 {
857     EntryForm *form;
858
859     form = WidgetToForm(w);
860     if (form) {
861         MoiraFocusOut(w, event, argv, count);
862         MoiraFormComplete(NULL, form);
863     }
864 }
865
866
867 void DoHelp(w, event, argv, count)
868 Widget w;
869 XEvent *event;
870 char **argv;
871 Cardinal *count;
872 {
873     EntryForm *form;
874
875     form = WidgetToForm(w);
876     if (form)
877       help(form->formname);
878 }
879
880
881 extern struct hash *create_hash();
882 static struct hash *WFmap = NULL;
883
884 MapWidgetToForm(w, f)
885 Widget *w;
886 EntryForm *f;
887 {
888     if (WFmap == NULL) {
889         WFmap = create_hash(101);
890     }
891     hash_store(WFmap, w, f);
892 }
893
894 EntryForm *WidgetToForm(w)
895 Widget *w;
896 {
897     return((EntryForm *) hash_lookup(WFmap, w));
898 }
899
900
901 /* Routines to deal with children of composite widgets */
902
903 Widget NthChild(w, n)
904 CompositeRec *w;
905 int n;
906 {
907     return(w->composite.children[n]);
908 }
909
910 int NumChildren(w)
911 CompositeRec *w;
912 {
913     return(w->composite.num_children);
914 }
This page took 0.161332 seconds and 5 git commands to generate.