aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schulz <[email protected]>2024-04-12 12:53:27 +0200
committerDavid Schulz <[email protected]>2024-04-15 07:45:15 +0000
commitee8245d8aaa4e34d2773c572aa05a4ca5866f151 (patch)
tree629ac912d9e2623b5fdd0bb15dde6fda4464839a
parent310d3cc041f5617adef10d37605264fda2eda6d3 (diff)
Core: allow multiple contexts per widget
This makes it possible to allow different sets of actions for a specific widget depending on the defined contexts for that widget. Fixes: QTCREATORBUG-30675 Fixes: QTCREATORBUG-30677 Change-Id: I408e0ae445b364d4f450ccdd2fbdfc81ece45015 Reviewed-by: Eike Ziller <[email protected]>
-rw-r--r--src/plugins/coreplugin/icore.cpp63
-rw-r--r--src/plugins/coreplugin/icore.h4
-rw-r--r--src/plugins/coreplugin/statusbarmanager.cpp10
-rw-r--r--src/plugins/help/helpplugin.cpp30
4 files changed, 61 insertions, 46 deletions
diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp
index 8a727494c2d..85401aa8bc7 100644
--- a/src/plugins/coreplugin/icore.cpp
+++ b/src/plugins/coreplugin/icore.cpp
@@ -314,7 +314,7 @@ public:
QList<IContext *> m_activeContext;
- std::unordered_map<QWidget *, IContext *> m_contextWidgets;
+ std::unordered_map<QWidget *, QList<IContext *>> m_contextWidgets;
ShortcutSettings *m_shortcutSettings = nullptr;
ToolSettings *m_toolSettings = nullptr;
@@ -836,16 +836,18 @@ QString ICore::versionString()
}
/*!
- Returns the top level IContext of the current context, or \c nullptr if
+ Returns a list IContexts for the current top level context widget, or an empty list if
there is none.
\sa updateAdditionalContexts()
\sa addContextObject()
\sa {The Action Manager and Commands}
*/
-IContext *ICore::currentContextObject()
+QList<IContext *> ICore::currentContextObjects()
{
- return d->m_activeContext.isEmpty() ? nullptr : d->m_activeContext.first();
+ if (d->m_activeContext.isEmpty())
+ return {};
+ return d->m_contextWidgets[d->m_activeContext.first()->widget()];
}
/*!
@@ -856,8 +858,7 @@ IContext *ICore::currentContextObject()
*/
QWidget *ICore::currentContextWidget()
{
- IContext *context = currentContextObject();
- return context ? context->widget() : nullptr;
+ return d->m_activeContext.isEmpty() ? nullptr : d->m_activeContext.first()->widget();
}
/*!
@@ -1525,8 +1526,10 @@ void ICore::extensionsInitialized()
void ICore::aboutToShutdown()
{
disconnect(qApp, &QApplication::focusChanged, d, &ICorePrivate::updateFocusWidget);
- for (auto contextPair : d->m_contextWidgets)
- disconnect(contextPair.second, &QObject::destroyed, d->m_mainwindow, nullptr);
+ for (auto contextsPair : d->m_contextWidgets) {
+ for (auto context : contextsPair.second)
+ disconnect(context, &QObject::destroyed, d->m_mainwindow, nullptr);
+ }
d->m_activeContext.clear();
d->m_mainwindow->hide();
}
@@ -2281,13 +2284,14 @@ void ICore::openFileWith()
}
/*!
- Returns the registered IContext instance for the specified \a widget,
+ Returns all registered IContext instance for the specified \a widget,
if any.
*/
-IContext *ICore::contextObject(QWidget *widget)
+QList<IContext *> ICore::contextObjects(QWidget *widget)
{
- const auto it = d->m_contextWidgets.find(widget);
- return it == d->m_contextWidgets.end() ? nullptr : it->second;
+ if (auto it = d->m_contextWidgets.find(widget); it != d->m_contextWidgets.end())
+ return it->second;
+ return {};
}
/*!
@@ -2306,11 +2310,7 @@ void ICore::addContextObject(IContext *context)
{
if (!context)
return;
- QWidget *widget = context->widget();
- if (d->m_contextWidgets.find(widget) != d->m_contextWidgets.end())
- return;
-
- d->m_contextWidgets.insert({widget, context});
+ d->m_contextWidgets[context->widget()].append(context);
connect(context, &QObject::destroyed, m_core, [context] { removeContextObject(context); });
}
@@ -2331,15 +2331,19 @@ void ICore::removeContextObject(IContext *context)
disconnect(context, &QObject::destroyed, m_core, nullptr);
- const auto it = std::find_if(d->m_contextWidgets.cbegin(),
- d->m_contextWidgets.cend(),
- [context](const std::pair<QWidget *, IContext *> &v) {
- return v.second == context;
- });
- if (it == d->m_contextWidgets.cend())
+ auto it = std::find_if(
+ d->m_contextWidgets.begin(),
+ d->m_contextWidgets.end(),
+ [context](const std::pair<QWidget *, QList<IContext *>> &v) {
+ return v.second.contains(context);
+ });
+ if (it == d->m_contextWidgets.end())
return;
- d->m_contextWidgets.erase(it);
+ it->second.removeAll(context);
+ if (it->second.isEmpty())
+ d->m_contextWidgets.erase(it);
+
if (d->m_activeContext.removeAll(context) > 0)
d->updateContextObject(d->m_activeContext);
}
@@ -2355,15 +2359,8 @@ void ICorePrivate::updateFocusWidget(QWidget *old, QWidget *now)
return;
QList<IContext *> newContext;
- if (QWidget *p = QApplication::focusWidget()) {
- IContext *context = nullptr;
- while (p) {
- context = ICore::contextObject(p);
- if (context)
- newContext.append(context);
- p = p->parentWidget();
- }
- }
+ for (QWidget *p = QApplication::focusWidget(); p; p = p->parentWidget())
+ newContext.append(ICore::contextObjects(p));
// ignore toplevels that define no context, like popups without parent
if (!newContext.isEmpty() || QApplication::focusWidget() == m_mainwindow->focusWidget())
diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h
index 8c713e156f4..2c2dbc3c57a 100644
--- a/src/plugins/coreplugin/icore.h
+++ b/src/plugins/coreplugin/icore.h
@@ -87,9 +87,9 @@ public:
static void raiseWindow(QWidget *widget);
static void raiseMainWindow();
- static IContext *currentContextObject();
+ static QList<IContext *> currentContextObjects();
static QWidget *currentContextWidget();
- static IContext *contextObject(QWidget *widget);
+ static QList<IContext *> contextObjects(QWidget *widget);
static void updateAdditionalContexts(const Context &remove, const Context &add,
ContextPriority priority = ContextPriority::Low);
static void addAdditionalContext(const Context &context,
diff --git a/src/plugins/coreplugin/statusbarmanager.cpp b/src/plugins/coreplugin/statusbarmanager.cpp
index c590b3f29ef..e85996b053a 100644
--- a/src/plugins/coreplugin/statusbarmanager.cpp
+++ b/src/plugins/coreplugin/statusbarmanager.cpp
@@ -156,13 +156,9 @@ StatusBarContext::StatusBarContext(QObject *parent)
Context StatusBarContext::context() const
{
- IMode *currentMode = ModeManager::currentMode();
- QWidget *modeWidget = currentMode ? currentMode->widget() : nullptr;
- if (modeWidget) {
- if (IContext *context = ICore::contextObject(modeWidget))
- return context->context();
- }
- return Context();
+ if (IMode *currentMode = ModeManager::currentMode())
+ return currentMode->context();
+ return {};
}
} // Core
diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp
index e9706a3db18..49b4624b269 100644
--- a/src/plugins/help/helpplugin.cpp
+++ b/src/plugins/help/helpplugin.cpp
@@ -102,6 +102,7 @@ public:
void modeChanged(Id mode, Id old);
void requestContextHelp();
+ void requestContextHelpFor(QList<QPointer<IContext>> contexts);
void showContextHelp(const HelpItem &contextHelp);
void activateIndex();
void activateContents();
@@ -464,11 +465,32 @@ void HelpPluginPrivate::requestContextHelp()
const HelpItem tipHelp = tipHelpValue.canConvert<HelpItem>()
? tipHelpValue.value<HelpItem>()
: HelpItem(tipHelpValue.toString());
- IContext *context = ICore::currentContextObject();
- if (tipHelp.isEmpty() && context)
- context->contextHelp([this](const HelpItem &item) { showContextHelp(item); });
- else
+ const QList<IContext *> contexts = ICore::currentContextObjects();
+ if (contexts.isEmpty() && !tipHelp.isEmpty()) {
showContextHelp(tipHelp);
+ } else {
+ requestContextHelpFor(Utils::transform(contexts, [](IContext *context) {
+ return QPointer<IContext>(context);
+ }));
+ }
+}
+
+void HelpPluginPrivate::requestContextHelpFor(QList<QPointer<IContext>> contexts)
+{
+ if (contexts.isEmpty())
+ return;
+ QPointer<IContext> context = contexts.takeFirst();
+ while (!context) {
+ if (contexts.isEmpty())
+ return;
+ context = contexts.takeFirst();
+ }
+ context->contextHelp([contexts, this](const HelpItem &item) {
+ if (!item.isEmpty())
+ showContextHelp(item);
+ else
+ requestContextHelpFor(contexts);
+ });
}
void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp)