From: Soeren Apel Date: Sun, 10 Mar 2019 19:11:48 +0000 (+0100) Subject: DecoderSelector: Implement filtering X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=b229a1b72d6f675e0fcf14aa83285e5c3ca122be;p=pulseview.git DecoderSelector: Implement filtering --- diff --git a/README b/README index 8608b3bf..588edc4c 100644 --- a/README +++ b/README @@ -47,6 +47,23 @@ is to be interpreted as Resource authors and licenses ----------------------------- +icons/application-exit.png, +icons/document-new.png, +icons/document-open.png, +icons/document-save-as.png, +icons/help-browser.png, +icons/media-playback-pause.png, +icons/media-playback-start.png, +icons/preferences-system.png, +icons/search.svg, +icons/window-new.png, +icons/zoom-fit-best.png, +icons/zoom-in.png, +icons/zoom-out.png: Tango Icon Library + http://tango.freedesktop.org/Tango_Desktop_Project + License: + Public Domain + icons/information.svg: Bobarino https://en.wikipedia.org/wiki/File:Information.svg License: diff --git a/icons/search.svg b/icons/search.svg new file mode 100644 index 00000000..1a4c1cd7 --- /dev/null +++ b/icons/search.svg @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pulseview.qrc b/pulseview.qrc index 33e36100..9acd3fac 100644 --- a/pulseview.qrc +++ b/pulseview.qrc @@ -19,6 +19,7 @@ icons/settings-views.svg icons/pulseview.png icons/pulseview.svg + icons/search.svg icons/status-green.svg icons/status-grey.svg icons/status-red.svg diff --git a/pv/subwindows/decoder_selector/subwindow.cpp b/pv/subwindows/decoder_selector/subwindow.cpp index 375e749e..719d2efa 100644 --- a/pv/subwindows/decoder_selector/subwindow.cpp +++ b/pv/subwindows/decoder_selector/subwindow.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,24 @@ namespace subwindows { namespace decoder_selector { +bool QCustomSortFilterProxyModel::filterAcceptsRow(int source_row, + const QModelIndex& source_parent) const +{ + // Search model recursively + + if (QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent)) + return true; + + const QModelIndex index = sourceModel()->index(source_row, 0, source_parent); + + for (int i = 0; i < sourceModel()->rowCount(index); i++) + if (filterAcceptsRow(i, index)) + return true; + + return false; +} + + void QCustomTreeView::currentChanged(const QModelIndex& current, const QModelIndex& previous) { @@ -53,17 +72,30 @@ SubWindow::SubWindow(Session& session, QWidget* parent) : info_label_body_(new QLabel()), info_label_footer_(new QLabel()), model_(new DecoderCollectionModel()), - sort_filter_model_(new QSortFilterProxyModel()) + sort_filter_model_(new QCustomSortFilterProxyModel()) { QVBoxLayout* root_layout = new QVBoxLayout(this); root_layout->setContentsMargins(0, 0, 0, 0); root_layout->addWidget(splitter_); + QWidget* upper_container = new QWidget(); + QVBoxLayout* upper_layout = new QVBoxLayout(upper_container); + upper_layout->setContentsMargins(0, 5, 0, 0); + QLineEdit* filter = new QLineEdit(); + upper_layout->addWidget(filter); + upper_layout->addWidget(tree_view_); + splitter_->setOrientation(Qt::Vertical); - splitter_->addWidget(tree_view_); + splitter_->addWidget(upper_container); splitter_->addWidget(info_box_); + const QIcon filter_icon(QIcon::fromTheme("search", + QIcon(":/icons/search.svg"))); + filter->setClearButtonEnabled(true); + filter->addAction(filter_icon, QLineEdit::LeadingPosition); + sort_filter_model_->setSourceModel(model_); + sort_filter_model_->setFilterCaseSensitivity(Qt::CaseInsensitive); tree_view_->setModel(sort_filter_model_); tree_view_->setRootIsDecorated(true); @@ -81,6 +113,9 @@ SubWindow::SubWindow(Session& session, QWidget* parent) : info_label_body_->setWordWrap(true); info_label_body_->setText(tr("Select a decoder to see its description here.")); + connect(filter, SIGNAL(textChanged(const QString&)), + this, SLOT(on_filter_changed(const QString&))); + connect(tree_view_, SIGNAL(currentChanged(const QModelIndex&)), this, SLOT(on_item_changed(const QModelIndex&))); connect(tree_view_, SIGNAL(activated(const QModelIndex&)), @@ -256,6 +291,11 @@ void SubWindow::on_item_activated(const QModelIndex& index) new_decoders_selected(decoders); } +void SubWindow::on_filter_changed(const QString& text) +{ + sort_filter_model_->setFilterFixedString(text); +} + } // namespace decoder_selector } // namespace subwindows } // namespace pv diff --git a/pv/subwindows/decoder_selector/subwindow.hpp b/pv/subwindows/decoder_selector/subwindow.hpp index dba6f6de..6f6456d3 100644 --- a/pv/subwindows/decoder_selector/subwindow.hpp +++ b/pv/subwindows/decoder_selector/subwindow.hpp @@ -85,6 +85,12 @@ private: }; +class QCustomSortFilterProxyModel : public QSortFilterProxyModel +{ +protected: + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; +}; + class QCustomTreeView : public QTreeView { Q_OBJECT @@ -127,6 +133,8 @@ public Q_SLOTS: void on_item_changed(const QModelIndex& index); void on_item_activated(const QModelIndex& index); + void on_filter_changed(const QString& text); + private: QSplitter* splitter_; QCustomTreeView* tree_view_; @@ -135,7 +143,7 @@ private: QLabel* info_label_body_; QLabel* info_label_footer_; DecoderCollectionModel* model_; - QSortFilterProxyModel* sort_filter_model_; + QCustomSortFilterProxyModel* sort_filter_model_; }; } // decoder_selector