From 48c2355472a552df00e29b6130fe96ac0c044ed3 Mon Sep 17 00:00:00 2001
From: stefan <stefan@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Mon, 3 May 2010 10:53:13 +0000
Subject: [PATCH] New SequenceViewer, observing scene for selection changes

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2166 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 .../gui/src/sequence/seq_secstr_painter.cc    |  2 -
 modules/gui/src/sequence/sequence_model.cc    | 40 ++++++++++++++
 modules/gui/src/sequence/sequence_model.hh    | 11 ++--
 .../gui/src/sequence/sequence_table_view.cc   |  4 ++
 .../gui/src/sequence/sequence_table_view.hh   |  1 +
 modules/gui/src/sequence/sequence_viewer.cc   | 47 +++++++++++++----
 modules/gui/src/sequence/sequence_viewer.hh   |  5 +-
 modules/gui/src/sequence/view_object.cc       | 52 ++++++++++++++++---
 modules/gui/src/sequence/view_object.hh       |  8 ++-
 9 files changed, 146 insertions(+), 24 deletions(-)

diff --git a/modules/gui/src/sequence/seq_secstr_painter.cc b/modules/gui/src/sequence/seq_secstr_painter.cc
index 095841b25..591559870 100644
--- a/modules/gui/src/sequence/seq_secstr_painter.cc
+++ b/modules/gui/src/sequence/seq_secstr_painter.cc
@@ -54,8 +54,6 @@ void SeqSecStrPainter::Paint(QPainter* painter, const QStyleOptionViewItem& opti
         painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
         pos = center + std_diff;
         painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-        //stack.push_back(QPointF(s.first*advance_, -.6*height_));
-        //stack.push_back(QPointF((s.last+1)*advance_,  -.6*height_));
       } else if (sec_element.IsHelical()) {
         int pos = center - diff;
         painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
diff --git a/modules/gui/src/sequence/sequence_model.cc b/modules/gui/src/sequence/sequence_model.cc
index 95613ac9a..ee2aba06a 100644
--- a/modules/gui/src/sequence/sequence_model.cc
+++ b/modules/gui/src/sequence/sequence_model.cc
@@ -143,6 +143,38 @@ ViewObject* SequenceModel::GetItem(const QModelIndex& index) const
   return this->GetRowWithItem(index).second;
 }
 
+int SequenceModel::GetGlobalRow(ViewObject* obj, int row) const
+{
+  int glob_row = -1;
+  int index = objects_.indexOf(obj);
+  if(index >= 0){
+    glob_row = 0;
+    for(int i=0; i<index; i++){
+      glob_row += objects_[i]->GetRowCount();
+    }
+    return glob_row + row;
+  }
+  return glob_row;
+}
+
+QModelIndexList SequenceModel::GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view)
+{
+  QModelIndexList list;
+  if(ViewObject* object = this->GetObject(entity)){
+    QMap<int, QList<int> > indexes = object->GetIndexesForView(view);
+    QMapIterator< int, QList<int> > i(indexes);
+    while (i.hasNext()) {
+      i.next();
+      int row = this->GetGlobalRow(object, i.key());
+      const QList<int>& index_list = i.value();
+      for(int i=0; i<index_list.size(); i++){
+        list.append(this->index(row,index_list[i]));
+      }
+    }
+  }
+  return list;
+}
+
 void SequenceModel::SelectionChanged(const QItemSelection& sel, const QItemSelection& desel)
 {
   QMap<int,QPair<QSet<int>,QSet<int> > > sel_map;
@@ -164,6 +196,14 @@ void SequenceModel::SelectionChanged(const QItemSelection& sel, const QItemSelec
   }
 }
 
+void SequenceModel::DoubleClicked(const QModelIndex& index)
+{
+  QPair<int, ViewObject*> item = this->GetRowWithItem(index);
+  if(item.second){
+    item.second->DoubleClicked(item.first,index.column());
+  }
+}
+
 int SequenceModel::rowCount(const QModelIndex& parent) const
 {
   int rows = 0;
diff --git a/modules/gui/src/sequence/sequence_model.hh b/modules/gui/src/sequence/sequence_model.hh
index 93e2f7cba..173c7f962 100644
--- a/modules/gui/src/sequence/sequence_model.hh
+++ b/modules/gui/src/sequence/sequence_model.hh
@@ -42,20 +42,21 @@ class SequenceModel : public QAbstractTableModel
 public:
   SequenceModel(QObject *parent = 0);
 
-  void InsertGfxEntity(gfx::EntityP& ent);
+  void InsertGfxEntity(gfx::EntityP& entity);
   void InsertChain(QString& name, mol::ChainView& view);
   void InsertSequence(QString& name, seq::SequenceHandle& seq);
   void InsertSequences(const QList<QString>& names, seq::SequenceList& list);
 
   void RemoveGfxEntity(gfx::EntityP& entity);
 
+  QModelIndexList GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view);
+  int GetGlobalRow(ViewObject* obj, int row) const;
+
   ViewObject* GetObject(gfx::EntityP& entity);
   const PainterList& GetPainters(const QModelIndex& index) const;
 
   ViewObject* GetItem(const QModelIndex& index) const;
 
-  void SelectionChanged(const QItemSelection& sel, const QItemSelection& desel);
-
   // abstract item model interface
   int rowCount(const QModelIndex& parent=QModelIndex()) const;
 
@@ -68,6 +69,10 @@ public:
 
   virtual Qt::ItemFlags flags(const QModelIndex& index=QModelIndex()) const;
 
+public slots:
+  void DoubleClicked(const QModelIndex& index);
+  void SelectionChanged(const QItemSelection& sel, const QItemSelection& desel);
+
 private:
   QPair<int, ViewObject*> GetRowWithItem(int row) const;
   QPair<int, ViewObject*> GetRowWithItem(const QModelIndex& index) const;
diff --git a/modules/gui/src/sequence/sequence_table_view.cc b/modules/gui/src/sequence/sequence_table_view.cc
index e9e4ab84c..44faeaebf 100644
--- a/modules/gui/src/sequence/sequence_table_view.cc
+++ b/modules/gui/src/sequence/sequence_table_view.cc
@@ -179,6 +179,10 @@ void SequenceTableView::resizeColumnsToContents(){
   updateNotMoveColumn();
 }
 
+QTableView* SequenceTableView::GetFirstRow(){
+  return column_not_move_;
+}
+
 SequenceTableView::~SequenceTableView(){}
 
 }}
diff --git a/modules/gui/src/sequence/sequence_table_view.hh b/modules/gui/src/sequence/sequence_table_view.hh
index b846982fa..9d3af2eac 100644
--- a/modules/gui/src/sequence/sequence_table_view.hh
+++ b/modules/gui/src/sequence/sequence_table_view.hh
@@ -41,6 +41,7 @@ public:
 public slots:
   void columnCountChanged(const QModelIndex& index, int old_count, int new_count);
   void resizeColumnsToContents();
+  QTableView* GetFirstRow();
 
 protected:
   virtual void resizeEvent(QResizeEvent *event);
diff --git a/modules/gui/src/sequence/sequence_viewer.cc b/modules/gui/src/sequence/sequence_viewer.cc
index 4496048c2..146040fd4 100644
--- a/modules/gui/src/sequence/sequence_viewer.cc
+++ b/modules/gui/src/sequence/sequence_viewer.cc
@@ -25,6 +25,7 @@
 #include <QVBoxLayout>
 #include <QPushButton>
 #include <QHeaderView>
+#include <QAbstractItemView>
 
 #include <ost/mol/chain_view.hh>
 #include <ost/mol/entity_view.hh>
@@ -57,12 +58,10 @@ SequenceViewerV2::SequenceViewerV2(QWidget* parent): Widget(NULL,parent)
 
   seq_table_view_->horizontalHeader()->setMinimumSectionSize(2);
   seq_table_view_->verticalHeader()->setMinimumSectionSize(2);
-
-  connect(seq_table_view_->selectionModel(),
-      SIGNAL(selectionChanged(const QItemSelection&,
-              const QItemSelection&)), this,
-      SLOT(OnSelectionChange(const QItemSelection&,
-              const QItemSelection&)));
+  seq_table_view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
+  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  connect(seq_table_view_,SIGNAL(doubleClicked(const QModelIndex&)),model_,SLOT(DoubleClicked(const QModelIndex&)));
+  connect(seq_table_view_->GetFirstRow(),SIGNAL(doubleClicked(const QModelIndex&)),model_,SLOT(DoubleClicked(const QModelIndex&)));
 }
 
 void SequenceViewerV2::NodeAdded(const gfx::GfxNodeP& n)
@@ -81,11 +80,41 @@ void SequenceViewerV2::NodeRemoved(const gfx::GfxNodeP& node)
   }
 }
 
-void SequenceViewerV2::OnSelectionChange(const QItemSelection& sel,
-  const QItemSelection& desel) {
+void SequenceViewerV2::SelectionModelChanged(const QItemSelection& sel, const QItemSelection& desel)
+{
+  gfx::Scene::Instance().DetachObserver(this);
   model_->SelectionChanged(sel, desel);
+  gfx::Scene::Instance().AttachObserver(this);
 }
 
-SequenceViewerV2::~SequenceViewerV2(){}
+void SequenceViewerV2::SelectionChanged(const gfx::GfxObjP& o,
+                                      const mol::EntityView& view)
+{
+  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  std::cout << "SELECTION CHANGED!" << std::endl;
+  QItemSelectionModel* model = seq_table_view_->selectionModel();
+  gfx::EntityP entity=boost::dynamic_pointer_cast<gfx::Entity>(o);
+  if(entity){
+    const QModelIndexList& list = model_->GetModelIndexes(entity, view);
+    std::cout << list.size() << std::endl;
+    QSet<int> rows_visited;
+    for(int i = 0; i<list.size(); i++){
+      int row =list[i].row();
+      if(!rows_visited.contains(row)){
+        model->select(list[i],QItemSelectionModel::Rows|QItemSelectionModel::Deselect);
+        rows_visited.insert(row);
+      }
+    }
+    for(int i = 0; i<list.size(); i++){
+      model->select(list[i],QItemSelectionModel::Select);
+    }
+  }
+  connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+}
+
+
+SequenceViewerV2::~SequenceViewerV2(){
+  gfx::Scene::Instance().DetachObserver(this);
+}
 
 }}
diff --git a/modules/gui/src/sequence/sequence_viewer.hh b/modules/gui/src/sequence/sequence_viewer.hh
index bf4fc4e20..0963b5b08 100644
--- a/modules/gui/src/sequence/sequence_viewer.hh
+++ b/modules/gui/src/sequence/sequence_viewer.hh
@@ -46,6 +46,7 @@ public:
 
   virtual void NodeAdded(const gfx::GfxNodeP& node);
   virtual void NodeRemoved(const gfx::GfxNodeP& node);
+  virtual void SelectionChanged(const gfx::GfxObjP& o, const mol::EntityView& view);
 
   virtual bool Restore(const QString&){return true;};
   virtual bool Save(const QString&){return true;};
@@ -54,8 +55,8 @@ private:
   SequenceModel* model_;
   SequenceTableView* seq_table_view_;
 
-public slots:
-  void OnSelectionChange(const QItemSelection& sel, const QItemSelection& desel);
+private slots:
+  void SelectionModelChanged(const QItemSelection&, const QItemSelection&);
 };
 
 }}
diff --git a/modules/gui/src/sequence/view_object.cc b/modules/gui/src/sequence/view_object.cc
index 670fad559..90116e04a 100644
--- a/modules/gui/src/sequence/view_object.cc
+++ b/modules/gui/src/sequence/view_object.cc
@@ -75,7 +75,7 @@ ViewObject::ViewObject(gfx::EntityP& entity, QObject* parent): QObject(parent),
 
 void ViewObject::Init()
 {
-  font_ = QFont("Courier",10);
+  font_ = QFont("Courier",30);
   QFontMetrics metrics = QFontMetrics(font_);
   default_size_=QSize(metrics.boundingRect('W').width(),metrics.boundingRect('|').height());
   default_cell_size_ = QSize(metrics.boundingRect('W').width()+2,metrics.boundingRect('|').height()*2);
@@ -157,7 +157,7 @@ void ViewObject::AddChain(mol::ChainView& chain, const QString& name)
         sec_str[i] = s.ss_type;
       }
     }
-    ListEntry entry(new_row, name, sequence, sec_str);
+    ListEntry entry(new_row, name, sequence, chain, sec_str);
     rows_.append(entry);
   }
 }
@@ -182,8 +182,8 @@ void ViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>&
 
     QSetIterator<int> i(removed);
     while (i.hasNext()){
-      int row = i.next();
-      if (mol::ResidueView rv=seq.GetResidue(row-1)) {
+      int column = i.next();
+      if (mol::ResidueView rv=seq.GetResidue(column-1)) {
         view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
       }
     }
@@ -191,8 +191,8 @@ void ViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>&
     view = seq.GetAttachedView().GetHandle().CreateEmptyView();
     i = QSetIterator<int>(added);
     while (i.hasNext()){
-      int row = i.next();
-      if (mol::ResidueView rv=seq.GetResidue(row-1)) {
+      int column = i.next();
+      if (mol::ResidueView rv=seq.GetResidue(column-1)) {
         view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
       }
     }
@@ -252,6 +252,46 @@ bool ViewObject::SetData(int column, const QVariant& value, int role)
   return false;
 }
 
+void ViewObject::DoubleClicked(int row, int column)
+{
+  if(column==0){
+    QSet<int> all;
+    for(int i = 1; i <= rows_[row].seq.GetLength(); i++){
+      all.insert(i);
+    }
+    this->SetSelection(row,all,QSet<int>());
+  }
+  else if(column>0){
+
+  }
+}
+
+QMap<int, QList<int> > ViewObject::GetIndexesForView(const mol::EntityView& view)
+{
+  if(view.GetChainCount()==0){
+    return QMap<int, QList<int> >();
+  }
+  else{
+    QMap<int, QList<int> > selected_indexes;
+    for(int i=0; i< rows_.size(); i++){
+      mol::ChainView dst_chain=(rows_[i].chain);
+      seq::SequenceHandle seq = rows_[i].seq;
+      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(),
+           e2=src_chain.GetResidueList().end(); j!=e2; ++j) {
+          mol::ResidueView dst_res=dst_chain.FindResidue(j->GetHandle());
+          assert(dst_res.IsValid());
+          int p=seq.GetPos(dst_res.GetIndex()+1);
+          assert(p>=0 && p<=seq.GetLength());
+          selected_indexes[i].append(p);
+        }
+      }
+    }
+    return selected_indexes;
+  }
+}
+
 Qt::ItemFlags ViewObject::Flags(int row, int column) const
 {
   if(row<0 || row >= rows_.size())return Qt::NoItemFlags;
diff --git a/modules/gui/src/sequence/view_object.hh b/modules/gui/src/sequence/view_object.hh
index 8f39f0cd4..d1e959fe7 100644
--- a/modules/gui/src/sequence/view_object.hh
+++ b/modules/gui/src/sequence/view_object.hh
@@ -46,6 +46,7 @@ struct ListEntry {
   Row*   row;
   QString name;
   seq::SequenceHandle seq;
+  mol::ChainView chain;
   QVarLengthArray<mol::SecStructure> secstr;
   ListEntry(): row(NULL)
          {}
@@ -57,8 +58,8 @@ struct ListEntry {
       seq::SequenceHandle& sequence): row(r), name(n), seq(sequence)
          {}
   ListEntry(Row* r, const QString& n,
-      seq::SequenceHandle& sequence,
-      QVarLengthArray<mol::SecStructure>& sec): row(r), name(n), seq(sequence), secstr(sec)
+      const seq::SequenceHandle& sequence, const mol::ChainView& c,
+      const QVarLengthArray<mol::SecStructure>& sec): row(r), name(n), seq(sequence), chain(c), secstr(sec)
          {}
 };
 
@@ -95,6 +96,9 @@ public:
 
   Qt::ItemFlags Flags(int row, int column) const;
 
+  void DoubleClicked(int row, int column);
+
+  QMap<int, QList<int> > GetIndexesForView(const mol::EntityView& view);
 
 private:
   void Init();
-- 
GitLab