forked from qt-creator/qt-creator
Allow nested IContexts and use it to give extra editor windows a context
The extra editor windows need to have editor manager context, otherwise
shortcuts (like ctrl+tab) do not work in them if e.g. projects mode is
active. Doing this via add/removeAdditionalContexts would be non-trivial
and error prone, so adding a context to the extra window is more
convenient. Since editors themselves already define a context, we need
to allow nesting of contexts.
Change-Id: I244eca53ebd665fd4d8fe7531e8ff701ed0b40b2
Reviewed-by: David Schulz <david.schulz@digia.com>
(cherry picked from commit deff0eb3c7)
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
@@ -507,8 +507,8 @@ bool BinEditorPlugin::initialize(const QStringList &arguments, QString *errorMes
|
|||||||
Q_UNUSED(arguments)
|
Q_UNUSED(arguments)
|
||||||
Q_UNUSED(errorMessage)
|
Q_UNUSED(errorMessage)
|
||||||
|
|
||||||
connect(Core::ICore::instance(), SIGNAL(contextAboutToChange(Core::IContext*)),
|
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
|
||||||
this, SLOT(updateCurrentEditor(Core::IContext*)));
|
this, SLOT(updateCurrentEditor(Core::IEditor*)));
|
||||||
|
|
||||||
addAutoReleasedObject(new BinEditorFactory(this));
|
addAutoReleasedObject(new BinEditorFactory(this));
|
||||||
addAutoReleasedObject(new BinEditorWidgetFactory);
|
addAutoReleasedObject(new BinEditorWidgetFactory);
|
||||||
@@ -519,31 +519,14 @@ void BinEditorPlugin::extensionsInitialized()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditorPlugin::updateCurrentEditor(Core::IContext *object)
|
void BinEditorPlugin::updateCurrentEditor(Core::IEditor *editor)
|
||||||
{
|
{
|
||||||
do {
|
BinEditor *binEditor = 0;
|
||||||
if (!object) {
|
if (editor)
|
||||||
if (!m_currentEditor)
|
binEditor = qobject_cast<BinEditor *>(editor->widget());
|
||||||
|
if (m_currentEditor == binEditor)
|
||||||
return;
|
return;
|
||||||
|
m_currentEditor = binEditor;
|
||||||
m_currentEditor = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
BinEditor *editor = qobject_cast<BinEditor *>(object->widget());
|
|
||||||
if (!editor) {
|
|
||||||
if (!m_currentEditor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_currentEditor = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (editor == m_currentEditor)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_currentEditor = editor;
|
|
||||||
|
|
||||||
} while (false);
|
|
||||||
updateActions();
|
updateActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ private slots:
|
|||||||
void selectAllAction();
|
void selectAllAction();
|
||||||
void updateActions();
|
void updateActions();
|
||||||
|
|
||||||
void updateCurrentEditor(Core::IContext *object);
|
void updateCurrentEditor(Core::IEditor *editor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::Context m_context;
|
Core::Context m_context;
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ BookmarkManager::BookmarkManager() :
|
|||||||
m_bookmarkIcon(QLatin1String(":/bookmarks/images/bookmark.png")),
|
m_bookmarkIcon(QLatin1String(":/bookmarks/images/bookmark.png")),
|
||||||
m_selectionModel(new QItemSelectionModel(this, this))
|
m_selectionModel(new QItemSelectionModel(this, this))
|
||||||
{
|
{
|
||||||
connect(Core::ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
|
connect(Core::ICore::instance(), SIGNAL(contextChanged(QList<Core::IContext*>,Core::Context)),
|
||||||
this, SLOT(updateActionStatus()));
|
this, SLOT(updateActionStatus()));
|
||||||
|
|
||||||
connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(sessionLoaded(QString)),
|
connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(sessionLoaded(QString)),
|
||||||
|
|||||||
@@ -218,8 +218,8 @@ DocumentManager::DocumentManager(QMainWindow *mw)
|
|||||||
m_instance = this;
|
m_instance = this;
|
||||||
connect(d->m_mainWindow, SIGNAL(windowActivated()),
|
connect(d->m_mainWindow, SIGNAL(windowActivated()),
|
||||||
this, SLOT(mainWindowActivated()));
|
this, SLOT(mainWindowActivated()));
|
||||||
connect(ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
|
connect(ICore::instance(), SIGNAL(contextChanged(QList<Core::IContext*>,Core::Context)),
|
||||||
this, SLOT(syncWithEditor(Core::IContext*)));
|
this, SLOT(syncWithEditor(QList<Core::IContext*>)));
|
||||||
|
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
@@ -1061,15 +1061,20 @@ void DocumentManager::checkForReload()
|
|||||||
// dump();
|
// dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentManager::syncWithEditor(Core::IContext *context)
|
void DocumentManager::syncWithEditor(const QList<Core::IContext *> &context)
|
||||||
{
|
{
|
||||||
if (!context)
|
if (context.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Core::IEditor *editor = Core::EditorManager::currentEditor();
|
Core::IEditor *editor = Core::EditorManager::currentEditor();
|
||||||
if (editor && editor->widget() == context->widget()
|
if (!editor || editor->isTemporary())
|
||||||
&& !editor->isTemporary())
|
return;
|
||||||
|
foreach (IContext *c, context) {
|
||||||
|
if (editor->widget() == c->widget()) {
|
||||||
setCurrentFile(editor->document()->fileName());
|
setCurrentFile(editor->document()->fileName());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ private slots:
|
|||||||
void checkForReload();
|
void checkForReload();
|
||||||
void changedFile(const QString &file);
|
void changedFile(const QString &file);
|
||||||
void mainWindowActivated();
|
void mainWindowActivated();
|
||||||
void syncWithEditor(Core::IContext *context);
|
void syncWithEditor(const QList<Core::IContext *> &context);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! The FileChangeBlocker blocks all change notifications to all IDocument * that
|
/*! The FileChangeBlocker blocks all change notifications to all IDocument * that
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ struct EditorManagerPrivate
|
|||||||
~EditorManagerPrivate();
|
~EditorManagerPrivate();
|
||||||
QList<EditLocation> m_globalHistory;
|
QList<EditLocation> m_globalHistory;
|
||||||
QList<Internal::SplitterOrView *> m_root;
|
QList<Internal::SplitterOrView *> m_root;
|
||||||
|
QList<IContext *> m_rootContext;
|
||||||
QPointer<IEditor> m_currentEditor;
|
QPointer<IEditor> m_currentEditor;
|
||||||
QPointer<IEditor> m_scheduledCurrentEditor;
|
QPointer<IEditor> m_scheduledCurrentEditor;
|
||||||
QPointer<EditorView> m_currentView;
|
QPointer<EditorView> m_currentView;
|
||||||
@@ -272,8 +273,8 @@ EditorManager::EditorManager(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
connect(ICore::instance(), SIGNAL(contextAboutToChange(Core::IContext*)),
|
connect(ICore::instance(), SIGNAL(contextAboutToChange(QList<Core::IContext*>)),
|
||||||
this, SLOT(handleContextChange(Core::IContext*)));
|
this, SLOT(handleContextChange(QList<Core::IContext*>)));
|
||||||
|
|
||||||
const Context editManagerContext(Constants::C_EDITORMANAGER);
|
const Context editManagerContext(Constants::C_EDITORMANAGER);
|
||||||
// combined context for edit & design modes
|
// combined context for edit & design modes
|
||||||
@@ -426,6 +427,7 @@ EditorManager::EditorManager(QWidget *parent) :
|
|||||||
// other setup
|
// other setup
|
||||||
SplitterOrView *firstRoot = new SplitterOrView();
|
SplitterOrView *firstRoot = new SplitterOrView();
|
||||||
d->m_root.append(firstRoot);
|
d->m_root.append(firstRoot);
|
||||||
|
d->m_rootContext.append(0);
|
||||||
d->m_currentView = firstRoot->view();
|
d->m_currentView = firstRoot->view();
|
||||||
|
|
||||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||||
@@ -458,9 +460,13 @@ EditorManager::~EditorManager()
|
|||||||
for (int i = 1; i < d->m_root.size(); ++i) {
|
for (int i = 1; i < d->m_root.size(); ++i) {
|
||||||
SplitterOrView *root = d->m_root.at(i);
|
SplitterOrView *root = d->m_root.at(i);
|
||||||
disconnect(root, SIGNAL(destroyed(QObject*)), this, SLOT(rootDestroyed(QObject*)));
|
disconnect(root, SIGNAL(destroyed(QObject*)), this, SLOT(rootDestroyed(QObject*)));
|
||||||
|
IContext *rootContext = d->m_rootContext.at(i);
|
||||||
|
ICore::removeContextObject(rootContext);
|
||||||
delete root;
|
delete root;
|
||||||
|
delete rootContext;
|
||||||
}
|
}
|
||||||
d->m_root.clear();
|
d->m_root.clear();
|
||||||
|
d->m_rootContext.clear();
|
||||||
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
@@ -504,12 +510,15 @@ void EditorManager::removeEditor(IEditor *editor)
|
|||||||
ICore::removeContextObject(editor);
|
ICore::removeContextObject(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorManager::handleContextChange(Core::IContext *context)
|
void EditorManager::handleContextChange(const QList<Core::IContext *> &context)
|
||||||
{
|
{
|
||||||
if (debugEditorManager)
|
if (debugEditorManager)
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
d->m_scheduledCurrentEditor = 0;
|
d->m_scheduledCurrentEditor = 0;
|
||||||
IEditor *editor = context ? qobject_cast<IEditor*>(context) : 0;
|
IEditor *editor = 0;
|
||||||
|
foreach (IContext *c, context)
|
||||||
|
if ((editor = qobject_cast<IEditor*>(c)))
|
||||||
|
break;
|
||||||
if (editor && editor != d->m_currentEditor) {
|
if (editor && editor != d->m_currentEditor) {
|
||||||
// Delay actually setting the current editor to after the current event queue has been handled
|
// Delay actually setting the current editor to after the current event queue has been handled
|
||||||
// Without doing this, e.g. clicking into projects tree or locator would always open editors
|
// Without doing this, e.g. clicking into projects tree or locator would always open editors
|
||||||
@@ -681,6 +690,10 @@ void EditorManager::splitNewWindow(Internal::EditorView *view)
|
|||||||
splitter->setAttribute(Qt::WA_DeleteOnClose);
|
splitter->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
splitter->setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
|
splitter->setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
|
||||||
splitter->resize(QSize(800, 600));
|
splitter->resize(QSize(800, 600));
|
||||||
|
IContext *context = new IContext;
|
||||||
|
context->setContext(Context(Constants::C_EDITORMANAGER));
|
||||||
|
context->setWidget(splitter);
|
||||||
|
ICore::addContextObject(context);
|
||||||
splitter->show();
|
splitter->show();
|
||||||
ICore::raiseWindow(splitter);
|
ICore::raiseWindow(splitter);
|
||||||
if (newEditor)
|
if (newEditor)
|
||||||
@@ -688,6 +701,7 @@ void EditorManager::splitNewWindow(Internal::EditorView *view)
|
|||||||
else
|
else
|
||||||
splitter->view()->setFocus();
|
splitter->view()->setFocus();
|
||||||
m_instance->d->m_root.append(splitter);
|
m_instance->d->m_root.append(splitter);
|
||||||
|
m_instance->d->m_rootContext.append(context);
|
||||||
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
|
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
|
||||||
m_instance->updateActions();
|
m_instance->updateActions();
|
||||||
}
|
}
|
||||||
@@ -883,11 +897,16 @@ void EditorManager::rootDestroyed(QObject *root)
|
|||||||
SplitterOrView *newActiveRoot = 0;
|
SplitterOrView *newActiveRoot = 0;
|
||||||
for (int i = 0; i < d->m_root.size(); ++i) {
|
for (int i = 0; i < d->m_root.size(); ++i) {
|
||||||
SplitterOrView *r = d->m_root.at(i);
|
SplitterOrView *r = d->m_root.at(i);
|
||||||
if (r == root)
|
if (r == root) {
|
||||||
d->m_root.removeAll(r);
|
d->m_root.removeAll(r);
|
||||||
else if (r->window() == activeWin)
|
IContext *context = d->m_rootContext.at(i);
|
||||||
|
ICore::removeContextObject(context);
|
||||||
|
delete context;
|
||||||
|
|
||||||
|
} else if (r->window() == activeWin) {
|
||||||
newActiveRoot = r;
|
newActiveRoot = r;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// check if the destroyed root had the current view or current editor
|
// check if the destroyed root had the current view or current editor
|
||||||
if (d->m_currentEditor || (d->m_currentView && d->m_currentView->parentSplitterOrView() != root))
|
if (d->m_currentEditor || (d->m_currentView && d->m_currentView->parentSplitterOrView() != root))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void gotoNextDocHistory();
|
void gotoNextDocHistory();
|
||||||
void gotoPreviousDocHistory();
|
void gotoPreviousDocHistory();
|
||||||
void handleContextChange(Core::IContext *context);
|
void handleContextChange(const QList<Core::IContext *> &context);
|
||||||
void updateActions();
|
void updateActions();
|
||||||
void makeCurrentEditorWritable();
|
void makeCurrentEditorWritable();
|
||||||
void vcsOpenCurrentEditor();
|
void vcsOpenCurrentEditor();
|
||||||
|
|||||||
@@ -332,9 +332,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void ICore::contextAboutToChange(Core::IContext *context)
|
\fn void ICore::contextAboutToChange(const QList<Core::IContext *> &context)
|
||||||
\brief Sent just before a new \a context becomes the current context
|
\brief Sent just before a new \a context becomes the current context
|
||||||
(meaning that its widget got focus).
|
(meaning that itself or one of its child widgets got focus).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -146,8 +146,8 @@ signals:
|
|||||||
void saveSettingsRequested();
|
void saveSettingsRequested();
|
||||||
void optionsDialogRequested();
|
void optionsDialogRequested();
|
||||||
void coreAboutToClose();
|
void coreAboutToClose();
|
||||||
void contextAboutToChange(Core::IContext *context);
|
void contextAboutToChange(const QList<Core::IContext *> &context);
|
||||||
void contextChanged(Core::IContext *context, const Core::Context &additionalContexts);
|
void contextChanged(const QList<Core::IContext *> &context, const Core::Context &additionalContexts);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ MainWindow::MainWindow() :
|
|||||||
m_navigationWidget(0),
|
m_navigationWidget(0),
|
||||||
m_rightPaneWidget(0),
|
m_rightPaneWidget(0),
|
||||||
m_versionDialog(0),
|
m_versionDialog(0),
|
||||||
m_activeContext(0),
|
|
||||||
m_generalSettings(new GeneralSettings),
|
m_generalSettings(new GeneralSettings),
|
||||||
m_shortcutSettings(new ShortcutSettings),
|
m_shortcutSettings(new ShortcutSettings),
|
||||||
m_toolSettings(new ToolSettings),
|
m_toolSettings(new ToolSettings),
|
||||||
@@ -457,7 +456,7 @@ void MainWindow::openDelayedFiles()
|
|||||||
|
|
||||||
IContext *MainWindow::currentContextObject() const
|
IContext *MainWindow::currentContextObject() const
|
||||||
{
|
{
|
||||||
return m_activeContext;
|
return m_activeContext.isEmpty() ? 0 : m_activeContext.first();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStatusBar *MainWindow::statusBar() const
|
QStatusBar *MainWindow::statusBar() const
|
||||||
@@ -1094,8 +1093,8 @@ void MainWindow::removeContextObject(IContext *context)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_contextWidgets.remove(widget);
|
m_contextWidgets.remove(widget);
|
||||||
if (m_activeContext == context)
|
if (m_activeContext.removeAll(context) > 0)
|
||||||
updateContextObject(0);
|
updateContextObject(m_activeContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::changeEvent(QEvent *e)
|
void MainWindow::changeEvent(QEvent *e)
|
||||||
@@ -1129,46 +1128,39 @@ void MainWindow::updateFocusWidget(QWidget *old, QWidget *now)
|
|||||||
if (qobject_cast<QMenuBar*>(now) || qobject_cast<QMenu*>(now))
|
if (qobject_cast<QMenuBar*>(now) || qobject_cast<QMenu*>(now))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IContext *newContext = 0;
|
QList<IContext *> newContext;
|
||||||
if (QWidget *p = qApp->focusWidget()) {
|
if (QWidget *p = qApp->focusWidget()) {
|
||||||
IContext *context = 0;
|
IContext *context = 0;
|
||||||
while (p) {
|
while (p) {
|
||||||
context = m_contextWidgets.value(p);
|
context = m_contextWidgets.value(p);
|
||||||
if (context) {
|
if (context)
|
||||||
newContext = context;
|
newContext.append(context);
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = p->parentWidget();
|
p = p->parentWidget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore toplevels that define no context, like popups without parent
|
// ignore toplevels that define no context, like popups without parent
|
||||||
if (newContext || qApp->focusWidget() == focusWidget())
|
if (!newContext.isEmpty() || qApp->focusWidget() == focusWidget())
|
||||||
updateContextObject(newContext);
|
updateContextObject(newContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateContextObject(IContext *context)
|
void MainWindow::updateContextObject(const QList<IContext *> &context)
|
||||||
{
|
{
|
||||||
if (context == m_activeContext)
|
|
||||||
return;
|
|
||||||
emit m_coreImpl->contextAboutToChange(context);
|
emit m_coreImpl->contextAboutToChange(context);
|
||||||
m_activeContext = context;
|
m_activeContext = context;
|
||||||
updateContext();
|
updateContext();
|
||||||
if (debugMainWindow)
|
if (debugMainWindow) {
|
||||||
qDebug() << "new context object =" << context << (context ? context->widget() : 0)
|
qDebug() << "new context objects =" << context;
|
||||||
<< (context ? context->widget()->metaObject()->className() : 0);
|
foreach (IContext *c, context)
|
||||||
|
qDebug() << (c ? c->widget() : 0) << (c ? c->widget()->metaObject()->className() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::resetContext()
|
|
||||||
{
|
|
||||||
updateContextObject(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::aboutToShutdown()
|
void MainWindow::aboutToShutdown()
|
||||||
{
|
{
|
||||||
disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
|
disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
|
||||||
this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
|
this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
|
||||||
m_activeContext = 0;
|
m_activeContext.clear();
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1252,8 +1244,8 @@ void MainWindow::updateContext()
|
|||||||
{
|
{
|
||||||
Context contexts;
|
Context contexts;
|
||||||
|
|
||||||
if (m_activeContext)
|
foreach (IContext *context, m_activeContext)
|
||||||
contexts.add(m_activeContext->context());
|
contexts.add(context->context());
|
||||||
|
|
||||||
contexts.add(m_additionalContexts);
|
contexts.add(m_additionalContexts);
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ public:
|
|||||||
IContext *contextObject(QWidget *widget);
|
IContext *contextObject(QWidget *widget);
|
||||||
void addContextObject(IContext *contex);
|
void addContextObject(IContext *contex);
|
||||||
void removeContextObject(IContext *contex);
|
void removeContextObject(IContext *contex);
|
||||||
void resetContext();
|
|
||||||
|
|
||||||
Core::IDocument *openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags);
|
Core::IDocument *openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags);
|
||||||
|
|
||||||
@@ -164,7 +163,7 @@ private slots:
|
|||||||
void openDelayedFiles();
|
void openDelayedFiles();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateContextObject(IContext *context);
|
void updateContextObject(const QList<IContext *> &context);
|
||||||
void updateContext();
|
void updateContext();
|
||||||
|
|
||||||
void registerDefaultContainers();
|
void registerDefaultContainers();
|
||||||
@@ -197,7 +196,7 @@ private:
|
|||||||
Core::StatusBarWidget *m_outputView;
|
Core::StatusBarWidget *m_outputView;
|
||||||
VersionDialog *m_versionDialog;
|
VersionDialog *m_versionDialog;
|
||||||
|
|
||||||
IContext *m_activeContext;
|
QList<IContext *> m_activeContext;
|
||||||
|
|
||||||
QMap<QWidget *, IContext *> m_contextWidgets;
|
QMap<QWidget *, IContext *> m_contextWidgets;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user