From 069efa948367c8ddaaf4fecef3ae2625538cd0b5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 29 Jan 2021 12:36:45 +0100 Subject: [PATCH] CommandLocator: move some part of the matching code into prepareSearch We can't call neither Command::isActive() nor QAction->isEnabled() from inside matchesFor(), as this function is called from non-gui thread and it may happen, that the gui thread modifies these data at the same time. Instead we prepare the needed data inside prepareSearch(). Change-Id: Ie9ddb8eb7df2c39e968ef117caf3ef1d04ed6a80 Reviewed-by: Eike Ziller --- .../coreplugin/locator/commandlocator.cpp | 46 +++++++++++-------- .../coreplugin/locator/commandlocator.h | 1 + 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/plugins/coreplugin/locator/commandlocator.cpp b/src/plugins/coreplugin/locator/commandlocator.cpp index c3cc9740a9a..207a96ae265 100644 --- a/src/plugins/coreplugin/locator/commandlocator.cpp +++ b/src/plugins/coreplugin/locator/commandlocator.cpp @@ -40,6 +40,7 @@ namespace Core { struct CommandLocatorPrivate { QList commands; + QList> commandsData; }; /*! @@ -70,33 +71,42 @@ void CommandLocator::appendCommand(Command *cmd) d->commands.push_back(cmd); } +void CommandLocator::prepareSearch(const QString &entry) +{ + Q_UNUSED(entry) + d->commandsData = {}; + const int count = d->commands.size(); + // Get active, enabled actions matching text, store in list. + // Reference via index in extraInfo. + for (int i = 0; i < count; ++i) { + Command *command = d->commands.at(i); + if (!command->isActive()) + continue; + QAction *action = command->action(); + if (action && action->isEnabled()) + d->commandsData.append(qMakePair(i, action->text())); + } +} + QList CommandLocator::matchesFor(QFutureInterface &future, const QString &entry) { QList goodEntries; QList betterEntries; - // Get active, enabled actions matching text, store in list. - // Reference via index in extraInfo. const Qt::CaseSensitivity entryCaseSensitivity = caseSensitivity(entry); - const int count = d->commands.size(); - for (int i = 0; i < count; i++) { + for (const auto &pair : qAsConst(d->commandsData)) { if (future.isCanceled()) break; - if (!d->commands.at(i)->isActive()) - continue; - QAction *action = d->commands.at(i)->action(); - if (action && action->isEnabled()) { - const QString text = Utils::stripAccelerator(action->text()); - const int index = text.indexOf(entry, 0, entryCaseSensitivity); - if (index >= 0) { - LocatorFilterEntry filterEntry(this, text, QVariant(i)); - filterEntry.highlightInfo = {index, int(entry.length())}; + const QString text = Utils::stripAccelerator(pair.second); + const int index = text.indexOf(entry, 0, entryCaseSensitivity); + if (index >= 0) { + LocatorFilterEntry filterEntry(this, text, QVariant(pair.first)); + filterEntry.highlightInfo = {index, int(entry.length())}; - if (index == 0) - betterEntries.append(filterEntry); - else - goodEntries.append(filterEntry); - } + if (index == 0) + betterEntries.append(filterEntry); + else + goodEntries.append(filterEntry); } } betterEntries.append(goodEntries); diff --git a/src/plugins/coreplugin/locator/commandlocator.h b/src/plugins/coreplugin/locator/commandlocator.h index 3e828952e56..0a496724a4b 100644 --- a/src/plugins/coreplugin/locator/commandlocator.h +++ b/src/plugins/coreplugin/locator/commandlocator.h @@ -45,6 +45,7 @@ public: void appendCommand(Command *cmd); + void prepareSearch(const QString &entry) override; QList matchesFor(QFutureInterface &future, const QString &entry) override; void accept(LocatorFilterEntry selection,