move SubanalysisWindow code to a subdirectory
[mussa.git] / qui / subanalysis / SubanalysisWindow.cpp
diff --git a/qui/subanalysis/SubanalysisWindow.cpp b/qui/subanalysis/SubanalysisWindow.cpp
new file mode 100644 (file)
index 0000000..056ba9b
--- /dev/null
@@ -0,0 +1,145 @@
+#include "qui/subanalysis/SubanalysisWindow.hpp"
+#include "qui/MussaWindow.hpp"
+
+#include "mussa_exceptions.hpp"
+#include "alg/mussa.hpp"
+
+#include <QMessageBox>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QGridLayout>
+
+SubanalysisWindow::SubanalysisWindow(MussaRef m, QWidget *parent)
+  : QWidget(parent),
+    analysis(m),
+    window(0),
+    threshold(0),
+    table(0),
+    ok(0),
+    cancel(0)
+{
+  QGridLayout *parameterLayout = new QGridLayout;
+
+  QLabel *thresholdLabel = new QLabel(tr("threshold (bp)"));
+  parameterLayout->addWidget(thresholdLabel, 0, 0);
+  threshold = new QSpinBox(this);
+  threshold->setValue(8);
+  parameterLayout->addWidget(threshold, 1, 0);
+  QLabel *windowLabel = new QLabel(tr("window (bp)"));
+  parameterLayout->addWidget(windowLabel, 0, 1);
+  window = new QSpinBox(this);
+  window->setValue(10);
+  parameterLayout->addWidget(window, 1, 1);
+
+  ok = new QPushButton(tr("&OK"), this);
+  ok->setEnabled( false );
+  connect(ok, SIGNAL(clicked()), this, SLOT(run()));
+
+  cancel = new QPushButton(tr("Cancel"), this);
+  connect(cancel, SIGNAL(clicked()), this, SLOT(abort()));
+
+  table = new QTableView(this);
+  table->setModel(&model);
+
+  // layout buttons
+  QHBoxLayout *buttonLayout = new QHBoxLayout;
+  buttonLayout->addWidget(ok);
+  buttonLayout->addWidget(cancel);
+
+  // layout verticle space
+  QVBoxLayout *verticalLayout = new QVBoxLayout;
+  verticalLayout->addLayout(parameterLayout);
+  verticalLayout->addWidget(table);
+  verticalLayout->addLayout(buttonLayout);
+  setLayout(verticalLayout);
+
+  // now that we're all setup lets get notices when we're updated
+  connect(&model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), 
+          this, SLOT(modelUpdated(const QModelIndex&, int, int)));
+  connect(&model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), 
+          this, SLOT(modelUpdated(const QModelIndex&, int, int)));
+          
+  updateTitle();        
+}
+
+SequenceLocationModel& SubanalysisWindow::getModel()
+{
+  return model;
+}
+
+void SubanalysisWindow::abort()
+{
+  model.clear();
+  hide();
+}
+
+void SubanalysisWindow::run()
+{
+  if (window == 0 or threshold == 0) {
+    throw std::runtime_error("SubanalysisWindow misconstructed");
+  }
+
+  if (model.size() == 0) {
+    throw std::runtime_error("It shouldn't be possible to call run with an "
+                             "empty model now.");
+  }
+
+  MussaRef new_m(new Mussa);
+  
+  for(SequenceLocationModel::iterator itor = model.begin();
+      itor != model.end();
+      ++itor)
+  {
+    // append_sequence from a const Sequence & will make a copy 
+    // for the shared pointer.
+    Sequence s = itor->getSelectedSequence();
+    s.clear_motifs();
+    new_m->append_sequence(s);
+  }
+
+  try {
+    new_m->set_window(window->value());
+    new_m->set_threshold(threshold->value());
+    new_m->analyze();
+    // FIXME: why isn't the nway_paths refined_pathz structure just initialized
+    // FIXME: with the contents of pathz?
+    new_m->set_soft_threshold(threshold->value());
+    // copy over motifs
+    std::vector<Sequence> motifs_copy;
+    std::vector<Color> color_copy;
+    const Mussa::motif_set motifs = analysis->motifs();
+    boost::shared_ptr<AnnotationColors> mapper = analysis->colorMapper();
+    for(Mussa::motif_set::const_iterator motif_i = motifs.begin();
+        motif_i != motifs.end();
+        ++motif_i)
+    {
+      motifs_copy.push_back(*motif_i);
+      color_copy.push_back(mapper->lookup("motif", motif_i->get_sequence()));
+    }
+    new_m->set_motifs(motifs_copy, color_copy);
+    MussaWindow *mw = new MussaWindow(new_m);
+    mw->show();
+    model.clear();
+    hide();
+  } catch(mussa_error e) {
+    QMessageBox::critical(this,
+                          "Mussa Subanalysis Error",
+                          QString(e.what()),
+                          QMessageBox::Ok, 0, 0);
+  }
+}
+
+void SubanalysisWindow::modelUpdated(const QModelIndex&, int, int )
+{
+  // if the model is empty we shouldn't be able to click ok
+  if (ok) ok->setEnabled(not model.empty());
+}
+
+void SubanalysisWindow::updateTitle()
+{
+  std::string title("Subanalysis: ");
+  if (analysis) {
+    title += analysis->get_title();
+  }
+  setWindowTitle(title.c_str());  
+}