From f7b555b7854d41f019fe405373ca3ca79ce03dc4 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Tue, 7 Sep 2010 11:41:48 +0200
Subject: [PATCH] Abort expensive cancelled computations.

---
 src/plugins/cpptools/cppcurrentdocumentfilter.cpp | 5 ++++-
 src/plugins/cpptools/cppcurrentdocumentfilter.h   | 2 +-
 src/plugins/cpptools/cpplocatorfilter.cpp         | 5 ++++-
 src/plugins/cpptools/cpplocatorfilter.h           | 2 +-
 src/plugins/help/helpindexfilter.cpp              | 7 +++++--
 src/plugins/help/helpindexfilter.h                | 2 +-
 src/plugins/help/remotehelpfilter.cpp             | 5 ++++-
 src/plugins/help/remotehelpfilter.h               | 2 +-
 src/plugins/locator/basefilefilter.cpp            | 5 ++++-
 src/plugins/locator/basefilefilter.h              | 2 +-
 src/plugins/locator/commandlocator.cpp            | 4 +++-
 src/plugins/locator/commandlocator.h              | 2 +-
 src/plugins/locator/filesystemfilter.cpp          | 6 +++++-
 src/plugins/locator/filesystemfilter.h            | 2 +-
 src/plugins/locator/ilocatorfilter.h              | 2 +-
 src/plugins/locator/locatorfiltersfilter.cpp      | 4 +++-
 src/plugins/locator/locatorfiltersfilter.h        | 2 +-
 src/plugins/locator/locatorwidget.cpp             | 5 +++--
 src/plugins/locator/opendocumentsfilter.cpp       | 4 +++-
 src/plugins/locator/opendocumentsfilter.h         | 2 +-
 src/plugins/texteditor/linenumberfilter.cpp       | 2 +-
 src/plugins/texteditor/linenumberfilter.h         | 2 +-
 22 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
index 60107acf4f3..838e0c1191d 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.cpp
@@ -58,7 +58,7 @@ CppCurrentDocumentFilter::CppCurrentDocumentFilter(CppModelManager *manager, Cor
             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);
     QList<Locator::FilterEntry> goodEntries;
@@ -82,6 +82,9 @@ QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(const QString &
 
     foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc)
     {
+        if (future.isCanceled())
+            break;
+
         if ((hasWildcard && regexp.exactMatch(info.symbolName))
             || (!hasWildcard && matcher.indexIn(info.symbolName) != -1))
         {
diff --git a/src/plugins/cpptools/cppcurrentdocumentfilter.h b/src/plugins/cpptools/cppcurrentdocumentfilter.h
index 0231124eb3a..6f4bbbc5cd4 100644
--- a/src/plugins/cpptools/cppcurrentdocumentfilter.h
+++ b/src/plugins/cpptools/cppcurrentdocumentfilter.h
@@ -53,7 +53,7 @@ public:
     QString displayName() const { return tr("Methods in current Document"); }
     QString id() const { return QLatin1String("Methods in current Document"); }
     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 refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp
index 2b10afdce60..62162025d25 100644
--- a/src/plugins/cpptools/cpplocatorfilter.cpp
+++ b/src/plugins/cpptools/cpplocatorfilter.cpp
@@ -76,7 +76,7 @@ static bool compareLexigraphically(const Locator::FilterEntry &a,
     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);
     QList<Locator::FilterEntry> goodEntries;
@@ -90,6 +90,9 @@ QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(const QString &origEntr
 
     QHashIterator<QString, QList<ModelItemInfo> > it(m_searchList);
     while (it.hasNext()) {
+        if (future.isCanceled())
+            break;
+
         it.next();
 
         const QList<ModelItemInfo> items = it.value();
diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h
index 7b13adc6c7f..c58a9100c1b 100644
--- a/src/plugins/cpptools/cpplocatorfilter.h
+++ b/src/plugins/cpptools/cpplocatorfilter.h
@@ -48,7 +48,7 @@ public:
     QString displayName() const { return tr("Classes and Methods"); }
     QString id() const { return QLatin1String("Classes and Methods"); }
     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 refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp
index 10c4fc06f59..5bb20698ed1 100644
--- a/src/plugins/help/helpindexfilter.cpp
+++ b/src/plugins/help/helpindexfilter.cpp
@@ -70,7 +70,7 @@ ILocatorFilter::Priority HelpIndexFilter::priority() const
     return Medium;
 }
 
-QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
+QList<FilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QStringList keywords;
     if (entry.length() < 2)
@@ -79,8 +79,11 @@ QList<FilterEntry> HelpIndexFilter::matchesFor(const QString &entry)
         keywords = Core::HelpManager::instance()->findKeywords(entry);
 
     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));
+    }
 
     return entries;
 }
diff --git a/src/plugins/help/helpindexfilter.h b/src/plugins/help/helpindexfilter.h
index dde609b3f54..0203890b90b 100644
--- a/src/plugins/help/helpindexfilter.h
+++ b/src/plugins/help/helpindexfilter.h
@@ -49,7 +49,7 @@ public:
     QString displayName() const;
     QString id() 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 refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/help/remotehelpfilter.cpp b/src/plugins/help/remotehelpfilter.cpp
index 8fcbeae3eda..05a7f462186 100644
--- a/src/plugins/help/remotehelpfilter.cpp
+++ b/src/plugins/help/remotehelpfilter.cpp
@@ -100,10 +100,13 @@ Locator::ILocatorFilter::Priority RemoteHelpFilter::priority() const
     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;
     foreach (const QString &url, m_remoteUrls) {
+        if (future.isCanceled())
+            break;
+
         entries.append(Locator::FilterEntry(this, url.arg(pattern), QVariant(),
             m_icon));
     }
diff --git a/src/plugins/help/remotehelpfilter.h b/src/plugins/help/remotehelpfilter.h
index e2d32fbb329..5c858de33cf 100644
--- a/src/plugins/help/remotehelpfilter.h
+++ b/src/plugins/help/remotehelpfilter.h
@@ -50,7 +50,7 @@ public:
     QString displayName() const;
     QString id() 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 refresh(QFutureInterface<void> &future);
     QByteArray saveState() const;
diff --git a/src/plugins/locator/basefilefilter.cpp b/src/plugins/locator/basefilefilter.cpp
index 4f35ec7d827..5ba5437cbc5 100644
--- a/src/plugins/locator/basefilefilter.cpp
+++ b/src/plugins/locator/basefilefilter.cpp
@@ -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();
     QList<FilterEntry> matches;
@@ -70,6 +70,9 @@ QList<FilterEntry> BaseFileFilter::matchesFor(const QString &origEntry)
     QStringListIterator paths(searchListPaths);
     QStringListIterator names(searchListNames);
     while (paths.hasNext() && names.hasNext()) {
+        if (future.isCanceled())
+            break;
+
         QString path = paths.next();
         QString name = names.next();
         if ((hasWildcard && regexp.exactMatch(name))
diff --git a/src/plugins/locator/basefilefilter.h b/src/plugins/locator/basefilefilter.h
index ee942694463..707a61dc261 100644
--- a/src/plugins/locator/basefilefilter.h
+++ b/src/plugins/locator/basefilefilter.h
@@ -43,7 +43,7 @@ class LOCATOR_EXPORT BaseFileFilter : public Locator::ILocatorFilter
 
 public:
     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;
 
 protected:
diff --git a/src/plugins/locator/commandlocator.cpp b/src/plugins/locator/commandlocator.cpp
index fa3684f60d6..cb1aa287c3b 100644
--- a/src/plugins/locator/commandlocator.cpp
+++ b/src/plugins/locator/commandlocator.cpp
@@ -84,7 +84,7 @@ ILocatorFilter::Priority CommandLocator::priority() const
     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;
     // 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 int count = d->commands.size();
     for (int i = 0; i  < count; i++) {
+        if (future.isCanceled())
+            break;
         if (d->commands.at(i)->isActive()) {
             if (QAction *action = d->commands.at(i)->action())
                 if (action->isEnabled()) {
diff --git a/src/plugins/locator/commandlocator.h b/src/plugins/locator/commandlocator.h
index bc18667191e..186bf9e916d 100644
--- a/src/plugins/locator/commandlocator.h
+++ b/src/plugins/locator/commandlocator.h
@@ -64,7 +64,7 @@ public:
     virtual QString displayName() const;
     virtual QString id() 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 refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/locator/filesystemfilter.cpp b/src/plugins/locator/filesystemfilter.cpp
index 6ef07bdbaec..fe24241dbe3 100644
--- a/src/plugins/locator/filesystemfilter.cpp
+++ b/src/plugins/locator/filesystemfilter.cpp
@@ -45,7 +45,7 @@ FileSystemFilter::FileSystemFilter(EditorManager *editorManager, LocatorWidget *
     setIncludedByDefault(false);
 }
 
-QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
+QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> value;
     QFileInfo entryInfo(entry);
@@ -75,6 +75,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
     QStringList files = dirInfo.entryList(fileFilter,
                                       QDir::Name|QDir::IgnoreCase|QDir::LocaleAware);
     foreach (const QString &dir, dirs) {
+        if (future.isCanceled())
+            break;
         if (dir != QLatin1String(".") && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) {
             FilterEntry filterEntry(this, dir, dirInfo.filePath(dir));
             filterEntry.resolveFileIcon = true;
@@ -82,6 +84,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(const QString &entry)
         }
     }
     foreach (const QString &file, files) {
+        if (future.isCanceled())
+            break;
         if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) {
             const QString fullPath = dirInfo.filePath(file);
             FilterEntry filterEntry(this, file, fullPath);
diff --git a/src/plugins/locator/filesystemfilter.h b/src/plugins/locator/filesystemfilter.h
index 07ab3414a52..21b740c6d69 100644
--- a/src/plugins/locator/filesystemfilter.h
+++ b/src/plugins/locator/filesystemfilter.h
@@ -56,7 +56,7 @@ public:
     QString displayName() const { return tr("Files in file system"); }
     QString id() const { return "Files in file system"; }
     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;
     QByteArray saveState() const;
     bool restoreState(const QByteArray &state);
diff --git a/src/plugins/locator/ilocatorfilter.h b/src/plugins/locator/ilocatorfilter.h
index f3207c20873..7f519d7fe1c 100644
--- a/src/plugins/locator/ilocatorfilter.h
+++ b/src/plugins/locator/ilocatorfilter.h
@@ -100,7 +100,7 @@ public:
     QString shortcutString() const;
 
     /* 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. */
     virtual void accept(FilterEntry selection) const = 0;
diff --git a/src/plugins/locator/locatorfiltersfilter.cpp b/src/plugins/locator/locatorfiltersfilter.cpp
index f02e63d4f37..a0fe20c4643 100644
--- a/src/plugins/locator/locatorfiltersfilter.cpp
+++ b/src/plugins/locator/locatorfiltersfilter.cpp
@@ -63,11 +63,13 @@ ILocatorFilter::Priority LocatorFiltersFilter::priority() const
     return High;
 }
 
-QList<FilterEntry> LocatorFiltersFilter::matchesFor(const QString &entry)
+QList<FilterEntry> LocatorFiltersFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> entries;
     if (entry.isEmpty()) {
         foreach (ILocatorFilter *filter, m_plugin->filters()) {
+            if (future.isCanceled())
+                break;
             if (!filter->shortcutString().isEmpty() && !filter->isHidden()) {
                 FilterEntry filterEntry(this,
                                   filter->shortcutString(),
diff --git a/src/plugins/locator/locatorfiltersfilter.h b/src/plugins/locator/locatorfiltersfilter.h
index ea7d5d75aa1..2b7d22e12b2 100644
--- a/src/plugins/locator/locatorfiltersfilter.h
+++ b/src/plugins/locator/locatorfiltersfilter.h
@@ -56,7 +56,7 @@ public:
     QString displayName() const;
     QString id() 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 refresh(QFutureInterface<void> &future);
     bool isConfigurable() const;
diff --git a/src/plugins/locator/locatorwidget.cpp b/src/plugins/locator/locatorwidget.cpp
index 0ee99048ea0..4ea486caddc 100644
--- a/src/plugins/locator/locatorwidget.cpp
+++ b/src/plugins/locator/locatorwidget.cpp
@@ -428,7 +428,7 @@ QList<ILocatorFilter*> LocatorWidget::filtersFor(const QString &text, QString &s
     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;
     const bool checkDuplicates = (filters.size() > 1);
@@ -436,7 +436,7 @@ static void filter_helper(QFutureInterface<FilterEntry> &entries, QList<ILocator
         if (entries.isCanceled())
             break;
 
-        foreach (const FilterEntry &entry, filter->matchesFor(searchText)) {
+        foreach (const FilterEntry &entry, filter->matchesFor(entries, searchText)) {
             if (checkDuplicates && alreadyAdded.contains(entry))
                 continue;
             entries.reportResult(entry);
@@ -453,6 +453,7 @@ void LocatorWidget::updateCompletionList(const QString &text)
 
     // cancel the old future
     m_entriesWatcher->future().cancel();
+    m_entriesWatcher->future().waitForFinished();
 
     QFuture<FilterEntry> future = QtConcurrent::run(filter_helper, filters, searchText);
     m_entriesWatcher->setFuture(future);
diff --git a/src/plugins/locator/opendocumentsfilter.cpp b/src/plugins/locator/opendocumentsfilter.cpp
index 535d670e470..0c06aff5a13 100644
--- a/src/plugins/locator/opendocumentsfilter.cpp
+++ b/src/plugins/locator/opendocumentsfilter.cpp
@@ -49,7 +49,7 @@ OpenDocumentsFilter::OpenDocumentsFilter(EditorManager *editorManager) :
     setIncludedByDefault(true);
 }
 
-QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry)
+QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     QList<FilterEntry> value;
     const QChar asterisk = QLatin1Char('*');
@@ -60,6 +60,8 @@ QList<FilterEntry> OpenDocumentsFilter::matchesFor(const QString &entry)
     if (!regexp.isValid())
         return value;
     foreach (const OpenEditorsModel::Entry &editorEntry, m_editors) {
+        if (future.isCanceled())
+            break;
         QString fileName = editorEntry.fileName();
         QString displayName = editorEntry.displayName();
         if (regexp.exactMatch(displayName)) {
diff --git a/src/plugins/locator/opendocumentsfilter.h b/src/plugins/locator/opendocumentsfilter.h
index 3b419b980be..33fe15a0621 100644
--- a/src/plugins/locator/opendocumentsfilter.h
+++ b/src/plugins/locator/opendocumentsfilter.h
@@ -55,7 +55,7 @@ public:
     QString displayName() const { return tr("Open documents"); }
     QString id() const { return "Open documents"; }
     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 refresh(QFutureInterface<void> &future);
 
diff --git a/src/plugins/texteditor/linenumberfilter.cpp b/src/plugins/texteditor/linenumberfilter.cpp
index 961c03c9e44..6cbd99713a0 100644
--- a/src/plugins/texteditor/linenumberfilter.cpp
+++ b/src/plugins/texteditor/linenumberfilter.cpp
@@ -48,7 +48,7 @@ LineNumberFilter::LineNumberFilter(QObject *parent)
     setIncludedByDefault(true);
 }
 
-QList<FilterEntry> LineNumberFilter::matchesFor(const QString &entry)
+QList<FilterEntry> LineNumberFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
 {
     bool ok;
     QList<FilterEntry> value;
diff --git a/src/plugins/texteditor/linenumberfilter.h b/src/plugins/texteditor/linenumberfilter.h
index 8a21a220a17..f4d61a66d5a 100644
--- a/src/plugins/texteditor/linenumberfilter.h
+++ b/src/plugins/texteditor/linenumberfilter.h
@@ -52,7 +52,7 @@ public:
     QString displayName() const { return tr("Line in current document"); }
     QString id() const { return "Line in current document"; }
     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 refresh(QFutureInterface<void> &) {}
 
-- 
GitLab