IntAction.hpp
MussaAlignedWindow.hpp
MussaWindow.hpp
- SequenceLocationModel.hpp
- SubanalysisWindow.hpp
ThresholdWidget.hpp
ZoomWidget.hpp
motif_editor/MotifModel.hpp
seqbrowser/SequenceBrowserSidebar.hpp
seqbrowser/SequenceBrowserWidget.hpp
seqbrowser/SequenceDescription.hpp
+ subanalysis/SequenceLocationModel.hpp
+ subanalysis/SubanalysisWindow.hpp
)
SET(GUI_SOURCES
ImageSaveDialog.cpp
IntAction.cpp
MussaAlignedWindow.cpp
MussaWindow.cpp
- SequenceLocationModel.cpp
- SubanalysisWindow.cpp
ThresholdWidget.cpp
ZoomWidget.cpp
motif_editor/MotifEditor.cpp
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)
#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
#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"
+++ /dev/null
-#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;
-}
-
+++ /dev/null
-#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
+++ /dev/null
-#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());
-}
+++ /dev/null
-#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
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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
--- /dev/null
+#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());
+}
--- /dev/null
+#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
#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"