Skip to content
Snippets Groups Projects
Commit 59c5dce1 authored by stefan's avatar stefan
Browse files

New SequenceViewer, added searchbar (Ctrl+F)

git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@2237 5a81b35b-ba03-0410-adc8-b2c5c5119f08
parent 1e709c33
Branches
Tags
No related merge requests found
......@@ -31,6 +31,7 @@ seq_text_painter.hh
sequence_delegate.hh
sequence_model.hh
sequence_row.hh
sequence_search_bar.hh
sequence_table_view.hh
sequence_viewer.hh
tick_painter.hh
......@@ -220,6 +221,7 @@ sequence/seq_text_painter.cc
sequence/sequence_delegate.cc
sequence/sequence_model.cc
sequence/sequence_row.cc
sequence/sequence_search_bar.cc
sequence/sequence_table_view.cc
sequence/sequence_viewer.cc
sequence/tick_painter.cc
......@@ -351,6 +353,7 @@ sequence/seq_text_painter.hh
sequence/sequence_delegate.hh
sequence/sequence_model.hh
sequence/sequence_row.hh
sequence/sequence_search_bar.hh
sequence/sequence_table_view.hh
sequence/sequence_viewer.hh
sequence/tick_painter.hh
......
......@@ -179,6 +179,25 @@ QModelIndexList SequenceModel::GetModelIndexes(gfx::EntityP& entity, const mol::
return list;
}
QModelIndexList SequenceModel::GetModelIndexes(const QString& subject, const QString& sequence_name)
{
QModelIndexList list;
for (int i = 0; i<objects_.size(); i++){
ViewObject* object = objects_[i];
QMap<int, QList<int> > indexes = object->GetIndexesForSubject(subject,sequence_name);
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;
......
......@@ -50,6 +50,8 @@ public:
void RemoveGfxEntity(gfx::EntityP& entity);
QModelIndexList GetModelIndexes(gfx::EntityP& entity, const mol::EntityView& view);
QModelIndexList GetModelIndexes(const QString& subject, const QString& sequence_name=QString());
int GetGlobalRow(ViewObject* obj, int row) const;
......
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
/*
Author: Marco Biasini
*/
#include "sequence_search_bar.hh"
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPainter>
#include <QPaintEvent>
#include <QLabel>
#include <QKeyEvent>
namespace ost { namespace gui {
SeqSearchBar::SeqSearchBar(QWidget* parent):
QWidget(parent)
{
subject_=new QLineEdit(this);
search_all_=new QCheckBox("search in all sequences", this);
search_in_=new QComboBox(this);
QHBoxLayout* l= new QHBoxLayout(this);
l->addSpacing(2);
l->addWidget(subject_, 0);
l->setStretch(0,1);
l->addWidget(search_all_, 0);
QLabel* label=new QLabel("search in:", this);
l->addSpacing(10);
l->addWidget(label, 0);
l->addWidget(search_in_, 0);
//subject_->setMaximumWidth(200);
setLayout(l);
l->setSizeConstraint(QLayout::SetMaximumSize);
l->setMargin(1);
search_all_->setCheckState(Qt::Checked);
search_in_->setEnabled(false);
#if defined(__APPLE__)
subject_->setAttribute(Qt::WA_MacSmallSize, true);
search_all_->setAttribute(Qt::WA_MacSmallSize, true);
search_in_->setAttribute(Qt::WA_MacSmallSize, true);
label->setAttribute(Qt::WA_MacSmallSize, true);
#endif
connect(subject_, SIGNAL(textChanged(const QString&)), this,
SLOT(OnSubjectChanged(const QString&)));
connect(search_all_, SIGNAL(stateChanged(int)), this,
SLOT(OnSearchAllChanged(int)));
connect(search_in_, SIGNAL(currentIndexChanged(int)), this,
SLOT(OnSearchInChanged(int)));
}
void SeqSearchBar::UpdateItems(const QStringList& sequences)
{
search_in_->clear();
for(int i=0;i< sequences.size(); i++){
search_in_->addItem(sequences[i]);
}
if (sequences.empty()) {
search_all_->setCheckState(Qt::Checked);
search_in_->setEnabled(false);
}
subject_->setFocus(Qt::ActiveWindowFocusReason);
subject_->selectAll();
}
void SeqSearchBar::OnSearchAllChanged(int state)
{
if (state==Qt::Unchecked) {
search_in_->setEnabled(true);
} else {
search_in_->setEnabled(false);
}
emit Changed(subject_->text(), search_all_->checkState()==Qt::Checked,
search_in_->currentText());
}
void SeqSearchBar::OnSearchInChanged(int index)
{
emit Changed(subject_->text(), search_all_->checkState()==Qt::Checked,
search_in_->currentText());
}
void SeqSearchBar::OnSubjectChanged(const QString& str)
{
emit Changed(str, search_all_->checkState()==Qt::Checked,
search_in_->currentText());
}
void SeqSearchBar::paintEvent(QPaintEvent* paint_event)
{
QPainter p(this);
p.setBrush(QBrush(QColor(Qt::blue).lighter(300)));
p.setPen(QPen(QColor(Qt::blue).lighter(200)));
p.drawRect(rect());
paint_event->accept();
}
void SeqSearchBar::keyPressEvent(QKeyEvent* key_event)
{
if (key_event->key()==Qt::Key_Escape) {
this->hide();
key_event->accept();
}
QWidget::keyPressEvent(key_event);
}
}}
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#ifndef OST_SEQUENCE_VIEWER_SEQUENCE_SEARCH_BAR_HH
#define OST_SEQUENCE_VIEWER_SEQUENCE_SEARCH_BAR_HH
/*
Author: Marco Biasini
*/
#include <ost/gui/module_config.hh>
#include <ost/seq/alignment_handle.hh>
#include <QWidget>
#include <QComboBox>
#include <QCheckBox>
#include <QSet>
namespace ost { namespace gui {
/// \brief search bar to search in multiple sequence alignment
class DLLEXPORT_OST_GUI SeqSearchBar : public QWidget {
Q_OBJECT
public:
SeqSearchBar(QWidget* parent=NULL);
void UpdateItems(const QStringList& sequences);
signals:
void Changed(const QString&, bool, const QString&);
public slots:
void OnSubjectChanged(const QString&);
void OnSearchInChanged(int);
void OnSearchAllChanged(int);
protected:
virtual void paintEvent(QPaintEvent* paint_event);
virtual void keyPressEvent(QKeyEvent* key_event);
private:
seq::AlignmentHandle ali_;
QLineEdit* subject_;
QCheckBox* search_all_;
QComboBox* search_in_;
};
}}
#endif
......@@ -95,8 +95,7 @@ void SequenceTableView::InitStaticColumn()
static_column_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
static_column_->show();
static_column_->setStyleSheet("QTableView { border: 0px;"
"background-color: #FFFFFF;"
"selection-background-color: #EEEEEE}"
"background-color: #FFFFFF}"
"QTableView::item{ border: none;"
"padding: 0px; border-width: 0px; margin: 0px;}");
static_column_->setShowGrid(false);
......@@ -130,8 +129,7 @@ void SequenceTableView::InitStaticRow()
static_row_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
static_row_->show();
static_row_->setStyleSheet("QTableView { border: 0px;"
"background-color: #FFFFFF;"
"selection-background-color: #EEEEEE}"
"background-color: #FFFFFF}"
"QTableView::item{ border: none;"
"padding: 0px; border-width: 0px; margin: 0px;}");
static_row_->setShowGrid(false);
......@@ -169,8 +167,7 @@ void SequenceTableView::InitStaticField(){
static_field_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
static_field_->show();
static_field_->setStyleSheet("QTableView { border: 0px;"
"background-color: #FFFFFF;"
"selection-background-color: #EEEEEE}"
"background-color: #FFFFFF}"
"QTableView::item{ border: none;"
"padding: 0px; border-width: 0px; margin: 0px;}");
static_field_->setShowGrid(false);
......
......@@ -22,10 +22,11 @@
*/
#include <boost/pointer_cast.hpp>
#include <QVBoxLayout>
#include <QPushButton>
#include <QHeaderView>
#include <QAbstractItemView>
#include <QHeaderView>
#include <QPushButton>
#include <QShortcut>
#include <QVBoxLayout>
#include <ost/mol/chain_view.hh>
#include <ost/mol/entity_view.hh>
......@@ -75,6 +76,13 @@ SequenceViewerV2::SequenceViewerV2(QWidget* parent): Widget(NULL,parent)
layout->setMargin(0);
layout->setSpacing(0);
seq_search_bar_ = new SeqSearchBar(this);
seq_search_bar_->hide();
layout->addWidget(seq_search_bar_);
QShortcut* shortcut=new QShortcut(QKeySequence(tr("Ctrl+F")), this);
connect(shortcut, SIGNAL(activated()), this, SLOT(FindInSequence()));
connect(seq_search_bar_, SIGNAL(Changed(const QString&, bool, const QString&)), this, SLOT(OnSearchBarUpdate(const QString&, bool, const QString&)));
seq_table_view_ = new SequenceTableView(model_);
layout->addWidget(seq_table_view_);
this->setLayout(layout);
......@@ -106,6 +114,7 @@ void SequenceViewerV2::NodeAdded(const gfx::GfxNodeP& n)
seq_table_view_->resizeColumnsToContents();
seq_table_view_->resizeRowsToContents();
}
this->UpdateSearchBar();
}
void SequenceViewerV2::NodeRemoved(const gfx::GfxNodeP& node)
......@@ -115,6 +124,16 @@ void SequenceViewerV2::NodeRemoved(const gfx::GfxNodeP& node)
}
}
void SequenceViewerV2::UpdateSearchBar()
{
QStringList sequence_names_;
for(int i = 1; i< model_->rowCount(); i++){
QString name = model_->data(model_->index(i,0),Qt::DisplayRole).toString();
sequence_names_.append(name);
}
seq_search_bar_->UpdateItems(sequence_names_);
}
void SequenceViewerV2::SelectionModelChanged(const QItemSelection& sel, const QItemSelection& desel)
{
gfx::Scene::Instance().DetachObserver(this);
......@@ -126,21 +145,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&)));
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);
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);
}
this->SelectList(list);
}
connect(seq_table_view_->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(SelectionModelChanged(const QItemSelection&, const QItemSelection&)));
}
......@@ -172,6 +180,46 @@ void SequenceViewerV2::MouseWheelEvent(QWheelEvent* event)
event->accept();
}
void SequenceViewerV2::FindInSequence()
{
if(seq_search_bar_->isHidden()){
seq_search_bar_->show();
}
else{
seq_search_bar_->hide();
}
}
void SequenceViewerV2::OnSearchBarUpdate(const QString& subject,
bool search_in_all, const QString& name)
{
seq_table_view_->selectionModel()->clear();
if(search_in_all){
const QModelIndexList& list = model_->GetModelIndexes(subject);
this->SelectList(list);
}
else{
const QModelIndexList& list = model_->GetModelIndexes(subject,name);
this->SelectList(list);
}
}
void SequenceViewerV2::SelectList(const QModelIndexList& list)
{
QItemSelectionModel* model = seq_table_view_->selectionModel();
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);
}
}
SequenceViewerV2::~SequenceViewerV2(){
gfx::Scene::Instance().DetachObserver(this);
}
......
......@@ -32,6 +32,7 @@
#include <ost/gui/module_config.hh>
#include "sequence_search_bar.hh"
#include "sequence_model.hh"
#include "sequence_table_view.hh"
......@@ -51,7 +52,18 @@ public:
virtual bool Restore(const QString&){return true;};
virtual bool Save(const QString&){return true;};
public slots:
/// \internal
void OnSearchBarUpdate(const QString&, bool, const QString&);
private slots:
/// \brief show sequence search bar
void FindInSequence();
private:
void UpdateSearchBar();
void SelectList(const QModelIndexList& list);
SeqSearchBar* seq_search_bar_;
SequenceModel* model_;
SequenceTableView* seq_table_view_;
......
......@@ -229,6 +229,35 @@ QMap<int, QList<int> > ViewObject::GetIndexesForView(const mol::EntityView& view
}
}
QMap<int, QList<int> > ViewObject::GetIndexesForSubject(const QString& subject, const QString& sequence_name)
{
if(subject.size()==0){
return QMap<int, QList<int> >();
}
QMap<int, QList<int> > selected_indexes;
String subject_str = subject.toStdString();
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();
String seq_str=seq.GetString();
size_t pos=0;
size_t first=String::npos;
while ((pos=seq_str.find(subject_str, pos))!=String::npos) {
if (first==String::npos) {
first=pos;
}
for(int j=0; j < subject.size(); j++){
selected_indexes[i].append(pos+j+1);
}
pos+=subject.length();
}
}
}
}
return selected_indexes;
}
Qt::ItemFlags ViewObject::Flags(int row, int column) const
{
if(row<0 || row >= rows_.size())return Qt::NoItemFlags;
......
......@@ -78,6 +78,7 @@ public:
void ZoomOut();
QMap<int, QList<int> > GetIndexesForView(const mol::EntityView& view);
QMap<int, QList<int> > GetIndexesForSubject(const QString& subject, const QString& sequence_name=QString());
private:
QList<BaseRow*> rows_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment