Commit c31c5612 authored by Eike Ziller's avatar Eike Ziller
Browse files

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: default avatarDavid Schulz <david.schulz@digia.com>
(cherry picked from commit deff0eb3

)
Reviewed-by: default avatarEike Ziller <eike.ziller@digia.com>
parent 2bfcb47d
......@@ -507,8 +507,8 @@ bool BinEditorPlugin::initialize(const QStringList &arguments, QString *errorMes
Q_UNUSED(arguments)
Q_UNUSED(errorMessage)
connect(Core::ICore::instance(), SIGNAL(contextAboutToChange(Core::IContext*)),
this, SLOT(updateCurrentEditor(Core::IContext*)));
connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(updateCurrentEditor(Core::IEditor*)));
addAutoReleasedObject(new BinEditorFactory(this));
addAutoReleasedObject(new BinEditorWidgetFactory);
......@@ -519,31 +519,14 @@ void BinEditorPlugin::extensionsInitialized()
{
}
void BinEditorPlugin::updateCurrentEditor(Core::IContext *object)
void BinEditorPlugin::updateCurrentEditor(Core::IEditor *editor)
{
do {
if (!object) {
if (!m_currentEditor)
return;
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);
BinEditor *binEditor = 0;
if (editor)
binEditor = qobject_cast<BinEditor *>(editor->widget());
if (m_currentEditor == binEditor)
return;
m_currentEditor = binEditor;
updateActions();
}
......
......@@ -76,7 +76,7 @@ private slots:
void selectAllAction();
void updateActions();
void updateCurrentEditor(Core::IContext *object);
void updateCurrentEditor(Core::IEditor *editor);
private:
Core::Context m_context;
......
......@@ -324,7 +324,7 @@ BookmarkManager::BookmarkManager() :
m_bookmarkIcon(QLatin1String(":/bookmarks/images/bookmark.png")),
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()));
connect(ProjectExplorerPlugin::instance()->session(), SIGNAL(sessionLoaded(QString)),
......
......@@ -218,8 +218,8 @@ DocumentManager::DocumentManager(QMainWindow *mw)
m_instance = this;
connect(d->m_mainWindow, SIGNAL(windowActivated()),
this, SLOT(mainWindowActivated()));
connect(ICore::instance(), SIGNAL(contextChanged(Core::IContext*,Core::Context)),
this, SLOT(syncWithEditor(Core::IContext*)));
connect(ICore::instance(), SIGNAL(contextChanged(QList<Core::IContext*>,Core::Context)),
this, SLOT(syncWithEditor(QList<Core::IContext*>)));
readSettings();
}
......@@ -1061,15 +1061,20 @@ void DocumentManager::checkForReload()
// dump();
}
void DocumentManager::syncWithEditor(Core::IContext *context)
void DocumentManager::syncWithEditor(const QList<Core::IContext *> &context)
{
if (!context)
if (context.isEmpty())
return;
Core::IEditor *editor = Core::EditorManager::currentEditor();
if (editor && editor->widget() == context->widget()
&& !editor->isTemporary())
setCurrentFile(editor->document()->fileName());
if (!editor || editor->isTemporary())
return;
foreach (IContext *c, context) {
if (editor->widget() == c->widget()) {
setCurrentFile(editor->document()->fileName());
break;
}
}
}
/*!
......
......@@ -149,7 +149,7 @@ private slots:
void checkForReload();
void changedFile(const QString &file);
void mainWindowActivated();
void syncWithEditor(Core::IContext *context);
void syncWithEditor(const QList<Core::IContext *> &context);
};
/*! The FileChangeBlocker blocks all change notifications to all IDocument * that
......
......@@ -177,6 +177,7 @@ struct EditorManagerPrivate
~EditorManagerPrivate();
QList<EditLocation> m_globalHistory;
QList<Internal::SplitterOrView *> m_root;
QList<IContext *> m_rootContext;
QPointer<IEditor> m_currentEditor;
QPointer<IEditor> m_scheduledCurrentEditor;
QPointer<EditorView> m_currentView;
......@@ -272,8 +273,8 @@ EditorManager::EditorManager(QWidget *parent) :
{
m_instance = this;
connect(ICore::instance(), SIGNAL(contextAboutToChange(Core::IContext*)),
this, SLOT(handleContextChange(Core::IContext*)));
connect(ICore::instance(), SIGNAL(contextAboutToChange(QList<Core::IContext*>)),
this, SLOT(handleContextChange(QList<Core::IContext*>)));
const Context editManagerContext(Constants::C_EDITORMANAGER);
// combined context for edit & design modes
......@@ -426,6 +427,7 @@ EditorManager::EditorManager(QWidget *parent) :
// other setup
SplitterOrView *firstRoot = new SplitterOrView();
d->m_root.append(firstRoot);
d->m_rootContext.append(0);
d->m_currentView = firstRoot->view();
QHBoxLayout *layout = new QHBoxLayout(this);
......@@ -458,9 +460,13 @@ EditorManager::~EditorManager()
for (int i = 1; i < d->m_root.size(); ++i) {
SplitterOrView *root = d->m_root.at(i);
disconnect(root, SIGNAL(destroyed(QObject*)), this, SLOT(rootDestroyed(QObject*)));
IContext *rootContext = d->m_rootContext.at(i);
ICore::removeContextObject(rootContext);
delete root;
delete rootContext;
}
d->m_root.clear();
d->m_rootContext.clear();
delete d;
}
......@@ -504,12 +510,15 @@ void EditorManager::removeEditor(IEditor *editor)
ICore::removeContextObject(editor);
}
void EditorManager::handleContextChange(Core::IContext *context)
void EditorManager::handleContextChange(const QList<Core::IContext *> &context)
{
if (debugEditorManager)
qDebug() << Q_FUNC_INFO;
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) {
// 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
......@@ -681,6 +690,10 @@ void EditorManager::splitNewWindow(Internal::EditorView *view)
splitter->setAttribute(Qt::WA_DeleteOnClose);
splitter->setAttribute(Qt::WA_QuitOnClose, false); // don't prevent Qt Creator from closing
splitter->resize(QSize(800, 600));
IContext *context = new IContext;
context->setContext(Context(Constants::C_EDITORMANAGER));
context->setWidget(splitter);
ICore::addContextObject(context);
splitter->show();
ICore::raiseWindow(splitter);
if (newEditor)
......@@ -688,6 +701,7 @@ void EditorManager::splitNewWindow(Internal::EditorView *view)
else
splitter->view()->setFocus();
m_instance->d->m_root.append(splitter);
m_instance->d->m_rootContext.append(context);
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
m_instance->updateActions();
}
......@@ -883,10 +897,15 @@ void EditorManager::rootDestroyed(QObject *root)
SplitterOrView *newActiveRoot = 0;
for (int i = 0; i < d->m_root.size(); ++i) {
SplitterOrView *r = d->m_root.at(i);
if (r == root)
if (r == root) {
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;
}
}
// check if the destroyed root had the current view or current editor
if (d->m_currentEditor || (d->m_currentView && d->m_currentView->parentSplitterOrView() != root))
......
......@@ -212,7 +212,7 @@ public slots:
private slots:
void gotoNextDocHistory();
void gotoPreviousDocHistory();
void handleContextChange(Core::IContext *context);
void handleContextChange(const QList<Core::IContext *> &context);
void updateActions();
void makeCurrentEditorWritable();
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
(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 optionsDialogRequested();
void coreAboutToClose();
void contextAboutToChange(Core::IContext *context);
void contextChanged(Core::IContext *context, const Core::Context &additionalContexts);
void contextAboutToChange(const QList<Core::IContext *> &context);
void contextChanged(const QList<Core::IContext *> &context, const Core::Context &additionalContexts);
};
} // namespace Core
......
......@@ -143,7 +143,6 @@ MainWindow::MainWindow() :
m_navigationWidget(0),
m_rightPaneWidget(0),
m_versionDialog(0),
m_activeContext(0),
m_generalSettings(new GeneralSettings),
m_shortcutSettings(new ShortcutSettings),
m_toolSettings(new ToolSettings),
......@@ -457,7 +456,7 @@ void MainWindow::openDelayedFiles()
IContext *MainWindow::currentContextObject() const
{
return m_activeContext;
return m_activeContext.isEmpty() ? 0 : m_activeContext.first();
}
QStatusBar *MainWindow::statusBar() const
......@@ -1094,8 +1093,8 @@ void MainWindow::removeContextObject(IContext *context)
return;
m_contextWidgets.remove(widget);
if (m_activeContext == context)
updateContextObject(0);
if (m_activeContext.removeAll(context) > 0)
updateContextObject(m_activeContext);
}
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))
return;
IContext *newContext = 0;
QList<IContext *> newContext;
if (QWidget *p = qApp->focusWidget()) {
IContext *context = 0;
while (p) {
context = m_contextWidgets.value(p);
if (context) {
newContext = context;
break;
}
if (context)
newContext.append(context);
p = p->parentWidget();
}
}
// ignore toplevels that define no context, like popups without parent
if (newContext || qApp->focusWidget() == focusWidget())
if (!newContext.isEmpty() || qApp->focusWidget() == focusWidget())
updateContextObject(newContext);
}
void MainWindow::updateContextObject(IContext *context)
void MainWindow::updateContextObject(const QList<IContext *> &context)
{
if (context == m_activeContext)
return;
emit m_coreImpl->contextAboutToChange(context);
m_activeContext = context;
updateContext();
if (debugMainWindow)
qDebug() << "new context object =" << context << (context ? context->widget() : 0)
<< (context ? context->widget()->metaObject()->className() : 0);
}
void MainWindow::resetContext()
{
updateContextObject(0);
if (debugMainWindow) {
qDebug() << "new context objects =" << context;
foreach (IContext *c, context)
qDebug() << (c ? c->widget() : 0) << (c ? c->widget()->metaObject()->className() : 0);
}
}
void MainWindow::aboutToShutdown()
{
disconnect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
this, SLOT(updateFocusWidget(QWidget*,QWidget*)));
m_activeContext = 0;
m_activeContext.clear();
hide();
}
......@@ -1252,8 +1244,8 @@ void MainWindow::updateContext()
{
Context contexts;
if (m_activeContext)
contexts.add(m_activeContext->context());
foreach (IContext *context, m_activeContext)
contexts.add(context->context());
contexts.add(m_additionalContexts);
......
......@@ -94,7 +94,6 @@ public:
IContext *contextObject(QWidget *widget);
void addContextObject(IContext *contex);
void removeContextObject(IContext *contex);
void resetContext();
Core::IDocument *openFiles(const QStringList &fileNames, ICore::OpenFilesFlags flags);
......@@ -164,7 +163,7 @@ private slots:
void openDelayedFiles();
private:
void updateContextObject(IContext *context);
void updateContextObject(const QList<IContext *> &context);
void updateContext();
void registerDefaultContainers();
......@@ -197,7 +196,7 @@ private:
Core::StatusBarWidget *m_outputView;
VersionDialog *m_versionDialog;
IContext *m_activeContext;
QList<IContext *> m_activeContext;
QMap<QWidget *, IContext *> m_contextWidgets;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment