1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11 
12 #include <sys/stat.h>
13 
14 #include <Xm/Form.h>
15 #include <Xm/Label.h>
16 #include <Xm/PushB.h>
17 #include <Xm/RowColumn.h>
18 #include <Xm/Separator.h>
19 #include <Xm/Text.h>
20 #include <Xm/ToggleB.h>
21 #include <Xm/ScrolledW.h>
22 #include <Xm/DrawingA.h>
23 #include <Xm/Frame.h>
24 
25 #include "ConfigurationDialog.h"
26 #include "ListIterator.h"
27 #include "CDBInput.h"
28 #include "CDBOutput.h"
29 #include "DescrDialog.h"
30 
31 #include "Application.h"
32 #include "DXApplication.h"
33 #include "ErrorDialogManager.h"
34 
35 #include "Parameter.h"
36 #include "Ark.h"
37 #include "Node.h"
38 #include "XmUtility.h"
39 
40 //
41 // W.R.T. input parameters:
42 // I made significant changes in Oct/95.  Here's my understanding of how
43 // it was broken, how it's supposed to work and the meanings of a few fields.
44 // Bugs:
45 //	c1tignor40: cdb trashes nodes' values which are set thru other ui dialogs
46 //	c1wright5:  click on the set value toggle repeatedly and the text varies
47 //	jkarol788,
48 //	jkarol789:  cancel and restore buttons don't do anything
49 // N.B. These were filed against 7.x.  These bugs didn't exist in 7.0.2, but that
50 // doesn't mean you can refer to 7.0.2 code to see how it looked when it worked.
51 // 7.0.2 was broken also, but in different ways.
52 //
53 // Nutshell:
54 //	The restore and apply callbacks guarantee that upon completion,
55 //	for each param
56 //	    input->initialValue == the value in the node
57 //	restore resolves differences by moving values from input->initialValue into node.
58 //	apply resolves differences by moving values from the node into initialValue.
59 //	(basically...  Exception: if you type but don't hit <Enter> then handle that
60 //	a little differently.)
61 // 	The changeInput method is invoked by Node::ioParameterStatusChanged() and
62 //	is therefore extremely problematic.  If We touch a param, We can know that
63 //	the new value doesn't belong in initialValue, but if someone else touches
64 //	a param then We cannot know.  But if We don't have this knowledge, then
65 //	We won't know which params should be restored or applied.
66 //	Note that once a cdb is created, it maintains (for better or worse) its
67 //	collection of input objects all the time regardless of its isManaged() state.
68 // A few of things I did were minor, but the major change I made was to add logic
69 // to changeInput() to prevent some
70 //
71 //
72 // input:	1 per param
73 // input->initialValue:	 equal to the value in the Node unless We've made a restorable
74 //	change.
75 // input->modified:	0 initially.  Set to 1 if the user makes a change.  Reset
76 //	in restore or apply.  This governs the action in changeInput.  If the user
77 //	has typed in new data then changeInput won't put new values into initialValue.
78 //	If the user hasn't touched a param using thru the cdb, then any update to that
79 // 	param goes into initialValue.  This is the change I made which makes the
80 //	restore,cancel,apply buttons work properly.
81 // input->valueChanged:  set to 1 if the value in the text widget has changed but
82 //	the value hasn't been used yet.  Set to 1 in a modifyVerifyCallback.
83 //
84 
85 char* ConfigurationDialog::HelpText = 0;
86 boolean ConfigurationDialog::ClassInitialized = FALSE;
87 String ConfigurationDialog::DefaultResources[] =
88 {
89     "*configNotationLabel.labelString:		Notation:",
90     "*configNotationLabel.foreground:		SteelBlue",
91 
92     "*configOkButton.labelString:		OK",
93     "*configApplyButton.labelString:		Apply",
94     "*configExpandButton.labelString:		Expand",
95     "*configCollapseButton.labelString:		Collapse",
96     "*configDescriptionButton.labelString:	Description...",
97     "*configSyntaxButton.labelString:		Help on Syntax",
98     "*configRestoreButton.labelString:		Restore",
99     "*configCancelButton.labelString:		Cancel",
100 
101     "*configInputTitle.labelString:		Inputs:",
102     "*configInputTitle.foreground:		SteelBlue",
103     "*configInputNameLabel.labelString:		Name",
104     "*configInputNameLabel.foreground:		SteelBlue",
105     "*configInputHideLabel.labelString:		Hide",
106     "*configInputHideLabel.foreground:		SteelBlue",
107     "*configInputTypeLabel.labelString:		Type",
108     "*configInputTypeLabel.foreground:		SteelBlue",
109     "*configInputSourceLabel.labelString:	Source",
110     "*configInputSourceLabel.foreground:	SteelBlue",
111     "*configInputValueLabel.labelString:	Value",
112     "*configInputValueLabel.foreground:		SteelBlue",
113 
114     "*configInputNameLabel.leftOffset:		0",
115     "*inputForm.configInputName.leftOffset:	0",
116     "*configInputHideLabel.leftOffset:		130",
117     "*inputForm.configInputHide.leftOffset:	140",
118     "*configInputTypeLabel.leftOffset:		170",
119     "*inputForm.configInputType.leftOffset:	170",
120     "*configInputSourceLabel.leftOffset:	380",
121     "*inputForm.configInputSource.leftOffset:	380",
122     "*inputForm.configInputSource.rightOffset:	-555",
123     "*configInputValueLabel.leftOffset:		560",
124     "*inputForm.textPopup.leftOffset:		560",
125 #if !defined(LESSTIF_VERSION)
126     "*inputForm.resizePolicy:			XmRESIZE_NONE",
127 #endif
128     "*configOutputTitle.labelString:		Outputs:",
129     "*configOutputTitle.foreground:		SteelBlue",
130     "*configOutputNameLabel.labelString:	Name",
131     "*configOutputNameLabel.foreground:		SteelBlue",
132     "*configOutputTypeLabel.labelString:	Type",
133     "*configOutputTypeLabel.foreground:		SteelBlue",
134     "*configOutputDestinationLabel.labelString:	Destination",
135     "*configOutputDestinationLabel.foreground:	SteelBlue",
136     "*configOutputCacheLabel.labelString:	Cache",
137     "*configOutputCacheLabel.foreground:	SteelBlue",
138     "*cacheFull.labelString:			All Results",
139     "*cacheLast.labelString:			Last Result",
140     "*cacheOff.labelString:			No Results",
141 
142 #if defined(aviion)
143     "*configOutputSection.cacheOptionMenu.labelString:",
144 #endif
145 
146     NULL
147 };
148 
149 #define MAX_INITIAL_BUTTONS 7
150 #define PIXELS_PER_LINE 30
151 
152 // This is used to set XmNtopOffset for the togglebutton widgets.  It's significant
153 // because setting it to 4 makes the textPopup widget overlap and the cdb's
154 // noticeably shorter.  Setting it to 7 makes the textPopup widgets not overlap
155 // and gives the appearance of a separator between each adjacent pair.
156 #define POPUP_OFFSET 5
157 
158 ConfigurationDialog*
AllocateConfigurationDialog(Widget parent,Node * node)159 ConfigurationDialog::AllocateConfigurationDialog(Widget parent,
160 						 Node *node)
161 {
162     return new ConfigurationDialog(parent, node);
163 }
164 
okCallback(Dialog * d)165 boolean ConfigurationDialog::okCallback(Dialog *d)
166 {
167     return this->applyCallback(d);
168 }
helpCallback(Dialog * d)169 void ConfigurationDialog::helpCallback(Dialog *d)
170 {
171     if (!this->descriptionDialog)
172 	this->descriptionDialog = new DescrDialog(this->getRootWidget(),
173 						  this->node);
174     this->descriptionDialog->post();
175 }
cancelCallback(Dialog * d)176 void ConfigurationDialog::cancelCallback(Dialog *d)
177 {
178     this->unmanage();
179     this->restoreCallback(d);
180 }
ConfigurationDialog_SyntaxCB(Widget widget,XtPointer clientdata,XtPointer)181 extern "C" void ConfigurationDialog_SyntaxCB(Widget widget,
182                                              XtPointer clientdata,
183                                              XtPointer)
184 {
185      ConfigurationDialog *dialog = (ConfigurationDialog*)clientdata;
186      InfoMessage(dialog->getHelpSyntaxString());
187 }
ConfigurationDialog_ApplyCB(Widget widget,XtPointer clientData,XtPointer)188 extern "C" void ConfigurationDialog_ApplyCB(Widget widget,
189 					XtPointer clientData,
190 					XtPointer)
191 {
192     ConfigurationDialog *dialog = (ConfigurationDialog*)clientData;
193     dialog->applyCallback(dialog);
194 }
195 
applyCallback(Dialog *)196 boolean ConfigurationDialog::applyCallback(Dialog *)
197 {
198     ListIterator li(this->inputList);
199     int i;
200     CDBInput *input;
201     Node     *n = this->node;
202     boolean anySet = FALSE;
203     boolean retval = TRUE;
204 
205     for (i = 1; NULL != (input = (CDBInput*)li.getNext()); ++i)
206     {
207 	if (input->valueChanged)
208 	{
209 	    if (this->widgetChanged(i, FALSE))
210 		anySet = TRUE;
211 	    else
212 		retval = FALSE;
213 	}
214 
215 	const char *valueString;
216 	if (n->isInputDefaulting(i))
217 	{
218 	    valueString = n->getInputDefaultValueString(i);
219 	}
220 	else
221 	{
222 	    valueString = n->getInputSetValueString(i);
223 	}
224 	input->setInitialValue(valueString);
225 	input->initialValueIsDefault = n->isInputDefaulting(i);
226 	input->initialIsHidden = !n->isInputVisible(i);
227 	input->modified = 0;
228     }
229 
230     if (anySet)
231 	n->sendValues(FALSE);
232 
233     const char *oldlabel = n->getLabelString();
234     char *s = XmTextGetString(this->notation);
235     if (!EqualString(oldlabel,s)) {
236 	if (n->setLabelString(s))  {
237 	    if (this->initialNotation)
238 		delete this->initialNotation;
239 	    this->initialNotation = DuplicateString(s);
240 	} else {
241 	    retval = FALSE;
242 	}
243     }
244     XtFree(s);
245 
246     return retval;
247 }
ConfigurationDialog_RestoreCB(Widget widget,XtPointer clientData,XtPointer)248 extern "C" void ConfigurationDialog_RestoreCB(Widget widget,
249 					XtPointer clientData,
250 					XtPointer)
251 {
252     ConfigurationDialog *dialog = (ConfigurationDialog*)clientData;
253     dialog->restoreCallback(dialog);
254 }
ConfigurationDialog_ExpandCB(Widget widget,XtPointer clientData,XtPointer)255 extern "C" void ConfigurationDialog_ExpandCB(Widget widget,
256 					XtPointer clientData,
257 					XtPointer)
258 {
259     ConfigurationDialog *dialog = (ConfigurationDialog*)clientData;
260     dialog->expandCallback(dialog);
261 }
ConfigurationDialog_CollapseCB(Widget widget,XtPointer clientData,XtPointer)262 extern "C" void ConfigurationDialog_CollapseCB(Widget widget,
263 					XtPointer clientData,
264 					XtPointer)
265 {
266     ConfigurationDialog *dialog = (ConfigurationDialog*)clientData;
267     dialog->collapseCallback(dialog);
268 }
269 
270 //
271 // At the end of restoreCallback(), the set of initial values for each param
272 // must be equal to what the node is holding.  Inside restoreCallback, these
273 // 2 sets are compared for every param and where they're different, the initial
274 // values stored locally are sent to the node.
275 //
restoreCallback(Dialog * clientData)276 void ConfigurationDialog::restoreCallback(Dialog *clientData)
277 {
278     ListIterator li(this->inputList);
279     int i;
280     CDBInput *input;
281     Node *n = this->node;
282     boolean anySet = FALSE;
283     boolean callbacksWereEnabled;
284 
285     for (i = 1; NULL != (input = (CDBInput*)li.getNext()); ++i)
286     {
287 	const char *defstr = n->getInputDefaultValueString(i);
288 	const char *inpstr = n->getInputValueString(i);
289 	boolean isdefing = n->isInputDefaulting(i);
290 
291   	if (!n->isInputViewable(i) || n->isInputConnected(i))
292 	    continue;
293 
294 	callbacksWereEnabled = input->valueTextPopup->disableCallbacks();
295 
296 	if (input->initialValueIsDefault)
297 	{
298 	    if (!n->isInputDefaulting(i))
299 	    {
300 		anySet = TRUE;
301 		n->useDefaultInputValue(i, FALSE);
302 	    }
303 	    else
304 		input->valueTextPopup->setText(defstr);
305 	}
306 	else
307 	{
308 	    if (!EqualString(input->initialValue, inpstr)) {
309 		if (EqualString(input->initialValue, defstr)) {
310 		    n->useDefaultInputValue(i);
311 		    input->setInitialValue (defstr);
312 		    input->valueTextPopup->setText(defstr);
313 		} else {
314 		    n->setInputValue(i,input->initialValue,DXType::UndefinedType,FALSE);
315 		    input->valueTextPopup->setText(input->initialValue);
316 		}
317 		anySet = TRUE;
318 	    } else {
319 		if (isdefing) {
320 		    n->setInputValue(i,input->initialValue,DXType::UndefinedType,FALSE);
321 		    anySet = TRUE;
322 		}
323 		input->valueTextPopup->setText(input->initialValue);
324 	    }
325 	}
326 	if (!n->isInputConnected(i) &&
327 	    (n->isInputVisible(i) != !input->initialIsHidden))
328 	    n->setInputVisibility(i, !input->initialIsHidden);
329 
330 	if (callbacksWereEnabled)
331 	    input->valueTextPopup->enableCallbacks();
332 
333 	input->valueChanged = FALSE;
334 	input->modified = 0;
335     }
336 
337     if (anySet)
338 	n->sendValues(FALSE);
339 
340     char *s = XmTextGetString(this->notation);
341     if (!EqualString(s,this->initialNotation)) {
342 	XmTextSetString(this->notation, this->initialNotation);
343 	n->setLabelString(this->initialNotation);
344     }
345     XtFree(s);
346 }
ActivateInputValueCB(TextPopup * tp,const char * value,void * clientData)347 void ConfigurationDialog::ActivateInputValueCB(TextPopup *tp,
348 						const char *value,
349 						void *clientData)
350 {
351 
352     int i;
353     ConfigurationDialog *dialog = (ConfigurationDialog *)clientData;
354     for (i = 1; i <= dialog->node->getInputCount(); ++i)
355     {
356 	CDBInput *input = (CDBInput *)dialog->inputList.getElement(i);
357 	if (input->valueTextPopup == tp)
358 	{
359 	    input->modified = 1;
360 	    dialog->widgetChanged(i);
361 	    break;
362 	}
363     }
364 }
ValueChangedInputValueCB(TextPopup * tp,const char * value,void * clientData)365 void ConfigurationDialog::ValueChangedInputValueCB( TextPopup *tp,
366                                                 const char *value,
367                                                 void *clientData)
368 
369 {
370     int i;
371     ConfigurationDialog *dialog = (ConfigurationDialog *)clientData;
372     for (i = 1; i <= dialog->node->getInputCount(); ++i)
373     {
374 	CDBInput *input = (CDBInput *)dialog->inputList.getElement(i);
375 	if (input->valueTextPopup == tp)
376 	{
377 	    input->modified = 1;
378 	    input->valueChanged = TRUE;
379 	    break;
380 	}
381     }
382 }
ConfigurationDialog_ActivateOutputCacheCB(Widget widget,XtPointer clientData,XtPointer)383 extern "C" void ConfigurationDialog_ActivateOutputCacheCB(Widget widget,
384 					      XtPointer clientData,
385 					      XtPointer)
386 {
387     int i;
388     ConfigurationDialog *dialog = (ConfigurationDialog *)clientData;
389     for (i = 1; i <= dialog->node->getOutputCount(); ++i)
390     {
391 	CDBOutput *output = (CDBOutput *)dialog->outputList.getElement(i);
392 	if (output->fullButton == widget)
393 	{
394 	    dialog->node->setOutputCacheability(i, OutputFullyCached);
395 	    break;
396 	}
397 	else if (output->lastButton == widget)
398 	{
399 	    dialog->node->setOutputCacheability(i, OutputCacheOnce);
400 	    break;
401 	}
402 	else if (output->offButton == widget)
403 	{
404 	    dialog->node->setOutputCacheability(i, OutputNotCached);
405 	    break;
406 	}
407     }
408 }
409 
410 //
ConfigurationDialog_ValueChangedInputNameCB(Widget widget,XtPointer clientData,XtPointer)411 extern "C" void ConfigurationDialog_ValueChangedInputNameCB(Widget widget,
412 						XtPointer clientData,
413 						XtPointer)
414 {
415     int i;
416     ConfigurationDialog *dialog = (ConfigurationDialog *)clientData;
417     Node *n = dialog->node;
418     char pname[128];
419 
420     for (i = 1; i <= dialog->node->getInputCount(); ++i)
421     {
422 	CDBInput *input = (CDBInput *)dialog->inputList.getElement(i);
423 	if (input->nameWidget == widget)
424 	{
425 	    input->modified = 1;
426 	    Boolean set;
427 	    XtVaGetValues(widget, XmNset, &set, NULL);
428 	    if (set && dialog->node->isInputDefaulting(i))
429 	    {
430 		//
431 		// If the user has changed the value widget, get the current
432 		// string and save it in the parameter.  Otherwise,
433 		// get the value from the parameter and put it in the
434 		// widget.
435 		const char *defstr = dialog->node->getInputDefaultValueString(i);
436 		const char *setstr = dialog->node->getInputSetValueString(i);
437 		boolean isset = (
438 		    (!EqualString (defstr, setstr)) &&
439 		    (!EqualString (setstr, "NULL"))
440 		);
441 		if (input->valueChanged)
442 		{
443 		    dialog->widgetChanged(i);
444 		}
445 		else if (isset)
446 		{
447 		    input->valueTextPopup->setText(setstr);
448 		    dialog->node->useAssignedInputValue(i);
449 		}
450 		else
451 		{
452 		    n->setInputValue(i, "NULL");
453 		}
454 		input->valueChanged = FALSE;
455 	    }
456 	    else if (!set && !n->isInputDefaulting(i))
457 	    {
458 		if (input->valueChanged)
459 		{
460 		    char *s = input->valueTextPopup->getText();
461 
462 		    if (!EqualString(s, n->getInputDefaultValueString(i)) &&
463 		        *s != '\0')
464 		    {
465 			if (n->setInputValue(i, s, DXType::UndefinedType, FALSE)				== DXType::UndefinedType)
466 			{
467 			    ErrorMessage(
468 				"String `%s' is not a valid value for "
469 				    "%s parameter '%s'",
470 				s, n->getNameString(),
471 				n->getInputNameString(i,pname));
472 			}
473 		    }
474 		    XtFree(s);
475 		}
476 		dialog->node->useDefaultInputValue(i);
477 		input->valueTextPopup->setText(
478 		    dialog->node->getInputDefaultValueString(i));
479 		input->valueChanged = FALSE;
480 	    }
481 	    break;
482 	}
483     }
484 }
485 //
ConfigurationDialog_ValueChangedInputHideCB(Widget widget,XtPointer clientData,XtPointer)486 extern "C" void ConfigurationDialog_ValueChangedInputHideCB(Widget widget,
487 						XtPointer clientData,
488 						XtPointer)
489 {
490     int i;
491     ConfigurationDialog *dialog = (ConfigurationDialog *)clientData;
492     for (i = 1; i <= dialog->node->getInputCount(); ++i)
493     {
494 	CDBInput *input = (CDBInput *)dialog->inputList.getElement(i);
495 	if (input->hideWidget == widget)
496 	{
497 	    input->modified = 1;
498 	    Boolean set;
499 	    XtVaGetValues(widget, XmNset, &set, NULL);
500 	    dialog->node->setInputVisibility(i, (boolean)!set);
501 	    if (set)
502 		XtSetSensitive(dialog->collapse, True);
503 	    break;
504 	}
505     }
506 }
507 
expandCallback(Dialog * clientData)508 void ConfigurationDialog::expandCallback(Dialog *clientData)
509 {
510     this->remanageInputs(TRUE);
511 }
collapseCallback(Dialog * clientData)512 void ConfigurationDialog::collapseCallback(Dialog *clientData)
513 {
514     this->remanageInputs(FALSE);
515 }
516 
ConfigurationDialog_ResizeCB(Widget widget,XtPointer clientData,XtPointer)517 extern "C" void ConfigurationDialog_ResizeCB(Widget widget,
518 					XtPointer clientData,
519 					XtPointer)
520 {
521 ConfigurationDialog *dialog = (ConfigurationDialog*)clientData;
522     ASSERT(dialog);
523     dialog->resizeCallback();
524 }
525 
526 //
527 // The contents of a scrolled window widget will not change size by itself
528 // nor will it have a size imposed on it by the scrolled window.  If the
529 // user resizes the window, then code must query for new dimensions and then
530 // force a new size on the contents of the scrolled window.
531 //
resizeCallback()532 void ConfigurationDialog::resizeCallback()
533 {
534 Dimension dw;
535 
536     if ((!this->getRootWidget()) || (!this->scrolledInputForm)) return ;
537     XtVaGetValues (this->getRootWidget(), XmNwidth, &dw, NULL);
538     if (dw<100) return ;
539 
540     Pixel ts,bs,bg;
541     Dimension sh,fh;
542     XtVaGetValues (this->inputScroller,
543 	XmNtopShadowColor,	&ts,
544 	XmNbottomShadowColor,	&bs,
545 	XmNbackground,		&bg,
546 	XmNheight,		&sh,
547     NULL);
548 
549     XtVaGetValues (this->scrolledInputForm, XmNheight, &fh, NULL);
550     if (fh > sh) {
551 	XtVaSetValues (XtParent(this->inputScroller),
552 	    XmNtopShadowColor,		ts,
553 	    XmNbottomShadowColor,	bs,
554 	NULL);
555 	XtVaSetValues (this->scrolledInputForm, XmNwidth, dw-35, NULL);
556     } else {
557 	XtVaSetValues (XtParent(this->inputScroller),
558 	    XmNtopShadowColor,		bg,
559 	    XmNbottomShadowColor,	bg,
560 	NULL);
561 	XtVaSetValues (this->scrolledInputForm, XmNwidth, dw-20, NULL);
562     }
563 }
564 
createInputs(Widget parent,Widget)565 Widget ConfigurationDialog::createInputs(Widget parent, Widget)
566 {
567     Node *n = this->node;
568     int numParam = n->getInputCount();
569     int j = 0;
570     Arg args[15];
571 
572 
573     Widget inputs = this->inputForm = XtVaCreateManagedWidget(
574 	"configInputSection",
575 	xmFormWidgetClass,
576 	parent,
577 	NULL);
578 
579     this->inputTitle = XtVaCreateWidget(
580 	"configInputTitle",
581 	xmLabelWidgetClass,
582 	inputs,
583         XmNtopAttachment   , XmATTACH_FORM,
584         XmNtopOffset       , 10,
585         XmNleftAttachment  , XmATTACH_FORM,
586         XmNalignment       , XmALIGNMENT_BEGINNING,
587 	NULL);
588 
589     Widget swp_form = XtVaCreateWidget ( "scroller_parent",
590 	xmFrameWidgetClass,	inputs,
591 	XmNtopAttachment, 	XmATTACH_WIDGET,
592 	XmNtopWidget, 		this->inputTitle,
593 	XmNleftAttachment, 	XmATTACH_FORM,
594 	XmNrightAttachment, 	XmATTACH_FORM,
595 	XmNbottomAttachment, 	XmATTACH_FORM,
596 	XmNtopOffset, 		10,
597 	XmNshadowThickness, 	2,
598     NULL);
599 
600     j = 0;
601 #if 0
602     XtSetArg (args[j], XmNtopAttachment, XmATTACH_WIDGET); j++;
603     XtSetArg (args[j], XmNtopWidget, this->inputTitle); j++;
604     XtSetArg (args[j], XmNleftAttachment, XmATTACH_FORM); j++;
605     XtSetArg (args[j], XmNrightAttachment, XmATTACH_FORM); j++;
606     XtSetArg (args[j], XmNbottomAttachment, XmATTACH_FORM); j++;
607     XtSetArg (args[j], XmNtopOffset, 10); j++;
608 #endif
609     XtSetArg (args[j], XmNshadowThickness, 0); j++;
610     XtSetArg (args[j], XmNscrollingPolicy, XmAUTOMATIC); j++;
611     XtSetArg (args[j], XmNspacing, 0); j++;
612     XtSetArg (args[j], XmNleftOffset, 0); j++;
613     XtSetArg (args[j], XmNrightOffset, 0); j++;
614     XtSetArg (args[j], XmNwidth, 790); j++;
615     this->inputScroller = XmCreateScrolledWindow (swp_form, "inputScroller", args, j);
616     XtManageChild(this->inputScroller);
617 
618     this->scrolledInputForm = XtVaCreateManagedWidget (
619 	"inputForm",
620 	xmFormWidgetClass,
621 	this->inputScroller,
622 	NULL
623     );
624     XtVaSetValues (this->inputScroller,
625 	XmNworkWindow, this->scrolledInputForm,
626     NULL);
627 
628     Widget hsb;
629     XtVaGetValues (this->inputScroller, XmNhorizontalScrollBar, &hsb, NULL);
630     if (hsb) XtUnmanageChild (hsb);
631 
632     int i;
633     for (i = 1; i <= numParam; ++i)
634 	this->newInput(i);
635 
636     //
637     // Set the height of the scrolled window.
638     //
639     int visCnt = 0;
640     for (i=1; i<=numParam; i++) {
641 	if (!n->isInputViewable(i)) continue;
642 	if (!n->isInputVisible(i)) continue;
643 	visCnt++;
644     }
645     if (visCnt > MAX_INITIAL_BUTTONS) visCnt = MAX_INITIAL_BUTTONS;
646     if (visCnt <= 0) visCnt = 1;
647     XtVaSetValues (this->inputScroller, XmNheight, 5+(visCnt*PIXELS_PER_LINE), NULL);
648 
649     j = 0;
650     XtSetArg (args[j], XmNtopAttachment, XmATTACH_FORM); j++;
651     XtSetArg (args[j], XmNleftAttachment, XmATTACH_FORM); j++;
652     XtSetArg (args[j], XmNrightAttachment, XmATTACH_FORM); j++;
653     XtSetArg (args[j], XmNbottomAttachment, XmATTACH_FORM); j++;
654     XtSetArg (args[j], XmNmappedWhenManaged, False); j++;
655     Widget drawa = XmCreateDrawingArea (inputs, "junk", args, j);
656     XtManageChild (drawa);
657     XtAddCallback (drawa, XmNresizeCallback,
658 	(XtCallbackProc)ConfigurationDialog_ResizeCB, (XtPointer)this);
659 
660     return inputs;
661 }
662 
createOutputs(Widget parent,Widget)663 Widget ConfigurationDialog::createOutputs(Widget parent, Widget )
664 {
665     Node *n = this->node;
666     int numParam = n->getOutputCount();
667     if (numParam == 0)
668 	return NULL;
669 
670     Widget outputs = XtVaCreateManagedWidget(
671 	"configOutputSection",
672 	xmFormWidgetClass,
673 	parent,
674 	XmNleftAttachment  , XmATTACH_FORM,
675 	XmNleftOffset      , 5,
676 	XmNrightAttachment , XmATTACH_FORM,
677 	XmNrightOffset     , 5,
678 	NULL);
679 
680     this->outputTitle = XtVaCreateManagedWidget(
681 	"configOutputTitle",
682 	xmLabelWidgetClass,
683 	outputs,
684         XmNtopAttachment   , XmATTACH_FORM,
685         XmNtopOffset       , 10,
686         XmNleftAttachment  , XmATTACH_FORM,
687         XmNalignment       , XmALIGNMENT_BEGINNING,
688 	NULL);
689 
690     this->outputNameLabel = XtVaCreateManagedWidget(
691 	"configOutputNameLabel",
692 	xmLabelWidgetClass,
693 	outputs,
694         XmNtopAttachment   , XmATTACH_WIDGET,
695         XmNtopWidget       , this->outputTitle,
696         XmNleftAttachment  , XmATTACH_FORM,
697         XmNwidth           , 130,
698         XmNalignment       , XmALIGNMENT_BEGINNING,
699 	NULL);
700 
701     this->outputTypeLabel = XtVaCreateManagedWidget(
702 	"configOutputTypeLabel",
703 	xmLabelWidgetClass,
704 	outputs,
705         XmNtopAttachment   , XmATTACH_WIDGET,
706         XmNtopWidget       , this->outputTitle,
707         XmNleftAttachment  , XmATTACH_WIDGET,
708         XmNleftWidget      , this->outputNameLabel,
709         XmNalignment       , XmALIGNMENT_BEGINNING,
710         XmNwidth           , 180,
711 	NULL);
712 
713     this->outputDestLabel = XtVaCreateManagedWidget(
714 	"configOutputDestinationLabel",
715 	xmLabelWidgetClass,
716 	outputs,
717         XmNtopAttachment   , XmATTACH_WIDGET,
718         XmNtopWidget       , this->outputTitle,
719         XmNleftAttachment  , XmATTACH_WIDGET,
720         XmNleftWidget      , this->outputTypeLabel,
721         XmNalignment       , XmALIGNMENT_BEGINNING,
722         XmNwidth           , 200,
723 	NULL);
724 
725     this->outputCacheLabel = XtVaCreateManagedWidget(
726 	"configOutputCacheLabel",
727 	xmLabelWidgetClass,
728 	outputs,
729         XmNtopAttachment   , XmATTACH_WIDGET,
730         XmNtopWidget       , this->outputTitle,
731         XmNleftAttachment  , XmATTACH_WIDGET,
732         XmNleftWidget      , this->outputDestLabel,
733         XmNwidth           , 120,
734         XmNalignment       , XmALIGNMENT_BEGINNING,
735 	NULL);
736 
737     int i;
738     for (i = 1; i <= numParam; ++i)
739 	this->newOutput(i);
740 
741     return outputs;
742 }
743 
744 
745 
746 // top == this->notation
createBody(Widget parent)747 Widget ConfigurationDialog::createBody(Widget parent)
748 {
749     this->typeWidth = 160;
750     this->outputForm = this->createOutputs(parent, NULL);
751     if (this->outputForm) {
752 	XtVaSetValues (this->outputForm,
753 	    XmNbottomAttachment,   XmATTACH_WIDGET,
754 	    XmNbottomWidget,       this->buttonSeparator,
755 	    XmNbottomOffset,       4,
756 	NULL);
757     }
758 
759     this->inputForm = this->createInputs(parent, this->notation);
760     if (this->inputForm) {
761 	XtVaSetValues (this->inputForm,
762 	    XmNtopAttachment,   XmATTACH_WIDGET,
763 	    XmNtopWidget,       this->notation,
764 	    XmNbottomAttachment, XmATTACH_WIDGET,
765 	    XmNbottomWidget,     (this->outputForm? this->outputForm: this->buttonSeparator),
766 	    XmNbottomOffset	   , 4,
767 	    XmNleftAttachment  , XmATTACH_FORM,
768 	    XmNleftOffset      , 5,
769 	    XmNrightAttachment , XmATTACH_FORM,
770 	    XmNrightOffset     , 5,
771 	NULL);
772     }
773     return this->outputForm == NULL? this->inputForm: this->outputForm;
774 }
775 
createDialog(Widget parent)776 Widget ConfigurationDialog::createDialog(Widget parent)
777 {
778     Arg arg[10];
779     int  n = 0;
780 
781     XtSetArg(arg[n], XmNminWidth, 770); n++;
782     XtSetArg(arg[n], XmNwidth, 800); n++;
783     XtSetArg(arg[n], XmNminHeight, 95); n++;
784     XtSetArg(arg[n], XmNallowShellResize, True); n++;
785 
786 //    Widget dialog = XmCreateFormDialog(parent, this->name, arg, n);
787     Widget dialog = this->CreateMainForm(parent, this->name, arg, n);
788     XtSetValues (XtParent(dialog), arg, n);
789 
790     XtVaSetValues(XtParent(dialog),
791 	XmNtitle, this->node->getNameString(),
792 	NULL);
793 
794     Widget label = XtVaCreateManagedWidget(
795 	"configNotationLabel",
796 	xmLabelWidgetClass,
797 	dialog,
798 	XmNtopAttachment,   XmATTACH_FORM,
799 	XmNtopOffset,       10,
800 	XmNleftAttachment,  XmATTACH_FORM,
801 	XmNleftOffset,      5,
802 	XmNalignment,       XmALIGNMENT_BEGINNING,
803 	NULL);
804     this->notation = XtVaCreateManagedWidget(
805 	"configNotationText",
806 	xmTextWidgetClass,
807 	dialog,
808 	XmNtopAttachment,   XmATTACH_FORM,
809 	XmNtopOffset,       10,
810 	XmNleftAttachment,  XmATTACH_WIDGET,
811 	XmNleftWidget,      label,
812 	XmNleftOffset,      10,
813 	XmNrightAttachment, XmATTACH_FORM,
814 	XmNrightOffset,     5,
815 	XmNeditMode,        XmSINGLE_LINE_EDIT,
816 	NULL);
817     XmTextSetString(this->notation, (char*)this->node->getLabelString());
818 
819 
820     Widget buttonForm = XtVaCreateManagedWidget(
821 	"configButtonForm",
822 	xmFormWidgetClass,
823 	dialog,
824 	XmNbottomAttachment    , XmATTACH_FORM,
825 	XmNbottomOffset        , 10,
826 	XmNleftAttachment   , XmATTACH_FORM,
827 	XmNleftOffset       , 5,
828 	XmNrightAttachment  , XmATTACH_FORM,
829 	XmNrightOffset      , 5,
830 	NULL);
831 
832     this->buttonSeparator = XtVaCreateManagedWidget(
833 	"configButtonSeparator",
834 	xmSeparatorWidgetClass,
835 	dialog,
836 	XmNbottomAttachment,    XmATTACH_WIDGET,
837 	XmNbottomWidget,        buttonForm,
838 	XmNbottomOffset,     6,
839 	XmNleftAttachment,   XmATTACH_FORM,
840 	XmNleftOffset,       0,
841 	XmNrightAttachment,  XmATTACH_FORM,
842 	XmNrightOffset,      0,
843 	NULL);
844 
845     this->ok = XtVaCreateManagedWidget(
846 	"configOkButton",
847 	xmPushButtonWidgetClass,
848 	buttonForm,
849 	XmNtopAttachment  , XmATTACH_FORM,
850 	XmNleftAttachment , XmATTACH_FORM,
851 	XmNwidth          , 70,
852 	NULL);
853 
854     this->apply = XtVaCreateManagedWidget(
855 	"configApplyButton",
856 	xmPushButtonWidgetClass,
857 	buttonForm,
858 	XmNtopAttachment  , XmATTACH_FORM,
859 	XmNleftAttachment , XmATTACH_WIDGET,
860 	XmNleftWidget     , this->ok,
861 	XmNleftOffset     , 10,
862 	XmNwidth          , 70,
863 	NULL);
864 
865     this->expand = XtVaCreateManagedWidget(
866 	"configExpandButton",
867 	xmPushButtonWidgetClass,
868 	buttonForm,
869 	XmNtopAttachment  , XmATTACH_FORM,
870 	XmNleftAttachment , XmATTACH_WIDGET,
871 	XmNleftWidget     , this->apply,
872 	XmNleftOffset     , 10,
873 	XmNwidth          , 70,
874 	NULL);
875     XtSetSensitive(this->expand, False);
876 
877     this->collapse = XtVaCreateManagedWidget(
878 	"configCollapseButton",
879 	xmPushButtonWidgetClass,
880 	buttonForm,
881 	XmNtopAttachment  , XmATTACH_FORM,
882 	XmNleftAttachment , XmATTACH_WIDGET,
883 	XmNleftWidget     , this->expand,
884 	XmNleftOffset     , 10,
885 	XmNwidth          , 70,
886 	NULL);
887     XtSetSensitive(this->collapse, False);
888 
889     this->help = XtVaCreateManagedWidget(
890 	"configDescriptionButton",
891 	xmPushButtonWidgetClass,
892 	buttonForm,
893 	XmNtopAttachment  , XmATTACH_FORM,
894 	XmNleftAttachment , XmATTACH_WIDGET,
895 	XmNleftWidget     , this->collapse,
896 	XmNleftOffset     , 10,
897 	XmNwidth          , 110,
898 	NULL);
899 
900     this->syntax = XtVaCreateManagedWidget(
901 	"configSyntaxButton",
902 	xmPushButtonWidgetClass,
903 	buttonForm,
904 	XmNtopAttachment  , XmATTACH_FORM,
905 	XmNleftAttachment , XmATTACH_WIDGET,
906 	XmNleftWidget     , this->help,
907 	XmNleftOffset     , 10,
908 	XmNwidth          , 110,
909 	NULL);
910 
911 
912     this->cancel = XtVaCreateManagedWidget(
913 	"configCancelButton",
914 	xmPushButtonWidgetClass,
915 	buttonForm,
916 	XmNtopAttachment  , XmATTACH_FORM,
917 	XmNrightAttachment, XmATTACH_FORM,
918 	XmNwidth          , 70,
919 	NULL);
920 
921     this->restore = XtVaCreateManagedWidget(
922 	"configRestoreButton",
923 	xmPushButtonWidgetClass,
924 	buttonForm,
925 	XmNtopAttachment  , XmATTACH_FORM,
926 	XmNrightAttachment, XmATTACH_WIDGET,
927 	XmNrightWidget    , this->cancel,
928 	XmNrightOffset    , 10,
929 	XmNwidth          , 70,
930 	NULL);
931 
932     //
933     // A Container for inputs and outputs.
934     // Must be done last becuase it requires this->buttonSeparator
935     //
936     this->createBody(dialog);
937 
938     return dialog;
939 }
940 
941 
942 //
943 //  This constructor is for derived classes (not instances of this class).
944 //
ConfigurationDialog(const char * name,Widget parent,Node * node)945 ConfigurationDialog::ConfigurationDialog(const char *name,
946 					Widget parent, Node *node):
947     			Dialog(name, parent)
948 {
949     this->initInstanceData(node);
950 }
951 
952 //
953 //  This constructor is for instances of this class (not derived classes).
954 //
ConfigurationDialog(Widget parent,Node * node)955 ConfigurationDialog::ConfigurationDialog(Widget parent, Node *node):
956     			Dialog("configurationDialog", parent)
957 {
958     this->initInstanceData(node);
959 
960     if (NOT ConfigurationDialog::ClassInitialized)
961     {
962         ConfigurationDialog::ClassInitialized = TRUE;
963 	this->installDefaultResources(theApplication->getRootWidget());
964     }
965 }
966 //
967 // Initialize instance data for the constructors
968 //
initInstanceData(Node * node)969 void ConfigurationDialog::initInstanceData(Node *node)
970 {
971     this->node = node;
972     this->notation = NULL;
973     this->apply = NULL;
974     this->restore = NULL;
975     this->expand = NULL;
976     this->collapse = NULL;
977 
978     this->descriptionDialog = NULL;
979 
980     this->inputNameLabel = NULL;
981     this->inputTypeLabel = NULL;
982     this->inputSourceLabel = NULL;
983     this->inputValueLabel = NULL;
984     this->outputForm = NULL;
985     this->inputForm = NULL;
986     this->inputScroller = NULL;
987     this->scrolledInputForm = NULL;
988 
989     this->outputNameLabel = NULL;
990     this->outputTypeLabel = NULL;
991     this->outputDestLabel = NULL;
992 
993     this->initialNotation = DuplicateString(this->node->getLabelString());
994 }
995 
~ConfigurationDialog()996 ConfigurationDialog::~ConfigurationDialog()
997 {
998     int i;
999     for (i = 1; i <= this->inputList.getSize(); ++i)
1000     {
1001 	CDBInput *input = (CDBInput*)this->inputList.getElement(i);
1002 	delete input;
1003     }
1004     this->inputList.clear();
1005     for (i = 1; i <= this->outputList.getSize(); ++i)
1006     {
1007 	CDBOutput *output = (CDBOutput*)this->outputList.getElement(i);
1008 	delete output;
1009     }
1010     this->outputList.clear();
1011 
1012     if (this->initialNotation)
1013 	delete this->initialNotation;
1014     if (this->descriptionDialog)
1015 	delete this->descriptionDialog;
1016 }
1017 
post()1018 void ConfigurationDialog::post()
1019 {
1020     ListIterator li(this->inputList);
1021     int i;
1022     CDBInput *input;
1023 
1024     for (i = 1; NULL != (input = (CDBInput*)li.getNext()); ++i)
1025     {
1026         input->valueChanged = FALSE;
1027     }
1028 
1029     boolean firstTime = this->getRootWidget() == NULL;
1030 
1031     this->Dialog::post();
1032 
1033     if (firstTime)
1034     {
1035 	if (this->apply)
1036 	    XtAddCallback(this->apply, XmNactivateCallback,
1037 		(XtCallbackProc)ConfigurationDialog_ApplyCB, (XtPointer)this);
1038 	if (this->syntax)
1039 	    XtAddCallback(this->syntax, XmNactivateCallback,
1040 		(XtCallbackProc)ConfigurationDialog_SyntaxCB, (XtPointer)this);
1041 	if (this->restore)
1042 	    XtAddCallback(this->restore, XmNactivateCallback,
1043 		(XtCallbackProc)ConfigurationDialog_RestoreCB, (XtPointer)this);
1044 	if (this->expand)
1045 	    XtAddCallback(this->expand, XmNactivateCallback,
1046 		(XtCallbackProc)ConfigurationDialog_ExpandCB, (XtPointer)this);
1047 	if (this->collapse)
1048 	    XtAddCallback(this->collapse, XmNactivateCallback,
1049 		(XtCallbackProc)ConfigurationDialog_CollapseCB, (XtPointer)this);
1050     }
1051 }
1052 
changeInput(int i)1053 void ConfigurationDialog::changeInput(int i)
1054 {
1055 boolean callbacksWereEnabled;
1056 Node *n = this->node;
1057 
1058 
1059     CDBInput *input = (CDBInput*) this->inputList.getElement(i);
1060 
1061     if ((!input->modified) && (!n->isInputConnected(i))) {
1062 	const char *valueString;
1063 	if (n->isInputDefaulting(i))
1064 	{
1065 	    valueString = n->getInputDefaultValueString(i);
1066 	}
1067 	else
1068 	{
1069 	    valueString = n->getInputSetValueString(i);
1070 	}
1071 	input->setInitialValue(valueString);
1072 	input->initialValueIsDefault = n->isInputDefaulting(i);
1073 	input->initialIsHidden = !n->isInputVisible(i);
1074     }
1075 
1076     if (input->nameWidget != NULL)
1077     {
1078 	char pname[128];
1079 	boolean connected  = n->isInputConnected(i);
1080 	boolean defaulting = n->isInputDefaulting(i);
1081 	boolean visible = n->isInputVisible(i);
1082 	int  nin = n->getInputCount();
1083 
1084 	// Temporarily disable callbacks.
1085 	callbacksWereEnabled = input->valueTextPopup->disableCallbacks();
1086 	XtRemoveCallback(input->nameWidget, XmNvalueChangedCallback,
1087 	    (XtCallbackProc)ConfigurationDialog_ValueChangedInputNameCB, (XtPointer)this);
1088 	XtRemoveCallback(input->hideWidget, XmNvalueChangedCallback,
1089 	    (XtCallbackProc)ConfigurationDialog_ValueChangedInputHideCB, (XtPointer)this);
1090 
1091 
1092 	//if (this->getRootWidget())
1093 	    //XtVaSetValues(this->getRootWidget(),
1094 		//XmNresizePolicy, XmRESIZE_NONE,
1095 		//NULL);
1096 
1097 	XmString name = XmStringCreate((char *)n->getInputNameString(i,pname),
1098 				       XmSTRING_DEFAULT_CHARSET);
1099 	XtVaSetValues(input->nameWidget,
1100 	    XmNset, connected || !defaulting,
1101 	    XmNlabelString, name,
1102 	    XmNsensitive, !connected,
1103 	    NULL);
1104 	XmStringFree(name);
1105 
1106 	XtVaSetValues(input->hideWidget,
1107 	    XmNset, (Boolean)!visible,
1108 	    NULL);
1109 	XtSetSensitive(input->hideWidget, (Boolean)!n->isInputConnected(i));
1110 	if (!visible)
1111 	    XtSetSensitive(this->collapse, True);
1112 
1113 	const char * const*typeString = n->getInputTypeStrings(i);
1114 	XmString typeList;
1115 	if (typeString[0] != NULL)
1116 	{
1117 	    const char * const*ts = typeString;
1118 	    int len = STRLEN(*ts) + 1;
1119 	    ++ts;
1120 	    while (*ts != NULL)
1121 	    {
1122 		len += STRLEN(*ts) + 2;
1123 		++ts;
1124 	    }
1125 	    ts = typeString;
1126 	    char *s = new char[len];
1127 	    strcpy(s, *ts);
1128 	    ++ts;
1129 	    while (*ts != NULL)
1130 	    {
1131 		strcat(s, ", ");
1132 		strcat(s, *ts);
1133 		++ts;
1134 	    }
1135 	    typeList = XmStringCreate(s, XmSTRING_DEFAULT_CHARSET);
1136 	    delete s;
1137 	}
1138 	else
1139 	    typeList = XmStringCreate("", XmSTRING_DEFAULT_CHARSET);
1140 	XtVaSetValues(input->typeWidget, XmNlabelString, typeList, NULL);
1141 	XmStringFree(typeList);
1142 
1143 	const char *sourceString;
1144 	if (n->isInputConnected(i))
1145 	{
1146 	    List *arcs = (List *)n->getInputArks(i);
1147 	    Ark *a = (Ark*)arcs->getElement(1);
1148 	    int paramNum;
1149 	    Node *source = a->getSourceNode(paramNum);
1150 	    sourceString = source->getNameString();
1151 	    XmString s = XmStringCreate((char *)sourceString,
1152 					XmSTRING_DEFAULT_CHARSET);
1153 	    XtVaSetValues(input->connectedToWidget,
1154 		XmNlabelString,	s,
1155 		NULL);
1156 	    XmStringFree(s);
1157 
1158 	    input->valueTextPopup->setText(
1159 			    source->getOutputValueString(paramNum));
1160 	}
1161 	else {
1162 	    XmString s = XmStringCreate("", XmSTRING_DEFAULT_CHARSET);
1163 	    XtVaSetValues(input->connectedToWidget,
1164 		XmNlabelString,	s,
1165 		NULL);
1166 	    XmStringFree(s);
1167 
1168 	    const char *valueString;
1169 	    if (n->isInputDefaulting(i))
1170 	    {
1171 		valueString = n->getInputDefaultValueString(i);
1172 	    }
1173 	    else
1174 	    {
1175 		valueString = n->getInputSetValueString(i);
1176 	    }
1177 	    char *oldValueString = input->valueTextPopup->getText();
1178 	    if  (!EqualString(oldValueString, valueString)) {
1179 		input->valueTextPopup->setText(valueString);
1180 		input->valueChanged = FALSE;
1181 	    }
1182 	    XtFree(oldValueString);
1183 	}
1184 	Boolean sens = !n->isInputConnected(i);
1185  	if (sens)
1186 	    input->valueTextPopup->activate();
1187 	else
1188 	    input->valueTextPopup->deactivate();
1189 
1190 	//if (this->getRootWidget())
1191 	    //XtVaSetValues(this->getRootWidget(),
1192 		//XmNresizePolicy, XmRESIZE_ANY,
1193 		//NULL);
1194 
1195 	if (!XtIsManaged(input->nameWidget))
1196 	{
1197 	    Widget top = NULL;
1198 	    if (!XtIsManaged(this->inputNameLabel))
1199 		this->remanageInputs(FALSE);
1200 	    else
1201 	    {
1202 		Widget managed[10];
1203 		int nmanaged = 0;
1204 		int j;
1205 		for (j = 1; j < i; ++j)
1206 		{
1207 		    CDBInput *input2 = (CDBInput*)this->inputList.getElement(j);
1208 		    if (input2 != NULL && input2->nameWidget != NULL &&
1209 			XtIsManaged(input2->nameWidget))
1210 		    {
1211 			top = input2->nameWidget;
1212 		    }
1213 		}
1214 		managed[nmanaged++] = input->nameWidget;
1215 		if (top) {
1216 		    XtVaSetValues(input->nameWidget,
1217 			XmNtopAttachment, XmATTACH_WIDGET,
1218 			XmNtopWidget, top,
1219 		    NULL);
1220 		} else {
1221 		    XtVaSetValues(input->nameWidget,XmNtopAttachment,XmATTACH_FORM,NULL);
1222 		}
1223 
1224 		managed[nmanaged++] = input->hideWidget;
1225 		managed[nmanaged++] = input->typeWidget;
1226 		managed[nmanaged++] = input->connectedToWidget;
1227 
1228 		if (n->isInputVisible(i))
1229 		    top = input->nameWidget;
1230 		Widget next = NULL;
1231 		for (j = i+1; j <= nin; ++j)
1232 		{
1233 		    CDBInput *input2 = (CDBInput*)this->inputList.getElement(j);
1234 		    if (input2 != NULL && input2->nameWidget != NULL &&
1235 			XtIsManaged(input2->nameWidget))
1236 		    {
1237 			next = input2->nameWidget;
1238 			break;
1239 		    }
1240 		}
1241 		if (n->isInputVisible(i)) {
1242 		    if (!XtIsManaged(input->valueTextPopup->getRootWidget())) {
1243 			Dimension ifh;
1244 			//
1245 			// Grow the window
1246 			//
1247 			XtVaGetValues (this->scrolledInputForm, XmNheight, &ifh, NULL);
1248 			XtVaSetValues (this->scrolledInputForm,
1249 			    XmNheight, ifh+PIXELS_PER_LINE, NULL);
1250 
1251 			XtVaGetValues (this->inputForm, XmNheight, &ifh, NULL);
1252 			if (ifh < (5+(MAX_INITIAL_BUTTONS * PIXELS_PER_LINE))) {
1253 			    XtVaSetValues (this->inputScroller,
1254 				XmNheight, ifh+PIXELS_PER_LINE,
1255 			    NULL);
1256 			}
1257 			this->resizeCallback();
1258 		    }
1259 		    input->valueTextPopup->manage();
1260 		    XtManageChildren(managed, nmanaged);
1261 		    if (next) XtVaSetValues(next, XmNtopWidget, input->nameWidget, NULL);
1262 		    XtSetSensitive(this->collapse, True);
1263 		    if (!XtIsManaged(XtParent(this->inputScroller)))
1264 			XtManageChild (XtParent(this->inputScroller));
1265 
1266 
1267 		} else {
1268 		    if (XtIsManaged(input->valueTextPopup->getRootWidget())) {
1269 			Dimension ifh;
1270 			//
1271 			// Shrink the window
1272 			//
1273 			XtVaGetValues (this->scrolledInputForm, XmNheight, &ifh, NULL);
1274 			if (ifh > PIXELS_PER_LINE)
1275 			    XtVaSetValues (this->scrolledInputForm,
1276 				XmNheight, ifh-PIXELS_PER_LINE,
1277 			    NULL);
1278 		    }
1279 		    input->valueTextPopup->unmanage();
1280 		    XtUnmanageChildren(managed, nmanaged);
1281 		    XtSetSensitive(this->expand, True);
1282 		}
1283 	    }
1284 	}
1285 
1286 	if (callbacksWereEnabled)
1287 	    input->valueTextPopup->enableCallbacks();
1288 	XtAddCallback(input->nameWidget, XmNvalueChangedCallback,
1289 	    (XtCallbackProc)ConfigurationDialog_ValueChangedInputNameCB, (XtPointer)this);
1290 	XtAddCallback(input->hideWidget, XmNvalueChangedCallback,
1291 	    (XtCallbackProc)ConfigurationDialog_ValueChangedInputHideCB, (XtPointer)this);
1292 
1293     }
1294 
1295 }
changeOutput(int i)1296 void ConfigurationDialog::changeOutput(int i)
1297 {
1298     Node *n = this->node;
1299     CDBOutput *output = (CDBOutput*)this->outputList.getElement(i);
1300 
1301     if (output->nameWidget != NULL)
1302     {
1303 	char pname[128];
1304 	//if (this->getRootWidget())
1305 	    //XtVaSetValues(this->getRootWidget(),
1306 		//XmNresizePolicy, XmRESIZE_NONE,
1307 		//NULL);
1308 
1309 	XmString name = XmStringCreate((char *)n->getOutputNameString(i,pname),
1310 				       XmSTRING_DEFAULT_CHARSET);
1311 	XtVaSetValues(output->nameWidget,
1312 	    XmNlabelString, name,
1313 	    NULL);
1314 	XmStringFree(name);
1315 
1316 	const char * const*typeString = n->getOutputTypeStrings(i);
1317 	XmString typeList;
1318 	if (typeString[0] != NULL)
1319 	{
1320 	    const char * const*ts = typeString;
1321 	    int len = STRLEN(*ts) + 1;
1322 	    ++ts;
1323 	    while (*ts != NULL)
1324 	    {
1325 		len += STRLEN(*ts) + 2;
1326 		++ts;
1327 	    }
1328 	    ts = typeString;
1329 	    char *s = new char[len];
1330 	    strcpy(s, *ts);
1331 	    ++ts;
1332 	    while (*ts != NULL)
1333 	    {
1334 		strcat(s, ", ");
1335 		strcat(s, *ts);
1336 		++ts;
1337 	    }
1338 	    typeList = XmStringCreate(s, XmSTRING_DEFAULT_CHARSET);
1339 	    delete s;
1340 	}
1341 	else
1342 	    typeList = XmStringCreate("", XmSTRING_DEFAULT_CHARSET);
1343 	XtVaSetValues(output->typeWidget, XmNlabelString, typeList, NULL);
1344 	XmStringFree(typeList);
1345 
1346 	XmString s;
1347 	if (n->isOutputConnected(i))
1348 	{
1349 	    char *destString;
1350 	    List *arcs = (List *)n->getOutputArks(i);
1351 	    ListIterator li(*arcs);
1352 	    Ark *a = (Ark*)li.getNext();
1353 	    int dummy;
1354 	    Node *dest = a->getDestinationNode(dummy);
1355 	    int len = STRLEN(dest->getNameString()) + 1;
1356 	    while ((a = (Ark*)li.getNext()) != NULL)
1357 	    {
1358 		dest = a->getDestinationNode(dummy);
1359 		len += STRLEN(dest->getNameString()) + 2;
1360 	    }
1361 	    destString = new char[len];
1362 	    li.setList(*arcs);
1363 	    a = (Ark*)li.getNext();
1364 	    dest = a->getDestinationNode(dummy);
1365 	    strcpy(destString, dest->getNameString());
1366 	    while ((a = (Ark*)li.getNext()) != NULL)
1367 	    {
1368 		dest = a->getDestinationNode(dummy);
1369 		strcat(destString, ", ");
1370 		strcat(destString, dest->getNameString());
1371 	    }
1372 	    s = XmStringCreate(destString, XmSTRING_DEFAULT_CHARSET);
1373 	    delete destString;
1374 	}
1375 	else {
1376 	    s = XmStringCreate("", XmSTRING_DEFAULT_CHARSET);
1377 	}
1378 	XtVaSetValues(output->connectedToWidget,
1379 	    XmNlabelString,	s,
1380 	    NULL);
1381 	XmStringFree(s);
1382 
1383 	switch (n->getOutputCacheability(i)) {
1384 	case OutputFullyCached:
1385 	    XtVaSetValues(output->cacheWidget,
1386 		XmNmenuHistory, output->fullButton, NULL);
1387 	    break;
1388 	case OutputCacheOnce:
1389 	    XtVaSetValues(output->cacheWidget,
1390 		XmNmenuHistory, output->lastButton, NULL);
1391 	    break;
1392 	case OutputNotCached:
1393 	    XtVaSetValues(output->cacheWidget,
1394 		XmNmenuHistory, output->offButton, NULL);
1395 	    break;
1396 	}
1397 
1398 	XtSetSensitive(output->cacheWidget,
1399 			n->isOutputCacheabilityWriteable(i));
1400 
1401 	//if (this->getRootWidget())
1402 	    //XtVaSetValues(this->getRootWidget(),
1403 		//XmNresizePolicy, XmRESIZE_ANY,
1404 		//NULL);
1405     }
1406 }
newInput(int i)1407 void ConfigurationDialog::newInput(int i)
1408 {
1409     Arg args[10];
1410     int m;
1411     Node *n = this->node;
1412     CDBInput *input = (CDBInput*)this->inputList.getElement(i);
1413     if (input == NULL)
1414     {
1415 	input = new CDBInput;
1416 	this->inputList.insertElement(input, i);
1417     }
1418 
1419     if (!n->isInputViewable(i))
1420 	return;
1421 
1422     Widget prevNameWidget = NULL;
1423     Widget prevTextPopup = NULL;
1424     int j;
1425     for (j = i - 1; j > 0; --j)
1426     {
1427 	CDBInput *prevInput = (CDBInput*)this->inputList.getElement(j);
1428 	if (prevInput != NULL && prevInput->nameWidget != NULL &&
1429 	    !prevInput->lineIsHidden)
1430 	{
1431 	    prevNameWidget = prevInput->nameWidget;
1432 	    prevTextPopup = prevInput->valueTextPopup->getRootWidget();
1433 	    break;
1434 	}
1435     }
1436 
1437     if (prevNameWidget == NULL)
1438     {
1439 	if (this->inputNameLabel == NULL)
1440 	{
1441 	    XtManageChild(this->inputTitle);
1442 
1443 	    this->inputNameLabel = XtVaCreateManagedWidget(
1444 		"configInputNameLabel",
1445 		xmLabelWidgetClass,
1446 		this->inputForm,
1447 		XmNtopAttachment   , XmATTACH_WIDGET,
1448 		XmNtopWidget       , this->inputTitle,
1449 		XmNleftAttachment  , XmATTACH_FORM,
1450 		XmNalignment       , XmALIGNMENT_BEGINNING,
1451 		XmNallowResize,     False,
1452 		NULL);
1453 
1454 	    XtVaSetValues (XtParent(this->inputScroller), XmNtopWidget, this->inputNameLabel, NULL);
1455 
1456 	    this->inputHideLabel = XtVaCreateManagedWidget(
1457 		"configInputHideLabel",
1458 		xmLabelWidgetClass,
1459 		this->inputForm,
1460 		XmNtopAttachment   , XmATTACH_WIDGET,
1461 		XmNtopWidget       , this->inputTitle,
1462 		XmNleftAttachment  , XmATTACH_FORM,
1463 		XmNalignment       , XmALIGNMENT_BEGINNING,
1464 		XmNallowResize,     False,
1465 		NULL);
1466 
1467 	    this->inputTypeLabel = XtVaCreateManagedWidget(
1468 		"configInputTypeLabel",
1469 		xmLabelWidgetClass,
1470 		this->inputForm,
1471 		XmNtopAttachment   , XmATTACH_WIDGET,
1472 		XmNtopWidget       , this->inputTitle,
1473 		XmNleftAttachment  , XmATTACH_FORM,
1474 		XmNalignment       , XmALIGNMENT_BEGINNING,
1475 		NULL);
1476 
1477 	    this->inputSourceLabel = XtVaCreateManagedWidget(
1478 		"configInputSourceLabel",
1479 		xmLabelWidgetClass,
1480 		this->inputForm,
1481 		XmNtopAttachment   , XmATTACH_WIDGET,
1482 		XmNtopWidget       , this->inputTitle,
1483 		XmNleftAttachment  , XmATTACH_FORM,
1484 		XmNalignment       , XmALIGNMENT_BEGINNING,
1485 		NULL);
1486 
1487 	    this->inputValueLabel = XtVaCreateManagedWidget(
1488 		"configInputValueLabel",
1489 		xmLabelWidgetClass,
1490 		this->inputForm,
1491 		XmNtopAttachment   , XmATTACH_WIDGET,
1492 		XmNtopWidget       , this->inputTitle,
1493 		XmNleftAttachment  , XmATTACH_FORM,
1494 		XmNrightAttachment , XmATTACH_FORM,
1495 		XmNalignment       , XmALIGNMENT_BEGINNING,
1496 		NULL);
1497 	}
1498     }
1499 
1500     Widget name;
1501     if (!prevNameWidget) {
1502 	name = XtVaCreateWidget(
1503 	    "configInputName",
1504 	    xmToggleButtonWidgetClass,
1505 	    this->scrolledInputForm,
1506 	    XmNtopAttachment,   XmATTACH_FORM,
1507 	    NULL);
1508     } else {
1509 	name = XtVaCreateWidget(
1510 	    "configInputName",
1511 	    xmToggleButtonWidgetClass,
1512 	    this->scrolledInputForm,
1513 	    XmNtopAttachment,   XmATTACH_WIDGET,
1514 	    XmNtopWidget,       prevNameWidget,
1515 	    NULL);
1516     }
1517 
1518     XtVaSetValues (name,
1519 	XmNuserData,        this,
1520 	XmNalignment,       XmALIGNMENT_BEGINNING,
1521 	XmNset,       	    (Boolean)(n->isInputConnected(i) ||
1522 				     !n->isInputDefaulting(i)),
1523 	XmNallowResize,     False,
1524 	XmNshadowThickness, 0,
1525 	XmNleftAttachment,  XmATTACH_FORM,
1526 	XmNtopOffset,       POPUP_OFFSET,
1527 	NULL);
1528 
1529     input->nameWidget = name;
1530     XtVaGetValues(name,
1531 	XmNtopShadowColor,    &this->standardTopShadowColor,
1532 	XmNbottomShadowColor, &this->standardBottomShadowColor,
1533 	NULL);
1534 
1535     XmString null = XmStringCreate("", XmSTRING_DEFAULT_CHARSET);
1536     Widget hide = XtVaCreateWidget(
1537 	"configInputHide",
1538 	xmToggleButtonWidgetClass,
1539 	this->scrolledInputForm,
1540 	XmNtopAttachment,   XmATTACH_OPPOSITE_WIDGET,
1541 	XmNtopWidget,       input->nameWidget,
1542 	XmNtopOffset,       0,
1543 	XmNleftAttachment,  XmATTACH_FORM,
1544 	XmNuserData,        this,
1545 	XmNalignment,       XmALIGNMENT_BEGINNING,
1546 	XmNset,       	    (Boolean)(!n->isInputVisible(i)),
1547 	XmNallowResize,     False,
1548 	XmNlabelString,     null,
1549 	XmNshadowThickness, 0,
1550 	NULL);
1551     input->hideWidget = hide;
1552     input->initialIsHidden = !n->isInputVisible(i);
1553     XmStringFree(null);
1554 
1555     Widget type = XtVaCreateWidget(
1556 	"configInputType",
1557 	xmLabelWidgetClass,
1558 	this->scrolledInputForm,
1559 	XmNtopAttachment,   XmATTACH_OPPOSITE_WIDGET,
1560 	XmNtopWidget,       input->nameWidget,
1561 	XmNtopOffset,       0,
1562 	XmNleftAttachment,  XmATTACH_FORM,
1563 	XmNalignment,       XmALIGNMENT_BEGINNING,
1564 	NULL);
1565     input->typeWidget = type;
1566 
1567     Widget source = XtVaCreateWidget(
1568 	"configInputSource",
1569 	xmLabelWidgetClass,
1570 	this->scrolledInputForm,
1571 	XmNtopAttachment,   XmATTACH_OPPOSITE_WIDGET,
1572 	XmNtopWidget,       input->nameWidget,
1573 	XmNtopOffset,       0,
1574 	XmNbottomAttachment,   XmATTACH_OPPOSITE_WIDGET,
1575 	XmNbottomWidget,       input->nameWidget,
1576 	XmNbottomOffset,       0,
1577 	XmNleftAttachment,  XmATTACH_FORM,
1578 	XmNrightAttachment, XmATTACH_OPPOSITE_FORM,
1579 	XmNalignment,       XmALIGNMENT_BEGINNING,
1580 	NULL);
1581     input->connectedToWidget = source;
1582 
1583     const char *const *options = n->getInputValueOptions(i);
1584     int option_count = 0;
1585     if (options) {
1586 	while (options[option_count])
1587 	    option_count++;
1588     }
1589     input->valueTextPopup->createTextPopup(this->scrolledInputForm,(const char**)options,
1590 			option_count,
1591 		    ConfigurationDialog::ActivateInputValueCB,
1592 		    ConfigurationDialog::ValueChangedInputValueCB,
1593 		    (void*)this);
1594 
1595     m = 0;
1596     XtSetArg (args[m], XmNtopAttachment,   XmATTACH_OPPOSITE_WIDGET); m++;
1597     XtSetArg (args[m], XmNtopWidget,       input->nameWidget); m++;
1598     XtSetArg (args[m], XmNtopOffset,       0); m++;
1599     XtSetArg (args[m], XmNleftAttachment,  XmATTACH_FORM); m++;
1600     XtSetArg (args[m], XmNleftOffset,  560); m++;
1601     XtSetArg (args[m], XmNrightAttachment, XmATTACH_FORM); m++;
1602     if (prevTextPopup) {
1603 	Dimension ph;
1604 	XtVaGetValues (prevTextPopup, XmNheight, &ph, NULL);
1605 	XtSetArg (args[m], XmNheight, ph); m++;
1606     }
1607     XtSetValues(input->valueTextPopup->getRootWidget(), args, m);
1608 
1609     const char *valueString;
1610     if (n->isInputDefaulting(i))
1611     {
1612 	valueString = n->getInputDefaultValueString(i);
1613     }
1614     else
1615     {
1616 	valueString = n->getInputSetValueString(i);
1617     }
1618     input->setInitialValue(valueString);
1619     input->initialValueIsDefault = n->isInputDefaulting(i);
1620     input->initialIsHidden = !n->isInputVisible(i);
1621 
1622     input->valueTextPopup->enableCallbacks();
1623 
1624     XtAddCallback(input->nameWidget, XmNvalueChangedCallback,
1625 	(XtCallbackProc)ConfigurationDialog_ValueChangedInputNameCB, (XtPointer)this);
1626     XtAddCallback(input->hideWidget, XmNvalueChangedCallback,
1627 	(XtCallbackProc)ConfigurationDialog_ValueChangedInputHideCB, (XtPointer)this);
1628 
1629     input->modified = 0;
1630     this->changeInput(i);
1631 
1632     Dimension width;
1633     XtVaGetValues(input->typeWidget, XmNwidth, &width, NULL);
1634     if (width > this->typeWidth)
1635 	this->typeWidth = width;
1636 
1637     input->lineIsHidden = !n->isInputVisible(i);
1638     if (!input->lineIsHidden)
1639     {
1640 	XtManageChild(input->nameWidget);
1641 	XtManageChild(input->hideWidget);
1642 	XtManageChild(input->typeWidget);
1643 	XtManageChild(input->connectedToWidget);
1644 	input->valueTextPopup->manage();
1645 	for (j = i + 1; j <= this->inputList.getSize(); ++j)
1646 	{
1647 	    CDBInput *nextInput = (CDBInput*)this->inputList.getElement(j);
1648 	    if (nextInput != NULL && nextInput->nameWidget != NULL &&
1649 		!nextInput->lineIsHidden)
1650 	    {
1651 		XtVaSetValues(nextInput->nameWidget,
1652 		    XmNtopWidget, input->nameWidget,
1653 		    XmNtopAttachment, XmATTACH_WIDGET,
1654 		    NULL);
1655 		break;
1656 	    }
1657 	}
1658     }
1659     else
1660     {
1661 	XtUnmanageChild(input->nameWidget);
1662 	XtUnmanageChild(input->hideWidget);
1663 	XtUnmanageChild(input->typeWidget);
1664 	XtUnmanageChild(input->connectedToWidget);
1665 	input->valueTextPopup->unmanage();
1666 	XtSetSensitive(this->expand, True);
1667     }
1668 
1669     //
1670     // Adjust the size of the scrolled Window.
1671     //
1672     int numParam = this->inputList.getSize();
1673     int visInputCount = 0;
1674     for (i=1; i<=numParam; i++) {
1675 	input = (CDBInput*)this->inputList.getElement(i);
1676 	if (!input->nameWidget) continue;
1677 	if (!XtIsManaged(input->nameWidget)) continue;
1678 	visInputCount++;
1679     }
1680     if (visInputCount) {
1681 	XtVaSetValues (this->scrolledInputForm,
1682 	    XmNheight, 5+(PIXELS_PER_LINE*visInputCount),
1683 	NULL);
1684 	if (!XtIsManaged(XtParent(this->inputScroller)))
1685 	    XtManageChild (XtParent(this->inputScroller));
1686 
1687 
1688         XSync (XtDisplay(this->scrolledInputForm), False);
1689 
1690         Dimension newHeight, oldHeight;
1691         int vis = visInputCount;
1692         if (vis > MAX_INITIAL_BUTTONS) vis = MAX_INITIAL_BUTTONS;
1693         if (vis <= 0) vis = visInputCount = 1;
1694         newHeight = 5+(vis*PIXELS_PER_LINE);
1695         XtVaGetValues (this->inputScroller, XmNheight, &oldHeight, NULL);
1696         if ((visInputCount <= MAX_INITIAL_BUTTONS) || (newHeight > oldHeight)) {
1697             XtVaSetValues (this->inputScroller,
1698                 XmNheight, newHeight,
1699             NULL);
1700         } else {
1701             this->resizeCallback();
1702         }
1703     }
1704 }
newOutput(int i)1705 void ConfigurationDialog::newOutput(int i)
1706 {
1707     Node *n = this->node;
1708     CDBOutput *output = (CDBOutput*)this->outputList.getElement(i);
1709     if (output == NULL)
1710     {
1711 	output = new CDBOutput;
1712 	this->outputList.insertElement(output, i);
1713     }
1714 
1715     if (!n->isOutputViewable(i))
1716 	return;
1717 
1718     Widget prevNameWidget = NULL;
1719     int j;
1720     for (j = i - 1; j > 0; --j)
1721     {
1722 	CDBOutput *prevOutput = (CDBOutput*)this->outputList.getElement(j);
1723 	if (prevOutput != NULL && prevOutput->nameWidget != NULL)
1724 	{
1725 	    prevNameWidget = prevOutput->nameWidget;
1726 	    break;
1727 	}
1728     }
1729     if (prevNameWidget == NULL)
1730     {
1731 	prevNameWidget = this->outputNameLabel;
1732     }
1733 
1734     Widget outputs = XtParent(prevNameWidget);
1735 
1736     Widget name = XtVaCreateManagedWidget(
1737 	"Name Goes Here",
1738 	xmLabelWidgetClass,
1739 	outputs,
1740 	XmNtopAttachment,   XmATTACH_WIDGET,
1741 	XmNtopWidget,       prevNameWidget,
1742 	XmNtopOffset,       3,
1743 	XmNleftAttachment,  XmATTACH_OPPOSITE_WIDGET,
1744 	XmNleftWidget,      this->outputNameLabel,
1745 	XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1746 	XmNrightWidget,     this->outputNameLabel,
1747 	XmNuserData,        this,
1748 	XmNalignment,       XmALIGNMENT_BEGINNING,
1749 	NULL);
1750     output->nameWidget = name;
1751 
1752     Widget type = XtVaCreateManagedWidget(
1753 	"Type Goes Here",
1754 	xmLabelWidgetClass,
1755 	outputs,
1756 	XmNtopAttachment,   XmATTACH_WIDGET,
1757 	XmNtopWidget,       prevNameWidget,
1758 	XmNtopOffset,       3,
1759 	XmNleftAttachment,  XmATTACH_OPPOSITE_WIDGET,
1760 	XmNleftWidget,      this->outputTypeLabel,
1761 	XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1762 	XmNrightWidget,     this->outputTypeLabel,
1763 	XmNalignment,       XmALIGNMENT_BEGINNING,
1764 	NULL);
1765     output->typeWidget = type;
1766 
1767     Widget dest = XtVaCreateManagedWidget(
1768 	"destination",
1769 	xmLabelWidgetClass,
1770 	outputs,
1771 	XmNtopAttachment,   XmATTACH_WIDGET,
1772 	XmNtopWidget,       prevNameWidget,
1773 	XmNtopOffset,       3,
1774 	XmNleftAttachment,  XmATTACH_OPPOSITE_WIDGET,
1775 	XmNleftWidget,      this->outputDestLabel,
1776 	XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1777 	XmNrightWidget,     this->outputDestLabel,
1778 	XmNalignment,       XmALIGNMENT_BEGINNING,
1779 	NULL);
1780     output->connectedToWidget = dest;
1781 
1782     output->cachePulldown =  XmCreatePulldownMenu(outputs,
1783 	"cachePulldown", NULL, 0);
1784     output->fullButton = XtVaCreateManagedWidget("cacheFull",
1785 	xmPushButtonWidgetClass, output->cachePulldown, NULL);
1786     output->lastButton = XtVaCreateManagedWidget("cacheLast",
1787 	xmPushButtonWidgetClass, output->cachePulldown, NULL);
1788     output->offButton = XtVaCreateManagedWidget("cacheOff",
1789 	xmPushButtonWidgetClass, output->cachePulldown, NULL);
1790     XtAddCallback(output->fullButton, XmNactivateCallback,
1791 		    (XtCallbackProc)ConfigurationDialog_ActivateOutputCacheCB,
1792 		    (XtPointer)this);
1793     XtAddCallback(output->lastButton, XmNactivateCallback,
1794 		    (XtCallbackProc)ConfigurationDialog_ActivateOutputCacheCB,
1795 		    (XtPointer)this);
1796     XtAddCallback(output->offButton, XmNactivateCallback,
1797 		    (XtCallbackProc)ConfigurationDialog_ActivateOutputCacheCB,
1798 		    (XtPointer)this);
1799 
1800     output->cacheWidget = XtVaCreateManagedWidget(
1801 	"cacheOptionMenu", xmRowColumnWidgetClass, outputs,
1802 	XmNtopAttachment,   XmATTACH_WIDGET,
1803 	XmNtopWidget,       prevNameWidget,
1804 	XmNtopOffset,       3,
1805 	XmNleftAttachment,  XmATTACH_OPPOSITE_WIDGET,
1806 	XmNleftWidget,      this->outputCacheLabel,
1807 	XmNleftOffset,      -10,
1808 	XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET,
1809 	XmNrightWidget,     this->outputCacheLabel,
1810 	XmNrowColumnType,   XmMENU_OPTION,
1811 	XmNsubMenuId,       output->cachePulldown,
1812 	NULL);
1813 
1814     this->changeOutput(i);
1815 
1816     Dimension width;
1817     XtVaGetValues(output->typeWidget, XmNwidth, &width, NULL);
1818     if (width > this->typeWidth)
1819 	this->typeWidth = width;
1820 
1821     for (j = i + 1; j <= this->outputList.getSize(); ++j)
1822     {
1823 	CDBOutput *nextOutput = (CDBOutput*)this->outputList.getElement(j);
1824 	if (nextOutput != NULL && nextOutput->nameWidget != NULL)
1825 	{
1826 	    XtVaSetValues(nextOutput->nameWidget,
1827 		XmNtopWidget, output->nameWidget,
1828 		NULL);
1829 	    XtVaSetValues(nextOutput->typeWidget,
1830 		XmNtopWidget, output->nameWidget,
1831 		NULL);
1832 	    XtVaSetValues(nextOutput->connectedToWidget,
1833 		XmNtopWidget, output->nameWidget,
1834 		NULL);
1835 	    XtVaSetValues(nextOutput->cacheWidget,
1836 		XmNtopWidget, output->nameWidget,
1837 		NULL);
1838 	    break;
1839 	}
1840     }
1841 
1842 #if defined(ibm6000)
1843     XtVaSetValues (outputs, XmNheight, 0, NULL);
1844 #endif
1845 }
1846 
deleteInput(int i)1847 void ConfigurationDialog::deleteInput(int i)
1848 {
1849     CDBInput *input = (CDBInput*)this->inputList.getElement(i);
1850     if (input == NULL)
1851 	return;
1852 
1853     if (input->nameWidget != NULL)
1854     {
1855 	input->valueTextPopup->disableCallbacks();
1856 	XtRemoveCallback(input->nameWidget, XmNvalueChangedCallback,
1857 	    (XtCallbackProc)ConfigurationDialog_ValueChangedInputNameCB, (XtPointer)this);
1858 	XtDestroyWidget(input->nameWidget);
1859 	XtDestroyWidget(input->typeWidget);
1860 	XtDestroyWidget(input->connectedToWidget);
1861 	XtDestroyWidget(input->valueTextPopup->getRootWidget());
1862 	XtDestroyWidget(input->hideWidget);
1863     }
1864 
1865     CDBInput *prevVisible;
1866     int j;
1867     for (j = i-1; (prevVisible = (CDBInput*)this->inputList.getElement(j)); --j)
1868 	if (!prevVisible->lineIsHidden)
1869 	    break;
1870     Widget prevWidget;
1871     if (prevVisible)
1872 	prevWidget = prevVisible->nameWidget;
1873     else
1874 	prevWidget = NULL;
1875 
1876     CDBInput *nextVisible;
1877     for (j = i+1; (nextVisible = (CDBInput*)this->inputList.getElement(j)); ++j)
1878 	if (!nextVisible->lineIsHidden)
1879 	    break;
1880     if (nextVisible)
1881 	if (prevWidget)
1882 	    XtVaSetValues(nextVisible->nameWidget, XmNtopWidget, prevWidget, NULL);
1883 	else
1884 	    XtVaSetValues(nextVisible->nameWidget, XmNtopAttachment, XmATTACH_FORM, NULL);
1885 
1886     this->inputList.deleteElement(i);
1887     delete input;
1888 
1889     //
1890     // Adjust the size of the scrolled Window.
1891     //
1892     int numParam = this->inputList.getSize();
1893     int visInputCount = 0;
1894     for (i=1; i<=numParam; i++) {
1895 	input = (CDBInput*)this->inputList.getElement(i);
1896 	if (!input->nameWidget) continue;
1897 	if (!XtIsManaged(input->nameWidget)) continue;
1898 	visInputCount++;
1899     }
1900     if (visInputCount) {
1901 	XtVaSetValues (this->scrolledInputForm,
1902 	    XmNheight, 5+(PIXELS_PER_LINE*visInputCount), NULL);
1903 	XSync (XtDisplay(this->scrolledInputForm), False);
1904 
1905 	Dimension newHeight, oldHeight;
1906 	int vis = visInputCount;
1907 	if (vis > MAX_INITIAL_BUTTONS) vis = MAX_INITIAL_BUTTONS;
1908 	if (vis <= 0) vis = visInputCount = 1;
1909 	newHeight = 5+(vis*PIXELS_PER_LINE);
1910 	XtVaGetValues (this->inputScroller, XmNheight, &oldHeight, NULL);
1911 	if ((visInputCount <= MAX_INITIAL_BUTTONS) || (newHeight > oldHeight)) {
1912 	    XtVaSetValues (this->inputScroller,
1913 		XmNheight, newHeight,
1914 	    NULL);
1915 	} else {
1916 	    this->resizeCallback();
1917 	}
1918     }
1919 }
deleteOutput(int i)1920 void ConfigurationDialog::deleteOutput(int i)
1921 {
1922     CDBOutput *output = (CDBOutput*)this->outputList.getElement(i);
1923     if (output == NULL)
1924 	return;
1925 
1926     Widget prevNameWidget=NULL;
1927     int j;
1928     for (j = i - 1; j > 0; --j)
1929     {
1930 	CDBOutput *prevOutput = (CDBOutput*)this->outputList.getElement(j);
1931 	if (prevOutput != NULL && prevOutput->nameWidget != NULL)
1932 	{
1933 	    prevNameWidget = prevOutput->nameWidget;
1934 	    break;
1935 	}
1936     }
1937     if (prevNameWidget == NULL)
1938     {
1939 	prevNameWidget = this->outputNameLabel;
1940     }
1941 
1942 
1943     for (j = i + 1; j <= this->outputList.getSize(); ++j)
1944     {
1945 	CDBOutput *nextOutput = (CDBOutput*)this->outputList.getElement(j);
1946 	if (nextOutput != NULL && nextOutput->nameWidget != NULL)
1947 	{
1948 	    XtVaSetValues(nextOutput->nameWidget,
1949 		XmNtopWidget, prevNameWidget,
1950 		NULL);
1951 	    XtVaSetValues(nextOutput->typeWidget,
1952 		XmNtopWidget, prevNameWidget,
1953 		NULL);
1954 	    XtVaSetValues(nextOutput->connectedToWidget,
1955 		XmNtopWidget, prevNameWidget,
1956 		NULL);
1957 	    XtVaSetValues(nextOutput->cacheWidget,
1958 		XmNtopWidget, prevNameWidget,
1959 		NULL);
1960 	    break;
1961 	}
1962     }
1963     if (output->nameWidget != NULL)
1964     {
1965 	XtDestroyWidget(output->nameWidget);
1966 	XtDestroyWidget(output->typeWidget);
1967 	XtDestroyWidget(output->connectedToWidget);
1968 	XtDestroyWidget(output->cacheWidget);
1969 	XtDestroyWidget(output->cachePulldown);
1970     }
1971     this->outputList.deleteElement(i);
1972     delete output;
1973 }
1974 
widgetChanged(int i,boolean send)1975 boolean ConfigurationDialog::widgetChanged(int i, boolean send)
1976 {
1977     CDBInput *input = (CDBInput*)this->inputList.getElement(i);
1978     const char *s = input->valueTextPopup->getText();
1979     boolean retval = TRUE;
1980     char pname[128];
1981 
1982     if (*s == '\0')
1983     {
1984 	this->node->useDefaultInputValue(i, send);
1985 	input->valueTextPopup->setText(
1986 			this->node->getInputDefaultValueString(i));
1987     }
1988     else if (EqualString(s, this->node->getInputDefaultValueString(i)))
1989     {
1990 	if ((s) && (s[0]))
1991 	    this->node->setInputValue(i, s, DXType::UndefinedType, send);
1992 	else
1993 	    this->node->setInputValue(i, "NULL", DXType::UndefinedType, send);
1994     }
1995     else if (this->node->setInputValue(i, s, DXType::UndefinedType, send) ==
1996 	     DXType::UndefinedType)
1997     {
1998 	ErrorMessage("String `%s' is not a valid value for %s parameter '%s'",
1999 	    s, this->node->getNameString(),
2000 		this->node->getInputNameString(i,pname));
2001 	retval = FALSE;
2002     }
2003     XtFree((char *)s);
2004 
2005     input->valueChanged = !retval;
2006     return retval;
2007 }
2008 
changeLabel()2009 void ConfigurationDialog::changeLabel()
2010 {
2011     const char *l = this->node->getLabelString();
2012     XmTextSetString(this->notation, (char *)l);
2013 }
2014 
remanageInputs(boolean force)2015 void ConfigurationDialog::remanageInputs(boolean force)
2016 {
2017     int count = this->node->getInputCount();
2018     int visible = 0;	// Are any input lines visible?
2019     int invisible = 0;	// Are any visible input lines invisible inputs?
2020     int noline    = 0;	// Are any invisible intputs' lines invisible?
2021     int i;
2022     Widget lastName = NULL;
2023     Widget *managed = new Widget[(count + 1) * 7];
2024     int     nmanaged = 0;
2025     Widget *unmanaged = new Widget[(count + 1) * 7];
2026     int     nunmanaged = 0;
2027 
2028     //
2029     // Make sure that all titles are managed.
2030     managed[nmanaged++] = this->inputTitle;
2031     managed[nmanaged++] = this->inputNameLabel;
2032     managed[nmanaged++] = this->inputHideLabel;
2033     managed[nmanaged++] = this->inputTypeLabel;
2034     managed[nmanaged++] = this->inputSourceLabel;
2035     managed[nmanaged++] = this->inputValueLabel;
2036     XtManageChildren(managed, nmanaged); nmanaged = 0;
2037     managed[nmanaged++] = XtParent(this->inputScroller);
2038     XtManageChildren(managed, nmanaged); nmanaged = 0;
2039     for (i = 1; i <= count; ++i)
2040     {
2041 	if (!this->node->isInputViewable(i))
2042 	    continue;
2043 	CDBInput *input = (CDBInput*)this->inputList.getElement(i);
2044 	if (force || this->node->isInputVisible(i))
2045 	{
2046 	    ++visible;
2047 	    if (!this->node->isInputVisible(i))
2048 		invisible++;
2049 	    ASSERT(input->nameWidget);
2050 	    if (!lastName)
2051 		XtVaSetValues(input->nameWidget,
2052 		    XmNtopAttachment, XmATTACH_FORM,
2053 		NULL);
2054 	    else
2055 		XtVaSetValues(input->nameWidget,
2056 		    XmNtopAttachment, XmATTACH_WIDGET,
2057 		    XmNtopWidget, lastName,
2058 		NULL);
2059 	    managed[nmanaged++] = input->nameWidget;
2060 	    managed[nmanaged++] = input->hideWidget;
2061 	    managed[nmanaged++] = input->typeWidget;
2062 	    managed[nmanaged++] = input->connectedToWidget;
2063 	    input->valueTextPopup->manage();
2064 	    lastName = input->nameWidget;
2065 	    input->lineIsHidden=FALSE;
2066 	}
2067 	else
2068 	{
2069 	    ++noline;
2070 	    unmanaged[nunmanaged++] = input->nameWidget;
2071 	    unmanaged[nunmanaged++] = input->hideWidget;
2072 	    unmanaged[nunmanaged++] = input->typeWidget;
2073 	    unmanaged[nunmanaged++] = input->connectedToWidget;
2074 	    input->valueTextPopup->unmanage();
2075 	    input->lineIsHidden=TRUE;
2076 	}
2077     }
2078     XtManageChildren(managed, nmanaged); nmanaged = 0;
2079     XtUnmanageChildren(unmanaged, nunmanaged); nunmanaged = 0;
2080 
2081     if (count > 0 && visible == 0)
2082     {
2083 	unmanaged[nunmanaged++] = this->inputTitle;
2084 	unmanaged[nunmanaged++] = this->inputNameLabel;
2085 	unmanaged[nunmanaged++] = this->inputHideLabel;
2086 	unmanaged[nunmanaged++] = this->inputTypeLabel;
2087 	unmanaged[nunmanaged++] = this->inputSourceLabel;
2088 	unmanaged[nunmanaged++] = this->inputValueLabel;
2089 	XtUnmanageChildren(unmanaged, nunmanaged); nunmanaged = 0;
2090 	unmanaged[nunmanaged++] = XtParent(this->inputScroller);
2091 	XtUnmanageChildren(unmanaged, nunmanaged); nunmanaged = 0;
2092     }
2093 
2094     //
2095     // too-small-dialog workaround for displaying on Sun4.
2096     //
2097     if (visible == 0 AND this->node->getOutputCount() == 0)
2098         XtVaSetValues(this->getRootWidget(), XmNwidth, 770, NULL);
2099 
2100     delete managed;
2101     delete unmanaged;
2102 
2103     //
2104     // If we just expanded, gray out expand.
2105     // if none of the visible lines are invisible parameters, gray out collpase.
2106     //
2107     XtSetSensitive(this->expand, (Boolean)noline != 0);
2108     XtSetSensitive(this->collapse, (Boolean)(invisible != 0));
2109 
2110     //
2111     // Set the height of the scrolled window.
2112     //
2113     XtVaSetValues (this->scrolledInputForm, XmNheight, 5+(PIXELS_PER_LINE*visible), NULL);
2114 
2115     Dimension oldHeight, newHeight;
2116     int vis = visible > MAX_INITIAL_BUTTONS ?
2117 		MAX_INITIAL_BUTTONS : visible < 1 ? 1 : visible;
2118 
2119     newHeight = 5+(vis*PIXELS_PER_LINE);
2120     XtVaGetValues (this->inputScroller, XmNheight, &oldHeight, NULL);
2121 
2122     Dimension ifh;
2123     int d = ((int)newHeight) - oldHeight;
2124 
2125     XtVaGetValues(this->inputForm, XmNheight, &ifh, NULL);
2126     XtVaSetValues(this->inputForm, XmNheight, ifh+d, NULL);
2127     XtVaSetValues(this->inputScroller, XmNheight, newHeight, NULL);
2128 
2129     Widget cw;
2130     Dimension fWidth, isWidth, cwWidth;
2131 
2132     XtVaGetValues(this->inputScroller,
2133 	    XmNwidth, &isWidth,
2134 	    XmNclipWindow, &cw,
2135 	    NULL);
2136 
2137     XtVaGetValues(cw, XmNwidth, &cwWidth, NULL);
2138     XtVaGetValues(this->scrolledInputForm, XmNwidth, &fWidth, NULL);
2139 
2140     d = (fWidth - cwWidth) + 10;
2141     if (d > 0)
2142     {
2143 	Dimension iWidth;
2144 	XtVaGetValues(this->inputForm, XmNwidth, &iWidth, NULL);
2145 	XtVaSetValues(this->inputForm, XmNwidth, iWidth+d, NULL);
2146 	XtVaGetValues(this->inputForm, XmNwidth, &iWidth, NULL);
2147 	XtVaSetValues(cw, XmNwidth, cwWidth+d, NULL);
2148 	XtVaGetValues(cw, XmNwidth, &cwWidth, NULL);
2149 	XtVaSetValues(this->inputScroller, XmNwidth, isWidth+d, NULL);
2150 	XtVaGetValues(this->inputScroller, XmNwidth, &isWidth, NULL);
2151     }
2152 }
2153 
2154 void
unmanage()2155 ConfigurationDialog::unmanage()
2156 {
2157     if (this->descriptionDialog)
2158 	this->descriptionDialog->unmanage();
2159     this->Dialog::unmanage();
2160 }
2161 void
manage()2162 ConfigurationDialog::manage()
2163 {
2164     this->restoreCallback(this);
2165     this->Dialog::manage();
2166 }
2167 //
2168 // Install the default resources for this class.
2169 //
installDefaultResources(Widget baseWidget)2170 void ConfigurationDialog::installDefaultResources(Widget  baseWidget)
2171 {
2172     this->setDefaultResources(baseWidget,ConfigurationDialog::DefaultResources);
2173     this->Dialog::installDefaultResources( baseWidget);
2174 }
getHelpSyntaxString()2175 const char *ConfigurationDialog::getHelpSyntaxString()
2176 {
2177     if (ConfigurationDialog::HelpText == 0) {
2178 	char *nosup = "No Syntax Help Available";
2179 	const char *dxroot = theDXApplication->getUIRoot();
2180 	if (!dxroot) {
2181 	    ConfigurationDialog::HelpText = new char[1+strlen(nosup)];
2182 	    strcpy (ConfigurationDialog::HelpText, nosup);
2183 	    return ConfigurationDialog::HelpText;
2184 	}
2185 
2186 	char supfile[1024];
2187 	sprintf(supfile,"%s/ui/syntax.txt",dxroot);
2188 	FILE *fp;
2189 	int helpsize;
2190 
2191 	struct STATSTRUCT buf;
2192 
2193 	if (STATFUNC(supfile, &buf) != 0) {
2194 	    ConfigurationDialog::HelpText = new char[1+strlen(nosup)];
2195 	    strcpy (ConfigurationDialog::HelpText, nosup);
2196 	    return ConfigurationDialog::HelpText;
2197 	}
2198 	helpsize = buf.st_size;
2199 
2200 	if (!(fp = fopen(supfile,"r")))
2201 	    return nosup;
2202 
2203 	char *helpstr = new char[helpsize + 30];
2204 	if (!helpstr) return nosup;
2205 	fread(helpstr,1,helpsize,fp);
2206 	fclose(fp);
2207 	helpstr[helpsize] = '\0'; // Null ternimate string
2208 	ConfigurationDialog::HelpText = helpstr;
2209     }
2210     return ConfigurationDialog::HelpText;
2211 }
2212 
2213