From 9d317f04f557e7437bf8ed95030a6409e43953c7 Mon Sep 17 00:00:00 2001
From: stefan <stefan@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Mon, 3 May 2010 10:53:11 +0000
Subject: [PATCH] Added selection update to gfx::Entity

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2164 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 modules/gui/src/sequence/sequence_delegate.cc |   5 +-
 modules/gui/src/sequence/sequence_model.cc    |  93 +++++++++++----
 modules/gui/src/sequence/sequence_model.hh    |  15 ++-
 modules/gui/src/sequence/sequence_viewer.cc   |  23 ++--
 modules/gui/src/sequence/sequence_viewer.hh   |   3 +
 modules/gui/src/sequence/view_object.cc       | 107 +++++++++++++-----
 modules/gui/src/sequence/view_object.hh       |  30 +++--
 7 files changed, 200 insertions(+), 76 deletions(-)

diff --git a/modules/gui/src/sequence/sequence_delegate.cc b/modules/gui/src/sequence/sequence_delegate.cc
index 827aef65f..6bb36cac4 100644
--- a/modules/gui/src/sequence/sequence_delegate.cc
+++ b/modules/gui/src/sequence/sequence_delegate.cc
@@ -36,7 +36,10 @@ void SequenceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti
 {
   const PainterList& painters = seq_model_->GetPainters(index);
   for(int i=0; i < painters.size(); i++){
-    painters[i]->Paint(painter, option, index);
+    painters[i]->parent();
+    if(painters[i]){
+      painters[i]->Paint(painter, option, index);
+    }
   }
 }
 
diff --git a/modules/gui/src/sequence/sequence_model.cc b/modules/gui/src/sequence/sequence_model.cc
index f52ddfd60..322ee4e45 100644
--- a/modules/gui/src/sequence/sequence_model.cc
+++ b/modules/gui/src/sequence/sequence_model.cc
@@ -21,6 +21,8 @@
   Author: Stefan Scheuber
  */
 
+#include <QMap>
+#include <QMapIterator>
 
 #include <QtGui>
 
@@ -57,14 +59,29 @@ void SequenceModel::InsertChain(QString& name, mol::ChainView& view){
   this->endInsertRows();
 }
 
-void SequenceModel::InsertSequences(QString& name, seq::SequenceList& list){
+void SequenceModel::InsertSequences(const QList<QString>& names, seq::SequenceList& list){
   this->beginInsertRows(this->index(this->rowCount(),0),this->rowCount(),this->rowCount()+list.GetCount());
-  objects_.append(new ViewObject(list, name, this));
+  objects_.append(new ViewObject(list, names, this));
   this->endInsertRows();
 }
 
-void SequenceModel::RemoveSequence(QString& name){
-  ViewObject* obj = this->GetObject(name);
+void SequenceModel::InsertGfxEntity(gfx::EntityP& ent){
+  mol::EntityView view=ent->GetView();
+  int size = view.GetChainList().size();
+  int cols = this->columnCount();
+  this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount()+size);
+  ViewObject* obj = new ViewObject(ent, this);
+  objects_.append(obj);
+  int new_cols = obj->GetMaxColumnCount();
+  if(new_cols > cols){
+    this->beginInsertColumns(QModelIndex(), cols, new_cols);
+    this->endInsertColumns();
+  }
+  this->endInsertRows();
+}
+
+void SequenceModel::RemoveSequence(gfx::EntityP& entity){
+  ViewObject* obj = this->GetObject(entity);
   if(obj){
     int index = objects_.indexOf(obj);
     this->beginRemoveRows(QModelIndex(),index,index);
@@ -73,35 +90,74 @@ void SequenceModel::RemoveSequence(QString& name){
   }
 }
 
-ViewObject* SequenceModel::GetObject(QString& name){
-  for (int i = 0 ; i< objects_.size(); i++){
-    if(name == objects_[i]->GetName()){
-      return objects_[i];
+ViewObject* SequenceModel::GetObject(gfx::EntityP& entity){
+  if(entity != NULL){
+    for (int i = 0 ; i< objects_.size(); i++){
+      if(entity == objects_[i]->GetGfxObject()){
+        return objects_[i];
+      }
     }
   }
   return NULL;
 }
 
 const PainterList& SequenceModel::GetPainters(const QModelIndex& index) const{
-  QPair<int, ViewObject*> pair = this->GetItem(index);
-  return pair.second->GetRow(pair.first)->GetPainters();
+  QPair<int, ViewObject*> pair = this->GetRowWithItem(index);
+  if(pair.second){
+    pair.second->GetRow(pair.first);
+    return pair.second->GetRow(pair.first)->GetPainters();
+  }
+  else{
+    assert(false);
+  }
 }
 
-QPair<int, ViewObject*> SequenceModel::GetItem(const QModelIndex& index) const{
+QPair<int, ViewObject*> SequenceModel::GetRowWithItem(int row) const{
   if(!objects_.isEmpty()){
-    int ind_row = index.row();
     int rows = 0;
-    int i = 0;
-    while (i < objects_.size() && rows < ind_row){
+    int i = -1;
+    int last_row = 0;
+    while (rows <= row && i < objects_.size()){
       i++;
-      rows += objects_[i]->GetRowCount();
+      last_row =objects_[i]->GetRowCount();
+      rows += last_row;
     }
-    int sub_index = ind_row - rows;
+    int sub_index = row - (rows-last_row);
     return QPair<int, ViewObject*>(sub_index, objects_[i]);
   }
   return QPair<int, ViewObject*>(-1, NULL);
 }
 
+QPair<int, ViewObject*> SequenceModel::GetRowWithItem(const QModelIndex& index) const{
+  return this->GetRowWithItem(index.row());
+}
+
+ViewObject* SequenceModel::GetItem(const QModelIndex& index) const
+{
+  return this->GetRowWithItem(index).second;
+}
+
+void SequenceModel::SelectionChanged(const QItemSelection& sel, const QItemSelection& desel)
+{
+  QMap<int,QPair<QSet<int>,QSet<int> > > sel_map;
+  const QModelIndexList& sel_indexes = sel.indexes();
+  for(int i =0; i< sel_indexes.size(); i++){
+     sel_map[sel_indexes[i].row()].first.insert(sel_indexes[i].column());
+  }
+
+  const QModelIndexList& desel_indexes = desel.indexes();
+  for(int i =0; i< desel_indexes.size(); i++){
+     sel_map[desel_indexes[i].row()].second.insert(desel_indexes[i].column());
+  }
+
+  QMapIterator< int,QPair<QSet<int>,QSet<int> > > i(sel_map);
+  while (i.hasNext()) {
+    i.next();
+    QPair<int, ViewObject*> item = this->GetRowWithItem(i.key());
+    item.second->SetSelection(item.first,i.value().first, i.value().second);
+  }
+}
+
 int SequenceModel::rowCount(const QModelIndex& parent) const
 {
   int rows = 0;
@@ -124,7 +180,7 @@ int SequenceModel::columnCount(const QModelIndex& parent) const
 
 QVariant SequenceModel::data(const QModelIndex& index, int role) const
 {
-  QPair<int, ViewObject*> item = this->GetItem(index);
+  QPair<int, ViewObject*> item = this->GetRowWithItem(index);
   if(!item.second) return QVariant();
   QVariant data = item.second->GetData(item.first,index.column(),role);
   return data;
@@ -141,11 +197,10 @@ QVariant SequenceModel::headerData(int section, Qt::Orientation orientation,
 
 Qt::ItemFlags SequenceModel::flags(const QModelIndex& index) const
 {
-  QPair<int, ViewObject*> item = GetItem(index);
+  QPair<int, ViewObject*> item = GetRowWithItem(index);
   if(item.second){
     return item.second->Flags(item.first, index.column());
   }
-
   return QAbstractItemModel::flags(index);
 }
 
diff --git a/modules/gui/src/sequence/sequence_model.hh b/modules/gui/src/sequence/sequence_model.hh
index 2b7bc481b..ad94c5930 100644
--- a/modules/gui/src/sequence/sequence_model.hh
+++ b/modules/gui/src/sequence/sequence_model.hh
@@ -24,6 +24,7 @@
  */
 
 #include <QAbstractTableModel>
+#include <QItemSelection>
 
 #include <ost/mol/chain_view.hh>
 
@@ -41,16 +42,19 @@ class SequenceModel : public QAbstractTableModel
 public:
   SequenceModel(QObject *parent = 0);
 
+  void InsertGfxEntity(gfx::EntityP& ent);
   void InsertChain(QString& name, mol::ChainView& view);
   void InsertSequence(QString& name, seq::SequenceHandle& seq);
-  void InsertSequences(QString& name, seq::SequenceList& list);
+  void InsertSequences(const QList<QString>& names, seq::SequenceList& list);
 
-  void RemoveSequence(QString& name);
+  void RemoveSequence(gfx::EntityP& entity);
 
-  ViewObject* GetObject(QString& name);
+  ViewObject* GetObject(gfx::EntityP& entity);
   const PainterList& GetPainters(const QModelIndex& index) const;
 
-  QPair<int, ViewObject*> GetItem(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;
@@ -65,6 +69,9 @@ public:
   virtual Qt::ItemFlags flags(const QModelIndex& index=QModelIndex()) const;
 
 private:
+  QPair<int, ViewObject*> GetRowWithItem(int row) const;
+  QPair<int, ViewObject*> GetRowWithItem(const QModelIndex& index) const;
+
   QList<ViewObject*> objects_;
 };
 
diff --git a/modules/gui/src/sequence/sequence_viewer.cc b/modules/gui/src/sequence/sequence_viewer.cc
index 25fbcfee1..73ab0efa6 100644
--- a/modules/gui/src/sequence/sequence_viewer.cc
+++ b/modules/gui/src/sequence/sequence_viewer.cc
@@ -57,22 +57,18 @@ 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&)));
 }
 
 void SequenceViewerV2::NodeAdded(const gfx::GfxNodeP& n)
 {
   if (gfx::EntityP o=boost::dynamic_pointer_cast<gfx::Entity>(n)) {
-    // extract all chains
-    mol::EntityView v=o->GetView();
-    for (mol::ChainViewList::const_iterator c=v.GetChainList().begin(),
-         e1=v.GetChainList().end(); c!=e1; ++c) {
-      mol::ChainView chain=*c;
-      QString name = QString(o->GetName().c_str());
-      if (chain.GetName()!="" && chain.GetName()!=" ") {
-        name= name + " ("+chain.GetName().c_str()+")";
-      }
-      model_->InsertChain(name,chain);
-    }
+    model_->InsertGfxEntity(o);
     seq_table_view_->resizeColumnsToContents();
     seq_table_view_->resizeRowsToContents();
   }
@@ -85,6 +81,11 @@ void SequenceViewerV2::NodeRemoved(const gfx::GfxNodeP& node)
   }
 }
 
+void SequenceViewerV2::OnSelectionChange(const QItemSelection& sel,
+  const QItemSelection& desel) {
+  model_->SelectionChanged(sel, desel);
+}
+
 SequenceViewerV2::~SequenceViewerV2(){}
 
 }}
diff --git a/modules/gui/src/sequence/sequence_viewer.hh b/modules/gui/src/sequence/sequence_viewer.hh
index 494e477e9..bf4fc4e20 100644
--- a/modules/gui/src/sequence/sequence_viewer.hh
+++ b/modules/gui/src/sequence/sequence_viewer.hh
@@ -53,6 +53,9 @@ public:
 private:
   SequenceModel* model_;
   SequenceTableView* seq_table_view_;
+
+public slots:
+  void OnSelectionChange(const QItemSelection& sel, const QItemSelection& desel);
 };
 
 }}
diff --git a/modules/gui/src/sequence/view_object.cc b/modules/gui/src/sequence/view_object.cc
index ce504fd8f..1db41336f 100644
--- a/modules/gui/src/sequence/view_object.cc
+++ b/modules/gui/src/sequence/view_object.cc
@@ -25,6 +25,7 @@
 #include <QtGui>
 
 #include <ost/mol/mol.hh>
+#include <ost/mol/view_op.hh>
 
 #include "painter.hh"
 #include "seq_secstr_painter.hh"
@@ -35,24 +36,40 @@
 
 namespace ost { namespace gui {
 
-ViewObject::ViewObject(seq::SequenceList& sequences, const QString& name, QObject *parent): QObject(parent), name_(name)
+ViewObject::ViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject *parent): QObject(parent)
 {
-  for(int i=0; i<sequences.GetCount(); i++){
-    seq::SequenceHandle seq = sequences[i];
-    this->AddSequence(seq);
+  if(names.size() == sequences.GetCount()){
+    for(int i=0; i<sequences.GetCount(); i++){
+      seq::SequenceHandle seq = sequences[i];
+      this->AddSequence(seq, names[i]);
+    }
+    this->Init();
   }
-  this->Init();
 }
 
-ViewObject::ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject *parent): QObject(parent), name_(name)
+ViewObject::ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
 {
-  this->AddSequence(sequence);
+  this->AddSequence(sequence, name);
   this->Init();
 }
 
-ViewObject::ViewObject(mol::ChainView& chain, const QString& name, QObject *parent): QObject(parent), name_(name)
+ViewObject::ViewObject(mol::ChainView& chain, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
 {
-  this->AddChain(chain);
+  this->AddChain(chain, name);
+  this->Init();
+}
+
+ViewObject::ViewObject(gfx::EntityP& entity, QObject* parent): QObject(parent), entity_(entity){
+  mol::EntityView view =entity->GetView();
+  for (mol::ChainViewList::const_iterator c=view.GetChainList().begin(),
+       e1=view.GetChainList().end(); c!=e1; ++c) {
+    mol::ChainView chain=*c;
+    QString name = QString(entity->GetName().c_str());
+    if (chain.GetName()!="" && chain.GetName()!=" ") {
+      name= name + " ("+chain.GetName().c_str()+")";
+    }
+    this->AddChain(chain, name);
+  }
   this->Init();
 }
 
@@ -61,7 +78,7 @@ void ViewObject::Init()
   font_ = QFont("Courier",10);
   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);
+  default_cell_size_ = QSize(metrics.boundingRect('W').width()+2,metrics.boundingRect('|').height()*2);
 }
 
 void ViewObject::InsertRow(int pos, Row* row)
@@ -98,18 +115,18 @@ int ViewObject::GetRowCount()
   return rows_.size();
 }
 
-void ViewObject::AddSequence(seq::SequenceHandle& sequence)
+void ViewObject::AddSequence(seq::SequenceHandle& sequence, const QString& name)
 {
   Row* new_row = new Row(this);
   Painter* p = new SeqSelectionPainter(this);
   new_row->InsertPainter(p);
   p = new SeqTextPainter(this);
   new_row->InsertPainter(p);
-  QPair<Row*, seq::SequenceHandle> pair(new_row,sequence);
-  //rows_.append(pair);
+  ListEntry entry(new_row, name, sequence);
+  rows_.append(entry);
 }
 
-void ViewObject::AddChain(mol::ChainView& chain)
+void ViewObject::AddChain(mol::ChainView& chain, const QString& name)
 {
   String seq_str;
   seq_str.reserve(chain.GetResidueCount());
@@ -119,7 +136,7 @@ void ViewObject::AddChain(mol::ChainView& chain)
     seq_str.append(1, res.GetOneLetterCode());
   }
   if (!seq_str.empty()) {
-    seq::SequenceHandle sequence=seq::CreateSequence(this->GetName().toStdString(), seq_str);
+    seq::SequenceHandle sequence=seq::CreateSequence(name.toStdString(), seq_str);
     mol::EntityView v_one_chain=chain.GetEntity().GetHandle().CreateEmptyView();
     v_one_chain.AddChain(chain, mol::ViewAddFlag::INCLUDE_ALL);
     sequence.AttachView(v_one_chain);
@@ -131,7 +148,6 @@ void ViewObject::AddChain(mol::ChainView& chain)
     new_row->InsertPainter(p);
     p = new SeqTextPainter(this);
     new_row->InsertPainter(p);
-    QPair<Row*, seq::SequenceHandle> pair(new_row,sequence);
     mol::alg::SecStructureSegments sec = mol::alg::ExtractSecStructureSegments(chain);
     QVarLengthArray<mol::SecStructure> sec_str(chain.GetResidueCount());
     for (mol::alg::SecStructureSegments::iterator i=sec.begin(),
@@ -141,20 +157,61 @@ void ViewObject::AddChain(mol::ChainView& chain)
         sec_str[i] = s.ss_type;
       }
     }
-    ListEntry entry(new_row, sequence, sec_str);
+    ListEntry entry(new_row, name, sequence, sec_str);
     rows_.append(entry);
   }
 }
 
+void ViewObject::AttachGfxObject(gfx::EntityP& ent)
+{
+  entity_ = ent;
+}
+
+gfx::EntityP& ViewObject::GetGfxObject()
+{
+  return entity_;
+}
+
+void ViewObject::SetSelection(int row, const QSet<int>& added, const QSet<int>& removed)
+{
+  if(gfx::EntityP entity = this->GetGfxObject()){
+    ListEntry& entry = rows_[row];
+    mol::EntityView sel = entity->GetSelection();
+    seq::SequenceHandle& seq = entry.seq;
+    mol::EntityView view = seq.GetAttachedView().GetHandle().CreateEmptyView();
+
+    QSetIterator<int> i(removed);
+    while (i.hasNext()){
+      std::cout << "REMOVED!" << std::endl;
+      int row = i.next();
+      if (mol::ResidueView rv=seq.GetResidue(row-1)) {
+        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 row = i.next();
+      if (mol::ResidueView rv=seq.GetResidue(row-1)) {
+        view.AddResidue(rv, mol::ViewAddFlag::INCLUDE_ATOMS);
+      }
+    }
+    sel = mol::Union(sel,view);
+    entity->SetSelection(sel);
+  }
+}
+
 QVariant ViewObject::GetData(int row, int column, int role)
 {
   if(row<0 || row >= rows_.size())return QVariant();
 
-  if(column<0 || column >= this->GetMaxColumnCount())return QVariant();
+  if(column<0 || column >= rows_[row].seq.GetLength())return QVariant();
 
-  if(column == 0 && row == 0) {
+  if(column == 0) {
     if (role == Qt::DisplayRole){
-      return QVariant(this->GetName());
+      return QVariant(rows_[row].name);
     }
   }
   else if(column > 0) {
@@ -211,14 +268,4 @@ Qt::ItemFlags ViewObject::Flags(int row, int column) const
   return Qt::NoItemFlags;
 }
 
-const QString& ViewObject::GetName() const
-{
- return name_;
-}
-
-void ViewObject::SetName(const QString& name)
-{
-  name_ = name;
-}
-
 }}
diff --git a/modules/gui/src/sequence/view_object.hh b/modules/gui/src/sequence/view_object.hh
index 795d996cd..8f39f0cd4 100644
--- a/modules/gui/src/sequence/view_object.hh
+++ b/modules/gui/src/sequence/view_object.hh
@@ -33,6 +33,8 @@
 #include <ost/mol/alg/sec_structure_segments.hh>
 #include <ost/mol/entity_handle.hh>
 
+#include <ost/gfx/entity.hh>
+
 #include <ost/seq/sequence_list.hh>
 
 #include "row.hh"
@@ -42,18 +44,21 @@ namespace ost { namespace gui {
 
 struct ListEntry {
   Row*   row;
+  QString name;
   seq::SequenceHandle seq;
   QVarLengthArray<mol::SecStructure> secstr;
   ListEntry(): row(NULL)
          {}
   ListEntry(Row* r): row(r)
          {}
-  ListEntry(Row* r,
-      seq::SequenceHandle& sequence): row(r), seq(sequence)
+  ListEntry(Row* r, const QString& n): row(r), name(n)
+         {}
+  ListEntry(Row* r, const QString& n,
+      seq::SequenceHandle& sequence): row(r), name(n), seq(sequence)
          {}
-  ListEntry(Row* r,
+  ListEntry(Row* r, const QString& n,
       seq::SequenceHandle& sequence,
-      QVarLengthArray<mol::SecStructure>& sec): row(r), seq(sequence), secstr(sec)
+      QVarLengthArray<mol::SecStructure>& sec): row(r), name(n), seq(sequence), secstr(sec)
          {}
 };
 
@@ -64,22 +69,25 @@ class ViewObject : public QObject
 
 
 public:
-  ViewObject(seq::SequenceList& sequences, const QString& name, QObject* parent = 0);
+  ViewObject(seq::SequenceList& sequences, const QList<QString>& names, QObject* parent = 0);
   ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject* parent = 0);
   ViewObject(mol::ChainView& chain, const QString& name, QObject* parent = 0);
+  ViewObject(gfx::EntityP& entity, QObject* parent = 0);
 
   void InsertRow(int pos, Row* row);
   void RemoveRow(Row* row);
 
-  const QString& GetName() const;
-  void SetName(const QString& name);
-
   Row* GetRow(int pos);
   int GetRowCount();
   int GetMaxColumnCount() const;
 
-  void AddSequence(seq::SequenceHandle& sequence);
-  void AddChain(mol::ChainView& chain);
+  void AddSequence(seq::SequenceHandle& sequence, const QString& name=QString());
+  void AddChain(mol::ChainView& chain, const QString& name=QString());
+
+  void AttachGfxObject(gfx::EntityP& ent);
+  gfx::EntityP& GetGfxObject();
+
+  void SetSelection(int row, const QSet<int>& added, const QSet<int>& removed);
 
   QVariant GetData(int row, int column, int role);
 
@@ -90,8 +98,8 @@ public:
 
 private:
   void Init();
-  QString name_;
   QList<ListEntry> rows_;
+  gfx::EntityP entity_;
   QFont font_;
   QSize default_size_;
   QSize default_cell_size_;
-- 
GitLab