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