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 <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2021-01-29 12:36:45 +01:00
parent be1d33299e
commit 069efa9483
2 changed files with 29 additions and 18 deletions

View File

@@ -40,6 +40,7 @@ namespace Core {
struct CommandLocatorPrivate
{
QList<Command *> commands;
QList<QPair<int, QString>> 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<LocatorFilterEntry> CommandLocator::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry)
{
QList<LocatorFilterEntry> goodEntries;
QList<LocatorFilterEntry> 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);

View File

@@ -45,6 +45,7 @@ public:
void appendCommand(Command *cmd);
void prepareSearch(const QString &entry) override;
QList<LocatorFilterEntry> matchesFor(QFutureInterface<LocatorFilterEntry> &future,
const QString &entry) override;
void accept(LocatorFilterEntry selection,