From 9a1be79c0d4390e95c843b16520f38a0e2c83f9c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 12 Apr 2023 20:12:57 +0200 Subject: [PATCH] LocatorWidget: Reuse LocatorMatcher in LocatorWidget Introduce QTC_USE_MATCHER env var temporarily. When this var is set, the locator will use LocatorMatcher internally. It's very hard to migrate all the matchesFor() implementations into the LocatorMatcherTask in one patch, so this var is going to be removed when all filters are migrated. Whenever a new patch providing the filter's migration is added, it may be tested by setting this env var. Add a temporary printout with info about which implementation is selected in runtime. Change-Id: If2d6006a89f3669ea4f6f8f171e59e00917419c4 Reviewed-by: Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot --- .../coreplugin/locator/ilocatorfilter.h | 6 +- .../coreplugin/locator/locatorwidget.cpp | 77 ++++++++++++++++++- .../coreplugin/locator/locatorwidget.h | 2 + 3 files changed, 83 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h index e2866d17519..7c89b69ee35 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.h +++ b/src/plugins/coreplugin/locator/ilocatorfilter.h @@ -22,7 +22,10 @@ namespace Utils::Tasking { class TaskItem; } namespace Core { -namespace Internal { class Locator; } +namespace Internal { +class Locator; +class LocatorWidget; +} class ILocatorFilter; class LocatorStoragePrivate; @@ -279,6 +282,7 @@ private: virtual LocatorMatcherTasks matchers() { return {}; } friend class Internal::Locator; + friend class Internal::LocatorWidget; static const QList allLocatorFilters(); Utils::Id m_id; diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 97ffcd8d4ba..01ea7f5b6ab 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,8 @@ const int LocatorEntryRole = int(HighlightingItemRole::User); namespace Core { namespace Internal { +static bool isUsingLocatorMatcher() { return qtcEnvironmentVariableIsSet("QTC_USE_MATCHER"); } + bool LocatorWidget::m_shuttingDown = false; QFuture LocatorWidget::m_sharedFuture; LocatorWidget *LocatorWidget::m_sharedFutureOrigin = nullptr; @@ -917,11 +920,80 @@ void LocatorWidget::setProgressIndicatorVisible(bool visible) m_progressIndicator->show(); } +void LocatorWidget::runMatcher(const QString &text) +{ + QString searchText; + const QList filters = filtersFor(text, searchText); + + LocatorMatcherTasks tasks; + for (ILocatorFilter *filter : filters) + tasks += filter->matchers(); + + m_locatorMatcher.reset(new LocatorMatcher); + m_locatorMatcher->setTasks(tasks); + m_locatorMatcher->setInputData(searchText); + + connect(m_locatorMatcher.get(), &LocatorMatcher::done, this, [this] { + m_showProgressTimer.stop(); + setProgressIndicatorVisible(false); + m_updateRequested = false; + m_locatorMatcher.release()->deleteLater(); + if (m_rowRequestedForAccept) { + acceptEntry(m_rowRequestedForAccept.value()); + m_rowRequestedForAccept.reset(); + return; + } + if (m_needsClearResult) { + m_locatorModel->clear(); + m_needsClearResult = false; + } + }); + connect(m_locatorMatcher.get(), &LocatorMatcher::serialOutputDataReady, + this, [this](const LocatorFilterEntries &serialOutputData) { + if (m_needsClearResult) { + m_locatorModel->clear(); + m_needsClearResult = false; + } + const bool selectFirst = m_locatorModel->rowCount() == 0; + m_locatorModel->addEntries(serialOutputData); + if (selectFirst) { + emit selectRow(0); + if (m_rowRequestedForAccept) + m_rowRequestedForAccept = 0; + } + }); + + m_showProgressTimer.start(); + m_needsClearResult = true; + m_updateRequested = true; + m_locatorMatcher->start(); +} + +// TODO: Remove when switched the default into new implementation. +static void printMatcherInfo() +{ + static bool printed = false; + if (printed) + return; + if (isUsingLocatorMatcher()) + qDebug() << "QTC_USE_MATCHER env var set, using new LocatorMatcher implementation."; + else + qDebug() << "QTC_USE_MATCHER env var not set, using old matchesFor implementation."; + printed = true; +} + void LocatorWidget::updateCompletionList(const QString &text) { if (m_shuttingDown) return; + printMatcherInfo(); + + if (isUsingLocatorMatcher()) { + runMatcher(text); + return; + } + m_updateRequested = true; if (m_sharedFuture.isRunning()) { // Cancel the old future. We may not just block the UI thread to wait for the search to @@ -987,7 +1059,10 @@ void LocatorWidget::scheduleAcceptEntry(const QModelIndex &index) // accept will be called after the update finished m_rowRequestedForAccept = index.row(); // do not wait for the rest of the search to finish - m_entriesWatcher->future().cancel(); + if (isUsingLocatorMatcher()) + m_locatorMatcher.reset(); + else + m_entriesWatcher->future().cancel(); } else { acceptEntry(index.row()); } diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h index efc90c3a517..4f6c1560ce5 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.h +++ b/src/plugins/coreplugin/locator/locatorwidget.h @@ -69,6 +69,7 @@ private: void updatePreviousFocusWidget(QWidget *previous, QWidget *current); bool eventFilter(QObject *obj, QEvent *event) override; + void runMatcher(const QString &text); void updateCompletionList(const QString &text); static QList filtersFor(const QString &text, QString &searchText); void setProgressIndicatorVisible(bool visible); @@ -95,6 +96,7 @@ private: QTimer m_showProgressTimer; std::optional m_rowRequestedForAccept; QPointer m_previousFocusWidget; + std::unique_ptr m_locatorMatcher; }; class LocatorPopup : public QWidget