diff --git a/modules/gui/src/gosty_app.cc b/modules/gui/src/gosty_app.cc index 9042605a2bda008f7ac0aeed8e55ae6e378d636d..342427a11ad9ece9609a12bb8b448c1e7319a6bc 100644 --- a/modules/gui/src/gosty_app.cc +++ b/modules/gui/src/gosty_app.cc @@ -104,7 +104,7 @@ SceneWin* GostyApp::GetSceneWin() SequenceViewer* GostyApp::GetSequenceViewer() { if (seq_viewer_==NULL) { - seq_viewer_=new SequenceViewer(false); + seq_viewer_=new SequenceViewer(false, true); seq_viewer_->SetDestroyOnClose(false); } return seq_viewer_; diff --git a/modules/gui/src/sequence_viewer/alignment_view_object.cc b/modules/gui/src/sequence_viewer/alignment_view_object.cc index 1ba35dae8e5537ee4a4149f22293f3e476af3077..1ce665c5c788ddf3f3b2e416d0de8fe7826f34b7 100644 --- a/modules/gui/src/sequence_viewer/alignment_view_object.cc +++ b/modules/gui/src/sequence_viewer/alignment_view_object.cc @@ -80,7 +80,7 @@ const QString AlignmentViewObject::conservation_mode_2 = "Highlight conservation AlignmentViewObject::AlignmentViewObject(const seq::AlignmentHandle& alignment, QObject* parent): SequenceViewObject(parent), alignment_(alignment) { for(int i=0; i<alignment.GetCount(); i++){ - seq::SequenceHandle seq_handle = alignment.GetSequence(i).Copy(); + seq::ConstSequenceHandle seq_handle = alignment.GetSequence(i); this->AddSequence(seq_handle, seq_handle.GetName().c_str()); } diff --git a/modules/gui/src/sequence_viewer/secstr_row.cc b/modules/gui/src/sequence_viewer/secstr_row.cc index 2610fc1a20493f14a50665270736addfb1718f35..506867d0002236ad3af6e42229d911bfdb910a1e 100644 --- a/modules/gui/src/sequence_viewer/secstr_row.cc +++ b/modules/gui/src/sequence_viewer/secstr_row.cc @@ -36,7 +36,7 @@ namespace ost { namespace gui { SecStrRow::SecStrRow(const QString& name, mol::ChainView& chain, SequenceViewObject* parent) : SequenceRow(name,parent) { this->SetChain(chain); } -void SecStrRow::SetSequence(seq::SequenceHandle& sequence) +void SecStrRow::SetSequence(seq::ConstSequenceHandle sequence) { //Do nothing } diff --git a/modules/gui/src/sequence_viewer/secstr_row.hh b/modules/gui/src/sequence_viewer/secstr_row.hh index 7a9d7991dc3e4dbf30f3d646eb4ba0d994591862..900659cd0968c4ced7bcdfd27495478f09f4ab89 100644 --- a/modules/gui/src/sequence_viewer/secstr_row.hh +++ b/modules/gui/src/sequence_viewer/secstr_row.hh @@ -38,12 +38,13 @@ class SecStrRow : public SequenceRow Q_OBJECT public: - SecStrRow(const QString& name, mol::ChainView& chain, SequenceViewObject* parent); + SecStrRow(const QString& name, mol::ChainView& chain, + SequenceViewObject* parent); virtual QVariant GetData(int column, int role) const; virtual void DoubleClicked(int column); - void SetSequence(seq::SequenceHandle& sequence); + void SetSequence(seq::ConstSequenceHandle sequence); void SetChain(mol::ChainView& chain); const mol::ChainView& GetChain() const; diff --git a/modules/gui/src/sequence_viewer/sequence_model.cc b/modules/gui/src/sequence_viewer/sequence_model.cc index 342a04e1f258cfe8b87cd0488bb616d46b94ab2c..b8dc257669677f595000a3088ce57a01ccb9b7e6 100644 --- a/modules/gui/src/sequence_viewer/sequence_model.cc +++ b/modules/gui/src/sequence_viewer/sequence_model.cc @@ -186,7 +186,7 @@ const PainterList& SequenceModel::GetPainters(const QModelIndex& index) const{ return empty_painter_list_; } -QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(int row) const{ +QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(int row) const { if(!objects_.isEmpty()){ int rows = 0; int i = -1; @@ -202,6 +202,25 @@ QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(int row) const{ return QPair<int, BaseViewObject*>(-1, NULL); } +void SequenceModel::EmitRowChanged(int row) +{ + emit this->dataChanged(this->index(row, 0), + this->index(row, this->columnCount()-1)); +} + +QPair<seq::AlignmentHandle, int> SequenceModel::GetAlignmentForRow(int row) +{ + QPair<int, BaseViewObject*> p=this->GetRowWithItem(row); + if (p.second) { + AlignmentViewObject* avo=dynamic_cast<AlignmentViewObject*>(p.second); + if (avo) { + return QPair<seq::AlignmentHandle, int>(avo->GetAlignment(), p.first); + } + } + return QPair<seq::AlignmentHandle, int>(seq::AlignmentHandle(), -1); +} + + QPair<int, BaseViewObject*> SequenceModel::GetRowWithItem(const QModelIndex& index) const{ return this->GetRowWithItem(index.row()); } diff --git a/modules/gui/src/sequence_viewer/sequence_model.hh b/modules/gui/src/sequence_viewer/sequence_model.hh index 5a105c66fd1b8aa6b95d9dc5883e998191192cba..cb5e2d849e5b92c5d1e48d0ec747a83a57f30bee 100644 --- a/modules/gui/src/sequence_viewer/sequence_model.hh +++ b/modules/gui/src/sequence_viewer/sequence_model.hh @@ -60,7 +60,6 @@ public: int GetGlobalRow(BaseViewObject* obj, int row) const; - const QStringList& GetDisplayModes(); const QStringList& GetDisplayModes(const gfx::EntityP& entity); const QStringList& GetDisplayModes(const seq::AlignmentHandle& alignment); @@ -84,7 +83,9 @@ public: int role=Qt::DisplayRole) const; virtual Qt::ItemFlags flags(const QModelIndex& index=QModelIndex()) const; - + QPair<seq::AlignmentHandle, int> GetAlignmentForRow(int row); + + void EmitRowChanged(int row); public slots: void ZoomIn(); void ZoomOut(); diff --git a/modules/gui/src/sequence_viewer/sequence_row.cc b/modules/gui/src/sequence_viewer/sequence_row.cc index 5537b9f82e51b1c121163147cf9f0edc950bd81b..77bc27897aaaf94fe459385bdbaad567f04e093b 100644 --- a/modules/gui/src/sequence_viewer/sequence_row.cc +++ b/modules/gui/src/sequence_viewer/sequence_row.cc @@ -34,7 +34,7 @@ #include <QtGui> namespace ost { namespace gui { -SequenceRow::SequenceRow(const QString& name, seq::SequenceHandle& sequence, SequenceViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name), name_font_(QFont("Courier",11)), sequence_(sequence) +SequenceRow::SequenceRow(const QString& name, seq::ConstSequenceHandle sequence, SequenceViewObject* parent) : BaseRow(QFont("Courier",11),parent), name_(name), name_font_(QFont("Courier",11)), sequence_(sequence) { name_font_.setBold(true); name_font_.setItalic(true); @@ -61,12 +61,12 @@ const QString& SequenceRow::GetName() const return this->name_; } -void SequenceRow::SetSequence(seq::SequenceHandle& sequence) +void SequenceRow::SetSequence(seq::ConstSequenceHandle sequence) { this->sequence_ = sequence; } -const seq::SequenceHandle& SequenceRow::GetSequence() const +const seq::ConstSequenceHandle& SequenceRow::GetSequence() const { return this->sequence_; } diff --git a/modules/gui/src/sequence_viewer/sequence_row.hh b/modules/gui/src/sequence_viewer/sequence_row.hh index 1665366ba447e0121b94a5c9a41fa5919616d291..b48c1c627db2ee1b893a575fdb4a44b751241346 100644 --- a/modules/gui/src/sequence_viewer/sequence_row.hh +++ b/modules/gui/src/sequence_viewer/sequence_row.hh @@ -38,7 +38,8 @@ class SequenceRow : public BaseRow Q_OBJECT public: - SequenceRow(const QString& name, seq::SequenceHandle& sequence, SequenceViewObject* parent); + SequenceRow(const QString& name, seq::ConstSequenceHandle sequence, + SequenceViewObject* parent); SequenceRow(const QString& name, SequenceViewObject* parent); virtual int GetColumnCount() const; @@ -50,15 +51,15 @@ public: void SetName(const QString& name); const QString& GetName() const; - virtual void SetSequence(seq::SequenceHandle& sequence); - const seq::SequenceHandle& GetSequence() const; + virtual void SetSequence(seq::ConstSequenceHandle sequence); + const seq::ConstSequenceHandle& GetSequence() const; virtual void SetSelection(const QSet<int>& added, const QSet<int>& removed); private: QString name_; QFont name_font_; - seq::SequenceHandle sequence_; + seq::ConstSequenceHandle sequence_; }; }} diff --git a/modules/gui/src/sequence_viewer/sequence_table_view.cc b/modules/gui/src/sequence_viewer/sequence_table_view.cc index 199ee8c4af907abd6d6c414c6aab704f86d3680b..bbe7a2da32421e150db3703e4f4ee1e7f701422d 100644 --- a/modules/gui/src/sequence_viewer/sequence_table_view.cc +++ b/modules/gui/src/sequence_viewer/sequence_table_view.cc @@ -89,7 +89,6 @@ void SequenceTableView::InitStaticColumn() for(int col=1; col<this->model()->columnCount(); col++){ static_column_->setColumnHidden(col, true); } - static_column_->setColumnWidth(0, this->columnWidth(0) ); static_column_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -380,8 +379,86 @@ void SequenceTableView::wheelEvent(QWheelEvent* event) } } +std::pair<int, int> SequenceTableView::GetSimpleSelection(int row) +{ + QModelIndexList sel=this->selectionModel()->selectedIndexes(); + QModelIndexList row_sel; + for (QModelIndexList::const_iterator i=sel.begin(), e=sel.end(); i!=e; ++i) { + if (i->row()==row) { + row_sel.push_back(*i); + } + } + if (row_sel.empty()) { + return std::make_pair(-1, -1); + } + std::sort(row_sel.begin(), row_sel.end(), std::less<QModelIndex>()); + for (QModelIndexList::const_iterator i=row_sel.begin()+1, + e=row_sel.end(); i!=e; ++i) { + if ((i-1)->column()!=i->column()-1) { + return std::make_pair(-1, -1); + } + } + return std::make_pair(row_sel.front().column()-1, row_sel.back().column()-1); +} + void SequenceTableView::keyPressEvent(QKeyEvent* event) { + if (this->IsSingleAlignment()) { + if (event->key()==Qt::Key_Space || event->key()==Qt::Key_Backspace) { + std::vector<QItemSelection> new_sel; + int row_count=this->model()->rowCount(); + seq::AlignmentHandle changed_aln; + for (int i=1; i<row_count; ++i) { + std::pair<int, int> sel=this->GetSimpleSelection(i); + if (sel.first==-1 && sel.second==-1) { + continue; + } + + SequenceModel* smodel=dynamic_cast<SequenceModel*>(this->model()); + QPair<seq::AlignmentHandle, int> aln=smodel->GetAlignmentForRow(i); + new_sel.push_back(QItemSelection(smodel->index(i, sel.first+1), + smodel->index(i, sel.second+1))); + if (aln.second==-1) { + continue; + } + int amount=0; + if (event->key()==Qt::Key_Space) { + amount=1; + if (aln.first.GetLength()==sel.second) { + continue; + } + if (aln.first.GetSequence(aln.second)[sel.second+1]!='-') { + continue; + } + } + if (event->key()==Qt::Key_Backspace) { + amount=-1; + if (sel.first==0) { + continue; + } + if (aln.first.GetSequence(aln.second)[sel.first-1]!='-') { + continue; + } + } + changed_aln=aln.first; + aln.first.ShiftRegion(sel.first, sel.second+1, amount, aln.second); + new_sel.back()=QItemSelection(smodel->index(i, sel.first+amount+1), + smodel->index(i, sel.second+amount+1)); + smodel->EmitRowChanged(i); + } + QItemSelectionModel* sel_model=this->selectionModel(); + sel_model->clear(); + for (size_t i=0; i<new_sel.size(); ++i) { + sel_model->select(new_sel[i], QItemSelectionModel::SelectCurrent); + } + if (changed_aln.IsValid()) { + emit this->AlignmentChanged(); + } + return; + } + + } + if(event->matches(QKeySequence::Copy)){ emit CopyEvent(event); } diff --git a/modules/gui/src/sequence_viewer/sequence_table_view.hh b/modules/gui/src/sequence_viewer/sequence_table_view.hh index 3114a8f6e8c334cd40f46529f9f05707aa62dcac..28eaf3b19c3ab9cd32bdb095fbb713313f4416c0 100644 --- a/modules/gui/src/sequence_viewer/sequence_table_view.hh +++ b/modules/gui/src/sequence_viewer/sequence_table_view.hh @@ -42,10 +42,14 @@ public: QTableView* GetStaticField(); ~SequenceTableView(); + + void SetSingleAlignment(bool flag) { single_alignment_=flag; } + + bool IsSingleAlignment() const { return single_alignment_; } signals: void MouseWheelEvent(QWheelEvent* event); void CopyEvent(QKeyEvent* event); - + void AlignmentChanged(); public slots: void columnCountChanged(const QModelIndex& index, int old_count, int new_count); void rowCountChanged(const QModelIndex& index, int old_count, int new_count); @@ -69,11 +73,14 @@ private slots: void ResizeHeight(int index, int, int size); private: + + std::pair<int, int> GetSimpleSelection(int row); QTableView* static_column_; QTableView* static_row_; QTableView* static_field_; SequenceDelegate* delegate_; QModelIndex last_double_click_; + bool single_alignment_; void updateStaticColumn(); void updateStaticRow(); void updateStaticField(); diff --git a/modules/gui/src/sequence_viewer/sequence_view_object.cc b/modules/gui/src/sequence_viewer/sequence_view_object.cc index 40a46a519d85158584d37338558bd70128fd7f6b..e884de755c74342180e4be5b88c9de08d012e551 100644 --- a/modules/gui/src/sequence_viewer/sequence_view_object.cc +++ b/modules/gui/src/sequence_viewer/sequence_view_object.cc @@ -100,7 +100,7 @@ void SequenceViewObject::Init() } } -void SequenceViewObject::AddSequence(seq::SequenceHandle& sequence, const QString& name) +void SequenceViewObject::AddSequence(seq::ConstSequenceHandle sequence, const QString& name) { SequenceRow* new_row = new SequenceRow(name, sequence, this); new_row->InsertPainter(background_painter); @@ -163,7 +163,7 @@ QMap<int, QList<int> > SequenceViewObject::GetIndexesForView(const mol::EntityVi for(int i=0; i< rows_.size(); i++){ if(SecStrRow* secstr_row = qobject_cast<SecStrRow*>(rows_[i])){ mol::ChainView dst_chain=(secstr_row->GetChain()); - seq::SequenceHandle seq = secstr_row->GetSequence(); + seq::ConstSequenceHandle seq = secstr_row->GetSequence(); if (mol::ChainView src_chain=view.FindChain(dst_chain.GetName())) { // for each residue in the selection deduce index in sequence for (mol::ResidueViewList::const_iterator j=src_chain.GetResidueList().begin(), @@ -191,7 +191,7 @@ QMap<int, QList<int> > SequenceViewObject::GetIndexesForSubject(const QString& s for(int i=0; i< rows_.size(); i++){ if(SequenceRow* secstr_row = qobject_cast<SequenceRow*>(rows_[i])){ if(sequence_name.size()==0 || sequence_name==secstr_row->GetName()){ - seq::SequenceHandle seq = secstr_row->GetSequence(); + seq::ConstSequenceHandle seq = secstr_row->GetSequence(); String seq_str=seq.GetString(); size_t pos=0; size_t first=String::npos; diff --git a/modules/gui/src/sequence_viewer/sequence_view_object.hh b/modules/gui/src/sequence_viewer/sequence_view_object.hh index ba862c724efba112968fdc735f0f1cc1271a4492..9060052e80baf5dbc05143a3236461604aa4e9c6 100644 --- a/modules/gui/src/sequence_viewer/sequence_view_object.hh +++ b/modules/gui/src/sequence_viewer/sequence_view_object.hh @@ -55,7 +55,7 @@ public: void Init(); - void AddSequence(seq::SequenceHandle& sequence, const QString& name=QString()); + void AddSequence(seq::ConstSequenceHandle sequence, const QString& name=QString()); void AddChain(mol::ChainView& chain, const QString& name=QString()); void AttachGfxObject(gfx::EntityP& ent); diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.cc b/modules/gui/src/sequence_viewer/sequence_viewer.cc index 79c13057f9e85b248bfc9590d3f5bc1af19929ad..5ad1dda2e48a38595ef5ab1ae657f901bf2cba86 100644 --- a/modules/gui/src/sequence_viewer/sequence_viewer.cc +++ b/modules/gui/src/sequence_viewer/sequence_viewer.cc @@ -38,6 +38,8 @@ #include "sequence_model.hh" #include "sequence_viewer.hh" +#include "sequence_search_bar.hh" +#include "sequence_table_view.hh" #include <QAbstractItemView> #include <QApplication> @@ -49,6 +51,7 @@ #include <QShortcut> #include <QVBoxLayout> #include <QVarLengthArray> + namespace ost { namespace gui { class SequenceViewerFactory: public WidgetFactory { @@ -73,8 +76,10 @@ struct GetNodesVisitor: public gfx::GfxNodeVisitor { gfx::NodePtrList GetNodes(){return nodes_;} }; -SequenceViewer::SequenceViewer(bool stand_alone, QWidget* parent): Widget(NULL,parent) +SequenceViewer::SequenceViewer(bool stand_alone, bool observe_scene, + QWidget* parent): Widget(NULL,parent) { + observe_scene_=observe_scene; model_ = new SequenceModel(this); QVBoxLayout* layout = new QVBoxLayout(this); @@ -90,8 +95,7 @@ SequenceViewer::SequenceViewer(bool stand_alone, QWidget* parent): Widget(NULL,p } this->InitSearchBar(); this->InitView(); - - if(!stand_alone){ + if (observe_scene_) { gfx::Scene::Instance().AttachObserver(this); gfx::GfxNodeP root_node = gfx::Scene::Instance().GetRootNode(); GetNodesVisitor gnv; @@ -99,8 +103,10 @@ SequenceViewer::SequenceViewer(bool stand_alone, QWidget* parent): Widget(NULL,p gfx::NodePtrList list = gnv.GetNodes(); for(unsigned int i=0; i<list.size();i++){ this->NodeAdded(list[i]); - } + } } + connect(seq_table_view_, SIGNAL(AlignmentChanged()), + this, SIGNAL(AlignmentChanged())); } void SequenceViewer::InitMenuBar() @@ -170,6 +176,10 @@ void SequenceViewer::InitActions() void SequenceViewer::AddEntity(const gfx::EntityP& entity) { + if (!observe_scene_) { + return; + } + seq_table_view_->SetSingleAlignment(false); model_->InsertGfxEntity(entity); this->FitToContents(); this->UpdateSearchBar(); @@ -177,11 +187,17 @@ void SequenceViewer::AddEntity(const gfx::EntityP& entity) void SequenceViewer::RemoveEntity(const gfx::EntityP& entity) { + if (!observe_scene_) { + return; + } model_->RemoveGfxEntity(entity); } void SequenceViewer::NodeAdded(const gfx::GfxNodeP& n) { + if (!observe_scene_) { + return; + } if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(n)) { this->AddEntity(o); } @@ -189,6 +205,9 @@ void SequenceViewer::NodeAdded(const gfx::GfxNodeP& n) void SequenceViewer::NodeRemoved(const gfx::GfxNodeP& node) { + if (!observe_scene_) { + return; + } if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(node)) { this->RemoveEntity(o); } @@ -197,6 +216,11 @@ void SequenceViewer::NodeRemoved(const gfx::GfxNodeP& node) void SequenceViewer::AddAlignment(const seq::AlignmentHandle& alignment) { if(alignment.GetCount()>0 && alignment.GetLength()>0){ + if (model_->rowCount()>1) { + seq_table_view_->SetSingleAlignment(false); + } else { + seq_table_view_->SetSingleAlignment(true); + } model_->InsertAlignment(alignment); this->FitToContents(); } diff --git a/modules/gui/src/sequence_viewer/sequence_viewer.hh b/modules/gui/src/sequence_viewer/sequence_viewer.hh index 6a3c49efcabf852bf39a1bf47d6f503f75c2c5ea..1f83cb7de4cd4a0f97c1007a4b6a605fda6781d9 100644 --- a/modules/gui/src/sequence_viewer/sequence_viewer.hh +++ b/modules/gui/src/sequence_viewer/sequence_viewer.hh @@ -28,37 +28,46 @@ #include <ost/gfx/scene.hh> #include <ost/gfx/gfx_object.hh> - +#include <ost/gfx/entity.hh> #include <ost/gui/widget.hh> #include <ost/gui/module_config.hh> -#include "sequence_search_bar.hh" -#include "sequence_model.hh" -#include "sequence_table_view.hh" #include <QWidget> #include <QActionGroup> #include <QToolBar> -namespace ost { namespace gui { +#include <QModelIndex> +#include <QItemSelection> + +namespace ost { + +namespace gui { + +class SeqSearchBar; +class SequenceModel; +class SequenceTableView; + /// \brief QTableView with first column not moving class DLLEXPORT_OST_GUI SequenceViewer : public Widget, public gfx::SceneObserver { Q_OBJECT public: - SequenceViewer(bool stand_alone=true, QWidget* parent=NULL); + SequenceViewer(bool stand_alone=true, bool observe_scene=false, + QWidget* parent=NULL); ~SequenceViewer(); virtual void SelectionChanged(const gfx::GfxObjP& o, const mol::EntityView& view); virtual void AddEntity(const gfx::EntityP& entity); virtual void RemoveEntity(const gfx::EntityP& entity); - + void SetObserveScene(bool flag) { observe_scene_=flag; } + bool IsObservingScene() const { return observe_scene_; } virtual void AddAlignment(const seq::AlignmentHandle& alignment); virtual void RemoveAlignment(const seq::AlignmentHandle& alignment); - - virtual bool Restore(const QString&){return true;}; - virtual bool Save(const QString&){return true;}; + + virtual bool Restore(const QString&){ return true; }; + virtual bool Save(const QString&){ return true; }; virtual const QStringList& GetDisplayModes(); virtual const QStringList& GetDisplayModes(const seq::AlignmentHandle& alignment); @@ -69,7 +78,8 @@ public: virtual const QString& GetCurrentDisplayMode(const gfx::EntityP& entity); virtual ActionList GetActions(); - +signals: + void AlignmentChanged(); public slots: void ChangeDisplayMode(const QString&); void ChangeDisplayMode(const seq::AlignmentHandle&, const QString&); @@ -92,11 +102,11 @@ private: SeqSearchBar* seq_search_bar_; SequenceModel* model_; SequenceTableView* seq_table_view_; - + ActionList action_list_; QActionGroup* display_mode_actions_; - + bool observe_scene_; private slots: void ChangeDisplayMode(); void FindInSequence();