aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/diffeditor
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2017-11-02 13:06:38 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2017-12-12 08:17:58 +0000
commit990da15c1ea8cde669b98430b7f27a13948f0ab8 (patch)
tree4dcb38f2656cae76d1df9f75ca03443f3eea81c8 /src/plugins/diffeditor
parent11d002968ea22c6df041a564a38e929c5ad1d1d2 (diff)
Refactor HighlightScrollBar
Rename it into HighlightScrollBarController. Don't derive it anymore from QScrollBar. Make it based on QObject and decorate the existing instance of QAbstractScrollArea as needed. Fix the highlight of the shared scrollbar of the SideBySideDiffEditor. Both left and right diff editors have their own HighlightScrollBarController and their own separate overlays, but both overlays are created as children of the same right editor instance. Synchronize also the cursor between left and right editors. Make highlight current line working. Make the overlay transparent for mouse events - this fixes issues on macOS when scolling over invisible scrollbar. Change-Id: Iab05c360173e09d8748658c59785da86438a7189 Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/diffeditor')
-rw-r--r--src/plugins/diffeditor/diffeditor.cpp3
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.cpp91
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.h2
-rw-r--r--src/plugins/diffeditor/unifieddiffeditorwidget.cpp3
4 files changed, 79 insertions, 20 deletions
diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp
index 8693d23505..0fbb63f27b 100644
--- a/src/plugins/diffeditor/diffeditor.cpp
+++ b/src/plugins/diffeditor/diffeditor.cpp
@@ -108,7 +108,6 @@ DescriptionEditorWidget::DescriptionEditorWidget(QWidget *parent)
DisplaySettings settings = displaySettings();
settings.m_textWrapping = false;
settings.m_displayLineNumbers = false;
- settings.m_highlightCurrentLine = false;
settings.m_displayFoldingMarkers = false;
settings.m_markTextChanges = false;
settings.m_highlightBlocks = false;
@@ -143,6 +142,8 @@ void DescriptionEditorWidget::setDisplaySettings(const DisplaySettings &ds)
{
DisplaySettings settings = displaySettings();
settings.m_visualizeWhitespace = ds.m_visualizeWhitespace;
+ settings.m_scrollBarHighlights = ds.m_scrollBarHighlights;
+ settings.m_highlightCurrentLine = ds.m_highlightCurrentLine;
TextEditorWidget::setDisplaySettings(settings);
}
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
index cdaad44d0b..f42acfe8da 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
@@ -42,6 +42,7 @@
#include <texteditor/displaysettings.h>
#include <coreplugin/icore.h>
+#include <coreplugin/find/highlightscrollbarcontroller.h>
#include <coreplugin/minisplitter.h>
#include <utils/tooltip/tooltip.h>
@@ -98,6 +99,8 @@ signals:
int diffFileIndex,
int chunkIndex);
void foldChanged(int blockNumber, bool folded);
+ void gotDisplaySettings();
+ void gotFocus();
protected:
int extraAreaWidth(int *markWidthPtr = nullptr) const override {
@@ -124,6 +127,7 @@ protected:
const QTextBlock &block,
QPointF offset,
const QRect &clip) override;
+ void focusInEvent(QFocusEvent *e) override;
private:
void paintSeparator(QPainter &painter, QColor &color, const QString &text,
@@ -158,7 +162,6 @@ SideDiffEditorWidget::SideDiffEditorWidget(QWidget *parent)
DisplaySettings settings = displaySettings();
settings.m_textWrapping = false;
settings.m_displayLineNumbers = true;
- settings.m_highlightCurrentLine = false;
settings.m_markTextChanges = false;
settings.m_highlightBlocks = false;
SelectableTextEditorWidget::setDisplaySettings(settings);
@@ -217,7 +220,10 @@ void SideDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds)
DisplaySettings settings = displaySettings();
settings.m_visualizeWhitespace = ds.m_visualizeWhitespace;
settings.m_displayFoldingMarkers = ds.m_displayFoldingMarkers;
+ settings.m_scrollBarHighlights = ds.m_scrollBarHighlights;
+ settings.m_highlightCurrentLine = ds.m_highlightCurrentLine;
SelectableTextEditorWidget::setDisplaySettings(settings);
+ emit gotDisplaySettings();
}
void SideDiffEditorWidget::applyFontSettings()
@@ -604,6 +610,12 @@ void SideDiffEditorWidget::drawCollapsedBlockPopup(QPainter &painter,
m_drawCollapsedClip = clip;
}
+void SideDiffEditorWidget::focusInEvent(QFocusEvent *e)
+{
+ SelectableTextEditorWidget::focusInEvent(e);
+ emit gotFocus();
+}
+
//////////////////
SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
@@ -613,9 +625,6 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
m_leftEditor = new SideDiffEditorWidget(this);
m_leftEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_leftEditor->setReadOnly(true);
- connect(TextEditorSettings::instance(), &TextEditorSettings::displaySettingsChanged,
- m_leftEditor, &SideDiffEditorWidget::setDisplaySettings);
- m_leftEditor->setDisplaySettings(TextEditorSettings::displaySettings());
m_leftEditor->setCodeStyle(TextEditorSettings::codeStyle());
connect(m_leftEditor, &SideDiffEditorWidget::jumpToOriginalFileRequested,
this, &SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested);
@@ -625,9 +634,6 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
m_rightEditor = new SideDiffEditorWidget(this);
m_rightEditor->setReadOnly(true);
- connect(TextEditorSettings::instance(), &TextEditorSettings::displaySettingsChanged,
- m_rightEditor, &SideDiffEditorWidget::setDisplaySettings);
- m_rightEditor->setDisplaySettings(TextEditorSettings::displaySettings());
m_rightEditor->setCodeStyle(TextEditorSettings::codeStyle());
connect(m_rightEditor, &SideDiffEditorWidget::jumpToOriginalFileRequested,
this, &SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested);
@@ -635,6 +641,44 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
this, &SideBySideDiffEditorWidget::slotRightContextMenuRequested,
Qt::DirectConnection);
+ auto setupHighlightController = [this]() {
+ HighlightScrollBarController *highlightController = m_leftEditor->highlightScrollBarController();
+ if (highlightController)
+ highlightController->setScrollArea(m_rightEditor);
+ };
+
+ setupHighlightController();
+ connect(m_leftEditor, &SideDiffEditorWidget::gotDisplaySettings, setupHighlightController);
+
+ m_rightEditor->verticalScrollBar()->setFocusProxy(m_leftEditor);
+ connect(m_leftEditor, &SideDiffEditorWidget::gotFocus, [this]() {
+ if (m_rightEditor->verticalScrollBar()->focusProxy() == m_leftEditor)
+ return; // We already did it before.
+
+ // Hack #1. If the left editor got a focus last time
+ // we don't want to focus right editor when clicking the right
+ // scrollbar.
+ m_rightEditor->verticalScrollBar()->setFocusProxy(m_leftEditor);
+
+ // Hack #2. If the focus is currently not on the scrollbar's proxy
+ // and we click on the scrollbar, the focus will go to the parent
+ // of the scrollbar. In order to give the focus to the proxy
+ // we need to set a click focus policy on the scrollbar.
+ // See QApplicationPrivate::giveFocusAccordingToFocusPolicy().
+ m_rightEditor->verticalScrollBar()->setFocusPolicy(Qt::ClickFocus);
+
+ // Hack #3. Setting the focus policy is not orthogonal to setting
+ // the focus proxy and unfortuantely it changes the policy of the proxy
+ // too. We bring back the original policy to keep tab focus working.
+ m_leftEditor->setFocusPolicy(Qt::StrongFocus);
+ });
+ connect(m_rightEditor, &SideDiffEditorWidget::gotFocus, [this]() {
+ // Unhack #1.
+ m_rightEditor->verticalScrollBar()->setFocusProxy(nullptr);
+ // Unhack #2.
+ m_rightEditor->verticalScrollBar()->setFocusPolicy(Qt::NoFocus);
+ });
+
connect(TextEditorSettings::instance(),
&TextEditorSettings::fontSettingsChanged,
this, &SideBySideDiffEditorWidget::setFontSettings);
@@ -678,7 +722,7 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
QVBoxLayout *l = new QVBoxLayout(this);
l->setMargin(0);
l->addWidget(m_splitter);
- setFocusProxy(m_rightEditor);
+ setFocusProxy(m_leftEditor);
m_leftContext = new IContext(this);
m_leftContext->setWidget(m_leftEditor);
@@ -1060,32 +1104,43 @@ void SideBySideDiffEditorWidget::leftCursorPositionChanged()
{
leftVSliderChanged();
leftHSliderChanged();
-
- if (m_controller.m_ignoreCurrentIndexChange)
- return;
-
- const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
- m_controller.m_ignoreCurrentIndexChange = true;
- emit currentDiffFileIndexChanged(
- m_leftEditor->fileIndexForBlockNumber(m_leftEditor->textCursor().blockNumber()));
- m_controller.m_ignoreCurrentIndexChange = oldIgnore;
+ handlePositionChange(m_leftEditor, m_rightEditor);
}
void SideBySideDiffEditorWidget::rightCursorPositionChanged()
{
rightVSliderChanged();
rightHSliderChanged();
+ handlePositionChange(m_rightEditor, m_leftEditor);
+}
+void SideBySideDiffEditorWidget::handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)
+{
if (m_controller.m_ignoreCurrentIndexChange)
return;
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
m_controller.m_ignoreCurrentIndexChange = true;
+ syncCursor(source, dest);
emit currentDiffFileIndexChanged(
- m_rightEditor->fileIndexForBlockNumber(m_rightEditor->textCursor().blockNumber()));
+ source->fileIndexForBlockNumber(source->textCursor().blockNumber()));
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
}
+void SideBySideDiffEditorWidget::syncCursor(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)
+{
+ const QTextCursor sourceCursor = source->textCursor();
+ const int sourceLine = sourceCursor.blockNumber();
+ const int sourceColumn = sourceCursor.positionInBlock();
+ QTextCursor destCursor = dest->textCursor();
+ const QTextBlock destBlock = dest->document()->findBlockByNumber(sourceLine);
+ const int destColumn = qMin(sourceColumn, destBlock.length());
+ const int destPosition = destBlock.position() + destColumn;
+ destCursor.setPosition(destPosition);
+ dest->setTextCursor(destCursor);
+
+}
+
} // namespace Internal
} // namespace DiffEditor
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.h b/src/plugins/diffeditor/sidebysidediffeditorwidget.h
index 44f536839b..ba5c8ef550 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.h
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.h
@@ -95,6 +95,8 @@ private:
void rightHSliderChanged();
void leftCursorPositionChanged();
void rightCursorPositionChanged();
+ void handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
+ void syncCursor(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
void showDiff();
diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
index e4f949c63f..dbea4cbfb9 100644
--- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
+++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp
@@ -58,7 +58,6 @@ UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent)
DisplaySettings settings = displaySettings();
settings.m_textWrapping = false;
settings.m_displayLineNumbers = true;
- settings.m_highlightCurrentLine = false;
settings.m_markTextChanges = false;
settings.m_highlightBlocks = false;
SelectableTextEditorWidget::setDisplaySettings(settings);
@@ -133,6 +132,8 @@ void UnifiedDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds)
DisplaySettings settings = displaySettings();
settings.m_visualizeWhitespace = ds.m_visualizeWhitespace;
settings.m_displayFoldingMarkers = ds.m_displayFoldingMarkers;
+ settings.m_scrollBarHighlights = ds.m_scrollBarHighlights;
+ settings.m_highlightCurrentLine = ds.m_highlightCurrentLine;
SelectableTextEditorWidget::setDisplaySettings(settings);
}