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