From 71e4a0d1515c0efed600a079ec96e938772e46c5 Mon Sep 17 00:00:00 2001
From: stefan <stefan@5a81b35b-ba03-0410-adc8-b2c5c5119f08>
Date: Wed, 5 May 2010 13:27:05 +0000
Subject: [PATCH] New SequenceViewer, add new datastructure to model

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2177 5a81b35b-ba03-0410-adc8-b2c5c5119f08
---
 modules/gui/src/sequence/base_row.cc          |   2 +-
 modules/gui/src/sequence/painter.hh           |   5 +
 modules/gui/src/sequence/secstr_row.cc        |  22 +-
 modules/gui/src/sequence/secstr_row.hh        |   3 +-
 .../gui/src/sequence/seq_secstr_painter.cc    |  89 ++++---
 .../gui/src/sequence/seq_secstr_painter.hh    |   1 +
 modules/gui/src/sequence/sequence_model.cc    |  14 +-
 modules/gui/src/sequence/sequence_model.hh    |   1 +
 modules/gui/src/sequence/sequence_row.cc      |   2 +-
 modules/gui/src/sequence/sequence_row.hh      |   2 +-
 modules/gui/src/sequence/view_object.cc       | 230 ++++--------------
 modules/gui/src/sequence/view_object.hh       |  34 +--
 12 files changed, 119 insertions(+), 286 deletions(-)

diff --git a/modules/gui/src/sequence/base_row.cc b/modules/gui/src/sequence/base_row.cc
index dab716f65..661d8f565 100644
--- a/modules/gui/src/sequence/base_row.cc
+++ b/modules/gui/src/sequence/base_row.cc
@@ -38,7 +38,7 @@ BaseRow::BaseRow(QFont font, QObject *parent) : QObject(parent)
 
 int BaseRow::GetColumnCount() const
 {
-  return -1;
+  return 0;
 }
 
 void BaseRow::Init()
diff --git a/modules/gui/src/sequence/painter.hh b/modules/gui/src/sequence/painter.hh
index 4c84fd61e..75e601cda 100644
--- a/modules/gui/src/sequence/painter.hh
+++ b/modules/gui/src/sequence/painter.hh
@@ -27,8 +27,11 @@
 #include <QPainter>
 #include <QStyleOptionViewItem>
 #include <QModelIndex>
+#include <QVarLengthArray>
 #include <QList>
 
+#include <ost/mol/alg/sec_structure_segments.hh>
+
 namespace ost { namespace gui {
 
 class Painter : public QObject
@@ -46,4 +49,6 @@ typedef QList<Painter*> PainterList;
 
 }}
 
+Q_DECLARE_METATYPE(QVarLengthArray<ost::mol::SecStructure>)
+
 #endif
diff --git a/modules/gui/src/sequence/secstr_row.cc b/modules/gui/src/sequence/secstr_row.cc
index 680533df1..2c7e36590 100644
--- a/modules/gui/src/sequence/secstr_row.cc
+++ b/modules/gui/src/sequence/secstr_row.cc
@@ -66,13 +66,18 @@ void SecStrRow::SetChain(mol::ChainView& chain)
       }
     }
     this->chain_ = chain;
-    this->SetSequence(sequence);
+    SequenceRow::SetSequence(sequence);
   }
 }
 
+const mol::ChainView& SecStrRow::GetChain() const
+{
+  return this->chain_;
+}
+
 QVariant SecStrRow::GetData(int column, int role) const
 {
-  if(column > 0 && column < this->GetSequence().GetLength()){
+  if(column > 0 && column <= this->GetSequence().GetLength()){
     if (role==Qt::UserRole){
       QVariant variant;
       variant.setValue(secstr_);
@@ -89,16 +94,17 @@ void SecStrRow::DoubleClicked(int column)
 {
   if(column>0){
     column-=1;
-    if(this->secstr_.size()>0 && column < this->secstr_.size()){
-      mol::SecStructure& src_str = this->secstr_[column];
+    const QVarLengthArray<mol::SecStructure>& sec = this->secstr_;
+    if(sec.size()>0 && column < sec.size()){
+      const 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 = this->secstr_[i];
-      while(i >= 0 && (col_str = this->secstr_[i])){
+      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()){
@@ -108,8 +114,8 @@ void SecStrRow::DoubleClicked(int column)
         else{break;}
       }
       i = column + 1;
-      if(i < this->secstr_.size()){
-        while(i < this->secstr_.size() && (col_str = this->secstr_[i])){
+      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()){
diff --git a/modules/gui/src/sequence/secstr_row.hh b/modules/gui/src/sequence/secstr_row.hh
index 4e3286a77..761bb9ac2 100644
--- a/modules/gui/src/sequence/secstr_row.hh
+++ b/modules/gui/src/sequence/secstr_row.hh
@@ -45,6 +45,7 @@ public:
 
   void SetSequence(seq::SequenceHandle& sequence);
   void SetChain(mol::ChainView& chain);
+  const mol::ChainView& GetChain() const;
 
 private:
   mol::ChainView chain_;
@@ -55,6 +56,4 @@ typedef QList<BaseRow*> BaseRowList;
 
 }}
 
-Q_DECLARE_METATYPE(QVarLengthArray<ost::mol::SecStructure>)
-
 #endif
diff --git a/modules/gui/src/sequence/seq_secstr_painter.cc b/modules/gui/src/sequence/seq_secstr_painter.cc
index 591559870..db82666d3 100644
--- a/modules/gui/src/sequence/seq_secstr_painter.cc
+++ b/modules/gui/src/sequence/seq_secstr_painter.cc
@@ -25,7 +25,6 @@
 #include <QtGui>
 
 #include "seq_secstr_painter.hh"
-#include "view_object.hh"
 
 namespace ost { namespace gui {
 
@@ -37,59 +36,55 @@ void SeqSecStrPainter::Paint(QPainter* painter, const QStyleOptionViewItem& opti
   QVariant var = index.data(Qt::UserRole);
   painter->save();
   painter->setPen(QPen(Qt::lightGray));
-  ListEntry entry = index.data(Qt::UserRole).value<ListEntry>();
-  if(entry.secstr.size()>0){
+  const QVarLengthArray<mol::SecStructure>& sec_str = index.data(Qt::UserRole).value<QVarLengthArray<mol::SecStructure> >();
+  int column = index.column()-1;
+  if(sec_str.size()>0 && column < sec_str.size()){
     QSize size = index.data(Qt::UserRole+1).toSize();
-    QVarLengthArray<mol::SecStructure>& sec_str = entry.secstr;
-    int column = index.column()-1;
-    if(column < sec_str.size()){
-      mol::SecStructure sec_element = sec_str[column];
+    mol::SecStructure sec_element = sec_str[column];
 
-      int std_diff = (size.height()/2);
-      int diff = size.height()/1.25;
-      int center = option.rect.top()+(option.rect.height()/2);
-
-      if (sec_element.IsCoil()) {
-        int pos = center - std_diff;
-        painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-        pos = center + std_diff;
-        painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-      } else if (sec_element.IsHelical()) {
-        int pos = center - diff;
+    int std_diff = (size.height()/2);
+    int diff = size.height()/1.25;
+    int center = option.rect.top()+(option.rect.height()/2);
+    if (sec_element.IsCoil()) {
+      int pos = center - std_diff;
+      painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
+      pos = center + std_diff;
+      painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
+    } else if (sec_element.IsHelical()) {
+      int pos = center - diff;
+      painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
+      pos = center + diff;
+      painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
+      if(column - 1 > 0 && !sec_str[column-1].IsHelical()){
+        painter->drawLine(option.rect.left(),center+std_diff,option.rect.left(),center+diff);
+        painter->drawLine(option.rect.left(),center-std_diff,option.rect.left(),center-diff);
+      }
+      if(column + 1 < sec_str.size() && !sec_str[column+1].IsHelical()){
+        painter->drawLine(option.rect.right(),center+std_diff,option.rect.right(),center+diff);
+        painter->drawLine(option.rect.right(),center-std_diff,option.rect.right(),center-diff);
+      }
+    } else if (sec_element.IsExtended()) {
+      int pos = center - diff;
+      if(column - 1 > 0 && !sec_str[column-1].IsExtended()){
+        painter->drawLine(option.rect.left(),center+std_diff,option.rect.left(),center+diff);
+        painter->drawLine(option.rect.left(),center-std_diff,option.rect.left(),center-diff);
+      }
+      if(column + 1 < sec_str.size() && !sec_str[column+1].IsExtended()){
+        int max_diff = size.height();
+        painter->drawLine(option.rect.left(),center+diff,option.rect.left(),center+max_diff);
+        painter->drawLine(option.rect.left(),center-diff,option.rect.left(),center-max_diff);
+        painter->drawLine(option.rect.left(),center+max_diff,option.rect.right(),center+std_diff);
+        painter->drawLine(option.rect.left(),center-max_diff,option.rect.right(),center-std_diff);
+      }
+      else{
         painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
         pos = center + diff;
         painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-        if(column - 1 > 0 && !sec_str[column-1].IsHelical()){
-          painter->drawLine(option.rect.left(),center+std_diff,option.rect.left(),center+diff);
-          painter->drawLine(option.rect.left(),center-std_diff,option.rect.left(),center-diff);
-        }
-        if(column + 1 < sec_str.size() && !sec_str[column+1].IsHelical()){
-          painter->drawLine(option.rect.right(),center+std_diff,option.rect.right(),center+diff);
-          painter->drawLine(option.rect.right(),center-std_diff,option.rect.right(),center-diff);
-        }
-      } else if (sec_element.IsExtended()) {
-        int pos = center - diff;
-        if(column - 1 > 0 && !sec_str[column-1].IsExtended()){
-          painter->drawLine(option.rect.left(),center+std_diff,option.rect.left(),center+diff);
-          painter->drawLine(option.rect.left(),center-std_diff,option.rect.left(),center-diff);
-        }
-        if(column + 1 < sec_str.size() && !sec_str[column+1].IsExtended()){
-          int max_diff = size.height();
-          painter->drawLine(option.rect.left(),center+diff,option.rect.left(),center+max_diff);
-          painter->drawLine(option.rect.left(),center-diff,option.rect.left(),center-max_diff);
-          painter->drawLine(option.rect.left(),center+max_diff,option.rect.right(),center+std_diff);
-          painter->drawLine(option.rect.left(),center-max_diff,option.rect.right(),center-std_diff);
-        }
-        else{
-          painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-          pos = center + diff;
-          painter->drawLine(option.rect.left(),pos,option.rect.right(),pos);
-        }
-      }
-      if(!(column+1 < sec_str.size())){
-        painter->drawLine(option.rect.right(),center+std_diff,option.rect.right(),center-std_diff);
       }
     }
+    if(!(column+1 < sec_str.size())){
+      painter->drawLine(option.rect.right(),center+std_diff,option.rect.right(),center-std_diff);
+    }
   }
   painter->restore();
 }
diff --git a/modules/gui/src/sequence/seq_secstr_painter.hh b/modules/gui/src/sequence/seq_secstr_painter.hh
index 7255a5f3e..fd1f5b27e 100644
--- a/modules/gui/src/sequence/seq_secstr_painter.hh
+++ b/modules/gui/src/sequence/seq_secstr_painter.hh
@@ -24,6 +24,7 @@
  */
 
 #include <QObject>
+#include <QVarLengthArray>
 
 #include "painter.hh"
 
diff --git a/modules/gui/src/sequence/sequence_model.cc b/modules/gui/src/sequence/sequence_model.cc
index c9152e0e5..ef91c46c0 100644
--- a/modules/gui/src/sequence/sequence_model.cc
+++ b/modules/gui/src/sequence/sequence_model.cc
@@ -31,7 +31,7 @@
 namespace ost { namespace gui {
 
 SequenceModel::SequenceModel(QObject *parent)
-    : QAbstractTableModel(parent)
+    : QAbstractTableModel(parent), max_columns(0)
 {
 }
 
@@ -41,6 +41,7 @@ void SequenceModel::InsertSequence(QString& name, seq::SequenceHandle& seq){
   this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
   objects_.append(new ViewObject(seq, name, this));
   if(new_cols > cols){
+    this->max_columns = new_cols;
     this->beginInsertColumns(QModelIndex(), cols, new_cols);
     this->endInsertColumns();
   }
@@ -53,6 +54,7 @@ void SequenceModel::InsertChain(QString& name, mol::ChainView& view){
   this->beginInsertRows(QModelIndex(),this->rowCount(),this->rowCount());
   objects_.append(new ViewObject(view, name, this));
   if(new_cols > cols){
+    this->max_columns = new_cols;
     this->beginInsertColumns(QModelIndex(), cols, new_cols);
     this->endInsertColumns();
   }
@@ -74,6 +76,7 @@ void SequenceModel::InsertGfxEntity(gfx::EntityP& ent){
   objects_.append(obj);
   int new_cols = obj->GetMaxColumnCount();
   if(new_cols > cols){
+    this->max_columns = new_cols;
     this->beginInsertColumns(QModelIndex(), cols, new_cols);
     this->endInsertColumns();
   }
@@ -89,6 +92,7 @@ void SequenceModel::RemoveGfxEntity(gfx::EntityP& entity){
     this->endRemoveRows();
     int cols = this->columnCount();
     if(cols_before>cols){
+      this->max_columns = cols;
       this->beginRemoveColumns(QModelIndex(), cols, cols_before);
       this->endRemoveColumns();
     }
@@ -214,13 +218,7 @@ int SequenceModel::rowCount(const QModelIndex& parent) const
 
 int SequenceModel::columnCount(const QModelIndex& parent) const
 {
-  int cols = 0;
-  for (int i = 0; i<objects_.size(); i++){
-    int max_col = objects_[i]->GetMaxColumnCount();
-    if(max_col >= cols)
-      cols = max_col;
-  }
-  return cols;
+  return max_columns;
 }
 
 QVariant SequenceModel::data(const QModelIndex& index, int role) const
diff --git a/modules/gui/src/sequence/sequence_model.hh b/modules/gui/src/sequence/sequence_model.hh
index a1a6f8652..6adb96909 100644
--- a/modules/gui/src/sequence/sequence_model.hh
+++ b/modules/gui/src/sequence/sequence_model.hh
@@ -78,6 +78,7 @@ private:
   QPair<int, ViewObject*> GetRowWithItem(const QModelIndex& index) const;
 
   QList<ViewObject*> objects_;
+  int max_columns;
 };
 
 
diff --git a/modules/gui/src/sequence/sequence_row.cc b/modules/gui/src/sequence/sequence_row.cc
index 6be93018c..b28b31e4f 100644
--- a/modules/gui/src/sequence/sequence_row.cc
+++ b/modules/gui/src/sequence/sequence_row.cc
@@ -50,7 +50,7 @@ void SequenceRow::SetName(const QString& name)
   this->name_ = name;
 }
 
-const QString& SequenceRow::GetName()
+const QString& SequenceRow::GetName() const
 {
   return this->name_;
 }
diff --git a/modules/gui/src/sequence/sequence_row.hh b/modules/gui/src/sequence/sequence_row.hh
index 07c1c1a6e..589207796 100644
--- a/modules/gui/src/sequence/sequence_row.hh
+++ b/modules/gui/src/sequence/sequence_row.hh
@@ -48,7 +48,7 @@ public:
   virtual void DoubleClicked(int column);
 
   void SetName(const QString& name);
-  const QString& GetName();
+  const QString& GetName() const;
 
   virtual void SetSequence(seq::SequenceHandle& sequence);
   const seq::SequenceHandle& GetSequence() const;
diff --git a/modules/gui/src/sequence/view_object.cc b/modules/gui/src/sequence/view_object.cc
index dba4df1dc..a69f29a90 100644
--- a/modules/gui/src/sequence/view_object.cc
+++ b/modules/gui/src/sequence/view_object.cc
@@ -27,6 +27,9 @@
 #include <ost/mol/mol.hh>
 #include <ost/mol/view_op.hh>
 
+#include "sequence_row.hh"
+#include "secstr_row.hh"
+
 #include "painter.hh"
 #include "seq_secstr_painter.hh"
 #include "seq_selection_painter.hh"
@@ -43,23 +46,21 @@ ViewObject::ViewObject(seq::SequenceList& sequences, const QList<QString>& names
       seq::SequenceHandle seq = sequences[i];
       this->AddSequence(seq, names[i]);
     }
-    this->Init();
   }
 }
 
 ViewObject::ViewObject(seq::SequenceHandle& sequence, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
 {
   this->AddSequence(sequence, name);
-  this->Init();
 }
 
 ViewObject::ViewObject(mol::ChainView& chain, const QString& name, QObject *parent): QObject(parent), entity_(gfx::EntityP())
 {
   this->AddChain(chain, name);
-  this->Init();
 }
 
-ViewObject::ViewObject(gfx::EntityP& entity, QObject* parent): QObject(parent), entity_(entity){
+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) {
@@ -70,42 +71,24 @@ ViewObject::ViewObject(gfx::EntityP& entity, QObject* parent): QObject(parent),
     }
     this->AddChain(chain, name);
   }
-  this->Init();
-}
-
-void ViewObject::Init()
-{
-  font_ = QFont("Courier",11);
-  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);
 }
 
 void ViewObject::InsertRow(int pos, BaseRow* row)
 {
   if(pos >= 0 && pos <= rows_.size()){
-    ListEntry entry(row);
-    rows_.insert(pos,entry);
+    rows_.insert(pos,row);
   }
 }
 
 void ViewObject::RemoveRow(BaseRow* row)
 {
-  QList<int> rows_to_delete;
-  for (int i = 0; i < rows_.size(); ++i){
-    if(rows_[i].row == row){
-      rows_to_delete.append(i);
-    }
-  }
-  for (int i= 0; i < rows_to_delete.size(); ++i){
-    rows_.removeAt(rows_to_delete[i]);
-  }
+  rows_.removeAll(row);
 }
 
 BaseRow* ViewObject::GetRow(int pos)
 {
    if(pos >= 0 && pos < rows_.size()){
-     return rows_[pos].row;
+     return rows_[pos];
    }
    return NULL;
 }
@@ -117,49 +100,24 @@ int ViewObject::GetRowCount()
 
 void ViewObject::AddSequence(seq::SequenceHandle& sequence, const QString& name)
 {
-  BaseRow* new_row = new BaseRow(this);
+  SequenceRow* new_row = new SequenceRow(name, sequence, this);
   Painter* p = new SeqSelectionPainter(this);
   new_row->InsertPainter(p);
   p = new SeqTextPainter(this);
   new_row->InsertPainter(p);
-  ListEntry entry(new_row, name, sequence);
-  rows_.append(entry);
+  rows_.append(new_row);
 }
 
 void ViewObject::AddChain(mol::ChainView& chain, const QString& name)
 {
-  String seq_str;
-  seq_str.reserve(chain.GetResidueCount());
-  for (mol::ResidueViewList::const_iterator r=chain.GetResidueList().begin(),
-       e2=chain.GetResidueList().end(); r!=e2; ++r) {
-    mol::ResidueView res=*r;
-    seq_str.append(1, res.GetOneLetterCode());
-  }
-  if (!seq_str.empty()) {
-    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);
-
-    BaseRow* new_row = new BaseRow(this);
-    Painter* p = new SeqSelectionPainter(this);
-    new_row->InsertPainter(p);
-    p = new SeqSecStrPainter(this);
-    new_row->InsertPainter(p);
-    p = new SeqTextPainter(this);
-    new_row->InsertPainter(p);
-    mol::alg::SecStructureSegments sec = mol::alg::ExtractSecStructureSegments(chain);
-    QVarLengthArray<mol::SecStructure> sec_str(chain.GetResidueCount());
-    for (mol::alg::SecStructureSegments::iterator i=sec.begin(),
-         e=sec.end(); i!=e; ++i) {
-      mol::alg::SecStructureSegment s=*i;
-      for(int i = s.first; i <= s.last ;i++){
-        sec_str[i] = s.ss_type;
-      }
-    }
-    ListEntry entry(new_row, name, sequence, chain, sec_str);
-    rows_.append(entry);
-  }
+  SecStrRow* new_row = new SecStrRow(name, chain, this);
+  Painter* p = new SeqSelectionPainter(this);
+  new_row->InsertPainter(p);
+  p = new SeqSecStrPainter(this);
+  new_row->InsertPainter(p);
+  p = new SeqTextPainter(this);
+  new_row->InsertPainter(p);
+  rows_.append(new_row);
 }
 
 void ViewObject::AttachGfxObject(gfx::EntityP& ent)
@@ -174,35 +132,8 @@ gfx::EntityP& ViewObject::GetGfxObject()
 
 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()){
-      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()-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);
-    sel.AddAllInclusiveBonds();
-    entity->SetSelection(sel);
+  if(SequenceRow* sequence_row = qobject_cast<SequenceRow*>(rows_[row])){
+    sequence_row->SetSelection(added,removed);
   }
 }
 
@@ -210,99 +141,32 @@ QVariant ViewObject::GetData(int row, int column, int role)
 {
   if(row<0 || row >= rows_.size())return QVariant();
 
-  if(column<0 || column >= rows_[row].seq.GetLength()+1)return QVariant();
-
-  if(column == 0) {
-    if (role == Qt::DisplayRole){
-      return QVariant(rows_[row].name);
-    }
-  }
-  else if(column > 0) {
-    if (role==Qt::DisplayRole) {
-      return QVariant(QString(rows_[row].seq.GetOneLetterCode(column - 1)));
-    }
-    if (role==Qt::FontRole){
-      return QVariant(font_);
-    }
-    if (role==Qt::SizeHintRole){
-      return QVariant(default_cell_size_);
-    }
-    if (role==Qt::UserRole){
-      QVariant variant;
-      variant.setValue(rows_[row]);
-      return variant;
-    }
-    if (role==Qt::UserRole+1){
-      return QVariant(default_size_);
-    }
-  }
-  return QVariant();
+  return rows_[row]->GetData(column,role);
 }
 
 int ViewObject::GetMaxColumnCount() const
 {
   int columns = 0;
   for(int i = 0; i < rows_.size(); i++){
-    int col_length = rows_[i].seq.GetLength();
-    if(columns <= col_length){
-      columns = col_length+1;
+    int col_length = rows_[i]->GetColumnCount();
+    if(columns < col_length){
+      columns = col_length;
     }
   }
   return columns;
 }
 
-bool ViewObject::SetData(int column, const QVariant& value, int role)
+bool ViewObject::SetData(int row, int column, const QVariant& value, int role)
 {
-  return false;
+  if(row<0 || row >= rows_.size())return false;
+
+  return rows_[row]->SetData(column, value, role);
 }
 
 void ViewObject::DoubleClicked(int row, int column)
 {
-  if(column==0){
-    QSet<int> all;
-    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>());
-    }
+  if(row>=0 || row < rows_.size()){
+    rows_[row]->DoubleClicked(column);
   }
 }
 
@@ -314,17 +178,19 @@ QMap<int, QList<int> > ViewObject::GetIndexesForView(const mol::EntityView& view
   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=dst_res.GetIndex()+1;
-          assert(p>=0 && p<=seq.GetLength());
-          selected_indexes[i].append(p);
+      if(SecStrRow* secstr_row = qobject_cast<SecStrRow*>(rows_[i])){
+        mol::ChainView dst_chain=(secstr_row->GetChain());
+        seq::SequenceHandle 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(),
+             e2=src_chain.GetResidueList().end(); j!=e2; ++j) {
+            mol::ResidueView dst_res=dst_chain.FindResidue(j->GetHandle());
+            assert(dst_res.IsValid());
+            int p=dst_res.GetIndex()+1;
+            assert(p>=0 && p<=seq.GetLength());
+            selected_indexes[i].append(p);
+          }
         }
       }
     }
@@ -336,15 +202,7 @@ Qt::ItemFlags ViewObject::Flags(int row, int column) const
 {
   if(row<0 || row >= rows_.size())return Qt::NoItemFlags;
 
-  if(column<0 || column >= this->GetMaxColumnCount())return Qt::NoItemFlags;
-
-  if(column==0){
-    return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
-  }
-  else if(column>0){
-    return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
-  }
-  return Qt::NoItemFlags;
+  return rows_[row]->Flags(column);
 }
 
 }}
diff --git a/modules/gui/src/sequence/view_object.hh b/modules/gui/src/sequence/view_object.hh
index 640f261ba..311b4ff83 100644
--- a/modules/gui/src/sequence/view_object.hh
+++ b/modules/gui/src/sequence/view_object.hh
@@ -42,28 +42,6 @@
 
 namespace ost { namespace gui {
 
-struct ListEntry {
-  BaseRow*   row;
-  QString name;
-  seq::SequenceHandle seq;
-  mol::ChainView chain;
-  QVarLengthArray<mol::SecStructure> secstr;
-  ListEntry(): row(NULL)
-         {}
-  ListEntry(BaseRow* r): row(r)
-         {}
-  ListEntry(BaseRow* r, const QString& n): row(r), name(n)
-         {}
-  ListEntry(BaseRow* r, const QString& n,
-      seq::SequenceHandle& sequence): row(r), name(n), seq(sequence)
-         {}
-  ListEntry(BaseRow* r, const QString& n,
-      const seq::SequenceHandle& sequence, const mol::ChainView& c,
-      const QVarLengthArray<mol::SecStructure>& sec): row(r), name(n), seq(sequence), chain(c), secstr(sec)
-         {}
-};
-
-
 class ViewObject : public QObject
 {
   Q_OBJECT
@@ -91,9 +69,7 @@ public:
   void SetSelection(int row, const QSet<int>& added, const QSet<int>& removed);
 
   QVariant GetData(int row, int column, int role);
-
-  bool SetData(int column, const QVariant& value, int role);
-
+  bool SetData(int row, int column, const QVariant& value, int role);
   Qt::ItemFlags Flags(int row, int column) const;
 
   void DoubleClicked(int row, int column);
@@ -101,17 +77,11 @@ public:
   QMap<int, QList<int> > GetIndexesForView(const mol::EntityView& view);
 
 private:
-  void Init();
-  QList<ListEntry> rows_;
+  QList<BaseRow*> rows_;
   gfx::EntityP entity_;
-  QFont font_;
-  QSize default_size_;
-  QSize default_cell_size_;
 };
 
 
 }}
 
-Q_DECLARE_METATYPE(ost::gui::ListEntry)
-
 #endif
-- 
GitLab