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:
Eike Ziller
2013-05-07 19:03:22 +02:00
parent 2bfcb47d63
commit c31c5612ab
11 changed files with 72 additions and 74 deletions

View File

@@ -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();
} }

View File

@@ -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;

View File

@@ -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)),

View File

@@ -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;
}
}
} }
/*! /*!

View File

@@ -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

View File

@@ -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;

View File

@@ -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();

View File

@@ -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).
*/ */
/*! /*!

View File

@@ -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

View File

@@ -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);

View File

@@ -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;