Interim work on creating projections from an imagefile
[ctsim.git] / src / docs.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          docs.cpp
5 **   Purpose:       Document routines for CTSim program
6 **   Programmer:    Kevin Rosenberg
7 **   Date Started:  July 2000
8 **
9 **  This is part of the CTSim program
10 **  Copyright (c) 1983-2009 Kevin Rosenberg
11 **
12 **  This program is free software; you can redistribute it and/or modify
13 **  it under the terms of the GNU General Public License (version 2) as
14 **  published by the Free Software Foundation.
15 **
16 **  This program is distributed in the hope that it will be useful,
17 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 **  GNU General Public License for more details.
20 **
21 **  You should have received a copy of the GNU General Public License
22 **  along with this program; if not, write to the Free Software
23 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 ******************************************************************************/
25
26 #include "wx/wxprec.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/wx.h"
30 #endif
31 #include "wx/txtstrm.h"
32 #include "wx/file.h"
33 #include "wx/thread.h"
34
35 #if !wxUSE_DOC_VIEW_ARCHITECTURE
36 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
37 #endif
38
39 #include "ct.h"
40 #include "ctsim.h"
41 #include "docs.h"
42 #include "views.h"
43 #include "threadrecon.h"
44
45
46 // ImageFileDocument
47
48 IMPLEMENT_DYNAMIC_CLASS(ImageFileDocument, wxDocument)
49
50 bool ImageFileDocument::OnSaveDocument(const wxString& filename)
51 {
52   if (! m_pImageFile->fileWrite (filename.mb_str(wxConvUTF8))) {
53     *theApp->getLog() << _T("Unable to write image file ") << filename << _T("\n");
54     return false;
55   }
56   if (theApp->getVerboseLogging())
57     *theApp->getLog() << _T("Wrote image file ") << filename << _T("\n");
58   Modify(false);
59   return true;
60 }
61
62 bool ImageFileDocument::OnOpenDocument(const wxString& filename)
63 {
64   if (! OnSaveModified())
65     return false;
66
67   if (! m_pImageFile->fileRead (filename.mb_str(wxConvUTF8))) {
68     *theApp->getLog() << _T("Unable to read image file ") << filename << _T("\n");
69     m_bBadFileOpen = true;
70     return false;
71   }
72
73   if (theApp->getVerboseLogging() && filename != _T(""))
74     *theApp->getLog() << _T("Read image file ") << filename << _T("\n");
75
76   SetFilename(filename, true);
77   Modify(false);
78   getView()->setInitialClientSize();
79   this->SetFilename(filename, true);
80   UpdateAllViews();
81   m_bBadFileOpen = false;
82
83   return true;
84 }
85
86 bool
87 ImageFileDocument::IsModified(void) const
88 {
89   return wxDocument::IsModified();
90 }
91
92 void
93 ImageFileDocument::Modify(bool mod)
94 {
95   wxDocument::Modify(mod);
96 }
97
98 ImageFileView*
99 ImageFileDocument::getView() const
100 {
101   return dynamic_cast<ImageFileView*>(GetFirstView());
102 }
103
104 bool
105 ImageFileDocument::Revert ()
106 {
107   if (IsModified()) {
108     wxString msg (_T("Revert to saved "));
109     msg += GetFilename();
110     msg += _T("?");
111     wxMessageDialog dialog (getView()->getFrame(), msg, _T("Are you sure?"), wxYES_NO | wxNO_DEFAULT);
112     if (dialog.ShowModal() == wxID_YES) {
113       if (theApp->getVerboseLogging())
114         *theApp->getLog() << _T("Reverting to saved ") << GetFilename() << _T("\n");
115       Modify (false);
116       OnOpenDocument (GetFilename());
117     }
118   }
119   UpdateAllViews();
120
121   return true;
122 }
123
124 void
125 ImageFileDocument::Activate()
126 {
127 #if CTSIM_MDI
128   getView()->getFrame()->Activate();
129 #endif
130 };
131
132 // BackgroundProcessingDocument - Base Class
133
134 IMPLEMENT_DYNAMIC_CLASS(BackgroundProcessingDocument, wxDocument)
135 BEGIN_EVENT_TABLE(BackgroundProcessingDocument, wxDocument)
136 END_EVENT_TABLE()
137
138 #ifdef HAVE_WXTHREADS
139 void
140 BackgroundProcessingDocument::addBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
141 {
142   wxCriticalSectionLocker locker (m_criticalSection);
143   if (pSupervisor)
144     m_vecpBackgroundSupervisors.push_back (pSupervisor);
145 }
146
147 void
148 BackgroundProcessingDocument::removeBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
149 {
150   m_criticalSection.Enter();
151   bool bFound = false;
152   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin();
153         i != m_vecpBackgroundSupervisors.end();
154         i++)
155           if (*i == pSupervisor) {
156             m_vecpBackgroundSupervisors.erase(i);
157             bFound = true;
158             break;
159         }
160   m_criticalSection.Leave();
161
162   if (! bFound)
163      sys_error (ERR_SEVERE, "Could not find background task [OnRemoveBackground]");
164 }
165 #endif
166
167 void
168 BackgroundProcessingDocument::cancelRunningTasks()
169 {
170 #ifdef HAVE_WXTHREADS
171   m_criticalSection.Enter();
172   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin();
173         i != m_vecpBackgroundSupervisors.end(); i++)
174           (*i)->onCancel();
175   m_criticalSection.Leave();
176
177   while (m_vecpBackgroundSupervisors.size() > 0) {
178      ::wxYield();
179      ::wxMilliSleep(50);
180   }
181 #endif
182 }
183
184
185 // ProjectionFileDocument
186
187 IMPLEMENT_DYNAMIC_CLASS(ProjectionFileDocument, BackgroundProcessingDocument)
188
189 bool
190 ProjectionFileDocument::OnSaveDocument(const wxString& filename)
191 {
192   if (! m_pProjectionFile->write (filename.mb_str(wxConvUTF8))) {
193     *theApp->getLog() << _T("Unable to write projection file ") << filename << _T("\n");
194     return false;
195   }
196   if (theApp->getVerboseLogging())
197     *theApp->getLog() << _T("Wrote projection file ") << filename << _T("\n");
198   Modify(false);
199   return true;
200 }
201
202 ProjectionFileDocument::~ProjectionFileDocument()
203 {
204   cancelRunningTasks();
205
206   delete m_pProjectionFile;
207 }
208
209 bool
210 ProjectionFileDocument::OnOpenDocument(const wxString& filename)
211 {
212   if (! OnSaveModified())
213     return false;
214
215   if (! m_pProjectionFile->read (filename.mb_str(wxConvUTF8))) {
216     *theApp->getLog() << _T("Unable to read projection file ") << filename << _T("\n");
217     m_bBadFileOpen = true;
218     return false;
219   }
220   m_bBadFileOpen = false;
221
222   if (theApp->getVerboseLogging() && filename != _T(""))
223     *theApp->getLog() << _T("Read projection file ") << filename << _T("\n");
224
225   SetFilename(filename, true);
226   Modify(false);
227   getView()->setInitialClientSize();
228   UpdateAllViews();
229
230   return true;
231 }
232
233 bool
234 ProjectionFileDocument::IsModified(void) const
235 {
236   return wxDocument::IsModified();
237 }
238
239 void
240 ProjectionFileDocument::Modify(bool mod)
241 {
242   wxDocument::Modify(mod);
243 }
244
245
246 ProjectionFileView*
247 ProjectionFileDocument::getView() const
248 {
249   return dynamic_cast<ProjectionFileView*>(GetFirstView());
250 }
251
252 void
253 ProjectionFileDocument::Activate()
254 {
255 #if CTSIM_MDI
256   getView()->getFrame()->Activate();
257 #endif
258 };
259
260 // PhantomFileDocument
261
262 IMPLEMENT_DYNAMIC_CLASS(PhantomFileDocument, BackgroundProcessingDocument)
263
264 PhantomFileDocument::~PhantomFileDocument()
265 {
266   cancelRunningTasks();
267 }
268
269 bool
270 PhantomFileDocument::OnOpenDocument(const wxString& constFilename)
271 {
272   if (! OnSaveModified())
273     return false;
274
275   wxString filename (constFilename);
276
277   if (wxFile::Exists (filename)) {
278     m_phantom.createFromPhmFile (filename.mb_str(wxConvUTF8));
279     if (theApp->getVerboseLogging())
280       *theApp->getLog() << _T("Read phantom file ") << filename << _T("\n");
281   } else {
282     filename.Replace (_T(".phm"), _T(""));
283     m_phantom.createFromPhantom (filename.mb_str(wxConvUTF8));
284   }
285   m_namePhantom = filename;
286   SetFilename (filename, true);
287   if (m_phantom.fail()) {
288     *theApp->getLog() << _T("Failure creating phantom ") << filename << _T("\n");
289     m_bBadFileOpen = true;
290     return false;
291   }
292   m_idPhantom = m_phantom.id();
293   Modify(false);
294   UpdateAllViews();
295   m_bBadFileOpen = false;
296
297   return true;
298 }
299
300 bool
301 PhantomFileDocument::OnSaveDocument(const wxString& filename)
302 {
303   if (! m_phantom.fileWrite (filename.mb_str(wxConvUTF8))) {
304     *theApp->getLog() << _T("Unable to write phantom file ") << filename << _T("\n");
305     return false;
306   }
307   if (theApp->getVerboseLogging())
308     *theApp->getLog() << _T("Wrote phantom file ") << filename << _T("\n");
309   Modify(false);
310   return true;
311 }
312
313 bool
314 PhantomFileDocument::IsModified(void) const
315 {
316   return false;
317 }
318
319 void
320 PhantomFileDocument::Modify(bool mod)
321 {
322   wxDocument::Modify(mod);
323 }
324
325
326 PhantomFileView*
327 PhantomFileDocument::getView() const
328 {
329   return dynamic_cast<PhantomFileView*>(GetFirstView());
330 }
331
332 void
333 PhantomFileDocument::Activate()
334 {
335 #if CTSIM_MDI
336   getView()->getFrame()->Activate();
337 #endif
338 };
339
340 // PlotFileDocument
341
342 IMPLEMENT_DYNAMIC_CLASS(PlotFileDocument, wxDocument)
343
344 bool
345 PlotFileDocument::OnSaveDocument(const wxString& filename)
346 {
347   m_namePlot = filename.c_str();
348   if (! m_plot.fileWrite (filename.mb_str(wxConvUTF8))) {
349     *theApp->getLog() << _T("Unable to write plot file ") << filename << _T("\n");
350     return false;
351   }
352   if (theApp->getVerboseLogging())
353     *theApp->getLog() << _T("Wrote plot file ") << filename << _T("\n");
354   Modify(false);
355   return true;
356 }
357
358 bool
359 PlotFileDocument::OnOpenDocument(const wxString& filename)
360 {
361   if (! OnSaveModified())
362     return false;
363
364   if (! m_plot.fileRead (filename.mb_str(wxConvUTF8))) {
365     *theApp->getLog() << _T("Unable to read plot file ") << filename << _T("\n");
366     m_bBadFileOpen = true;
367     return false;
368   }
369   m_bBadFileOpen = false;
370
371   if (theApp->getVerboseLogging() && filename != _T(""))
372     *theApp->getLog() << _T("Read plot file ") << filename << _T("\n");
373
374   SetFilename (filename, true);
375   m_namePlot = filename.c_str();
376   Modify (false);
377   getView()->setInitialClientSize();
378   UpdateAllViews();
379
380   return true;
381 }
382
383
384 bool
385 PlotFileDocument::IsModified(void) const
386 {
387   return wxDocument::IsModified();
388 }
389
390 void
391 PlotFileDocument::Modify (bool mod)
392 {
393   wxDocument::Modify(mod);
394 }
395
396 PlotFileView*
397 PlotFileDocument::getView() const
398 {
399   return dynamic_cast<PlotFileView*>(GetFirstView());
400 }
401
402 void
403 PlotFileDocument::Activate()
404 {
405 #if CTSIM_MDI
406   getView()->getFrame()->Activate();
407 #endif
408 };
409
410 //////////////////////////////////////////////////////////////////////////
411 //
412 // TextFileDocument
413 //
414 //////////////////////////////////////////////////////////////////////////
415
416 IMPLEMENT_DYNAMIC_CLASS(TextFileDocument, wxDocument)
417
418 bool
419 TextFileDocument::OnSaveDocument(const wxString& filename)
420 {
421   TextFileView *view = getView();
422   if (! view->getTextCtrl()->SaveFile(filename))
423     return false;
424   Modify(false);
425   return true;
426 }
427
428 bool
429 TextFileDocument::OnOpenDocument(const wxString& filename)
430 {
431   TextFileView *view = getView();
432
433   if (! view->getTextCtrl()->LoadFile(filename)) {
434     m_bBadFileOpen = true;
435     return false;
436   }
437
438   SetFilename (filename, true);
439   Modify (false);
440   UpdateAllViews();
441   m_bBadFileOpen = false;
442   return true;
443 }
444
445 bool
446 TextFileDocument::IsModified(void) const
447 {
448   return false;
449
450   TextFileView *view = getView();
451
452   if (view)
453     return (wxDocument::IsModified() || view->getTextCtrl()->IsModified());
454   else
455     return wxDocument::IsModified();
456 }
457
458
459 TextFileView*
460 TextFileDocument::getView() const
461 {
462   return dynamic_cast<TextFileView*>(GetFirstView());
463 }
464
465 wxTextCtrl*
466 TextFileDocument::getTextCtrl()
467 {
468   return dynamic_cast<TextFileView*>(GetFirstView())->getTextCtrl();
469 }
470
471 //////////////////////////////////////////////////////////////////////////
472 //
473 // Graph3dFileDocument
474 //
475 //////////////////////////////////////////////////////////////////////////
476
477 #if wxUSE_GLCANVAS
478
479 IMPLEMENT_DYNAMIC_CLASS(Graph3dFileDocument, wxDocument)
480
481 Graph3dFileDocument::Graph3dFileDocument(void)
482 : m_bBadFileOpen(false), m_nVertices(0), m_pVertices(0), m_pNormals(0),m_nx(0),m_ny(0),m_array(0)
483 {
484 }
485
486 Graph3dFileDocument::~Graph3dFileDocument()
487 {
488 }
489
490 bool
491 Graph3dFileDocument::OnSaveDocument(const wxString& filename)
492 {
493   Modify(false);
494   return true;
495 }
496
497 bool
498 Graph3dFileDocument::OnOpenDocument(const wxString& filename)
499 {
500   SetFilename (filename, true);
501   Modify (false);
502   getView()->setInitialClientSize();
503   UpdateAllViews();
504   m_bBadFileOpen = false;
505   return true;
506 }
507
508 bool
509 Graph3dFileDocument::IsModified(void) const
510 {
511     return wxDocument::IsModified();
512 }
513
514
515 Graph3dFileView*
516 Graph3dFileDocument::getView() const
517 {
518   return dynamic_cast<Graph3dFileView*>(GetFirstView());
519 }
520
521 bool
522 Graph3dFileDocument::createFromImageFile (const ImageFile& rImageFile)
523 {
524   m_nx = rImageFile.nx();
525   m_ny = rImageFile.ny();
526   m_array = rImageFile.getArray();
527
528   return true;
529 }
530
531 void
532 Graph3dFileDocument::Activate()
533 {
534 #if CTSIM_MDI
535   getView()->getFrame()->Activate();
536 #endif
537 };
538
539
540 #endif // wxUSE_GLCANVAS