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 
13 
14 #include <sys/types.h>
15 #include <time.h>
16 #include <sys/stat.h>
17 #if defined(HAVE_UNISTD_H)
18 #include <unistd.h>
19 #endif
20 
21 
22 #include "GridChoice.h"
23 #include "GARApplication.h"
24 #include "ToggleButtonInterface.h"
25 #include "NoUndoChoiceCommand.h"
26 #include "GARChooserWindow.h"
27 #include "GARMainWindow.h"
28 #include "WarningDialogManager.h"
29 #include "ErrorDialogManager.h"
30 
31 #include <Xm/Xm.h>
32 #include <Xm/Label.h>
33 #include <Xm/Form.h>
34 #include <Xm/Separator.h>
35 #include <Xm/RowColumn.h>
36 #include "../widgets/Stepper.h"
37 
38 #include "grid1.bm"
39 #include "grid2.bm"
40 #include "grid3.bm"
41 #include "grid4.bm"
42 
43 boolean GridChoice::ClassInitialized = FALSE;
44 
45 String GridChoice::DefaultResources[] = {
46     "*smdForm*Offset:				10",
47     "*smdForm*XmToggleButton.shadowThickness: 	0",
48     "*smdForm*XmRowColumn.orientation:		XmHORIZONTAL",
49     "*smdForm*titleLabel.labelString: 		Description of your data",
50     "*smdForm*gridType.labelString: 		Grid type",
51     "*smdForm*numVarLabel.labelString:		Number of variables",
52     "*smdForm*numVarLabel.leftOffset:		30",
53     "*smdForm*dimensionLabel.labelString:	Dimension:",
54     "*smdForm*dimensionLabel.topOffset:		12",
55     "*smdForm*dimensionStepper.topOffset:	12",
56     "*smdForm*singleTimeStep.labelString:	Single time step",
57     "*smdForm*dataOrg.topOffset:		13",
58     "*smdForm*dataOrg.labelString:		Data organization:",
59     "*smdForm*dataOrg.leftOffset:		30",
60     "*smdForm*blockRB.marginRight:		30",
61     "*smdForm*blockRB.labelString:		Block",
62     "*smdForm*spreadsheetRB.labelString:	Columnar",
63 
64     "*gridRadio.orientation:			XmHORIZONTAL",
65     "*gridRadio.spacing:			40",
66     "*positionsOption.labelString:		Positions in data file",
67     "*notebook*positionsOption.indicatorType:	XmN_OF_MANY",
68     "*notebook*singleTimeStep.indicatorType:	XmN_OF_MANY",
69 
70     "*accelerators:             		#augment\n"
71     "<Key>Return:                 		BulletinBoardReturn()",
72 
73     NUL(char*)
74 };
75 
GridChoice(GARChooserWindow * gcw,Symbol sym)76 GridChoice::GridChoice (GARChooserWindow *gcw, Symbol sym) :
77     NonimportableChoice ("griddedData", TRUE, TRUE, TRUE, TRUE, gcw, sym)
78 {
79     this->dimension_l = NUL(Widget);
80     this->dimension_s = NUL(Widget);
81     this->data_org_l = NUL(Widget);
82     this->data_org_rb = NUL(Widget);
83 
84     this->recursive = FALSE;
85 
86     this->gridTypeCmd =
87 	new NoUndoChoiceCommand ("gridType", this->getCommandScope(),
88 	    TRUE, this, NoUndoChoiceCommand::SetGridType);
89 
90     this->positionsCmd =
91 	new NoUndoChoiceCommand ("positions", this->getCommandScope(),
92 	    TRUE, this, NoUndoChoiceCommand::Positions);
93 
94     this->positions_was_on = FALSE;
95 }
96 
~GridChoice()97 GridChoice::~GridChoice()
98 {
99     if (this->gridTypeCmd) delete this->gridTypeCmd;
100     if (this->positionsCmd) delete this->positionsCmd;
101 }
102 
initialize()103 void GridChoice::initialize()
104 {
105     if (GridChoice::ClassInitialized) return ;
106     GridChoice::ClassInitialized = TRUE;
107 
108     this->setDefaultResources
109 	(theApplication->getRootWidget(), TypeChoice::DefaultResources);
110     this->setDefaultResources
111 	(theApplication->getRootWidget(), NonimportableChoice::DefaultResources);
112     this->setDefaultResources
113 	(theApplication->getRootWidget(), GridChoice::DefaultResources);
114 }
115 
116 
createBody(Widget parent,Widget top)117 Widget GridChoice::createBody (Widget parent, Widget top)
118 {
119     Widget smd_form =
120 	XtVaCreateManagedWidget("smdForm",
121 	    xmFormWidgetClass, 	parent,
122 	    XmNtopAttachment,	(top?XmATTACH_WIDGET:XmATTACH_FORM),
123 	    XmNtopWidget,	top,
124 	    XmNtopOffset,	(top?0:2),
125 	    XmNleftAttachment,	XmATTACH_FORM,
126 	    XmNleftOffset,	2,
127 	NULL);
128 
129     Display *d = XtDisplay(smd_form);
130     Window win = XtWindow(theApplication->getRootWidget());
131     Pixel bg, fg, bs;
132     int depth;
133 
134     XtVaGetValues(smd_form,
135 	XmNforeground, &fg,
136 	XmNbackground, &bg,
137 	XmNdepth,	&depth,
138 	XmNbottomShadowColor, &bs,
139     NULL);
140 
141 
142     Widget label2 =
143 	XtVaCreateManagedWidget("gridType", xmLabelWidgetClass, smd_form,
144 	    XmNtopAttachment,	XmATTACH_FORM,
145 	    XmNtopOffset,	21,
146 	    XmNleftAttachment,	XmATTACH_FORM,
147 	NULL);
148 
149     Widget radioBox = XmCreateRadioBox (smd_form, "gridRadio", NULL, 0);
150     XtManageChild (radioBox);
151     XtVaSetValues (radioBox,
152 	XmNtopAttachment,	XmATTACH_FORM,
153 	XmNleftAttachment,	XmATTACH_WIDGET,
154 	XmNleftWidget,		label2,
155     NULL);
156 
157     //
158     // G R I D   T Y P E   1
159     //
160     Pixmap pix = XCreatePixmapFromBitmapData(
161 	d, win, (char *)grid1_bits, grid1_width, grid1_height,
162 	fg, bg, depth);
163     Pixmap sel_pix = XCreatePixmapFromBitmapData(
164 	d, win, (char *)grid1_bits, grid1_width, grid1_height,
165 	fg, bs, depth);
166     this->grid1Option =
167 	new ToggleButtonInterface (radioBox, "grid1Option", this->gridTypeCmd,
168 	    TRUE, "Regular grid: data-point specified by origin-delta pairs");
169     XtVaSetValues (this->grid1Option->getRootWidget(),
170 	XmNindicatorOn,		False,
171 	XmNlabelType,		XmPIXMAP,
172 	XmNlabelPixmap,		pix,
173 	XmNselectPixmap,	sel_pix,
174 	XmNshadowThickness, 	1,
175 	XmNspacing,		0,
176 	XmNmarginLeft,		0,
177 	XmNmarginRight,		0,
178 	XmNfillOnSelect,	True,
179 	XmNselectColor,		bs,
180     NULL);
181 
182     //
183     // G R I D   T Y P E   2
184     //
185     pix = XCreatePixmapFromBitmapData(
186 	d, win, (char *)grid2_bits, grid2_width, grid2_height,
187 	fg, bg, depth);
188     sel_pix = XCreatePixmapFromBitmapData(
189 	d, win, (char *)grid2_bits, grid2_width, grid2_height,
190 	fg, bs, depth);
191     this->grid2Option =
192 	new ToggleButtonInterface (radioBox, "grid2Option", this->gridTypeCmd,
193 	    FALSE, "Partly regular: dimension(s) not describable by origin-delta pair");
194     XtVaSetValues (this->grid2Option->getRootWidget(),
195 	XmNindicatorOn,		False,
196 	XmNlabelType,		XmPIXMAP,
197 	XmNlabelPixmap,		pix,
198 	XmNselectPixmap,	sel_pix,
199 	XmNshadowThickness, 	1,
200 	XmNspacing,		0,
201 	XmNmarginLeft,		0,
202 	XmNmarginRight,		0,
203 	XmNfillOnSelect,	True,
204 	XmNselectColor,		bs,
205     NULL);
206 
207     //
208     // G R I D   T Y P E   3
209     //
210     pix = XCreatePixmapFromBitmapData(
211 	d, win, (char *)grid3_bits, grid3_width, grid3_height,
212 	fg, bg, depth);
213     sel_pix = XCreatePixmapFromBitmapData(
214 	d, win, (char *)grid3_bits, grid3_width, grid3_height,
215 	fg, bs, depth);
216     this->grid3Option =
217 	new ToggleButtonInterface (radioBox, "grid3Option", this->gridTypeCmd,
218 	    FALSE, "Warped regular grid: specify each position explicitly");
219     XtVaSetValues (this->grid3Option->getRootWidget(),
220 	XmNindicatorOn,		False,
221 	XmNlabelType,		XmPIXMAP,
222 	XmNlabelPixmap,		pix,
223 	XmNselectPixmap,	sel_pix,
224 	XmNshadowThickness, 	1,
225 	XmNspacing,		0,
226 	XmNmarginLeft,		0,
227 	XmNmarginRight,		0,
228 	XmNfillOnSelect,	True,
229 	XmNselectColor,		bs,
230     NULL);
231 
232     //
233     // G R I D   T Y P E   4
234     //
235     pix = XCreatePixmapFromBitmapData(
236 	d, win, (char *)grid4_bits, grid4_width, grid4_height,
237 	fg, bg, depth);
238     sel_pix = XCreatePixmapFromBitmapData(
239 	d, win, (char *)grid4_bits, grid4_width, grid4_height,
240 	fg, bs, depth);
241     this->grid4Option =
242 	new ToggleButtonInterface (radioBox, "grid4Option", this->gridTypeCmd,
243 	    FALSE, "Scattered data: no connections between data points");
244     XtVaSetValues (this->grid4Option->getRootWidget(),
245 	XmNindicatorOn,		False,
246 	XmNlabelType,		XmPIXMAP,
247 	XmNlabelPixmap,		pix,
248 	XmNselectPixmap,	sel_pix,
249 	XmNshadowThickness, 	1,
250 	XmNspacing,		0,
251 	XmNmarginLeft,		0,
252 	XmNmarginRight,		0,
253 	XmNfillOnSelect,	True,
254 	XmNselectColor,		bs,
255     NULL);
256 
257     this->number_var_l =
258 	XtVaCreateManagedWidget("numVarLabel",
259 		xmLabelWidgetClass,     smd_form,
260 		XmNleftAttachment,	XmATTACH_FORM,
261 		XmNtopAttachment,	XmATTACH_WIDGET,
262 		XmNtopWidget,		radioBox,
263 		NULL);
264     this->number_var_s =
265 	XtVaCreateManagedWidget("numVarStepper",
266 		xmStepperWidgetClass,   smd_form,
267 		XmNleftAttachment,	XmATTACH_POSITION,
268 		XmNleftPosition,	50,
269 		XmNtopAttachment,	XmATTACH_WIDGET,
270 		XmNtopWidget,		radioBox,
271 		XmNiMinimum,		1,
272 		XmNiMaximum,		1000,
273 		XmNiValueStep,		1,
274 		XmNiValue,		1,
275 		NULL);
276 
277     this->positionsOption =
278 	new ToggleButtonInterface (smd_form, "positionsOption", this->positionsCmd,
279 	    FALSE, "Does your data look like this: x1,y1,data1; x2,y2,data2; ...?");
280     XtVaSetValues (this->positionsOption->getRootWidget(),
281 	XmNleftAttachment,	XmATTACH_FORM,
282 	XmNtopAttachment,	XmATTACH_WIDGET,
283 	XmNtopWidget,		this->number_var_s,
284     NULL);
285 
286     this->dimension_l =
287 	XtVaCreateWidget("dimensionLabel",
288 		xmLabelWidgetClass,     smd_form,
289 		XmNleftAttachment,	XmATTACH_POSITION,
290 		XmNleftPosition,	50,
291 		XmNtopAttachment,	XmATTACH_WIDGET,
292 		XmNtopWidget,		this->number_var_s,
293 		NULL);
294     this->dimension_s =
295 	XtVaCreateWidget("dimensionStepper",
296 		xmStepperWidgetClass,   smd_form,
297 		XmNleftAttachment,	XmATTACH_WIDGET,
298 		XmNleftWidget,		this->dimension_l,
299 		XmNtopAttachment,	XmATTACH_WIDGET,
300 		XmNtopWidget,		this->number_var_s,
301 		XmNiMinimum,		1,
302 		XmNiMaximum,		4,
303 		XmNiValueStep,		1,
304 		XmNiValue,		3,
305 		NULL);
306     this->singleTimeStepOption =
307 	new ToggleButtonInterface (smd_form, "singleTimeStep", this->gcw->getNullCmd(),
308 	    TRUE, "Does your data contain only one time step?");
309     XtVaSetValues (this->singleTimeStepOption->getRootWidget(),
310 	XmNleftAttachment,	XmATTACH_FORM,
311 	XmNtopAttachment,	XmATTACH_WIDGET,
312 	XmNtopWidget,		this->positionsOption->getRootWidget(),
313     NULL);
314 
315     this->data_org_l =
316 	XtVaCreateManagedWidget("dataOrg",
317 		xmLabelWidgetClass,     smd_form,
318 		XmNleftAttachment,	XmATTACH_FORM,
319 		XmNtopAttachment,	XmATTACH_WIDGET,
320 		XmNtopWidget,		this->singleTimeStepOption->getRootWidget(),
321 		NULL);
322     this->data_org_rb =
323 	XmCreateRadioBox(smd_form, "data_org_rb", NULL, 0);
324     XtVaSetValues(this->data_org_rb,
325 		XmNleftAttachment,	XmATTACH_POSITION,
326 		XmNleftPosition,	50,
327 		XmNtopAttachment,	XmATTACH_WIDGET,
328 		XmNtopWidget,		this->singleTimeStepOption->getRootWidget(),
329 		XmNmarginWidth,		0,
330 #ifndef OS2
331 		XmNpacking,		XmPACK_TIGHT,
332 #else
333                 XmNorientation,         XmHORIZONTAL,
334 #endif
335 		NULL);
336     XtManageChild(this->data_org_rb);
337 
338     this->blockOption = new ToggleButtonInterface
339 	(this->data_org_rb, "blockRB", this->gcw->getNullCmd(), TRUE,
340 	"Data Interleaving:      t[1], t[2], ..., t[n],         p[1], p[2], ..., p[n]");
341 
342     this->spreadSheetOption = new ToggleButtonInterface
343 	(this->data_org_rb, "spreadsheetRB", this->gcw->getNullCmd(), FALSE,
344 	"Data Interleaving:      t[1],p[1]     t[2],p[2]     ...     t[n],p[n]");
345 
346     return smd_form;
347 }
348 
prompter()349 boolean GridChoice::prompter()
350 {
351     unsigned long mode = 0;
352     mode = GMW_FULL;
353 
354     GARMainWindow *gmw = theGARApplication->getMainWindow();
355     if (gmw) {
356 	Command *fullCmd = gmw->getFullCmd();
357 	if ((gmw->isManaged()) && (fullCmd->isActive()))
358 	    fullCmd->execute();
359     }
360 
361 
362     if (this->grid4Option->getState())
363 	    mode |= GMW_POINTS;
364 
365     if (!this->singleTimeStepOption->getState())
366 	mode |= GMW_SERIES;
367 
368     if (this->spreadSheetOption->getState())
369 	mode |= GMW_SPREADSHEET;
370     gmw = theGARApplication->getMainWindow();
371     if (!gmw) {
372 	theGARApplication->postMainWindow(mode);
373 	gmw = theGARApplication->getMainWindow();
374     } else {
375 	gmw->newGAR(mode);
376 	gmw->manage();
377     }
378     ASSERT(gmw);
379 
380 
381     if (this->positionsOption->getState()) {
382 	int dim;
383 	XtVaGetValues(this->dimension_s, XmNiValue, &dim, NULL);
384 	char structure[256];
385 	sprintf(structure, "%d-vector", dim);
386 	gmw->addField("locations", structure);
387     }
388 
389     //
390     // Add the variables
391     //
392     int i, vars;
393     XtVaGetValues(this->number_var_s, XmNiValue, &vars, NULL);
394     for(i = 0; i < vars; i++)
395     {
396 	char fieldname[256];
397 	sprintf(fieldname, "field%d", i);
398 	gmw->addField(fieldname, "scalar");
399     }
400     return TRUE;
401 }
402 
simplePrompter()403 boolean GridChoice::simplePrompter()
404 {
405     unsigned long mode = 0;
406     GARMainWindow *gmw = theGARApplication->getMainWindow();
407     if (gmw) {
408 	theGARApplication->mainWindow = NUL(GARMainWindow*);
409 	delete gmw;
410 	gmw = NUL(GARMainWindow*);
411     }
412 
413     if (!this->singleTimeStepOption->getState()) {
414        if (this->grid4Option->getState())
415  	  mode = GMW_FULL | GMW_SERIES | GMW_POINTS;
416        else
417  	  mode = GMW_FULL | GMW_SERIES;
418     } else if (this->grid1Option->getState()) {
419 	    mode = GMW_GRID | GMW_POSITIONS | GMW_SIMP_POSITIONS;
420     } else if (this->grid2Option->getState()) {
421 	    mode = GMW_GRID | GMW_POSITIONS | GMW_POSITION_LIST;
422     }
423     else if (this->grid3Option->getState()) {
424 	    mode = GMW_GRID;
425     }
426     else if (this->grid4Option->getState()) {
427        if (this->positionsOption->getState())
428 	    mode = GMW_POINTS;
429        else
430 	    mode |= (GMW_POINTS | GMW_POSITIONS);
431     }
432 
433     if (this->spreadSheetOption->getState())
434 	mode |= GMW_SPREADSHEET;
435 
436     if (this->positionsOption->getState()) {
437 	//
438 	// Turn off the positions section
439 	//
440 	mode &= ~(GMW_POSITIONS | GMW_SIMP_POSITIONS);
441     }
442 
443 
444     theGARApplication->postMainWindow(mode);
445     gmw = theGARApplication->getMainWindow();
446     ASSERT(gmw);
447 
448 
449     if (this->positionsOption->getState()) {
450 	int dim;
451 	XtVaGetValues(this->dimension_s, XmNiValue, &dim, NULL);
452 	char structure[256];
453 	sprintf(structure, "%d-vector", dim);
454 	gmw->addField("locations", structure);
455     }
456 
457     //
458     // Add the variables
459     //
460     int i, vars;
461     XtVaGetValues(this->number_var_s, XmNiValue, &vars, NULL);
462     for(i = 0; i < vars; i++)
463     {
464 	char fieldname[256];
465 	sprintf(fieldname, "field%d", i);
466 	gmw->addField(fieldname, "scalar");
467     }
468     return TRUE;
469 }
470 
471 
472 
473 
usePositions()474 boolean GridChoice::usePositions()
475 {
476     if (this->grid4Option->getState())
477 	this->positions_was_on = this->positionsOption->getState();
478     if (this->positionsOption->getState()) {
479 	XtManageChild (this->dimension_l);
480 	XtManageChild (this->dimension_s);
481     } else {
482 	XtUnmanageChild (this->dimension_l);
483 	XtUnmanageChild (this->dimension_s);
484     }
485     return TRUE;
486 }
487 
488 
489 
490 
setGridType()491 boolean GridChoice::setGridType()
492 {
493     this->setCommandActivation();
494     return this->usePositions();
495 }
496 
497 
498 //
499 // file_checked means that the caller has looked for the file and found
500 // that is exists.
501 //
setCommandActivation(boolean file_checked)502 void GridChoice::setCommandActivation(boolean file_checked)
503 {
504 boolean file_ready = FALSE;
505 char* fname = NUL(char*);
506 
507     if (this->recursive) return ;
508 
509     boolean is_general;
510     char *gen_ext = ".general";
511     int gen_len = strlen(gen_ext);
512     char *general_file = NUL(char*);
513 
514     //
515     // Does the text widget at the top contain a valid data file name?
516     //
517     if (!file_checked) {
518 	const char *cp = this->gcw->getDataFilename();
519 	if ((cp) && (cp[0])) {
520 	    const char *file_name = fname =
521 		theGARApplication->resolvePathName(cp, this->getFileExtension());
522 	    if (file_name) {
523 		file_ready = TRUE;
524 		int len = strlen(cp);
525 		if (len > gen_len) {
526 		    is_general = (strcmp (gen_ext, &cp[len-gen_len]) == 0);
527 		    general_file = DuplicateString(file_name);
528 		    if (is_general) {
529 			this->recursive = TRUE;
530 			theGARApplication->openGeneralFile(general_file);
531 			this->recursive = FALSE;
532 		    }
533 		}
534 	    }
535 	}
536     } else
537 	file_ready = TRUE;
538 
539     char msg[128];
540     GARMainWindow *gmw = theGARApplication->getMainWindow();
541     if (file_ready) {
542         if (this->isBrowsable()) {
543             this->browseCmd->activate();
544         } else {
545             sprintf (msg, "The file is available but is not ascii.");
546             this->browseCmd->deactivate(msg);
547         }
548         if (this->isTestable()) {
549             if ((!gmw) || (theGARApplication->isDirty() == TRUE)) {
550                 if (!gmw)
551                     sprintf (msg,
552 		       "You must create a .general file, first.  Use the full prompter.");
553                 else
554                     sprintf (msg,
555 			"You must save the .general file you have already started.");
556                 this->verifyDataCmd->deactivate(msg);
557             } else {
558                 this->verifyDataCmd->activate();
559             }
560         } else {
561             sprintf (msg, "Only files which the import module can read can be tested.");
562             this->verifyDataCmd->deactivate(msg);
563         }
564 
565         if (this->visualizable) {
566             if  ((!gmw) || (theGARApplication->isDirty() == TRUE)) {
567                 if (!gmw)
568                     sprintf (msg,
569 		       "You must create a .general file, first.  Use the full prompter.");
570                 else
571                     sprintf (msg,
572 			"You must save the .general file you have already started.");
573                 this->visualizeCmd->deactivate(msg);
574             } else {
575 		this->visualizeCmd->activate();
576             }
577         } else {
578             sprintf (msg, "Only files which the import module can read can be tested.");
579             this->visualizeCmd->deactivate(msg);
580         }
581 	//
582 	// If the file changed, then toss out net_to_run
583 	//
584 	ASSERT(fname);
585 
586 	boolean file_changed = theGARApplication->isDirty();
587 	if (!this->previous_data_file)
588 	    file_changed = TRUE;
589 	else if (!EqualString (this->previous_data_file, fname))
590 	    file_changed = TRUE;
591 
592 	if (file_changed) {
593 	    if (this->net_to_run) delete this->net_to_run;
594 	    this->net_to_run = NUL(char*);
595 	    if (this->previous_data_file) delete this->previous_data_file;
596 	    this->previous_data_file = NUL(char*);
597 	}
598     } else {
599 	if (this->net_to_run) {
600 	    delete this->net_to_run;
601 	    this->net_to_run = NUL(char*);
602 	    if (this->previous_data_file) delete this->previous_data_file;
603 	    this->previous_data_file = NUL(char*);
604 	}
605 
606 	if (this->isBrowsable())
607 	    this->browseCmd->deactivate ("You must specify a data file name, first.");
608 	if (this->isTestable())
609 	    this->verifyDataCmd->deactivate ("You must specify a data file name, first.");
610 	if (this->isVisualizable())
611 	    this->visualizeCmd->deactivate ("You must specify a data file name, first.");
612     }
613 
614     if ((this->grid1Option->getState()) || (this->grid2Option->getState())) {
615 	this->positionsOption->setState (FALSE, TRUE);
616 	this->positionsCmd->deactivate("Used only for warped-regular or scattered data");
617     } else if (this->grid3Option->getState()) {
618 	this->positionsOption->setState (TRUE, TRUE);
619 	this->positionsCmd->deactivate("Your data must look like this: x1,y1,data1; x2,y2,data2; ...");
620     } else {
621 	this->positionsOption->setState (this->positions_was_on, TRUE);
622 	this->positionsCmd->activate();
623     }
624 
625     if (fname) {
626 	if (this->previous_data_file) delete this->previous_data_file;
627 	this->previous_data_file = DuplicateString(fname);
628 	delete fname;
629     }
630 
631 }
632 
verify(const char * seek)633 boolean GridChoice::verify(const char *seek)
634 {
635     //
636     // Before doing anything, check for a filename.  Normally, the visualize,
637     // and verify buttons are grey if there isn't a .general file to work on
638     // however, if the user presses File/New, then the prompter is clean and
639     // has no file.  If that's the case, then just issue an error.
640     //
641     GARMainWindow *gmw = theGARApplication->getMainWindow();
642     ASSERT(gmw);
643     const char *cp = gmw->getFilename();
644     if ((!cp) || (!cp[0])) {
645 	ErrorMessage("You must save a valid general file, first.");
646 	return FALSE;
647     }
648 
649     if (!this->connect(TypeChoice::ImageMode)) return FALSE;
650     const char *net_dir = theGARApplication->getResourcesNetDir();
651     char net_file[512];
652     sprintf (net_file, "%s/ui/decision.net", net_dir);
653     DXLConnection* conn = this->gcw->getConnection();
654     DXLLoadVisualProgram (conn, net_file);
655 
656     DXLSetString (conn, "test_file", cp);
657     DXLSetString (conn, "test_format", this->getImportType());
658     if (!seek) {
659         DXLSetValue (conn, "DescribeOrVisualize", "2");
660 	//
661 	// Commented out because wer're in ImageMode and dxui will get the
662 	// messages. They won't be shipped here.
663         //this->gcw->showMessages();
664     } else {
665         DXLSetValue (conn, "DescribeOrVisualize", seek);
666     }
667 
668     DXLExecuteOnce (conn);
669 
670     return TRUE;
671 }
672 
673 
674 //
675 // Decision tree for picking a net to run:
676 //
visualize()677 boolean GridChoice::visualize()
678 {
679     char net_file[512];
680     const char *net_dir = theGARApplication->getResourcesNetDir();
681     if (!this->net_to_run) {
682         return this->verify("1");
683     }
684 
685     if (!this->connect(TypeChoice::ImageMode)) return FALSE;
686     DXLConnection* conn = this->gcw->getConnection();
687 
688     GARMainWindow *gmw = theGARApplication->getMainWindow();
689     ASSERT(gmw);
690 
691     sprintf (net_file, "%s/ui/%s", net_dir, this->net_to_run);
692     char *cp = GARApplication::FileFound(net_file, NUL(char*));
693     if ((cp) && (cp[0])) {
694         char* args[4];
695         args[0] = "_filename_";
696         args[1] = DuplicateString(gmw->getFilename());
697         args[2] = "_filetype_";
698         args[3] = DuplicateString(this->getImportType());
699         this->gcw->loadAndSet (conn, net_file, args, 4);
700         delete args[1];
701         delete args[3];
702         uiDXLOpenAllImages (conn);
703 
704         this->hideList();
705         DXLExecuteOnce(conn);
706         delete cp;
707         return TRUE;
708     } else {
709 	WarningMessage ("Could not find %s", net_file);
710 	return FALSE;
711     }
712 }
713 
714 
canHandle(const char * ext)715 boolean GridChoice::canHandle (const char *ext)
716 {
717     if ((!ext) || (!ext[0])) return FALSE;
718 
719     if (EqualString(ext, ".GENERAL")) return TRUE;
720     if (EqualString(ext, ".general")) return TRUE;
721 
722     return FALSE;
723 }
724 
retainsControl(const char * new_file)725 boolean GridChoice::retainsControl(const char* new_file)
726 {
727     GARMainWindow *gmw = theGARApplication->getMainWindow();
728     if (!gmw) return FALSE;
729     return TRUE;
730 }
731