forked from qt-creator/qt-creator
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 <eike.ziller@qt.io>
This commit is contained in:
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user