move SubanalysisWindow code to a subdirectory
authorDiane Trout <diane@caltech.edu>
Mon, 30 Oct 2006 22:47:45 +0000 (22:47 +0000)
committerDiane Trout <diane@caltech.edu>
Mon, 30 Oct 2006 22:47:45 +0000 (22:47 +0000)
12 files changed:
qui/CMakeLists.txt
qui/MussaAlignedWindow.hpp
qui/MussaWindow.hpp
qui/SequenceLocationModel.cpp [deleted file]
qui/SequenceLocationModel.hpp [deleted file]
qui/SubanalysisWindow.cpp [deleted file]
qui/SubanalysisWindow.hpp [deleted file]
qui/subanalysis/SequenceLocationModel.cpp [new file with mode: 0644]
qui/subanalysis/SequenceLocationModel.hpp [new file with mode: 0644]
qui/subanalysis/SubanalysisWindow.cpp [new file with mode: 0644]
qui/subanalysis/SubanalysisWindow.hpp [new file with mode: 0644]
qui/test/TestSequenceLocationModel.hpp

index d4ab6dbe95e7e7e5295e4e149e33f38711123ebf..e7339adb04bf22989cbfb09e9fb5efd04c769142 100644 (file)
@@ -21,8 +21,6 @@ SET(MOC_HEADERS
       IntAction.hpp           
       MussaAlignedWindow.hpp  
       MussaWindow.hpp
-      SequenceLocationModel.hpp
-      SubanalysisWindow.hpp
       ThresholdWidget.hpp
       ZoomWidget.hpp
       motif_editor/MotifModel.hpp
@@ -38,6 +36,8 @@ SET(MOC_HEADERS
       seqbrowser/SequenceBrowserSidebar.hpp
       seqbrowser/SequenceBrowserWidget.hpp
       seqbrowser/SequenceDescription.hpp
+      subanalysis/SequenceLocationModel.hpp
+      subanalysis/SubanalysisWindow.hpp
     )
 SET(GUI_SOURCES 
       ImageSaveDialog.cpp      
@@ -45,8 +45,6 @@ SET(GUI_SOURCES
       IntAction.cpp            
       MussaAlignedWindow.cpp
       MussaWindow.cpp
-      SequenceLocationModel.cpp
-      SubanalysisWindow.cpp
       ThresholdWidget.cpp
       ZoomWidget.cpp
       motif_editor/MotifEditor.cpp
@@ -64,6 +62,8 @@ SET(GUI_SOURCES
       seqbrowser/SequenceBrowserSidebar.cpp
       seqbrowser/SequenceBrowserWidget.cpp
       seqbrowser/SequenceDescription.cpp
+      subanalysis/SequenceLocationModel.cpp
+      subanalysis/SubanalysisWindow.cpp
      )
 SET(PY_SOURCES ../py/python.cpp)
 SET(RCCS ../icons.qrc)
index 391ca54063aa168a82acfe6244911a625c3498d3..28d43d6e8e2fe82d03c244fb1eef1efc50d8a358 100644 (file)
@@ -14,7 +14,7 @@
 #include "qui/ZoomWidget.hpp"
 #include "qui/ThresholdWidget.hpp"
 #include "qui/seqbrowser/SequenceBrowserWidget.hpp"
-#include "qui/SubanalysisWindow.hpp"
+#include "qui/subanalysis/SubanalysisWindow.hpp"
 
 //! Show sequence alignments
 class MussaAlignedWindow : public QMainWindow
index d848fea24c5c671e187ac6fc68d019fc521987c2..8afa91b31b60d3efa72e08a4b543e8db6203996f 100644 (file)
@@ -16,7 +16,7 @@
 #include "qui/motif_editor/MotifEditor.hpp"
 #include "qui/mussa_setup_dialog/MussaSetupDialog.hpp"
 #include "qui/seqbrowser/SequenceBrowserWidget.hpp"
-#include "qui/SubanalysisWindow.hpp"
+#include "qui/subanalysis/SubanalysisWindow.hpp"
 #include "qui/ThresholdWidget.hpp"
 #include "qui/ZoomWidget.hpp"
 
diff --git a/qui/SequenceLocationModel.cpp b/qui/SequenceLocationModel.cpp
deleted file mode 100644 (file)
index a4e9c71..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "qui/SequenceLocationModel.hpp"
-
-SequenceLocationModel::SequenceLocationModel(QObject *parent) 
-  : QAbstractTableModel(parent)
-{
-}
-
-void SequenceLocationModel::assign(
-    SequenceLocationModel::size_type num, 
-    const SequenceLocation& val
-)
-{
-  sequence_locations.assign(num, val);
-}
-
-SequenceLocation& SequenceLocationModel::at(
-    SequenceLocationModel::size_type index
-)
-{
-  return sequence_locations.at(index);
-}
-
-SequenceLocation& SequenceLocationModel::back()
-{
-  return sequence_locations.back();
-}
-
-SequenceLocationModel::iterator SequenceLocationModel::begin()
-{
-  return sequence_locations.begin();
-}
-
-SequenceLocationModel::const_iterator SequenceLocationModel::begin() const
-{
-  return sequence_locations.begin();
-}
-
-void SequenceLocationModel::clear()
-{
-  if (sequence_locations.size() != 0) {
-    beginRemoveRows(QModelIndex(), 0, sequence_locations.size()-1);
-    sequence_locations.clear();
-    endRemoveRows();
-  }
-}
-
-SequenceLocationModel::iterator SequenceLocationModel::end()
-{
-  return sequence_locations.end();
-}
-
-SequenceLocationModel::const_iterator SequenceLocationModel::end() const
-{
-  return sequence_locations.end();
-}
-
-bool SequenceLocationModel::empty() const
-{
-  return sequence_locations.empty();
-}
-
-SequenceLocation& SequenceLocationModel::operator[](
-    SequenceLocationModel::size_type index
-)
-{
-  return sequence_locations[index];
-}
-
-void SequenceLocationModel::pop_back()
-{
-  int last_element = sequence_locations.size()-1;
-  if (last_element >= 0) {
-    beginRemoveRows(QModelIndex(), last_element, last_element);
-    sequence_locations.pop_back();
-    endRemoveRows();
-  } 
-}
-
-void SequenceLocationModel::push_back(SequenceLocation& item)
-{
-  int last_element = sequence_locations.size();
-  beginInsertRows(QModelIndex(), last_element, last_element);
-  sequence_locations.push_back(item);
-  endInsertRows();
-}
-
-SequenceLocationModel::size_type SequenceLocationModel::size() const
-{
-  return sequence_locations.size();
-}
-
-int 
-SequenceLocationModel::rowCount( const QModelIndex& parent) const
-{
-  return sequence_locations.size();
-}
-
-int 
-SequenceLocationModel::columnCount(const QModelIndex& parent) const
-{
-  return 3;
-}
-
-QVariant 
-SequenceLocationModel::data(const QModelIndex &index, int role) const
-{
-  if (!index.isValid())
-    return QVariant();
-  
-  if (index.row() >= sequence_locations.size())
-    return QVariant();
-
-  if (index.column() >= 3)
-    return QVariant();
-
-  if (role == Qt::DisplayRole) {
-    if (index.column() == 0 ) {
-      const Sequence& seq = sequence_locations[index.row()].getSequence();
-      std::string name(seq.get_name());
-      if (name.size() == 0) {
-        return QString(tr("Unnamed Sequence"));
-      } else {
-        return QVariant(QString(name.c_str()));
-      }
-    } else if (index.column() == 1) {
-      return QVariant(sequence_locations[index.row()].getLeft());
-    } else if (index.column() == 2) {
-      return QVariant(sequence_locations[index.row()].getRight());
-    }
-  }
-  return QVariant();
-}
-
-QVariant 
-SequenceLocationModel::headerData(
-    int section, 
-    Qt::Orientation orientation, 
-    int role
-) const
-{
-  if (role != Qt::DisplayRole)
-    return QVariant();
-
-  if (orientation == Qt::Horizontal) {
-    switch(section) {
-      case 0:
-        return QString("Sequence");
-        break;
-      case 1:
-        return QString("Left");
-        break;
-      case 2:
-        return QString("Right");
-        break;
-      default:
-        return QVariant();
-        break;
-    }
-  }
-  return QVariant();
-}
-
-bool SequenceLocationModel::setData(
-   const QModelIndex& index, 
-   const QVariant &value, 
-   int role
-)
-{
-   bool isInt;
-   int intValue(value.toInt(&isInt));
-   if (index.isValid() and role == Qt::EditRole and isInt) {
-    SequenceLocation& location = sequence_locations[index.row()];
-    switch(index.column()) {
-      case 0:
-        return false;
-        break;
-      case 1:
-        location.setLeft(intValue);
-        break;
-      case 2:
-        location.setRight(intValue);
-        break;
-      default:
-        return false;
-        break;
-    }
-    emit dataChanged(index, index);
-    return true;
-  } else {
-    return false;
-  }
-}
-
-Qt::ItemFlags SequenceLocationModel::flags(const QModelIndex& index) const
-{
-  if (!index.isValid())
-    return Qt::ItemIsEnabled;
-
-  // first column is not editable
-  if (index.column() == 0)
-    return QAbstractItemModel::flags(index);
-  else
-    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
-}
-
diff --git a/qui/SequenceLocationModel.hpp b/qui/SequenceLocationModel.hpp
deleted file mode 100644 (file)
index 6b6a924..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _SEQUENCE_LOCATION_MODEL_HPP_
-#define _SEQUENCE_LOCATION_MODEL_HPP_
-
-#include <QAbstractTableModel>
-#include "alg/sequence_location.hpp"
-#include <vector>
-
-class SequenceLocationModel : public QAbstractTableModel
-{
-  Q_OBJECT
-
-  public:
-    SequenceLocationModel(QObject *parent = 0);
-
-    typedef std::vector<SequenceLocation> model_type;
-    typedef model_type::size_type size_type;
-    typedef model_type::iterator iterator; 
-    typedef model_type::const_iterator const_iterator; 
-    //! \defgroup VectorInterface
-    //! \addtogroup VectorInterface
-    //! \@{
-    //! assign num copies of val to our vector
-    void assign(size_type num, const SequenceLocation& val);
-    //! return a specific element
-    SequenceLocation& at(size_type index);
-    //! return the last element
-    SequenceLocation& back();
-    //! return an iterator to the beginning of the model
-    iterator begin();
-    //! return an iterator to the beginning of the model
-    const_iterator begin() const;
-    //! empty the model
-    void clear();
-    //! return an iterator to the end of the model
-    iterator end();
-    //! return an iterator to the end of the model
-    const_iterator end() const;
-    //! is the model empty?
-    bool empty() const;
-    //! return a specific element
-    SequenceLocation& operator[](size_type index);
-    //! remove the last element from our model
-    void pop_back();
-    //! add a sequence location to the end of our model
-    void push_back(SequenceLocation&);
-    //! how many elements are in our model.
-    size_type size() const;
-    //! \@}
-
-    //! \defgroup QtModelInterface
-    //! \addtogroup QtModel
-    //! \@{
-    int rowCount(const QModelIndex& parent=QModelIndex()) const;
-    int columnCount(const QModelIndex& parent=QModelIndex()) const;
-    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
-
-    QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
-
-    bool setData(const QModelIndex& index, const QVariant &value, 
-                 int role=Qt::EditRole);
-    Qt::ItemFlags flags(const QModelIndex& index) const;
-
-    //bool insertRows(int row, int count, 
-    //                const QModelIndex& parent=QModelIndex());
-    //bool removeRows(int row, int count,
-    //                const QModelIndex& parent=QModelIndex());
-    //! \@}
-  private:
-    model_type sequence_locations;
-};
-
-#endif
diff --git a/qui/SubanalysisWindow.cpp b/qui/SubanalysisWindow.cpp
deleted file mode 100644 (file)
index 99dfb69..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "qui/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());  
-}
diff --git a/qui/SubanalysisWindow.hpp b/qui/SubanalysisWindow.hpp
deleted file mode 100644 (file)
index 9d9ef73..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef _SUBANALYSIS_H_
-#define _SUBANALYSIS_H_
-
-#include <QTableView>
-#include <QPushButton>
-#include <QSpinBox>
-#include <QStringList>
-#include <QWidget>
-
-#include "qui/SequenceLocationModel.hpp"
-#include "alg/mussa.hpp"
-
-class SubanalysisWindow : public QWidget
-{
-  Q_OBJECT 
-
-public: 
-  SubanalysisWindow(MussaRef m, QWidget *parent = 0);
-
-  //! return a modifiable reference to our SequenceLocationModel
-  SequenceLocationModel& getModel();
-
-public slots:
-  //! clear our model and close the window
-  void abort();
-  //! create a subanalysis and run it
-  void run();
-  //! provide a way for the model to tell us to update our gui
-  void modelUpdated(const QModelIndex&, int, int);
-  //! update our title
-  void updateTitle();
-
-private:
-  //! keep track of what analysis we're attached to
-  MussaRef analysis;
-  QSpinBox *window;
-  QSpinBox *threshold;
-  QTableView *table;
-  QPushButton *ok;
-  QPushButton *cancel;
-
-  SequenceLocationModel model;
-};
-
-//! reference to a subanalysis window
-typedef boost::shared_ptr<SubanalysisWindow> SubanalysisWindowRef;
-#endif
diff --git a/qui/subanalysis/SequenceLocationModel.cpp b/qui/subanalysis/SequenceLocationModel.cpp
new file mode 100644 (file)
index 0000000..22f5d08
--- /dev/null
@@ -0,0 +1,205 @@
+#include "qui/subanalysis/SequenceLocationModel.hpp"
+
+SequenceLocationModel::SequenceLocationModel(QObject *parent) 
+  : QAbstractTableModel(parent)
+{
+}
+
+void SequenceLocationModel::assign(
+    SequenceLocationModel::size_type num, 
+    const SequenceLocation& val
+)
+{
+  sequence_locations.assign(num, val);
+}
+
+SequenceLocation& SequenceLocationModel::at(
+    SequenceLocationModel::size_type index
+)
+{
+  return sequence_locations.at(index);
+}
+
+SequenceLocation& SequenceLocationModel::back()
+{
+  return sequence_locations.back();
+}
+
+SequenceLocationModel::iterator SequenceLocationModel::begin()
+{
+  return sequence_locations.begin();
+}
+
+SequenceLocationModel::const_iterator SequenceLocationModel::begin() const
+{
+  return sequence_locations.begin();
+}
+
+void SequenceLocationModel::clear()
+{
+  if (sequence_locations.size() != 0) {
+    beginRemoveRows(QModelIndex(), 0, sequence_locations.size()-1);
+    sequence_locations.clear();
+    endRemoveRows();
+  }
+}
+
+SequenceLocationModel::iterator SequenceLocationModel::end()
+{
+  return sequence_locations.end();
+}
+
+SequenceLocationModel::const_iterator SequenceLocationModel::end() const
+{
+  return sequence_locations.end();
+}
+
+bool SequenceLocationModel::empty() const
+{
+  return sequence_locations.empty();
+}
+
+SequenceLocation& SequenceLocationModel::operator[](
+    SequenceLocationModel::size_type index
+)
+{
+  return sequence_locations[index];
+}
+
+void SequenceLocationModel::pop_back()
+{
+  int last_element = sequence_locations.size()-1;
+  if (last_element >= 0) {
+    beginRemoveRows(QModelIndex(), last_element, last_element);
+    sequence_locations.pop_back();
+    endRemoveRows();
+  } 
+}
+
+void SequenceLocationModel::push_back(SequenceLocation& item)
+{
+  int last_element = sequence_locations.size();
+  beginInsertRows(QModelIndex(), last_element, last_element);
+  sequence_locations.push_back(item);
+  endInsertRows();
+}
+
+SequenceLocationModel::size_type SequenceLocationModel::size() const
+{
+  return sequence_locations.size();
+}
+
+int 
+SequenceLocationModel::rowCount( const QModelIndex& parent) const
+{
+  return sequence_locations.size();
+}
+
+int 
+SequenceLocationModel::columnCount(const QModelIndex& parent) const
+{
+  return 3;
+}
+
+QVariant 
+SequenceLocationModel::data(const QModelIndex &index, int role) const
+{
+  if (!index.isValid())
+    return QVariant();
+  
+  if (index.row() >= sequence_locations.size())
+    return QVariant();
+
+  if (index.column() >= 3)
+    return QVariant();
+
+  if (role == Qt::DisplayRole) {
+    if (index.column() == 0 ) {
+      const Sequence& seq = sequence_locations[index.row()].getSequence();
+      std::string name(seq.get_name());
+      if (name.size() == 0) {
+        return QString(tr("Unnamed Sequence"));
+      } else {
+        return QVariant(QString(name.c_str()));
+      }
+    } else if (index.column() == 1) {
+      return QVariant(sequence_locations[index.row()].getLeft());
+    } else if (index.column() == 2) {
+      return QVariant(sequence_locations[index.row()].getRight());
+    }
+  }
+  return QVariant();
+}
+
+QVariant 
+SequenceLocationModel::headerData(
+    int section, 
+    Qt::Orientation orientation, 
+    int role
+) const
+{
+  if (role != Qt::DisplayRole)
+    return QVariant();
+
+  if (orientation == Qt::Horizontal) {
+    switch(section) {
+      case 0:
+        return QString("Sequence");
+        break;
+      case 1:
+        return QString("Left");
+        break;
+      case 2:
+        return QString("Right");
+        break;
+      default:
+        return QVariant();
+        break;
+    }
+  }
+  return QVariant();
+}
+
+bool SequenceLocationModel::setData(
+   const QModelIndex& index, 
+   const QVariant &value, 
+   int role
+)
+{
+   bool isInt;
+   int intValue(value.toInt(&isInt));
+   if (index.isValid() and role == Qt::EditRole and isInt) {
+    SequenceLocation& location = sequence_locations[index.row()];
+    switch(index.column()) {
+      case 0:
+        return false;
+        break;
+      case 1:
+        location.setLeft(intValue);
+        break;
+      case 2:
+        location.setRight(intValue);
+        break;
+      default:
+        return false;
+        break;
+    }
+    emit dataChanged(index, index);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+Qt::ItemFlags SequenceLocationModel::flags(const QModelIndex& index) const
+{
+  if (!index.isValid())
+    return Qt::ItemIsEnabled;
+
+  // first column is not editable
+  if (index.column() == 0)
+    return QAbstractItemModel::flags(index);
+  else
+    return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
+}
+
diff --git a/qui/subanalysis/SequenceLocationModel.hpp b/qui/subanalysis/SequenceLocationModel.hpp
new file mode 100644 (file)
index 0000000..100fd46
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef _SEQUENCE_LOCATION_MODEL_HPP_
+#define _SEQUENCE_LOCATION_MODEL_HPP_
+
+#include <QObject>
+#include <QAbstractTableModel>
+#include "alg/sequence_location.hpp"
+#include <vector>
+
+class SequenceLocationModel : public QAbstractTableModel
+{
+  Q_OBJECT
+
+  public:
+    SequenceLocationModel(QObject *parent = 0);
+
+    typedef std::vector<SequenceLocation> model_type;
+    typedef model_type::size_type size_type;
+    typedef model_type::iterator iterator; 
+    typedef model_type::const_iterator const_iterator; 
+    //! \defgroup VectorInterface
+    //! \addtogroup VectorInterface
+    //! \@{
+    //! assign num copies of val to our vector
+    void assign(size_type num, const SequenceLocation& val);
+    //! return a specific element
+    SequenceLocation& at(size_type index);
+    //! return the last element
+    SequenceLocation& back();
+    //! return an iterator to the beginning of the model
+    iterator begin();
+    //! return an iterator to the beginning of the model
+    const_iterator begin() const;
+    //! empty the model
+    void clear();
+    //! return an iterator to the end of the model
+    iterator end();
+    //! return an iterator to the end of the model
+    const_iterator end() const;
+    //! is the model empty?
+    bool empty() const;
+    //! return a specific element
+    SequenceLocation& operator[](size_type index);
+    //! remove the last element from our model
+    void pop_back();
+    //! add a sequence location to the end of our model
+    void push_back(SequenceLocation&);
+    //! how many elements are in our model.
+    size_type size() const;
+    //! \@}
+
+    //! \defgroup QtModelInterface
+    //! \addtogroup QtModel
+    //! \@{
+    int rowCount(const QModelIndex& parent=QModelIndex()) const;
+    int columnCount(const QModelIndex& parent=QModelIndex()) const;
+    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
+
+    QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
+
+    bool setData(const QModelIndex& index, const QVariant &value, 
+                 int role=Qt::EditRole);
+    Qt::ItemFlags flags(const QModelIndex& index) const;
+
+    //bool insertRows(int row, int count, 
+    //                const QModelIndex& parent=QModelIndex());
+    //bool removeRows(int row, int count,
+    //                const QModelIndex& parent=QModelIndex());
+    //! \@}
+  private:
+    model_type sequence_locations;
+};
+
+#endif
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());  
+}
diff --git a/qui/subanalysis/SubanalysisWindow.hpp b/qui/subanalysis/SubanalysisWindow.hpp
new file mode 100644 (file)
index 0000000..ce9f62c
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _SUBANALYSIS_H_
+#define _SUBANALYSIS_H_
+
+#include <QTableView>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QStringList>
+#include <QWidget>
+
+#include "qui/subanalysis/SequenceLocationModel.hpp"
+#include "alg/mussa.hpp"
+
+class SubanalysisWindow : public QWidget
+{
+  Q_OBJECT 
+
+public: 
+  SubanalysisWindow(MussaRef m, QWidget *parent = 0);
+
+  //! return a modifiable reference to our SequenceLocationModel
+  SequenceLocationModel& getModel();
+
+public slots:
+  //! clear our model and close the window
+  void abort();
+  //! create a subanalysis and run it
+  void run();
+  //! provide a way for the model to tell us to update our gui
+  void modelUpdated(const QModelIndex&, int, int);
+  //! update our title
+  void updateTitle();
+
+private:
+  //! keep track of what analysis we're attached to
+  MussaRef analysis;
+  QSpinBox *window;
+  QSpinBox *threshold;
+  QTableView *table;
+  QPushButton *ok;
+  QPushButton *cancel;
+
+  SequenceLocationModel model;
+};
+
+//! reference to a subanalysis window
+typedef boost::shared_ptr<SubanalysisWindow> SubanalysisWindowRef;
+#endif
index a1a774e0b46adf99b68f59b3a1be68abe369bb49..153a4f5eb7dc7e56d8707ba12d353ac33698f034 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _TEST_SEQUENCE_LOCATION_MODEL_HPP_
 #define _TEST_SEQUENCE_LOCATION_MODEL_HPP_
-#include "qui/SequenceLocationModel.hpp"
+#include "qui/subanalysis/SequenceLocationModel.hpp"
 #include "alg/sequence_location.hpp"
 #include "alg/sequence.hpp"