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(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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user