forked from Ivasoft/DSView
Add search function for protocol list viewer @ LA mode
This commit is contained in:
@@ -611,7 +611,7 @@ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
|
||||
QComboBox:hover,QAbstractSpinBox:hover,QLineEdit:hover,QTextEdit:hover,QPlainTextEdit:hover,QAbstractView:hover,QTreeView:hover
|
||||
{
|
||||
border: 1px solid #78879b;
|
||||
border: 1px solid #606060;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
|
||||
BIN
DSView/icons/next.png
Normal file → Executable file
BIN
DSView/icons/next.png
Normal file → Executable file
Binary file not shown.
|
Before Width: | Height: | Size: 699 B After Width: | Height: | Size: 465 B |
BIN
DSView/icons/pre.png
Normal file → Executable file
BIN
DSView/icons/pre.png
Normal file → Executable file
Binary file not shown.
|
Before Width: | Height: | Size: 681 B After Width: | Height: | Size: 475 B |
@@ -653,5 +653,10 @@ void DecoderStack::set_options_changed(bool changed)
|
||||
_options_changed = changed;
|
||||
}
|
||||
|
||||
bool DecoderStack::out_of_memory() const
|
||||
{
|
||||
return _no_memory;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace pv
|
||||
|
||||
@@ -137,6 +137,8 @@ public:
|
||||
uint64_t sample_count() const;
|
||||
uint64_t sample_rate() const;
|
||||
|
||||
bool out_of_memory() const;
|
||||
|
||||
private:
|
||||
boost::optional<uint64_t> wait_for_data() const;
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
#include <QScrollBar>
|
||||
#include <QLineEdit>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -47,7 +49,8 @@ namespace dock {
|
||||
|
||||
ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
QScrollArea(parent),
|
||||
_session(session)
|
||||
_session(session),
|
||||
_cur_search_index(-1)
|
||||
{
|
||||
_up_widget = new QWidget(this);
|
||||
|
||||
@@ -93,7 +96,7 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
_up_layout->addStretch(1);
|
||||
|
||||
_up_widget->setLayout(_up_layout);
|
||||
_up_widget->setMinimumHeight(120);
|
||||
_up_widget->setMinimumHeight(150);
|
||||
|
||||
// this->setWidget(_widget);
|
||||
// _widget->setGeometry(0, 0, sizeHint().width(), 500);
|
||||
@@ -129,12 +132,53 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
_table_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
_table_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
|
||||
_pre_button = new QPushButton(_dn_widget);
|
||||
_nxt_button = new QPushButton(_dn_widget);
|
||||
_pre_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/pre.png")));
|
||||
_nxt_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/next.png")));
|
||||
connect(_pre_button, SIGNAL(clicked()),
|
||||
this, SLOT(search_pre()));
|
||||
connect(_nxt_button, SIGNAL(clicked()),
|
||||
this, SLOT(search_nxt()));
|
||||
|
||||
QPushButton *search_button = new QPushButton(this);
|
||||
search_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/search.png")));
|
||||
search_button->setFixedWidth(search_button->height());
|
||||
search_button->setDisabled(true);
|
||||
_search_edit = new QLineEdit(_dn_widget);
|
||||
_search_edit->setPlaceholderText(tr("search"));
|
||||
QHBoxLayout *search_layout = new QHBoxLayout();
|
||||
search_layout->addWidget(search_button);
|
||||
search_layout->addStretch();
|
||||
search_layout->setContentsMargins(0, 0, 0, 0);
|
||||
_search_edit->setLayout(search_layout);
|
||||
_search_edit->setTextMargins(search_button->width(), 0, 0, 0);
|
||||
QSizePolicy sp = _search_edit->sizePolicy();
|
||||
sp.setHorizontalStretch(1);
|
||||
_search_edit->setSizePolicy(sp);
|
||||
|
||||
QHBoxLayout *dn_search_layout = new QHBoxLayout();
|
||||
dn_search_layout->addWidget(_pre_button, 0, Qt::AlignLeft);
|
||||
dn_search_layout->addWidget(_search_edit, 0, Qt::AlignLeft);
|
||||
dn_search_layout->addWidget(_nxt_button, 0, Qt::AlignRight);
|
||||
|
||||
_matchs_label = new QLabel(_dn_widget);
|
||||
QHBoxLayout *dn_match_layout = new QHBoxLayout();
|
||||
dn_match_layout->addWidget(new QLabel(tr("Matching Items:")), 0, Qt::AlignLeft);
|
||||
dn_match_layout->addWidget(_matchs_label, 0, Qt::AlignLeft);
|
||||
dn_match_layout->addStretch(1);
|
||||
|
||||
QVBoxLayout *dn_layout = new QVBoxLayout();
|
||||
dn_layout->addLayout(dn_title_layout);
|
||||
dn_layout->addLayout(dn_search_layout);
|
||||
dn_layout->addLayout(dn_match_layout);
|
||||
dn_layout->addWidget(_table_view);
|
||||
|
||||
_dn_widget->setLayout(dn_layout);
|
||||
_dn_widget->setMinimumHeight(400);
|
||||
_dn_widget->setMinimumHeight(350);
|
||||
|
||||
_split_widget = new QSplitter(this);
|
||||
_split_widget->insertWidget(0, _up_widget);
|
||||
@@ -154,12 +198,22 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
connect(this, SIGNAL(protocol_updated()), this, SLOT(update_model()));
|
||||
connect(_table_view, SIGNAL(clicked(QModelIndex)), this, SLOT(item_clicked(QModelIndex)));
|
||||
connect(_table_view->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(column_resize(int, int, int)));
|
||||
//connect(_table_view->verticalScrollBar(), SIGNAL(sliderMoved()), this, SLOT(sliderMoved()));
|
||||
connect(_search_edit, SIGNAL(editingFinished()), this, SLOT(search_done()));
|
||||
}
|
||||
|
||||
ProtocolDock::~ProtocolDock()
|
||||
{
|
||||
}
|
||||
|
||||
void ProtocolDock::paintEvent(QPaintEvent *)
|
||||
{
|
||||
// QStyleOption opt;
|
||||
// opt.init(this);
|
||||
// QPainter p(this);
|
||||
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
int ProtocolDock::decoder_name_cmp(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(((const srd_decoder*)a)->name,
|
||||
@@ -220,7 +274,7 @@ void ProtocolDock::add_protocol()
|
||||
// progress connection
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
_session.get_decode_signals());
|
||||
connect(decode_sigs.back().get(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progess(int)));
|
||||
connect(decode_sigs.back().get(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progress(int)));
|
||||
|
||||
protocol_updated();
|
||||
}
|
||||
@@ -339,23 +393,29 @@ void ProtocolDock::del_all_protocol()
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::decoded_progess(int progress)
|
||||
void ProtocolDock::decoded_progress(int progress)
|
||||
{
|
||||
(void) progress;
|
||||
|
||||
int pg;
|
||||
QString err="";
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
_session.get_decode_signals());
|
||||
int index = 0;
|
||||
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||
QString progress_str = QString::number(d->get_progress()) + "%";
|
||||
if (d->get_progress() == 100)
|
||||
pg = d->get_progress();
|
||||
if (d->decoder()->out_of_memory())
|
||||
err = tr("(Out of Memory)");
|
||||
QString progress_str = QString::number(pg) + "%" + err;
|
||||
if (pg == 100)
|
||||
_progress_label_list.at(index)->setStyleSheet("color:green;");
|
||||
else
|
||||
_progress_label_list.at(index)->setStyleSheet("color:red;");
|
||||
_progress_label_list.at(index)->setText(progress_str);
|
||||
index++;
|
||||
}
|
||||
update_model();
|
||||
if (pg == 0 || pg % 10 == 1)
|
||||
update_model();
|
||||
}
|
||||
|
||||
void ProtocolDock::set_model()
|
||||
@@ -363,6 +423,8 @@ void ProtocolDock::set_model()
|
||||
pv::dialogs::ProtocolList *protocollist_dlg = new pv::dialogs::ProtocolList(this, _session);
|
||||
protocollist_dlg->exec();
|
||||
resize_table_view(_session.get_decoder_model());
|
||||
_model_proxy.setSourceModel(_session.get_decoder_model());
|
||||
search_done();
|
||||
}
|
||||
|
||||
void ProtocolDock::update_model()
|
||||
@@ -386,7 +448,8 @@ void ProtocolDock::update_model()
|
||||
if (index >= decode_sigs.size())
|
||||
decoder_model->setDecoderStack(decode_sigs.at(0)->decoder());
|
||||
}
|
||||
|
||||
_model_proxy.setSourceModel(decoder_model);
|
||||
search_done();
|
||||
resize_table_view(decoder_model);
|
||||
}
|
||||
|
||||
@@ -417,10 +480,50 @@ void ProtocolDock::item_clicked(const QModelIndex &index)
|
||||
_session.show_region(ann.start_sample(), ann.end_sample());
|
||||
}
|
||||
}
|
||||
_table_view->resizeRowToContents(index.row());
|
||||
if (index.column() != _model_proxy.filterKeyColumn()) {
|
||||
_model_proxy.setFilterKeyColumn(index.column());
|
||||
_model_proxy.setSourceModel(decoder_model);
|
||||
search_done();
|
||||
}
|
||||
QModelIndex filterIndex = _model_proxy.mapFromSource(index);
|
||||
if (filterIndex.isValid()) {
|
||||
_cur_search_index = filterIndex.row();
|
||||
} else {
|
||||
if (_model_proxy.rowCount() == 0) {
|
||||
_cur_search_index = -1;
|
||||
} else {
|
||||
uint64_t up = 0;
|
||||
uint64_t dn = _model_proxy.rowCount() - 1;
|
||||
do {
|
||||
uint64_t md = (up + dn)/2;
|
||||
QModelIndex curIndex = _model_proxy.mapToSource(_model_proxy.index(md,_model_proxy.filterKeyColumn()));
|
||||
if (index.row() == curIndex.row()) {
|
||||
_cur_search_index = md;
|
||||
break;
|
||||
} else if (md == up) {
|
||||
if (curIndex.row() < index.row() && up < dn) {
|
||||
QModelIndex nxtIndex = _model_proxy.mapToSource(_model_proxy.index(md+1,_model_proxy.filterKeyColumn()));
|
||||
if (nxtIndex.row() < index.row())
|
||||
md++;
|
||||
}
|
||||
_cur_search_index = md + ((curIndex.row() < index.row()) ? 0.5 : -0.5);
|
||||
break;
|
||||
} else if (curIndex.row() < index.row()) {
|
||||
up = md;
|
||||
} else if (curIndex.row() > index.row()) {
|
||||
dn = md;
|
||||
}
|
||||
}while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::column_resize(int index, int old_size, int new_size)
|
||||
{
|
||||
(void)index;
|
||||
(void)old_size;
|
||||
(void)new_size;
|
||||
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
|
||||
if (decoder_model->getDecoderStack()) {
|
||||
int top_row = _table_view->rowAt(0);
|
||||
@@ -438,5 +541,47 @@ void ProtocolDock::export_table_view()
|
||||
protocolexp_dlg->exec();
|
||||
}
|
||||
|
||||
void ProtocolDock::search_pre()
|
||||
{
|
||||
// now the proxy only contains rows that match the name
|
||||
// let's take the pre one and map it to the original model
|
||||
if (_model_proxy.rowCount() == 0)
|
||||
return;
|
||||
_cur_search_index -= 1;
|
||||
if (_cur_search_index <= -1 || _cur_search_index >= _model_proxy.rowCount())
|
||||
_cur_search_index = _model_proxy.rowCount() - 1;
|
||||
QModelIndex matchingIndex = _model_proxy.mapToSource(_model_proxy.index(ceil(_cur_search_index),_model_proxy.filterKeyColumn()));
|
||||
if(matchingIndex.isValid()){
|
||||
_table_view->scrollTo(matchingIndex);
|
||||
_table_view->setCurrentIndex(matchingIndex);
|
||||
_table_view->clicked(matchingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::search_nxt()
|
||||
{
|
||||
// now the proxy only contains rows that match the name
|
||||
// let's take the pre one and map it to the original model
|
||||
if (_model_proxy.rowCount() == 0)
|
||||
return;
|
||||
_cur_search_index += 1;
|
||||
if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount())
|
||||
_cur_search_index = 0;
|
||||
QModelIndex matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn()));
|
||||
if(matchingIndex.isValid()){
|
||||
_table_view->scrollTo(matchingIndex);
|
||||
_table_view->setCurrentIndex(matchingIndex);
|
||||
_table_view->clicked(matchingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::search_done()
|
||||
{
|
||||
QString str = _search_edit->text().trimmed();
|
||||
_model_proxy.setFilterFixedString(str);
|
||||
_matchs_label->setText(QString::number(_model_proxy.rowCount()));
|
||||
}
|
||||
|
||||
|
||||
} // namespace dock
|
||||
} // namespace pv
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QScrollArea>
|
||||
#include <QSplitter>
|
||||
#include <QTableView>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -60,6 +61,7 @@ class ProtocolDock : public QScrollArea
|
||||
public:
|
||||
ProtocolDock(QWidget *parent, SigSession &session);
|
||||
~ProtocolDock();
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
void del_all_protocol();
|
||||
|
||||
@@ -70,12 +72,15 @@ private slots:
|
||||
void add_protocol();
|
||||
void rst_protocol();
|
||||
void del_protocol();
|
||||
void decoded_progess(int progress);
|
||||
void decoded_progress(int progress);
|
||||
void set_model();
|
||||
void update_model();
|
||||
void export_table_view();
|
||||
void item_clicked(const QModelIndex &index);
|
||||
void column_resize(int index, int old_size, int new_size);
|
||||
void search_pre();
|
||||
void search_nxt();
|
||||
void search_done();
|
||||
|
||||
private:
|
||||
static int decoder_name_cmp(const void *a, const void *b);
|
||||
@@ -83,11 +88,17 @@ private:
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
QSortFilterProxyModel _model_proxy;
|
||||
double _cur_search_index;
|
||||
|
||||
QSplitter *_split_widget;
|
||||
QWidget *_up_widget;
|
||||
QWidget *_dn_widget;
|
||||
QTableView *_table_view;
|
||||
QPushButton *_pre_button;
|
||||
QPushButton *_nxt_button;
|
||||
QLineEdit *_search_edit;
|
||||
QLabel *_matchs_label;
|
||||
|
||||
QPushButton *_add_button;
|
||||
QPushButton *_del_all_button;
|
||||
|
||||
@@ -60,13 +60,13 @@ SearchDock::SearchDock(QWidget *parent, View &view, SigSession &session) :
|
||||
connect(&_nxt_button, SIGNAL(clicked()),
|
||||
this, SLOT(on_next()));
|
||||
|
||||
_pre_button.setIcon(QIcon::fromTheme("search",
|
||||
_pre_button.setIcon(QIcon::fromTheme("searchDock",
|
||||
QIcon(":/icons/pre.png")));
|
||||
_nxt_button.setIcon(QIcon::fromTheme("search",
|
||||
_nxt_button.setIcon(QIcon::fromTheme("searchDock",
|
||||
QIcon(":/icons/next.png")));
|
||||
|
||||
QPushButton *_search_button = new QPushButton(this);
|
||||
_search_button->setIcon(QIcon::fromTheme("search",
|
||||
_search_button->setIcon(QIcon::fromTheme("searchDock",
|
||||
QIcon(":/icons/search.png")));
|
||||
_search_button->setFixedWidth(_search_button->height());
|
||||
_search_button->setDisabled(true);
|
||||
|
||||
@@ -792,7 +792,9 @@ void DecodeTrace::on_new_decode_data()
|
||||
{
|
||||
uint64_t real_end = min(_decoder_stack->sample_count(), _decode_end+1);
|
||||
const int64_t need_sample_count = real_end - _decode_start;
|
||||
if (need_sample_count <= 0) {
|
||||
if (real_end == 0) {
|
||||
_progress = 0;
|
||||
} else if (need_sample_count <= 0) {
|
||||
_progress = 100;
|
||||
} else {
|
||||
const uint64_t samples_decoded = _decoder_stack->samples_decoded();
|
||||
|
||||
@@ -119,6 +119,8 @@ void Header::paintEvent(QPaintEvent*)
|
||||
//painter.setRenderHint(QPainter::Antialiasing);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
||||
|
||||
painter.begin(this);
|
||||
|
||||
const int w = width();
|
||||
const vector< boost::shared_ptr<Trace> > traces(
|
||||
_view.get_traces(ALL_VIEW));
|
||||
|
||||
@@ -182,6 +182,7 @@ void Ruler::paintEvent(QPaintEvent*)
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
|
||||
|
||||
p.begin(this);
|
||||
//QPainter p(this);
|
||||
//p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ void Viewport::paintEvent(QPaintEvent *event)
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
|
||||
|
||||
p.begin(this);
|
||||
const vector< boost::shared_ptr<Trace> > traces(_view.get_traces(_type));
|
||||
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user