keep motifs after closing window
[mussa.git] / qui / MussaWindow.cpp
index 58fea508458d23fe3fdc975c42de47bff58ce8de..5d934fa36d637536fa33b03ccac033cdaa5c8f72 100644 (file)
@@ -32,17 +32,23 @@ namespace fs = boost::filesystem;
 
 using namespace std;
 
+static void init_resources() {
+  static bool resources_loaded = false;
+  if (not resources_loaded) {
+    Q_INIT_RESOURCE(icons);
+    resources_loaded = true;
+  }
+}
+
 MussaWindow::MussaWindow(MussaRef analysis_, QWidget *parent) :
   QMainWindow(parent),
   analysis(analysis_),
-  default_dir(new QDir(QDir::home().absolutePath())),
   motif_editor(0),
-  setup_analysis_dialog(new MussaSetupDialog(this)),
-  subanalysis_window(new SubanalysisWindow(analysis)),
-  browser(new SequenceBrowserWidget(default_dir, this)),  
-  mussaViewTB(new QToolBar("Path Views")),
-  zoom(new ZoomWidget),
-  threshold(new ThresholdWidget),
+  setup_analysis_dialog(0),
+  browser(0),
+  mussaViewTB(0),
+  zoom(0),
+  threshold(0),
   progress_dialog(0),
   aboutAction(0),
   closeAction(0),
@@ -62,14 +68,15 @@ MussaWindow::MussaWindow(MussaRef analysis_, QWidget *parent) :
   viewMussaAlignmentAction(0),
   manualAssistant(0)
 {
+  init_resources();
+  setupWidgets();
   setupActions();
-  setupMainMenu();
   setupAssistant();
+  setupMainMenu();
+  
+  setWindowIcon(QIcon(":/icons/mussa.png"));
+  default_dir.reset(new QDir(QDir::home().absolutePath()));
 
-  //This next setWhatsThis function prevents
-  // a segfault when using WhatsThis feature with 
-  // opengl widget.
-  //scene->setWhatsThis(tr("Mussa in OpenGL!"));
   setCentralWidget(browser);
   // well updatePosition isn't quite right as we really just need
   // to call update()
@@ -77,19 +84,11 @@ MussaWindow::MussaWindow(MussaRef analysis_, QWidget *parent) :
   connect(this, SIGNAL(changedMotifs()), this, SLOT(updateAnnotations()));
   connect(browser, SIGNAL(basepairsCopied(size_t)), 
           this, SLOT(showBasePairsCopied(size_t)));
-
-  //mussaViewTB->addAction(toggleMotifsAction);
-  mussaViewTB->addWidget(zoom);
-  
   connect(zoom, SIGNAL(valueChanged(double)), 
           browser, SLOT(setZoom(double)));
-  
-  // threshold range is set in updateAnalysis
-  
-  //scene->setClipPlane(20);
-  // FIXME: for when we get the paths drawn at the appropriate depth
-  //connect(threshold, SIGNAL(thresholdChanged(int)),
-  //        this, SLOT(setClipPlane(int)));
+  mussaViewTB->addWidget(zoom);
+
+  // threshold range is set in updateAnalysis  
   connect(threshold, SIGNAL(thresholdChanged(int)),
           this, SLOT(setSoftThreshold(int)));
   mussaViewTB->addWidget(threshold);
@@ -97,10 +96,11 @@ MussaWindow::MussaWindow(MussaRef analysis_, QWidget *parent) :
   addToolBar(mussaViewTB);
 
   statusBar()->showMessage("Welcome to mussa", 2000);
+
   // FIXME: we should start refactoring the connect call to updateAnalysis or something
   if (analysis) {
-    connect(analysis.get(), SIGNAL(progress(const std::string&, int, int)),
-            this, SLOT(updateProgress(const std::string&, int, int)));
+    connect(analysis.get(), SIGNAL(progress(const QString&, int, int)),
+            this, SLOT(updateProgress(const QString&, int, int)));
     connect(analysis.get(), SIGNAL(isModified(bool)),
             this, SLOT(updateAnalysisModified(bool)));        
   }
@@ -178,7 +178,7 @@ void MussaWindow::setupActions()
   mussaManualAssistantAction = new QAction(tr("Mussagl Manual..."), this);
   mussaManualAssistantAction->setIcon(QIcon(":/icons/contents.png"));
   connect(mussaManualAssistantAction, SIGNAL(triggered()),
-         this, SLOT(showManual()));
+               this, SLOT(showManual()));
 
   newMussaWindowAction = new QAction(tr("&New Mussa Window"), this);
   newMussaWindowAction->setStatusTip("open another mussa window to allow comparing results");
@@ -208,9 +208,11 @@ void MussaWindow::setupActions()
 
   //Save pixel map action
   saveBrowserPixmapAction = new QAction(tr("Save to image..."), this);
-  connect(saveBrowserPixmapAction, (SIGNAL(triggered())),
-         browser, SLOT(promptSaveBrowserPixmap()));
-  saveBrowserPixmapAction->setIcon(QIcon(":/icons/image2.png"));
+  if (browser) {
+    connect(saveBrowserPixmapAction, (SIGNAL(triggered())),
+            browser, SLOT(promptSaveBrowserPixmap()));
+    saveBrowserPixmapAction->setIcon(QIcon(":/icons/image2.png"));
+  }
 
   viewMussaAlignmentAction = new QAction(tr("View sequence alignment"), this);
   connect(viewMussaAlignmentAction, SIGNAL(triggered()),
@@ -257,9 +259,10 @@ void MussaWindow::setupMainMenu()
 
   newMenu = menuBar()->addMenu(tr("&Edit"));
   newMenu->addAction(editMotifsAction);
-  newMenu->addAction(browser->getCopySelectedSequenceAsStringAction());
-  newMenu->addAction(browser->getCopySelectedSequenceAsFastaAction());
+  if (browser) newMenu->addAction(browser->getCopySelectedSequenceAsStringAction());
+  if (browser) newMenu->addAction(browser->getCopySelectedSequenceAsFastaAction());
   newMenu->addAction(createSubAnalysisAction);
+  if (browser) newMenu->addAction(browser->getEditSequencePropertiesAction());
  
   newMenu = menuBar()->addMenu(tr("&View"));
   newMenu->addAction(viewMussaAlignmentAction);
@@ -272,13 +275,25 @@ void MussaWindow::setupMainMenu()
   newMenu->addAction(aboutAction);
 
   // add some extra features to the context menu
-  QMenu *popupMenu = browser->getPopupMenu();
-  if (popupMenu) {
-    popupMenu->addAction(viewMussaAlignmentAction);
-    popupMenu->addAction(createSubAnalysisAction);
+  if (browser) {
+    QMenu *popupMenu = browser->getPopupMenu();
+    if (popupMenu) {
+      popupMenu->addAction(viewMussaAlignmentAction);
+      popupMenu->addAction(createSubAnalysisAction);
+    }
   }
 }
 
+void MussaWindow::setupWidgets()
+{
+  setup_analysis_dialog = new MussaSetupDialog;
+  subanalysis_window.reset(new SubanalysisWindow(analysis));
+  browser = new SequenceBrowserWidget(default_dir);
+  mussaViewTB = new QToolBar("Path Views", this);
+  zoom = new ZoomWidget(mussaViewTB);
+  threshold = new ThresholdWidget(mussaViewTB);
+}
+
 void MussaWindow::setupAssistant()
 {
 #if defined(QT_QTASSISTANT_FOUND)
@@ -309,6 +324,11 @@ void MussaWindow::about()
 
 void MussaWindow::clear()
 {
+  if (motif_editor != 0) {
+    motif_editor->hide();
+    delete motif_editor;
+  }
+  
   aligned_windows.clear();
   browser->clear();
 }
@@ -444,13 +464,11 @@ bool MussaWindow::isClearingAnalysisSafe()
 
 void MussaWindow::editMotifs()
 {
-  if (motif_editor != 0) {
-    motif_editor->hide();
-    delete motif_editor;
+  if (not motif_editor) {
+    motif_editor = new MotifEditor(analysis);
+    connect(motif_editor, SIGNAL(changedMotifs()), 
+            this, SLOT(updateAnnotations()));
   }
-  motif_editor = new MotifEditor(analysis);
-  connect(motif_editor, SIGNAL(changedMotifs()), 
-          this, SLOT(updateAnnotations()));
   motif_editor->show();
 }
 
@@ -529,10 +547,10 @@ void MussaWindow::loadMupa()
     // but this should work for the moment.
     if (not isClearingAnalysisSafe()) return;
 
-    MussaRef m(new Mussa);
+    MussaRef m = Mussa::init();
     fs::path converted_path(mupa_path.toStdString(), fs::native);
-    connect(m.get(), SIGNAL(progress(const std::string&, int, int)),
-            this, SLOT(updateProgress(const std::string&, int, int)));
+    connect(m.get(), SIGNAL(progress(const QString&, int, int)),
+            this, SLOT(updateProgress(const QString&, int, int)));
     m->load_mupa_file(converted_path);
     m->analyze();
     setAnalysis(m);
@@ -566,10 +584,10 @@ void MussaWindow::loadSavedAnalysis()
     // but this should work for the moment.
     if (not isClearingAnalysisSafe()) return;
 
-    MussaRef m(new Mussa);
+    MussaRef m = Mussa::init();
     fs::path converted_path(muway_dir.toStdString(), fs::native);
-    connect(m.get(), SIGNAL(progress(const std::string&, int, int)),
-            this, SLOT(updateProgress(const std::string&, int, int)));
+    connect(m.get(), SIGNAL(progress(const QString&, int, int)),
+            this, SLOT(updateProgress(const QString&, int, int)));
     m->load(converted_path);
     // only switch mussas if we loaded without error
     if (analysis->empty()) {
@@ -583,6 +601,12 @@ void MussaWindow::loadSavedAnalysis()
       win->default_dir->setPath(converted_path.branch_path().native_directory_string().c_str());
       win->show();
     }
+  } catch (boost::filesystem::filesystem_error e) {
+    QString msg("Unable to load ");
+    msg += muway_dir;
+    msg += "\n";
+    msg += e.what();
+    QMessageBox::warning(this, "Load Parameter", msg);    
   } catch (mussa_load_error e) {
     QString msg("Unable to load ");
     msg += muway_dir;
@@ -595,8 +619,7 @@ void MussaWindow::loadSavedAnalysis()
 
 void MussaWindow::newMussaWindow()
 {
-  MussaRef a(new Mussa);
-  MussaWindow *win = new MussaWindow(a);
+  MussaWindow *win = new MussaWindow(Mussa::init());
   win->default_dir = default_dir;
   win->show();
 }
@@ -769,7 +792,7 @@ void MussaWindow::updateLinks()
 }
 
 void 
-MussaWindow::updateProgress(const string& description, int current, int max)
+MussaWindow::updateProgress(const QString& description, int current, int max)
 {  
   // if we're done  
   if (current == max) {
@@ -781,9 +804,8 @@ MussaWindow::updateProgress(const string& description, int current, int max)
   } else {
     // if we're starting, create the dialog
     if (progress_dialog == 0) {
-      QString desc(description.c_str());
       QString cancel("Cancel");
-      progress_dialog = new QProgressDialog(desc, cancel, current, max, this);
+      progress_dialog = new QProgressDialog(description, cancel, current, max, this);
       progress_dialog->show();
     } else {
       // just update the dialog