r1864: border fixes
[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-2001 Kevin Rosenberg
11 **
12 **  $Id: docs.cpp,v 1.38 2002/05/03 00:40:30 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 __GNUG__
29 // #pragma implementation
30 #endif
31
32 #include "wx/wxprec.h"
33
34 #ifndef WX_PRECOMP
35 #include "wx/wx.h"
36 #endif
37 #include "wx/txtstrm.h"
38 #include "wx/file.h"
39 #include "wx/thread.h"
40
41 #if !wxUSE_DOC_VIEW_ARCHITECTURE
42 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
43 #endif
44
45 #include "ct.h"
46 #include "ctsim.h"
47 #include "docs.h"
48 #include "views.h"
49 #include "threadrecon.h"
50
51
52 // ImageFileDocument
53
54 IMPLEMENT_DYNAMIC_CLASS(ImageFileDocument, wxDocument)
55
56 bool ImageFileDocument::OnSaveDocument(const wxString& filename)
57 {
58   if (! m_pImageFile->fileWrite (filename)) {
59     *theApp->getLog() << "Unable to write image file " << filename << "\n";
60     return false;
61   }
62   if (theApp->getVerboseLogging())
63     *theApp->getLog() << "Wrote image file " << filename << "\n";
64   Modify(false);
65   return true;
66 }
67
68 bool ImageFileDocument::OnOpenDocument(const wxString& filename)
69 {
70   if (! OnSaveModified())
71     return false;
72
73   if (! m_pImageFile->fileRead (filename.c_str())) {
74     *theApp->getLog() << "Unable to read image file " << filename << "\n";
75     m_bBadFileOpen = true;
76     return false;
77   }
78   if (theApp->getVerboseLogging())
79     *theApp->getLog() << "Read image file " << filename << "\n";
80   SetFilename(filename, true);  
81   Modify(false);
82   UpdateAllViews();
83   getView()->setInitialClientSize();
84   m_bBadFileOpen = false;
85
86   return true;
87 }
88
89 bool 
90 ImageFileDocument::IsModified(void) const
91 {
92   return wxDocument::IsModified();
93 }
94
95 void 
96 ImageFileDocument::Modify(bool mod)
97 {
98   wxDocument::Modify(mod);
99 }
100
101 ImageFileView* 
102 ImageFileDocument::getView() const
103
104   return dynamic_cast<ImageFileView*>(GetFirstView()); 
105 }
106
107 bool
108 ImageFileDocument::Revert ()
109 {
110   if (IsModified()) {
111     wxString msg ("Revert to saved ");
112     msg += GetFilename();
113     msg += "?";
114     wxMessageDialog dialog (getView()->getFrame(), msg, "Are you sure?", wxYES_NO | wxNO_DEFAULT);
115     if (dialog.ShowModal() == wxID_YES) {
116       if (theApp->getVerboseLogging())
117         *theApp->getLog() << "Reverting to saved " << GetFilename() << "\n";
118       Modify (false);
119       OnOpenDocument (GetFilename());
120     }
121   }
122   //getView()->OnUpdate (getView(), NULL);
123   UpdateAllViews();
124
125   return true;
126 }
127
128 void
129 ImageFileDocument::Activate()
130 {
131 #if CTSIM_MDI
132   getView()->getFrame()->Activate();
133 #endif
134 };
135
136 // BackgroundProcessingDocument - Base Class
137
138 IMPLEMENT_DYNAMIC_CLASS(BackgroundProcessingDocument, wxDocument)
139 BEGIN_EVENT_TABLE(BackgroundProcessingDocument, wxDocument)
140 END_EVENT_TABLE()
141
142 #ifdef HAVE_WXTHREADS
143 void
144 BackgroundProcessingDocument::addBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
145 {
146   wxCriticalSectionLocker locker (m_criticalSection);
147   if (pSupervisor)
148     m_vecpBackgroundSupervisors.push_back (pSupervisor);
149 }
150
151 void
152 BackgroundProcessingDocument::removeBackgroundSupervisor (BackgroundSupervisor* pSupervisor)
153 {
154   m_criticalSection.Enter();
155   bool bFound = false;
156   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin(); 
157         i != m_vecpBackgroundSupervisors.end(); 
158         i++) 
159           if (*i == pSupervisor) {
160             m_vecpBackgroundSupervisors.erase(i);
161             bFound = true;
162             break;
163         }
164   m_criticalSection.Leave();
165
166   if (! bFound) 
167      sys_error (ERR_SEVERE, "Could not find background task [OnRemoveBackground]");
168 }
169 #endif
170
171 void
172 BackgroundProcessingDocument::cancelRunningTasks()
173 {
174 #ifdef HAVE_WXTHREADS
175   m_criticalSection.Enter();
176   for (BackgroundContainer::iterator i = m_vecpBackgroundSupervisors.begin(); 
177         i != m_vecpBackgroundSupervisors.end(); i++)
178           (*i)->onCancel();
179   m_criticalSection.Leave();
180
181   while (m_vecpBackgroundSupervisors.size() > 0) {
182      ::wxYield();
183      ::wxUsleep(50);
184   }
185 #endif
186 }
187
188
189 // ProjectionFileDocument
190
191 IMPLEMENT_DYNAMIC_CLASS(ProjectionFileDocument, BackgroundProcessingTask)
192
193 bool 
194 ProjectionFileDocument::OnSaveDocument(const wxString& filename)
195 {
196   if (! m_pProjectionFile->write (filename.c_str())) {
197     *theApp->getLog() << "Unable to write projection file " << filename << "\n";
198     return false;
199   }
200   if (theApp->getVerboseLogging())
201     *theApp->getLog() << "Wrote projection file " << filename << "\n";
202   Modify(false);
203   return true;
204 }
205
206 ProjectionFileDocument::~ProjectionFileDocument()
207 {
208   cancelRunningTasks();
209
210   delete m_pProjectionFile;
211 }
212
213 bool 
214 ProjectionFileDocument::OnOpenDocument(const wxString& filename)
215 {
216   if (! OnSaveModified())
217     return false;
218
219   if (! m_pProjectionFile->read (filename.c_str())) {
220     *theApp->getLog() << "Unable to read projection file " << filename << "\n";
221     m_bBadFileOpen = true;
222     return false;
223   }
224   if (theApp->getVerboseLogging())
225     *theApp->getLog() << "Read projection file " << filename << "\n";
226   SetFilename(filename, true);
227   Modify(false);
228   UpdateAllViews();
229   getView()->setInitialClientSize();
230   m_bBadFileOpen = false;
231   
232   return true;
233 }
234
235 bool 
236 ProjectionFileDocument::IsModified(void) const
237 {
238   return wxDocument::IsModified();
239 }
240
241 void 
242 ProjectionFileDocument::Modify(bool mod)
243 {
244   wxDocument::Modify(mod);
245 }
246
247
248 ProjectionFileView* 
249 ProjectionFileDocument::getView() const
250
251   return dynamic_cast<ProjectionFileView*>(GetFirstView()); 
252 }
253
254 void
255 ProjectionFileDocument::Activate()
256 {
257 #if CTSIM_MDI
258   getView()->getFrame()->Activate();
259 #endif
260 };
261
262 // PhantomFileDocument
263
264 IMPLEMENT_DYNAMIC_CLASS(PhantomFileDocument, BackgroundProcessingTask)
265
266 PhantomFileDocument::~PhantomFileDocument()
267 {
268   cancelRunningTasks();
269 }
270
271 bool 
272 PhantomFileDocument::OnOpenDocument(const wxString& filename)
273 {
274   if (! OnSaveModified())
275     return false;
276
277   wxString myFilename = filename;
278   if (wxFile::Exists (myFilename)) {
279     m_phantom.createFromFile (myFilename);
280     if (theApp->getVerboseLogging())
281       *theApp->getLog() << "Read phantom file " << filename << "\n";
282   } else {
283     myFilename.Replace (".phm", "");
284     m_phantom.createFromPhantom (myFilename);
285   }
286   m_namePhantom = myFilename;
287   SetFilename (myFilename, true);
288   if (m_phantom.fail()) {
289     *theApp->getLog() << "Failure creating phantom " << myFilename << "\n";
290     m_bBadFileOpen = true;
291     return false;
292   }
293   m_idPhantom = m_phantom.id();
294   Modify(false);
295   UpdateAllViews();
296   //GetFirstView()->OnUpdate (GetFirstView(), NULL);
297   m_bBadFileOpen = false;
298   
299   return true;
300 }
301
302 bool 
303 PhantomFileDocument::OnSaveDocument(const wxString& filename)
304 {
305   if (! m_phantom.fileWrite (filename.c_str())) {
306     *theApp->getLog() << "Unable to write phantom file " << filename << "\n";
307     return false;
308   }
309   if (theApp->getVerboseLogging())
310     *theApp->getLog() << "Wrote phantom file " << filename << "\n";
311   Modify(false);
312   return true;
313 }
314
315 bool 
316 PhantomFileDocument::IsModified(void) const
317 {
318   return false;
319 }
320
321 void 
322 PhantomFileDocument::Modify(bool mod)
323 {
324   wxDocument::Modify(mod);
325 }
326
327
328 PhantomFileView* 
329 PhantomFileDocument::getView() const
330
331   return dynamic_cast<PhantomFileView*>(GetFirstView()); 
332 }
333
334 void
335 PhantomFileDocument::Activate()
336 {
337 #if CTSIM_MDI
338   getView()->getFrame()->Activate();
339 #endif
340 };
341
342 // PlotFileDocument
343
344 IMPLEMENT_DYNAMIC_CLASS(PlotFileDocument, wxDocument)
345
346 bool 
347 PlotFileDocument::OnSaveDocument(const wxString& filename)
348 {
349   m_namePlot = filename.c_str();
350   if (! m_plot.fileWrite (filename)) {
351     *theApp->getLog() << "Unable to write plot file " << filename << "\n";
352     return false;
353   }
354   if (theApp->getVerboseLogging())
355     *theApp->getLog() << "Wrote plot file " << filename << "\n";
356   Modify(false);
357   return true;
358 }
359
360 bool 
361 PlotFileDocument::OnOpenDocument(const wxString& filename)
362 {
363   if (! OnSaveModified())
364     return false;
365
366   if (! m_plot.fileRead (filename.c_str())) {
367     *theApp->getLog() << "Unable to read plot file " << filename << "\n";
368     m_bBadFileOpen = true;
369     return false;
370   }
371   if (theApp->getVerboseLogging())
372     *theApp->getLog() << "Read plot file " << filename << "\n";
373   SetFilename (filename, true);
374   m_namePlot = filename.c_str();
375   Modify (false);
376   UpdateAllViews();
377   //GetFirstView()->OnUpdate (NULL, NULL);
378   m_bBadFileOpen = false;
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   //  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