SubanalysisWindow.hpp
ThresholdWidget.hpp
ZoomWidget.hpp
- motif_editor/MotifDetail.hpp
+ motif_editor/MotifModel.hpp
motif_editor/MotifEditor.hpp
+ motif_editor/MotifEditorDelegate.hpp
mussa_setup_dialog/IsFileValidator.hpp
mussa_setup_dialog/MussaSetupDialog.hpp
mussa_setup_dialog/MussaSetupWidget.hpp
SubanalysisWindow.cpp
ThresholdWidget.cpp
ZoomWidget.cpp
- motif_editor/MotifDetail.cpp
motif_editor/MotifEditor.cpp
+ motif_editor/MotifEditorDelegate.cpp
+ motif_editor/MotifElement.cpp
+ motif_editor/MotifModel.cpp
mussa_setup_dialog/IsFileValidator.cpp
mussa_setup_dialog/MussaSetupDialog.cpp
mussa_setup_dialog/MussaSetupWidget.cpp
if (fileNames.size() != 1) {
return;
}
-
fs::path save_path(fileNames[0].toStdString(), fs::native);
// do you want to overwrite?
if (fs::exists(save_path) and
+++ /dev/null
-#include <QColorDialog>
-#include <QHBoxLayout>
-#include <QRegExp>
-
-#include "qui/motif_editor/MotifDetail.hpp"
-
-#include <iostream>
-using namespace std;
-
-static const QRegExp iupacAlphabet("[ACTGUWRKYSMBHDVN]*", Qt::CaseInsensitive);
-static const QRegExpValidator iupacValidator(iupacAlphabet, 0);
-
-MotifDetail::MotifDetail(QWidget *parent)
- : QWidget(parent),
- motif_color(1.0, 1.0, 1.0)
-{
- setupWidget();
-}
-
-MotifDetail::MotifDetail(const MotifDetail &md)
- : QWidget((QWidget *)md.parent()),
- motif_color(md.motif_color),
- motifText(md.motifText.displayText()),
- motifName(md.motifName.displayText())
-{
-}
-
-MotifDetail::MotifDetail(std::string& m, Color& c, std::string& name, QWidget *parent)
- : QWidget(parent),
- motif_color(c),
- motifText(m.c_str()),
- motifName(name.c_str())
-{
- setupWidget();
-}
-
-void MotifDetail::setupWidget()
-{
- QHBoxLayout *layout = new QHBoxLayout;
-
- enabledButton.setCheckState(Qt::Checked);
- layout->addWidget(&enabledButton);
- colorButton.setFlat(true);
- colorButton.setPalette(QPalette(qcolor()));
- colorButton.setAutoFillBackground(true);
- connect(&colorButton, SIGNAL(clicked()), this, SLOT(promptColor()));
- layout->addWidget(&colorButton);
- motifText.setValidator(&iupacValidator);
- layout->addWidget(&motifText);
- layout->addWidget(&motifName);
-
- setLayout(layout);
-}
-
-void MotifDetail::setMotif(const string &m)
-{
- motifText.setText(m.c_str());
-}
-
-string MotifDetail::motif() const
-{
- return motifText.text().toStdString();
-}
-
-void MotifDetail::setName(const std::string& name)
-{
- motifName.setText(name.c_str());
-}
-
-std::string MotifDetail::name() const
-{
- return motifName.text().toStdString();
-}
-
-void MotifDetail::setColor(const Color &c)
-{
- motif_color = c;
- colorButton.setPalette(QPalette(qcolor()));
-}
-
-Color MotifDetail::color() const
-{
- return motif_color;
-}
-
-QColor MotifDetail::qcolor() const
-{
- QColor qc;
- qc.setRedF(motif_color.r());
- qc.setGreenF(motif_color.g());
- qc.setBlueF(motif_color.b());
- return qc;
-}
-
-void MotifDetail::promptColor()
-{
- QColor new_qcolor = QColorDialog::getColor(qcolor(), this);
- Color new_color(new_qcolor.redF(), new_qcolor.greenF(), new_qcolor.blueF());
- setColor(new_color);
-}
-
-bool MotifDetail::enabled() const
-{
- return (enabledButton.checkState() == Qt::Checked);
-}
+++ /dev/null
-#ifndef _MOTIF_DETAIL_H
-#define _MOTIF_DETAIL_H
-
-#include <string>
-
-#include <QCheckBox>
-#include <QColor>
-#include <QLineEdit>
-#include <QPushButton>
-#include <QRegExpValidator>
-#include <QWidget>
-
-//#include "alg/sequence.hpp"
-#include "alg/color.hpp"
-
-class MotifDetail : public QWidget
-{
- Q_OBJECT
-
-public:
- MotifDetail(QWidget *parent=0);
- MotifDetail(const MotifDetail &);
- MotifDetail(std::string& m, Color& c, std::string& name, QWidget *parent=0);
-
- void setMotif(const std::string& m);
- std::string motif() const;
-
- void setName(const std::string& name);
- std::string name() const;
-
- void setColor(const Color&);
- Color color() const;
- QColor qcolor() const;
-
- // is this motif enabled?
- bool enabled() const;
-
-public slots:
- void promptColor();
-
-private:
- void setupWidget();
-
- Color motif_color;
-
- // widgets
- QCheckBox enabledButton;
- QPushButton colorButton;
- QLineEdit motifText;
- QLineEdit motifName;
-};
-#endif
MotifEditor::MotifEditor(Mussa *m, QWidget *parent)
: QWidget(parent),
analysis(m),
- applyButton("set motifs")
+ editor_layout(new QVBoxLayout(parent)),
+ button_layout(new QHBoxLayout(parent)),
+ table(new QTableView(this)),
+ delegate(new MotifEditorDelegate(this)),
+ applyButton(new QPushButton("apply")),
+ model(0)
{
assert (m != 0);
const set<Sequence> &motif = analysis->motifs();
vector<Sequence> motif_seq(motif.begin(), motif.end());
- connect(&applyButton, SIGNAL(clicked()), this, SLOT(updateMotifs()));
- layout.addWidget(&applyButton);
+ applyButton->setFocusPolicy(Qt::StrongFocus);
+ connect(applyButton, SIGNAL(clicked()), this, SLOT(updateMotifs()));
+ button_layout->addStretch();
+ button_layout->addWidget(applyButton);
+
+ table->setItemDelegate(delegate);
- for(size_t i=0; i != 10; ++i)
- {
- MotifDetail *detail = new MotifDetail;
- if (i < motif_seq.size()) {
- detail->setMotif(motif_seq[i].get_sequence());
- detail->setColor(analysis->colorMapper()->lookup("motif", motif_seq[i].get_sequence()));
- }
- motif_details.push_back(detail);
- layout.addWidget(detail);
- }
- setLayout(&layout);
+ editor_layout->addWidget(table);
+ editor_layout->addLayout(button_layout);
+ setLayout(editor_layout);
+
+ updateTitle();
+ updateModel();
}
-MotifEditor::MotifEditor(const MotifEditor& me)
- : QWidget((QWidget*)me.parent()),
- analysis(me.analysis),
- applyButton(me.applyButton.text())
+void MotifEditor::updateModel()
{
+ MotifModel *new_model = new MotifModel();
+
+ new_model->push_empty();
+
+ // if there was an old model, delete it
+ if (model) {
+ delete model;
+ }
+ // update the QTableView
+ model = new_model;
+ table->setModel(model);
+ updateView();
}
void MotifEditor::updateMotifs()
analysis->colorMapper()->appendTypeColor("motif", motif_default);
// add our motifs back
- vector<Sequence> motifs;
- vector<Color> colors;
+ vector<Sequence> new_motifs;
+ vector<Color> new_colors;
- for(std::vector<MotifDetail *>::iterator md_i = motif_details.begin();
- md_i != motif_details.end();
+ for(MotifModel::iterator md_i = model->begin();
+ md_i != model->end();
++md_i)
{
- if ((*md_i)->motif().size() > 0 && (*md_i)->enabled()) {
- Sequence new_motif((*md_i)->motif());
- new_motif.set_fasta_header((*md_i)->name());
- motifs.push_back((*md_i)->motif());
- colors.push_back((*md_i)->color());
+ if (md_i->getSequence().size() > 0 && md_i->isEnabled()) {
+ new_motifs.push_back(md_i->getSequence());
+ new_colors.push_back(md_i->getColor());
}
}
- analysis->set_motifs(motifs, colors);
+ analysis->set_motifs(new_motifs, new_colors);
emit changedMotifs();
}
-//MotifEditor::
+void MotifEditor::updateTitle()
+{
+ QString title("Motif Editor: ");
+ title.append(analysis->get_name().c_str());
+ setWindowTitle(title);
+
+}
+
+void MotifEditor::updateView()
+{
+ for (int row = 0; row < model->rowCount(QModelIndex()); ++row)
+ table->resizeRowToContents(row);
+ for (int column = 0; column < model->columnCount(QModelIndex()); ++column)
+ table->resizeColumnToContents(column);
+}
+
#include <vector>
#include <QPushButton>
+#include <QScrollArea>
+#include <QTableView>
#include <QVBoxLayout>
#include <QWidget>
#include "alg/mussa.hpp"
-#include "qui/motif_editor/MotifDetail.hpp"
+#include "qui/motif_editor/MotifModel.hpp"
class MotifEditor : public QWidget
{
public:
MotifEditor(Mussa* m, QWidget *parent=0);
- MotifEditor(const MotifEditor&);
+ //! update our window title
+ void updateTitle();
+ //! resize cells
+ void updateView();
+
public slots:
- // called to apply motif changes
+ //! create model and attach it to the table view
+ void updateModel();
+ //! called to apply motif changes
void updateMotifs();
signals:
- // emitted when the use has applied the motif changes
+ //! emitted when the use has applied the motif changes
void changedMotifs();
private:
Mussa* analysis;
- QPushButton applyButton;
- QVBoxLayout layout;
-
- std::vector<MotifDetail *> motif_details;
+ QPushButton *applyButton;
+ QVBoxLayout *editor_layout;
+ QHBoxLayout *button_layout;
+ QTableView *table;
+ MotifEditorDelegate *delegate;
+
+ MotifModel *model;
};
#endif
--- /dev/null
+#include "qui/motif_editor/MotifEditorDelegate.hpp"
+
+#include <Qt>
+#include <QCheckBox>
+#include <QColorDialog>
+#include <QEvent>
+#include <QKeyEvent>
+#include <QLineEdit>
+#include <QPainter>
+
+MotifEditorDelegate::MotifEditorDelegate(QWidget *parent) :
+ QItemDelegate(parent)
+{
+}
+
+QWidget *MotifEditorDelegate::createEditor(
+ QWidget *parent,
+ const QStyleOptionViewItem & /* option */,
+ const QModelIndex &index) const
+{
+ QWidget *widget = 0;
+ switch(index.column()) {
+ // case MotifModel::EnabledCell is handled in editorEvent
+ // case MotifModel::ColorCell:
+ // both of these should be text boxes
+ case MotifModel::NameCell:
+ case MotifModel::SequenceCell:
+ widget = new QLineEdit(parent);
+ widget->installEventFilter(const_cast<MotifEditorDelegate*>(this));
+ break;
+ default:
+ break;
+ }
+ return widget;
+}
+
+//! check to see if our event is something that should "activate" our cell
+static bool is_cell_activated(QEvent *event)
+{
+ // if a mouse releases on us we can toggle
+ if (event->type() == QEvent::MouseButtonRelease) {
+ return true;
+ // if we're a keypress
+ } else if (event->type() == QEvent::KeyPress) {
+ // try to convert to a KeyEvent
+ QKeyEvent *key_event = dynamic_cast<QKeyEvent *>(event);
+ // if we've gotten our key event, did the use hit the enter/return key?
+ if (key_event) {
+ if (key_event->key() == Qt::Key_Enter or key_event->key() == Qt::Key_Return) {
+ return true;
+ }
+ }
+ }
+ // all other cases don't toggle
+ return false;
+}
+bool MotifEditorDelegate::editorEvent(
+ QEvent *event,
+ QAbstractItemModel *model,
+ const QStyleOptionViewItem &option,
+ const QModelIndex & index )
+{
+ switch (index.column()) {
+ case MotifModel::EnabledCell:
+ if (is_cell_activated(event)) {
+ QVariant value = index.model()->data(index, Qt::DisplayRole);
+ value = not value.toBool();
+ model->setData(index, value);
+ return true;
+ }
+ break;
+ case MotifModel::ColorCell:
+ if (is_cell_activated(event)) {
+ QVariant value = index.model()->data(index, Qt::DisplayRole);
+ QColor old_color = value.value<QColor>();
+ QColor new_color = QColorDialog::getColor(old_color);
+ // color is not valid if user hit the cancel button on the color dialog
+ if (new_color.isValid()) {
+ model->setData(index, QVariant(new_color));
+ } else {
+ model->setData(index, QVariant(old_color));
+ }
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return this->QItemDelegate::editorEvent(event, model, option, index);
+}
+
+void MotifEditorDelegate::setEditorData(
+ QWidget *editor,
+ const QModelIndex &index) const
+{
+ QVariant value = index.model()->data(index, Qt::DisplayRole);
+ switch(index.column()) {
+ // toggling MotifModel::EnabledCell is handled by editorEvent
+ // case MotifModel::ColorCell is handled by paint and editorEvent
+
+ // both of these should be text boxes
+ case MotifModel::NameCell:
+ case MotifModel::SequenceCell:
+ static_cast<QLineEdit*>(editor)->setText(value.toString());
+ break;
+ default:
+ break;
+ }
+}
+
+void MotifEditorDelegate::setModelData(
+ QWidget *editor,
+ QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ QVariant value;
+ switch(index.column()) {
+ // both of these should be text boxes
+ case MotifModel::NameCell:
+ case MotifModel::SequenceCell:
+ value = static_cast<QLineEdit*>(editor)->text();
+ model->setData(index, value);
+ break;
+ default:
+ break;
+ }
+}
+
+struct painter_save_restore {
+ painter_save_restore(QPainter *p) { painter = p; painter->save(); }
+ ~painter_save_restore() { painter->restore(); }
+ QPainter *painter;
+};
+
+static void drawHighlightIfNeeded(QPainter *painter, const QStyleOptionViewItem &option)
+{
+ if (option.state & QStyle::State_Selected) {
+ painter->setBrush(option.palette.highlight());
+ painter->drawRect(option.rect);
+ }
+}
+
+void MotifEditorDelegate::paint(
+ QPainter * painter,
+ const QStyleOptionViewItem & option,
+ const QModelIndex & index ) const
+{
+ painter_save_restore saved(painter);
+
+ QVariant value = index.model()->data(index, Qt::DisplayRole);
+ switch(index.column()) {
+ case MotifModel::EnabledCell:
+ {
+ painter->setPen(Qt::NoPen);
+ drawHighlightIfNeeded(painter, option);
+ Qt::CheckState state = (value.toBool()) ? Qt::Checked : Qt::Unchecked;
+ this->QItemDelegate::drawCheck(painter, option, option.rect, state);
+ }
+ break;
+ case MotifModel::ColorCell:
+ {
+ painter->setPen(Qt::NoPen);
+ drawHighlightIfNeeded(painter, option);
+ QColor color(value.value<QColor>());
+ painter->setBrush(QBrush(color));
+ painter->drawRoundRect(option.rect, 60, 60);
+ }
+ break;
+ default:
+ this->QItemDelegate::paint(painter, option, index);
+ break;
+ }
+}
+
+void MotifEditorDelegate::updateEditorGeometry(
+ QWidget *editor,
+ const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ editor->setGeometry(option.rect);
+}
+
\ No newline at end of file
--- /dev/null
+#ifndef MOTIFEDITORDELEGATE_HPP_
+#define MOTIFEDITORDELEGATE_HPP_
+
+#include <QItemDelegate>
+#include <QWidget>
+
+#include "qui/motif_editor/MotifModel.hpp"
+
+class MotifEditorDelegate : public QItemDelegate
+{
+ Q_OBJECT
+
+public:
+ MotifEditorDelegate(QWidget *parent=0);
+
+ //! construct a editor widget for a given index.
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+
+ virtual bool editorEvent(QEvent *event, QAbstractItemModel *model,
+ const QStyleOptionViewItem & option, const QModelIndex & index );
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+ void updateEditorGeometry(QWidget *editor,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+ virtual void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
+private:
+};
+
+#endif /*MOTIFEDITORDELEGATE_HPP_*/
--- /dev/null
+#include "qui/motif_editor/MotifEditor.hpp"
+
+#include <iostream>
+
+MotifElement::MotifElement() :
+ enabled(true),
+ color(Color(1.0,0.0,0.0,1.0)),
+ motif()
+{
+}
+
+MotifElement::MotifElement(const Sequence& seq, Color c) :
+ enabled(true),
+ color(c),
+ motif(seq)
+{
+}
+
+bool MotifElement::isEmpty() const
+{
+ if (motif.get_name().size() == 0 and motif.size() == 0) {
+ return true;
+ }
+ return false;
+}
+//! should we search the analysis for this element?
+bool MotifElement::isEnabled() const
+{
+ return enabled;
+}
+
+//! set the state for searching the analysis for this element?
+void MotifElement::setEnabled(bool enabled_)
+{
+ enabled = enabled_;
+}
+
+//! return color should this motif be drawn as
+Color MotifElement::getColor() const
+{
+ return color;
+}
+
+//! set what color this motif should be drawn as
+void MotifElement::setColor(const Color& c)
+{
+ color = c;
+}
+
+//! return color should this motif be drawn as
+QColor MotifElement::getQColor() const
+{
+ QColor qcolor;
+ qcolor.setRgbF(color.r(), color.g(), color.b(), color.a());
+ return qcolor;
+}
+
+//! set what color this motif should be drawn as
+void MotifElement::setQColor(const QColor& c)
+{
+ color = Color(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+}
+
+//! return sequence
+const Sequence& MotifElement::getSequence() const
+{
+ return motif;
+}
+
+//! set sequence
+void MotifElement::setSequence(const Sequence& seq)
+{
+ motif = seq;
+}
+
+//! set sequence text
+void MotifElement::setSequence(const std::string& seq_text)
+{
+ motif.set_sequence(seq_text);
+}
+
+QString MotifElement::getSequenceText() const
+{
+ return QString(motif.get_sequence().c_str());
+}
+
+//! get sequence name
+std::string MotifElement::getName() const
+{
+ return motif.get_name();
+}
+
+//! set sequence name
+void MotifElement::setName(const std::string& seq_name)
+{
+ motif.set_fasta_header(seq_name);
+}
\ No newline at end of file
--- /dev/null
+#ifndef MOTIFELEMENT_HPP_
+#define MOTIFELEMENT_HPP_
+
+#include <QColor>
+#include <QString>
+
+#include "alg/color.hpp"
+#include "alg/sequence.hpp"
+
+class MotifElement {
+public:
+ MotifElement();
+ MotifElement(const Sequence& seq, Color c=Color(1.0,0.0,0.0,1.0));
+
+ //! is the element "empty"
+ bool isEmpty() const;
+
+ //! should we search the analysis for this element?
+ bool isEnabled() const;
+ //! set the state for searching the analysis for this element?
+ void setEnabled(bool);
+
+ //! return color should this motif be drawn as
+ Color getColor() const;
+ //! set what color this motif should be drawn as
+ void setColor(const Color& c);
+ //! return QColor should this motif should be drawn as
+ QColor getQColor() const;
+ //! set color using QColor
+ void setQColor(const QColor& c);
+
+ //! return sequence
+ const Sequence& getSequence() const;
+ //! set sequence
+ void setSequence(const Sequence& seq);
+ //! set sequence text
+ void setSequence(const std::string& seq_text);
+ //! get sequence text
+ QString getSequenceText() const;
+
+ //! get sequence name
+ std::string getName() const;
+ //! set sequence name
+ void setName(const std::string& seq_name);
+
+protected:
+ //! search for motif
+ bool enabled;
+ //! store motif color
+ Color color;
+ //! store sequence
+ Sequence motif;
+};
+#endif /*MOTIFELEMENT_HPP_*/
--- /dev/null
+#include "qui/motif_editor/MotifModel.hpp"
+
+#include <QColor>
+
+MotifModel::MotifModel(QObject *parent)
+ : QAbstractTableModel(parent)
+{
+}
+
+void MotifModel::assign(
+ MotifModel::size_type num,
+ const MotifElement& val
+)
+{
+ motifs.assign(num, val);
+}
+
+MotifElement& MotifModel::at(
+ MotifModel::size_type index
+)
+{
+ return motifs.at(index);
+}
+
+MotifElement& MotifModel::back()
+{
+ return motifs.back();
+}
+
+MotifModel::iterator MotifModel::begin()
+{
+ return motifs.begin();
+}
+
+MotifModel::const_iterator MotifModel::begin() const
+{
+ return motifs.begin();
+}
+
+void MotifModel::clear()
+{
+ if (motifs.size() != 0) {
+ beginRemoveRows(QModelIndex(), 0, motifs.size()-1);
+ motifs.clear();
+ endRemoveRows();
+ }
+}
+
+MotifModel::iterator MotifModel::end()
+{
+ return motifs.end();
+}
+
+MotifModel::const_iterator MotifModel::end() const
+{
+ return motifs.end();
+}
+
+bool MotifModel::empty() const
+{
+ return motifs.empty();
+}
+
+MotifElement& MotifModel::operator[](
+ MotifModel::size_type index
+)
+{
+ return motifs[index];
+}
+
+void MotifModel::pop_back()
+{
+ int last_element = motifs.size()-1;
+ if (last_element >= 0) {
+ beginRemoveRows(QModelIndex(), last_element, last_element);
+ motifs.pop_back();
+ endRemoveRows();
+ }
+}
+
+void MotifModel::push_back(const MotifElement& item)
+{
+ int last_element = motifs.size();
+ beginInsertRows(QModelIndex(), last_element, last_element);
+ motifs.push_back(item);
+ endInsertRows();
+}
+
+void MotifModel::push_empty()
+{
+ MotifElement blank;
+ push_back(blank);
+}
+
+MotifModel::size_type MotifModel::size() const
+{
+ return motifs.size();
+}
+
+int
+MotifModel::rowCount( const QModelIndex& parent) const
+{
+ return motifs.size();
+}
+
+int
+MotifModel::columnCount(const QModelIndex& parent) const
+{
+ return 4;
+}
+
+QVariant
+MotifModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (index.row() >= motifs.size())
+ return QVariant();
+
+ if (index.column() >= 4)
+ return QVariant();
+
+ const MotifElement& motif = motifs[index.row()];
+ if (role == Qt::DisplayRole) {
+ switch (index.column() ) {
+ case MotifModel::EnabledCell:
+ return QVariant(motif.isEnabled());
+ break;
+ case MotifModel::ColorCell:
+ return QVariant(motif.getQColor());
+ break;
+ case MotifModel::NameCell:
+ return QString(motif.getName().c_str());
+ break;
+ case MotifModel::SequenceCell:
+ return QString(motif.getSequenceText());
+ break;
+ }
+ }
+ return QVariant();
+}
+
+QVariant
+MotifModel::headerData(
+ int section,
+ Qt::Orientation orientation,
+ int role
+) const
+{
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (orientation == Qt::Horizontal) {
+ switch(section) {
+ case MotifModel::EnabledCell:
+ return QString("Enabled");
+ break;
+ case MotifModel::ColorCell:
+ return QString("Color");
+ break;
+ case MotifModel::NameCell:
+ return QString("Name");
+ break;
+ case MotifModel::SequenceCell:
+ return QString("Sequence");
+ break;
+ default:
+ return QVariant();
+ break;
+ }
+ }
+ return QVariant();
+}
+
+bool MotifModel::setData(
+ const QModelIndex& index,
+ const QVariant &value,
+ int role
+)
+{
+ if (index.isValid() and role == Qt::EditRole) {
+ MotifElement& motif = motifs[index.row()];
+ switch(index.column()) {
+ case MotifModel::EnabledCell:
+ motif.setEnabled(value.toBool());
+ break;
+ case MotifModel::ColorCell:
+ motif.setQColor(value.value<QColor>());
+ break;
+ case MotifModel::NameCell:
+ motif.setName(value.toString().toStdString());
+ break;
+ case MotifModel::SequenceCell:
+ motif.setSequence(value.toString().toStdString());
+ break;
+ default:
+ return false;
+ break;
+ }
+ emit dataChanged(index, index);
+ // automatically grow the list of motifs when the last one is full
+ if (not back().isEmpty()) {
+ push_empty();
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Qt::ItemFlags MotifModel::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 _MOTIF_MODEL_HPP_
+#define _MOTIF_MODEL_HPP_
+
+#include "alg/sequence.hpp"
+#include "qui/motif_editor/MotifElement.hpp"
+#include "qui/motif_editor/MotifEditorDelegate.hpp"
+
+#include <QAbstractTableModel>
+
+#include <vector>
+
+class MotifModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+ public:
+ MotifModel(QObject *parent = 0);
+
+ typedef std::vector<MotifElement> model_type;
+ typedef model_type::size_type size_type;
+ typedef model_type::iterator iterator;
+ typedef model_type::const_iterator const_iterator;
+
+ enum cell_names { EnabledCell, ColorCell, NameCell, SequenceCell };
+ //! \defgroup VectorInterface
+ //! \addtogroup VectorInterface
+ //! \@{
+ //! assign num copies of val to our vector
+ void assign(size_type num, const MotifElement& val);
+ //! return a specific element
+ MotifElement& at(size_type index);
+ //! return the last element
+ MotifElement& 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
+ MotifElement& operator[](size_type index);
+ //! remove the last element from our model
+ void pop_back();
+ //! add a MotifElement location to the end of our model
+ void push_back(const MotifElement&);
+ //! add an empty element to the end of our model
+ void push_empty();
+ //! 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 motifs;
+};
+
+#endif