From 39e9c5ef20df0b75eb8b5a1b27af609fa7ff20e3 Mon Sep 17 00:00:00 2001 From: Petar Perisin Date: Thu, 1 Nov 2012 03:43:28 +0100 Subject: [PATCH] Editor: Allow to open links in a new split. This changes current behavior while opening links. Link is now opened in next split by default. If you use CTRL+Click to open links, it will also open in next split. However, by using CTRL+ALT+click it will open in current split. There are two new checkboxes in Tools/Options/Text Editor/Display: - "Open Links in New Split" - if it is checked, links will not be opened in current split. However, if document with link is already opened, it will be used to open the split - "Force open links in next split" - Links will always open in next split, even if their document is already opened somewhere else. Task-number: QTCREATORBUG-8117 Change-Id: Ib99075b55d9e9683ed2c2386767227457de0a3fc Reviewed-by: David Schulz --- doc/src/editors/creator-coding-edit-mode.qdoc | 14 ++- src/plugins/cppeditor/cppeditor.cpp | 59 ++++++++++- src/plugins/cpptools/cpptoolsplugin.cpp | 28 ++++- src/plugins/texteditor/basetexteditor.cpp | 87 +++++++++++++-- src/plugins/texteditor/basetexteditor.h | 6 ++ src/plugins/texteditor/displaysettings.cpp | 12 ++- src/plugins/texteditor/displaysettings.h | 2 + .../texteditor/displaysettingspage.cpp | 16 ++- src/plugins/texteditor/displaysettingspage.h | 3 + src/plugins/texteditor/displaysettingspage.ui | 100 ++++++++++++------ 10 files changed, 276 insertions(+), 51 deletions(-) diff --git a/doc/src/editors/creator-coding-edit-mode.qdoc b/doc/src/editors/creator-coding-edit-mode.qdoc index ae996910819..c98a3b55e0e 100644 --- a/doc/src/editors/creator-coding-edit-mode.qdoc +++ b/doc/src/editors/creator-coding-edit-mode.qdoc @@ -118,7 +118,9 @@ \section1 Moving to Symbol Definition or Declaration You can move directly to the definition or the declaration of a symbol by - holding the \key Ctrl and clicking the symbol. + holding the \key Ctrl and clicking the symbol. If you have multiple splits + opened, link will be opened in next split. To open it in current split, + hold \key Ctrl and \key Alt while clicking on the symbol. To enable this moving function, in \gui Tools > \gui{Options} > \gui{Text Editor} > \gui Behavior, select \gui{Enable mouse navigation}. @@ -126,11 +128,17 @@ You can also select the symbol and press \key F2, or right-click the symbol and select \gui {Follow Symbol Under Cursor} to move to its definition or declaration. This feature is supported for namespaces, classes, methods, - variables, include statements, and macros. + variables, include statements, and macros. If you have multiple splits + opened, the result will be shown in another split. To switch between the definition and declaration of a symbol, press \key {Shift+F2} or right-click the symbol and select \gui {Switch Between - Method Declaration/Definition}. + Method Declaration/Definition}. If you have multiple splits opened, the + result will be shown in another split. + + Although links are opened in another split by default, this can be disabled + in \gui Tools > \gui{Options} > \gui{Text Editor} > \gui Display, by + unchecking \gui{Open Links in Next Split}. \section1 Using Update Code Model diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index dce4273133e..f7b0b01756a 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1108,6 +1108,8 @@ void CPPEditorWidget::switchDeclarationDefinition() if (! function) function = lastVisibleSymbol->enclosingFunction(); + Core::EditorManager* editorManager = Core::EditorManager::instance(); + if (function) { LookupContext context(thisDocument, snapshot); @@ -1128,12 +1130,61 @@ void CPPEditorWidget::switchDeclarationDefinition() } } } - if (! best.isEmpty()) - openCppEditorAt(linkToSymbol(best.first())); + if (! best.isEmpty()) { + Core::IEditor *editor = editorManager->currentEditor(); + CPPEditorWidget::Link symbolLink = linkToSymbol(best.first()); + if (editorManager->hasSplitter()) { + if (forceOpenLinksInNextSplit()) { + editorManager->gotoOtherSplit(); + } else if (openLinksInNextSplit()) { + bool isVisible = false; + foreach (Core::IEditor *visEditor, editorManager->visibleEditors()) { + if (visEditor->document() && + (symbolLink.fileName == visEditor->document()->fileName()) && + (visEditor != editor)) { + isVisible = true; + editorManager->activateEditor(visEditor); + break; + } + } + + if (!isVisible) + editorManager->gotoOtherSplit(); + } else { + editorManager->addCurrentPositionToNavigationHistory(); + } + } + openCppEditorAt(symbolLink); + } } else if (lastVisibleSymbol && lastVisibleSymbol->isDeclaration() && lastVisibleSymbol->type()->isFunctionType()) { - if (Symbol *def = symbolFinder()->findMatchingDefinition(lastVisibleSymbol, snapshot, true)) - openCppEditorAt(linkToSymbol(def)); + if (Symbol *def = symbolFinder()->findMatchingDefinition(lastVisibleSymbol, snapshot)) { + Core::IEditor *editor = editorManager->currentEditor(); + CPPEditorWidget::Link symbolLink = linkToSymbol(def); + if (editorManager->hasSplitter() && (editor->document()->fileName() != symbolLink.fileName)) { + if (forceOpenLinksInNextSplit()) { + editorManager->gotoOtherSplit(); + } else if (openLinksInNextSplit()) { + bool isVisible = false; + foreach (Core::IEditor *visEditor, editorManager->visibleEditors()) { + if (visEditor->document() && + (symbolLink.fileName == visEditor->document()->fileName()) && + (visEditor != editor)) { + isVisible = true; + editorManager->activateEditor(visEditor); + break; + } + } + + if (!isVisible) + editorManager->gotoOtherSplit(); + } else { + editorManager->addCurrentPositionToNavigationHistory(); + } + } + + openCppEditorAt(symbolLink); + } } } } diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp index 8c9b35d893c..db50b073807 100644 --- a/src/plugins/cpptools/cpptoolsplugin.cpp +++ b/src/plugins/cpptools/cpptoolsplugin.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -158,8 +159,31 @@ void CppToolsPlugin::switchHeaderSource() { Core::IEditor *editor = Core::EditorManager::currentEditor(); QString otherFile = correspondingHeaderOrSource(editor->document()->fileName()); - if (!otherFile.isEmpty()) - Core::EditorManager::openEditor(otherFile); + if (otherFile.isEmpty()) + return; + + Core::EditorManager* editorManager = Core::EditorManager::instance(); + editorManager->addCurrentPositionToNavigationHistory(); + TextEditor::BaseTextEditorWidget *ed = qobject_cast(editor->widget()); + if (editorManager->hasSplitter()) { + if (ed->forceOpenLinksInNextSplit()) { + editorManager->gotoOtherSplit(); + } else if (ed->openLinksInNextSplit()) { + bool isVisible = false; + foreach (Core::IEditor *visEditor, editorManager->visibleEditors()) { + if (visEditor->document() && + (otherFile == visEditor->document()->fileName())) { + isVisible = true; + editorManager->activateEditor(visEditor); + break; + } + } + + if (!isVisible) + editorManager->gotoOtherSplit(); + } + } + Core::EditorManager::openEditor(otherFile); } static QStringList findFilesInProject(const QString &name, diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index dbc908ac3c2..1e718f1187e 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1068,7 +1068,35 @@ void BaseTextEditorWidget::unindent() void BaseTextEditorWidget::openLinkUnderCursor() { - openLink(findLinkAt(textCursor())); + Core::EditorManager* editorManager = Core::EditorManager::instance(); + Link symbolLink = findLinkAt(textCursor()); + + if (!openLinksInNextSplit() || !editorManager->hasSplitter()) { + openLink(symbolLink); + return; + } + + Core::IEditor *editor = Core::EditorManager::currentEditor(); + + if (forceOpenLinksInNextSplit()) { + editorManager->gotoOtherSplit(); + } else { + bool isVisible = false; + foreach (Core::IEditor *visEditor, editorManager->visibleEditors()) { + if (visEditor->document() && + (symbolLink.fileName == visEditor->document()->fileName()) && + (visEditor != editor)) { + isVisible = true; + editorManager->activateEditor(visEditor); + break; + } + } + + if (!isVisible) + editorManager->gotoOtherSplit(); + } + openLink(symbolLink); + editorManager->activateEditor(editor); } void BaseTextEditorWidget::moveLineUpDown(bool up) @@ -2297,6 +2325,26 @@ bool BaseTextEditorWidget::lineNumbersVisible() const return d->m_lineNumbersVisible; } +void BaseTextEditorWidget::setOpenLinksInNextSplit(bool b) +{ + d->m_displaySettings.m_openLinksInNextSplit = b; +} + +bool BaseTextEditorWidget::openLinksInNextSplit() const +{ + return d->m_displaySettings.m_openLinksInNextSplit; +} + +void BaseTextEditorWidget::setForceOpenLinksInNextSplit(bool b) +{ + d->m_displaySettings.m_forceOpenLinksInNextSplit = b; +} + +bool BaseTextEditorWidget::forceOpenLinksInNextSplit() const +{ + return d->m_displaySettings.m_forceOpenLinksInNextSplit; +} + void BaseTextEditorWidget::setMarksVisible(bool b) { d->m_marksVisible = b; @@ -4256,13 +4304,38 @@ void BaseTextEditorWidget::mousePressEvent(QMouseEvent *e) void BaseTextEditorWidget::mouseReleaseEvent(QMouseEvent *e) { if (mouseNavigationEnabled() - && d->m_linkPressed - && e->modifiers() & Qt::ControlModifier - && !(e->modifiers() & Qt::ShiftModifier) - && e->button() == Qt::LeftButton - ) { + && d->m_linkPressed + && e->modifiers() & Qt::ControlModifier + && !(e->modifiers() & Qt::ShiftModifier) + && e->button() == Qt::LeftButton + ) { + + Core::EditorManager* editorManager = Core::EditorManager::instance(); + editorManager->addCurrentPositionToNavigationHistory(); + Core::IEditor *editor = Core::EditorManager::currentEditor(); const QTextCursor cursor = cursorForPosition(e->pos()); - if (openLink(findLinkAt(cursor))) { + Link symbolLink = findLinkAt(cursor); + if (((!(e->modifiers() & Qt::AltModifier)) == openLinksInNextSplit()) && + (editorManager->hasSplitter())) { + if (forceOpenLinksInNextSplit()) { + editorManager->gotoOtherSplit(); + } else { + bool isVisible = false; + foreach (Core::IEditor *visEditor, editorManager->visibleEditors()) + if (visEditor->document() && + (symbolLink.fileName == visEditor->document()->fileName()) && + (editor != visEditor)) { + isVisible = true; + editorManager->activateEditor(visEditor); + break; + } + + if (!isVisible) + editorManager->gotoOtherSplit(); + } + } + + if (openLink(symbolLink)) { clearLink(); return; } diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index a61c30b6d1b..529c7c07401 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -181,6 +181,12 @@ public: void setLineNumbersVisible(bool b); bool lineNumbersVisible() const; + void setOpenLinksInNextSplit(bool b); + bool openLinksInNextSplit() const; + + void setForceOpenLinksInNextSplit(bool b); + bool forceOpenLinksInNextSplit() const; + void setMarksVisible(bool b); bool marksVisible() const; diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp index be5e6f81a95..f453d9b0c35 100644 --- a/src/plugins/texteditor/displaysettings.cpp +++ b/src/plugins/texteditor/displaysettings.cpp @@ -45,6 +45,8 @@ static const char highlightMatchingParenthesesKey[] = "HightlightMatchingParenth static const char markTextChangesKey[] = "MarkTextChanges"; static const char autoFoldFirstCommentKey[] = "AutoFoldFirstComment"; static const char centerCursorOnScrollKey[] = "CenterCursorOnScroll"; +static const char openLinksInNextSplitKey[] = "OpenLinksInNextSplitKey"; +static const char forceOpenLinksInNextSplitKey[] = "ForceOpenLinksInNextSplitKey"; static const char groupPostfix[] = "DisplaySettings"; namespace TextEditor { @@ -62,7 +64,9 @@ DisplaySettings::DisplaySettings() : m_highlightMatchingParentheses(true), m_markTextChanges(true), m_autoFoldFirstComment(true), - m_centerCursorOnScroll(false) + m_centerCursorOnScroll(false), + m_openLinksInNextSplit(true), + m_forceOpenLinksInNextSplit(false) { } @@ -85,6 +89,8 @@ void DisplaySettings::toSettings(const QString &category, QSettings *s) const s->setValue(QLatin1String(markTextChangesKey), m_markTextChanges); s->setValue(QLatin1String(autoFoldFirstCommentKey), m_autoFoldFirstComment); s->setValue(QLatin1String(centerCursorOnScrollKey), m_centerCursorOnScroll); + s->setValue(QLatin1String(openLinksInNextSplitKey), m_openLinksInNextSplit); + s->setValue(QLatin1String(forceOpenLinksInNextSplitKey), m_forceOpenLinksInNextSplit); s->endGroup(); } @@ -110,6 +116,8 @@ void DisplaySettings::fromSettings(const QString &category, const QSettings *s) m_markTextChanges = s->value(group + QLatin1String(markTextChangesKey), m_markTextChanges).toBool(); m_autoFoldFirstComment = s->value(group + QLatin1String(autoFoldFirstCommentKey), m_autoFoldFirstComment).toBool(); m_centerCursorOnScroll = s->value(group + QLatin1String(centerCursorOnScrollKey), m_centerCursorOnScroll).toBool(); + m_openLinksInNextSplit = s->value(group + QLatin1String(openLinksInNextSplitKey), m_openLinksInNextSplit).toBool(); + m_forceOpenLinksInNextSplit = s->value(group + QLatin1String(forceOpenLinksInNextSplitKey), m_forceOpenLinksInNextSplit).toBool(); } bool DisplaySettings::equals(const DisplaySettings &ds) const @@ -127,6 +135,8 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const && m_markTextChanges == ds.m_markTextChanges && m_autoFoldFirstComment== ds.m_autoFoldFirstComment && m_centerCursorOnScroll == ds.m_centerCursorOnScroll + && m_openLinksInNextSplit == ds.m_openLinksInNextSplit + && m_forceOpenLinksInNextSplit == ds.m_forceOpenLinksInNextSplit ; } diff --git a/src/plugins/texteditor/displaysettings.h b/src/plugins/texteditor/displaysettings.h index c64c63f3abf..61e6df3ec7a 100644 --- a/src/plugins/texteditor/displaysettings.h +++ b/src/plugins/texteditor/displaysettings.h @@ -59,6 +59,8 @@ public: bool m_markTextChanges; bool m_autoFoldFirstComment; bool m_centerCursorOnScroll; + bool m_openLinksInNextSplit; + bool m_forceOpenLinksInNextSplit; bool equals(const DisplaySettings &ds) const; }; diff --git a/src/plugins/texteditor/displaysettingspage.cpp b/src/plugins/texteditor/displaysettingspage.cpp index a95c434ba7f..20299357694 100644 --- a/src/plugins/texteditor/displaysettingspage.cpp +++ b/src/plugins/texteditor/displaysettingspage.cpp @@ -74,6 +74,7 @@ QWidget *DisplaySettingsPage::createPage(QWidget *parent) QWidget *w = new QWidget(parent); d->m_page = new Internal::Ui::DisplaySettingsPage; d->m_page->setupUi(w); + connect(d->m_page->openLinksInNextSplit, SIGNAL(toggled(bool)), this, SLOT(updateForceOpenLinksInNextSplit(bool))); settingsToUI(); if (d->m_searchKeywords.isEmpty()) { QTextStream(&d->m_searchKeywords) << d->m_page->displayLineNumbers->text() @@ -85,7 +86,9 @@ QWidget *DisplaySettingsPage::createPage(QWidget *parent) << ' ' << d->m_page->highlightMatchingParentheses->text() << ' ' << d->m_page->enableTextWrapping->text() << ' ' << d->m_page->autoFoldFirstComment->text() - << ' ' << d->m_page->centerOnScroll->text(); + << ' ' << d->m_page->centerOnScroll->text() + << ' ' << d->m_page->openLinksInNextSplit->text() + << ' ' << d->m_page->forceOpenLinksInNextSplit->text(); d->m_searchKeywords.remove(QLatin1Char('&')); } return w; @@ -109,6 +112,13 @@ void DisplaySettingsPage::finish() d->m_page = 0; } +void DisplaySettingsPage::updateForceOpenLinksInNextSplit(bool openLinksInNextSplitChecked) +{ + d->m_page->forceOpenLinksInNextSplit->setEnabled(openLinksInNextSplitChecked); + if (!openLinksInNextSplitChecked) + d->m_page->forceOpenLinksInNextSplit->setChecked(openLinksInNextSplitChecked); +} + void DisplaySettingsPage::settingsFromUI(DisplaySettings &displaySettings) const { displaySettings.m_displayLineNumbers = d->m_page->displayLineNumbers->isChecked(); @@ -124,6 +134,8 @@ void DisplaySettingsPage::settingsFromUI(DisplaySettings &displaySettings) const displaySettings.m_markTextChanges = d->m_page->markTextChanges->isChecked(); displaySettings.m_autoFoldFirstComment = d->m_page->autoFoldFirstComment->isChecked(); displaySettings.m_centerCursorOnScroll = d->m_page->centerOnScroll->isChecked(); + displaySettings.m_openLinksInNextSplit = d->m_page->openLinksInNextSplit->isChecked(); + displaySettings.m_forceOpenLinksInNextSplit = d->m_page->forceOpenLinksInNextSplit->isChecked(); } void DisplaySettingsPage::settingsToUI() @@ -142,6 +154,8 @@ void DisplaySettingsPage::settingsToUI() d->m_page->markTextChanges->setChecked(displaySettings.m_markTextChanges); d->m_page->autoFoldFirstComment->setChecked(displaySettings.m_autoFoldFirstComment); d->m_page->centerOnScroll->setChecked(displaySettings.m_centerCursorOnScroll); + d->m_page->openLinksInNextSplit->setChecked(displaySettings.m_openLinksInNextSplit); + d->m_page->forceOpenLinksInNextSplit->setChecked(displaySettings.m_forceOpenLinksInNextSplit); } const DisplaySettings &DisplaySettingsPage::displaySettings() const diff --git a/src/plugins/texteditor/displaysettingspage.h b/src/plugins/texteditor/displaysettingspage.h index 78f22466bbd..ac0185c2ed4 100644 --- a/src/plugins/texteditor/displaysettingspage.h +++ b/src/plugins/texteditor/displaysettingspage.h @@ -65,6 +65,9 @@ public: signals: void displaySettingsChanged(const TextEditor::DisplaySettings &); +private slots: + void updateForceOpenLinksInNextSplit(bool openLinksInNextSplitChecked); + private: void settingsFromUI(DisplaySettings &displaySettings) const; void settingsToUI(); diff --git a/src/plugins/texteditor/displaysettingspage.ui b/src/plugins/texteditor/displaysettingspage.ui index 6a1f7b46f59..5053a8b103d 100644 --- a/src/plugins/texteditor/displaysettingspage.ui +++ b/src/plugins/texteditor/displaysettingspage.ui @@ -6,8 +6,8 @@ 0 0 - 471 - 288 + 501 + 323 @@ -80,31 +80,10 @@ Display - - + + - Display line &numbers - - - - - - - Highlight current &line - - - - - - - Display &folding markers - - - - - - - Highlight &blocks + &Highlight matching parentheses @@ -125,10 +104,10 @@ - - + + - &Animate matching parentheses + Highlight &blocks @@ -139,20 +118,75 @@ - + + + + Display &folding markers + + + + + + + Highlight current &line + + + + + + + &Animate matching parentheses + + + + + + + Display line &numbers + + + + Auto-fold first &comment - - + + - &Highlight matching parentheses + Open Links in Another Split + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Force Open Links in Next Split + + + + +