From b8acf23ec4da9bc889a0eb91401ff6d9380cb5de Mon Sep 17 00:00:00 2001
From: jkobus <jaroslaw.kobus@digia.com>
Date: Wed, 22 May 2013 16:33:44 +0200
Subject: [PATCH] Synchronize horizontal scroll bars in diff editor

Synchronize horizontal scroll bars by default.
Added corner widget to toggle synchronization off.

Change-Id: I52316f1d9399b9ad21a346d65873b37ce0a9b98f
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
---
 src/plugins/diffeditor/diffeditorwidget.cpp | 63 ++++++++++++++++++---
 src/plugins/diffeditor/diffeditorwidget.h   |  8 ++-
 2 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/src/plugins/diffeditor/diffeditorwidget.cpp b/src/plugins/diffeditor/diffeditorwidget.cpp
index 2b0c7bae5ea..f68381adafd 100644
--- a/src/plugins/diffeditor/diffeditorwidget.cpp
+++ b/src/plugins/diffeditor/diffeditorwidget.cpp
@@ -36,6 +36,7 @@
 #include <QScrollBar>
 #include <QPainter>
 #include <QDir>
+#include <QToolButton>
 
 #include <texteditor/basetexteditor.h>
 #include <texteditor/snippets/snippeteditor.h>
@@ -477,10 +478,20 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
     : QWidget(parent),
       m_contextLinesNumber(3),
       m_ignoreWhitespaces(true),
+      m_syncScrollBars(true),
       m_foldingBlocker(false)
 {
     TextEditor::TextEditorSettings *settings = TextEditorSettings::instance();
 
+    QToolButton *toggleSync = new QToolButton();
+    toggleSync = new QToolButton;
+    toggleSync->setText(QLatin1String("S"));
+    toggleSync->setCheckable(true);
+    toggleSync->setChecked(m_syncScrollBars);
+    toggleSync->setToolTip(tr("Synchronize Horizontal Scroll Bars"));
+    toggleSync->setAutoRaise(true);
+    connect(toggleSync, SIGNAL(clicked(bool)), this, SLOT(toggleScrollBarSynchronization(bool)));
+
     m_leftEditor = new DiffViewEditorWidget(this);
     m_leftEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     m_leftEditor->setReadOnly(true);
@@ -490,6 +501,7 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
     m_leftEditor->setCodeStyle(settings->codeStyle());
 
     m_rightEditor = new DiffViewEditorWidget(this);
+    m_rightEditor->setCornerWidget(toggleSync);
     m_rightEditor->setReadOnly(true);
     m_rightEditor->setHighlightCurrentLine(false);
     m_rightEditor->setWordWrapMode(QTextOption::NoWrap);
@@ -497,19 +509,36 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
     m_rightEditor->setCodeStyle(settings->codeStyle());
 
     connect(m_leftEditor->verticalScrollBar(), SIGNAL(valueChanged(int)),
-            this, SLOT(leftSliderChanged()));
+            this, SLOT(leftVSliderChanged()));
     connect(m_leftEditor->verticalScrollBar(), SIGNAL(actionTriggered(int)),
-            this, SLOT(leftSliderChanged()));
+            this, SLOT(leftVSliderChanged()));
+    connect(m_leftEditor, SIGNAL(cursorPositionChanged()),
+            this, SLOT(leftVSliderChanged()));
+
+    connect(m_leftEditor->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+            this, SLOT(leftHSliderChanged()));
+    connect(m_leftEditor->horizontalScrollBar(), SIGNAL(actionTriggered(int)),
+            this, SLOT(leftHSliderChanged()));
     connect(m_leftEditor, SIGNAL(cursorPositionChanged()),
-            this, SLOT(leftSliderChanged()));
+            this, SLOT(leftHSliderChanged()));
+
     connect(m_leftEditor->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)),
             this, SLOT(leftDocumentSizeChanged()));
+
     connect(m_rightEditor->verticalScrollBar(), SIGNAL(valueChanged(int)),
-            this, SLOT(rightSliderChanged()));
+            this, SLOT(rightVSliderChanged()));
     connect(m_rightEditor->verticalScrollBar(), SIGNAL(actionTriggered(int)),
-            this, SLOT(rightSliderChanged()));
+            this, SLOT(rightVSliderChanged()));
     connect(m_rightEditor, SIGNAL(cursorPositionChanged()),
-            this, SLOT(rightSliderChanged()));
+            this, SLOT(rightVSliderChanged()));
+
+    connect(m_rightEditor->horizontalScrollBar(), SIGNAL(valueChanged(int)),
+            this, SLOT(rightHSliderChanged()));
+    connect(m_rightEditor->horizontalScrollBar(), SIGNAL(actionTriggered(int)),
+            this, SLOT(rightHSliderChanged()));
+    connect(m_rightEditor, SIGNAL(cursorPositionChanged()),
+            this, SLOT(rightHSliderChanged()));
+
     connect(m_rightEditor->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)),
             this, SLOT(rightDocumentSizeChanged()));
 
@@ -517,6 +546,7 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
     m_splitter->addWidget(m_leftEditor);
     m_splitter->addWidget(m_rightEditor);
     QVBoxLayout *l = new QVBoxLayout(this);
+    l->setMargin(0);
     l->addWidget(m_splitter);
 
     clear();
@@ -1277,16 +1307,28 @@ void DiffEditorWidget::colorDiff(const QList<FileData> &fileDataList)
                                       + rightSelections);
 }
 
-void DiffEditorWidget::leftSliderChanged()
+void DiffEditorWidget::leftVSliderChanged()
 {
     m_rightEditor->verticalScrollBar()->setValue(m_leftEditor->verticalScrollBar()->value());
 }
 
-void DiffEditorWidget::rightSliderChanged()
+void DiffEditorWidget::rightVSliderChanged()
 {
     m_leftEditor->verticalScrollBar()->setValue(m_rightEditor->verticalScrollBar()->value());
 }
 
+void DiffEditorWidget::leftHSliderChanged()
+{
+    if (m_syncScrollBars)
+        m_rightEditor->horizontalScrollBar()->setValue(m_leftEditor->horizontalScrollBar()->value());
+}
+
+void DiffEditorWidget::rightHSliderChanged()
+{
+    if (m_syncScrollBars)
+        m_leftEditor->horizontalScrollBar()->setValue(m_rightEditor->horizontalScrollBar()->value());
+}
+
 void DiffEditorWidget::leftDocumentSizeChanged()
 {
     synchronizeFoldings(m_leftEditor, m_rightEditor);
@@ -1297,6 +1339,11 @@ void DiffEditorWidget::rightDocumentSizeChanged()
     synchronizeFoldings(m_rightEditor, m_leftEditor);
 }
 
+void DiffEditorWidget::toggleScrollBarSynchronization(bool on)
+{
+    m_syncScrollBars = on;
+}
+
 /* Special version of that method (original: TextEditor::BaseTextDocumentLayout::doFoldOrUnfold())
    The hack lies in fact, that when unfolding all direct sub-blocks are made visible,
    while some of them need to stay invisible (i.e. unfolded chunk lines)
diff --git a/src/plugins/diffeditor/diffeditorwidget.h b/src/plugins/diffeditor/diffeditorwidget.h
index b4e7fe83b4b..eaa71f0495d 100644
--- a/src/plugins/diffeditor/diffeditorwidget.h
+++ b/src/plugins/diffeditor/diffeditorwidget.h
@@ -92,10 +92,13 @@ protected:
     TextEditor::SnippetEditorWidget *rightEditor() const;
 
 private slots:
-    void leftSliderChanged();
-    void rightSliderChanged();
+    void leftVSliderChanged();
+    void rightVSliderChanged();
+    void leftHSliderChanged();
+    void rightHSliderChanged();
     void leftDocumentSizeChanged();
     void rightDocumentSizeChanged();
+    void toggleScrollBarSynchronization(bool on);
 
 private:
     struct DiffList {
@@ -130,6 +133,7 @@ private:
     QList<FileData> m_contextFileData; // ultimate data to be shown, contextLinesNumber taken into account
     int m_contextLinesNumber;
     bool m_ignoreWhitespaces;
+    bool m_syncScrollBars;
 
     bool m_foldingBlocker;
 };
-- 
GitLab