From 6f5d752a482ed5329216b30bda3ab901ef0e8069 Mon Sep 17 00:00:00 2001
From: stefan <stefan@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Mon, 3 May 2010 10:53:16 +0000
Subject: [PATCH] New sequence viewer, double click on residue selects
 secstructure elements

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2169 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 modules/gui/src/sequence/sequence_model.cc    | 13 ++--
 modules/gui/src/sequence/sequence_model.hh    |  6 +-
 .../gui/src/sequence/sequence_table_view.cc   | 19 ++++++
 .../gui/src/sequence/sequence_table_view.hh   |  3 +
 modules/gui/src/sequence/sequence_viewer.cc   | 10 +++-
 modules/gui/src/sequence/sequence_viewer.hh   |  2 +
 modules/gui/src/sequence/view_object.cc       | 60 +++++++++++++++----
 7 files changed, 90 insertions(+), 23 deletions(-)

diff --git a/modules/gui/src/sequence/sequence_model.cc b/modules/gui/src/sequence/sequence_model.cc
index ee2aba06a..c9152e0e5 100644
--- a/modules/gui/src/sequence/sequence_model.cc
+++ b/modules/gui/src/sequence/sequence_model.cc
@@ -81,22 +81,21 @@ void SequenceModel::InsertGfxEntity(gfx::EntityP& ent){
 }
 
 void SequenceModel::RemoveGfxEntity(gfx::EntityP& entity){
-  ViewObject* obj = this->GetObject(entity);
-  if(obj){
-    int index = objects_.indexOf(obj);
+  if(ViewObject* obj = this->GetItem(entity)){
+    int index = this->GetGlobalRow(obj,0);
     this->beginRemoveRows(QModelIndex(),index,index+obj->GetRowCount()-1);
     int cols_before = this->columnCount();
-    objects_.removeAt(index);
+    objects_.removeOne(obj);
     this->endRemoveRows();
     int cols = this->columnCount();
     if(cols_before>cols){
-      this->beginRemoveColumns(QModelIndex(), cols, cols_before-1);
+      this->beginRemoveColumns(QModelIndex(), cols, cols_before);
       this->endRemoveColumns();
     }
   }
 }
 
-ViewObject* SequenceModel::GetObject(gfx::EntityP& entity){
+ViewObject* SequenceModel::GetItem(gfx::EntityP& entity){
   if(entity != NULL){
     for (int i = 0 ; i< objects_.size(); i++){
       if(entity == objects_[i]->GetGfxObject()){
@@ -160,7 +159,7 @@ int SequenceModel::GetGlobalRow(ViewObject* obj, int row) const
 QModelIndexList SequenceModel::GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view)
 {
   QModelIndexList list;
-  if(ViewObject* object = this->GetObject(entity)){
+  if(ViewObject* object = this->GetItem(entity)){
     QMap<int, QList<int> > indexes = object->GetIndexesForView(view);
     QMapIterator< int, QList<int> > i(indexes);
     while (i.hasNext()) {
diff --git a/modules/gui/src/sequence/sequence_model.hh b/modules/gui/src/sequence/sequence_model.hh
index 173c7f962..a1a6f8652 100644
--- a/modules/gui/src/sequence/sequence_model.hh
+++ b/modules/gui/src/sequence/sequence_model.hh
@@ -52,10 +52,8 @@ public:
   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;
+  const PainterList& GetPainters(const QModelIndex& index) const;
 
   // abstract item model interface
   int rowCount(const QModelIndex& parent=QModelIndex()) const;
@@ -74,6 +72,8 @@ public slots:
   void SelectionChanged(const QItemSelection& sel, const QItemSelection& desel);
 
 private:
+  ViewObject* GetItem(gfx::EntityP& entity);
+  ViewObject* GetItem(const QModelIndex& index) const;
   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 44faeaebf..c19ca30da 100644
--- a/modules/gui/src/sequence/sequence_table_view.cc
+++ b/modules/gui/src/sequence/sequence_table_view.cc
@@ -24,6 +24,7 @@
 #include <QHeaderView>
 #include <QScrollBar>
 #include <QTableWidgetItem>
+#include <QMouseEvent>
 
 #include <iostream>
 #include "sequence_table_view.hh"
@@ -183,6 +184,24 @@ QTableView* SequenceTableView::GetFirstRow(){
   return column_not_move_;
 }
 
+void SequenceTableView::mouseDoubleClickEvent(QMouseEvent *event)
+{
+  QModelIndex index = indexAt(event->pos());
+  this->last_double_click_ = index;
+  QAbstractItemView::mouseDoubleClickEvent(event);
+}
+
+
+void SequenceTableView::mouseReleaseEvent(QMouseEvent* event)
+{
+  QModelIndex index = indexAt(event->pos());
+  bool double_click = (index.isValid() && index == this->last_double_click_);
+  if (double_click) {
+    return;
+  }
+  QAbstractItemView::mouseReleaseEvent(event);
+}
+
 SequenceTableView::~SequenceTableView(){}
 
 }}
diff --git a/modules/gui/src/sequence/sequence_table_view.hh b/modules/gui/src/sequence/sequence_table_view.hh
index 9d3af2eac..5fc244b2d 100644
--- a/modules/gui/src/sequence/sequence_table_view.hh
+++ b/modules/gui/src/sequence/sequence_table_view.hh
@@ -44,6 +44,8 @@ public slots:
   QTableView* GetFirstRow();
 
 protected:
+  virtual void mouseDoubleClickEvent(QMouseEvent* event);
+  virtual void mouseReleaseEvent(QMouseEvent* event);
   virtual void resizeEvent(QResizeEvent *event);
   virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers);
   void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible);
@@ -55,6 +57,7 @@ private slots:
 private:
   QTableView* column_not_move_;
   SequenceDelegate* delegate_;
+  QModelIndex last_double_click_;
   void updateNotMoveColumn();
 };
 
diff --git a/modules/gui/src/sequence/sequence_viewer.cc b/modules/gui/src/sequence/sequence_viewer.cc
index 146040fd4..14b095761 100644
--- a/modules/gui/src/sequence/sequence_viewer.cc
+++ b/modules/gui/src/sequence/sequence_viewer.cc
@@ -61,7 +61,7 @@ SequenceViewerV2::SequenceViewerV2(QWidget* parent): Widget(NULL,parent)
   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&)));
+  connect(seq_table_view_->GetFirstRow(),SIGNAL(doubleClicked(const QModelIndex&)),this,SLOT(DoubleClicked(const QModelIndex&)));
 }
 
 void SequenceViewerV2::NodeAdded(const gfx::GfxNodeP& n)
@@ -91,12 +91,10 @@ 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();
@@ -112,6 +110,12 @@ void SequenceViewerV2::SelectionChanged(const gfx::GfxObjP& o,
   connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
 }
 
+void SequenceViewerV2::DoubleClicked(const QModelIndex& index)
+{
+  disconnect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
+  model_->DoubleClicked(index);
+  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 0963b5b08..bcedf4a97 100644
--- a/modules/gui/src/sequence/sequence_viewer.hh
+++ b/modules/gui/src/sequence/sequence_viewer.hh
@@ -57,6 +57,8 @@ private:
 
 private slots:
   void SelectionModelChanged(const QItemSelection&, const QItemSelection&);
+  void DoubleClicked(const QModelIndex& index);
+
 };
 
 }}
diff --git a/modules/gui/src/sequence/view_object.cc b/modules/gui/src/sequence/view_object.cc
index 90116e04a..2dc4de045 100644
--- a/modules/gui/src/sequence/view_object.cc
+++ b/modules/gui/src/sequence/view_object.cc
@@ -182,18 +182,22 @@ void ViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>&
 
     QSetIterator<int> i(removed);
     while (i.hasNext()){
-      int column = i.next();
-      if (mol::ResidueView rv=seq.GetResidue(column-1)) {
-        view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+      int column = i.next()-1;
+      if(column >= 0 && column < seq.GetLength()){
+        if (mol::ResidueView rv=seq.GetResidue(seq.GetResidueIndex(column))) {
+          view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+        }
       }
     }
     sel = mol::Difference(sel,view);
     view = seq.GetAttachedView().GetHandle().CreateEmptyView();
     i = QSetIterator<int>(added);
     while (i.hasNext()){
-      int column = i.next();
-      if (mol::ResidueView rv=seq.GetResidue(column-1)) {
-        view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+      int column = i.next()-1;
+      if(column >= 0 && column < seq.GetLength()){
+        if (mol::ResidueView rv=seq.GetResidue(seq.GetResidueIndex(column))) {
+          view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+        }
       }
     }
     sel = mol::Union(sel,view);
@@ -256,13 +260,49 @@ 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);
+    int seq_length = rows_[row].seq.GetLength();
+    for(int i = 0; i < seq_length; i++){
+      all.insert(i+1);
     }
     this->SetSelection(row,all,QSet<int>());
   }
   else if(column>0){
-
+    column-=1;
+    QVarLengthArray<mol::SecStructure> sec = rows_[row].secstr;
+    if(sec.size()>0 && column < sec.size()){
+      mol::SecStructure& src_str = sec[column];
+      QVarLengthArray<bool> src_type(3);
+      src_type[0] = src_str.IsHelical();
+      src_type[1] = src_str.IsExtended();
+      src_type[2] = src_str.IsCoil();
+      int i = column;
+      QSet<int> cols_to_add;
+      mol::SecStructure& col_str = sec[i];
+      while(i >= 0 && (col_str = sec[i])){
+        if(src_type[0] == col_str.IsHelical()
+            && src_type[1] == col_str.IsExtended()
+            && src_type[2] == col_str.IsCoil()){
+        cols_to_add.insert(i+1);
+        --i;
+        }
+        else{break;}
+      }
+      i = column + 1;
+      if(i < sec.size()){
+        while(i < sec.size() && (col_str = sec[i])){
+          if(src_type[0] == col_str.IsHelical()
+              && src_type[1] == col_str.IsExtended()
+              && src_type[2] == col_str.IsCoil()){
+          cols_to_add.insert(i+1);
+          ++i;
+          }
+          else{
+            break;
+          }
+        }
+      }
+      this->SetSelection(row,cols_to_add, QSet<int>());
+    }
   }
 }
 
@@ -282,7 +322,7 @@ QMap<int, QList<int> > ViewObject::GetIndexesForView(const mol::EntityView& view
            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);
+          int p=dst_res.GetIndex()+1;
           assert(p>=0 && p<=seq.GetLength());
           selected_indexes[i].append(p);
         }
-- 
GitLab