forked from qt-creator/qt-creator
VCS: Handle code folding in diff view
Allow to do codefolding on files and hunks in the diff editor
This commit is contained in:
@@ -114,7 +114,7 @@ QString GitEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
|
|
||||||
VCSBase::DiffHighlighter *GitEditor::createDiffHighlighter() const
|
VCSBase::DiffHighlighter *GitEditor::createDiffHighlighter() const
|
||||||
{
|
{
|
||||||
const QRegExp filePattern(QLatin1String("^[-+][-+][-+] [ab].*"));
|
const QRegExp filePattern(QLatin1String("^(diff --git a/|index |[+-][+-][+-] [ab]).*$"));
|
||||||
return new VCSBase::DiffHighlighter(filePattern);
|
return new VCSBase::DiffHighlighter(filePattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
|
|
||||||
#include "diffhighlighter.h"
|
#include "diffhighlighter.h"
|
||||||
|
|
||||||
|
#include <texteditor/basetextdocumentlayout.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
@@ -36,7 +38,12 @@
|
|||||||
#include <QtCore/QRegExp>
|
#include <QtCore/QRegExp>
|
||||||
#include <QtGui/QBrush>
|
#include <QtGui/QBrush>
|
||||||
|
|
||||||
|
static const int BASE_LEVEL = 0;
|
||||||
|
static const int FILE_LEVEL = 1;
|
||||||
|
static const int LOCATION_LEVEL = 2;
|
||||||
|
|
||||||
namespace VCSBase {
|
namespace VCSBase {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
// Formats used by DiffHighlighter
|
// Formats used by DiffHighlighter
|
||||||
enum DiffFormats {
|
enum DiffFormats {
|
||||||
@@ -48,8 +55,16 @@ enum DiffFormats {
|
|||||||
NumDiffFormats
|
NumDiffFormats
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FoldingState {
|
||||||
|
StartOfFile,
|
||||||
|
Header,
|
||||||
|
File,
|
||||||
|
Location
|
||||||
|
};
|
||||||
|
|
||||||
// --- DiffHighlighterPrivate
|
// --- DiffHighlighterPrivate
|
||||||
struct DiffHighlighterPrivate {
|
class DiffHighlighterPrivate {
|
||||||
|
public:
|
||||||
DiffHighlighterPrivate(const QRegExp &filePattern);
|
DiffHighlighterPrivate(const QRegExp &filePattern);
|
||||||
inline DiffFormats analyzeLine(const QString &block) const;
|
inline DiffFormats analyzeLine(const QString &block) const;
|
||||||
|
|
||||||
@@ -59,13 +74,16 @@ struct DiffHighlighterPrivate {
|
|||||||
const QChar m_diffOutIndicator;
|
const QChar m_diffOutIndicator;
|
||||||
QTextCharFormat m_formats[NumDiffFormats];
|
QTextCharFormat m_formats[NumDiffFormats];
|
||||||
QTextCharFormat m_addedTrailingWhiteSpaceFormat;
|
QTextCharFormat m_addedTrailingWhiteSpaceFormat;
|
||||||
|
|
||||||
|
FoldingState m_foldingState;
|
||||||
};
|
};
|
||||||
|
|
||||||
DiffHighlighterPrivate::DiffHighlighterPrivate(const QRegExp &filePattern) :
|
DiffHighlighterPrivate::DiffHighlighterPrivate(const QRegExp &filePattern) :
|
||||||
m_filePattern(filePattern),
|
m_filePattern(filePattern),
|
||||||
m_locationIndicator(QLatin1String("@@")),
|
m_locationIndicator(QLatin1String("@@")),
|
||||||
m_diffInIndicator(QLatin1Char('+')),
|
m_diffInIndicator(QLatin1Char('+')),
|
||||||
m_diffOutIndicator(QLatin1Char('-'))
|
m_diffOutIndicator(QLatin1Char('-')),
|
||||||
|
m_foldingState(StartOfFile)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(filePattern.isValid(), /**/);
|
QTC_ASSERT(filePattern.isValid(), /**/);
|
||||||
}
|
}
|
||||||
@@ -85,11 +103,13 @@ DiffFormats DiffHighlighterPrivate::analyzeLine(const QString &text) const
|
|||||||
return DiffTextFormat;
|
return DiffTextFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
// --- DiffHighlighter
|
// --- DiffHighlighter
|
||||||
DiffHighlighter::DiffHighlighter(const QRegExp &filePattern,
|
DiffHighlighter::DiffHighlighter(const QRegExp &filePattern,
|
||||||
QTextDocument *document) :
|
QTextDocument *document) :
|
||||||
TextEditor::SyntaxHighlighter(document),
|
TextEditor::SyntaxHighlighter(document),
|
||||||
m_d(new DiffHighlighterPrivate(filePattern))
|
m_d(new Internal::DiffHighlighterPrivate(filePattern))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,11 +133,11 @@ void DiffHighlighter::highlightBlock(const QString &text)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const int length = text.length();
|
const int length = text.length();
|
||||||
const DiffFormats format = m_d->analyzeLine(text);
|
const Internal::DiffFormats format = m_d->analyzeLine(text);
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case DiffTextFormat:
|
case Internal::DiffTextFormat:
|
||||||
break;
|
break;
|
||||||
case DiffInFormat: {
|
case Internal::DiffInFormat: {
|
||||||
// Mark trailing whitespace.
|
// Mark trailing whitespace.
|
||||||
const int trimmedLen = trimmedLength(text);
|
const int trimmedLen = trimmedLength(text);
|
||||||
setFormat(0, trimmedLen, m_d->m_formats[format]);
|
setFormat(0, trimmedLen, m_d->m_formats[format]);
|
||||||
@@ -129,6 +149,61 @@ void DiffHighlighter::highlightBlock(const QString &text)
|
|||||||
setFormat(0, length, m_d->m_formats[format]);
|
setFormat(0, length, m_d->m_formats[format]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// codefolding:
|
||||||
|
TextEditor::TextBlockUserData *data =
|
||||||
|
TextEditor::BaseTextDocumentLayout::userData(currentBlock());
|
||||||
|
Q_ASSERT(data);
|
||||||
|
if (!TextEditor::BaseTextDocumentLayout::testUserData(currentBlock().previous()))
|
||||||
|
m_d->m_foldingState = Internal::StartOfFile;
|
||||||
|
|
||||||
|
switch (m_d->m_foldingState) {
|
||||||
|
case Internal::StartOfFile:
|
||||||
|
case Internal::Header:
|
||||||
|
switch (format) {
|
||||||
|
case Internal::DiffFileFormat:
|
||||||
|
m_d->m_foldingState = Internal::File;
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
||||||
|
break;
|
||||||
|
case Internal::DiffLocationFormat:
|
||||||
|
m_d->m_foldingState = Internal::Location;
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
m_d->m_foldingState = Internal::Header;
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Internal::File:
|
||||||
|
switch (format) {
|
||||||
|
case Internal::DiffFileFormat:
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
||||||
|
break;
|
||||||
|
case Internal::DiffLocationFormat:
|
||||||
|
m_d->m_foldingState = Internal::Location;
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Internal::Location:
|
||||||
|
switch (format) {
|
||||||
|
case Internal::DiffFileFormat:
|
||||||
|
m_d->m_foldingState = Internal::File;
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), BASE_LEVEL);
|
||||||
|
break;
|
||||||
|
case Internal::DiffLocationFormat:
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), FILE_LEVEL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), LOCATION_LEVEL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QTextCharFormat invertedColorFormat(const QTextCharFormat &in)
|
static inline QTextCharFormat invertedColorFormat(const QTextCharFormat &in)
|
||||||
@@ -141,10 +216,11 @@ static inline QTextCharFormat invertedColorFormat(const QTextCharFormat &in)
|
|||||||
|
|
||||||
void DiffHighlighter::setFormats(const QVector<QTextCharFormat> &s)
|
void DiffHighlighter::setFormats(const QVector<QTextCharFormat> &s)
|
||||||
{
|
{
|
||||||
if (s.size() == NumDiffFormats) {
|
if (s.size() == Internal::NumDiffFormats) {
|
||||||
qCopy(s.constBegin(), s.constEnd(), m_d->m_formats);
|
qCopy(s.constBegin(), s.constEnd(), m_d->m_formats);
|
||||||
// Display trailing blanks with colors swapped
|
// Display trailing blanks with colors swapped
|
||||||
m_d->m_addedTrailingWhiteSpaceFormat = invertedColorFormat(m_d->m_formats[DiffInFormat]);
|
m_d->m_addedTrailingWhiteSpaceFormat =
|
||||||
|
invertedColorFormat(m_d->m_formats[Internal::DiffInFormat]);
|
||||||
} else {
|
} else {
|
||||||
qWarning("%s: insufficient setting size: %d", Q_FUNC_INFO, s.size());
|
qWarning("%s: insufficient setting size: %d", Q_FUNC_INFO, s.size());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ namespace TextEditor {
|
|||||||
|
|
||||||
namespace VCSBase {
|
namespace VCSBase {
|
||||||
|
|
||||||
struct DiffHighlighterPrivate;
|
namespace Internal {
|
||||||
|
class DiffHighlighterPrivate;
|
||||||
|
} // namespace Internal
|
||||||
|
|
||||||
/* A highlighter for diffs. Parametrizable by the file indicator,
|
/* A highlighter for diffs. Parametrizable by the file indicator,
|
||||||
* which is for example '^====' in case of p4:
|
* which is for example '^====' in case of p4:
|
||||||
@@ -81,7 +83,7 @@ public:
|
|||||||
QRegExp filePattern() const;
|
QRegExp filePattern() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DiffHighlighterPrivate *m_d;
|
Internal::DiffHighlighterPrivate *m_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VCSBase
|
} // namespace VCSBase
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ void VCSBaseEditor::init()
|
|||||||
break;
|
break;
|
||||||
case DiffOutput: {
|
case DiffOutput: {
|
||||||
DiffHighlighter *dh = createDiffHighlighter();
|
DiffHighlighter *dh = createDiffHighlighter();
|
||||||
|
setCodeFoldingSupported(true);
|
||||||
baseTextDocument()->setSyntaxHighlighter(dh);
|
baseTextDocument()->setSyntaxHighlighter(dh);
|
||||||
d->m_diffFilePattern = dh->filePattern();
|
d->m_diffFilePattern = dh->filePattern();
|
||||||
connect(this, SIGNAL(textChanged()), this, SLOT(slotPopulateDiffBrowser()));
|
connect(this, SIGNAL(textChanged()), this, SLOT(slotPopulateDiffBrowser()));
|
||||||
|
|||||||
Reference in New Issue
Block a user