From: Diane Trout Date: Mon, 30 Oct 2006 22:47:45 +0000 (+0000) Subject: move SubanalysisWindow code to a subdirectory X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=81c0ac18dbece99f99afb5b127e91162e1935de4 move SubanalysisWindow code to a subdirectory --- diff --git a/qui/CMakeLists.txt b/qui/CMakeLists.txt index d4ab6db..e7339ad 100644 --- a/qui/CMakeLists.txt +++ b/qui/CMakeLists.txt @@ -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) diff --git a/qui/MussaAlignedWindow.hpp b/qui/MussaAlignedWindow.hpp index 391ca54..28d43d6 100644 --- a/qui/MussaAlignedWindow.hpp +++ b/qui/MussaAlignedWindow.hpp @@ -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 diff --git a/qui/MussaWindow.hpp b/qui/MussaWindow.hpp index d848fea..8afa91b 100644 --- a/qui/MussaWindow.hpp +++ b/qui/MussaWindow.hpp @@ -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 index a4e9c71..0000000 --- a/qui/SequenceLocationModel.cpp +++ /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 index 6b6a924..0000000 --- a/qui/SequenceLocationModel.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _SEQUENCE_LOCATION_MODEL_HPP_ -#define _SEQUENCE_LOCATION_MODEL_HPP_ - -#include -#include "alg/sequence_location.hpp" -#include - -class SequenceLocationModel : public QAbstractTableModel -{ - Q_OBJECT - - public: - SequenceLocationModel(QObject *parent = 0); - - typedef std::vector 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 index 99dfb69..0000000 --- a/qui/SubanalysisWindow.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "qui/SubanalysisWindow.hpp" -#include "qui/MussaWindow.hpp" - -#include "mussa_exceptions.hpp" -#include "alg/mussa.hpp" - -#include -#include -#include -#include - -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 motifs_copy; - std::vector color_copy; - const Mussa::motif_set motifs = analysis->motifs(); - boost::shared_ptr 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 index 9d9ef73..0000000 --- a/qui/SubanalysisWindow.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef _SUBANALYSIS_H_ -#define _SUBANALYSIS_H_ - -#include -#include -#include -#include -#include - -#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 SubanalysisWindowRef; -#endif diff --git a/qui/subanalysis/SequenceLocationModel.cpp b/qui/subanalysis/SequenceLocationModel.cpp new file mode 100644 index 0000000..22f5d08 --- /dev/null +++ b/qui/subanalysis/SequenceLocationModel.cpp @@ -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 index 0000000..100fd46 --- /dev/null +++ b/qui/subanalysis/SequenceLocationModel.hpp @@ -0,0 +1,73 @@ +#ifndef _SEQUENCE_LOCATION_MODEL_HPP_ +#define _SEQUENCE_LOCATION_MODEL_HPP_ + +#include +#include +#include "alg/sequence_location.hpp" +#include + +class SequenceLocationModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + SequenceLocationModel(QObject *parent = 0); + + typedef std::vector 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 index 0000000..056ba9b --- /dev/null +++ b/qui/subanalysis/SubanalysisWindow.cpp @@ -0,0 +1,145 @@ +#include "qui/subanalysis/SubanalysisWindow.hpp" +#include "qui/MussaWindow.hpp" + +#include "mussa_exceptions.hpp" +#include "alg/mussa.hpp" + +#include +#include +#include +#include + +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 motifs_copy; + std::vector color_copy; + const Mussa::motif_set motifs = analysis->motifs(); + boost::shared_ptr 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 index 0000000..ce9f62c --- /dev/null +++ b/qui/subanalysis/SubanalysisWindow.hpp @@ -0,0 +1,47 @@ +#ifndef _SUBANALYSIS_H_ +#define _SUBANALYSIS_H_ + +#include +#include +#include +#include +#include + +#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 SubanalysisWindowRef; +#endif diff --git a/qui/test/TestSequenceLocationModel.hpp b/qui/test/TestSequenceLocationModel.hpp index a1a774e..153a4f5 100644 --- a/qui/test/TestSequenceLocationModel.hpp +++ b/qui/test/TestSequenceLocationModel.hpp @@ -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"