diff --git a/src/plugins/cppeditor/cpptypehierarchy.cpp b/src/plugins/cppeditor/cpptypehierarchy.cpp index 34025a59bd8..0178ab60557 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.cpp +++ b/src/plugins/cppeditor/cpptypehierarchy.cpp @@ -130,15 +130,21 @@ CppTypeHierarchyWidget::CppTypeHierarchyWidget() connect(CppEditorPlugin::instance(), &CppEditorPlugin::typeHierarchyRequested, this, &CppTypeHierarchyWidget::perform); - connect(&m_futureWatcher, &QFutureWatcher>::finished, + connect(&m_futureWatcher, &QFutureWatcher::finished, this, &CppTypeHierarchyWidget::displayHierarchy); + + m_synchronizer.setCancelOnWait(true); } -CppTypeHierarchyWidget::~CppTypeHierarchyWidget() +void CppTypeHierarchyWidget::updateSynchronizer() { - if (m_future.isRunning()) { - m_future.cancel(); - m_future.waitForFinished(); + const QList> futures = m_synchronizer.futures(); + + m_synchronizer.clearFutures(); + + for (const QFuture &future : futures) { + if (!future.isFinished()) + m_synchronizer.addFuture(future); } } @@ -147,6 +153,8 @@ void CppTypeHierarchyWidget::perform() if (m_future.isRunning()) m_future.cancel(); + updateSynchronizer(); + auto editor = qobject_cast(Core::EditorManager::currentEditor()); if (!editor) { showNoTypeHierarchyLabel(); @@ -165,13 +173,15 @@ void CppTypeHierarchyWidget::perform() evaluator.setLookupBaseClasses(true); evaluator.setLookupDerivedClasses(true); m_future = evaluator.asyncExecute(); - m_futureWatcher.setFuture(m_future); + m_futureWatcher.setFuture(QFuture(m_future)); + m_synchronizer.addFuture(QFuture(m_future)); Core::ProgressManager::addTask(m_future, tr("Evaluating Type Hierarchy"), "TypeHierarchy"); } void CppTypeHierarchyWidget::displayHierarchy() { + updateSynchronizer(); hideProgress(); clearTypeHierarchy(); diff --git a/src/plugins/cppeditor/cpptypehierarchy.h b/src/plugins/cppeditor/cpptypehierarchy.h index 83b1a4d99f3..94414db895c 100644 --- a/src/plugins/cppeditor/cpptypehierarchy.h +++ b/src/plugins/cppeditor/cpptypehierarchy.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -75,7 +76,6 @@ class CppTypeHierarchyWidget : public QWidget Q_OBJECT public: CppTypeHierarchyWidget(); - ~CppTypeHierarchyWidget() override; void perform(); @@ -92,6 +92,7 @@ private: void hideProgress(); void clearTypeHierarchy(); void onItemActivated(const QModelIndex &index); + void updateSynchronizer(); CppEditorWidget *m_cppEditor = nullptr; Utils::NavigationTreeView *m_treeView = nullptr; @@ -102,7 +103,8 @@ private: TextEditor::TextEditorLinkLabel *m_inspectedClass = nullptr; QLabel *m_infoLabel = nullptr; QFuture> m_future; - QFutureWatcher> m_futureWatcher; + QFutureWatcher m_futureWatcher; + QFutureSynchronizer m_synchronizer; Utils::ProgressIndicator *m_progressIndicator = nullptr; }; diff --git a/src/plugins/cpptools/cppelementevaluator.cpp b/src/plugins/cpptools/cppelementevaluator.cpp index 208f75433dc..0e739ddeab2 100644 --- a/src/plugins/cpptools/cppelementevaluator.cpp +++ b/src/plugins/cpptools/cppelementevaluator.cpp @@ -214,6 +214,8 @@ void CppClass::lookupDerived(QFutureInterfaceBase &futureInterface, using Data = QPair; snapshot.updateDependencyTable(futureInterface); + if (futureInterface.isCanceled()) + return; CppTools::TypeHierarchyBuilder builder(declaration, snapshot); const CppTools::TypeHierarchy &completeHierarchy = builder.buildDerivedTypeHierarchy(futureInterface); @@ -531,7 +533,7 @@ static void handleLookupItemMatch(QFutureInterface> & if (futureInterface.isCanceled()) return; - auto cppClass = new CppClass(declaration); + QSharedPointer cppClass(new CppClass(declaration)); if (lookupBaseClasses) cppClass->lookupBases(futureInterface, declaration, contextToUse); if (futureInterface.isCanceled()) @@ -540,7 +542,7 @@ static void handleLookupItemMatch(QFutureInterface> & cppClass->lookupDerived(futureInterface, declaration, snapshot); if (futureInterface.isCanceled()) return; - element = QSharedPointer(cppClass); + element = cppClass; } else if (Enum *enumDecl = declaration->asEnum()) { element = QSharedPointer(new CppEnum(enumDecl)); } else if (auto enumerator = dynamic_cast(declaration)) {