forked from qt-creator/qt-creator
Refactor DiffEditorWidgets, introduce common widget controller
Reduce code repetition. Change-Id: I416555dd83ce888088a6a259777c294a6feb35f4 Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
@@ -8,6 +8,7 @@ HEADERS += diffeditor_global.h \
|
||||
diffeditordocument.h \
|
||||
diffeditorfactory.h \
|
||||
diffeditorplugin.h \
|
||||
diffeditorwidgetcontroller.h \
|
||||
differ.h \
|
||||
diffutils.h \
|
||||
diffview.h \
|
||||
@@ -21,6 +22,7 @@ SOURCES += diffeditor.cpp \
|
||||
diffeditordocument.cpp \
|
||||
diffeditorfactory.cpp \
|
||||
diffeditorplugin.cpp \
|
||||
diffeditorwidgetcontroller.cpp \
|
||||
differ.cpp \
|
||||
diffutils.cpp \
|
||||
diffview.cpp \
|
||||
|
||||
@@ -28,6 +28,8 @@ QtcPlugin {
|
||||
"diffeditorfactory.h",
|
||||
"diffeditorplugin.cpp",
|
||||
"diffeditorplugin.h",
|
||||
"diffeditorwidgetcontroller.cpp",
|
||||
"diffeditorwidgetcontroller.h",
|
||||
"differ.cpp",
|
||||
"differ.h",
|
||||
"diffutils.cpp",
|
||||
|
||||
209
src/plugins/diffeditor/diffeditorwidgetcontroller.cpp
Normal file
209
src/plugins/diffeditor/diffeditorwidgetcontroller.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
#include "diffeditorconstants.h"
|
||||
#include "diffeditordocument.h"
|
||||
|
||||
#include <coreplugin/patchtool.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <texteditor/fontsettings.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <cpaster/codepasterservice.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QTextCodec>
|
||||
|
||||
using namespace Core;
|
||||
using namespace TextEditor;
|
||||
|
||||
namespace DiffEditor {
|
||||
namespace Internal {
|
||||
|
||||
DiffEditorWidgetController::DiffEditorWidgetController(QWidget *diffEditorWidget)
|
||||
: QObject(diffEditorWidget)
|
||||
, m_diffEditorWidget(diffEditorWidget)
|
||||
{
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::setDocument(DiffEditorDocument *document)
|
||||
{
|
||||
m_document = document;
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::patch(bool revert)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const QString title = revert ? tr("Revert Chunk") : tr("Apply Chunk");
|
||||
const QString question = revert
|
||||
? tr("Would you like to revert the chunk?")
|
||||
: tr("Would you like to apply the chunk?");
|
||||
if (QMessageBox::No == QMessageBox::question(m_diffEditorWidget, title,
|
||||
question,
|
||||
QMessageBox::Yes
|
||||
| QMessageBox::No)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
const QString fileName = revert
|
||||
? fileData.rightFileInfo.fileName
|
||||
: fileData.leftFileInfo.fileName;
|
||||
|
||||
const QString workingDirectory = m_document->baseDirectory().isEmpty()
|
||||
? QFileInfo(fileName).absolutePath()
|
||||
: m_document->baseDirectory();
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, revert);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
if (PatchTool::runPatch(EditorManager::defaultTextCodec()->fromUnicode(patch),
|
||||
workingDirectory, strip, revert))
|
||||
m_document->reload();
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::jumpToOriginalFile(const QString &fileName,
|
||||
int lineNumber,
|
||||
int columnNumber)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const QDir dir(m_document->baseDirectory());
|
||||
const QString absoluteFileName = dir.absoluteFilePath(fileName);
|
||||
const QFileInfo fi(absoluteFileName);
|
||||
if (fi.exists() && !fi.isDir())
|
||||
EditorManager::openEditorAt(absoluteFileName, lineNumber, columnNumber);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::setFontSettings(const FontSettings &fontSettings)
|
||||
{
|
||||
m_fileLineFormat = fontSettings.toTextCharFormat(C_DIFF_FILE_LINE);
|
||||
m_chunkLineFormat = fontSettings.toTextCharFormat(C_DIFF_CONTEXT_LINE);
|
||||
m_leftLineFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_LINE);
|
||||
m_leftCharFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_CHAR);
|
||||
m_rightLineFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_LINE);
|
||||
m_rightCharFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_CHAR);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addCodePasterAction(QMenu *menu)
|
||||
{
|
||||
if (ExtensionSystem::PluginManager::getObject<CodePaster::Service>()) {
|
||||
// optional code pasting service
|
||||
QAction *sendChunkToCodePasterAction = menu->addAction(tr("Send Chunk to CodePaster..."));
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered,
|
||||
this, &DiffEditorWidgetController::slotSendChunkToCodePaster);
|
||||
}
|
||||
}
|
||||
|
||||
bool DiffEditorWidgetController::setAndVerifyIndexes(QMenu *menu,
|
||||
int diffFileIndex, int chunkIndex)
|
||||
{
|
||||
if (!m_document)
|
||||
return false;
|
||||
|
||||
m_contextMenuFileIndex = diffFileIndex;
|
||||
m_contextMenuChunkIndex = chunkIndex;
|
||||
|
||||
if (m_contextMenuFileIndex < 0 || m_contextMenuChunkIndex < 0)
|
||||
return false;
|
||||
|
||||
if (m_contextMenuFileIndex >= m_contextFileData.count())
|
||||
return false;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
if (m_contextMenuChunkIndex >= fileData.chunks.count())
|
||||
return false;
|
||||
|
||||
m_document->chunkActionsRequested(menu, diffFileIndex, chunkIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DiffEditorWidgetController::fileNamesAreDifferent() const
|
||||
{
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
return fileData.leftFileInfo.fileName != fileData.rightFileInfo.fileName;
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addApplyAction(QMenu *menu, int diffFileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
|
||||
connect(applyAction, &QAction::triggered, this, &DiffEditorWidgetController::slotApplyChunk);
|
||||
applyAction->setEnabled(setAndVerifyIndexes(menu, diffFileIndex, chunkIndex)
|
||||
&& fileNamesAreDifferent());
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addRevertAction(QMenu *menu, int diffFileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
|
||||
connect(revertAction, &QAction::triggered, this, &DiffEditorWidgetController::slotRevertChunk);
|
||||
revertAction->setEnabled(setAndVerifyIndexes(menu, diffFileIndex, chunkIndex));
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotSendChunkToCodePaster()
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
// Retrieve service by soft dependency.
|
||||
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
||||
QTC_ASSERT(pasteService, return);
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, false);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
pasteService->postText(patch, QLatin1String(Constants::DIFF_EDITOR_MIMETYPE));
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotApplyChunk()
|
||||
{
|
||||
patch(false);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotRevertChunk()
|
||||
{
|
||||
patch(true);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace DiffEditor
|
||||
86
src/plugins/diffeditor/diffeditorwidgetcontroller.h
Normal file
86
src/plugins/diffeditor/diffeditorwidgetcontroller.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "diffutils.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QTextCharFormat>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QMenu)
|
||||
|
||||
namespace Core { class IDocument; }
|
||||
namespace TextEditor { class FontSettings; }
|
||||
|
||||
namespace DiffEditor {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class DiffEditorDocument;
|
||||
|
||||
class DiffEditorWidgetController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DiffEditorWidgetController(QWidget *diffEditorWidget);
|
||||
|
||||
void setDocument(DiffEditorDocument *document);
|
||||
|
||||
void patch(bool revert);
|
||||
void jumpToOriginalFile(const QString &fileName, int lineNumber,
|
||||
int columnNumber);
|
||||
void setFontSettings(const TextEditor::FontSettings &fontSettings);
|
||||
void addCodePasterAction(QMenu *menu);
|
||||
void addApplyAction(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
void addRevertAction(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
|
||||
bool m_ignoreCurrentIndexChange = false;
|
||||
QList<FileData> m_contextFileData; // ultimate data to be shown
|
||||
// contextLineCount taken into account
|
||||
QTextCharFormat m_fileLineFormat;
|
||||
QTextCharFormat m_chunkLineFormat;
|
||||
QTextCharFormat m_leftLineFormat;
|
||||
QTextCharFormat m_rightLineFormat;
|
||||
QTextCharFormat m_leftCharFormat;
|
||||
QTextCharFormat m_rightCharFormat;
|
||||
|
||||
private:
|
||||
void slotSendChunkToCodePaster();
|
||||
void slotApplyChunk();
|
||||
void slotRevertChunk();
|
||||
bool setAndVerifyIndexes(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
bool fileNamesAreDifferent() const;
|
||||
|
||||
QWidget *m_diffEditorWidget;
|
||||
|
||||
DiffEditorDocument *m_document = nullptr;
|
||||
|
||||
int m_contextMenuFileIndex = -1;
|
||||
int m_contextMenuChunkIndex = -1;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace DiffEditor
|
||||
@@ -27,35 +27,21 @@
|
||||
#include "selectabletexteditorwidget.h"
|
||||
#include "diffeditordocument.h"
|
||||
#include "diffutils.h"
|
||||
#include "diffeditorconstants.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <QTextBlock>
|
||||
#include <QTextCodec>
|
||||
#include <QScrollBar>
|
||||
#include <QPainter>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/textdocumentlayout.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/textdocumentlayout.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/displaysettings.h>
|
||||
#include <texteditor/highlighterutils.h>
|
||||
|
||||
#include <coreplugin/minisplitter.h>
|
||||
#include <coreplugin/patchtool.h>
|
||||
|
||||
#include <cpaster/codepasterservice.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
|
||||
using namespace Core;
|
||||
@@ -136,7 +122,7 @@ private:
|
||||
|
||||
// block number, visual line number.
|
||||
QMap<int, int> m_lineNumbers;
|
||||
int m_lineNumberDigits;
|
||||
int m_lineNumberDigits = 1;
|
||||
// block number, fileInfo. Set for file lines only.
|
||||
QMap<int, DiffFileInfo> m_fileInfo;
|
||||
// block number, skipped lines. Set for chunk lines only.
|
||||
@@ -145,7 +131,7 @@ private:
|
||||
QMap<int, QPair<int, int> > m_chunkInfo;
|
||||
// block number, separator. Set for file, chunk or span line.
|
||||
QMap<int, bool> m_separators;
|
||||
bool m_inPaintEvent;
|
||||
bool m_inPaintEvent = false;
|
||||
QColor m_fileLineForeground;
|
||||
QColor m_chunkLineForeground;
|
||||
QColor m_textForeground;
|
||||
@@ -153,9 +139,7 @@ private:
|
||||
};
|
||||
|
||||
SideDiffEditorWidget::SideDiffEditorWidget(QWidget *parent)
|
||||
: SelectableTextEditorWidget("DiffEditor.SideDiffEditor", parent),
|
||||
m_lineNumberDigits(1),
|
||||
m_inPaintEvent(false)
|
||||
: SelectableTextEditorWidget("DiffEditor.SideDiffEditor", parent)
|
||||
{
|
||||
DisplaySettings settings = displaySettings();
|
||||
settings.m_textWrapping = false;
|
||||
@@ -439,11 +423,11 @@ void SideDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
||||
return;
|
||||
|
||||
const int blockNumber = cursor.blockNumber();
|
||||
const int columnNumber = cursor.positionInBlock();
|
||||
if (!m_lineNumbers.contains(blockNumber))
|
||||
return;
|
||||
|
||||
const int lineNumber = m_lineNumbers.value(blockNumber);
|
||||
const int columnNumber = cursor.positionInBlock();
|
||||
|
||||
emit jumpToOriginalFileRequested(fileIndexForBlockNumber(blockNumber),
|
||||
lineNumber, columnNumber);
|
||||
@@ -506,12 +490,7 @@ void SideDiffEditorWidget::paintEvent(QPaintEvent *e)
|
||||
|
||||
SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_document(0)
|
||||
, m_ignoreCurrentIndexChange(false)
|
||||
, m_foldingBlocker(false)
|
||||
, m_horizontalSync(false)
|
||||
, m_contextMenuFileIndex(-1)
|
||||
, m_contextMenuChunkIndex(-1)
|
||||
, m_controller(this)
|
||||
{
|
||||
m_leftEditor = new SideDiffEditorWidget(this);
|
||||
m_leftEditor->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@@ -582,17 +561,17 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
|
||||
|
||||
void SideBySideDiffEditorWidget::setDocument(DiffEditorDocument *document)
|
||||
{
|
||||
m_document = document;
|
||||
m_controller.setDocument(document);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::clear(const QString &message)
|
||||
{
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
setDiff(QList<FileData>(), QString());
|
||||
m_leftEditor->clearAll(message);
|
||||
m_rightEditor->clearAll(message);
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::setDiff(const QList<FileData> &diffFileList,
|
||||
@@ -600,31 +579,31 @@ void SideBySideDiffEditorWidget::setDiff(const QList<FileData> &diffFileList,
|
||||
{
|
||||
Q_UNUSED(workingDirectory)
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
m_leftEditor->clear();
|
||||
m_rightEditor->clear();
|
||||
|
||||
m_contextFileData = diffFileList;
|
||||
if (m_contextFileData.isEmpty()) {
|
||||
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);
|
||||
} else {
|
||||
showDiff();
|
||||
}
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
|
||||
{
|
||||
if (m_ignoreCurrentIndexChange)
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
const int blockNumber = m_leftEditor->blockNumberForFileIndex(diffFileIndex);
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
QTextBlock leftBlock = m_leftEditor->document()->findBlockByNumber(blockNumber);
|
||||
QTextCursor leftCursor = m_leftEditor->textCursor();
|
||||
leftCursor.setPosition(leftBlock.position());
|
||||
@@ -637,7 +616,7 @@ void SideBySideDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
|
||||
m_rightEditor->setTextCursor(rightCursor);
|
||||
m_rightEditor->verticalScrollBar()->setValue(blockNumber);
|
||||
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::setHorizontalSync(bool sync)
|
||||
@@ -666,12 +645,12 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
QString leftTexts, rightTexts;
|
||||
int blockNumber = 0;
|
||||
QChar separator = QLatin1Char('\n');
|
||||
for (int i = 0; i < m_contextFileData.count(); i++) {
|
||||
for (int i = 0; i < m_controller.m_contextFileData.count(); i++) {
|
||||
QString leftText, rightText;
|
||||
const FileData &contextFileData = m_contextFileData.at(i);
|
||||
const FileData &contextFileData = m_controller.m_contextFileData.at(i);
|
||||
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_fileLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_fileLineFormat));
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_controller.m_fileLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_controller.m_fileLineFormat));
|
||||
m_leftEditor->setFileInfo(blockNumber, contextFileData.leftFileInfo);
|
||||
m_rightEditor->setFileInfo(blockNumber, contextFileData.rightFileInfo);
|
||||
leftText = separator;
|
||||
@@ -681,8 +660,8 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
int lastLeftLineNumber = -1;
|
||||
|
||||
if (contextFileData.binaryFiles) {
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
m_leftEditor->setSkippedLines(blockNumber, -2);
|
||||
m_rightEditor->setSkippedLines(blockNumber, -2);
|
||||
leftText += separator;
|
||||
@@ -698,8 +677,8 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
if (!chunkData.contextChunk) {
|
||||
const int skippedLines = leftLineNumber - lastLeftLineNumber - 1;
|
||||
if (skippedLines > 0) {
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
m_leftEditor->setSkippedLines(blockNumber, skippedLines);
|
||||
m_rightEditor->setSkippedLines(blockNumber, skippedLines);
|
||||
leftText += separator;
|
||||
@@ -733,11 +712,11 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
|
||||
if (!rowData.equal) {
|
||||
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_leftLineFormat));
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_controller.m_leftLineFormat));
|
||||
else
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_spanLineFormat));
|
||||
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_rightLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_controller.m_rightLineFormat));
|
||||
else
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_spanLineFormat));
|
||||
}
|
||||
@@ -747,7 +726,7 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
itLeft.next();
|
||||
leftFormats[blockNumber].append(
|
||||
DiffSelection(itLeft.key(), itLeft.value(),
|
||||
&m_leftCharFormat));
|
||||
&m_controller.m_leftCharFormat));
|
||||
}
|
||||
|
||||
QMapIterator<int, int> itRight(rightLineData.changedPositions);
|
||||
@@ -755,7 +734,7 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
itRight.next();
|
||||
rightFormats[blockNumber].append(
|
||||
DiffSelection(itRight.key(), itRight.value(),
|
||||
&m_rightCharFormat));
|
||||
&m_controller.m_rightCharFormat));
|
||||
}
|
||||
|
||||
leftText += separator;
|
||||
@@ -777,8 +756,8 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
}
|
||||
|
||||
if (skippedLines >= -1) {
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
leftFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
rightFormats[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
m_leftEditor->setSkippedLines(blockNumber, skippedLines);
|
||||
m_rightEditor->setSkippedLines(blockNumber, skippedLines);
|
||||
leftText += separator;
|
||||
@@ -797,13 +776,13 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
if (leftTexts.isEmpty() && rightTexts.isEmpty())
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
m_leftEditor->clear();
|
||||
m_leftEditor->setPlainText(leftTexts);
|
||||
m_rightEditor->clear();
|
||||
m_rightEditor->setPlainText(rightTexts);
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
|
||||
m_leftEditor->setSelections(leftFormats);
|
||||
m_rightEditor->setSelections(rightFormats);
|
||||
@@ -813,12 +792,7 @@ void SideBySideDiffEditorWidget::setFontSettings(
|
||||
const FontSettings &fontSettings)
|
||||
{
|
||||
m_spanLineFormat = fontSettings.toTextCharFormat(C_LINE_NUMBER);
|
||||
m_fileLineFormat = fontSettings.toTextCharFormat(C_DIFF_FILE_LINE);
|
||||
m_chunkLineFormat = fontSettings.toTextCharFormat(C_DIFF_CONTEXT_LINE);
|
||||
m_leftLineFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_LINE);
|
||||
m_leftCharFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_CHAR);
|
||||
m_rightLineFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_LINE);
|
||||
m_rightCharFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_CHAR);
|
||||
m_controller.setFontSettings(fontSettings);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested(
|
||||
@@ -826,10 +800,10 @@ void SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested(
|
||||
int lineNumber,
|
||||
int columnNumber)
|
||||
{
|
||||
if (diffFileIndex < 0 || diffFileIndex >= m_contextFileData.count())
|
||||
if (diffFileIndex < 0 || diffFileIndex >= m_controller.m_contextFileData.count())
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(diffFileIndex);
|
||||
const FileData fileData = m_controller.m_contextFileData.at(diffFileIndex);
|
||||
const QString leftFileName = fileData.leftFileInfo.fileName;
|
||||
const QString rightFileName = fileData.rightFileInfo.fileName;
|
||||
if (leftFileName == rightFileName) {
|
||||
@@ -850,14 +824,14 @@ void SideBySideDiffEditorWidget::slotLeftJumpToOriginalFileRequested(
|
||||
rightLineNumber++;
|
||||
if (leftLineNumber == lineNumber) {
|
||||
int colNr = rowData.equal ? columnNumber : 0;
|
||||
jumpToOriginalFile(leftFileName, rightLineNumber, colNr);
|
||||
m_controller.jumpToOriginalFile(leftFileName, rightLineNumber, colNr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// different file (e.g. in Tools | Diff...)
|
||||
jumpToOriginalFile(leftFileName, lineNumber, columnNumber);
|
||||
m_controller.jumpToOriginalFile(leftFileName, lineNumber, columnNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -866,25 +840,12 @@ void SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested(
|
||||
int lineNumber,
|
||||
int columnNumber)
|
||||
{
|
||||
if (diffFileIndex < 0 || diffFileIndex >= m_contextFileData.count())
|
||||
if (diffFileIndex < 0 || diffFileIndex >= m_controller.m_contextFileData.count())
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(diffFileIndex);
|
||||
const FileData fileData = m_controller.m_contextFileData.at(diffFileIndex);
|
||||
const QString fileName = fileData.rightFileInfo.fileName;
|
||||
jumpToOriginalFile(fileName, lineNumber, columnNumber);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::jumpToOriginalFile(const QString &fileName,
|
||||
int lineNumber, int columnNumber)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const QDir dir(m_document->baseDirectory());
|
||||
const QString absoluteFileName = dir.absoluteFilePath(fileName);
|
||||
QFileInfo fi(absoluteFileName);
|
||||
if (fi.exists() && !fi.isDir())
|
||||
EditorManager::openEditorAt(absoluteFileName, lineNumber, columnNumber);
|
||||
m_controller.jumpToOriginalFile(fileName, lineNumber, columnNumber);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
|
||||
@@ -892,37 +853,9 @@ void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
|
||||
int chunkIndex)
|
||||
{
|
||||
menu->addSeparator();
|
||||
if (ExtensionSystem::PluginManager::getObject<CodePaster::Service>()) {
|
||||
// optional code pasting service
|
||||
QAction *sendChunkToCodePasterAction =
|
||||
menu->addAction(tr("Send Chunk to CodePaster..."));
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered,
|
||||
this, &SideBySideDiffEditorWidget::slotSendChunkToCodePaster);
|
||||
menu->addSeparator();
|
||||
}
|
||||
QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
|
||||
connect(applyAction, &QAction::triggered, this, &SideBySideDiffEditorWidget::slotApplyChunk);
|
||||
applyAction->setEnabled(false);
|
||||
|
||||
m_contextMenuFileIndex = diffFileIndex;
|
||||
m_contextMenuChunkIndex = chunkIndex;
|
||||
|
||||
if (m_contextMenuFileIndex < 0 || m_contextMenuChunkIndex < 0)
|
||||
return;
|
||||
|
||||
if (m_contextMenuFileIndex >= m_contextFileData.count())
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
if (m_contextMenuChunkIndex >= fileData.chunks.count())
|
||||
return;
|
||||
|
||||
m_document->chunkActionsRequested(menu, diffFileIndex, chunkIndex);
|
||||
|
||||
if (fileData.leftFileInfo.fileName == fileData.rightFileInfo.fileName)
|
||||
return;
|
||||
|
||||
applyAction->setEnabled(true);
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addApplyAction(menu, diffFileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
|
||||
@@ -930,98 +863,9 @@ void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
|
||||
int chunkIndex)
|
||||
{
|
||||
menu->addSeparator();
|
||||
if (ExtensionSystem::PluginManager::getObject<CodePaster::Service>()) {
|
||||
// optional code pasting service
|
||||
QAction *sendChunkToCodePasterAction =
|
||||
menu->addAction(tr("Send Chunk to CodePaster..."));
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered,
|
||||
this, &SideBySideDiffEditorWidget::slotSendChunkToCodePaster);
|
||||
menu->addSeparator();
|
||||
}
|
||||
QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
|
||||
connect(revertAction, &QAction::triggered, this, &SideBySideDiffEditorWidget::slotRevertChunk);
|
||||
revertAction->setEnabled(false);
|
||||
|
||||
m_contextMenuFileIndex = diffFileIndex;
|
||||
m_contextMenuChunkIndex = chunkIndex;
|
||||
|
||||
if (m_contextMenuFileIndex < 0 || m_contextMenuChunkIndex < 0)
|
||||
return;
|
||||
|
||||
if (m_contextMenuFileIndex >= m_contextFileData.count())
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
if (m_contextMenuChunkIndex >= fileData.chunks.count())
|
||||
return;
|
||||
|
||||
m_document->chunkActionsRequested(menu, diffFileIndex, chunkIndex);
|
||||
|
||||
revertAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotSendChunkToCodePaster()
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
// Retrieve service by soft dependency.
|
||||
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
||||
QTC_ASSERT(pasteService, return);
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, false);
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
pasteService->postText(patch, QLatin1String(Constants::DIFF_EDITOR_MIMETYPE));
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotApplyChunk()
|
||||
{
|
||||
patch(false);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotRevertChunk()
|
||||
{
|
||||
patch(true);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::patch(bool revert)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
|
||||
const QString title = revert ? tr("Revert Chunk") : tr("Apply Chunk");
|
||||
const QString question = revert
|
||||
? tr("Would you like to revert the chunk?")
|
||||
: tr("Would you like to apply the chunk?");
|
||||
if (QMessageBox::No == QMessageBox::question(this, title,
|
||||
question,
|
||||
QMessageBox::Yes
|
||||
| QMessageBox::No)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
||||
|
||||
const QString fileName = revert
|
||||
? fileData.rightFileInfo.fileName
|
||||
: fileData.leftFileInfo.fileName;
|
||||
|
||||
const QString workingDirectory = m_document->baseDirectory().isEmpty()
|
||||
? QFileInfo(fileName).absolutePath()
|
||||
: m_document->baseDirectory();
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, revert);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
if (PatchTool::runPatch(EditorManager::defaultTextCodec()->fromUnicode(patch),
|
||||
workingDirectory, strip, revert))
|
||||
m_document->reload();
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addRevertAction(menu, diffFileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::leftVSliderChanged()
|
||||
@@ -1051,14 +895,14 @@ void SideBySideDiffEditorWidget::leftCursorPositionChanged()
|
||||
leftVSliderChanged();
|
||||
leftHSliderChanged();
|
||||
|
||||
if (m_ignoreCurrentIndexChange)
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
emit currentDiffFileIndexChanged(
|
||||
m_leftEditor->fileIndexForBlockNumber(m_leftEditor->textCursor().blockNumber()));
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::rightCursorPositionChanged()
|
||||
@@ -1066,14 +910,14 @@ void SideBySideDiffEditorWidget::rightCursorPositionChanged()
|
||||
rightVSliderChanged();
|
||||
rightHSliderChanged();
|
||||
|
||||
if (m_ignoreCurrentIndexChange)
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
emit currentDiffFileIndexChanged(
|
||||
m_rightEditor->fileIndexForBlockNumber(m_rightEditor->textCursor().blockNumber()));
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "diffutils.h"
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTextCharFormat>
|
||||
@@ -40,6 +40,7 @@ QT_END_NAMESPACE
|
||||
namespace DiffEditor {
|
||||
|
||||
class DiffEditorController;
|
||||
class FileData;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
@@ -78,9 +79,6 @@ private slots:
|
||||
int chunkIndex);
|
||||
void slotRightContextMenuRequested(QMenu *menu, int diffFileIndex,
|
||||
int chunkIndex);
|
||||
void slotSendChunkToCodePaster();
|
||||
void slotApplyChunk();
|
||||
void slotRevertChunk();
|
||||
void leftVSliderChanged();
|
||||
void rightVSliderChanged();
|
||||
void leftHSliderChanged();
|
||||
@@ -90,30 +88,16 @@ private slots:
|
||||
|
||||
private:
|
||||
void showDiff();
|
||||
void jumpToOriginalFile(const QString &fileName,
|
||||
int lineNumber, int columnNumber);
|
||||
void patch(bool revert);
|
||||
|
||||
DiffEditorDocument *m_document;
|
||||
SideDiffEditorWidget *m_leftEditor;
|
||||
SideDiffEditorWidget *m_rightEditor;
|
||||
QSplitter *m_splitter;
|
||||
|
||||
QList<FileData> m_contextFileData; // ultimate data to be shown, contextLineCount taken into account
|
||||
DiffEditorWidgetController m_controller;
|
||||
|
||||
bool m_ignoreCurrentIndexChange;
|
||||
bool m_foldingBlocker;
|
||||
bool m_horizontalSync;
|
||||
int m_contextMenuFileIndex;
|
||||
int m_contextMenuChunkIndex;
|
||||
bool m_horizontalSync = false;
|
||||
|
||||
QTextCharFormat m_spanLineFormat;
|
||||
QTextCharFormat m_fileLineFormat;
|
||||
QTextCharFormat m_chunkLineFormat;
|
||||
QTextCharFormat m_leftLineFormat;
|
||||
QTextCharFormat m_leftCharFormat;
|
||||
QTextCharFormat m_rightLineFormat;
|
||||
QTextCharFormat m_rightCharFormat;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -24,41 +24,22 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "unifieddiffeditorwidget.h"
|
||||
#include "diffeditorcontroller.h"
|
||||
#include "diffutils.h"
|
||||
#include "diffeditorconstants.h"
|
||||
#include "diffeditordocument.h"
|
||||
#include "diffutils.h"
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
#include <QMenu>
|
||||
#include <QPlainTextDocumentLayout>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
#include <QTextCodec>
|
||||
#include <QPainter>
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/textdocumentlayout.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/displaysettings.h>
|
||||
#include <texteditor/highlighterutils.h>
|
||||
|
||||
#include <coreplugin/patchtool.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <cpaster/codepasterservice.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
|
||||
//static const int FILE_LEVEL = 1;
|
||||
//static const int CHUNK_LEVEL = 2;
|
||||
|
||||
using namespace Core;
|
||||
using namespace TextEditor;
|
||||
|
||||
@@ -67,12 +48,7 @@ namespace Internal {
|
||||
|
||||
UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent)
|
||||
: SelectableTextEditorWidget("DiffEditor.UnifiedDiffEditor", parent)
|
||||
, m_document(0)
|
||||
, m_ignoreCurrentIndexChange(false)
|
||||
, m_contextMenuFileIndex(-1)
|
||||
, m_contextMenuChunkIndex(-1)
|
||||
, m_leftLineNumberDigits(1)
|
||||
, m_rightLineNumberDigits(1)
|
||||
, m_controller(this)
|
||||
{
|
||||
DisplaySettings settings = displaySettings();
|
||||
settings.m_textWrapping = false;
|
||||
@@ -101,7 +77,7 @@ UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent)
|
||||
|
||||
void UnifiedDiffEditorWidget::setDocument(DiffEditorDocument *document)
|
||||
{
|
||||
m_document = document;
|
||||
m_controller.setDocument(document);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::saveState()
|
||||
@@ -117,11 +93,11 @@ void UnifiedDiffEditorWidget::restoreState()
|
||||
if (m_state.isNull())
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
SelectableTextEditorWidget::restoreState(m_state);
|
||||
m_state.clear();
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds)
|
||||
@@ -133,23 +109,18 @@ void UnifiedDiffEditorWidget::setDisplaySettings(const DisplaySettings &ds)
|
||||
|
||||
void UnifiedDiffEditorWidget::setFontSettings(const FontSettings &fontSettings)
|
||||
{
|
||||
m_fileLineFormat = fontSettings.toTextCharFormat(C_DIFF_FILE_LINE);
|
||||
m_chunkLineFormat = fontSettings.toTextCharFormat(C_DIFF_CONTEXT_LINE);
|
||||
m_leftLineFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_LINE);
|
||||
m_leftCharFormat = fontSettings.toTextCharFormat(C_DIFF_SOURCE_CHAR);
|
||||
m_rightLineFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_LINE);
|
||||
m_rightCharFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_CHAR);
|
||||
m_controller.setFontSettings(fontSettings);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::slotCursorPositionChangedInEditor()
|
||||
{
|
||||
if (m_ignoreCurrentIndexChange)
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
emit currentDiffFileIndexChanged(fileIndexForBlockNumber(textCursor().blockNumber()));
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
|
||||
@@ -182,109 +153,11 @@ void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
if (!m_document || !m_document->controller())
|
||||
return;
|
||||
|
||||
menu->addSeparator();
|
||||
menu->addSeparator();
|
||||
if (ExtensionSystem::PluginManager::getObject<CodePaster::Service>()) {
|
||||
// optional code pasting service
|
||||
QAction *sendChunkToCodePasterAction =
|
||||
menu->addAction(tr("Send Chunk to CodePaster..."));
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered,
|
||||
this, &UnifiedDiffEditorWidget::slotSendChunkToCodePaster);
|
||||
}
|
||||
QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
|
||||
connect(applyAction, &QAction::triggered, this, &UnifiedDiffEditorWidget::slotApplyChunk);
|
||||
QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
|
||||
connect(revertAction, &QAction::triggered, this, &UnifiedDiffEditorWidget::slotRevertChunk);
|
||||
|
||||
m_contextMenuFileIndex = diffFileIndex;
|
||||
m_contextMenuChunkIndex = chunkIndex;
|
||||
|
||||
applyAction->setEnabled(false);
|
||||
revertAction->setEnabled(false);
|
||||
|
||||
if (m_contextMenuFileIndex < 0 || m_contextMenuChunkIndex < 0)
|
||||
return;
|
||||
|
||||
if (m_contextMenuFileIndex >= m_contextFileData.count())
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
if (m_contextMenuChunkIndex >= fileData.chunks.count())
|
||||
return;
|
||||
|
||||
m_document->chunkActionsRequested(menu, diffFileIndex, chunkIndex);
|
||||
|
||||
revertAction->setEnabled(true);
|
||||
|
||||
if (fileData.leftFileInfo.fileName == fileData.rightFileInfo.fileName)
|
||||
return;
|
||||
|
||||
applyAction->setEnabled(true);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::slotSendChunkToCodePaster()
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
// Retrieve service by soft dependency.
|
||||
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
||||
QTC_ASSERT(pasteService, return);
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, false);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
pasteService->postText(patch, QLatin1String(Constants::DIFF_EDITOR_MIMETYPE));
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::slotApplyChunk()
|
||||
{
|
||||
patch(false);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::slotRevertChunk()
|
||||
{
|
||||
patch(true);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::patch(bool revert)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const QString title = revert ? tr("Revert Chunk") : tr("Apply Chunk");
|
||||
const QString question = revert
|
||||
? tr("Would you like to revert the chunk?")
|
||||
: tr("Would you like to apply the chunk?");
|
||||
if (QMessageBox::No == QMessageBox::question(this, title, question,
|
||||
QMessageBox::Yes
|
||||
| QMessageBox::No)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
const QString fileName = revert
|
||||
? fileData.rightFileInfo.fileName
|
||||
: fileData.leftFileInfo.fileName;
|
||||
|
||||
const QString workingDirectory = m_document->baseDirectory().isEmpty()
|
||||
? QFileInfo(fileName).absolutePath()
|
||||
: m_document->baseDirectory();
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, revert);
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
if (PatchTool::runPatch(EditorManager::defaultTextCodec()->fromUnicode(patch),
|
||||
workingDirectory, strip, revert))
|
||||
m_document->reload();
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addApplyAction(menu, diffFileIndex, chunkIndex);
|
||||
m_controller.addRevertAction(menu, diffFileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::clear(const QString &message)
|
||||
@@ -297,12 +170,12 @@ void UnifiedDiffEditorWidget::clear(const QString &message)
|
||||
m_chunkInfo.clear();
|
||||
setSelections(QMap<int, QList<DiffSelection> >());
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
SelectableTextEditorWidget::clear();
|
||||
setDiff(QList<FileData>(), QString());
|
||||
setPlainText(message);
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
QString UnifiedDiffEditorWidget::lineNumber(int blockNumber) const
|
||||
@@ -370,7 +243,7 @@ void UnifiedDiffEditorWidget::setDiff(const QList<FileData> &diffFileList,
|
||||
{
|
||||
Q_UNUSED(workingDirectory)
|
||||
|
||||
m_contextFileData = diffFileList;
|
||||
m_controller.m_contextFileData = diffFileList;
|
||||
|
||||
showDiff();
|
||||
}
|
||||
@@ -391,7 +264,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
||||
int charCount = 0;
|
||||
QList<TextLineData> leftBuffer, rightBuffer;
|
||||
|
||||
(*selections)[*blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
(*selections)[*blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
|
||||
int lastEqualRow = -1;
|
||||
if (lastChunk) {
|
||||
@@ -424,7 +297,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
||||
const int blockDelta = line.count(QLatin1Char('\n')); // no new line
|
||||
// could have been added
|
||||
for (int k = 0; k < blockDelta; k++)
|
||||
(*selections)[*blockNumber + blockCount + 1 + k].append(&m_leftLineFormat);
|
||||
(*selections)[*blockNumber + blockCount + 1 + k].append(&m_controller.m_leftLineFormat);
|
||||
QMapIterator<int, int> itPos(lineData.changedPositions);
|
||||
while (itPos.hasNext()) {
|
||||
itPos.next();
|
||||
@@ -433,7 +306,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
||||
const int endPos = itPos.value() < 0
|
||||
? itPos.value() : itPos.value() + 1;
|
||||
(*selections)[*blockNumber + blockCount + 1].append(
|
||||
DiffSelection(startPos, endPos, &m_leftCharFormat));
|
||||
DiffSelection(startPos, endPos, &m_controller.m_leftCharFormat));
|
||||
}
|
||||
|
||||
if (!line.isEmpty()) {
|
||||
@@ -464,7 +337,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
||||
// could have been added
|
||||
|
||||
for (int k = 0; k < blockDelta; k++)
|
||||
(*selections)[*blockNumber + blockCount + 1 + k].append(&m_rightLineFormat);
|
||||
(*selections)[*blockNumber + blockCount + 1 + k].append(&m_controller.m_rightLineFormat);
|
||||
QMapIterator<int, int> itPos(lineData.changedPositions);
|
||||
while (itPos.hasNext()) {
|
||||
itPos.next();
|
||||
@@ -473,7 +346,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
||||
const int endPos = itPos.value() < 0
|
||||
? itPos.value() : itPos.value() + 1;
|
||||
(*selections)[*blockNumber + blockCount + 1].append
|
||||
(DiffSelection(startPos, endPos, &m_rightCharFormat));
|
||||
(DiffSelection(startPos, endPos, &m_controller.m_rightCharFormat));
|
||||
}
|
||||
|
||||
if (!line.isEmpty()) {
|
||||
@@ -548,16 +421,16 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
|
||||
QMap<int, QList<DiffSelection> > selections;
|
||||
|
||||
for (int i = 0; i < m_contextFileData.count(); i++) {
|
||||
const FileData &fileData = m_contextFileData.at(i);
|
||||
for (int i = 0; i < m_controller.m_contextFileData.count(); i++) {
|
||||
const FileData &fileData = m_controller.m_contextFileData.at(i);
|
||||
const QString leftFileInfo = QLatin1String("--- ")
|
||||
+ fileData.leftFileInfo.fileName + QLatin1Char('\n');
|
||||
const QString rightFileInfo = QLatin1String("+++ ")
|
||||
+ fileData.rightFileInfo.fileName + QLatin1Char('\n');
|
||||
setFileInfo(blockNumber, fileData.leftFileInfo, fileData.rightFileInfo);
|
||||
selections[blockNumber].append(DiffSelection(&m_fileLineFormat));
|
||||
selections[blockNumber].append(DiffSelection(&m_controller.m_fileLineFormat));
|
||||
blockNumber++;
|
||||
selections[blockNumber].append(DiffSelection(&m_fileLineFormat));
|
||||
selections[blockNumber].append(DiffSelection(&m_controller.m_fileLineFormat));
|
||||
blockNumber++;
|
||||
|
||||
diffText += leftFileInfo;
|
||||
@@ -565,7 +438,7 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
charNumber += leftFileInfo.count() + rightFileInfo.count();
|
||||
|
||||
if (fileData.binaryFiles) {
|
||||
selections[blockNumber].append(DiffSelection(&m_chunkLineFormat));
|
||||
selections[blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||
blockNumber++;
|
||||
const QString binaryLine = QLatin1String("Binary files ")
|
||||
+ fileData.leftFileInfo.fileName
|
||||
@@ -596,10 +469,10 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
}
|
||||
|
||||
diffText.replace(QLatin1Char('\r'), QLatin1Char(' '));
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
setPlainText(diffText);
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
|
||||
setSelections(selections);
|
||||
}
|
||||
@@ -662,7 +535,7 @@ void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
||||
if (fileIndex < 0)
|
||||
return;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(fileIndex);
|
||||
const FileData fileData = m_controller.m_contextFileData.at(fileIndex);
|
||||
const QString leftFileName = fileData.leftFileInfo.fileName;
|
||||
const QString rightFileName = fileData.rightFileInfo.fileName;
|
||||
|
||||
@@ -670,7 +543,7 @@ void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
||||
|
||||
const int rightLineNumber = m_rightLineNumbers.value(blockNumber, -1);
|
||||
if (rightLineNumber >= 0) {
|
||||
jumpToOriginalFile(rightFileName, rightLineNumber, columnNumber);
|
||||
m_controller.jumpToOriginalFile(rightFileName, rightLineNumber, columnNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -690,39 +563,25 @@ void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
||||
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
||||
newRightLineNumber++;
|
||||
if (newLeftLineNumber == leftLineNumber) {
|
||||
jumpToOriginalFile(leftFileName, newRightLineNumber, 0);
|
||||
m_controller.jumpToOriginalFile(leftFileName, newRightLineNumber, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
jumpToOriginalFile(leftFileName, leftLineNumber, columnNumber);
|
||||
m_controller.jumpToOriginalFile(leftFileName, leftLineNumber, columnNumber);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::jumpToOriginalFile(const QString &fileName,
|
||||
int lineNumber,
|
||||
int columnNumber)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
const QDir dir(m_document->baseDirectory());
|
||||
const QString absoluteFileName = dir.absoluteFilePath(fileName);
|
||||
QFileInfo fi(absoluteFileName);
|
||||
if (fi.exists() && !fi.isDir())
|
||||
EditorManager::openEditorAt(absoluteFileName, lineNumber, columnNumber);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
|
||||
{
|
||||
if (m_ignoreCurrentIndexChange)
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
const bool oldIgnore = m_ignoreCurrentIndexChange;
|
||||
m_ignoreCurrentIndexChange = true;
|
||||
const bool oldIgnore = m_controller.m_ignoreCurrentIndexChange;
|
||||
m_controller.m_ignoreCurrentIndexChange = true;
|
||||
const int blockNumber = blockNumberForFileIndex(diffFileIndex);
|
||||
|
||||
QTextBlock block = document()->findBlockByNumber(blockNumber);
|
||||
@@ -730,7 +589,7 @@ void UnifiedDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
|
||||
cursor.setPosition(block.position());
|
||||
setTextCursor(cursor);
|
||||
verticalScrollBar()->setValue(blockNumber);
|
||||
m_ignoreCurrentIndexChange = oldIgnore;
|
||||
m_controller.m_ignoreCurrentIndexChange = oldIgnore;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "diffutils.h"
|
||||
#include "selectabletexteditorwidget.h"
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
|
||||
namespace TextEditor {
|
||||
class DisplaySettings;
|
||||
@@ -81,10 +81,6 @@ private slots:
|
||||
|
||||
void slotCursorPositionChangedInEditor();
|
||||
|
||||
void slotSendChunkToCodePaster();
|
||||
void slotApplyChunk();
|
||||
void slotRevertChunk();
|
||||
|
||||
private:
|
||||
void setLeftLineNumber(int blockNumber, int lineNumber);
|
||||
void setRightLineNumber(int blockNumber, int lineNumber);
|
||||
@@ -102,39 +98,23 @@ private:
|
||||
int fileIndexForBlockNumber(int blockNumber) const;
|
||||
int chunkIndexForBlockNumber(int blockNumber) const;
|
||||
void jumpToOriginalFile(const QTextCursor &cursor);
|
||||
void jumpToOriginalFile(const QString &fileName,
|
||||
int lineNumber,
|
||||
int columnNumber);
|
||||
void addContextMenuActions(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int chunkIndex);
|
||||
void patch(bool revert);
|
||||
|
||||
DiffEditorDocument *m_document;
|
||||
|
||||
// block number, visual line number.
|
||||
QMap<int, int> m_leftLineNumbers;
|
||||
QMap<int, int> m_rightLineNumbers;
|
||||
bool m_ignoreCurrentIndexChange;
|
||||
int m_contextMenuFileIndex;
|
||||
int m_contextMenuChunkIndex;
|
||||
|
||||
int m_leftLineNumberDigits;
|
||||
int m_rightLineNumberDigits;
|
||||
DiffEditorWidgetController m_controller;
|
||||
|
||||
int m_leftLineNumberDigits = 1;
|
||||
int m_rightLineNumberDigits = 1;
|
||||
// block number, visual line number.
|
||||
QMap<int, QPair<DiffFileInfo, DiffFileInfo> > m_fileInfo;
|
||||
// start block number, block count of a chunk, chunk index inside a file.
|
||||
QMap<int, QPair<int, int> > m_chunkInfo;
|
||||
|
||||
QList<FileData> m_contextFileData; // ultimate data to be shown
|
||||
// contextLineCount taken into account
|
||||
|
||||
QTextCharFormat m_fileLineFormat;
|
||||
QTextCharFormat m_chunkLineFormat;
|
||||
QTextCharFormat m_leftLineFormat;
|
||||
QTextCharFormat m_rightLineFormat;
|
||||
QTextCharFormat m_leftCharFormat;
|
||||
QTextCharFormat m_rightCharFormat;
|
||||
QByteArray m_state;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user