Avoid UI freezing when search in protocol list viewer

This commit is contained in:
DreamSourceLab 2016-06-21 21:52:22 +08:00
parent cace16dd8e
commit 4f2e5c2e10
6 changed files with 79 additions and 45 deletions

View File

@ -43,8 +43,8 @@ class DecoderModel : public QAbstractTableModel
public:
DecoderModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex & /*parent*/) const;
int columnCount(const QModelIndex & /*parent*/) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role) const;

View File

@ -297,6 +297,21 @@ uint64_t DecoderStack::list_annotation_size() const
return max_annotation_size;
}
uint64_t DecoderStack::list_annotation_size(uint16_t row_index) const
{
//lock_guard<boost::recursive_mutex> lock(_output_mutex);
//int row = 0;
for (map<const Row, RowData>::const_iterator i = _rows.begin();
i != _rows.end(); i++) {
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
if (iter != _rows_lshow.end() && (*iter).second)
if (row_index-- == 0) {
return (*i).second.get_annotation_size();
}
}
return 0;
}
bool DecoderStack::list_annotation(pv::data::decode::Annotation &ann,
uint16_t row_index, uint64_t col_index) const
{
@ -387,6 +402,7 @@ void DecoderStack::begin_decode()
if (!_options_changed)
return;
_options_changed = false;
// if (_decode_thread.joinable()) {
// _decode_thread.interrupt();
// _decode_thread.join();
@ -545,7 +561,6 @@ void DecoderStack::decode_data(
}
entry_cnt++;
}
_options_changed = false;
decode_done();
}

View File

@ -107,6 +107,8 @@ public:
bool has_annotations(const decode::Row &row) const;
uint64_t list_annotation_size() const;
uint64_t list_annotation_size(uint16_t row_index) const;
bool list_annotation(decode::Annotation &ann,
uint16_t row_index, uint64_t col_index) const;

View File

@ -40,6 +40,9 @@
#include <QScrollBar>
#include <QLineEdit>
#include <QRegExp>
#include <QFuture>
#include <QProgressDialog>
#include <QtConcurrent/QtConcurrent>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
@ -50,7 +53,9 @@ namespace dock {
ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
QScrollArea(parent),
_session(session),
_cur_search_index(-1)
_cur_search_index(-1),
_search_edited(false),
_searching(false)
{
_up_widget = new QWidget(this);
@ -199,7 +204,7 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
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()));
connect(_search_edit, SIGNAL(editingFinished()), this, SLOT(search_changed()));
}
ProtocolDock::~ProtocolDock()
@ -543,6 +548,7 @@ void ProtocolDock::export_table_view()
void ProtocolDock::search_pre()
{
search_update();
// 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) {
@ -598,6 +604,7 @@ void ProtocolDock::search_pre()
void ProtocolDock::search_nxt()
{
search_update();
// 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) {
@ -663,6 +670,46 @@ void ProtocolDock::search_done()
_matchs_label->setText(QString::number(_model_proxy.rowCount()));
}
void ProtocolDock::search_changed()
{
_search_edited = true;
_matchs_label->setText("...");
}
void ProtocolDock::search_update()
{
if (!_search_edited)
return;
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
boost::shared_ptr<pv::data::DecoderStack> decoder_stack = decoder_model->getDecoderStack();
if (!decoder_stack)
return;
if (decoder_stack->list_annotation_size(_model_proxy.filterKeyColumn()) > ProgressRows) {
QFuture<void> future;
future = QtConcurrent::run([&]{
search_done();
});
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
QProgressDialog dlg(tr("Searching..."),
tr("Cancel"),0,0,this,flags);
dlg.setWindowModality(Qt::WindowModal);
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
dlg.setCancelButton(NULL);
QFutureWatcher<void> watcher;
watcher.setFuture(future);
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
dlg.exec();
} else {
search_done();
}
_search_edited = false;
//search_done();
}
} // namespace dock
} // namespace pv

View File

@ -38,6 +38,7 @@
#include <QSortFilterProxyModel>
#include <vector>
#include <boost/thread.hpp>
#include <libsigrok4DSL/libsigrok.h>
@ -57,6 +58,9 @@ class ProtocolDock : public QScrollArea
{
Q_OBJECT
public:
static const uint64_t ProgressRows = 100000;
public:
ProtocolDock(QWidget *parent, SigSession &session);
~ProtocolDock();
@ -80,6 +84,8 @@ private slots:
void search_pre();
void search_nxt();
void search_done();
void search_changed();
void search_update();
private:
static int decoder_name_cmp(const void *a, const void *b);
@ -113,6 +119,10 @@ private:
QPushButton *_dn_set_button;
QPushButton *_dn_save_button;
mutable boost::mutex _search_mutex;
bool _search_edited;
bool _searching;
};
} // namespace dock

View File

@ -336,46 +336,6 @@ void DecodeTrace::paint_fore(QPainter &p, int left, int right)
using namespace pv::data::decode;
(void)right;
// const int row_height = _view->get_signalHeight();
// for (size_t i = 0; i < _cur_row_headings.size(); i++)
// {
// const int y = (i + 0.5) * row_height + get_y() - _totalHeight * 0.5;
// p.setPen(QPen(Qt::NoPen));
// p.setBrush(QApplication::palette().brush(QPalette::WindowText));
// if (i != 0)
// {
// const QPointF points[] = {
// QPointF(left, y - ArrowSize),
// QPointF(left + ArrowSize, y),
// QPointF(left, y + ArrowSize)
// };
// p.drawPolygon(points, countof(points));
// }
// const QRect r(left + ArrowSize * 2, y - row_height / 2,
// right - left, row_height);
// const QString h(_cur_row_headings[i]);
// const int f = Qt::AlignLeft | Qt::AlignBottom |
// Qt::TextDontClip;
// // Draw the outline
// QFont font=p.font();
// font.setPointSize(DefaultFontSize);
// p.setFont(font);
//// p.setPen(QApplication::palette().color(QPalette::Base));
//// for (int dx = -1; dx <= 1; dx++)
//// for (int dy = -1; dy <= 1; dy++)
//// if (dx != 0 && dy != 0)
//// p.drawText(r.translated(dx, dy), f, h);
// // Draw the text
// p.setPen(DARK_FORE);
// p.drawText(r, f, h);
// }
}
bool DecodeTrace::create_popup()