1 // $Id: gc_file_dialogs.cpp,v 1.48 2011/03/08 19:22:00 bobgian Exp $
2
3 /*
4 Copyright 2002 Mary Kuhner, Jon Yamato, and Joseph Felsenstein
5
6 This software is distributed free of charge for non-commercial use
7 and is copyrighted. Of course, we do not guarantee that the software
8 works, and are not responsible for any damage you may cause or have.
9 */
10
11 #include <cassert>
12
13 #include "errhandling.h"
14 #include "gc_data.h"
15 #include "gc_datastore.h"
16 #include "gc_errhandling.h"
17 #include "gc_event_ids.h"
18 #include "gc_file.h"
19 #include "gc_file_dialogs.h"
20 #include "gc_layout.h"
21 #include "gc_loci_match.h"
22 #include "gc_phase_err.h"
23 #include "gc_pop_match.h"
24 #include "gc_strings.h"
25 #include "gc_strings_cmdfile.h"
26 #include "gc_strings_phase.h"
27 #include "gc_text_ctrl.h"
28
29 #include "giraffe32.xpm"
30 #include "tinyxml.h"
31
32 #include "wx/checkbox.h"
33 #include "wx/filedlg.h"
34 #include "wx/icon.h"
35 #include "wx/log.h"
36 #include "wx/sizer.h"
37 #include "wx/statline.h"
38
39 //------------------------------------------------------------------------------------
40
gcFullPath(size_t fileId)41 gcFullPath::gcFullPath(size_t fileId)
42 :
43 m_fileId(fileId)
44 {
45 }
46
~gcFullPath()47 gcFullPath::~gcFullPath()
48 {
49 }
50
51 wxString
FromDataStore(GCDataStore & dataStore)52 gcFullPath::FromDataStore(GCDataStore & dataStore)
53 {
54 return dataStore.GetDataFile(m_fileId).GetName();
55 }
56
57 //------------------------------------------------------------------------------------
58
gcParseInfoNone()59 gcParseInfoNone::gcParseInfoNone()
60 {
61 }
62
~gcParseInfoNone()63 gcParseInfoNone::~gcParseInfoNone()
64 {
65 }
66
67 wxString
FromDataStore(GCDataStore &)68 gcParseInfoNone::FromDataStore(GCDataStore &)
69 {
70 return gcstr::parseInfoNone;
71 }
72
73 //------------------------------------------------------------------------------------
74
gcParseInfoOne(size_t fileId)75 gcParseInfoOne::gcParseInfoOne(size_t fileId)
76 :
77 m_fileId(fileId)
78 {
79 }
80
~gcParseInfoOne()81 gcParseInfoOne::~gcParseInfoOne()
82 {
83 }
84
85 wxString
FromDataStore(GCDataStore & dataStore)86 gcParseInfoOne::FromDataStore(GCDataStore & dataStore)
87 {
88 const GCFile & fileRef = dataStore.GetDataFile(m_fileId);
89 const GCParse & parse = dataStore.GetParse(fileRef);
90 wxString parseInfo = parse.GetSettings();
91 return parseInfo;
92 }
93
94 //------------------------------------------------------------------------------------
95
gcParseChoice(size_t parseId)96 gcParseChoice::gcParseChoice(size_t parseId)
97 :
98 m_parseId(parseId),
99 m_box(NULL)
100 {
101 }
102
~gcParseChoice()103 gcParseChoice::~gcParseChoice()
104 {
105 }
106
107 #if 0 // Potentially DEAD CODE (bobgian, Feb 2010)
108
109 wxString
110 gcParseChoice::GetLabel(GCDataStore & dataStore)
111 {
112 const GCParse & parse = dataStore.GetParse(m_parseId);
113 wxString parseInfo = parse.GetSettings();
114 return parseInfo;
115 }
116
117 bool
118 gcParseChoice::GetEnabled(GCDataStore & dataStore)
119 {
120 return true;
121 }
122
123 bool
124 gcParseChoice::GetSelected(GCDataStore & dataStore)
125 {
126 const GCParse & thisParse = dataStore.GetParse(m_parseId);
127 const GCFile & fileRef = thisParse.GetFileRef();
128
129 if(dataStore.GetStructures().HasParse(fileRef))
130 {
131 const GCParse & assignedParse = dataStore.GetStructures().GetParse(fileRef);
132 return (assignedParse.GetId() == m_parseId);
133 }
134 }
135
136 void
137 gcParseChoice::SetSelected(GCDataStore & dataStore, bool selected)
138 {
139 }
140
141 #endif
142
143 void
UpdateDisplayInitial(GCDataStore & dataStore)144 gcParseChoice::UpdateDisplayInitial(GCDataStore & dataStore)
145 {
146 assert(m_box != NULL);
147
148 // if it parsed, it's a legal choice
149 m_box->Enable(true);
150
151 // display settings next to check box
152 const GCParse & parse = dataStore.GetParse(m_parseId);
153 wxString parseInfo = parse.GetSettings();
154 m_box->SetLabel(parseInfo);
155
156 UpdateDisplayInterim(dataStore);
157 }
158
159 void
UpdateDisplayInterim(GCDataStore & dataStore)160 gcParseChoice::UpdateDisplayInterim(GCDataStore & dataStore)
161 {
162 assert(m_box != NULL);
163
164 const GCParse & thisParse = dataStore.GetParse(m_parseId);
165 const GCFile & fileRef = thisParse.GetFileRef();
166
167 if(dataStore.GetStructures().HasParse(fileRef))
168 {
169 const GCParse & assignedParse = dataStore.GetStructures().GetParse(fileRef);
170 if (assignedParse.GetId() == m_parseId)
171 {
172 m_box->SetValue(1);
173 return;
174 }
175 }
176
177 m_box->SetValue(0);
178 }
179
180 void
UpdateDataInterim(GCDataStore & dataStore)181 gcParseChoice::UpdateDataInterim(GCDataStore & dataStore)
182 {
183 int value = m_box->GetValue();
184 if(value > 0)
185 {
186 const GCParse & thisParse = dataStore.GetParse(m_parseId);
187 dataStore.GetStructures().SetParse(thisParse);
188 }
189 }
190
191 void
UpdateDataFinal(GCDataStore & dataStore)192 gcParseChoice::UpdateDataFinal(GCDataStore & dataStore)
193 {
194 UpdateDataInterim(dataStore);
195 }
196
197 wxWindow *
MakeWindow(wxWindow * parent)198 gcParseChoice::MakeWindow(wxWindow * parent)
199 {
200 m_box = new wxCheckBox(parent,-1,"");
201 return m_box;
202 }
203
204 wxWindow *
FetchWindow()205 gcParseChoice::FetchWindow()
206 {
207 return m_box;
208 }
209
210 size_t
GetRelevantId()211 gcParseChoice::GetRelevantId()
212 {
213 return m_parseId;
214 }
215
216 //------------------------------------------------------------------------------------
217
gcFileEditDialog(wxWindow * parent,GCDataStore & dataStore,size_t fileId)218 gcFileEditDialog::gcFileEditDialog( wxWindow * parent,
219 GCDataStore & dataStore,
220 size_t fileId)
221 :
222 gcUpdatingDialog( parent,
223 dataStore,
224 wxString::Format(gcstr::editFileSettings,
225 dataStore.GetDataFile(fileId).GetShortName().c_str()),
226 false),
227 // false value is because there is no such
228 // thing as a newborn, empty file
229 m_fileId(fileId)
230 {
231 }
232
~gcFileEditDialog()233 gcFileEditDialog::~gcFileEditDialog()
234 {
235 }
236
237 void
DoDelete()238 gcFileEditDialog::DoDelete()
239 {
240 m_dataStore.RemoveDataFile(m_dataStore.GetDataFile(m_fileId));
241 }
242
243 bool
DoDialogAddFiles(wxWindow * parentWindow,GCDataStore & dataStore)244 DoDialogAddFiles(wxWindow * parentWindow, GCDataStore & dataStore)
245 {
246 wxFileDialog dataFileDialog(parentWindow,
247 gcstr::dataFilesSelect,
248 wxEmptyString, // default directory == current
249 wxEmptyString, // default file = none
250 gcstr::dataFiles, // show .phy and .mig files
251 wxFD_OPEN | wxFD_CHANGE_DIR | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
252
253 dataFileDialog.SetIcon(wxICON(giraffe32));
254 bool producedResultWeShouldKeep = false;
255
256 std::vector<GCFile*> addedFiles;
257
258 if(dataFileDialog.ShowModal() == wxID_OK)
259 {
260 wxArrayString fullPathFileNames;
261 dataFileDialog.GetPaths(fullPathFileNames);
262 fullPathFileNames.Sort();
263 for(size_t fileIndex=0; fileIndex < fullPathFileNames.Count(); fileIndex++)
264 {
265 try
266 {
267 GCFile & fileRef = dataStore.AddDataFile(fullPathFileNames[fileIndex]);
268 producedResultWeShouldKeep = true;
269 addedFiles.push_back(&fileRef);
270 }
271 catch (const gc_ex& e)
272 {
273 dataStore.GCError(e.what());
274 }
275 }
276 }
277
278 #if 0 // Potentially DEAD CODE (bobgian, Feb 2010)
279 std::vector<GCFile*> suspiciousFiles;
280 for(size_t i = 0; i < addedFiles.size(); i++)
281 {
282 GCFile & fileRef = *(addedFiles[i]);
283 bool hasShortName = false;
284 for(size_t j = 0; j < fileRef.GetParseCount(); j++)
285 {
286 const GCParse & parseRef = fileRef.GetParse(j);
287 if(parseRef.GetHasSpacesInNames())
288 {
289 hasShortName = true;
290 }
291 }
292 if(hasShortName)
293 {
294 suspiciousFiles.push_back(&fileRef);
295 }
296 }
297
298 if(!suspiciousFiles.empty())
299 {
300 for(size_t i=0; i < suspiciousFiles.size(); i++)
301 {
302 wxLogDebug("short name file %s",suspiciousFiles[i]->GetName().c_str());
303 }
304 }
305 #endif
306
307 return producedResultWeShouldKeep;
308 }
309
310 //------------------------------------------------------------------------------------
311
gcHapDefaultChoice(size_t fileId)312 gcHapDefaultChoice::gcHapDefaultChoice(size_t fileId)
313 :
314 m_fileId(fileId)
315 {
316 }
317
~gcHapDefaultChoice()318 gcHapDefaultChoice::~gcHapDefaultChoice()
319 {
320 }
321
322 void
UpdateDisplayInitial(GCDataStore & dataStore)323 gcHapDefaultChoice::UpdateDisplayInitial(GCDataStore & dataStore)
324 {
325 UpdateDisplayInterim(dataStore);
326 }
327
328 void
UpdateDisplayInterim(GCDataStore & dataStore)329 gcHapDefaultChoice::UpdateDisplayInterim(GCDataStore & dataStore)
330 {
331 m_box->SetLabel(gcstr::hapFileDefault);
332 m_box->SetValue( dataStore.GetStructures().HasHapFileAdjacent(m_fileId) ? 0 : 1 );
333 }
334
335 void
UpdateDataInterim(GCDataStore & dataStore)336 gcHapDefaultChoice::UpdateDataInterim(GCDataStore & dataStore)
337 {
338 if(m_box->GetValue() > 0)
339 {
340 dataStore.GetStructures().UnsetHapFileAdjacent(m_fileId);
341 }
342 }
343
344 void
UpdateDataFinal(GCDataStore & dataStore)345 gcHapDefaultChoice::UpdateDataFinal(GCDataStore & dataStore)
346 {
347 UpdateDataInterim(dataStore);
348 }
349
350 wxWindow *
MakeWindow(wxWindow * parent)351 gcHapDefaultChoice::MakeWindow(wxWindow * parent)
352 {
353 m_box = new wxCheckBox(parent,-1,"");
354 return m_box;
355 }
356
357 wxWindow *
FetchWindow()358 gcHapDefaultChoice::FetchWindow()
359 {
360 return m_box;
361 }
362
363 size_t
GetRelevantId()364 gcHapDefaultChoice::GetRelevantId()
365 {
366 assert(false);
367 return 0;
368 }
369
370 //------------------------------------------------------------------------------------
371
gcHapAdjacentChoice(size_t fileId)372 gcHapAdjacentChoice::gcHapAdjacentChoice(size_t fileId)
373 :
374 m_fileId(fileId)
375 {
376 }
377
~gcHapAdjacentChoice()378 gcHapAdjacentChoice::~gcHapAdjacentChoice()
379 {
380 }
381
382 void
UpdateDisplayInitial(GCDataStore & dataStore)383 gcHapAdjacentChoice::UpdateDisplayInitial(GCDataStore & dataStore)
384 {
385 UpdateDisplayInterim(dataStore);
386 }
387
388 void
UpdateDisplayInterim(GCDataStore & dataStore)389 gcHapAdjacentChoice::UpdateDisplayInterim(GCDataStore & dataStore)
390 {
391 const GCStructures & structures = dataStore.GetStructures();
392
393 if(dataStore.FileInducesHaps(m_fileId))
394 {
395 m_box->SetValue(0);
396 m_panel->Enable(false);
397 }
398
399 if(structures.HasHapFileAdjacent(m_fileId))
400 {
401 m_box->SetValue(1);
402 m_text->SetValue(wxString::Format("%ld",(long)structures.GetHapFileAdjacent(m_fileId)));
403 }
404 else
405 {
406 m_box->SetValue(0);
407 }
408 }
409
410 void
UpdateDataInterim(GCDataStore & dataStore)411 gcHapAdjacentChoice::UpdateDataInterim(GCDataStore & dataStore)
412 {
413 if(m_box->GetValue() > 0)
414 {
415 wxString numHapsString = m_text->GetValue();
416 long numHaps;
417 if(numHapsString.ToLong(&numHaps) && (numHaps > 1))
418 {
419 dataStore.GetStructures().SetHapFileAdjacent(m_fileId,(size_t)numHaps);
420 }
421 else
422 {
423 throw gc_bad_ind_match_adjacency_value(numHapsString);
424 }
425 }
426 }
427
428 void
UpdateDataFinal(GCDataStore & dataStore)429 gcHapAdjacentChoice::UpdateDataFinal(GCDataStore & dataStore)
430 {
431 UpdateDataInterim(dataStore);
432 }
433
434 wxWindow *
MakeWindow(wxWindow * parent)435 gcHapAdjacentChoice::MakeWindow(wxWindow * parent)
436 {
437 m_panel = new wxPanel(parent,-1);
438 wxBoxSizer * sizer = new wxBoxSizer(wxHORIZONTAL);
439 m_box = new wxCheckBox(m_panel,-1,gcstr_phase::adjacentHaps1);
440 m_text = new GCNonNegativeIntegerInput(m_panel);
441 m_text->SetValue(wxString::Format("%ld",(long)(gcdata::defaultHapCount)));
442 wxStaticText * statText = new wxStaticText(m_panel,-1,gcstr_phase::adjacentHaps2);
443 sizer->Add(m_box);
444 sizer->Add(m_text);
445 sizer->Add(statText);
446 m_panel->SetSizerAndFit(sizer);
447 return m_panel;
448 }
449
450 wxWindow *
FetchWindow()451 gcHapAdjacentChoice::FetchWindow()
452 {
453 return m_box;
454 }
455
456 size_t
GetRelevantId()457 gcHapAdjacentChoice::GetRelevantId()
458 {
459 assert(false);
460 return 0;
461 }
462
463 //------------------------------------------------------------------------------------
464
465 #if 0 // Potentially DEAD CODE (bobgian, Feb 2010)
466
467 gcHapResolverChoice::gcHapResolverChoice(size_t fileId, size_t hapResolverId)
468 :
469 m_fileId(fileId),
470 m_hapResolverId(hapResolverId)
471 {
472 }
473
474 gcHapResolverChoice::~gcHapResolverChoice()
475 {
476 }
477
478 void
479 gcHapResolverChoice::UpdateDisplayInitial(GCDataStore & dataStore)
480 {
481
482 const gcHapResolver & hapResolver = dataStore.GetHapResolver(m_hapResolverId);
483 m_box->SetLabel(hapResolver.DisplayString());
484 UpdateDisplayInterim(dataStore);
485 }
486
487 void
488 gcHapResolverChoice::UpdateDisplayInterim(GCDataStore & dataStore)
489 {
490 const GCStructures & structures = dataStore.GetStructures();
491
492 int checkValue = 0;
493 if(structures.HasHapFile(m_fileId))
494 {
495 if(structures.GetHapFileId(m_fileId) == m_hapResolverId)
496 {
497 checkValue = 1;
498 }
499 }
500
501 m_box->SetValue(checkValue);
502 }
503
504 void
505 gcHapResolverChoice::UpdateDataInterim(GCDataStore & dataStore)
506 {
507 if(m_box->GetValue() > 0)
508 {
509 dataStore.GetStructures().SetHapFile(m_fileId,m_hapResolverId);
510 }
511 }
512
513 void
514 gcHapResolverChoice::UpdateDataFinal(GCDataStore & dataStore)
515 {
516 UpdateDataInterim(dataStore);
517 }
518
519 wxWindow *
520 gcHapResolverChoice::MakeWindow(wxWindow * parent)
521 {
522 m_box = new wxCheckBox(parent,-1,"");
523 return m_box;
524
525 }
526
527 wxWindow *
528 gcHapResolverChoice::FetchWindow()
529 {
530 return m_box;
531 }
532
533 size_t
534 gcHapResolverChoice::GetRelevantId()
535 {
536 assert(false);
537 return 0;
538 }
539
540 #endif
541
542 //------------------------------------------------------------------------------------
543
gcHapChoices(wxWindow * parent,GCDataStore & dataStore,size_t fileId,std::vector<gcChoiceObject * > choices)544 gcHapChoices::gcHapChoices( wxWindow * parent,
545 GCDataStore & dataStore,
546 size_t fileId,
547 std::vector<gcChoiceObject*> choices)
548 :
549 gcUpdatingChoose(parent,gcstr::chooseHapResolution,choices),
550 m_fileId(fileId)
551 {
552 }
553
~gcHapChoices()554 gcHapChoices::~gcHapChoices()
555 {
556 }
557
558 void
BuildDisplay(GCDataStore & dataStore)559 gcHapChoices::BuildDisplay(GCDataStore & dataStore)
560 {
561 gcUpdatingChoose::BuildDisplay(dataStore);
562 }
563
564 //------------------------------------------------------------------------------------
565
566 bool
DoDialogEditFile(wxWindow * parentWindow,GCDataStore & dataStore,size_t fileId)567 DoDialogEditFile(wxWindow * parentWindow, GCDataStore & dataStore, size_t fileId)
568 {
569 gcFileEditDialog dialog(parentWindow,dataStore,fileId);
570
571 // build the dialog
572 gcDialogCreator creator;
573 wxBoxSizer * contentSizer = new wxBoxSizer(wxVERTICAL);
574
575 // always give the full path name
576 gcPlainTextHelper * fullPathHelper = new gcFullPath(fileId);
577 gcUpdatingComponent * fullPath = new gcUpdatingPlainText(
578 &dialog,
579 gcstr::fullPath,
580 fullPathHelper);
581 contentSizer->Add(fullPath,
582 0,
583 wxALL | wxALIGN_CENTER | wxEXPAND ,
584 gclayout::borderSizeSmall);
585 creator.AddComponent(dialog,fullPath);
586
587 // always give the parse info, but what kind depends on if there
588 // were any choices
589 gcUpdatingComponent * parseInfo = NULL;
590 const GCFile & fileRef = dataStore.GetDataFile(fileId);
591 size_t numParses = fileRef.GetParseCount();
592
593 if(numParses == 0)
594 {
595 gcPlainTextHelper * parseNone = new gcParseInfoNone();
596 parseInfo = new gcUpdatingPlainText(&dialog,
597 gcstr::parseInfo,
598 parseNone);
599 }
600
601 if(numParses == 1)
602 {
603 gcPlainTextHelper * parseOne = new gcParseInfoOne(fileId);
604 parseInfo = new gcUpdatingPlainText(&dialog,
605 gcstr::parseInfo,
606 parseOne);
607 }
608
609 if(numParses > 1)
610 {
611 std::vector<gcChoiceObject*> parseChoices;
612 for(size_t index=0; index < numParses; index++)
613 {
614 const GCParse & parseRef = fileRef.GetParse(index);
615 gcParseChoice * choice = new gcParseChoice(parseRef.GetId());
616 parseChoices.push_back(choice);
617 }
618
619 parseInfo = new gcUpdatingChoose(&dialog,
620 gcstr::chooseOneParse,
621 parseChoices);
622 }
623
624 assert(parseInfo != NULL);
625 contentSizer->Add(parseInfo,
626 0,
627 wxALL | wxALIGN_CENTER | wxEXPAND ,
628 gclayout::borderSizeSmall);
629 creator.AddComponent(dialog,parseInfo);
630
631 ////////////////////////////////////////////
632 std::vector<gcChoiceObject*> hapChoiceVec;
633 hapChoiceVec.push_back(new gcHapDefaultChoice(fileId));
634 hapChoiceVec.push_back(new gcHapAdjacentChoice(fileId));
635
636 gcHapChoices * hapFileInfo = new gcHapChoices(&dialog,dataStore,fileId,hapChoiceVec);
637 contentSizer->Add(hapFileInfo,
638 1,
639 wxALL | wxALIGN_CENTER | wxEXPAND ,
640 gclayout::borderSizeSmall);
641 creator.AddComponent(dialog,hapFileInfo);
642
643 ////////////////////////////////////////////
644
645 creator.PlaceContent(dialog,contentSizer);
646
647 return dialog.Go();
648 }
649
650 bool
DoDialogExportFile(wxWindow * parentWindow,GCDataStore & dataStore)651 DoDialogExportFile(wxWindow * parentWindow, GCDataStore & dataStore)
652 {
653 try
654 {
655 TiXmlDocument * docPointer = dataStore.ExportFile();
656 wxString titleString = gcstr::dataFileExport;
657 #ifdef LAMARC_COMPILE_MACOSX
658 titleString += gcstr::saveFileInstructionsForMac;
659 #endif
660 wxFileDialog dataFileDialog( parentWindow,
661 titleString,
662 wxEmptyString, // current dir
663 dataStore.GetOutfileName(),
664 gcstr::exportFileGlob,
665 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
666 // don't wxFD_CHANGE_DIR -- it should be contextual
667 // based on operation, but since it's not, let's
668 // not change on export
669 if(dataFileDialog.ShowModal() == wxID_OK)
670 {
671 wxString fullPathFileName = dataFileDialog.GetPath();
672 dataStore.SetOutfileName(fullPathFileName);
673 dataStore.WriteExportedData(docPointer);
674 wxLogVerbose(gcverbose::exportSuccess,fullPathFileName.c_str());
675 return true;
676 }
677 }
678 catch(const gc_abandon_export& x)
679 {
680 // do nothing except interrupt;
681 }
682 catch(const gc_ex& g)
683 {
684 dataStore.GCError(g.what());
685 }
686 return false;
687 }
688
689 bool
DoDialogExportBatchFile(wxWindow * parentWindow,GCDataStore & dataStore)690 DoDialogExportBatchFile(wxWindow * parentWindow, GCDataStore & dataStore)
691 {
692 try
693 {
694 TiXmlDocument * docPointer = dataStore.ExportBatch();
695 wxString titleString = gcstr::dataFileBatchExport;
696 #ifdef LAMARC_COMPILE_MACOSX
697 titleString += gcstr::saveFileInstructionsForMac;
698 #endif
699 wxFileDialog batchFileDialog( parentWindow,
700 titleString,
701 wxEmptyString, // current dir
702 gcstr::batchFileDefault,
703 gcstr::exportFileGlob,
704 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
705 // don't wxFD_CHANGE_DIR -- it should be contextual
706 // based on operation, but since it's not, let's
707 // not change on export
708 if(batchFileDialog.ShowModal() == wxID_OK)
709 {
710 wxString fullPathFileName = batchFileDialog.GetPath();
711 dataStore.WriteBatchFile(docPointer,fullPathFileName);
712 delete docPointer;
713 return true;
714 }
715 }
716 catch(const gc_ex& g)
717 {
718 dataStore.GCError(g.what());
719 }
720 return false;
721 }
722
723 bool
DoDialogReadCmdFile(wxWindow * parentWindow,GCDataStore & dataStore)724 DoDialogReadCmdFile(wxWindow * parentWindow, GCDataStore & dataStore)
725 {
726 wxFileDialog cmdFileDialog(parentWindow,
727 gcstr_cmdfile::cmdFilesSelect,
728 wxEmptyString, // default directory == current
729 wxEmptyString, // default file = none
730 gcstr::xmlFiles, // files to display
731 wxFD_OPEN | wxFD_CHANGE_DIR | wxFD_FILE_MUST_EXIST );
732 // EWFIX.P3.BUG.524 -- add wxFD_MULTIPLE to add multiple files
733 // and use GetPaths instead of GetPath
734 bool producedResultWeShouldKeep = false;
735
736 if(cmdFileDialog.ShowModal() == wxID_OK)
737 {
738 #if 0 // EWFIX.P3.BUG.524
739 wxArrayString fullPathFileNames;
740 cmdFileDialog.GetPaths(fullPathFileNames);
741 fullPathFileNames.Sort();
742 for(size_t fileIndex=0; fileIndex < fullPathFileNames.Count(); fileIndex++)
743 {
744 wxString cmdFileName = fullPathFileNames[fileIndex];
745 #endif
746 wxString cmdFileName = cmdFileDialog.GetPath();
747 try
748 {
749 dataStore.ProcessCmdFile(cmdFileName);
750 producedResultWeShouldKeep = true;
751 }
752 catch(const gc_ex& e)
753 {
754 // EWFIX.P3 -- use file name
755 wxString msg = wxString::Format(gcerr_cmdfile::badCmdFile,
756 cmdFileName.c_str(),
757 e.what());
758 dataStore.GCError(msg);
759 }
760 catch(const data_error& e)
761 {
762 // EWFIX.P3 -- use file name
763 wxString msg = wxString::Format(gcerr_cmdfile::badCmdFile,
764 cmdFileName.c_str(),
765 e.what());
766 dataStore.GCError(msg);
767 }
768 #if 0 // EWFIX.P3.BUG.524
769 }
770 #endif
771 }
772 return producedResultWeShouldKeep;
773 }
774
775 //------------------------------------------------------------------------------------
776
777 bool
OperateOn(wxWindow * parent,GCDataStore & dataStore)778 gcActor_File_Edit::OperateOn(wxWindow * parent, GCDataStore & dataStore)
779 {
780 return DoDialogEditFile(parent,dataStore,m_fileId);
781 }
782
783 //____________________________________________________________________________________
784