r582: no message
[ctsim.git] / src / ctsim.cpp
index 38c939c66e47bd26adfb1acf0e065692eee12c77..0d459ad784a6d8c0458043bce3c6b2aac274f543 100644 (file)
@@ -7,9 +7,9 @@
 **   Date Started:  July 2000
 **
 **  This is part of the CTSim program
-**  Copyright (C) 1983-2000 Kevin Rosenberg
+**  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: ctsim.cpp,v 1.60 2001/01/30 05:05:41 kevin Exp $
+**  $Id: ctsim.cpp,v 1.89 2001/02/25 10:52:55 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
 #define strdup _strdup
 #endif
 
-// For compilers that support precompilation, includes "wx/wx.h".
 #include "wx/wxprec.h"
 
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
 #ifndef WX_PRECOMP
 #include "wx/wx.h"
 #endif
@@ -43,6 +38,9 @@
 #include "wx/image.h"
 #include "wx/filesys.h"
 #include "wx/fs_zip.h"
+#ifdef __WXMSW__
+#include "wx/msw/helpchm.h"
+#endif
 
 #if !wxUSE_DOC_VIEW_ARCHITECTURE
 #error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in setup.h!
 
 #include "ct.h"
 #include "ctsim.h"
-#include "ctsim-map.h"
 #include "docs.h"
 #include "views.h"
 #include "dialogs.h"
+#include "tips.h"
+#include "backgroundmgr.h"
 
 #if defined(HAVE_CONFIG_H)
 #include "config.h"
 #endif
 #endif
 
-static const char* rcsindent = "$Id: ctsim.cpp,v 1.60 2001/01/30 05:05:41 kevin Exp $";
+static const char* rcsindent = "$Id: ctsim.cpp,v 1.89 2001/02/25 10:52:55 kevin Exp $";
 
 struct option CTSimApp::ctsimOptions[] = 
 {
        {"help", 0, 0, O_HELP},
        {"version", 0, 0, O_VERSION},
+  {"print", 0, 0, O_PRINT},
        {0, 0, 0, 0}
 };
 
 IMPLEMENT_APP(CTSimApp)
 
 CTSimApp::CTSimApp()
-: m_docManager(NULL), m_pFrame(NULL), m_pLog(0), m_pLogDoc(0)
+:  m_bAdvancedOptions(false), m_bSetModifyNewDocs(true), m_bVerboseLogging(false), m_bShowStartupTips(true),
+   m_iCurrentTip(0), m_bUseBackgroundTasks(false),
+  m_docManager(NULL), m_pFrame(NULL), m_pLog(0), m_pLogDoc(0), m_pConfig(0)
 {
        theApp = this;
 }
@@ -102,10 +104,10 @@ CTSimApp::OnInit()
        setpriority (PRIO_PROCESS, 0, 15);  // set to low scheduling priority
 #endif
        
-       m_pConfig = new wxConfig("ctsim");
-       wxConfigBase::Set(m_pConfig);
+       openConfig();
        
        g_bRunningWXWindows = true;
+  bool bPrintFiles = false;
        // process options
        while (1) {
                int c = getopt_long (argc, argv, "", ctsimOptions, NULL);
@@ -125,6 +127,9 @@ CTSimApp::OnInit()
                case '?':
                        usage (argv[0]);
                        exit (0);
+    case O_PRINT:
+      bPrintFiles = true;
+      break;
                default:
                        usage (argv[0]);
                        exit (1);
@@ -138,7 +143,10 @@ CTSimApp::OnInit()
        m_pDocTemplPhantom = new wxDocTemplate (m_docManager, "PhantomFile", "*.phm", "", "phm", "PhantomFile", "PhantomView", CLASSINFO(PhantomFileDocument), CLASSINFO(PhantomFileView));
        m_pDocTemplPlot = new wxDocTemplate (m_docManager, "PlotFile", "*.plt", "", "plt", "PlotFile", "PlotView", CLASSINFO(PlotFileDocument), CLASSINFO(PlotFileView));
        m_pDocTemplText = new wxDocTemplate (m_docManager, "TextFile", "*.txt", "", "txt", "TextFile", "TextView", CLASSINFO(TextFileDocument), CLASSINFO(TextFileView), wxTEMPLATE_INVISIBLE);
-       
+#if wxUSE_GLCANVAS
+       m_pDocTemplGraph3d = new wxDocTemplate (m_docManager, "Graph3dFile", "*.g3d", "", "g3d", "Graph3dFile", "Graph3dView", CLASSINFO(Graph3dFileDocument), CLASSINFO(Graph3dFileView), wxTEMPLATE_INVISIBLE);
+#endif
+
 #if wxUSE_GIF
        wxImage::AddHandler(new wxGIFHandler);     // Required for images in the online documentation
 #endif
@@ -158,16 +166,10 @@ CTSimApp::OnInit()
        m_pFrame->Show(true);  
        SetTopWindow (m_pFrame);
        
-       for (int i = optind + 1; i <= argc; i++) {
-               wxString filename = argv [i - 1];
-               m_docManager->CreateDocument (filename, wxDOC_SILENT);
-       }
-       
        if (m_pConfig)
                m_docManager->FileHistoryLoad(*m_pConfig);
        
 #ifdef CTSIM_MDI
-#if 1
        m_pLogDoc = newTextDoc();
        if (m_pLogDoc) {
                m_pLog = m_pLogDoc->getTextCtrl();
@@ -180,29 +182,63 @@ CTSimApp::OnInit()
                m_pLogDoc->getView()->getFrame()->SetSize (0, ySize - yLogSize, xSize, yLogSize);
                m_pLogDoc->getView()->getFrame()->Show (true);
        } else
-#else
-//    wxMDIChildFrame *pLogFrame = new wxMDIChildFrame (m_pFrame, -1, "Log", wxDefaultPosition, wxSize(0,0), wxTHICK_FRAME, "Log");
-    m_pLog = new wxTextCtrl(m_pFrame->GetClientWindow(), -1, "", wxPoint(0,0), wxSize(0,0), wxTE_MULTILINE | wxTE_READONLY);
-               int xSize, ySize;
-               m_pFrame->GetClientSize(&xSize, &ySize);
-               int yLogSize = ySize / 5;
-               m_pLog->SetSize (0, ySize - yLogSize, xSize, yLogSize);
-               m_pLog->Show (true);
-    m_pLog->Enable (true);
-#endif
 #else
                m_pLog = new wxTextCtrl (m_pFrame, -1, "Log Window\n", wxPoint(0, 0), wxSize(0,0), wxTE_MULTILINE | wxTE_READONLY);
 #endif
        wxLog::SetActiveTarget (new wxLogTextCtrl(m_pLog));
-       
+
+       wxString helpDir;
+       if (! m_pConfig->Read("HelpDir", &helpDir))
+               helpDir = ::wxGetCwd();
 #ifdef CTSIM_WINHELP
-       if (! m_pFrame->getWinHelpController().Initialize("ctsim"))
+       if (! m_pFrame->getWinHelpController().Initialize(helpDir + "/ctsim"))
                *m_pLog << "Cannot initialize the Windows Help system" << "\n";
-#endif
-       if (! m_pFrame->getHtmlHelpController().Initialize(::wxGetCwd() + "/ctsim"))
+#else
+       if (! m_pFrame->getHtmlHelpController().Initialize(helpDir + "/ctsim") &&
+               ! m_pFrame->getHtmlHelpController().Initialize("/usr/local/man/ctsim"))
                *m_pLog << "Cannot initialize the HTML Help system" << "\n";
-       
-       return true;
+       else {
+           if (::wxDirExists ("/tmp"))
+               m_pFrame->getHtmlHelpController().SetTempDir(_T("/tmp"));
+           m_pFrame->getHtmlHelpController().UseConfig (m_pConfig);
+       }
+#endif
+
+       for (int i = optind + 1; i <= argc; i++) {
+               wxString filename = argv [i - 1];
+               wxDocument* pNewDoc = m_docManager->CreateDocument (filename, wxDOC_SILENT);
+    if (bPrintFiles) {
+      wxView* pNewView = pNewDoc->GetFirstView();
+      wxPrintout *printout = pNewView->OnCreatePrintout();
+      if (printout) {
+        wxPrinter printer;
+        printer.Print(pNewView->GetFrame(), printout, TRUE);
+        delete printout;
+      }
+      wxCommandEvent nullEvent;
+      nullEvent.SetId (wxID_CLOSE);
+      m_docManager->OnFileClose (nullEvent);
+    }
+       }
+  if (bPrintFiles) {
+    wxCommandEvent closeEvent;
+    closeEvent.SetInt (MAINMENU_FILE_EXIT);
+    m_pFrame->AddPendingEvent(closeEvent);
+  }
+
+  if (getStartupTips())
+    ShowTips();
+
+  m_pBackgroundMgr = new BackgroundManager;
+  return true;
+}
+
+void
+CTSimApp::ShowTips()
+{
+    CTSimTipProvider tipProvider (m_iCurrentTip);
+    setStartupTips (::wxShowTip (m_pFrame, &tipProvider, getStartupTips()));
+    m_iCurrentTip = tipProvider.GetCurrentTip();
 }
 
 
@@ -229,12 +265,46 @@ CTSimApp::usage(const char* program)
 int
 CTSimApp::OnExit()
 {
+  closeConfig();
+
 #ifdef HAVE_DMALLOC
        dmalloc_shutdown();
 #endif
        return 0;
 }
 
+void
+CTSimApp::openConfig()
+{
+#ifdef MSVC
+  m_pConfig = new wxConfig("ctsim", "Kevin Rosenberg", "", "", wxCONFIG_USE_LOCAL_FILE);
+#else
+  m_pConfig = new wxConfig("ctsim", "Kevin Rosenberg", ".ctsim", "", wxCONFIG_USE_LOCAL_FILE);
+#endif
+
+       wxConfigBase::Set(m_pConfig);
+  m_pConfig->Read ("AdvancedOptions", &m_bAdvancedOptions);
+  m_pConfig->Read ("SetModifyNewDocs", &m_bSetModifyNewDocs);
+  m_pConfig->Read ("VerboseLogging", &m_bVerboseLogging);
+  m_pConfig->Read ("StartupTips", &m_bShowStartupTips);
+  m_pConfig->Read ("CurrentTip", &m_iCurrentTip);
+  m_pConfig->Read ("UseBackgroundTasks", &m_bUseBackgroundTasks);
+}
+
+void
+CTSimApp::closeConfig()
+{
+  m_pConfig->Write ("AdvancedOptions", m_bAdvancedOptions);
+  m_pConfig->Write ("SetModifyNewDocs", m_bSetModifyNewDocs);
+  m_pConfig->Write ("VerboseLogging", m_bVerboseLogging);
+  m_pConfig->Write ("StartupTips", m_bShowStartupTips);
+  m_pConfig->Write ("CurrentTip", m_iCurrentTip);
+  m_pConfig->Write ("UseBackgroundTasks", m_bUseBackgroundTasks);
+
+       delete m_pConfig;
+}
+
+
 wxString
 CTSimApp::getUntitledFilename()
 {
@@ -259,9 +329,24 @@ IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
 BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
 #endif
 
+EVT_MENU(MAINMENU_FILE_PREFERENCES, MainFrame::OnPreferences)
 EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
 EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
-EVT_MENU(MAINMENU_HELP_TOPICS, MainFrame::OnHelpTopics)
+EVT_MENU(MAINMENU_HELP_TIPS, MainFrame::OnHelpTips)
+EVT_MENU(IDH_QUICKSTART, MainFrame::OnHelpButton)
+EVT_MENU(MAINMENU_LOG_EVENT, MainFrame::OnLogEvent)
+EVT_BUTTON(IDH_DLG_RASTERIZE, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_PROJECTIONS, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_RECONSTRUCTION, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_FILTER, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_MINMAX, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_EXPORT, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_PHANTOM, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_COMPARISON, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_PREFERENCES, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_POLAR, MainFrame::OnHelpButton)
+EVT_BUTTON(IDH_DLG_AUTOSCALE, MainFrame::OnHelpButton)
+
 EVT_SIZE(MainFrame::OnSize)
 
 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
@@ -314,6 +399,7 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const
        file_menu->Append(wxID_OPEN, "&Open...\tCtrl-O");
        
        file_menu->AppendSeparator();
+  file_menu->Append (MAINMENU_FILE_PREFERENCES, "Prefere&nces...");
        file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
        
        //  history of files visited
@@ -326,12 +412,13 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const
 #endif
        
        wxMenu* help_menu = new wxMenu;
-       help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents\tF1");
-       help_menu->Append(MAINMENU_HELP_TOPICS, "&Topics\tCtrl-T");
+       help_menu->Append (MAINMENU_HELP_CONTENTS, "&Contents\tF1");
+  help_menu->Append (MAINMENU_HELP_TIPS, "&Tips");
+  help_menu->Append (IDH_QUICKSTART, "&Quick Start");
 #if defined(CTSIM_WINHELP) && (defined(DEBUG) || defined(_DEBUG))
-       help_menu->Append(MAINMENU_HELP_SECONDARY, "&Secondary Help");
+       help_menu->Append (MAINMENU_HELP_SECONDARY, "&Secondary Help");
 #endif
-       help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
+       help_menu->Append (MAINMENU_HELP_ABOUT, "&About");
        
        wxMenuBar* menu_bar = new wxMenuBar;
        
@@ -364,16 +451,15 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const
        
        wxAcceleratorEntry accelEntries[15];
        accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('O'), wxID_OPEN);
-       accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('H'), MAINMENU_HELP_TOPICS);
        accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('P'), MAINMENU_FILE_CREATE_PHANTOM);
        accelEntries[3].Set (wxACCEL_CTRL, static_cast<int>('F'), MAINMENU_FILE_CREATE_FILTER);
-#ifndef CTSIM_MDI
        accelEntries[4].Set (wxACCEL_NORMAL, WXK_F1, MAINMENU_HELP_CONTENTS);
+#ifndef CTSIM_MDI
        for (i = 0; i < 10; i++)
                accelEntries[i+4].Set (wxACCEL_CTRL, static_cast<int>('0'+i), MAINMENU_WINDOW_BASE+i);
        wxAcceleratorTable accelTable (15, accelEntries);
 #else
-       wxAcceleratorTable accelTable (4, accelEntries);
+       wxAcceleratorTable accelTable (5, accelEntries);
 #endif
        
        SetAcceleratorTable (accelTable);
@@ -382,10 +468,23 @@ MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const
 MainFrame::~MainFrame()
 {
   m_bShuttingDown = true; // Currently used so that Log Window will close
+#if 0
+  // delete all non-modified documents
+       wxList& rListDocs = theApp->getDocManager()->GetDocuments();
+       for (wxNode* pNode = rListDocs.GetFirst(); pNode != NULL; pNode = pNode->GetNext()) {
+               wxDocument* pDoc = dynamic_cast<wxDocument*>(pNode->GetData());
+    if (pDoc && ! pDoc->IsModified()) {
+      theApp->getDocManager()->RemoveDocument(pDoc);
+      delete pDoc;
+    }
+       }
+#endif
+  ::wxYield();
        if (theApp->getConfig())
                theApp->getDocManager()->FileHistorySave (*theApp->getConfig());
-       delete theApp->getDocManager();
-       
+  ::wxYield();
+       delete theApp->getDocManager(); 
+
 }
 
 void
@@ -415,7 +514,8 @@ MainFrame::OnCreatePhantom(wxCommandEvent& event)
        int dialogReturn = dialogPhantom.ShowModal();
        if (dialogReturn == wxID_OK) {
                wxString selection (dialogPhantom.getPhantom());
-               *theApp->getLog() << "Selected phantom " << selection.c_str() << "\n";
+    if (theApp->getVerboseLogging())
+               *theApp->getLog() << "Selected phantom " << selection.c_str() << "\n";
                wxString filename = selection + ".phm";
                m_iDefaultPhantomID = Phantom::convertNameToPhantomID (selection.c_str());
                theApp->getDocManager()->CreateDocument (filename, wxDOC_SILENT);
@@ -447,6 +547,7 @@ MainFrame::OnCreateFilter (wxCommandEvent& WXUNUSED(event))
                *theApp->getLog() << os.str().c_str() << "\n";
                wxString filename = "untitled.if";
                ImageFileDocument* pFilterDoc = theApp->newImageDoc();
+    pFilterDoc->setBadFileOpen();
                if (! pFilterDoc) {
                        sys_error (ERR_SEVERE, "Unable to create filter image");
                        return;
@@ -455,7 +556,8 @@ MainFrame::OnCreateFilter (wxCommandEvent& WXUNUSED(event))
                rIF.setArraySize (m_iDefaultFilterXSize, m_iDefaultFilterYSize);
                rIF.filterResponse (strDomain.c_str(), m_dDefaultFilterBandwidth, strFilter.c_str(), m_dDefaultFilterParam, m_dDefaultFilterInputScale, m_dDefaultFilterOutputScale);
                rIF.labelAdd (os.str().c_str());
-    pFilterDoc->Modify (true);
+    if (theApp->getAskDeleteNewDocs())
+      pFilterDoc->Modify (true);
                pFilterDoc->UpdateAllViews();
                pFilterDoc->GetFirstView()->OnUpdate (NULL, NULL);
                pFilterDoc->getView()->getFrame()->SetClientSize(m_iDefaultFilterXSize, m_iDefaultFilterYSize);
@@ -481,14 +583,27 @@ CTSimApp::getCompatibleImages (const ImageFileDocument* pIFDoc, std::vector<Imag
        }
 }
 
+
+void
+MainFrame::OnLogEvent (wxCommandEvent& event)
+{
+  *theApp->getLog() << event.GetString();
+}
+
+void
+MainFrame::OnHelpTips (wxCommandEvent& event)
+{
+  theApp->ShowTips();
+}
+
 void 
-MainFrame::OnHelpTopics (wxCommandEvent& event)
+MainFrame::OnHelpContents (wxCommandEvent& event)
 {
        showHelp (event.GetId());
 }
 
 void 
-MainFrame::OnHelpContents (wxCommandEvent& event)
+MainFrame::OnHelpButton (wxCommandEvent& event)
 {
        showHelp (event.GetId());
 }
@@ -504,12 +619,6 @@ MainFrame::OnHelpSecondary (wxCommandEvent& event)
 void
 MainFrame::showHelp (int commandID)
 {
-#ifdef CTSIM_WINHELP
-       m_winHelp.LoadFile();
-#else
-       m_htmlHelp.LoadFile();
-#endif
-       
        switch (commandID) {
                
        case MAINMENU_HELP_CONTENTS:
@@ -519,18 +628,15 @@ MainFrame::showHelp (int commandID)
                m_htmlHelp.DisplayContents ();
 #endif
                break;
-               
-       case MAINMENU_HELP_TOPICS:
+
+
+       default:
 #ifdef CTSIM_WINHELP
-               m_winHelp.DisplaySection (introduction);
+    m_winHelp.DisplaySection (commandID);
 #else
-               m_htmlHelp.DisplayIndex();
+    m_htmlHelp.Display (commandID);
 #endif
                break;
-               
-       default:
-               *theApp->getLog() << "Unknown help command # " << commandID << "\n";
-               break;
        }
 }
 
@@ -749,14 +855,37 @@ BitmapDialog::~BitmapDialog()
 {}
 
 
+void 
+MainFrame::OnPreferences (wxCommandEvent& WXUNUSED(event) )
+{
+  DialogPreferences dlg (this, "CTSim Preferences", theApp->getAdvancedOptions(), 
+    theApp->getAskDeleteNewDocs(), theApp->getVerboseLogging(), theApp->getStartupTips(), 
+    theApp->getUseBackgroundTasks());
+  if (dlg.ShowModal() == wxID_OK) {
+    theApp->setAdvancedOptions (dlg.getAdvancedOptions());
+    theApp->setAskDeleteNewDocs (dlg.getAskDeleteNewDocs());
+    theApp->setVerboseLogging (dlg.getVerboseLogging());
+    theApp->setStartupTips (dlg.getStartupTips());
+    theApp->setUseBackgroundTasks (dlg.getUseBackgroundTasks());
+  }
+}
+
+
 #include "./splash.xpm"
 void 
 MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
 {
-       wxBitmap bmp (splash);
+  long lFreeMem = ::wxGetFreeMemory() / (1024L * 1024L);
+  wxString strOSDesc = ::wxGetOsDescription();
+  *theApp->getLog() << "Operation System: " << strOSDesc;
+  if (lFreeMem > 0)
+    *theApp->getLog() << ",  Free Memory: " << lFreeMem << " MB";
+  *theApp->getLog() << "\n";
+
+  wxBitmap bmp (splash);
        if (bmp.Ok()) {
                BitmapDialog dlg (&bmp, "About CTSim");
-               dlg.Show(true);
+               dlg.ShowModal();
        } else {
                wxString msg = "CTSim\nThe Open Source Computed Tomography Simulator\n";
 #ifdef CTSIMVERSION
@@ -884,3 +1013,25 @@ CTSimApp::newPhantomDoc()
        
        return newDoc;
 }
+
+#if wxUSE_GLCANVAS
+
+Graph3dFileDocument*
+CTSimApp::newGraph3dDoc()
+{
+       Graph3dFileDocument* newDoc = dynamic_cast<Graph3dFileDocument*>(m_pDocTemplGraph3d->CreateDocument (""));
+       if (newDoc) {
+               Graph3dFileView* pView = newDoc->getView();
+               if (pView) {
+                       wxFrame* pFrame = pView->getFrame();
+                       if (pFrame)
+                               pFrame->SetSize (0,0);
+               }
+    newDoc->SetDocumentName (m_pDocTemplGraph3d->GetDocumentName());
+    newDoc->SetDocumentTemplate (m_pDocTemplGraph3d);
+    newDoc->OnNewDocument();
+       }
+       
+       return newDoc;
+}
+#endif