Unregister deleted IContext objects automatically

Change-Id: I7b84c02c8fe1e7201431116e3d993792370fb942
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Eike Ziller
2020-05-26 13:13:37 +02:00
parent fcbbcc7465
commit 6d97c1fcb1
5 changed files with 27 additions and 15 deletions

View File

@@ -124,8 +124,9 @@
Core::ICore::addContextObject(contextObj); Core::ICore::addContextObject(contextObj);
\endcode \endcode
You also have to unregister the IContext object with IContext instances are automatically unregistered when they are deleted.
Core::ICore::removeContextObject() when you do not need it anymore. Use Core::ICore::removeContextObject() if you need to unregister an IContext
instance manually.
Some constructs in \QC automatically have an associated context, like Some constructs in \QC automatically have an associated context, like
Core::IEditor and Core::IMode. Core::IEditor and Core::IMode.

View File

@@ -179,8 +179,10 @@ QDebug operator<<(QDebug debug, const Core::Context &context)
Core::ICore::addContextObject() to have an effect. For many subclasses of Core::ICore::addContextObject() to have an effect. For many subclasses of
IContext, like Core::IEditor and Core::IMode, this is done automatically. IContext, like Core::IEditor and Core::IMode, this is done automatically.
But instances of IContext can be created manually to associate a context But instances of IContext can be created manually to associate a context
and context help for an arbitrary widget, too. Mind that IContext instances and context help for an arbitrary widget, too. IContext instances are
must be unregistered with Core::ICore::removeContextObject() as well. 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 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 chain, the associated context list is made active. This makes actions active

View File

@@ -569,6 +569,7 @@ void ICore::addContextObject(IContext *context)
/*! /*!
Unregisters a \a context object from the list of know contexts. Unregisters a \a context object from the list of know contexts.
IContext instances are automatically removed when they are deleted.
\sa addContextObject(), updateAdditionalContexts(), currentContextObject() \sa addContextObject(), updateAdditionalContexts(), currentContextObject()
*/ */

View File

@@ -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) void MainWindow::addContextObject(IContext *context)
@@ -927,10 +928,11 @@ void MainWindow::addContextObject(IContext *context)
if (!context) if (!context)
return; return;
QWidget *widget = context->widget(); QWidget *widget = context->widget();
if (m_contextWidgets.contains(widget)) if (m_contextWidgets.find(widget) != m_contextWidgets.end())
return; 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) void MainWindow::removeContextObject(IContext *context)
@@ -938,11 +940,17 @@ void MainWindow::removeContextObject(IContext *context)
if (!context) if (!context)
return; return;
QWidget *widget = context->widget(); disconnect(context, &QObject::destroyed, this, nullptr);
if (!m_contextWidgets.contains(widget))
const auto it = std::find_if(m_contextWidgets.cbegin(),
m_contextWidgets.cend(),
[context](const std::pair<QWidget *, IContext *> &v) {
return v.second == context;
});
if (it == m_contextWidgets.cend())
return; return;
m_contextWidgets.remove(widget); m_contextWidgets.erase(it);
if (m_activeContext.removeAll(context) > 0) if (m_activeContext.removeAll(context) > 0)
updateContextObject(m_activeContext); updateContextObject(m_activeContext);
} }
@@ -959,7 +967,7 @@ void MainWindow::updateFocusWidget(QWidget *old, QWidget *now)
if (QWidget *p = QApplication::focusWidget()) { if (QWidget *p = QApplication::focusWidget()) {
IContext *context = nullptr; IContext *context = nullptr;
while (p) { while (p) {
context = m_contextWidgets.value(p); context = contextObject(p);
if (context) if (context)
newContext.append(context); newContext.append(context);
p = p->parentWidget(); p = p->parentWidget();

View File

@@ -31,10 +31,10 @@
#include <utils/appmainwindow.h> #include <utils/appmainwindow.h>
#include <utils/dropsupport.h> #include <utils/dropsupport.h>
#include <QMap>
#include <QColor> #include <QColor>
#include <functional> #include <functional>
#include <unordered_map>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QPrinter; class QPrinter;
@@ -82,7 +82,7 @@ public:
void extensionsInitialized(); void extensionsInitialized();
void aboutToShutdown(); void aboutToShutdown();
IContext *contextObject(QWidget *widget); IContext *contextObject(QWidget *widget) const;
void addContextObject(IContext *context); void addContextObject(IContext *context);
void removeContextObject(IContext *context); void removeContextObject(IContext *context);
@@ -164,7 +164,7 @@ private:
QList<IContext *> m_activeContext; QList<IContext *> m_activeContext;
QMap<QWidget *, IContext *> m_contextWidgets; std::unordered_map<QWidget *, IContext *> m_contextWidgets;
GeneralSettings *m_generalSettings = nullptr; GeneralSettings *m_generalSettings = nullptr;
SystemSettings *m_systemSettings = nullptr; SystemSettings *m_systemSettings = nullptr;