Commit a74b59ff authored by jkobus's avatar jkobus Committed by Jarek Kobus

Add DiffEditorController

Change-Id: Ic2f4a38d2ed08426ca7e5229d959b10fa545c129
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent be2b7561
......@@ -49,15 +49,19 @@ namespace DiffEditor {
///////////////////////////////// DiffEditor //////////////////////////////////
DiffEditor::DiffEditor(DiffEditorWidget *editorWidget)
: IEditor(0),
m_toolWidget(0),
m_file(new Internal::DiffEditorFile(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE), this)),
m_editorWidget(editorWidget),
m_entriesComboBox(0)
: IEditor(0)
, m_toolWidget(0)
, m_file(new Internal::DiffEditorFile(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE), this))
, m_editorWidget(editorWidget)
, m_diffEditorController(0)
, m_entriesComboBox(0)
{
setWidget(editorWidget);
connect(m_editorWidget, SIGNAL(navigatedToDiffFile(int)),
this, SLOT(activateEntry(int)));
m_diffEditorController = editorWidget ? editorWidget->diffEditorController() : 0;
if (m_diffEditorController) {
connect(m_diffEditorController, SIGNAL(currentDiffFileIndexChanged(int)),
this, SLOT(activateEntry(int)));
}
}
DiffEditor::~DiffEditor()
......@@ -123,8 +127,6 @@ QWidget *DiffEditor::toolBar()
whitespaceButton->setText(tr("Ignore Whitespace"));
whitespaceButton->setCheckable(true);
whitespaceButton->setChecked(true);
connect(whitespaceButton, SIGNAL(clicked(bool)),
m_editorWidget, SLOT(setIgnoreWhitespaces(bool)));
m_toolWidget->addWidget(whitespaceButton);
QLabel *contextLabel = new QLabel(m_toolWidget);
......@@ -137,8 +139,6 @@ QWidget *DiffEditor::toolBar()
contextSpinBox->setValue(3);
contextSpinBox->setFrame(false);
contextSpinBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); // Mac Qt5
connect(contextSpinBox, SIGNAL(valueChanged(int)),
m_editorWidget, SLOT(setContextLinesNumber(int)));
m_toolWidget->addWidget(contextSpinBox);
QToolButton *toggleSync = new QToolButton(m_toolWidget);
......@@ -146,21 +146,29 @@ QWidget *DiffEditor::toolBar()
toggleSync->setCheckable(true);
toggleSync->setChecked(true);
toggleSync->setToolTip(tr("Synchronize Horizontal Scroll Bars"));
connect(toggleSync, SIGNAL(clicked(bool)),
m_editorWidget, SLOT(setHorizontalScrollBarSynchronization(bool)));
m_toolWidget->addWidget(toggleSync);
if (m_diffEditorController) {
connect(whitespaceButton, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setIgnoreWhitespaces(bool)));
connect(contextSpinBox, SIGNAL(valueChanged(int)),
m_diffEditorController, SLOT(setContextLinesNumber(int)));
connect(toggleSync, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setHorizontalScrollBarSynchronization(bool)));
// TODO: synchronize in opposite direction too
}
return m_toolWidget;
}
void DiffEditor::setDiff(const QList<DiffEditorWidget::DiffFilesContents> &diffFileList,
void DiffEditor::setDiff(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory)
{
m_entriesComboBox->clear();
const int count = diffFileList.count();
for (int i = 0; i < count; i++) {
const DiffEditorWidget::DiffFileInfo leftEntry = diffFileList.at(i).leftFileInfo;
const DiffEditorWidget::DiffFileInfo rightEntry = diffFileList.at(i).rightFileInfo;
const DiffEditorController::DiffFileInfo leftEntry = diffFileList.at(i).leftFileInfo;
const DiffEditorController::DiffFileInfo rightEntry = diffFileList.at(i).rightFileInfo;
const QString leftShortFileName = QFileInfo(leftEntry.fileName).fileName();
const QString rightShortFileName = QFileInfo(rightEntry.fileName).fileName();
QString itemText;
......@@ -194,14 +202,16 @@ void DiffEditor::setDiff(const QList<DiffEditorWidget::DiffFilesContents> &diffF
m_entriesComboBox->setItemData(m_entriesComboBox->count() - 1, itemToolTip, Qt::ToolTipRole);
}
updateEntryToolTip();
m_editorWidget->setDiff(diffFileList, workingDirectory);
if (m_diffEditorController)
m_diffEditorController->setDiffContents(diffFileList, workingDirectory);
}
void DiffEditor::clear(const QString &message)
{
m_entriesComboBox->clear();
updateEntryToolTip();
m_editorWidget->clear(message);
if (m_diffEditorController)
m_diffEditorController->clear(message);
}
void DiffEditor::updateEntryToolTip()
......@@ -214,7 +224,8 @@ void DiffEditor::updateEntryToolTip()
void DiffEditor::entryActivated(int index)
{
updateEntryToolTip();
m_editorWidget->navigateToDiffFile(index);
if (m_diffEditorController)
m_diffEditorController->setCurrentDiffFileIndex(index);
}
void DiffEditor::activateEntry(int index)
......
......@@ -31,7 +31,7 @@
#define DIFFEDITOR_H
#include "diffeditor_global.h"
#include "diffeditorwidget.h"
#include "diffeditorcontroller.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
......@@ -42,6 +42,7 @@ class QComboBox;
QT_END_NAMESPACE
namespace DiffEditor {
class DiffEditorWidget;
namespace Internal {
class DiffEditorFile;
......@@ -55,7 +56,7 @@ public:
virtual ~DiffEditor();
public:
void setDiff(const QList<DiffEditorWidget::DiffFilesContents> &diffFileList,
void setDiff(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory = QString());
void clear(const QString &message);
......@@ -81,6 +82,7 @@ private:
Internal::DiffEditorFile *m_file;
DiffEditorWidget *m_editorWidget;
DiffEditorController *m_diffEditorController;
QComboBox *m_entriesComboBox;
};
......
......@@ -2,8 +2,9 @@ DEFINES += DIFFEDITOR_LIBRARY
include(../../qtcreatorplugin.pri)
HEADERS += diffeditor_global.h \
diffeditorconstants.h \
diffeditor.h \
diffeditorconstants.h \
diffeditorcontroller.h \
diffeditorfactory.h \
diffeditorfile.h \
diffeditorplugin.h \
......@@ -13,6 +14,7 @@ HEADERS += diffeditor_global.h \
diffshoweditorfactory.h
SOURCES += diffeditor.cpp \
diffeditorcontroller.cpp \
diffeditorfactory.cpp \
diffeditorfile.cpp \
diffeditorplugin.cpp \
......
......@@ -15,6 +15,8 @@ QtcPlugin {
"diffeditor.h",
"diffeditor_global.h",
"diffeditorconstants.h",
"diffeditorcontroller.cpp",
"diffeditorcontroller.h",
"diffeditorfactory.cpp",
"diffeditorfactory.h",
"diffeditorfile.cpp",
......
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "diffeditorcontroller.h"
namespace DiffEditor {
DiffEditorController::DiffEditorController(QObject *parent)
: QObject(parent),
m_contextLinesNumber(3),
m_ignoreWhitespaces(true),
m_syncScrollBars(true)
{
clear();
}
DiffEditorController::~DiffEditorController()
{
}
QString DiffEditorController::clearMessage() const
{
return m_clearMessage;
}
QList<DiffEditorController::DiffFilesContents> DiffEditorController::diffContents() const
{
return m_diffFileList;
}
QString DiffEditorController::workingDirectory() const
{
return m_workingDirectory;
}
int DiffEditorController::contextLinesNumber() const
{
return m_contextLinesNumber;
}
bool DiffEditorController::isIgnoreWhitespaces() const
{
return m_ignoreWhitespaces;
}
bool DiffEditorController::horizontalScrollBarSynchronization() const
{
return m_syncScrollBars;
}
int DiffEditorController::currentDiffFileIndex() const
{
return m_currentDiffFileIndex;
}
void DiffEditorController::clear()
{
clear(tr("No difference"));
}
void DiffEditorController::clear(const QString &message)
{
m_clearMessage = message;
m_currentDiffFileIndex = -1;
emit cleared(message);
}
void DiffEditorController::setDiffContents(const QList<DiffFilesContents> &diffFileList, const QString &workingDirectory)
{
m_diffFileList = diffFileList;
m_workingDirectory = workingDirectory;
m_currentDiffFileIndex = (diffFileList.isEmpty() ? -1 : 0);
emit diffContentsChanged(diffFileList, workingDirectory);
}
void DiffEditorController::setContextLinesNumber(int lines)
{
const int l = qMax(lines, -1);
if (m_contextLinesNumber == l)
return;
m_contextLinesNumber = l;
emit contextLinesNumberChanged(l);
}
void DiffEditorController::setIgnoreWhitespaces(bool ignore)
{
if (m_ignoreWhitespaces == ignore)
return;
m_ignoreWhitespaces = ignore;
emit ignoreWhitespacesChanged(ignore);
}
void DiffEditorController::setHorizontalScrollBarSynchronization(bool on)
{
if (m_syncScrollBars == on)
return;
m_syncScrollBars = on;
emit horizontalScrollBarSynchronizationChanged(on);
}
void DiffEditorController::setCurrentDiffFileIndex(int diffFileIndex)
{
if (!m_diffFileList.count())
return; // -1 is the only valid value in this case
const int newIndex = qBound(0, diffFileIndex, m_diffFileList.count() - 1);
if (m_currentDiffFileIndex == newIndex)
return;
m_currentDiffFileIndex = newIndex;
emit currentDiffFileIndexChanged(newIndex);
}
} // namespace DiffEditor
//QTextCodec *DiffEditorWidget::codec() const
//{
//}
//QString DiffEditorWidget::source() const
//{
// return m_source;
//}
//void DiffEditorWidget::setSource(const QString &source)
//{
// m_source = source;
//}
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DIFFEDITORCONTROLLER_H
#define DIFFEDITORCONTROLLER_H
#include "diffeditor_global.h"
#include <QObject>
namespace DiffEditor {
class DIFFEDITOR_EXPORT DiffEditorController : public QObject
{
// Q_PROPERTY(QString source READ source WRITE setSource)
Q_OBJECT
public:
class DiffFileInfo {
public:
DiffFileInfo() {}
DiffFileInfo(const QString &file) : fileName(file) {}
DiffFileInfo(const QString &file, const QString &type) : fileName(file), typeInfo(type) {}
QString fileName;
QString typeInfo;
};
class DiffFilesContents {
public:
DiffFileInfo leftFileInfo;
QString leftText;
DiffFileInfo rightFileInfo;
QString rightText;
};
DiffEditorController(QObject *parent = 0);
~DiffEditorController();
// QTextCodec *codec() const;
// QString source() const;
// void setSource(const QString &source);
QString clearMessage() const;
QList<DiffFilesContents> diffContents() const;
QString workingDirectory() const;
int contextLinesNumber() const;
bool isIgnoreWhitespaces() const;
bool horizontalScrollBarSynchronization() const;
int currentDiffFileIndex() const;
public slots:
void clear();
void clear(const QString &message);
void setDiffContents(const QList<DiffEditorController::DiffFilesContents> &diffFileList, const QString &workingDirectory = QString());
void setContextLinesNumber(int lines);
void setIgnoreWhitespaces(bool ignore);
void setHorizontalScrollBarSynchronization(bool on);
void setCurrentDiffFileIndex(int diffFileIndex);
signals:
// This sets the current diff file index to -1
void cleared(const QString message);
// This sets the current diff file index to 0 (unless diffFileList is empty)
void diffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList, const QString &workingDirectory);
void contextLinesNumberChanged(int lines);
void ignoreWhitespacesChanged(bool ignore);
void horizontalScrollBarSynchronizationChanged(bool on);
void currentDiffFileIndexChanged(int diffFileIndex);
private:
QString m_clearMessage;
QList<DiffFilesContents> m_diffFileList;
QString m_workingDirectory;
int m_contextLinesNumber;
bool m_ignoreWhitespaces;
bool m_syncScrollBars;
int m_currentDiffFileIndex;
};
} // namespace DiffEditor
#endif // DIFFEDITORCONTROLLER_H
......@@ -49,6 +49,8 @@ DiffEditorFactory::DiffEditorFactory(QObject *parent)
Core::IEditor *DiffEditorFactory::createEditor()
{
DiffEditorWidget *editorWidget = new DiffEditorWidget();
DiffEditorController *editorController = new DiffEditorController(editorWidget);
editorWidget->setDiffEditorController(editorController);
DiffEditor *editor = new DiffEditor(editorWidget);
return editor;
}
......
......@@ -114,12 +114,12 @@ void DiffEditorPlugin::diff()
const QString text1 = getFileContents(fileName1, codec);
const QString text2 = getFileContents(fileName2, codec);
DiffEditorWidget::DiffFilesContents dfc;
DiffEditorController::DiffFilesContents dfc;
dfc.leftFileInfo = fileName1;
dfc.leftText = text1;
dfc.rightFileInfo = fileName2;
dfc.rightText = text2;
QList<DiffEditorWidget::DiffFilesContents> list;
QList<DiffEditorController::DiffFilesContents> list;
list.append(dfc);
editor->setDiff(list);
......
......@@ -64,7 +64,8 @@ using namespace TextEditor;
namespace DiffEditor {
struct TextLineData {
class TextLineData {
public:
enum TextLineType {
TextLine,
Separator,
......@@ -77,7 +78,8 @@ struct TextLineData {
QString text;
};
struct RowData {
class RowData {
public:
RowData() : equal(true) {}
RowData(const TextLineData &l)
: leftLine(l), rightLine(l), equal(true) {}
......@@ -88,7 +90,8 @@ struct RowData {
bool equal; // true if left and right lines are equal, taking whitespaces into account (or both invalid)
};
struct ChunkData {
class ChunkData {
public:
ChunkData() : contextChunk(false) {}
QList<RowData> rows;
bool contextChunk;
......@@ -96,12 +99,13 @@ struct ChunkData {
QMap<int, int> changedRightPositions; // counting from the beginning of the chunk
};
struct FileData {
class FileData {
public:
FileData() {}
FileData(const ChunkData &chunkData) { chunks.append(chunkData); }
QList<ChunkData> chunks;
DiffEditorWidget::DiffFileInfo leftFileInfo;
DiffEditorWidget::DiffFileInfo rightFileInfo;
DiffEditorController::DiffFileInfo leftFileInfo;
DiffEditorController::DiffFileInfo rightFileInfo;
};
//////////////////////
......@@ -132,7 +136,7 @@ public:
~MultiHighlighter();
virtual void setFontSettings(const TextEditor::FontSettings &fontSettings);
void setDocuments(const QList<QPair<DiffEditorWidget::DiffFileInfo, QString> > &documents);
void setDocuments(const QList<QPair<DiffEditorController::DiffFileInfo, QString> > &documents);
protected:
virtual void highlightBlock(const QString &text);
......@@ -150,9 +154,9 @@ class DiffViewEditorWidget : public BaseTextEditorWidget
{
Q_OBJECT
public:
struct ExtendedFileInfo
{
DiffEditorWidget::DiffFileInfo fileInfo;
class ExtendedFileInfo {
public:
DiffEditorController::DiffFileInfo fileInfo;
TextEditor::SyntaxHighlighter *highlighter;
};
......@@ -164,21 +168,20 @@ public:
}
// block number, file info
QMap<int, DiffEditorWidget::DiffFileInfo> fileInfo() const { return m_fileInfo; }
QMap<int, DiffEditorController::DiffFileInfo> fileInfo() const { return m_fileInfo; }
void setLineNumber(int blockNumber, int lineNumber);
void setFileInfo(int blockNumber, const DiffEditorWidget::DiffFileInfo &fileInfo);
void setFileInfo(int blockNumber, const DiffEditorController::DiffFileInfo &fileInfo);
void setSkippedLines(int blockNumber, int skippedLines) { m_skippedLines[blockNumber] = skippedLines; setSeparator(blockNumber, true); }
void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; }
bool isFileLine(int blockNumber) const { return m_fileInfo.contains(blockNumber); }
int blockNumberForFileIndex(int fileIndex) const;
int fileIndexForBlockNumber(int blockNumber) const;
bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); }
void clearAll();
void clearAll(const QString &message);
void clearAllData();
QTextBlock firstVisibleBlock() const { return BaseTextEditorWidget::firstVisibleBlock(); }
void setDocuments(const QList<QPair<DiffEditorWidget::DiffFileInfo, QString> > &documents);
void setDocuments(const QList<QPair<DiffEditorController::DiffFileInfo, QString> > &documents);
public slots:
void setDisplaySettings(const DisplaySettings &ds);
......@@ -216,7 +219,7 @@ private:
QMap<int, int> m_lineNumbers;
int m_lineNumberDigits;
// block number, fileInfo. Set for file lines only.
QMap<int, DiffEditorWidget::DiffFileInfo> m_fileInfo;
QMap<int, DiffEditorController::DiffFileInfo> m_fileInfo;
// block number, skipped lines. Set for chunk lines only.
QMap<int, int> m_skippedLines;
// block number, separator. Set for file, chunk or span line.
......@@ -243,7 +246,7 @@ MultiHighlighter::MultiHighlighter(DiffViewEditorWidget *editor, QTextDocument *
MultiHighlighter::~MultiHighlighter()
{
setDocuments(QList<QPair<DiffEditorWidget::DiffFileInfo, QString> >());
setDocuments(QList<QPair<DiffEditorController::DiffFileInfo, QString> >());
}
void MultiHighlighter::setFontSettings(const TextEditor::FontSettings &fontSettings)
......@@ -256,7 +259,7 @@ void MultiHighlighter::setFontSettings(const TextEditor::FontSettings &fontSetti
}
}
void MultiHighlighter::setDocuments(const QList<QPair<DiffEditorWidget::DiffFileInfo, QString> > &documents)
void MultiHighlighter::setDocuments(const QList<QPair<DiffEditorController::DiffFileInfo, QString> > &documents)
{
// clear old documents
qDeleteAll(m_documents);
......@@ -266,7 +269,7 @@ void MultiHighlighter::setDocuments(const QList<QPair<DiffEditorWidget::DiffFile
// create new documents
for (int i = 0; i < documents.count(); i++) {
DiffEditorWidget::DiffFileInfo fileInfo = documents.at(i).first;
DiffEditorController::DiffFileInfo fileInfo = documents.at(i).first;
const QString contents = documents.at(i).second;
QTextDocument *document = new QTextDocument(contents);
const MimeType mimeType = MimeDatabase::findByFile(QFileInfo(fileInfo.fileName));
......@@ -316,8 +319,8 @@ void DiffViewEditorEditable::slotTooltipRequested(TextEditor::ITextEditor *edito
if (!ew)
return;
QMap<int, DiffEditorWidget::DiffFileInfo> fi = ew->fileInfo();
QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it
QMap<int, DiffEditorController::DiffFileInfo> fi = ew->fileInfo();
QMap<int, DiffEditorController::DiffFileInfo>::const_iterator it
= fi.constFind(ew->document()->findBlock(position).blockNumber());
if (it != fi.constEnd()) {
Utils::ToolTip::show(globalPoint, Utils::TextContent(it.value().fileName),
......@@ -433,7 +436,7 @@ void DiffViewEditorWidget