From 6d97c1fcb1f0a8c712d902065a887f8b74c61cf4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 26 May 2020 13:13:37 +0200 Subject: Unregister deleted IContext objects automatically Change-Id: I7b84c02c8fe1e7201431116e3d993792370fb942 Reviewed-by: hjk --- doc/qtcreatordev/src/actionmanager.qdoc | 5 +++-- src/plugins/coreplugin/icontext.cpp | 6 ++++-- src/plugins/coreplugin/icore.cpp | 1 + src/plugins/coreplugin/mainwindow.cpp | 24 ++++++++++++++++-------- src/plugins/coreplugin/mainwindow.h | 6 +++--- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/doc/qtcreatordev/src/actionmanager.qdoc b/doc/qtcreatordev/src/actionmanager.qdoc index 194d0eefdf..49c57d6818 100644 --- a/doc/qtcreatordev/src/actionmanager.qdoc +++ b/doc/qtcreatordev/src/actionmanager.qdoc @@ -124,8 +124,9 @@ Core::ICore::addContextObject(contextObj); \endcode - You also have to unregister the IContext object with - Core::ICore::removeContextObject() when you do not need it anymore. + IContext instances are automatically unregistered when they are deleted. + Use Core::ICore::removeContextObject() if you need to unregister an IContext + instance manually. Some constructs in \QC automatically have an associated context, like Core::IEditor and Core::IMode. diff --git a/src/plugins/coreplugin/icontext.cpp b/src/plugins/coreplugin/icontext.cpp index 30dbf87059..300fe62704 100644 --- a/src/plugins/coreplugin/icontext.cpp +++ b/src/plugins/coreplugin/icontext.cpp @@ -179,8 +179,10 @@ QDebug operator<<(QDebug debug, const Core::Context &context) Core::ICore::addContextObject() to have an effect. For many subclasses of IContext, like Core::IEditor and Core::IMode, this is done automatically. But instances of IContext can be created manually to associate a context - and context help for an arbitrary widget, too. Mind that IContext instances - must be unregistered with Core::ICore::removeContextObject() as well. + and context help for an arbitrary widget, too. IContext instances are + automatically unregistered when they are deleted. Use + Core::ICore::removeContextObject() if you need to unregister an IContext + instance manually. Whenever the widget is part of the application wide focus widget's parent chain, the associated context list is made active. This makes actions active diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index b5986bd67c..cf3e2907d6 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -569,6 +569,7 @@ void ICore::addContextObject(IContext *context) /*! Unregisters a \a context object from the list of know contexts. + IContext instances are automatically removed when they are deleted. \sa addContextObject(), updateAdditionalContexts(), currentContextObject() */ diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 2a9d4edeee..2109dc27e6 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -917,9 +917,10 @@ void MainWindow::openFileWith() } } -IContext *MainWindow::contextObject(QWidget *widget) +IContext *MainWindow::contextObject(QWidget *widget) const { - return m_contextWidgets.value(widget); + const auto it = m_contextWidgets.find(widget); + return it == m_contextWidgets.end() ? nullptr : it->second; } void MainWindow::addContextObject(IContext *context) @@ -927,10 +928,11 @@ void MainWindow::addContextObject(IContext *context) if (!context) return; QWidget *widget = context->widget(); - if (m_contextWidgets.contains(widget)) + if (m_contextWidgets.find(widget) != m_contextWidgets.end()) return; - m_contextWidgets.insert(widget, context); + m_contextWidgets.insert(std::make_pair(widget, context)); + connect(context, &QObject::destroyed, this, [this, context] { removeContextObject(context); }); } void MainWindow::removeContextObject(IContext *context) @@ -938,11 +940,17 @@ void MainWindow::removeContextObject(IContext *context) if (!context) return; - QWidget *widget = context->widget(); - if (!m_contextWidgets.contains(widget)) + disconnect(context, &QObject::destroyed, this, nullptr); + + const auto it = std::find_if(m_contextWidgets.cbegin(), + m_contextWidgets.cend(), + [context](const std::pair &v) { + return v.second == context; + }); + if (it == m_contextWidgets.cend()) return; - m_contextWidgets.remove(widget); + m_contextWidgets.erase(it); if (m_activeContext.removeAll(context) > 0) updateContextObject(m_activeContext); } @@ -959,7 +967,7 @@ void MainWindow::updateFocusWidget(QWidget *old, QWidget *now) if (QWidget *p = QApplication::focusWidget()) { IContext *context = nullptr; while (p) { - context = m_contextWidgets.value(p); + context = contextObject(p); if (context) newContext.append(context); p = p->parentWidget(); diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h index 554e7b6206..78ec6495d6 100644 --- a/src/plugins/coreplugin/mainwindow.h +++ b/src/plugins/coreplugin/mainwindow.h @@ -31,10 +31,10 @@ #include #include -#include #include #include +#include QT_BEGIN_NAMESPACE class QPrinter; @@ -82,7 +82,7 @@ public: void extensionsInitialized(); void aboutToShutdown(); - IContext *contextObject(QWidget *widget); + IContext *contextObject(QWidget *widget) const; void addContextObject(IContext *context); void removeContextObject(IContext *context); @@ -164,7 +164,7 @@ private: QList m_activeContext; - QMap m_contextWidgets; + std::unordered_map m_contextWidgets; GeneralSettings *m_generalSettings = nullptr; SystemSettings *m_systemSettings = nullptr; -- cgit v1.2.1