SideBySideDiffEditor: Avoid code repetition

Change-Id: Ie49834a4896dbf32a87329345e52dc99ca2f86bd
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-09-29 14:25:34 +02:00
parent 38b19bfae6
commit 2d360db2c3
15 changed files with 207 additions and 305 deletions

View File

@@ -13,6 +13,7 @@ add_qtc_plugin(DiffEditor
diffeditoricons.h
diffeditorplugin.cpp diffeditorplugin.h
diffeditorwidgetcontroller.cpp diffeditorwidgetcontroller.h
diffenums.h
diffutils.cpp diffutils.h
diffview.cpp diffview.h
selectabletexteditorwidget.cpp selectabletexteditorwidget.h

View File

@@ -292,15 +292,11 @@ TextEditorWidget *DiffEditor::unifiedEditorWidget() const
return m_unifiedView->textEditorWidget();
}
TextEditorWidget *DiffEditor::leftEditorWidget() const
TextEditorWidget *DiffEditor::sideEditorWidget(DiffSide side) const
{
return m_sideBySideView->leftEditorWidget();
return m_sideBySideView->sideEditorWidget(side);
}
TextEditorWidget *DiffEditor::rightEditorWidget() const
{
return m_sideBySideView->rightEditorWidget();
}
void DiffEditor::documentHasChanged()
{

View File

@@ -3,6 +3,8 @@
#pragma once
#include "diffenums.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <utils/guard.h>
@@ -38,8 +40,7 @@ public:
QWidget *toolBar() override;
TextEditor::TextEditorWidget *descriptionWidget() const;
TextEditor::TextEditorWidget *unifiedEditorWidget() const;
TextEditor::TextEditorWidget *leftEditorWidget() const;
TextEditor::TextEditorWidget *rightEditorWidget() const;
TextEditor::TextEditorWidget *sideEditorWidget(DiffSide side) const;
private:
DiffEditor();

View File

@@ -32,6 +32,7 @@ QtcPlugin {
"diffeditorplugin.h",
"diffeditorwidgetcontroller.cpp",
"diffeditorwidgetcontroller.h",
"diffenums.h",
"diffutils.cpp",
"diffutils.h",
"diffview.cpp",

View File

@@ -34,13 +34,13 @@ DiffEditorFactory::DiffEditorFactory() :
Constants::DIFF_EDITOR_ID,
Id(Constants::SIDE_BY_SIDE_VIEW_ID).withSuffix(1),
TextEditorActionHandler::None,
[](IEditor *e) { return static_cast<DiffEditor *>(e)->leftEditorWidget(); }
[](IEditor *e) { return static_cast<DiffEditor *>(e)->sideEditorWidget(LeftSide); }
},
rightHandler {
Constants::DIFF_EDITOR_ID,
Id(Constants::SIDE_BY_SIDE_VIEW_ID).withSuffix(2),
TextEditorActionHandler::None,
[](Core::IEditor *e) { return static_cast<DiffEditor *>(e)->rightEditorWidget(); }
[](Core::IEditor *e) { return static_cast<DiffEditor *>(e)->sideEditorWidget(RightSide); }
}
{
setId(Constants::DIFF_EDITOR_ID);

View File

@@ -266,22 +266,16 @@ bool DiffEditorWidgetController::fileNamesAreDifferent(int fileIndex) const
return fileData.fileInfo[LeftSide].fileName != fileData.fileInfo[RightSide].fileName;
}
void DiffEditorWidgetController::addApplyAction(QMenu *menu, int fileIndex, int chunkIndex)
void DiffEditorWidgetController::addApplyRevertAction(QMenu *menu, int fileIndex, int chunkIndex, DiffSide side)
{
QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
connect(applyAction, &QAction::triggered, this, [this, fileIndex, chunkIndex] {
patch(false, fileIndex, chunkIndex);
const QString actionName = side == LeftSide ? tr("Apply Chunk...") : tr("Revert Chunk...");
QAction *action = menu->addAction(actionName);
connect(action, &QAction::triggered, this, [this, fileIndex, chunkIndex, side] {
patch(side == RightSide, fileIndex, chunkIndex);
});
applyAction->setEnabled(chunkExists(fileIndex, chunkIndex) && fileNamesAreDifferent(fileIndex));
}
void DiffEditorWidgetController::addRevertAction(QMenu *menu, int fileIndex, int chunkIndex)
{
QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
connect(revertAction, &QAction::triggered, this, [this, fileIndex, chunkIndex] {
patch(true, fileIndex, chunkIndex);
});
revertAction->setEnabled(chunkExists(fileIndex, chunkIndex));
const bool enabled = chunkExists(fileIndex, chunkIndex)
&& (side == RightSide || fileNamesAreDifferent(fileIndex));
action->setEnabled(enabled);
}
void DiffEditorWidgetController::addExtraActions(QMenu *menu, int fileIndex, int chunkIndex,

View File

@@ -38,8 +38,7 @@ public:
int columnNumber);
void setFontSettings(const TextEditor::FontSettings &fontSettings);
void addCodePasterAction(QMenu *menu, int fileIndex, int chunkIndex);
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
void addApplyRevertAction(QMenu *menu, int fileIndex, int chunkIndex, DiffSide side);
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection);
void updateCannotDecodeInfo();
void setBusyShowing(bool busy);

View File

@@ -0,0 +1,14 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
namespace DiffEditor {
enum DiffSide {
LeftSide,
RightSide,
SideCount // Use only in array declarations
};
} // namespace DiffEditor

View File

@@ -4,6 +4,7 @@
#pragma once
#include "diffeditor_global.h"
#include "diffenums.h"
#include <utils/algorithm.h>
@@ -18,12 +19,6 @@ namespace Utils { class Diff; }
namespace DiffEditor {
enum DiffSide {
LeftSide,
RightSide,
SideCount // Use only in array declarations
};
class DIFFEDITOR_EXPORT DiffFileInfo {
public:
enum PatchBehaviour {

View File

@@ -166,16 +166,10 @@ QWidget *SideBySideView::widget()
return m_widget;
}
TextEditor::TextEditorWidget *SideBySideView::leftEditorWidget()
TextEditor::TextEditorWidget *SideBySideView::sideEditorWidget(DiffSide side)
{
widget(); // ensure widget creation
return m_widget->leftEditorWidget();
}
TextEditor::TextEditorWidget *SideBySideView::rightEditorWidget()
{
widget(); // ensure widget creation
return m_widget->rightEditorWidget();
return m_widget->sideEditorWidget(side);
}
void SideBySideView::setDocument(DiffEditorDocument *document)

View File

@@ -3,6 +3,8 @@
#pragma once
#include "diffenums.h"
#include <utils/id.h>
#include <QIcon>
@@ -95,8 +97,7 @@ public:
SideBySideView();
QWidget *widget() override;
TextEditor::TextEditorWidget *leftEditorWidget();
TextEditor::TextEditorWidget *rightEditorWidget();
TextEditor::TextEditorWidget *sideEditorWidget(DiffSide side);
void setDocument(DiffEditorDocument *document) override;

View File

@@ -32,9 +32,16 @@ using namespace Core;
using namespace TextEditor;
using namespace Utils;
using namespace std::placeholders;
namespace DiffEditor {
namespace Internal {
static DiffSide oppositeSide(DiffSide side)
{
return side == LeftSide ? RightSide : LeftSide;
}
class SideDiffEditorWidget : public SelectableTextEditorWidget
{
Q_OBJECT
@@ -760,61 +767,76 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
: QWidget(parent)
, m_controller(this)
{
m_leftEditor = new SideDiffEditorWidget(this);
m_leftEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_leftEditor->setReadOnly(true);
m_leftEditor->setCodeStyle(TextEditorSettings::codeStyle());
connect(m_leftEditor, &SideDiffEditorWidget::jumpToOriginalFileRequested,
this, &SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested);
connect(m_leftEditor, &SideDiffEditorWidget::contextMenuRequested,
this, &SideBySideDiffEditorWidget::slotLeftContextMenuRequested,
Qt::DirectConnection);
auto setupEditor = [this](DiffSide side) {
m_editor[side] = new SideDiffEditorWidget(this);
m_editor[side]->setReadOnly(true);
m_editor[side]->setCodeStyle(TextEditorSettings::codeStyle());
m_rightEditor = new SideDiffEditorWidget(this);
m_rightEditor->setReadOnly(true);
m_rightEditor->setCodeStyle(TextEditorSettings::codeStyle());
connect(m_rightEditor, &SideDiffEditorWidget::jumpToOriginalFileRequested,
this, &SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested);
connect(m_rightEditor, &SideDiffEditorWidget::contextMenuRequested,
this, &SideBySideDiffEditorWidget::slotRightContextMenuRequested,
Qt::DirectConnection);
connect(m_editor[side], &SideDiffEditorWidget::jumpToOriginalFileRequested,
this, std::bind(&SideBySideDiffEditorWidget::jumpToOriginalFileRequested, this,
side, _1, _2, _3));
connect(m_editor[side], &SideDiffEditorWidget::contextMenuRequested,
this, std::bind(&SideBySideDiffEditorWidget::contextMenuRequested, this,
side, _1, _2, _3, _4));
auto setupHighlightController = [this] {
HighlightScrollBarController *highlightController = m_leftEditor->highlightScrollBarController();
if (highlightController)
highlightController->setScrollArea(m_rightEditor);
connect(m_editor[side]->verticalScrollBar(), &QAbstractSlider::valueChanged,
this, std::bind(&SideBySideDiffEditorWidget::verticalSliderChanged, this, side));
connect(m_editor[side]->verticalScrollBar(), &QAbstractSlider::actionTriggered,
this, std::bind(&SideBySideDiffEditorWidget::verticalSliderChanged, this, side));
connect(m_editor[side]->horizontalScrollBar(), &QAbstractSlider::valueChanged,
this, std::bind(&SideBySideDiffEditorWidget::horizontalSliderChanged, this, side));
connect(m_editor[side]->horizontalScrollBar(), &QAbstractSlider::actionTriggered,
this, std::bind(&SideBySideDiffEditorWidget::horizontalSliderChanged, this, side));
connect(m_editor[side], &QPlainTextEdit::cursorPositionChanged,
this, std::bind(&SideBySideDiffEditorWidget::cursorPositionChanged, this, side));
connect(m_editor[side]->horizontalScrollBar(), &QAbstractSlider::rangeChanged,
this, &SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy);
auto context = new IContext(this);
context->setWidget(m_editor[side]);
context->setContext(Context(Utils::Id(Constants::SIDE_BY_SIDE_VIEW_ID).withSuffix(1)));
ICore::addContextObject(context);
};
setupEditor(LeftSide);
setupEditor(RightSide);
m_editor[LeftSide]->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setupHighlightController();
connect(m_leftEditor, &SideDiffEditorWidget::gotDisplaySettings, this, setupHighlightController);
auto setupHighlight = [this] {
HighlightScrollBarController *ctrl = m_editor[LeftSide]->highlightScrollBarController();
if (ctrl)
ctrl->setScrollArea(m_editor[RightSide]);
};
setupHighlight();
connect(m_editor[LeftSide], &SideDiffEditorWidget::gotDisplaySettings, this, setupHighlight);
m_rightEditor->verticalScrollBar()->setFocusProxy(m_leftEditor);
connect(m_leftEditor, &SideDiffEditorWidget::gotFocus, this, [this] {
if (m_rightEditor->verticalScrollBar()->focusProxy() == m_leftEditor)
m_editor[RightSide]->verticalScrollBar()->setFocusProxy(m_editor[LeftSide]);
connect(m_editor[LeftSide], &SideDiffEditorWidget::gotFocus, this, [this] {
if (m_editor[RightSide]->verticalScrollBar()->focusProxy() == m_editor[LeftSide])
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 #1. If the left editor got a focus last time we don't want to focus right editor
// when clicking the right scrollbar.
m_editor[RightSide]->verticalScrollBar()->setFocusProxy(m_editor[LeftSide]);
// 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.
// 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);
m_editor[RightSide]->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);
// 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_editor[LeftSide]->setFocusPolicy(Qt::StrongFocus);
});
connect(m_rightEditor, &SideDiffEditorWidget::gotFocus, this, [this] {
connect(m_editor[RightSide], &SideDiffEditorWidget::gotFocus, this, [this] {
// Unhack #1.
m_rightEditor->verticalScrollBar()->setFocusProxy(nullptr);
m_editor[RightSide]->verticalScrollBar()->setFocusProxy(nullptr);
// Unhack #2.
m_rightEditor->verticalScrollBar()->setFocusPolicy(Qt::NoFocus);
m_editor[RightSide]->verticalScrollBar()->setFocusPolicy(Qt::NoFocus);
});
connect(TextEditorSettings::instance(),
@@ -822,61 +844,20 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
this, &SideBySideDiffEditorWidget::setFontSettings);
setFontSettings(TextEditorSettings::fontSettings());
connect(m_leftEditor->verticalScrollBar(), &QAbstractSlider::valueChanged,
this, &SideBySideDiffEditorWidget::leftVSliderChanged);
connect(m_leftEditor->verticalScrollBar(), &QAbstractSlider::actionTriggered,
this, &SideBySideDiffEditorWidget::leftVSliderChanged);
connect(m_leftEditor->horizontalScrollBar(), &QAbstractSlider::valueChanged,
this, &SideBySideDiffEditorWidget::leftHSliderChanged);
connect(m_leftEditor->horizontalScrollBar(), &QAbstractSlider::actionTriggered,
this, &SideBySideDiffEditorWidget::leftHSliderChanged);
connect(m_leftEditor, &QPlainTextEdit::cursorPositionChanged,
this, &SideBySideDiffEditorWidget::leftCursorPositionChanged);
connect(m_rightEditor->verticalScrollBar(), &QAbstractSlider::valueChanged,
this, &SideBySideDiffEditorWidget::rightVSliderChanged);
connect(m_rightEditor->verticalScrollBar(), &QAbstractSlider::actionTriggered,
this, &SideBySideDiffEditorWidget::rightVSliderChanged);
connect(m_rightEditor->horizontalScrollBar(), &QAbstractSlider::valueChanged,
this, &SideBySideDiffEditorWidget::rightHSliderChanged);
connect(m_rightEditor->horizontalScrollBar(), &QAbstractSlider::actionTriggered,
this, &SideBySideDiffEditorWidget::rightHSliderChanged);
connect(m_rightEditor, &QPlainTextEdit::cursorPositionChanged,
this, &SideBySideDiffEditorWidget::rightCursorPositionChanged);
connect(m_leftEditor, &SideDiffEditorWidget::foldChanged,
m_rightEditor, &SideDiffEditorWidget::setFolded);
connect(m_rightEditor, &SideDiffEditorWidget::foldChanged,
m_leftEditor, &SideDiffEditorWidget::setFolded);
connect(m_leftEditor->horizontalScrollBar(), &QAbstractSlider::rangeChanged,
this, &SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy);
connect(m_rightEditor->horizontalScrollBar(), &QAbstractSlider::rangeChanged,
this, &SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy);
connect(m_editor[LeftSide], &SideDiffEditorWidget::foldChanged,
m_editor[RightSide], &SideDiffEditorWidget::setFolded);
connect(m_editor[RightSide], &SideDiffEditorWidget::foldChanged,
m_editor[LeftSide], &SideDiffEditorWidget::setFolded);
syncHorizontalScrollBarPolicy();
m_splitter = new MiniSplitter(this);
m_splitter->addWidget(m_leftEditor);
m_splitter->addWidget(m_rightEditor);
m_splitter->addWidget(m_editor[LeftSide]);
m_splitter->addWidget(m_editor[RightSide]);
QVBoxLayout *l = new QVBoxLayout(this);
l->setContentsMargins(0, 0, 0, 0);
l->addWidget(m_splitter);
setFocusProxy(m_leftEditor);
auto leftContext = new IContext(this);
leftContext->setWidget(m_leftEditor);
leftContext->setContext(Core::Context(Utils::Id(Constants::SIDE_BY_SIDE_VIEW_ID).withSuffix(1)));
Core::ICore::addContextObject(leftContext);
auto rightContext = new IContext(this);
rightContext->setWidget(m_rightEditor);
rightContext->setContext(Core::Context(Utils::Id(Constants::SIDE_BY_SIDE_VIEW_ID).withSuffix(2)));
Core::ICore::addContextObject(rightContext);
setFocusProxy(m_editor[LeftSide]);
}
SideBySideDiffEditorWidget::~SideBySideDiffEditorWidget()
@@ -887,14 +868,9 @@ SideBySideDiffEditorWidget::~SideBySideDiffEditorWidget()
}
}
TextEditorWidget *SideBySideDiffEditorWidget::leftEditorWidget() const
TextEditorWidget *SideBySideDiffEditorWidget::sideEditorWidget(DiffSide side) const
{
return m_leftEditor;
}
TextEditorWidget *SideBySideDiffEditorWidget::rightEditorWidget() const
{
return m_rightEditor;
return m_editor[side];
}
void SideBySideDiffEditorWidget::setDocument(DiffEditorDocument *document)
@@ -916,8 +892,8 @@ void SideBySideDiffEditorWidget::clear(const QString &message)
{
const GuardLocker locker(m_controller.m_ignoreChanges);
setDiff({});
m_leftEditor->clearAll(message);
m_rightEditor->clearAll(message);
for (SideDiffEditorWidget *editor : m_editor)
editor->clearAll(message);
if (m_watcher) {
m_watcher->cancel();
DiffEditorPlugin::addFuture(m_watcher->future());
@@ -929,14 +905,14 @@ void SideBySideDiffEditorWidget::clear(const QString &message)
void SideBySideDiffEditorWidget::setDiff(const QList<FileData> &diffFileList)
{
const GuardLocker locker(m_controller.m_ignoreChanges);
m_leftEditor->clearAll(tr("Waiting for data..."));
m_rightEditor->clearAll(tr("Waiting for data..."));
for (SideDiffEditorWidget *editor : m_editor)
editor->clearAll(tr("Waiting for data..."));
m_controller.m_contextFileData = diffFileList;
if (m_controller.m_contextFileData.isEmpty()) {
const QString msg = tr("No difference.");
m_leftEditor->setPlainText(msg);
m_rightEditor->setPlainText(msg);
for (SideDiffEditorWidget *editor : m_editor)
editor->setPlainText(msg);
} else {
showDiff();
}
@@ -947,40 +923,36 @@ void SideBySideDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
if (m_controller.m_ignoreChanges.isLocked())
return;
const int blockNumber = m_leftEditor->diffData().blockNumberForFileIndex(diffFileIndex);
const int blockNumber = m_editor[LeftSide]->diffData().blockNumberForFileIndex(diffFileIndex);
const GuardLocker locker(m_controller.m_ignoreChanges);
m_controller.setCurrentDiffFileIndex(diffFileIndex);
QTextBlock leftBlock = m_leftEditor->document()->findBlockByNumber(blockNumber);
QTextCursor leftCursor = m_leftEditor->textCursor();
leftCursor.setPosition(leftBlock.position());
m_leftEditor->setTextCursor(leftCursor);
m_leftEditor->verticalScrollBar()->setValue(blockNumber);
QTextBlock rightBlock = m_rightEditor->document()->findBlockByNumber(blockNumber);
QTextCursor rightCursor = m_rightEditor->textCursor();
rightCursor.setPosition(rightBlock.position());
m_rightEditor->setTextCursor(rightCursor);
m_rightEditor->verticalScrollBar()->setValue(blockNumber);
for (SideDiffEditorWidget *editor : m_editor) {
QTextBlock block = editor->document()->findBlockByNumber(blockNumber);
QTextCursor cursor = editor->textCursor();
cursor.setPosition(block.position());
editor->setTextCursor(cursor);
editor->verticalScrollBar()->setValue(blockNumber);
}
}
void SideBySideDiffEditorWidget::setHorizontalSync(bool sync)
{
m_horizontalSync = sync;
rightHSliderChanged();
horizontalSliderChanged(RightSide);
}
void SideBySideDiffEditorWidget::saveState()
{
m_leftEditor->saveState();
m_rightEditor->saveState();
for (SideDiffEditorWidget *editor : m_editor)
editor->saveState();
}
void SideBySideDiffEditorWidget::restoreState()
{
m_leftEditor->restoreState();
m_rightEditor->restoreState();
for (SideDiffEditorWidget *editor : m_editor)
editor->restoreState();
}
void SideBySideDiffEditorWidget::showDiff()
@@ -990,12 +962,12 @@ void SideBySideDiffEditorWidget::showDiff()
connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [this] {
if (m_watcher->isCanceled()) {
m_leftEditor->clearAll(tr("Retrieving data failed."));
m_rightEditor->clearAll(tr("Retrieving data failed."));
for (SideDiffEditorWidget *editor : m_editor)
editor->clearAll(tr("Retrieving data failed."));
} else {
const ShowResults results = m_watcher->result();
m_leftEditor->setDiffData(results[LeftSide].diffData);
m_rightEditor->setDiffData(results[RightSide].diffData);
m_editor[LeftSide]->setDiffData(results[LeftSide].diffData);
m_editor[RightSide]->setDiffData(results[RightSide].diffData);
TextDocumentPtr leftDoc(results[LeftSide].textDocument);
TextDocumentPtr rightDoc(results[RightSide].textDocument);
{
@@ -1003,14 +975,14 @@ void SideBySideDiffEditorWidget::showDiff()
// TextDocument was living in no thread, so it's safe to pull it
leftDoc->moveToThread(thread());
rightDoc->moveToThread(thread());
m_leftEditor->setTextDocument(leftDoc);
m_rightEditor->setTextDocument(rightDoc);
m_editor[LeftSide]->setTextDocument(leftDoc);
m_editor[RightSide]->setTextDocument(rightDoc);
m_leftEditor->setReadOnly(true);
m_rightEditor->setReadOnly(true);
m_editor[LeftSide]->setReadOnly(true);
m_editor[RightSide]->setReadOnly(true);
}
m_leftEditor->setSelections(results[LeftSide].selections);
m_rightEditor->setSelections(results[RightSide].selections);
m_editor[LeftSide]->setSelections(results[LeftSide].selections);
m_editor[RightSide]->setSelections(results[RightSide].selections);
setCurrentDiffFileIndex(m_controller.currentDiffFileIndex());
}
m_watcher.release()->deleteLater();
@@ -1091,146 +1063,92 @@ void SideBySideDiffEditorWidget::setFontSettings(const FontSettings &fontSetting
m_controller.setFontSettings(fontSettings);
}
void SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested(
int diffFileIndex,
int lineNumber,
int columnNumber)
void SideBySideDiffEditorWidget::jumpToOriginalFileRequested(DiffSide side, int diffFileIndex,
int lineNumber, int columnNumber)
{
if (diffFileIndex < 0 || diffFileIndex >= m_controller.m_contextFileData.count())
return;
const FileData fileData = m_controller.m_contextFileData.at(diffFileIndex);
const QString leftFileName = fileData.fileInfo[LeftSide].fileName;
const QString rightFileName = fileData.fileInfo[RightSide].fileName;
if (leftFileName == rightFileName) {
// The same file (e.g. in git diff), jump to the line number taken from the right editor.
// Warning: git show SHA^ vs SHA or git diff HEAD vs Index
// (when Working tree has changed in meantime) will not work properly.
for (const ChunkData &chunkData : fileData.chunks) {
const QString fileName = fileData.fileInfo[side].fileName;
const DiffSide otherSide = oppositeSide(side);
const QString otherFileName = fileData.fileInfo[otherSide].fileName;
if (side == RightSide || fileName != otherFileName) {
// different file (e.g. in Tools | Diff...)
m_controller.jumpToOriginalFile(fileName, lineNumber, columnNumber);
return;
}
int leftLineNumber = chunkData.startingLineNumber[LeftSide];
int rightLineNumber = chunkData.startingLineNumber[RightSide];
// The same file (e.g. in git diff), jump to the line number taken from the right editor.
// Warning: git show SHA^ vs SHA or git diff HEAD vs Index
// (when Working tree has changed in meantime) will not work properly.
for (const ChunkData &chunkData : fileData.chunks) {
for (int j = 0; j < chunkData.rows.count(); j++) {
const RowData rowData = chunkData.rows.at(j);
if (rowData.line[LeftSide].textLineType == TextLineData::TextLine)
leftLineNumber++;
if (rowData.line[RightSide].textLineType == TextLineData::TextLine)
rightLineNumber++;
if (leftLineNumber == lineNumber) {
int colNr = rowData.equal ? columnNumber : 0;
m_controller.jumpToOriginalFile(leftFileName, rightLineNumber, colNr);
return;
}
int thisLineNumber = chunkData.startingLineNumber[side];
int otherLineNumber = chunkData.startingLineNumber[otherSide];
for (int j = 0; j < chunkData.rows.count(); j++) {
const RowData rowData = chunkData.rows.at(j);
if (rowData.line[side].textLineType == TextLineData::TextLine)
thisLineNumber++;
if (rowData.line[otherSide].textLineType == TextLineData::TextLine)
otherLineNumber++;
if (thisLineNumber == lineNumber) {
int colNr = rowData.equal ? columnNumber : 0;
m_controller.jumpToOriginalFile(fileName, otherLineNumber, colNr);
return;
}
}
} else {
// different file (e.g. in Tools | Diff...)
m_controller.jumpToOriginalFile(leftFileName, lineNumber, columnNumber);
}
}
void SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested(
int diffFileIndex,
int lineNumber,
int columnNumber)
{
if (diffFileIndex < 0 || diffFileIndex >= m_controller.m_contextFileData.count())
return;
const FileData fileData = m_controller.m_contextFileData.at(diffFileIndex);
const QString fileName = fileData.fileInfo[RightSide].fileName;
m_controller.jumpToOriginalFile(fileName, lineNumber, columnNumber);
}
void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
int fileIndex,
int chunkIndex,
const ChunkSelection &selection)
void SideBySideDiffEditorWidget::contextMenuRequested(DiffSide side, QMenu *menu, int fileIndex,
int chunkIndex, const ChunkSelection &selection)
{
menu->addSeparator();
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
m_controller.addApplyRevertAction(menu, fileIndex, chunkIndex, side);
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
}
void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
int fileIndex,
int chunkIndex,
const ChunkSelection &selection)
{
menu->addSeparator();
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
}
void SideBySideDiffEditorWidget::leftVSliderChanged()
void SideBySideDiffEditorWidget::verticalSliderChanged(DiffSide side)
{
if (m_controller.m_ignoreChanges.isLocked())
return;
m_rightEditor->verticalScrollBar()->setValue(m_leftEditor->verticalScrollBar()->value());
m_editor[oppositeSide(side)]->verticalScrollBar()->setValue(
m_editor[side]->verticalScrollBar()->value());
}
void SideBySideDiffEditorWidget::rightVSliderChanged()
void SideBySideDiffEditorWidget::horizontalSliderChanged(DiffSide side)
{
if (m_controller.m_ignoreChanges.isLocked() || !m_horizontalSync)
return;
m_editor[oppositeSide(side)]->horizontalScrollBar()->setValue(
m_editor[side]->horizontalScrollBar()->value());
}
void SideBySideDiffEditorWidget::cursorPositionChanged(DiffSide side)
{
if (m_controller.m_ignoreChanges.isLocked())
return;
m_leftEditor->verticalScrollBar()->setValue(m_rightEditor->verticalScrollBar()->value());
}
void SideBySideDiffEditorWidget::leftHSliderChanged()
{
if (m_controller.m_ignoreChanges.isLocked())
return;
if (m_horizontalSync)
m_rightEditor->horizontalScrollBar()->setValue(m_leftEditor->horizontalScrollBar()->value());
}
void SideBySideDiffEditorWidget::rightHSliderChanged()
{
if (m_controller.m_ignoreChanges.isLocked())
return;
if (m_horizontalSync)
m_leftEditor->horizontalScrollBar()->setValue(m_rightEditor->horizontalScrollBar()->value());
}
void SideBySideDiffEditorWidget::leftCursorPositionChanged()
{
if (m_controller.m_ignoreChanges.isLocked())
return;
handlePositionChange(m_leftEditor, m_rightEditor);
leftVSliderChanged();
leftHSliderChanged();
}
void SideBySideDiffEditorWidget::rightCursorPositionChanged()
{
if (m_controller.m_ignoreChanges.isLocked())
return;
handlePositionChange(m_rightEditor, m_leftEditor);
rightVSliderChanged();
rightHSliderChanged();
handlePositionChange(m_editor[side], m_editor[oppositeSide(side)]);
verticalSliderChanged(side);
horizontalSliderChanged(side);
}
void SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy()
{
const bool alwaysOn = m_leftEditor->horizontalScrollBar()->maximum()
|| m_rightEditor->horizontalScrollBar()->maximum();
const Qt::ScrollBarPolicy newPolicy = alwaysOn
? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded;
if (m_leftEditor->horizontalScrollBarPolicy() != newPolicy)
m_leftEditor->setHorizontalScrollBarPolicy(newPolicy);
if (m_rightEditor->horizontalScrollBarPolicy() != newPolicy)
m_rightEditor->setHorizontalScrollBarPolicy(newPolicy);
const bool alwaysOn = m_editor[LeftSide]->horizontalScrollBar()->maximum()
|| m_editor[RightSide]->horizontalScrollBar()->maximum();
const Qt::ScrollBarPolicy newPolicy = alwaysOn ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded;
for (SideDiffEditorWidget *editor : m_editor) {
if (editor->horizontalScrollBarPolicy() != newPolicy)
editor->setHorizontalScrollBarPolicy(newPolicy);
}
}
void SideBySideDiffEditorWidget::handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)

View File

@@ -3,6 +3,7 @@
#pragma once
#include "diffenums.h"
#include "diffeditorwidgetcontroller.h"
#include "selectabletexteditorwidget.h" // TODO: we need DiffSelections here only
@@ -94,8 +95,7 @@ public:
explicit SideBySideDiffEditorWidget(QWidget *parent = nullptr);
~SideBySideDiffEditorWidget();
TextEditor::TextEditorWidget *leftEditorWidget() const;
TextEditor::TextEditorWidget *rightEditorWidget() const;
TextEditor::TextEditorWidget *sideEditorWidget(DiffSide side) const;
void setDocument(DiffEditorDocument *document);
DiffEditorDocument *diffDocument() const;
@@ -115,28 +115,20 @@ signals:
private:
void setFontSettings(const TextEditor::FontSettings &fontSettings);
void slotLeftJumpToOriginalFileRequested(int diffFileIndex,
int lineNumber, int columnNumber);
void slotRightJumpToOriginalFileRequested(int diffFileIndex,
int lineNumber, int columnNumber);
void slotLeftContextMenuRequested(QMenu *menu, int fileIndex,
int chunkIndex, const ChunkSelection &selection);
void slotRightContextMenuRequested(QMenu *menu, int fileIndex,
int chunkIndex, const ChunkSelection &selection);
void leftVSliderChanged();
void rightVSliderChanged();
void leftHSliderChanged();
void rightHSliderChanged();
void leftCursorPositionChanged();
void rightCursorPositionChanged();
void jumpToOriginalFileRequested(DiffSide side, int diffFileIndex,
int lineNumber, int columnNumber);
void contextMenuRequested(DiffSide side, QMenu *menu, int fileIndex, int chunkIndex,
const ChunkSelection &selection);
void verticalSliderChanged(DiffSide side);
void horizontalSliderChanged(DiffSide side);
void cursorPositionChanged(DiffSide side);
void syncHorizontalScrollBarPolicy();
void handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
void syncCursor(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
void showDiff();
SideDiffEditorWidget *m_leftEditor = nullptr;
SideDiffEditorWidget *m_rightEditor = nullptr;
std::array<SideDiffEditorWidget *, SideCount> m_editor{};
QSplitter *m_splitter = nullptr;
DiffEditorWidgetController m_controller;

View File

@@ -212,16 +212,14 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
delete menu;
}
void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu,
int fileIndex,
int chunkIndex,
void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu, int fileIndex, int chunkIndex,
const ChunkSelection &selection)
{
menu->addSeparator();
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
m_controller.addApplyRevertAction(menu, fileIndex, chunkIndex, LeftSide);
m_controller.addApplyRevertAction(menu, fileIndex, chunkIndex, RightSide);
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
}

View File

@@ -103,9 +103,7 @@ private:
int fileIndexForBlockNumber(int blockNumber) const;
int chunkIndexForBlockNumber(int blockNumber) const;
void jumpToOriginalFile(const QTextCursor &cursor);
void addContextMenuActions(QMenu *menu,
int fileIndex,
int chunkIndex,
void addContextMenuActions(QMenu *menu, int fileIndex, int chunkIndex,
const ChunkSelection &selection);
UnifiedDiffData m_data;