Commit 8cad9453 authored by jkobus's avatar jkobus Committed by Jarek Kobus
Browse files

Implement unified diff editor



Change-Id: I93e0bfd71a8a650afbe2ca9e0f1f3dbfc9d57db0
Reviewed-by: default avatarJarek Kobus <jaroslaw.kobus@digia.com>
parent 8cb25f9e
......@@ -42,7 +42,6 @@
<file>images/replace.png</file>
<file>images/reset.png</file>
<file>images/sidebaricon.png</file>
<file>images/topbaricon.png</file>
<file>images/splitbutton_horizontal.png</file>
<file>images/splitbutton_horizontal@2x.png</file>
<file>images/statusbar.png</file>
......@@ -89,8 +88,6 @@
<file>images/splitbutton_vertical.png</file>
<file>images/splitbutton_vertical@2x.png</file>
<file>images/panel_manage_button.png</file>
<file>images/sidebysidediff.png</file>
<file>images/textdiff.png</file>
<file>images/pause.png</file>
</qresource>
</RCC>
......@@ -197,7 +197,6 @@ const char ICON_CLEAR[] = ":/core/images/clear.png";
const char ICON_RESET[] = ":/core/images/reset.png";
const char ICON_MAGNIFIER[] = ":/core/images/magnifier.png";
const char ICON_TOGGLE_SIDEBAR[] = ":/core/images/sidebaricon.png";
const char ICON_TOGGLE_TOPBAR[] = ":/core/images/topbaricon.png";
const char ICON_CLOSE_DOCUMENT[] = ":/core/images/button_close.png";
const char ICON_CLOSE[] = ":/core/images/closebutton.png";
const char ICON_CLOSE_DARK[] = ":/core/images/darkclosebutton.png";
......@@ -207,8 +206,6 @@ const char ICON_CLOSE_SPLIT_TOP[] = ":/core/images/splitbutton_closetop.png";
const char ICON_CLOSE_SPLIT_BOTTOM[] = ":/core/images/splitbutton_closebottom.png";
const char ICON_CLOSE_SPLIT_LEFT[] = ":/core/images/splitbutton_closeleft.png";
const char ICON_CLOSE_SPLIT_RIGHT[] = ":/core/images/splitbutton_closeright.png";
const char ICON_SIDE_BY_SIDE_DIFF[] = ":/core/images/sidebysidediff.png";
const char ICON_TEXT_DIFF[] = ":/core/images/textdiff.png";
const char ICON_FILTER[] = ":/core/images/filtericon.png";
const char ICON_LINK[] = ":/core/images/linkicon.png";
const char ICON_PAUSE[] = ":/core/images/pause.png";
......
......@@ -93,7 +93,9 @@ bool PatchTool::runPatch(const QByteArray &input, const QString &workingDirector
QProcess patchProcess;
if (!workingDirectory.isEmpty())
patchProcess.setWorkingDirectory(workingDirectory);
QStringList args(QLatin1String("-p") + QString::number(strip));
QStringList args;
if (strip >= 0)
args << (QLatin1String("-p") + QString::number(strip));
if (reverse)
args << QLatin1String("-R");
MessageManager::write(QApplication::translate("Core::PatchTool", "Executing in %1: %2 %3").
......
......@@ -32,6 +32,7 @@
#include "diffeditordocument.h"
#include "diffeditorguicontroller.h"
#include "sidebysidediffeditorwidget.h"
#include "unifieddiffeditorwidget.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
......@@ -41,6 +42,7 @@
#include <texteditor/texteditorsettings.h>
#include <texteditor/displaysettings.h>
#include <QStackedWidget>
#include <QToolButton>
#include <QSpinBox>
#include <QStyle>
......@@ -49,6 +51,15 @@
#include <QToolBar>
#include <QComboBox>
#include <QFileInfo>
#include <QTextCodec>
static const char settingsGroupC[] = "DiffEditor";
static const char diffEditorTypeKeyC[] = "DiffEditorType";
static const char sideBySideDiffEditorValueC[] = "SideBySide";
static const char unifiedDiffEditorValueC[] = "Unified";
static const char legacySettingsGroupC[] = "Git";
static const char useDiffEditorKeyC[] = "UseDiffEditor";
using namespace TextEditor;
......@@ -115,12 +126,16 @@ DiffEditor::DiffEditor()
: IEditor(0)
, m_document(new DiffEditorDocument())
, m_descriptionWidget(0)
, m_diffWidget(0)
, m_stackedWidget(0)
, m_sideBySideEditor(0)
, m_unifiedEditor(0)
, m_currentEditor(0)
, m_controller(0)
, m_guiController(0)
, m_toolBar(0)
, m_entriesComboBox(0)
, m_toggleDescriptionAction(0)
, m_diffEditorSwitcher(0)
{
ctor();
}
......@@ -129,45 +144,64 @@ DiffEditor::DiffEditor(DiffEditor *other)
: IEditor(0)
, m_document(other->m_document)
, m_descriptionWidget(0)
, m_diffWidget(0)
, m_stackedWidget(0)
, m_sideBySideEditor(0)
, m_unifiedEditor(0)
, m_currentEditor(0)
, m_controller(0)
, m_guiController(0)
, m_toolBar(0)
, m_entriesComboBox(0)
, m_toggleDescriptionAction(0)
, m_diffEditorSwitcher(0)
{
ctor();
}
void DiffEditor::ctor()
{
setDuplicateSupported(true);
QSplitter *splitter = new Core::MiniSplitter(Qt::Vertical);
m_descriptionWidget = new Internal::DescriptionEditorWidget(splitter);
m_descriptionWidget->setReadOnly(true);
splitter->addWidget(m_descriptionWidget);
m_diffWidget = new SideBySideDiffEditorWidget(splitter);
splitter->addWidget(m_diffWidget);
m_stackedWidget = new QStackedWidget(splitter);
splitter->addWidget(m_stackedWidget);
m_sideBySideEditor = new SideBySideDiffEditorWidget(m_stackedWidget);
m_stackedWidget->addWidget(m_sideBySideEditor);
m_unifiedEditor = new UnifiedDiffEditorWidget(m_stackedWidget);
m_stackedWidget->addWidget(m_unifiedEditor);
setWidget(splitter);
connect(TextEditorSettings::instance(), SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)),
m_descriptionWidget, SLOT(setDisplaySettings(TextEditor::DisplaySettings)));
connect(TextEditorSettings::instance(), SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
m_descriptionWidget->baseTextDocument(), SLOT(setFontSettings(TextEditor::FontSettings)));
m_descriptionWidget->setDisplaySettings(TextEditorSettings::displaySettings());
m_descriptionWidget->setCodeStyle(TextEditorSettings::codeStyle());
m_descriptionWidget->baseTextDocument()->setFontSettings(TextEditorSettings::fontSettings());
connect(TextEditorSettings::instance(),
SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)),
m_descriptionWidget,
SLOT(setDisplaySettings(TextEditor::DisplaySettings)));
connect(TextEditorSettings::instance(),
SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
m_descriptionWidget->baseTextDocument(),
SLOT(setFontSettings(TextEditor::FontSettings)));
m_descriptionWidget->setDisplaySettings(
TextEditorSettings::displaySettings());
m_descriptionWidget->setCodeStyle(
TextEditorSettings::codeStyle());
m_descriptionWidget->baseTextDocument()->setFontSettings(
TextEditorSettings::fontSettings());
m_controller = m_document->controller();
m_guiController = new DiffEditorGuiController(m_controller, this);
m_diffWidget->setDiffEditorGuiController(m_guiController);
connect(m_controller, SIGNAL(cleared(QString)),
this, SLOT(slotCleared(QString)));
connect(m_controller, SIGNAL(diffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)),
this, SLOT(slotDiffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)));
connect(m_controller, SIGNAL(diffFilesChanged(QList<FileData>,QString)),
this, SLOT(slotDiffFilesChanged(QList<FileData>,QString)));
connect(m_controller, SIGNAL(descriptionChanged(QString)),
this, SLOT(slotDescriptionChanged(QString)));
connect(m_controller, SIGNAL(descriptionEnablementChanged(bool)),
......@@ -179,6 +213,10 @@ void DiffEditor::ctor()
slotDescriptionChanged(m_controller->description());
slotDescriptionVisibilityChanged();
showDiffEditor(readCurrentDiffEditorSetting());
toolBar();
}
DiffEditor::~DiffEditor()
......@@ -193,11 +231,36 @@ Core::IEditor *DiffEditor::duplicate()
return new DiffEditor(this);
}
bool DiffEditor::open(QString *errorString, const QString &fileName, const QString &realFileName)
bool DiffEditor::open(QString *errorString,
const QString &fileName,
const QString &realFileName)
{
Q_UNUSED(errorString)
Q_UNUSED(fileName)
Q_UNUSED(realFileName)
if (!m_controller)
return false;
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
*errorString = tr("Could not open patch file \"%1\".").arg(fileName);
return false;
}
const QString patch = Core::EditorManager::defaultTextCodec()->toUnicode(file.readAll());
bool ok = false;
QList<FileData> fileDataList
= DiffUtils::readPatch(patch,
m_controller->isIgnoreWhitespace(),
&ok);
if (!ok) {
*errorString = tr("Could not parse patch file \"%1\". "
"The contents is not of unified diff format.")
.arg(fileName);
return false;
}
m_controller->setDiffFiles(fileDataList, QFileInfo(fileName).absolutePath());
return true;
}
......@@ -223,7 +286,7 @@ QWidget *DiffEditor::toolBar()
return m_toolBar;
// Create
m_toolBar = createToolBar(m_diffWidget);
m_toolBar = createToolBar(m_sideBySideEditor);
m_entriesComboBox = new QComboBox;
m_entriesComboBox->setMinimumContentsLength(20);
......@@ -238,7 +301,7 @@ QWidget *DiffEditor::toolBar()
QToolButton *whitespaceButton = new QToolButton(m_toolBar);
whitespaceButton->setText(tr("Ignore Whitespace"));
whitespaceButton->setCheckable(true);
whitespaceButton->setChecked(true);
whitespaceButton->setChecked(m_controller->isIgnoreWhitespace());
m_toolBar->addWidget(whitespaceButton);
QLabel *contextLabel = new QLabel(m_toolBar);
......@@ -247,40 +310,58 @@ QWidget *DiffEditor::toolBar()
m_toolBar->addWidget(contextLabel);
QSpinBox *contextSpinBox = new QSpinBox(m_toolBar);
contextSpinBox->setRange(-1, 100);
contextSpinBox->setValue(3);
contextSpinBox->setRange(1, 100);
contextSpinBox->setValue(m_controller->contextLinesNumber());
contextSpinBox->setFrame(false);
contextSpinBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); // Mac Qt5
contextSpinBox->setSizePolicy(QSizePolicy::Minimum,
QSizePolicy::Expanding); // Mac Qt5
m_toolBar->addWidget(contextSpinBox);
QToolButton *toggleSync = new QToolButton(m_toolBar);
toggleSync->setIcon(QIcon(QLatin1String(Core::Constants::ICON_LINK)));
toggleSync->setCheckable(true);
toggleSync->setChecked(true);
toggleSync->setChecked(m_guiController->horizontalScrollBarSynchronization());
toggleSync->setToolTip(tr("Synchronize Horizontal Scroll Bars"));
m_toolBar->addWidget(toggleSync);
QToolButton *toggleDescription = new QToolButton(m_toolBar);
toggleDescription->setIcon(QIcon(QLatin1String(Core::Constants::ICON_TOGGLE_TOPBAR)));
toggleDescription->setIcon(
QIcon(QLatin1String(Constants::ICON_TOP_BAR)));
toggleDescription->setCheckable(true);
toggleDescription->setChecked(true);
toggleDescription->setChecked(m_guiController->isDescriptionVisible());
m_toggleDescriptionAction = m_toolBar->addWidget(toggleDescription);
slotDescriptionVisibilityChanged();
QToolButton *reloadButton = new QToolButton(m_toolBar);
reloadButton->setIcon(QIcon(QLatin1String(Constants::ICON_RELOAD)));
reloadButton->setToolTip(tr("Reload Editor"));
m_toolBar->addWidget(reloadButton);
m_diffEditorSwitcher = new QToolButton(m_toolBar);
m_toolBar->addWidget(m_diffEditorSwitcher);
updateDiffEditorSwitcher();
connect(whitespaceButton, SIGNAL(clicked(bool)),
m_guiController, SLOT(setIgnoreWhitespaces(bool)));
m_controller, SLOT(setIgnoreWhitespace(bool)));
connect(m_controller, SIGNAL(ignoreWhitespaceChanged(bool)),
whitespaceButton, SLOT(setChecked(bool)));
connect(contextSpinBox, SIGNAL(valueChanged(int)),
m_guiController, SLOT(setContextLinesNumber(int)));
m_controller, SLOT(setContextLinesNumber(int)));
connect(m_controller, SIGNAL(contextLinesNumberChanged(int)),
contextSpinBox, SLOT(setValue(int)));
connect(toggleSync, SIGNAL(clicked(bool)),
m_guiController, SLOT(setHorizontalScrollBarSynchronization(bool)));
connect(toggleDescription, SIGNAL(clicked(bool)),
m_guiController, SLOT(setDescriptionVisible(bool)));
// TODO: synchronize in opposite direction too
connect(m_diffEditorSwitcher, SIGNAL(clicked()),
this, SLOT(slotDiffEditorSwitched()));
connect(reloadButton, SIGNAL(clicked()),
m_controller, SLOT(requestReload()));
return m_toolBar;
}
DiffEditorController * DiffEditor::controller() const
DiffEditorController *DiffEditor::controller() const
{
return m_controller;
}
......@@ -306,16 +387,16 @@ void DiffEditor::slotCleared(const QString &message)
updateEntryToolTip();
}
void DiffEditor::slotDiffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory)
void DiffEditor::slotDiffFilesChanged(const QList<FileData> &diffFileList,
const QString &workingDirectory)
{
Q_UNUSED(workingDirectory)
m_entriesComboBox->clear();
const int count = diffFileList.count();
for (int i = 0; i < count; i++) {
const DiffEditorController::DiffFileInfo leftEntry = diffFileList.at(i).leftFileInfo;
const DiffEditorController::DiffFileInfo rightEntry = diffFileList.at(i).rightFileInfo;
const DiffFileInfo leftEntry = diffFileList.at(i).leftFileInfo;
const DiffFileInfo rightEntry = diffFileList.at(i).rightFileInfo;
const QString leftShortFileName = QFileInfo(leftEntry.fileName).fileName();
const QString rightShortFileName = QFileInfo(rightEntry.fileName).fileName();
QString itemText;
......@@ -327,26 +408,34 @@ void DiffEditor::slotDiffContentsChanged(const QList<DiffEditorController::DiffF
itemToolTip = leftEntry.fileName;
} else {
itemToolTip = tr("[%1] vs. [%2] %3")
.arg(leftEntry.typeInfo, rightEntry.typeInfo, leftEntry.fileName);
.arg(leftEntry.typeInfo,
rightEntry.typeInfo,
leftEntry.fileName);
}
} else {
if (leftShortFileName == rightShortFileName) {
itemText = leftShortFileName;
} else {
itemText = tr("%1 vs. %2")
.arg(leftShortFileName, rightShortFileName);
.arg(leftShortFileName,
rightShortFileName);
}
if (leftEntry.typeInfo.isEmpty() && rightEntry.typeInfo.isEmpty()) {
itemToolTip = tr("%1 vs. %2")
.arg(leftEntry.fileName, rightEntry.fileName);
.arg(leftEntry.fileName,
rightEntry.fileName);
} else {
itemToolTip = tr("[%1] %2 vs. [%3] %4")
.arg(leftEntry.typeInfo, leftEntry.fileName, rightEntry.typeInfo, rightEntry.fileName);
.arg(leftEntry.typeInfo,
leftEntry.fileName,
rightEntry.typeInfo,
rightEntry.fileName);
}
}
m_entriesComboBox->addItem(itemText);
m_entriesComboBox->setItemData(m_entriesComboBox->count() - 1, itemToolTip, Qt::ToolTipRole);
m_entriesComboBox->setItemData(m_entriesComboBox->count() - 1,
itemToolTip, Qt::ToolTipRole);
}
updateEntryToolTip();
}
......@@ -381,7 +470,114 @@ void DiffEditor::slotDescriptionVisibilityChanged()
toggle->setToolTip(tr("Show Change Description"));
m_toggleDescriptionAction->setVisible(enabled);
}
void DiffEditor::slotDiffEditorSwitched()
{
QWidget *oldEditor = m_currentEditor;
QWidget *newEditor = 0;
if (oldEditor == m_sideBySideEditor)
newEditor = m_unifiedEditor;
else if (oldEditor == m_unifiedEditor)
newEditor = m_sideBySideEditor;
else
newEditor = readCurrentDiffEditorSetting();
showDiffEditor(newEditor);
}
void DiffEditor::updateDiffEditorSwitcher()
{
if (!m_diffEditorSwitcher)
return;
QIcon actionIcon;
QString actionToolTip;
if (m_currentEditor == m_unifiedEditor) {
actionIcon = QIcon(QLatin1String(Constants::ICON_SIDE_BY_SIDE_DIFF));
actionToolTip = tr("Switch to Side By Side Diff Editor");
} else if (m_currentEditor == m_sideBySideEditor) {
actionIcon = QIcon(QLatin1String(Constants::ICON_UNIFIED_DIFF));
actionToolTip = tr("Switch to Unified Diff Editor");
}
m_diffEditorSwitcher->setIcon(actionIcon);
m_diffEditorSwitcher->setToolTip(actionToolTip);
}
void DiffEditor::showDiffEditor(QWidget *newEditor)
{
if (m_currentEditor == newEditor)
return;
if (m_currentEditor == m_sideBySideEditor)
m_sideBySideEditor->setDiffEditorGuiController(0);
else if (m_currentEditor == m_unifiedEditor)
m_unifiedEditor->setDiffEditorGuiController(0);
m_currentEditor = newEditor;
if (m_currentEditor == m_unifiedEditor)
m_unifiedEditor->setDiffEditorGuiController(m_guiController);
else if (m_currentEditor == m_sideBySideEditor)
m_sideBySideEditor->setDiffEditorGuiController(m_guiController);
m_stackedWidget->setCurrentWidget(m_currentEditor);
writeCurrentDiffEditorSetting(m_currentEditor);
updateDiffEditorSwitcher();
}
QWidget *DiffEditor::readLegacyCurrentDiffEditorSetting()
{
QSettings *s = Core::ICore::settings();
s->beginGroup(QLatin1String(legacySettingsGroupC));
const bool legacyExists = s->contains(QLatin1String(useDiffEditorKeyC));
const bool legacyEditor = s->value(
QLatin1String(useDiffEditorKeyC), true).toBool();
if (legacyExists)
s->remove(QLatin1String(useDiffEditorKeyC));
s->endGroup();
QWidget *currentEditor = m_sideBySideEditor;
if (!legacyEditor)
currentEditor = m_unifiedEditor;
if (legacyExists && currentEditor == m_unifiedEditor)
writeCurrentDiffEditorSetting(currentEditor);
return currentEditor;
}
QWidget *DiffEditor::readCurrentDiffEditorSetting()
{
// replace it with m_sideBySideEditor when dropping legacy stuff
QWidget *defaultEditor = readLegacyCurrentDiffEditorSetting();
QSettings *s = Core::ICore::settings();
s->beginGroup(QLatin1String(settingsGroupC));
const QString editorString = s->value(
QLatin1String(diffEditorTypeKeyC)).toString();
s->endGroup();
if (editorString == QLatin1String(unifiedDiffEditorValueC))
return m_unifiedEditor;
if (editorString == QLatin1String(sideBySideDiffEditorValueC))
return m_sideBySideEditor;
return defaultEditor;
}
void DiffEditor::writeCurrentDiffEditorSetting(QWidget *currentEditor)
{
const QString editorString = currentEditor == m_unifiedEditor
? QLatin1String(unifiedDiffEditorValueC)
: QLatin1String(sideBySideDiffEditorValueC);
QSettings *s = Core::ICore::settings();
s->beginGroup(QLatin1String(settingsGroupC));
s->setValue(QLatin1String(diffEditorTypeKeyC), editorString);
s->endGroup();
}
} // namespace DiffEditor
......
......@@ -37,9 +37,10 @@
#include <coreplugin/idocument.h>
QT_BEGIN_NAMESPACE
class QToolBar;
class QComboBox;
class QToolBar;
class QToolButton;
class QStackedWidget;
QT_END_NAMESPACE
namespace TextEditor { class BaseTextEditorWidget; }
......@@ -49,6 +50,7 @@ namespace DiffEditor {
class DiffEditorDocument;
class DiffEditorGuiController;
class SideBySideDiffEditorWidget;
class UnifiedDiffEditorWidget;
class DIFFEDITOR_EXPORT DiffEditor : public Core::IEditor
{
......@@ -64,7 +66,9 @@ public:
// Core::IEditor
Core::IEditor *duplicate();
bool open(QString *errorString, const QString &fileName, const QString &realFileName);
bool open(QString *errorString,
const QString &fileName,
const QString &realFileName);
Core::IDocument *document();
QWidget *toolBar();
......@@ -74,24 +78,34 @@ public slots:
private slots:
void slotCleared(const QString &message);
void slotDiffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory);
void slotDiffFilesChanged(const QList<FileData> &diffFileList,
const QString &workingDirectory);
void entryActivated(int index);
void slotDescriptionChanged(const QString &description);
void slotDescriptionVisibilityChanged();
void slotDiffEditorSwitched();
private:
void ctor();
void updateEntryToolTip();
void showDiffEditor(QWidget *newEditor);
void updateDiffEditorSwitcher();
QWidget *readLegacyCurrentDiffEditorSetting();
QWidget *readCurrentDiffEditorSetting();
void writeCurrentDiffEditorSetting(QWidget *currentEditor);
QSharedPointer<DiffEditorDocument> m_document;
TextEditor::BaseTextEditorWidget *m_descriptionWidget;
SideBySideDiffEditorWidget *m_diffWidget;
QStackedWidget *m_stackedWidget;
SideBySideDiffEditorWidget *m_sideBySideEditor;
UnifiedDiffEditorWidget *m_unifiedEditor;
QWidget *m_currentEditor;
DiffEditorController *m_controller;
DiffEditorGuiController *m_guiController;
QToolBar *m_toolBar;
QComboBox *m_entriesComboBox;
QAction *m_toggleDescriptionAction;
QToolButton *m_diffEditorSwitcher;
};
} // namespace DiffEditor
......
......@@ -10,9 +10,12 @@ HEADERS += diffeditor_global.h \
diffeditorguicontroller.h \
diffeditormanager.h \
diffeditorplugin.h \
diffeditorreloader.h \
differ.h \
diffutils.h \
sidebysidediffeditorwidget.h
selectabletexteditorwidget.h \
sidebysidediffeditorwidget.h \
unifieddiffeditorwidget.h
SOURCES += diffeditor.cpp \
diffeditorcontroller.cpp \
......@@ -21,8 +24,11 @@ SOURCES += diffeditor.cpp \
diffeditorguicontroller.cpp \
diffeditormanager.cpp \
diffeditorplugin.cpp \
diffeditorreloader.cpp \
differ.cpp \
diffutils.cpp \
sidebysidediffeditorwidget.cpp
selectabletexteditorwidget.cpp \
sidebysidediffeditorwidget.cpp \
unifieddiffeditorwidget.cpp
RESOURCES +=
RESOURCES += diffeditor.qrc
......@@ -15,6 +15,7 @@ QtcPlugin {
files: [
"diffeditor.cpp",
"diffeditor.h",
"diffeditor.qrc",
"diffeditor_global.h",
"diffeditorconstants.h",
"diffeditorcontroller.cpp",
......@@ -29,12 +30,16 @@ QtcPlugin {
"diffeditormanager.h",
"diffeditorplugin.cpp",
"diffeditorplugin.h",
"diffeditorreloader.cpp",
"diffeditorreloader.h",
"differ.cpp",
"differ.h",
"diffutils.cpp",
"diffutils.h",
"sidebysidediffeditorwidget.cpp",
"sidebysidediffeditorwidget.h",
"unifieddiffeditorwidget.cpp",
"unifieddiffeditorwidget.h",
]
}