diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index 1bdc864a0743fecbc15846c154cff43cbde5f2c2..db0b96591faf314d8aa7bdbe3c0b9e181e0e8430 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -109,7 +109,7 @@ const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide"; const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow"; const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit"; 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_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72 const char CLOSEALL[] = "QtCreator.CloseAll"; diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 88762f1f29853a3aeeee779375b94cd573db4387..b31a5d131b55d90bcce454d3203170e12e6df42e 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -196,7 +196,7 @@ struct EditorManagerPrivate QAction *m_splitNewWindowAction; QAction *m_removeCurrentSplitAction; QAction *m_removeAllSplitsAction; - QAction *m_gotoOtherSplitAction; + QAction *m_gotoNextSplitAction; QAction *m_saveCurrentEditorContextAction; QAction *m_saveAsCurrentEditorContextAction; @@ -399,11 +399,11 @@ EditorManager::EditorManager(QWidget *parent) : mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); - d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this); - cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); + d->m_gotoNextSplitAction = new QAction(tr("Go to Next Split"), this); + cmd = ActionManager::registerAction(d->m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o"))); 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 *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED); @@ -604,13 +604,20 @@ EditorView *EditorManager::viewForEditor(IEditor *editor) return 0; } -SplitterOrView *EditorManager::findRoot(EditorView *view) +SplitterOrView *EditorManager::findRoot(const EditorView *view, int *rootIndex) { 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(); } - return current; + QTC_CHECK(false); // we should never have views without a root + return 0; } 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); } +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) { Q_ASSERT(view && editor); @@ -1398,11 +1417,8 @@ IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId, 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(); return m_instance->openEditor(m_instance->currentEditorView(), fileName, editorId, flags, newEditor); @@ -1973,7 +1989,7 @@ void EditorManager::updateActions() bool hasSplitter = parentSplitter && parentSplitter->isSplitter(); d->m_removeCurrentSplitAction->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) @@ -2010,7 +2026,8 @@ QList<IEditor*> EditorManager::visibleEditors() const if (view->currentEditor()) editors.append(view->currentEditor()); view = view->findNextView(); - } while (view && view != firstView); + QTC_ASSERT(view != firstView, break); // we start with firstView and shouldn't have cycles + } while (view); } } else { if (root->editor()) @@ -2375,26 +2392,77 @@ void EditorManager::removeAllSplits() 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() { EditorView *view = currentEditorView(); if (!view) return; - SplitterOrView *root = findRoot(view); - QTC_ASSERT(root, return); - if (!root->isSplitter()) - splitSideBySide(); - - view = view->findNextView(); - if (view) { - if (IEditor *editor = view->currentEditor()) { - setCurrentEditor(editor, true); - editor->widget()->setFocus(); - ICore::raiseWindow(editor->widget()); + 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); + // stay in same window if it is split + if (root->isSplitter()) { + nextView = root->findFirstView(); + QTC_CHECK(nextView != view); } 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() diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index 1dabf2f3685ade99819e5d85e3f34ba5e7da18eb..74297304602485be44657a36495a6faf3a7bb90c 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -117,7 +117,7 @@ public: static QString splitLineNumber(QString *fileName); static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(), 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); static IEditor *openEditorWithContents(const Id &editorId, QString *titlePattern = 0, const QString &contents = QString()); @@ -234,6 +234,8 @@ private slots: void rootDestroyed(QObject *root); void setCurrentEditorFromContextChange(); + void gotoNextSplit(); + public slots: void goBackInNavigationHistory(); void goForwardInNavigationHistory(); @@ -257,6 +259,7 @@ private: IEditor *duplicateEditor(IEditor *editor); IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0); void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0); + void activateView(Internal::EditorView *view); IEditor *openEditor(Internal::EditorView *view, const QString &fileName, const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0); @@ -264,7 +267,7 @@ private: void setCurrentView(Internal::EditorView *view); Internal::EditorView *currentEditorView() const; 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 closeDuplicate(IEditor *editor); diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 87e4ecee5aa486f642576ab86d5a601daa20fc82..30cbb9c0233dfb163835f0e76f4b550e4e66a182 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -144,8 +144,8 @@ EditorView *EditorView::findNextView() current = parent; parent = current->findParentSplitter(); } - // current has no parent, so just take the very first view - return current->findFirstView(); + // current has no parent, so we are at the top and there is no "next" view + return 0; } void EditorView::closeView() diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index dd42d6cb7f28b75985caeb633263c8059e32d373..00e6a932378714e8a094aae5f977c094ec51559b 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1994,8 +1994,6 @@ bool CPPEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit) Core::EditorManager *editorManager = Core::EditorManager::instance(); if (inNextSplit) { - if (!editorManager->hasSplitter()) - editorManager->splitSideBySide(); editorManager->gotoOtherSplit(); } else if (baseTextDocument()->fileName() == link.targetFileName) { editorManager->addCurrentPositionToNavigationHistory(); diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 7f70a37640c9cfb21620743049bfeba69d9c3fe5..66e8a6896607ad9a629b6215d92de77eab3a23f2 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -164,7 +164,7 @@ void CppToolsPlugin::switchHeaderSourceInNextSplit() QString otherFile = correspondingHeaderOrSource( Core::EditorManager::currentEditor()->document()->fileName()); if (!otherFile.isEmpty()) - Core::EditorManager::openEditorInNextSplit(otherFile); + Core::EditorManager::openEditorInOtherSplit(otherFile); } static QStringList findFilesInProject(const QString &name, diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 235696eda64dec69e58683f8706855bd3b99b94d..3d9c30356a8e0eb58a95fa42d395ec79b3422aae 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1324,7 +1324,7 @@ void FakeVimPluginPrivate::windowCommand(const QString &map, int count) else if (key == _("S") || key == _("<C-S>")) triggerAction(Core::Constants::SPLIT); 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>")) moveSomewhere(&moveRightWeight, key == _("<S-L>") ? -1 : count); else if (key.contains(_("LEFT")) || key == _("H") || key == _("<S-H>")) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 2b3f5eef3abc420fb741ac12170c7f45130a5ea2..3984a4ca9b7477954cd1218cad95f80467ee47b3 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -4910,8 +4910,6 @@ bool BaseTextEditorWidget::openLink(const Link &link, bool inNextSplit) Core::EditorManager *editorManager = Core::EditorManager::instance(); if (inNextSplit) { - if (!editorManager->hasSplitter()) - editorManager->splitSideBySide(); editorManager->gotoOtherSplit(); } else if (baseTextDocument()->fileName() == link.targetFileName) { editorManager->addCurrentPositionToNavigationHistory();