r604: no message
[ctsim.git] / src / ctsim.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          ctsim.cpp
5 **   Purpose:       Top-level routines of CTSim program
6 **   Programmer:    Kevin Rosenberg
7 **   Date Started:  July 2000
8 **
9 **  This is part of the CTSim program
10 **  Copyright (c) 1983-2001 Kevin Rosenberg
11 **
12 **  $Id: ctsim.cpp,v 1.94 2001/03/04 22:30:19 kevin Exp $
13 **
14 **  This program is free software; you can redistribute it and/or modify
15 **  it under the terms of the GNU General Public License (version 2) as
16 **  published by the Free Software Foundation.
17 **
18 **  This program is distributed in the hope that it will be useful,
19 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 **  GNU General Public License for more details.
22 **
23 **  You should have received a copy of the GNU General Public License
24 **  along with this program; if not, write to the Free Software
25 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 ******************************************************************************/
27
28 #ifdef MSVC
29 #define strdup _strdup
30 #endif
31
32 #include "wx/wxprec.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #endif
37
38 #include "wx/image.h"
39 #include "wx/filesys.h"
40 #include "wx/fs_zip.h"
41 #ifdef __WXMSW__
42 #include "wx/msw/helpchm.h"
43 #endif
44
45 #if !wxUSE_DOC_VIEW_ARCHITECTURE
46 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
47 #endif
48
49
50 #include "ct.h"
51 #include "ctsim.h"
52 #include "docs.h"
53 #include "views.h"
54 #include "dialogs.h"
55 #include "tips.h"
56 #include "backgroundmgr.h"
57
58 #if defined(HAVE_CONFIG_H)
59 #include "config.h"
60 #endif
61
62 #if defined(HAVE_GETOPT_H) || defined(HAVE_GETOPT_LONG)
63 #ifdef MSVC
64 #define __STDC__ 1
65 #endif
66 #include "getopt.h"
67 #ifdef MSVC
68 #undef __STDC__
69 #endif
70 #endif
71
72 static const char* rcsindent = "$Id: ctsim.cpp,v 1.94 2001/03/04 22:30:19 kevin Exp $";
73
74 struct option CTSimApp::ctsimOptions[] = 
75 {
76   {"help", 0, 0, O_HELP},
77   {"version", 0, 0, O_VERSION},
78   {"print", 0, 0, O_PRINT},
79   {0, 0, 0, 0}
80 };
81
82 IMPLEMENT_APP(CTSimApp)
83
84 CTSimApp::CTSimApp()
85 :  m_bAdvancedOptions(false), m_bSetModifyNewDocs(true), m_bVerboseLogging(false), m_bShowStartupTips(true),
86 m_iCurrentTip(0), m_bUseBackgroundTasks(false),
87 m_docManager(NULL), m_pFrame(NULL), m_pLog(0),  m_pConfig(0), m_pLogDoc(0)
88 {
89   theApp = this;
90 }
91
92 #ifdef HAVE_SYS_TIME_H
93 #include <sys/time.h>
94 #endif
95
96 #ifdef HAVE_SYS_RESOURCE_H
97 #include <sys/resource.h>
98 #endif
99
100 bool
101 CTSimApp::OnInit()
102 {
103 #ifdef HAVE_SETPRIORITY
104   setpriority (PRIO_PROCESS, 0, 15);  // set to low scheduling priority
105 #endif
106   
107   openConfig();
108   
109   g_bRunningWXWindows = true;
110   bool bPrintFiles = false;
111   // process options
112   while (1) {
113     int c = getopt_long (argc, argv, "", ctsimOptions, NULL);
114     if (c == -1)
115       break;
116     
117     switch (c) {
118     case O_VERSION:
119       std::cout << rcsindent << std::endl;
120 #ifdef CTSIMVERSION
121       std::cout << "Version: CTSIMVERSION" << std::endl;
122 #elif defined(VERSION)
123       std::cout << "Version: VERSION" << std::endl;
124 #endif
125       exit(0);
126     case O_HELP:
127     case '?':
128       usage (argv[0]);
129       exit (0);
130     case O_PRINT:
131       bPrintFiles = true;
132       break;
133     default:
134       usage (argv[0]);
135       exit (1);
136     }
137   }
138   
139   m_docManager = new wxDocManager (wxDEFAULT_DOCMAN_FLAGS, true);
140   
141   m_pDocTemplImage = new wxDocTemplate (m_docManager, "ImageFile", "*.if", "", "if", "ImageFile", "ImageView", CLASSINFO(ImageFileDocument), CLASSINFO(ImageFileView));
142   m_pDocTemplProjection = new wxDocTemplate (m_docManager, "ProjectionFile", "*.pj", "", "pj", "ProjectionFile", "ProjectionView", CLASSINFO(ProjectionFileDocument), CLASSINFO(ProjectionFileView));
143   m_pDocTemplPhantom = new wxDocTemplate (m_docManager, "PhantomFile", "*.phm", "", "phm", "PhantomFile", "PhantomView", CLASSINFO(PhantomFileDocument), CLASSINFO(PhantomFileView));
144   m_pDocTemplPlot = new wxDocTemplate (m_docManager, "PlotFile", "*.plt", "", "plt", "PlotFile", "PlotView", CLASSINFO(PlotFileDocument), CLASSINFO(PlotFileView));
145   m_pDocTemplText = new wxDocTemplate (m_docManager, "TextFile", "*.txt", "", "txt", "TextFile", "TextView", CLASSINFO(TextFileDocument), CLASSINFO(TextFileView), wxTEMPLATE_INVISIBLE);
146 #if wxUSE_GLCANVAS
147   m_pDocTemplGraph3d = new wxDocTemplate (m_docManager, "Graph3dFile", "*.g3d", "", "g3d", "Graph3dFile", "Graph3dView", CLASSINFO(Graph3dFileDocument), CLASSINFO(Graph3dFileView), wxTEMPLATE_INVISIBLE);
148 #endif
149   
150 #if wxUSE_GIF
151   wxImage::AddHandler(new wxGIFHandler);     // Required for images in the online documentation
152 #endif
153   
154 #if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
155   wxFileSystem::AddHandler(new wxZipFSHandler);     // Required for advanced HTML help
156 #endif
157   
158   // Create the main frame window
159   int xDisplay, yDisplay;
160   ::wxDisplaySize (&xDisplay, &yDisplay);
161   m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), 
162     wxSize(nearest<int>(xDisplay * .75), nearest<int>(yDisplay * .755)), wxDEFAULT_FRAME_STYLE);
163   
164   setIconForFrame (m_pFrame);
165   m_pFrame->Centre(wxBOTH);
166   m_pFrame->Show(true);  
167   SetTopWindow (m_pFrame);
168   
169   if (m_pConfig)
170     m_docManager->FileHistoryLoad(*m_pConfig);
171   
172 #ifdef CTSIM_MDI
173   m_pLogDoc = newTextDoc();
174   if (m_pLogDoc) {
175     m_pLog = m_pLogDoc->getTextCtrl();
176     m_pLogDoc->SetDocumentName("Log.txt");
177     m_pLogDoc->SetFilename("Log.txt");
178     m_pLogDoc->getView()->getFrame()->SetTitle("Log");
179     int xSize, ySize;
180     m_pFrame->GetClientSize(&xSize, &ySize);
181     int yLogSize = ySize / 4;
182     m_pLogDoc->getView()->getFrame()->SetSize (0, ySize - yLogSize, xSize, yLogSize);
183     m_pLogDoc->getView()->getFrame()->Show (true);
184   } else
185 #else
186     m_pLog = new wxTextCtrl (m_pFrame, -1, "Log Window\n", wxPoint(0, 0), wxSize(0,0), wxTE_MULTILINE | wxTE_READONLY);
187 #endif
188   wxLog::SetActiveTarget (new wxLogTextCtrl(m_pLog));
189   
190   wxString helpDir;
191   if (! m_pConfig->Read("HelpDir", &helpDir))
192     helpDir = ::wxGetCwd();
193 #ifdef CTSIM_WINHELP
194   if (! m_pFrame->getWinHelpController().Initialize(helpDir + "/ctsim"))
195     *m_pLog << "Cannot initialize the Windows Help system" << "\n";
196 #else
197   if (! m_pFrame->getHtmlHelpController().Initialize(helpDir + "/ctsim") &&
198     ! m_pFrame->getHtmlHelpController().Initialize("/usr/local/man/ctsim"))
199     *m_pLog << "Cannot initialize the HTML Help system" << "\n";
200   else {
201     if (::wxDirExists ("/tmp"))
202       m_pFrame->getHtmlHelpController().SetTempDir(_T("/tmp"));
203     m_pFrame->getHtmlHelpController().UseConfig (m_pConfig);
204   }
205 #endif
206   
207   for (int i = optind + 1; i <= argc; i++) {
208     wxString filename = argv [i - 1];
209     wxDocument* pNewDoc = m_docManager->CreateDocument (filename, wxDOC_SILENT);
210     if (bPrintFiles) {
211       wxView* pNewView = pNewDoc->GetFirstView();
212       wxPrintout *printout = pNewView->OnCreatePrintout();
213       if (printout) {
214         wxPrinter printer;
215         printer.Print(pNewView->GetFrame(), printout, TRUE);
216         delete printout;
217       }
218       wxCommandEvent nullEvent;
219       nullEvent.SetId (wxID_CLOSE);
220       m_docManager->OnFileClose (nullEvent);
221     }
222   }
223   if (bPrintFiles) {
224     wxCommandEvent closeEvent;
225     closeEvent.SetInt (MAINMENU_FILE_EXIT);
226     m_pFrame->AddPendingEvent(closeEvent);
227   }
228   
229   if (getStartupTips())
230     ShowTips();
231   
232   m_pBackgroundMgr = new BackgroundManager;
233   return true;
234 }
235
236 void
237 CTSimApp::ShowTips()
238 {
239   CTSimTipProvider tipProvider (m_iCurrentTip);
240   setStartupTips (::wxShowTip (m_pFrame, &tipProvider, getStartupTips()));
241   m_iCurrentTip = tipProvider.GetCurrentTip();
242 }
243
244
245 #include "./ctsim.xpm"
246 void
247 CTSimApp::setIconForFrame(wxFrame* pFrame)
248 {
249   wxIcon iconApp (ctsim16_xpm);
250   
251   if (iconApp.Ok())
252     pFrame->SetIcon (iconApp);
253 }
254
255 void
256 CTSimApp::usage(const char* program)
257 {
258   std::cout << "usage: " << fileBasename(program) << " [files-to-open...] [OPTIONS]\n";
259   std::cout << "Computed Tomography Simulator (Graphical Shell)\n";
260   std::cout << "\n";
261   std::cout << "  --version Display version\n";
262   std::cout << "  --help    Display this help message\n";
263 }
264
265 int
266 CTSimApp::OnExit()
267 {
268   closeConfig();
269   
270 #ifdef HAVE_DMALLOC
271   dmalloc_shutdown();
272 #endif
273   return 0;
274 }
275
276 void
277 CTSimApp::openConfig()
278 {
279 #ifdef MSVC
280   m_pConfig = new wxConfig("ctsim", "Kevin Rosenberg", "", "", wxCONFIG_USE_LOCAL_FILE);
281 #else
282   m_pConfig = new wxConfig("ctsim", "Kevin Rosenberg", ".ctsim", "", wxCONFIG_USE_LOCAL_FILE);
283 #endif
284   
285   wxConfigBase::Set(m_pConfig);
286   m_pConfig->Read ("AdvancedOptions", &m_bAdvancedOptions);
287   m_pConfig->Read ("SetModifyNewDocs", &m_bSetModifyNewDocs);
288   m_pConfig->Read ("VerboseLogging", &m_bVerboseLogging);
289   m_pConfig->Read ("StartupTips", &m_bShowStartupTips);
290   m_pConfig->Read ("CurrentTip", &m_iCurrentTip);
291   m_pConfig->Read ("UseBackgroundTasks", &m_bUseBackgroundTasks);
292 }
293
294 void
295 CTSimApp::closeConfig()
296 {
297   m_pConfig->Write ("AdvancedOptions", m_bAdvancedOptions);
298   m_pConfig->Write ("SetModifyNewDocs", m_bSetModifyNewDocs);
299   m_pConfig->Write ("VerboseLogging", m_bVerboseLogging);
300   m_pConfig->Write ("StartupTips", m_bShowStartupTips);
301   m_pConfig->Write ("CurrentTip", m_iCurrentTip);
302   m_pConfig->Write ("UseBackgroundTasks", m_bUseBackgroundTasks);
303   
304   delete m_pConfig;
305 }
306
307
308 wxString
309 CTSimApp::getUntitledFilename()
310 {
311   static int untitledNumber = 1;
312   
313   wxString filename ("Untitled");
314   filename << untitledNumber++;
315   
316   return (filename);
317 }
318
319
320 // Top-level window for CTSim
321
322 #if CTSIM_MDI
323 IMPLEMENT_CLASS(MainFrame, wxMDIParentFrame)
324
325 BEGIN_EVENT_TABLE(MainFrame, wxMDIParentFrame)
326 #else
327 IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
328
329 BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
330 #endif
331
332 EVT_MENU(MAINMENU_FILE_PREFERENCES, MainFrame::OnPreferences)
333 EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
334 EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
335 EVT_MENU(MAINMENU_HELP_TIPS, MainFrame::OnHelpTips)
336 EVT_MENU(MAINMENU_IMPORT, MainFrame::OnImport)
337 EVT_MENU(IDH_QUICKSTART, MainFrame::OnHelpButton)
338 EVT_MENU(MAINMENU_LOG_EVENT, MainFrame::OnLogEvent)
339 EVT_MENU(NEW_IMAGEFILE_EVENT, MainFrame::OnNewImageFile)
340 EVT_MENU(NEW_PROJECTIONFILE_EVENT, MainFrame::OnNewProjectionFile)
341 EVT_BUTTON(IDH_DLG_RASTERIZE, MainFrame::OnHelpButton)
342 EVT_BUTTON(IDH_DLG_PROJECTIONS, MainFrame::OnHelpButton)
343 EVT_BUTTON(IDH_DLG_RECONSTRUCTION, MainFrame::OnHelpButton)
344 EVT_BUTTON(IDH_DLG_FILTER, MainFrame::OnHelpButton)
345 EVT_BUTTON(IDH_DLG_MINMAX, MainFrame::OnHelpButton)
346 EVT_BUTTON(IDH_DLG_EXPORT, MainFrame::OnHelpButton)
347 EVT_BUTTON(IDH_DLG_PHANTOM, MainFrame::OnHelpButton)
348 EVT_BUTTON(IDH_DLG_COMPARISON, MainFrame::OnHelpButton)
349 EVT_BUTTON(IDH_DLG_PREFERENCES, MainFrame::OnHelpButton)
350 EVT_BUTTON(IDH_DLG_POLAR, MainFrame::OnHelpButton)
351 EVT_BUTTON(IDH_DLG_AUTOSCALE, MainFrame::OnHelpButton)
352
353 EVT_SIZE(MainFrame::OnSize)
354
355 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
356 EVT_MENU(MAINMENU_HELP_SECONDARY, MainFrame::OnHelpSecondary)
357 #endif
358 EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom)
359 EVT_MENU(MAINMENU_FILE_CREATE_FILTER, MainFrame::OnCreateFilter)
360 EVT_MENU(MAINMENU_FILE_EXIT, MainFrame::OnExit)
361 EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, MainFrame::OnMRUFile)
362 EVT_MENU(MAINMENU_WINDOW_BASE, MainFrame::OnWindowMenu0)
363 EVT_MENU(MAINMENU_WINDOW_BASE+1, MainFrame::OnWindowMenu1)
364 EVT_MENU(MAINMENU_WINDOW_BASE+2, MainFrame::OnWindowMenu2)
365 EVT_MENU(MAINMENU_WINDOW_BASE+3, MainFrame::OnWindowMenu3)
366 EVT_MENU(MAINMENU_WINDOW_BASE+4, MainFrame::OnWindowMenu4)
367 EVT_MENU(MAINMENU_WINDOW_BASE+5, MainFrame::OnWindowMenu5)
368 EVT_MENU(MAINMENU_WINDOW_BASE+6, MainFrame::OnWindowMenu6)
369 EVT_MENU(MAINMENU_WINDOW_BASE+7, MainFrame::OnWindowMenu7)
370 EVT_MENU(MAINMENU_WINDOW_BASE+8, MainFrame::OnWindowMenu8)
371 EVT_MENU(MAINMENU_WINDOW_BASE+9, MainFrame::OnWindowMenu9)
372 EVT_MENU(MAINMENU_WINDOW_BASE+10, MainFrame::OnWindowMenu10)
373 EVT_MENU(MAINMENU_WINDOW_BASE+11, MainFrame::OnWindowMenu11)
374 EVT_MENU(MAINMENU_WINDOW_BASE+12, MainFrame::OnWindowMenu12)
375 EVT_MENU(MAINMENU_WINDOW_BASE+13, MainFrame::OnWindowMenu13)
376 EVT_MENU(MAINMENU_WINDOW_BASE+14, MainFrame::OnWindowMenu14)
377 EVT_MENU(MAINMENU_WINDOW_BASE+15, MainFrame::OnWindowMenu15)
378 EVT_MENU(MAINMENU_WINDOW_BASE+16, MainFrame::OnWindowMenu16)
379 EVT_MENU(MAINMENU_WINDOW_BASE+17, MainFrame::OnWindowMenu17)
380 EVT_MENU(MAINMENU_WINDOW_BASE+18, MainFrame::OnWindowMenu18)
381 EVT_MENU(MAINMENU_WINDOW_BASE+19, MainFrame::OnWindowMenu19)
382 EVT_UPDATE_UI_RANGE(MAINMENU_WINDOW_BASE, MAINMENU_WINDOW_BASE+20, MainFrame::OnUpdateUI)
383 END_EVENT_TABLE()
384
385
386
387 #if CTSIM_MDI
388 MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type)
389 : wxDocMDIParentFrame(manager, NULL, id, title, pos, size, type, "MainFrame")
390 #else
391 MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type)
392 : wxDocParentFrame(manager, frame, id, title, pos, size, type, "MainFrame")
393 #endif
394 {
395   m_bShuttingDown = false;
396   
397   //// Make a menubar
398   wxMenu *file_menu = new wxMenu;
399   
400   file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...\tCtrl-P");
401   file_menu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...\tCtrl-F");
402   file_menu->Append(wxID_OPEN, "&Open...\tCtrl-O");
403   
404   file_menu->AppendSeparator();
405   file_menu->Append (MAINMENU_IMPORT, "&Import...\tCtrl-M");
406   file_menu->Append (MAINMENU_FILE_PREFERENCES, "Prefere&nces...");
407   file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
408   
409   //  history of files visited
410   theApp->getDocManager()->FileHistoryAddFilesToMenu(file_menu);
411   theApp->getDocManager()->FileHistoryUseMenu(file_menu);
412   
413 #ifndef CTSIM_MDI
414   m_pWindowMenu = new wxMenu;
415   m_pWindowMenu->UpdateUI (this);
416 #endif
417   
418   wxMenu* help_menu = new wxMenu;
419   help_menu->Append (MAINMENU_HELP_CONTENTS, "&Contents\tF1");
420   help_menu->Append (MAINMENU_HELP_TIPS, "&Tips");
421   help_menu->Append (IDH_QUICKSTART, "&Quick Start");
422 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
423   help_menu->Append (MAINMENU_HELP_SECONDARY, "&Secondary Help");
424 #endif
425   help_menu->Append (MAINMENU_HELP_ABOUT, "&About");
426   
427   wxMenuBar* menu_bar = new wxMenuBar;
428   
429   menu_bar->Append(file_menu, "&File");
430 #ifndef CTSIM_MDI
431   menu_bar->Append(m_pWindowMenu, "&Window");
432 #endif
433   menu_bar->Append(help_menu, "&Help");
434   
435   SetMenuBar(menu_bar);
436   
437   
438 #ifndef CTSIM_MDI
439   int i;
440   for (i = 0; i < MAX_WINDOW_MENUITEMS; i++) {
441     m_apWindowMenuItems[i] = new wxMenuItem (m_pWindowMenu, MAINMENU_WINDOW_BASE+i, wxString("[EMPTY]"));
442     m_pWindowMenu->Append (m_apWindowMenuItems[i]);
443     m_pWindowMenu->Enable (MAINMENU_WINDOW_BASE+i, false);
444   }
445 #endif
446   
447   m_iDefaultPhantomID = Phantom::PHM_HERMAN;
448   m_iDefaultFilterID = SignalFilter::FILTER_BANDLIMIT;
449   m_iDefaultFilterDomainID = SignalFilter::DOMAIN_FREQUENCY;
450   m_iDefaultFilterXSize = 256;
451   m_iDefaultFilterYSize = 256;
452   m_dDefaultFilterParam = 1.;
453   m_dDefaultFilterBandwidth = 1.;
454   m_dDefaultFilterInputScale = 1.;
455   m_dDefaultFilterOutputScale = 1.;
456   m_iDefaultImportFormat = ImageFile::IMPORT_FORMAT_PPM;
457   
458   wxAcceleratorEntry accelEntries[15];
459   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('O'), wxID_OPEN);
460   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('P'), MAINMENU_FILE_CREATE_PHANTOM);
461   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('F'), MAINMENU_FILE_CREATE_FILTER);
462   accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('M'), MAINMENU_IMPORT);
463   accelEntries[4].Set (wxACCEL_NORMAL, WXK_F1, MAINMENU_HELP_CONTENTS);
464 #ifndef CTSIM_MDI
465   for (i = 0; i < 10; i++)
466     accelEntries[i+5].Set (wxACCEL_CTRL, static_cast<int>('0'+i), MAINMENU_WINDOW_BASE+i);
467   wxAcceleratorTable accelTable (15, accelEntries);
468 #else
469   wxAcceleratorTable accelTable (5, accelEntries);
470 #endif
471   
472   SetAcceleratorTable (accelTable);
473 }
474
475 MainFrame::~MainFrame()
476 {
477   m_bShuttingDown = true; // Currently used so that Log Window will close
478 #if 0
479   // delete all non-modified documents
480   wxList& rListDocs = theApp->getDocManager()->GetDocuments();
481   for (wxNode* pNode = rListDocs.GetFirst(); pNode != NULL; pNode = pNode->GetNext()) {
482     wxDocument* pDoc = dynamic_cast<wxDocument*>(pNode->GetData());
483     if (pDoc && ! pDoc->IsModified()) {
484       theApp->getDocManager()->RemoveDocument(pDoc);
485       delete pDoc;
486     }
487   }
488 #endif
489   ::wxYield();
490   if (theApp->getConfig())
491     theApp->getDocManager()->FileHistorySave (*theApp->getConfig());
492   ::wxYield();
493   delete theApp->getDocManager();       
494   
495 }
496
497 void
498 MainFrame::OnSize (wxSizeEvent& event)
499 {
500 #ifdef CTSIM_MDI
501   if (theApp->getLogDoc()) {
502     int xSize, ySize;   
503     GetClientSize(&xSize, &ySize);
504     int yLogSize = ySize / 4;
505                   theApp->getLogDoc()->getView()->getFrame()->SetSize (0, ySize - yLogSize, xSize, yLogSize);
506       theApp->getLogDoc()->getView()->getFrame()->Show (true);
507   }
508 #endif
509   
510 #if CTSIM_MDI
511   wxDocMDIParentFrame::OnSize (event);
512 #else
513   wxDocParentFrame::OnSize (event);
514 #endif
515 }
516
517 void 
518 MainFrame::OnCreatePhantom(wxCommandEvent& event)
519 {
520   DialogGetPhantom dialogPhantom (this, m_iDefaultPhantomID);
521   int dialogReturn = dialogPhantom.ShowModal();
522   if (dialogReturn == wxID_OK) {
523     wxString selection (dialogPhantom.getPhantom());
524     if (theApp->getVerboseLogging())
525       *theApp->getLog() << "Selected phantom " << selection.c_str() << "\n";
526     wxString filename = selection + ".phm";
527     m_iDefaultPhantomID = Phantom::convertNameToPhantomID (selection.c_str());
528     theApp->getDocManager()->CreateDocument (filename, wxDOC_SILENT);
529   }
530   
531 }
532
533 void 
534 MainFrame::OnCreateFilter (wxCommandEvent& WXUNUSED(event))
535 {
536   DialogGetFilterParameters dialogFilter (this, m_iDefaultFilterXSize, m_iDefaultFilterYSize, m_iDefaultFilterID, m_dDefaultFilterParam, m_dDefaultFilterBandwidth, m_iDefaultFilterDomainID, m_dDefaultFilterInputScale, m_dDefaultFilterOutputScale);
537   int dialogReturn = dialogFilter.ShowModal();
538   if (dialogReturn == wxID_OK) {
539     wxString strFilter (dialogFilter.getFilterName());
540     wxString strDomain (dialogFilter.getDomainName());
541     m_iDefaultFilterID = SignalFilter::convertFilterNameToID (strFilter.c_str());
542     m_iDefaultFilterDomainID = SignalFilter::convertDomainNameToID (strDomain.c_str());
543     m_iDefaultFilterXSize = dialogFilter.getXSize();
544     m_iDefaultFilterYSize = dialogFilter.getYSize();
545     m_dDefaultFilterBandwidth = dialogFilter.getBandwidth();
546     m_dDefaultFilterParam= dialogFilter.getFilterParam();
547     m_dDefaultFilterInputScale = dialogFilter.getInputScale();
548     m_dDefaultFilterOutputScale = dialogFilter.getOutputScale();
549     std::ostringstream os;
550     os << "Generate Filter=" << strFilter.c_str() 
551       << ", size=(" << static_cast<int>(m_iDefaultFilterXSize) << "," << static_cast<int>(m_iDefaultFilterYSize) 
552       << "), domain=" << strDomain.c_str() << ", filterParam=" << m_dDefaultFilterParam << ", bandwidth=" << m_dDefaultFilterBandwidth 
553       << ", inputScale=" << m_dDefaultFilterInputScale << ", outputScale=" << m_dDefaultFilterOutputScale;
554     *theApp->getLog() << os.str().c_str() << "\n";
555     wxString filename = "untitled.if";
556     ImageFileDocument* pFilterDoc = theApp->newImageDoc();
557     pFilterDoc->setBadFileOpen();
558     if (! pFilterDoc) {
559       sys_error (ERR_SEVERE, "Unable to create filter image");
560       return;
561     }
562     ImageFile& rIF = pFilterDoc->getImageFile();
563     rIF.setArraySize (m_iDefaultFilterXSize, m_iDefaultFilterYSize);
564     rIF.filterResponse (strDomain.c_str(), m_dDefaultFilterBandwidth, strFilter.c_str(), m_dDefaultFilterParam, m_dDefaultFilterInputScale, m_dDefaultFilterOutputScale);
565     rIF.labelAdd (os.str().c_str());
566     if (theApp->getAskDeleteNewDocs())
567       pFilterDoc->Modify (true);
568     pFilterDoc->UpdateAllViews();
569     pFilterDoc->GetFirstView()->OnUpdate (NULL, NULL);
570     pFilterDoc->getView()->getFrame()->SetClientSize(m_iDefaultFilterXSize, m_iDefaultFilterYSize);
571     pFilterDoc->getView()->getFrame()->Show(true);
572   }
573 }
574
575 void
576 CTSimApp::getCompatibleImages (const ImageFileDocument* pIFDoc, std::vector<ImageFileDocument*>& vecIF)
577 {
578   const ImageFile& rIF = pIFDoc->getImageFile();
579   unsigned int nx = rIF.nx();
580   unsigned int ny = rIF.ny();
581   wxList& rListDocs = m_docManager->GetDocuments();
582   for (wxNode* pNode = rListDocs.GetFirst(); pNode != NULL; pNode = pNode->GetNext()) {
583     wxDocument* pDoc = reinterpret_cast<wxDocument*>(pNode->GetData());
584     ImageFileDocument* pIFCompareDoc = dynamic_cast<ImageFileDocument*>(pDoc);
585     if (pIFCompareDoc && (pIFDoc != pIFCompareDoc)) {
586       const ImageFile& rCompareIF = pIFCompareDoc->getImageFile();
587       if (rCompareIF.nx() == nx && rCompareIF.ny() == ny)
588         vecIF.push_back (pIFCompareDoc);
589     }
590   }
591 }
592
593
594 void
595 MainFrame::OnNewImageFile (wxCommandEvent& event)
596 {
597   ImageFile* pImageFile = reinterpret_cast<ImageFile*>(event.GetClientData());
598
599   ImageFileDocument* pImageDoc = theApp->newImageDoc();
600   if (! pImageDoc) {
601     sys_error (ERR_SEVERE, "Unable to create image file");
602     return;
603   }  
604   pImageDoc->setImageFile (pImageFile);
605   pImageDoc->UpdateAllViews (NULL);
606   if (ImageFileView* imageView = pImageDoc->getView()) {
607     imageView->OnUpdate (imageView, NULL);
608     imageView->getFrame()->SetFocus();
609     imageView->getFrame()->Show(true);
610   }
611   if (theApp->getAskDeleteNewDocs())
612     pImageDoc->Modify (true);
613
614 }
615
616 void
617 MainFrame::OnNewProjectionFile (wxCommandEvent& event)
618 {
619   Projections* pProjections = reinterpret_cast<Projections*>(event.GetClientData());
620   ProjectionFileDocument* pProjDoc = theApp->newProjectionDoc();
621   if (! pProjDoc) {
622     sys_error (ERR_SEVERE, "Unable to create projection file");
623     return;
624   }  
625   pProjDoc->setProjections (pProjections);
626   pProjDoc->UpdateAllViews (NULL);
627   if (ProjectionFileView* projView = pProjDoc->getView()) {
628     projView->OnUpdate (projView, NULL);
629     projView->getFrame()->SetFocus();
630     projView->getFrame()->Show(true);
631   }
632
633   if (theApp->getAskDeleteNewDocs())
634     pProjDoc->Modify (true);
635 }
636
637 void
638 MainFrame::OnLogEvent (wxCommandEvent& event)
639 {
640   *theApp->getLog() << event.GetString();
641 }
642
643 void
644 MainFrame::OnHelpTips (wxCommandEvent& event)
645 {
646   theApp->ShowTips();
647 }
648
649 void 
650 MainFrame::OnHelpContents (wxCommandEvent& event)
651 {
652   showHelp (event.GetId());
653 }
654
655 void 
656 MainFrame::OnHelpButton (wxCommandEvent& event)
657 {
658   showHelp (event.GetId());
659 }
660
661 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
662 void
663 MainFrame::OnHelpSecondary (wxCommandEvent& event)
664 {
665   m_htmlHelp.DisplayContents();
666 }
667 #endif
668
669 void
670 MainFrame::showHelp (int commandID)
671 {
672   switch (commandID) {
673     
674   case MAINMENU_HELP_CONTENTS:
675 #ifdef CTSIM_WINHELP
676     m_winHelp.DisplayContents ();
677 #else
678     m_htmlHelp.DisplayContents ();
679 #endif
680     break;
681     
682     
683   default:
684 #ifdef CTSIM_WINHELP
685     m_winHelp.DisplaySection (commandID);
686 #else
687     m_htmlHelp.Display (commandID);
688 #endif
689     break;
690   }
691 }
692
693 void 
694 MainFrame::OnExit (wxCommandEvent& WXUNUSED(event) )
695 {
696   Close(true);
697 }
698
699 void
700 MainFrame::OnUpdateUI (wxUpdateUIEvent& rEvent)
701 {
702 #ifndef CTSIM_MDI
703   int iPos = 0;
704   wxList& rListDocs = theApp->getDocManager()->GetDocuments();
705   wxNode* pNode = rListDocs.GetFirst();
706   while (iPos < MAX_WINDOW_MENUITEMS && pNode != NULL) {
707     wxDocument* pDoc = static_cast<wxDocument*>(pNode->GetData());
708     wxString strFilename = pDoc->GetFilename();
709     if (iPos < 10) {
710       strFilename += "\tCtrl-";
711       strFilename += static_cast<char>('0' + iPos);
712     }
713     static_cast<wxMenuItemBase*>(m_apWindowMenuItems[iPos])->SetName (strFilename);
714     m_apWindowMenuData[iPos] = pDoc;
715     m_pWindowMenu->Enable (MAINMENU_WINDOW_BASE+iPos, true);
716     iPos++;
717     pNode = pNode->GetNext();
718   }
719   for (int i = iPos; i < MAX_WINDOW_MENUITEMS; i++) {
720     m_pWindowMenu->Enable (MAINMENU_WINDOW_BASE+i, false);
721     static_cast<wxMenuItemBase*>(m_apWindowMenuItems[i])->SetName (wxString("[EMPTY]"));
722     m_apWindowMenuData[i] = NULL;
723   }
724 #endif  
725 }
726
727 #ifdef CTSIM_CUSTOM_MRU
728 void 
729 MainFrame::OnMRUFile (wxCommandEvent& event)
730 {
731   wxString fileName (theApp->getDocManager()->GetHistoryFile(event.GetId() - wxID_FILE1));
732   if (fileName != "")
733     theApp->getDocManager()->CreateDocument(fileName, wxDOC_SILENT);
734 }
735 #endif
736
737 void 
738 MainFrame::DoWindowMenu (int iMenuPosition, wxCommandEvent& event)
739 {
740   if (wxDocument* pDoc = m_apWindowMenuData [iMenuPosition]) {
741     wxString strFilename = pDoc->GetFilename();
742     const wxView* pView = pDoc->GetFirstView();
743     if (pView) {
744       wxFrame* pFrame = pView->GetFrame();
745       pFrame->SetFocus();
746       pFrame->Raise();
747     }
748   }
749 }
750
751 void MainFrame::OnWindowMenu0 (wxCommandEvent& event)
752 { DoWindowMenu (0, event); }
753
754 void MainFrame::OnWindowMenu1 (wxCommandEvent& event)
755 { DoWindowMenu (1, event); }
756
757 void MainFrame::OnWindowMenu2 (wxCommandEvent& event)
758 { DoWindowMenu (2, event); }
759
760 void MainFrame::OnWindowMenu3 (wxCommandEvent& event)
761 { DoWindowMenu (3, event); }
762
763 void MainFrame::OnWindowMenu4 (wxCommandEvent& event)
764 { DoWindowMenu (4, event); }
765
766 void MainFrame::OnWindowMenu5 (wxCommandEvent& event)
767 { DoWindowMenu (5, event); }
768
769 void MainFrame::OnWindowMenu6 (wxCommandEvent& event)
770 { DoWindowMenu (6, event); }
771
772 void MainFrame::OnWindowMenu7 (wxCommandEvent& event)
773 { DoWindowMenu (7, event); }
774
775 void MainFrame::OnWindowMenu8 (wxCommandEvent& event)
776 { DoWindowMenu (8, event); }
777
778 void MainFrame::OnWindowMenu9 (wxCommandEvent& event)
779 { DoWindowMenu (9, event); }
780
781 void MainFrame::OnWindowMenu10 (wxCommandEvent& event)
782 { DoWindowMenu (10, event); }
783
784 void MainFrame::OnWindowMenu11 (wxCommandEvent& event)
785 { DoWindowMenu (11, event); }
786
787 void MainFrame::OnWindowMenu12 (wxCommandEvent& event)
788 { DoWindowMenu (12, event); }
789
790 void MainFrame::OnWindowMenu13 (wxCommandEvent& event)
791 { DoWindowMenu (13, event); }
792
793 void MainFrame::OnWindowMenu14 (wxCommandEvent& event)
794 { DoWindowMenu (14, event); }
795
796 void MainFrame::OnWindowMenu15 (wxCommandEvent& event)
797 { DoWindowMenu (15, event); }
798
799 void MainFrame::OnWindowMenu16 (wxCommandEvent& event)
800 { DoWindowMenu (16, event); }
801
802 void MainFrame::OnWindowMenu17 (wxCommandEvent& event)
803 { DoWindowMenu (17, event); }
804
805 void MainFrame::OnWindowMenu18 (wxCommandEvent& event)
806 { DoWindowMenu (18, event); }
807
808 void MainFrame::OnWindowMenu19 (wxCommandEvent& event)
809 { DoWindowMenu (19, event); }
810
811
812 class BitmapControl : public wxPanel
813 {
814 private:  
815   DECLARE_DYNAMIC_CLASS (BitmapControl)
816     DECLARE_EVENT_TABLE ()
817     wxBitmap* m_pBitmap;
818   
819 public:
820   BitmapControl (wxBitmap* pBitmap, wxWindow *parent, wxWindowID id = -1,
821     const wxPoint& pos = wxDefaultPosition,
822     const wxSize& size = wxDefaultSize,
823     long style = wxSTATIC_BORDER,
824     const wxValidator& validator = wxDefaultValidator,
825     const wxString& name = "BitmapCtrl");
826   
827   
828   virtual ~BitmapControl();
829   
830   virtual wxSize GetBestSize() const;
831   
832   wxBitmap* getBitmap() 
833   { return m_pBitmap; }
834   
835   void OnPaint(wxPaintEvent& event);
836 };
837
838
839 BEGIN_EVENT_TABLE(BitmapControl, wxPanel)
840 EVT_PAINT(BitmapControl::OnPaint)
841 END_EVENT_TABLE()
842
843 IMPLEMENT_CLASS(BitmapControl, wxPanel)
844
845
846 BitmapControl::BitmapControl (wxBitmap* pBitmap, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, 
847                               long style, const wxValidator& validator, const wxString& name)
848                               : m_pBitmap(pBitmap)
849 {
850   Create(parent, id, pos, size, style, name);
851   
852   SetSize (GetBestSize());
853 }
854
855 wxSize
856 BitmapControl::GetBestSize () const
857 {
858   if (m_pBitmap)
859     return wxSize (m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
860   else
861     return wxSize(0,0);
862 }
863
864 BitmapControl::~BitmapControl()
865 {}
866
867 void
868 BitmapControl::OnPaint (wxPaintEvent& event)
869 {
870   wxPaintDC dc(this);
871   if (m_pBitmap)
872     dc.DrawBitmap (*m_pBitmap, 0, 0);
873 }
874
875
876 class BitmapDialog : public wxDialog {
877 private:
878   BitmapControl* m_pBitmapCtrl;
879   
880 public:
881   BitmapDialog (wxBitmap* pBitmap, char const* pszTitle);
882   virtual ~BitmapDialog();
883 };
884
885 BitmapDialog::BitmapDialog (wxBitmap* pBitmap, char const* pszTitle)
886 : wxDialog(theApp->getMainFrame(), -1, wxString(pszTitle), wxDefaultPosition, wxDefaultSize, wxDIALOG_MODAL | wxDEFAULT_DIALOG_STYLE)
887 {
888   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);
889   
890   pTopSizer->Add (new BitmapControl (pBitmap, this), 0, wxALIGN_CENTER | wxALL, 5);
891   
892   wxBoxSizer* pButtonSizer = new wxBoxSizer (wxHORIZONTAL);
893   wxButton* pButtonOk = new wxButton (this, wxID_OK, "Ok");
894   pButtonSizer->Add (pButtonOk, 0, wxEXPAND | wxALL, 10);
895   
896   pTopSizer->Add (pButtonSizer, 0, wxALIGN_CENTER);
897   
898   SetAutoLayout (true);
899   SetSizer (pTopSizer);
900   pTopSizer->Fit (this);
901   pTopSizer->SetSizeHints (this);
902 }
903
904 BitmapDialog::~BitmapDialog()
905 {}
906
907
908 void 
909 MainFrame::OnPreferences (wxCommandEvent& WXUNUSED(event) )
910 {
911   DialogPreferences dlg (this, "CTSim Preferences", theApp->getAdvancedOptions(), 
912     theApp->getAskDeleteNewDocs(), theApp->getVerboseLogging(), theApp->getStartupTips(), 
913     theApp->getUseBackgroundTasks());
914   if (dlg.ShowModal() == wxID_OK) {
915     theApp->setAdvancedOptions (dlg.getAdvancedOptions());
916     theApp->setAskDeleteNewDocs (dlg.getAskDeleteNewDocs());
917     theApp->setVerboseLogging (dlg.getVerboseLogging());
918     theApp->setStartupTips (dlg.getStartupTips());
919     theApp->setUseBackgroundTasks (dlg.getUseBackgroundTasks());
920   }
921 }
922
923 void 
924 MainFrame::OnImport (wxCommandEvent& WXUNUSED(event) )
925 {
926   DialogImportParameters dialogImport (this, m_iDefaultImportFormat);
927   if (dialogImport.ShowModal() != wxID_OK)
928     return;
929   
930   wxString strFormatName (dialogImport.getFormatName ());
931   m_iDefaultImportFormat = ImageFile::convertImportFormatNameToID (strFormatName.c_str());
932   
933   wxString strExt;
934   wxString strWildcard;
935   if (m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_PPM) {
936     strExt = ".ppm";
937     strWildcard = "PPM Files (*.ppm)|*.ppm|PGM Files (*.pgm)|*.pgm";
938   }
939 #ifdef HAVE_PNG
940   else if (m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_PNG) {
941     strExt = ".png";
942     strWildcard = "PNG Files (*.png)|*.png";
943   }
944 #endif
945 #ifdef HAVE_CTN_DICOM
946   else if (m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_DICOM) {
947     strExt = "*.*";
948     strWildcard = "Dicom Files (*.*)|*.*";
949   }
950 #endif
951   else {
952     return;
953   }
954   
955   wxString strFilename = wxFileSelector (wxString("Import Filename"), wxString(""), 
956     wxString(""), strExt, strWildcard, wxHIDE_READONLY | wxOPEN);
957   if (! strFilename.IsEmpty()) {
958     if (m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_PPM || m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_PNG) {
959       ImageFile* pIF = new ImageFile;
960       if (pIF->importImage (strFormatName.c_str(), strFilename.c_str())) {
961         ImageFileDocument* pIFDoc = theApp->newImageDoc();
962         pIFDoc->setImageFile(pIF);
963         pIFDoc->getView()->getFrame()->Show(true);
964         std::ostringstream os;
965         os << "Import file " << strFilename.c_str() << " (type " << strFormatName.c_str() << ")";
966         pIF->labelAdd (os.str().c_str());
967         if (theApp->getAskDeleteNewDocs())
968           pIFDoc->Modify (true);
969         pIFDoc->UpdateAllViews();
970         pIFDoc->GetFirstView()->OnUpdate (NULL, NULL);
971         pIFDoc->getView()->getFrame()->Show(true);
972       } else
973         delete pIF;
974     } 
975 #ifdef HAVE_CTN_DICOM
976     else if (m_iDefaultImportFormat == ImageFile::IMPORT_FORMAT_DICOM) {
977       DicomImporter dicomImport (strFilename.c_str());
978       if (dicomImport.fail()) {
979         ::wxMessageBox (dicomImport.failMessage().c_str(), "Import Error");
980       } else if (dicomImport.testImage()) {
981         ImageFileDocument* pIFDoc = theApp->newImageDoc();
982         ImageFile* pIF = dicomImport.getImageFile();
983         pIFDoc->setImageFile (pIF);
984         pIFDoc->getView()->getFrame()->Show(true);
985         std::ostringstream os;
986         os << "Import file " << strFilename.c_str() << " (type " << strFormatName.c_str() << ")";
987         pIF->labelAdd (os.str().c_str());
988         if (theApp->getAskDeleteNewDocs())
989           pIFDoc->Modify (true);
990         pIFDoc->UpdateAllViews();
991         pIFDoc->GetFirstView()->OnUpdate (NULL, NULL);
992         pIFDoc->getView()->getFrame()->Show(true);
993       } else if (dicomImport.testProjections()) {
994         ProjectionFileDocument* pProjDoc = theApp->newProjectionDoc();
995         Projections* pProj = dicomImport.getProjections();
996         pProjDoc->setProjections (pProj);
997         pProjDoc->getView()->getFrame()->Show(true);
998         std::ostringstream os;
999         os << "Import projection file " << strFilename.c_str() << " (type " << strFormatName.c_str() << ")";
1000         pProj->setRemark (os.str().c_str());
1001         if (theApp->getAskDeleteNewDocs())
1002           pProjDoc->Modify (true);
1003         pProjDoc->UpdateAllViews();
1004         pProjDoc->GetFirstView()->OnUpdate (NULL, NULL);
1005         pProjDoc->getView()->getFrame()->Show(true);
1006       } else
1007         ::wxMessageBox ("Unrecognized DICOM file contents", "Import Error");
1008     } 
1009 #endif
1010     else
1011       sys_error (ERR_WARNING, "Unknown import format type");
1012   }
1013 }
1014
1015 #include "./splash.xpm"
1016 void 
1017 MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
1018 {
1019   long lFreeMem = ::wxGetFreeMemory() / (1024L * 1024L);
1020   wxString strOSDesc = ::wxGetOsDescription();
1021   *theApp->getLog() << "Operation System: " << strOSDesc;
1022   if (lFreeMem > 0)
1023     *theApp->getLog() << ",  Free Memory: " << lFreeMem << " MB";
1024   *theApp->getLog() << "\n";
1025   
1026   wxBitmap bmp (splash);
1027   if (bmp.Ok()) {
1028     BitmapDialog dlg (&bmp, "About CTSim");
1029     dlg.ShowModal();
1030   } else {
1031     wxString msg = "CTSim\nThe Open Source Computed Tomography Simulator\n";
1032 #ifdef CTSIMVERSION
1033     msg += "Version ";
1034     msg += CTSIMVERSION;
1035     msg += "\n\n";
1036 #elif defined(VERSION)
1037     msg << "Version: " <<  VERSION << "\n\n";
1038 #endif
1039     msg += "Author: Kevin Rosenberg <kevin@rosenberg.net>\nUsage: ctsim [files-to-open..] [--help]";
1040     
1041     wxMessageBox(msg, "About CTSim", wxOK | wxICON_INFORMATION, this);
1042   }
1043 }
1044
1045
1046 ProjectionFileDocument*
1047 CTSimApp::newProjectionDoc()
1048 {
1049   ProjectionFileDocument* newDoc = dynamic_cast<ProjectionFileDocument*>(m_pDocTemplProjection->CreateDocument (""));
1050   if (newDoc) {
1051     ProjectionFileView* pView = newDoc->getView();
1052     if (pView) {
1053       wxFrame* pFrame = pView->getFrame();
1054       if (pFrame) {
1055         pFrame->SetSize (0,0);
1056         pFrame->Show (false);
1057       }
1058     }
1059     newDoc->SetDocumentName (m_pDocTemplProjection->GetDocumentName());
1060     newDoc->SetDocumentTemplate (m_pDocTemplProjection);
1061     newDoc->OnNewDocument();
1062   }
1063   
1064   return newDoc;
1065 }
1066
1067 ImageFileDocument*
1068 CTSimApp::newImageDoc()
1069 {
1070   ImageFileDocument* newDoc = dynamic_cast<ImageFileDocument*>(m_pDocTemplImage->CreateDocument (""));
1071   if (newDoc) {
1072     ImageFileView* pView = newDoc->getView();
1073     if (pView) {
1074       wxFrame* pFrame = pView->getFrame();
1075       if (pFrame) {
1076         pFrame->SetSize (0,0);
1077         pFrame->Show (false);
1078       }
1079     }
1080     newDoc->SetDocumentName (m_pDocTemplImage->GetDocumentName());
1081     newDoc->SetDocumentTemplate (m_pDocTemplImage);
1082     newDoc->OnNewDocument();
1083   }
1084   
1085   return newDoc;
1086 }
1087
1088 PlotFileDocument*
1089 CTSimApp::newPlotDoc()
1090 {
1091   PlotFileDocument* newDoc = dynamic_cast<PlotFileDocument*>(m_pDocTemplPlot->CreateDocument (""));
1092   if (newDoc) {
1093     PlotFileView* pView = newDoc->getView();
1094     if (pView) {
1095       wxFrame* pFrame = pView->getFrame();
1096       if (pFrame) {
1097         wxSize size;
1098         m_pFrame->GetClientSize (&size.x, &size.y);
1099         pFrame->SetSize (size.x / 2, size.y / 2);
1100         pFrame->Show (false);
1101       }
1102     }
1103     newDoc->SetDocumentName (m_pDocTemplPlot->GetDocumentName());
1104     newDoc->SetDocumentTemplate (m_pDocTemplPlot);
1105     newDoc->OnNewDocument();
1106   }
1107   
1108   return newDoc;
1109 }
1110
1111
1112 TextFileDocument*
1113 CTSimApp::newTextDoc()
1114 {
1115   wxString strFilename (getUntitledFilename());
1116   strFilename += ".txt";
1117   
1118   TextFileDocument* newDoc = dynamic_cast<TextFileDocument*>(m_pDocTemplText->CreateDocument (""));
1119   if (newDoc) {
1120     TextFileView* pView = newDoc->getView();
1121     if (pView) {
1122       wxFrame* pFrame = pView->getFrame();
1123       if (pFrame) {
1124         wxSize size;
1125         m_pFrame->GetClientSize (&size.x, &size.y);;
1126         pFrame->SetSize (size.x / 2, size.y / 2);
1127         pFrame->Show (false);
1128       }
1129     }
1130     newDoc->SetDocumentName (m_pDocTemplText->GetDocumentName());
1131     newDoc->SetDocumentTemplate (m_pDocTemplText);
1132     newDoc->OnNewDocument();
1133   }
1134   
1135   return newDoc;
1136 }
1137
1138
1139 PhantomFileDocument*
1140 CTSimApp::newPhantomDoc()
1141 {
1142   PhantomFileDocument* newDoc = dynamic_cast<PhantomFileDocument*>(m_pDocTemplPhantom->CreateDocument (""));
1143   if (newDoc) {
1144     PhantomFileView* pView = newDoc->getView();
1145     if (pView) {
1146       wxFrame* pFrame = pView->getFrame();
1147       if (pFrame)
1148         pFrame->SetSize (0,0);
1149     }
1150     newDoc->SetDocumentName (m_pDocTemplPhantom->GetDocumentName());
1151     newDoc->SetDocumentTemplate (m_pDocTemplPhantom);
1152     newDoc->OnNewDocument();
1153   }
1154   
1155   return newDoc;
1156 }
1157
1158 #if wxUSE_GLCANVAS
1159
1160 Graph3dFileDocument*
1161 CTSimApp::newGraph3dDoc()
1162 {
1163   Graph3dFileDocument* newDoc = dynamic_cast<Graph3dFileDocument*>(m_pDocTemplGraph3d->CreateDocument (""));
1164   if (newDoc) {
1165     Graph3dFileView* pView = newDoc->getView();
1166     if (pView) {
1167       wxFrame* pFrame = pView->getFrame();
1168       if (pFrame)
1169         pFrame->SetSize (0,0);
1170     }
1171     newDoc->SetDocumentName (m_pDocTemplGraph3d->GetDocumentName());
1172     newDoc->SetDocumentTemplate (m_pDocTemplGraph3d);
1173     newDoc->OnNewDocument();
1174   }
1175   
1176   return newDoc;
1177 }
1178 #endif