Cycle through extra editor windows when cycling through splits

Change-Id: I1bd5654d62b11456c35cc5bf1099e41fb3559bc7
Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
Eike Ziller
2013-05-22 16:00:26 +02:00
committed by David Schulz
parent cb00983043
commit 7d986f0486
8 changed files with 103 additions and 36 deletions

View File

@@ -109,7 +109,7 @@ const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide";
const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow"; const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow";
const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit"; const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit";
const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits"; const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits";
const char GOTO_OTHER_SPLIT[] = "QtCreator.GotoOtherSplit"; const char GOTO_NEXT_SPLIT[] = "QtCreator.GotoOtherSplit";
const char CLOSE[] = "QtCreator.Close"; const char CLOSE[] = "QtCreator.Close";
const char CLOSE_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72 const char CLOSE_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72
const char CLOSEALL[] = "QtCreator.CloseAll"; const char CLOSEALL[] = "QtCreator.CloseAll";

View File

@@ -196,7 +196,7 @@ struct EditorManagerPrivate
QAction *m_splitNewWindowAction; QAction *m_splitNewWindowAction;
QAction *m_removeCurrentSplitAction; QAction *m_removeCurrentSplitAction;
QAction *m_removeAllSplitsAction; QAction *m_removeAllSplitsAction;
QAction *m_gotoOtherSplitAction; QAction *m_gotoNextSplitAction;
QAction *m_saveCurrentEditorContextAction; QAction *m_saveCurrentEditorContextAction;
QAction *m_saveAsCurrentEditorContextAction; QAction *m_saveAsCurrentEditorContextAction;
@@ -399,11 +399,11 @@ EditorManager::EditorManager(QWidget *parent) :
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this); d->m_gotoNextSplitAction = new QAction(tr("Go to Next Split"), this);
cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); cmd = ActionManager::registerAction(d->m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit())); connect(d->m_gotoNextSplitAction, SIGNAL(triggered()), this, SLOT(gotoNextSplit()));
ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT); ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT);
ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED); ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED);
@@ -604,13 +604,20 @@ EditorView *EditorManager::viewForEditor(IEditor *editor)
return 0; return 0;
} }
SplitterOrView *EditorManager::findRoot(EditorView *view) SplitterOrView *EditorManager::findRoot(const EditorView *view, int *rootIndex)
{ {
SplitterOrView *current = view->parentSplitterOrView(); SplitterOrView *current = view->parentSplitterOrView();
while (current && !m_instance->d->m_root.contains(current)) { while (current) {
int index = m_instance->d->m_root.indexOf(current);
if (index >= 0) {
if (rootIndex)
*rootIndex = index;
return current;
}
current = current->findParentSplitter(); current = current->findParentSplitter();
} }
return current; QTC_CHECK(false); // we should never have views without a root
return 0;
} }
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
@@ -1151,6 +1158,18 @@ void EditorManager::activateEditorForIndex(Internal::EditorView *view, const QMo
d->m_editorModel->removeEditor(index); d->m_editorModel->removeEditor(index);
} }
void EditorManager::activateView(EditorView *view)
{
QTC_ASSERT(view, return);
if (IEditor *editor = view->currentEditor()) {
setCurrentEditor(editor, true);
editor->widget()->setFocus();
ICore::raiseWindow(editor->widget());
} else {
setCurrentView(view);
}
}
Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor) Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor)
{ {
Q_ASSERT(view && editor); Q_ASSERT(view && editor);
@@ -1398,11 +1417,8 @@ IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId,
fileName, editorId, flags, newEditor); fileName, editorId, flags, newEditor);
} }
IEditor *EditorManager::openEditorInNextSplit(const QString &fileName, const Id &editorId, OpenEditorFlags flags, bool *newEditor) IEditor *EditorManager::openEditorInOtherSplit(const QString &fileName, const Id &editorId, OpenEditorFlags flags, bool *newEditor)
{ {
if (!m_instance->hasSplitter())
m_instance->splitSideBySide();
m_instance->gotoOtherSplit(); m_instance->gotoOtherSplit();
return m_instance->openEditor(m_instance->currentEditorView(), return m_instance->openEditor(m_instance->currentEditorView(),
fileName, editorId, flags, newEditor); fileName, editorId, flags, newEditor);
@@ -1973,7 +1989,7 @@ void EditorManager::updateActions()
bool hasSplitter = parentSplitter && parentSplitter->isSplitter(); bool hasSplitter = parentSplitter && parentSplitter->isSplitter();
d->m_removeCurrentSplitAction->setEnabled(hasSplitter); d->m_removeCurrentSplitAction->setEnabled(hasSplitter);
d->m_removeAllSplitsAction->setEnabled(hasSplitter); d->m_removeAllSplitsAction->setEnabled(hasSplitter);
d->m_gotoOtherSplitAction->setEnabled(hasSplitter); d->m_gotoNextSplitAction->setEnabled(hasSplitter || d->m_root.size() > 1);
} }
void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool enable) void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool enable)
@@ -2010,7 +2026,8 @@ QList<IEditor*> EditorManager::visibleEditors() const
if (view->currentEditor()) if (view->currentEditor())
editors.append(view->currentEditor()); editors.append(view->currentEditor());
view = view->findNextView(); view = view->findNextView();
} while (view && view != firstView); QTC_ASSERT(view != firstView, break); // we start with firstView and shouldn't have cycles
} while (view);
} }
} else { } else {
if (root->editor()) if (root->editor())
@@ -2375,26 +2392,77 @@ void EditorManager::removeAllSplits()
root->unsplitAll(); root->unsplitAll();
} }
/*!
* Moves focus to the next split, cycling through windows.
*/
void EditorManager::gotoNextSplit()
{
EditorView *view = currentEditorView();
if (!view)
return;
EditorView *nextView = view->findNextView();
if (!nextView) {
// we are in the "last" view in this root
int rootIndex = -1;
SplitterOrView *root = findRoot(view, &rootIndex);
QTC_ASSERT(root, return);
QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
// find next root. this might be the same root if there's only one.
int nextRootIndex = rootIndex + 1;
if (nextRootIndex >= d->m_root.size())
nextRootIndex = 0;
nextView = d->m_root.at(nextRootIndex)->findFirstView();
QTC_CHECK(nextView);
}
if (nextView)
activateView(nextView);
}
/*!
* Moves focus to "other" split, possibly creating a split if necessary.
* If there's no split and no other window, a side-by-side split is created.
* If the current window is split, focus is moved to the next split within this window, cycling.
* If the current window is not split, focus is moved to the next window.
*/
void EditorManager::gotoOtherSplit() void EditorManager::gotoOtherSplit()
{ {
EditorView *view = currentEditorView(); EditorView *view = currentEditorView();
if (!view) if (!view)
return; return;
SplitterOrView *root = findRoot(view); EditorView *nextView = view->findNextView();
if (!nextView) {
// we are in the "last" view in this root
int rootIndex = -1;
SplitterOrView *root = findRoot(view, &rootIndex);
QTC_ASSERT(root, return); QTC_ASSERT(root, return);
if (!root->isSplitter()) QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
splitSideBySide(); // stay in same window if it is split
if (root->isSplitter()) {
view = view->findNextView(); nextView = root->findFirstView();
if (view) { QTC_CHECK(nextView != view);
if (IEditor *editor = view->currentEditor()) {
setCurrentEditor(editor, true);
editor->widget()->setFocus();
ICore::raiseWindow(editor->widget());
} else { } else {
setCurrentView(view); // find next root. this might be the same root if there's only one.
int nextRootIndex = rootIndex + 1;
if (nextRootIndex >= d->m_root.size())
nextRootIndex = 0;
nextView = d->m_root.at(nextRootIndex)->findFirstView();
QTC_CHECK(nextView);
// if we had only one root with only one view, we end up at the startpoint
// in that case we need to split
if (nextView == view) {
QTC_CHECK(!root->isSplitter());
splitSideBySide(); // that deletes 'view'
view = root->findFirstView();
nextView = view->findNextView();
QTC_CHECK(nextView != view);
QTC_CHECK(nextView);
} }
} }
}
if (nextView)
activateView(nextView);
} }
qint64 EditorManager::maxTextFileSize() qint64 EditorManager::maxTextFileSize()

View File

@@ -117,7 +117,7 @@ public:
static QString splitLineNumber(QString *fileName); static QString splitLineNumber(QString *fileName);
static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(), static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(),
OpenEditorFlags flags = 0, bool *newEditor = 0); OpenEditorFlags flags = 0, bool *newEditor = 0);
static IEditor *openEditorInNextSplit(const QString &fileName, const Id &editorId = Id(), static IEditor *openEditorInOtherSplit(const QString &fileName, const Id &editorId = Id(),
OpenEditorFlags flags = 0, bool *newEditor = 0); OpenEditorFlags flags = 0, bool *newEditor = 0);
static IEditor *openEditorWithContents(const Id &editorId, static IEditor *openEditorWithContents(const Id &editorId,
QString *titlePattern = 0, const QString &contents = QString()); QString *titlePattern = 0, const QString &contents = QString());
@@ -234,6 +234,8 @@ private slots:
void rootDestroyed(QObject *root); void rootDestroyed(QObject *root);
void setCurrentEditorFromContextChange(); void setCurrentEditorFromContextChange();
void gotoNextSplit();
public slots: public slots:
void goBackInNavigationHistory(); void goBackInNavigationHistory();
void goForwardInNavigationHistory(); void goForwardInNavigationHistory();
@@ -257,6 +259,7 @@ private:
IEditor *duplicateEditor(IEditor *editor); IEditor *duplicateEditor(IEditor *editor);
IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0); IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0);
void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0); void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0);
void activateView(Internal::EditorView *view);
IEditor *openEditor(Internal::EditorView *view, const QString &fileName, IEditor *openEditor(Internal::EditorView *view, const QString &fileName,
const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0); const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0);
@@ -264,7 +267,7 @@ private:
void setCurrentView(Internal::EditorView *view); void setCurrentView(Internal::EditorView *view);
Internal::EditorView *currentEditorView() const; Internal::EditorView *currentEditorView() const;
static Internal::EditorView *viewForEditor(IEditor *editor); static Internal::EditorView *viewForEditor(IEditor *editor);
static Internal::SplitterOrView *findRoot(Internal::EditorView *view); static Internal::SplitterOrView *findRoot(const Internal::EditorView *view, int *rootIndex = 0);
void closeEditor(IEditor *editor); void closeEditor(IEditor *editor);
void closeDuplicate(IEditor *editor); void closeDuplicate(IEditor *editor);

View File

@@ -144,8 +144,8 @@ EditorView *EditorView::findNextView()
current = parent; current = parent;
parent = current->findParentSplitter(); parent = current->findParentSplitter();
} }
// current has no parent, so just take the very first view // current has no parent, so we are at the top and there is no "next" view
return current->findFirstView(); return 0;
} }
void EditorView::closeView() void EditorView::closeView()

View File

@@ -1994,8 +1994,6 @@ bool CPPEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit)
Core::EditorManager *editorManager = Core::EditorManager::instance(); Core::EditorManager *editorManager = Core::EditorManager::instance();
if (inNextSplit) { if (inNextSplit) {
if (!editorManager->hasSplitter())
editorManager->splitSideBySide();
editorManager->gotoOtherSplit(); editorManager->gotoOtherSplit();
} else if (baseTextDocument()->fileName() == link.targetFileName) { } else if (baseTextDocument()->fileName() == link.targetFileName) {
editorManager->addCurrentPositionToNavigationHistory(); editorManager->addCurrentPositionToNavigationHistory();

View File

@@ -164,7 +164,7 @@ void CppToolsPlugin::switchHeaderSourceInNextSplit()
QString otherFile = correspondingHeaderOrSource( QString otherFile = correspondingHeaderOrSource(
Core::EditorManager::currentEditor()->document()->fileName()); Core::EditorManager::currentEditor()->document()->fileName());
if (!otherFile.isEmpty()) if (!otherFile.isEmpty())
Core::EditorManager::openEditorInNextSplit(otherFile); Core::EditorManager::openEditorInOtherSplit(otherFile);
} }
static QStringList findFilesInProject(const QString &name, static QStringList findFilesInProject(const QString &name,

View File

@@ -1324,7 +1324,7 @@ void FakeVimPluginPrivate::windowCommand(const QString &map, int count)
else if (key == _("S") || key == _("<C-S>")) else if (key == _("S") || key == _("<C-S>"))
triggerAction(Core::Constants::SPLIT); triggerAction(Core::Constants::SPLIT);
else if (key == _("W") || key == _("<C-W>")) else if (key == _("W") || key == _("<C-W>"))
triggerAction(Core::Constants::GOTO_OTHER_SPLIT); triggerAction(Core::Constants::GOTO_NEXT_SPLIT);
else if (key.contains(_("RIGHT")) || key == _("L") || key == _("<S-L>")) else if (key.contains(_("RIGHT")) || key == _("L") || key == _("<S-L>"))
moveSomewhere(&moveRightWeight, key == _("<S-L>") ? -1 : count); moveSomewhere(&moveRightWeight, key == _("<S-L>") ? -1 : count);
else if (key.contains(_("LEFT")) || key == _("H") || key == _("<S-H>")) else if (key.contains(_("LEFT")) || key == _("H") || key == _("<S-H>"))

View File

@@ -4910,8 +4910,6 @@ bool BaseTextEditorWidget::openLink(const Link &link, bool inNextSplit)
Core::EditorManager *editorManager = Core::EditorManager::instance(); Core::EditorManager *editorManager = Core::EditorManager::instance();
if (inNextSplit) { if (inNextSplit) {
if (!editorManager->hasSplitter())
editorManager->splitSideBySide();
editorManager->gotoOtherSplit(); editorManager->gotoOtherSplit();
} else if (baseTextDocument()->fileName() == link.targetFileName) { } else if (baseTextDocument()->fileName() == link.targetFileName) {
editorManager->addCurrentPositionToNavigationHistory(); editorManager->addCurrentPositionToNavigationHistory();