Update copyright date; remove old CVS keyword
[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   UpdateAllViews();
80   m_bBadFileOpen = false;
81
82   return true;
83 }
84
85 bool
86 ImageFileDocument::IsModified(void) const
87 {
88   return wxDocument::IsModified();
89 }
90
91 void
92 ImageFileDocument::Modify(bool mod)
93 {
94   wxDocument::Modify(mod);
95 }
96
97 ImageFileView*
98 ImageFileDocument::getView() const
99 {
100   return dynamic_cast<ImageFileView*>(GetFirstView());
101 }
102
103 bool
104 ImageFileDocument::Revert ()
105 {
106   if (IsModified()) {
107     wxString msg (_T("Revert to saved "));
108     msg += GetFilename();
109     msg += _T("?");
110     wxMessageDialog dialog (getView()->getFrame(), msg, _T("Are you sure?"), wxYES_NO | wxNO_DEFAULT);
111     if (dialog.ShowModal() == wxID_YES) {
112       if (theApp->getVerboseLogging())
113         *theApp->getLog() << _T("Reverting to saved ") << GetFilename() << _T("\n");
114       Modify (false);
115       OnOpenDocument (GetFilename());
116     }
117   }
118   UpdateAllViews();
119
120   return true;
121 }
122
123 void
124 ImageFileDocument::Activate()
125 {
126 #if CTSIM_MDI
127   getView()->getFrame()->Activate();
128 #endif
129 };
130
131 // BackgroundProcessingDocument - Base Class
132
133 IMPLEMENT_DYNAMIC_CLASS(BackgroundProcessingDocument, wxDocument)
134 BEGIN_EVENT_TABLE(BackgroundProcessingDocument, wxDocument)
135 END_EVENT_TABLE()
136
137 #ifdef HAVE_WXTHREADS
138 void
139 BackgroundProcessingDocument::addBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
140 {
141   wxCriticalSectionLocker locker (m_criticalSection);
142   if (pSupervisor)
143     m_vecpBackgroundSupervisors.push_back (pSupervisor);
144 }
145
146 void
147 BackgroundProcessingDocument::removeBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
148 {
149   m_criticalSection.Enter();
150   bool bFound = false;
151   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin();
152         i != m_vecpBackgroundSupervisors.end();
153         i++)
154           if (*i == pSupervisor) {
155             m_vecpBackgroundSupervisors.erase(i);
156             bFound = true;
157             break;
158         }
159   m_criticalSection.Leave();
160
161   if (! bFound)
162      sys_error (ERR_SEVERE, "Could not find background task [OnRemoveBackground]");
163 }
164 #endif
165
166 void
167 BackgroundProcessingDocument::cancelRunningTasks()
168 {
169 #ifdef HAVE_WXTHREADS
170   m_criticalSection.Enter();
171   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin();
172         i != m_vecpBackgroundSupervisors.end(); i++)
173           (*i)->onCancel();
174   m_criticalSection.Leave();
175
176   while (m_vecpBackgroundSupervisors.size() > 0) {
177      ::wxYield();
178      ::wxMilliSleep(50);
179   }
180 #endif
181 }
182
183
184 // ProjectionFileDocument
185
186 IMPLEMENT_DYNAMIC_CLASS(ProjectionFileDocument, BackgroundProcessingDocument)
187
188 bool
189 ProjectionFileDocument::OnSaveDocument(const wxString& filename)
190 {
191   if (! m_pProjectionFile->write (filename.mb_str(wxConvUTF8))) {
192     *theApp->getLog() << _T("Unable to write projection file ") << filename << _T("\n");
193     return false;
194   }
195   if (theApp->getVerboseLogging())
196     *theApp->getLog() << _T("Wrote projection file ") << filename << _T("\n");
197   Modify(false);
198   return true;
199 }
200
201 ProjectionFileDocument::~ProjectionFileDocument()
202 {
203   cancelRunningTasks();
204
205   delete m_pProjectionFile;
206 }
207
208 bool
209 ProjectionFileDocument::OnOpenDocument(const wxString& filename)
210 {
211   if (! OnSaveModified())
212     return false;
213
214   if (! m_pProjectionFile->read (filename.mb_str(wxConvUTF8))) {
215     *theApp->getLog() << _T("Unable to read projection file ") << filename << _T("\n");
216     m_bBadFileOpen = true;
217     return false;
218   }
219   m_bBadFileOpen = false;
220
221   if (theApp->getVerboseLogging() && filename != _T(""))
222     *theApp->getLog() << _T("Read projection file ") << filename << _T("\n");
223
224   SetFilename(filename, true);
225   Modify(false);
226   getView()->setInitialClientSize();
227   UpdateAllViews();
228
229   return true;
230 }
231
232 bool
233 ProjectionFileDocument::IsModified(void) const
234 {
235   return wxDocument::IsModified();
236 }
237
238 void
239 ProjectionFileDocument::Modify(bool mod)
240 {
241   wxDocument::Modify(mod);
242 }
243
244
245 ProjectionFileView*
246 ProjectionFileDocument::getView() const
247 {
248   return dynamic_cast<ProjectionFileView*>(GetFirstView());
249 }
250
251 void
252 ProjectionFileDocument::Activate()
253 {
254 #if CTSIM_MDI
255   getView()->getFrame()->Activate();
256 #endif
257 };
258
259 // PhantomFileDocument
260
261 IMPLEMENT_DYNAMIC_CLASS(PhantomFileDocument, BackgroundProcessingDocument)
262
263 PhantomFileDocument::~PhantomFileDocument()
264 {
265   cancelRunningTasks();
266 }
267
268 bool
269 PhantomFileDocument::OnOpenDocument(const wxString& constFilename)
270 {
271   if (! OnSaveModified())
272     return false;
273
274   wxString filename (constFilename);
275
276   if (wxFile::Exists (filename)) {
277     m_phantom.createFromFile (filename.mb_str(wxConvUTF8));
278     if (theApp->getVerboseLogging())
279       *theApp->getLog() << _T("Read phantom file ") << filename << _T("\n");
280   } else {
281     filename.Replace (_T(".phm"), _T(""));
282     m_phantom.createFromPhantom (filename.mb_str(wxConvUTF8));
283   }
284   m_namePhantom = filename;
285   SetFilename (filename, true);
286   if (m_phantom.fail()) {
287     *theApp->getLog() << _T("Failure creating phantom ") << filename << _T("\n");
288     m_bBadFileOpen = true;
289     return false;
290   }
291   m_idPhantom = m_phantom.id();
292   Modify(false);
293   UpdateAllViews();
294   m_bBadFileOpen = false;
295
296   return true;
297 }
298
299 bool
300 PhantomFileDocument::OnSaveDocument(const wxString& filename)
301 {
302   if (! m_phantom.fileWrite (filename.mb_str(wxConvUTF8))) {
303     *theApp->getLog() << _T("Unable to write phantom file ") << filename << _T("\n");
304     return false;
305   }
306   if (theApp->getVerboseLogging())
307     *theApp->getLog() << _T("Wrote phantom file ") << filename << _T("\n");
308   Modify(false);
309   return true;
310 }
311
312 bool
313 PhantomFileDocument::IsModified(void) const
314 {
315   return false;
316 }
317
318 void
319 PhantomFileDocument::Modify(bool mod)
320 {
321   wxDocument::Modify(mod);
322 }
323
324
325 PhantomFileView*
326 PhantomFileDocument::getView() const
327 {
328   return dynamic_cast<PhantomFileView*>(GetFirstView());
329 }
330
331 void
332 PhantomFileDocument::Activate()
333 {
334 #if CTSIM_MDI
335   getView()->getFrame()->Activate();
336 #endif
337 };
338
339 // PlotFileDocument
340
341 IMPLEMENT_DYNAMIC_CLASS(PlotFileDocument, wxDocument)
342
343 bool
344 PlotFileDocument::OnSaveDocument(const wxString& filename)
345 {
346   m_namePlot = filename.c_str();
347   if (! m_plot.fileWrite (filename.mb_str(wxConvUTF8))) {
348     *theApp->getLog() << _T("Unable to write plot file ") << filename << _T("\n");
349     return false;
350   }
351   if (theApp->getVerboseLogging())
352     *theApp->getLog() << _T("Wrote plot file ") << filename << _T("\n");
353   Modify(false);
354   return true;
355 }
356
357 bool
358 PlotFileDocument::OnOpenDocument(const wxString& filename)
359 {
360   if (! OnSaveModified())
361     return false;
362
363   if (! m_plot.fileRead (filename.mb_str(wxConvUTF8))) {
364     *theApp->getLog() << _T("Unable to read plot file ") << filename << _T("\n");
365     m_bBadFileOpen = true;
366     return false;
367   }
368   m_bBadFileOpen = false;
369
370   if (theApp->getVerboseLogging() && filename != _T(""))
371     *theApp->getLog() << _T("Read plot file ") << filename << _T("\n");
372
373   SetFilename (filename, true);
374   m_namePlot = filename.c_str();
375   Modify (false);
376   getView()->setInitialClientSize();
377   UpdateAllViews();
378
379   return true;
380 }
381
382
383 bool
384 PlotFileDocument::IsModified(void) const
385 {
386   return wxDocument::IsModified();
387 }
388
389 void
390 PlotFileDocument::Modify (bool mod)
391 {
392   wxDocument::Modify(mod);
393 }
394
395 PlotFileView*
396 PlotFileDocument::getView() const
397 {
398   return dynamic_cast<PlotFileView*>(GetFirstView());
399 }
400
401 void
402 PlotFileDocument::Activate()
403 {
404 #if CTSIM_MDI
405   getView()->getFrame()->Activate();
406 #endif
407 };
408
409 //////////////////////////////////////////////////////////////////////////
410 //
411 // TextFileDocument
412 //
413 //////////////////////////////////////////////////////////////////////////
414
415 IMPLEMENT_DYNAMIC_CLASS(TextFileDocument, wxDocument)
416
417 bool
418 TextFileDocument::OnSaveDocument(const wxString& filename)
419 {
420   TextFileView *view = getView();
421   if (! view->getTextCtrl()->SaveFile(filename))
422     return false;
423   Modify(false);
424   return true;
425 }
426
427 bool
428 TextFileDocument::OnOpenDocument(const wxString& filename)
429 {
430   TextFileView *view = getView();
431
432   if (! view->getTextCtrl()->LoadFile(filename)) {
433     m_bBadFileOpen = true;
434     return false;
435   }
436
437   SetFilename (filename, true);
438   Modify (false);
439   UpdateAllViews();
440   m_bBadFileOpen = false;
441   return true;
442 }
443
444 bool
445 TextFileDocument::IsModified(void) const
446 {
447   return false;
448
449   TextFileView *view = getView();
450
451   if (view)
452     return (wxDocument::IsModified() || view->getTextCtrl()->IsModified());
453   else
454     return wxDocument::IsModified();
455 }
456
457
458 TextFileView*
459 TextFileDocument::getView() const
460 {
461   return dynamic_cast<TextFileView*>(GetFirstView());
462 }
463
464 wxTextCtrl*
465 TextFileDocument::getTextCtrl()
466 {
467   return dynamic_cast<TextFileView*>(GetFirstView())->getTextCtrl();
468 }
469
470 //////////////////////////////////////////////////////////////////////////
471 //
472 // Graph3dFileDocument
473 //
474 //////////////////////////////////////////////////////////////////////////
475
476 #if wxUSE_GLCANVAS
477
478 IMPLEMENT_DYNAMIC_CLASS(Graph3dFileDocument, wxDocument)
479
480 Graph3dFileDocument::Graph3dFileDocument(void)
481 : m_bBadFileOpen(false), m_nVertices(0), m_pVertices(0), m_pNormals(0),m_nx(0),m_ny(0),m_array(0)
482 {
483 }
484
485 Graph3dFileDocument::~Graph3dFileDocument()
486 {
487 }
488
489 bool
490 Graph3dFileDocument::OnSaveDocument(const wxString& filename)
491 {
492   Modify(false);
493   return true;
494 }
495
496 bool
497 Graph3dFileDocument::OnOpenDocument(const wxString& filename)
498 {
499   SetFilename (filename, true);
500   Modify (false);
501   getView()->setInitialClientSize();
502   UpdateAllViews();
503   m_bBadFileOpen = false;
504   return true;
505 }
506
507 bool
508 Graph3dFileDocument::IsModified(void) const
509 {
510     return wxDocument::IsModified();
511 }
512
513
514 Graph3dFileView*
515 Graph3dFileDocument::getView() const
516 {
517   return dynamic_cast<Graph3dFileView*>(GetFirstView());
518 }
519
520 bool
521 Graph3dFileDocument::createFromImageFile (const ImageFile& rImageFile)
522 {
523   m_nx = rImageFile.nx();
524   m_ny = rImageFile.ny();
525   m_array = rImageFile.getArray();
526
527   return true;
528 }
529
530 void
531 Graph3dFileDocument::Activate()
532 {
533 #if CTSIM_MDI
534   getView()->getFrame()->Activate();
535 #endif
536 };
537
538
539 #endif // wxUSE_GLCANVAS