r632: Added Clipboard functions to image files
[ctsim.git] / src / docs.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          doc.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.34 2001/03/11 17:55:29 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()->OnUpdate (getView(), NULL);
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 void
108 ImageFileDocument::Activate()
109 {
110 #if CTSIM_MDI
111   getView()->getFrame()->Activate();
112 #endif
113 };
114
115 bool
116 ImageFileDocument::Revert ()
117 {
118   if (IsModified()) {
119     wxString msg ("Revert to saved ");
120     msg += GetFilename();
121     msg += "?";
122     wxMessageDialog dialog (getView()->getFrame(), msg, "Are you sure?", wxYES_NO | wxNO_DEFAULT);
123     if (dialog.ShowModal() == wxID_YES) {
124       if (theApp->getVerboseLogging())
125         *theApp->getLog() << "Reverting to saved " << GetFilename() << "\n";
126       Modify (false);
127       OnOpenDocument (GetFilename());
128     }
129   }
130   getView()->OnUpdate (getView(), NULL);
131   UpdateAllViews();
132
133   return true;
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   GetFirstView()->OnUpdate (GetFirstView(), NULL);
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 // PhantomFileDocument
255
256 IMPLEMENT_DYNAMIC_CLASS(PhantomFileDocument, BackgroundProcessingTask)
257
258 PhantomFileDocument::~PhantomFileDocument()
259 {
260   cancelRunningTasks();
261 }
262
263 bool 
264 PhantomFileDocument::OnOpenDocument(const wxString& filename)
265 {
266   if (! OnSaveModified())
267     return false;
268
269   wxString myFilename = filename;
270   if (wxFile::Exists (myFilename)) {
271     m_phantom.createFromFile (myFilename);
272     if (theApp->getVerboseLogging())
273       *theApp->getLog() << "Read phantom file " << filename << "\n";
274   } else {
275     myFilename.Replace (".phm", "");
276     m_phantom.createFromPhantom (myFilename);
277   }
278   m_namePhantom = myFilename;
279   SetFilename (myFilename, true);
280   if (m_phantom.fail()) {
281     *theApp->getLog() << "Failure creating phantom " << myFilename << "\n";
282     m_bBadFileOpen = true;
283     return false;
284   }
285   m_idPhantom = m_phantom.id();
286   Modify(false);
287   UpdateAllViews();
288   GetFirstView()->OnUpdate (GetFirstView(), NULL);
289   m_bBadFileOpen = false;
290   
291   return true;
292 }
293
294 bool 
295 PhantomFileDocument::OnSaveDocument(const wxString& filename)
296 {
297   if (! m_phantom.fileWrite (filename.c_str())) {
298     *theApp->getLog() << "Unable to write phantom file " << filename << "\n";
299     return false;
300   }
301   if (theApp->getVerboseLogging())
302     *theApp->getLog() << "Wrote phantom file " << filename << "\n";
303   Modify(false);
304   return true;
305 }
306
307 bool 
308 PhantomFileDocument::IsModified(void) const
309 {
310   return false;
311 }
312
313 void 
314 PhantomFileDocument::Modify(bool mod)
315 {
316   wxDocument::Modify(mod);
317 }
318
319
320 PhantomFileView* 
321 PhantomFileDocument::getView() const
322
323   return dynamic_cast<PhantomFileView*>(GetFirstView()); 
324 }
325
326 // PlotFileDocument
327
328 IMPLEMENT_DYNAMIC_CLASS(PlotFileDocument, wxDocument)
329
330 bool 
331 PlotFileDocument::OnSaveDocument(const wxString& filename)
332 {
333   m_namePlot = filename.c_str();
334   if (! m_plot.fileWrite (filename)) {
335     *theApp->getLog() << "Unable to write plot file " << filename << "\n";
336     return false;
337   }
338   if (theApp->getVerboseLogging())
339     *theApp->getLog() << "Wrote plot file " << filename << "\n";
340   Modify(false);
341   return true;
342 }
343
344 bool 
345 PlotFileDocument::OnOpenDocument(const wxString& filename)
346 {
347   if (! OnSaveModified())
348     return false;
349
350   if (! m_plot.fileRead (filename.c_str())) {
351     *theApp->getLog() << "Unable to read plot file " << filename << "\n";
352     m_bBadFileOpen = true;
353     return false;
354   }
355   if (theApp->getVerboseLogging())
356     *theApp->getLog() << "Read plot file " << filename << "\n";
357   SetFilename (filename, true);
358   m_namePlot = filename.c_str();
359   Modify (false);
360   UpdateAllViews();
361   GetFirstView()->OnUpdate (NULL, NULL);
362   m_bBadFileOpen = false;
363   
364   return true;
365 }
366
367
368 bool 
369 PlotFileDocument::IsModified(void) const
370 {
371   return wxDocument::IsModified();
372 }
373
374 void 
375 PlotFileDocument::Modify (bool mod)
376 {
377   wxDocument::Modify(mod);
378 }
379
380 PlotFileView* 
381 PlotFileDocument::getView() const
382
383   return dynamic_cast<PlotFileView*>(GetFirstView()); 
384 }
385
386 //////////////////////////////////////////////////////////////////////////
387 //
388 // TextFileDocument
389 //
390 //////////////////////////////////////////////////////////////////////////
391
392 IMPLEMENT_DYNAMIC_CLASS(TextFileDocument, wxDocument)
393
394 bool 
395 TextFileDocument::OnSaveDocument(const wxString& filename)
396 {
397   TextFileView *view = getView();
398   if (! view->getTextCtrl()->SaveFile(filename))
399     return false;
400   Modify(false);
401   return true;
402 }
403
404 bool 
405 TextFileDocument::OnOpenDocument(const wxString& filename)
406 {
407   TextFileView *view = getView();
408   
409   if (! view->getTextCtrl()->LoadFile(filename)) {
410     m_bBadFileOpen = true;
411     return false;
412   }
413   
414   SetFilename (filename, true);
415   Modify (false);
416   UpdateAllViews();
417   m_bBadFileOpen = false;
418   return true;
419 }
420
421 bool 
422 TextFileDocument::IsModified(void) const
423 {
424   return false;
425   
426   TextFileView *view = getView();
427   
428   if (view)
429     return (wxDocument::IsModified() || view->getTextCtrl()->IsModified());
430   else
431     return wxDocument::IsModified();
432 }
433
434
435 TextFileView* 
436 TextFileDocument::getView() const
437
438   return dynamic_cast<TextFileView*>(GetFirstView()); 
439 }
440
441 wxTextCtrl* 
442 TextFileDocument::getTextCtrl()
443
444   return dynamic_cast<TextFileView*>(GetFirstView())->getTextCtrl(); 
445 }
446
447 //////////////////////////////////////////////////////////////////////////
448 //
449 // Graph3dFileDocument
450 //
451 //////////////////////////////////////////////////////////////////////////
452
453 #if wxUSE_GLCANVAS
454
455 IMPLEMENT_DYNAMIC_CLASS(Graph3dFileDocument, wxDocument)
456
457 Graph3dFileDocument::Graph3dFileDocument(void) 
458 : m_bBadFileOpen(false), m_nVertices(0), m_pVertices(0), m_pNormals(0),m_nx(0),m_ny(0),m_array(0)
459 {
460 }
461
462 Graph3dFileDocument::~Graph3dFileDocument() 
463 {
464 //    delete [] m_pVertices;
465 //    delete [] m_pNormals;
466 }
467
468 bool 
469 Graph3dFileDocument::OnSaveDocument(const wxString& filename)
470 {
471   Modify(false);
472   return true;
473 }
474
475 bool 
476 Graph3dFileDocument::OnOpenDocument(const wxString& filename)
477 {
478   SetFilename (filename, true);
479   Modify (false);
480   UpdateAllViews();
481   m_bBadFileOpen = false;
482   return true;
483 }
484
485 bool 
486 Graph3dFileDocument::IsModified(void) const
487 {
488     return wxDocument::IsModified();
489 }
490
491
492 Graph3dFileView* 
493 Graph3dFileDocument::getView() const
494
495   return dynamic_cast<Graph3dFileView*>(GetFirstView()); 
496 }
497
498 bool
499 Graph3dFileDocument::createFromImageFile (const ImageFile& rImageFile)
500 {
501 //  delete [] m_pVertices;
502 //  delete [] m_pNormals;
503
504
505   m_nx = rImageFile.nx();
506   m_ny = rImageFile.ny();
507   m_array = rImageFile.getArray();
508
509   return true;
510 }
511
512 #endif // wxUSE_GLCANVAS