diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index b860bc1f..b2226cd8 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -59,6 +59,7 @@ LogicSnapshot::LogicSnapshot() : _is_loop = false; _loop_offset = 0; _able_free = true; + _is_search_stop = false; } LogicSnapshot::~LogicSnapshot() @@ -1258,6 +1259,7 @@ bool LogicSnapshot::pattern_search(int64_t start, int64_t end, int64_t& index, { std::lock_guard lock(_mutex); + _is_search_stop = false; start += _loop_offset; end += _loop_offset; index += _loop_offset; @@ -1324,12 +1326,16 @@ bool LogicSnapshot::pattern_search_self(int64_t start, int64_t end, int64_t &ind index = end; } - while (index != to) + while (index != to && !_is_search_stop) { macthed = 0; for (int i = 0; i < count; i++) { + if (_is_search_stop){ + break; + } + val = (char)get_sample_self(index, chanIndexs[i]); if (flagList[i] == '0') diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index e64f63d1..acd36dd0 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -150,6 +150,10 @@ public: return _loop_offset; } + inline void cancel_search(){ + _is_search_stop = true; + } + int get_block_index_with_sample(uint64_t sample_index, uint64_t *out_offset); private: @@ -257,6 +261,7 @@ private: std::vector _free_block_list; struct BlockIndex _cur_ref_block_indexs[CHANNEL_MAX_COUNT]; int _lst_free_block_index; + bool _is_search_stop; friend class LogicSnapshotTest::Pow2; friend class LogicSnapshotTest::Basic; diff --git a/DSView/pv/dock/searchdock.cpp b/DSView/pv/dock/searchdock.cpp index 85471196..17e52268 100644 --- a/DSView/pv/dock/searchdock.cpp +++ b/DSView/pv/dock/searchdock.cpp @@ -38,11 +38,40 @@ #include #include #include +#include #include "../config/appconfig.h" #include "../ui/langresource.h" #include "../ui/msgbox.h" #include "../appcontrol.h" #include "../ui/fn.h" +#include "../log.h" + + +class EdgeSearchProgressDialog : public QProgressDialog +{ +public: + EdgeSearchProgressDialog(QWidget *parent, QString &title, QString &cancelText) + :QProgressDialog(title, cancelText, 0, 0, parent, Qt::CustomizeWindowHint) + { + + } + + ~EdgeSearchProgressDialog(){ + + } + +protected: + void keyPressEvent(QKeyEvent *event) override + { + if (event->key() == Qt::Key_Escape) { + canceled(); + close(); + } + else { + QWidget::keyPressEvent(event); + } + } +}; namespace pv { namespace dock { @@ -55,6 +84,9 @@ SearchDock::SearchDock(QWidget *parent, View &view, SigSession *session) : _session(session), _view(view) { + _is_busy = false; + _is_cancel = false; + _search_button = new QPushButton(this); _search_button->setFixedWidth(_search_button->height()); _search_button->setDisabled(true); @@ -109,14 +141,16 @@ void SearchDock::reStyle() void SearchDock::paintEvent(QPaintEvent *) { -// QStyleOption opt; -// opt.init(this); -// QPainter p(this); -// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } void SearchDock::on_previous() { + if (_is_busy){ + dsv_info("The searching task is busy,please wait."); + return; + } + + _is_cancel = false; bool ret; int64_t last_pos; bool last_hit; @@ -140,28 +174,35 @@ void SearchDock::on_previous() } else { QFuture future; + future = QtConcurrent::run([&]{ last_pos -= last_hit; + _is_busy = true; ret = logic_snapshot->pattern_search(0, end, last_pos, _pattern, false); + _is_busy = false; }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_PREVIOUS), "Search Previous..."), - L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"),0,0,this,flags); + QString title = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_PREVIOUS), "Search Previous..."); + QString cancelText = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"); + EdgeSearchProgressDialog dlg(this, title, cancelText); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - dlg.setCancelButton(NULL); QFutureWatcher watcher; - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + connect(&watcher, SIGNAL(finished()), &dlg, SLOT(cancel())); + connect(&dlg, SIGNAL(canceled()), SLOT(on_progress_cancel())); watcher.setFuture(future); dlg.exec(); if (!ret) { QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_PATTERN_NOT_FOUND), "Pattern not found!")); - MsgBox::Show(strMsg); - return; - } else { + if (!_is_cancel){ + MsgBox::Show(strMsg); + } + } + else { _view.set_search_pos(last_pos, true); } } @@ -169,6 +210,13 @@ void SearchDock::on_previous() void SearchDock::on_next() { + if (_is_busy){ + dsv_info("The searching task is busy,please wait."); + return; + } + + _is_cancel = false; + bool ret; int64_t last_pos; const auto snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC); @@ -187,34 +235,54 @@ void SearchDock::on_next() QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_SEARCH_AT_END), "Search cursor at the end position!")); MsgBox::Show(strMsg); return; - } else { + } + else { QFuture future; + future = QtConcurrent::run([&]{ + _is_busy = true; ret = logic_snapshot->pattern_search(0, end, last_pos, _pattern, true); + _is_busy = false; }); + Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_NEXT), "Search Next..."), - L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"),0,0,this,flags); + QString title = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_SEARCH_NEXT), "Search Next..."); + QString cancelText = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CANCEL), "Cancel"); + EdgeSearchProgressDialog dlg(this, title, cancelText); dlg.setWindowModality(Qt::WindowModal); dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - dlg.setCancelButton(NULL); QFutureWatcher watcher; - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); + connect(&watcher, SIGNAL(finished()), &dlg, SLOT(cancel())); + connect(&dlg, SIGNAL(canceled()), SLOT(on_progress_cancel())); watcher.setFuture(future); dlg.exec(); if (!ret) { QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_PATTERN_NOT_FOUND), "Pattern not found!")); - MsgBox::Show(strMsg); - return; - } else { + if (!_is_cancel){ + MsgBox::Show(strMsg); + } + } + else { _view.set_search_pos(last_pos, true); } } } +void SearchDock::on_progress_cancel() +{ + const auto snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC); + const auto logic_snapshot = dynamic_cast(snapshot); + + _is_cancel = true; + + if (logic_snapshot != NULL){ + logic_snapshot->cancel_search(); + } +} + void SearchDock::on_set() { dialogs::Search dlg(this, _session, _pattern); diff --git a/DSView/pv/dock/searchdock.h b/DSView/pv/dock/searchdock.h index 08e1fb40..c635c366 100644 --- a/DSView/pv/dock/searchdock.h +++ b/DSView/pv/dock/searchdock.h @@ -81,6 +81,7 @@ public slots: void on_previous(); void on_next(); void on_set(); + void on_progress_cancel(); private: SigSession *_session; @@ -91,6 +92,8 @@ private: QPushButton _nxt_button; widgets::FakeLineEdit* _search_value; QPushButton *_search_button; + bool _is_busy; + bool _is_cancel; }; } // namespace dock