Abort expensive cancelled computations.

This commit is contained in:
Roberto Raggi
2010-09-07 11:41:48 +02:00
parent 5ea1efb55f
commit f7b555b785
22 changed files with 50 additions and 24 deletions

View File

@@ -58,7 +58,7 @@ CppCurrentDocumentFilter::CppCurrentDocumentFilter(CppModelManager *manager, Cor
this, SLOT(onEditorAboutToClose(Core::IEditor*))); this, SLOT(onEditorAboutToClose(Core::IEditor*)));
} }
QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString & origEntry) QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString & origEntry)
{ {
QString entry = trimWildcards(origEntry); QString entry = trimWildcards(origEntry);
QList<Locator::FilterEntry> goodEntries; QList<Locator::FilterEntry> goodEntries;
@@ -82,6 +82,9 @@ QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString &
foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc) foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc)
{ {
if (future.isCanceled())
break;
if ((hasWildcard && regexp.exactMatch(info.symbolName)) if ((hasWildcard && regexp.exactMatch(info.symbolName))
|| (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) || (!hasWildcard && matcher.indexIn(info.symbolName) != -1))
{ {

View File

@@ -53,7 +53,7 @@ public:
QString displayName() const { return tr("Methods in current Document"); } QString displayName() const { return tr("Methods in current Document"); }
QString id() const { return QLatin1String("Methods in current Document"); } QString id() const { return QLatin1String("Methods in current Document"); }
Priority priority() const { return Medium; } Priority priority() const { return Medium; }
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);

View File

@@ -76,7 +76,7 @@ static bool compareLexigraphically(const Locator::FilterEntry &a,
return a.displayName < b.displayName; return a.displayName < b.displayName;
} }
QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntry) QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
{ {
QString entry = trimWildcards(origEntry); QString entry = trimWildcards(origEntry);
QList<Locator::FilterEntry> goodEntries; QList<Locator::FilterEntry> goodEntries;
@@ -90,6 +90,9 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntr
QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList); QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList);
while (it.hasNext()) { while (it.hasNext()) {
if (future.isCanceled())
break;
it.next(); it.next();
const QList<ModelItemInfo> items = it.value(); const QList<ModelItemInfo> items = it.value();

View File

@@ -48,7 +48,7 @@ public:
QString displayName() const { return tr("Classes and Methods"); } QString displayName() const { return tr("Classes and Methods"); }
QString id() const { return QLatin1String("Classes and Methods"); } QString id() const { return QLatin1String("Classes and Methods"); }
Priority priority() const { return Medium; } Priority priority() const { return Medium; }
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);

View File

@@ -70,7 +70,7 @@ ILocatorFilter::Priority HelpIndexFilter::priority() const
return Medium; return Medium;
} }
QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry) QList<FilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
QStringList keywords; QStringList keywords;
if (entry.length() < 2) if (entry.length() < 2)
@@ -79,8 +79,11 @@ QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
keywords = Core::HelpManager::instance()->findKeywords(entry); keywords = Core::HelpManager::instance()->findKeywords(entry);
QList<FilterEntry> entries; QList<FilterEntry> entries;
foreach (const QString &keyword, keywords) foreach (const QString &keyword, keywords) {
if (future.isCanceled())
break;
entries.append(FilterEntry(this, keyword, QVariant(), m_icon)); entries.append(FilterEntry(this, keyword, QVariant(), m_icon));
}
return entries; return entries;
} }

View File

@@ -49,7 +49,7 @@ public:
QString displayName() const; QString displayName() const;
QString id() const; QString id() const;
Priority priority() const; Priority priority() const;
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);

View File

@@ -100,10 +100,13 @@ Locator::ILocatorFilter::Priority RemoteHelpFilter::priority() const
return Medium; return Medium;
} }
QList<Locator::FilterEntry> RemoteHelpFilter::matchesFor(const QString &pattern) QList<Locator::FilterEntry> RemoteHelpFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &pattern)
{ {
QList<Locator::FilterEntry> entries; QList<Locator::FilterEntry> entries;
foreach (const QString &url, m_remoteUrls) { foreach (const QString &url, m_remoteUrls) {
if (future.isCanceled())
break;
entries.append(Locator::FilterEntry(this, url.arg(pattern), QVariant(), entries.append(Locator::FilterEntry(this, url.arg(pattern), QVariant(),
m_icon)); m_icon));
} }

View File

@@ -50,7 +50,7 @@ public:
QString displayName() const; QString displayName() const;
QString id() const; QString id() const;
Priority priority() const; Priority priority() const;
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);
QByteArray saveState() const; QByteArray saveState() const;

View File

@@ -42,7 +42,7 @@ BaseFileFilter::BaseFileFilter()
{ {
} }
QList<FilterEntry> BaseFileFilter::matchesFor(const QString &origEntry) QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
{ {
updateFiles(); updateFiles();
QList<FilterEntry> matches; QList<FilterEntry> matches;
@@ -70,6 +70,9 @@ QList<FilterEntry> BaseFileFilter::matchesFor(const QString &origEntry)
QStringListIterator paths(searchListPaths); QStringListIterator paths(searchListPaths);
QStringListIterator names(searchListNames); QStringListIterator names(searchListNames);
while (paths.hasNext() && names.hasNext()) { while (paths.hasNext() && names.hasNext()) {
if (future.isCanceled())
break;
QString path = paths.next(); QString path = paths.next();
QString name = names.next(); QString name = names.next();
if ((hasWildcard && regexp.exactMatch(name)) if ((hasWildcard && regexp.exactMatch(name))

View File

@@ -43,7 +43,7 @@ class LOCATOR_EXPORT BaseFileFilter : public Locator::ILocatorFilter
public: public:
BaseFileFilter(); BaseFileFilter();
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
protected: protected:

View File

@@ -84,7 +84,7 @@ ILocatorFilter::Priority CommandLocator::priority() const
return Medium; return Medium;
} }
QList<Locator::FilterEntry> CommandLocator::matchesFor(const QString &entry) QList<Locator::FilterEntry> CommandLocator::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
QList<FilterEntry> filters; QList<FilterEntry> filters;
// Get active, enabled actions matching text, store in list. // Get active, enabled actions matching text, store in list.
@@ -92,6 +92,8 @@ QList<Locator::FilterEntry> CommandLocator::matchesFor(const QString &entry)
const QChar ampersand = QLatin1Char('&'); const QChar ampersand = QLatin1Char('&');
const int count = d->commands.size(); const int count = d->commands.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (future.isCanceled())
break;
if (d->commands.at(i)->isActive()) { if (d->commands.at(i)->isActive()) {
if (QAction *action = d->commands.at(i)->action()) if (QAction *action = d->commands.at(i)->action())
if (action->isEnabled()) { if (action->isEnabled()) {

View File

@@ -64,7 +64,7 @@ public:
virtual QString displayName() const; virtual QString displayName() const;
virtual QString id() const; virtual QString id() const;
virtual Priority priority() const; virtual Priority priority() const;
virtual QList<FilterEntry> matchesFor(const QString &entry); virtual QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
virtual void accept(FilterEntry selection) const; virtual void accept(FilterEntry selection) const;
virtual void refresh(QFutureInterface<void> &future); virtual void refresh(QFutureInterface<void> &future);

View File

@@ -45,7 +45,7 @@ FileSystemFilter::FileSystemFilter(EditorManager *editorManager, LocatorWidget *
setIncludedByDefault(false); setIncludedByDefault(false);
} }
QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry) QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
QList<FilterEntry> value; QList<FilterEntry> value;
QFileInfo entryInfo(entry); QFileInfo entryInfo(entry);
@@ -75,6 +75,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
QStringList files = dirInfo.entryList(fileFilter, QStringList files = dirInfo.entryList(fileFilter,
QDir::Name|QDir::IgnoreCase|QDir::LocaleAware); QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
foreach (const QString &dir, dirs) { foreach (const QString &dir, dirs) {
if (future.isCanceled())
break;
if (dir != QLatin1String(".") && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) { if (dir != QLatin1String(".") && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) {
FilterEntry filterEntry(this, dir, dirInfo.filePath(dir)); FilterEntry filterEntry(this, dir, dirInfo.filePath(dir));
filterEntry.resolveFileIcon = true; filterEntry.resolveFileIcon = true;
@@ -82,6 +84,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
} }
} }
foreach (const QString &file, files) { foreach (const QString &file, files) {
if (future.isCanceled())
break;
if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) { if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) {
const QString fullPath = dirInfo.filePath(file); const QString fullPath = dirInfo.filePath(file);
FilterEntry filterEntry(this, file, fullPath); FilterEntry filterEntry(this, file, fullPath);

View File

@@ -56,7 +56,7 @@ public:
QString displayName() const { return tr("Files in file system"); } QString displayName() const { return tr("Files in file system"); }
QString id() const { return "Files in file system"; } QString id() const { return "Files in file system"; }
Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; } Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; }
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
QByteArray saveState() const; QByteArray saveState() const;
bool restoreState(const QByteArray &state); bool restoreState(const QByteArray &state);

View File

@@ -100,7 +100,7 @@ public:
QString shortcutString() const; QString shortcutString() const;
/* List of matches for the given user entry. */ /* List of matches for the given user entry. */
virtual QList<FilterEntry> matchesFor(const QString &entry) = 0; virtual QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry) = 0;
/* User has selected the given entry that belongs to this filter. */ /* User has selected the given entry that belongs to this filter. */
virtual void accept(FilterEntry selection) const = 0; virtual void accept(FilterEntry selection) const = 0;

View File

@@ -63,11 +63,13 @@ ILocatorFilter::Priority LocatorFiltersFilter::priority() const
return High; return High;
} }
QList<FilterEntry> LocatorFiltersFilter::matchesFor(const QString &entry) QList<FilterEntry> LocatorFiltersFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
QList<FilterEntry> entries; QList<FilterEntry> entries;
if (entry.isEmpty()) { if (entry.isEmpty()) {
foreach (ILocatorFilter *filter, m_plugin->filters()) { foreach (ILocatorFilter *filter, m_plugin->filters()) {
if (future.isCanceled())
break;
if (!filter->shortcutString().isEmpty() && !filter->isHidden()) { if (!filter->shortcutString().isEmpty() && !filter->isHidden()) {
FilterEntry filterEntry(this, FilterEntry filterEntry(this,
filter->shortcutString(), filter->shortcutString(),

View File

@@ -56,7 +56,7 @@ public:
QString displayName() const; QString displayName() const;
QString id() const; QString id() const;
Priority priority() const; Priority priority() const;
QList<FilterEntry> matchesFor(const QString &entry); QList<FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(FilterEntry selection) const; void accept(FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);
bool isConfigurable() const; bool isConfigurable() const;

View File

@@ -428,7 +428,7 @@ QList<ILocatorFilter*> LocatorWidget::filtersFor(const QString &text, QString &s
return activeFilters; return activeFilters;
} }
static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocatorFilter *> filters, QString searchText) static void filter_helper(QFutureInterface<Locator::FilterEntry> &entries, QList<ILocatorFilter *> filters, QString searchText)
{ {
QSet<FilterEntry> alreadyAdded; QSet<FilterEntry> alreadyAdded;
const bool checkDuplicates = (filters.size() > 1); const bool checkDuplicates = (filters.size() > 1);
@@ -436,7 +436,7 @@ static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocator
if (entries.isCanceled()) if (entries.isCanceled())
break; break;
foreach (const FilterEntry &entry, filter->matchesFor(searchText)) { foreach (const FilterEntry &entry, filter->matchesFor(entries, searchText)) {
if (checkDuplicates && alreadyAdded.contains(entry)) if (checkDuplicates && alreadyAdded.contains(entry))
continue; continue;
entries.reportResult(entry); entries.reportResult(entry);
@@ -453,6 +453,7 @@ void LocatorWidget::updateCompletionList(const QString &text)
// cancel the old future // cancel the old future
m_entriesWatcher->future().cancel(); m_entriesWatcher->future().cancel();
m_entriesWatcher->future().waitForFinished();
QFuture<FilterEntry> future = QtConcurrent::run(filter_helper, filters, searchText); QFuture<FilterEntry> future = QtConcurrent::run(filter_helper, filters, searchText);
m_entriesWatcher->setFuture(future); m_entriesWatcher->setFuture(future);

View File

@@ -49,7 +49,7 @@ OpenDocumentsFilter::OpenDocumentsFilter(EditorManager *editorManager) :
setIncludedByDefault(true); setIncludedByDefault(true);
} }
QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry) QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
QList<FilterEntry> value; QList<FilterEntry> value;
const QChar asterisk = QLatin1Char('*'); const QChar asterisk = QLatin1Char('*');
@@ -60,6 +60,8 @@ QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry)
if (!regexp.isValid()) if (!regexp.isValid())
return value; return value;
foreach (const OpenEditorsModel::Entry &editorEntry, m_editors) { foreach (const OpenEditorsModel::Entry &editorEntry, m_editors) {
if (future.isCanceled())
break;
QString fileName = editorEntry.fileName(); QString fileName = editorEntry.fileName();
QString displayName = editorEntry.displayName(); QString displayName = editorEntry.displayName();
if (regexp.exactMatch(displayName)) { if (regexp.exactMatch(displayName)) {

View File

@@ -55,7 +55,7 @@ public:
QString displayName() const { return tr("Open documents"); } QString displayName() const { return tr("Open documents"); }
QString id() const { return "Open documents"; } QString id() const { return "Open documents"; }
Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; } Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::Medium; }
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &future); void refresh(QFutureInterface<void> &future);

View File

@@ -48,7 +48,7 @@ LineNumberFilter::LineNumberFilter(QObject *parent)
setIncludedByDefault(true); setIncludedByDefault(true);
} }
QList<FilterEntry> LineNumberFilter::matchesFor(const QString &entry) QList<FilterEntry> LineNumberFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
{ {
bool ok; bool ok;
QList<FilterEntry> value; QList<FilterEntry> value;

View File

@@ -52,7 +52,7 @@ public:
QString displayName() const { return tr("Line in current document"); } QString displayName() const { return tr("Line in current document"); }
QString id() const { return "Line in current document"; } QString id() const { return "Line in current document"; }
Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::High; } Locator::ILocatorFilter::Priority priority() const { return Locator::ILocatorFilter::High; }
QList<Locator::FilterEntry> matchesFor(const QString &entry); QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
void accept(Locator::FilterEntry selection) const; void accept(Locator::FilterEntry selection) const;
void refresh(QFutureInterface<void> &) {} void refresh(QFutureInterface<void> &) {}