Commit 39e9c5ef authored by Petar Perisin's avatar Petar Perisin Committed by David Schulz
Browse files

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: default avatarDavid Schulz <david.schulz@digia.com>
parent c0e7b65d
......@@ -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
......
......@@ -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);
}
}
}
}
......
......@@ -55,6 +55,7 @@
#include <coreplugin/vcsmanager.h>
#include <coreplugin/documentmanager.h>
#include <cppeditor/cppeditorconstants.h>
#include <texteditor/basetexteditor.h>
#include <QtConcurrentRun>
#include <QFutureSynchronizer>
......@@ -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<TextEditor::BaseTextEditorWidget *>(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,
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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
;
}
......
......@@ -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;
};
......
......@@ -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
......
......@@ -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();
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>471</width>
<height>288</height>
<width>501</width>
<height>323</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
......@@ -80,24 +80,27 @@
<string>Display</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="displayLineNumbers">
<item row="4" column="1">
<widget class="QCheckBox" name="highlightMatchingParentheses">
<property name="text">
<string>Display line &amp;numbers</string>
<string>&amp;Highlight matching parentheses</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="highlightCurrentLine">
<item row="2" column="0">
<widget class="QCheckBox" name="markTextChanges">
<property name="text">
<string>Highlight current &amp;line</string>
<string>Mark &amp;text changes</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="displayFoldingMarkers">
<item row="4" column="0">
<widget class="QCheckBox" name="visualizeWhitespace">
<property name="toolTip">
<string>Show tabs and spaces.</string>
</property>
<property name="text">
<string>Display &amp;folding markers</string>
<string>&amp;Visualize whitespace</string>
</property>
</widget>
</item>
......@@ -108,20 +111,24 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="markTextChanges">
<item row="5" column="0">
<widget class="QCheckBox" name="centerOnScroll">
<property name="text">
<string>Mark &amp;text changes</string>
<string>Center &amp;cursor on scroll</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="visualizeWhitespace">
<property name="toolTip">
<string>Show tabs and spaces.</string>
<item row="1" column="0">
<widget class="QCheckBox" name="displayFoldingMarkers">
<property name="text">
<string>Display &amp;folding markers</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="highlightCurrentLine">
<property name="text">
<string>&amp;Visualize whitespace</string>
<string>Highlight current &amp;line</string>
</property>
</widget>
</item>
......@@ -132,27 +139,54 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="centerOnScroll">
<item row="0" column="0">
<widget class="QCheckBox" name="displayLineNumbers">
<property name="text">
<string>Center &amp;cursor on scroll</string>
<string>Display line &amp;numbers</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="0">
<widget class="QCheckBox" name="autoFoldFirstComment">
<property name="text">
<string>Auto-fold first &amp;comment</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="highlightMatchingParentheses">
<item row="5" column="1">
<widget class="QCheckBox" name="openLinksInNextSplit">
<property name="text">
<string>&amp;Highlight matching parentheses</string>
<string>Open Links in Another Split</string>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="forceOpenLinksInNextSplit">
<property name="text">
<string>Force Open Links in Next Split</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
......
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