diff --git a/plugins/problemreporter/problemsview.h b/plugins/problemreporter/problemsview.h --- a/plugins/problemreporter/problemsview.h +++ b/plugins/problemreporter/problemsview.h @@ -30,6 +30,7 @@ class QAction; class QActionGroup; +class QLineEdit; class QMenu; class QTabWidget; @@ -104,6 +105,12 @@ QAction* m_errorSeverityAction = nullptr; QAction* m_warningSeverityAction = nullptr; QAction* m_hintSeverityAction = nullptr; + + void setFilter(const QString& filterText); + void setFilter(const QString& filterText, int tabIdx); + + QLineEdit* m_filterEdit; + int m_prevTabIdx; }; } diff --git a/plugins/problemreporter/problemsview.cpp b/plugins/problemreporter/problemsview.cpp --- a/plugins/problemreporter/problemsview.cpp +++ b/plugins/problemreporter/problemsview.cpp @@ -23,9 +23,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -201,6 +203,34 @@ currentView()->model()->setGrouping(index); }); } + + { + QTimer* filterTimer = new QTimer(this); + filterTimer->setSingleShot(true); + + connect(filterTimer, &QTimer::timeout, [this]() { + setFilter(m_filterEdit->text()); + }); + + m_filterEdit = new QLineEdit(this); + m_filterEdit->setClearButtonEnabled(true); + m_filterEdit->setPlaceholderText(i18n("Search...")); + + QSizePolicy p(m_filterEdit->sizePolicy()); + p.setHorizontalPolicy(QSizePolicy::Fixed); + m_filterEdit->setSizePolicy(p); + + connect(m_filterEdit, &QLineEdit::textChanged, [this, filterTimer](const QString&) { + filterTimer->start(500); + }); + + QWidgetAction* filterAction = new QWidgetAction(this); + filterAction->setDefaultWidget(m_filterEdit); + addAction(filterAction); + + m_prevTabIdx = -1; + setFocusProxy(m_filterEdit); + } } void ProblemsView::updateActions() @@ -229,6 +259,8 @@ } problemModel->setSeverities(IProblem::Error | IProblem::Warning | IProblem::Hint); + + setFocus(); // set focus to default widget (filterEdit) } /// TODO: Move to util? @@ -385,6 +417,10 @@ if (idx == -1) return; + setFilter(QStringLiteral(""), m_prevTabIdx); + setFilter(QStringLiteral("")); + m_prevTabIdx = idx; + updateActions(); } @@ -453,4 +489,26 @@ currentView()->model()->setScope(scope); } +void ProblemsView::setFilter(const QString& filterText) +{ + setFilter(filterText, m_tabWidget->currentIndex()); +} + +void ProblemsView::setFilter(const QString& filterText, int tabIdx) +{ + if (tabIdx < 0 || tabIdx >= m_tabWidget->count()) + return; + + ProblemTreeView* view = static_cast(m_tabWidget->widget(tabIdx)); + int rows = view->setFilter(filterText); + + updateTab(tabIdx, rows); + + if (tabIdx == m_tabWidget->currentIndex()) { + m_filterEdit->blockSignals(true); + m_filterEdit->setText(filterText); + m_filterEdit->blockSignals(false); + } +} + } diff --git a/plugins/problemreporter/problemtreeview.h b/plugins/problemreporter/problemtreeview.h --- a/plugins/problemreporter/problemtreeview.h +++ b/plugins/problemreporter/problemtreeview.h @@ -50,6 +50,8 @@ const QVector& roles = QVector()) override; void reset() override; + int setFilter(const QString& filterText); + public slots: void openDocumentForCurrentProblem(); diff --git a/plugins/problemreporter/problemtreeview.cpp b/plugins/problemreporter/problemtreeview.cpp --- a/plugins/problemreporter/problemtreeview.cpp +++ b/plugins/problemreporter/problemtreeview.cpp @@ -100,6 +100,9 @@ connect(model(), &QAbstractItemModel::rowsInserted, this, &ProblemTreeView::changed); connect(model(), &QAbstractItemModel::rowsRemoved, this, &ProblemTreeView::changed); connect(model(), &QAbstractItemModel::modelReset, this, &ProblemTreeView::changed); + + m_proxy->setFilterKeyColumn(-1); + m_proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); } ProblemTreeView::~ProblemTreeView() @@ -151,6 +154,13 @@ resizeColumns(); } +int ProblemTreeView::setFilter(const QString& filterText) +{ + m_proxy->setFilterFixedString(filterText); + + return m_proxy->rowCount(); +} + ProblemModel* ProblemTreeView::model() const { return static_cast(m_proxy->sourceModel());