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