forked from qt-creator/qt-creator
VCS: Refactor fileNameFromDiffSpecification
Use diff file pattern to match file name. Avoid duplication. Include unit tests for Git Change-Id: Ib68a08368270a27976a3e16bdd1cb219a52b8889 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
57ee50d52f
commit
7b39f41c05
@@ -52,11 +52,13 @@ using namespace Bazaar;
|
|||||||
BazaarEditor::BazaarEditor(const VcsBase::VcsBaseEditorParameters *type, QWidget *parent)
|
BazaarEditor::BazaarEditor(const VcsBase::VcsBaseEditorParameters *type, QWidget *parent)
|
||||||
: VcsBase::VcsBaseEditorWidget(type, parent),
|
: VcsBase::VcsBaseEditorWidget(type, parent),
|
||||||
m_changesetId(QLatin1String(Constants::CHANGESET_ID)),
|
m_changesetId(QLatin1String(Constants::CHANGESET_ID)),
|
||||||
m_exactChangesetId(QLatin1String(Constants::CHANGESET_ID_EXACT)),
|
m_exactChangesetId(QLatin1String(Constants::CHANGESET_ID_EXACT))
|
||||||
m_diffFileId(QLatin1String("^=== [a-z]+ [a-z]+ '(.*)'\\s*"))
|
|
||||||
{
|
{
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate %1"));
|
setAnnotateRevisionTextFormat(tr("Annotate %1"));
|
||||||
setAnnotatePreviousRevisionTextFormat(tr("Annotate parent revision %1"));
|
setAnnotatePreviousRevisionTextFormat(tr("Annotate parent revision %1"));
|
||||||
|
// Diff format:
|
||||||
|
// === <change> <file|dir> 'mainwindow.cpp'
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String("^=== [a-z]+ [a-z]+ '(.+)'\\s*")));
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> BazaarEditor::annotationChanges() const
|
QSet<QString> BazaarEditor::annotationChanges() const
|
||||||
@@ -111,25 +113,8 @@ QString BazaarEditor::changeUnderCursor(const QTextCursor &cursorIn) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp BazaarEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return m_diffFileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *BazaarEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *BazaarEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new BazaarAnnotationHighlighter(changes, bg);
|
return new BazaarAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BazaarEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// Check for:
|
|
||||||
// === <change> <file|dir> 'mainwindow.cpp'
|
|
||||||
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
|
|
||||||
const QString line = block.text();
|
|
||||||
if (m_diffFileId.indexIn(line) != -1)
|
|
||||||
return findDiffFile(m_diffFileId.cap(1));
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
@@ -46,13 +46,10 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &cursor) const;
|
QString changeUnderCursor(const QTextCursor &cursor) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const;
|
|
||||||
|
|
||||||
mutable QRegExp m_changesetId;
|
mutable QRegExp m_changesetId;
|
||||||
mutable QRegExp m_exactChangesetId;
|
mutable QRegExp m_exactChangesetId;
|
||||||
mutable QRegExp m_diffFileId;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -591,6 +591,41 @@ void BazaarPlugin::diffFromEditorSelected(const QStringList &files)
|
|||||||
m_client->diff(m_submitRepository, files);
|
m_client->diff(m_submitRepository, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
void BazaarPlugin::testDiffFileResolving_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>("header");
|
||||||
|
QTest::addColumn<QByteArray>("fileName");
|
||||||
|
|
||||||
|
QTest::newRow("New") << QByteArray(
|
||||||
|
"=== added file 'src/plugins/bazaar/bazaareditor.cpp'\n"
|
||||||
|
"--- src/plugins/bazaar/bazaareditor.cpp\t1970-01-01 00:00:00 +0000\n"
|
||||||
|
"+++ src/plugins/bazaar/bazaareditor.cpp\t2013-01-20 21:39:47 +0000\n"
|
||||||
|
"@@ -0,0 +1,121 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/bazaar/bazaareditor.cpp");
|
||||||
|
QTest::newRow("Deleted") << QByteArray(
|
||||||
|
"=== removed file 'src/plugins/bazaar/bazaareditor.cpp'\n"
|
||||||
|
"--- src/plugins/bazaar/bazaareditor.cpp\t2013-01-20 21:39:47 +0000\n"
|
||||||
|
"+++ src/plugins/bazaar/bazaareditor.cpp\t1970-01-01 00:00:00 +0000\n"
|
||||||
|
"@@ -1,121 +0,0 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/bazaar/bazaareditor.cpp");
|
||||||
|
QTest::newRow("Modified") << QByteArray(
|
||||||
|
"=== modified file 'src/plugins/bazaar/bazaareditor.cpp'\n"
|
||||||
|
"--- src/plugins/bazaar/bazaareditor.cpp\t2010-08-27 14:12:44 +0000\n"
|
||||||
|
"+++ src/plugins/bazaar/bazaareditor.cpp\t2011-02-28 21:24:19 +0000\n"
|
||||||
|
"@@ -727,6 +727,9 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/bazaar/bazaareditor.cpp");
|
||||||
|
}
|
||||||
|
|
||||||
|
void BazaarPlugin::testDiffFileResolving()
|
||||||
|
{
|
||||||
|
BazaarEditor editor(editorParameters + 3, 0);
|
||||||
|
VcsBase::VcsBaseEditorWidget::testDiffFileResolving(&editor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void BazaarPlugin::commitFromEditor()
|
void BazaarPlugin::commitFromEditor()
|
||||||
{
|
{
|
||||||
// Close the submit editor
|
// Close the submit editor
|
||||||
|
@@ -112,6 +112,10 @@ private slots:
|
|||||||
void showCommitWidget(const QList<VcsBase::VcsBaseClient::StatusItem> &status);
|
void showCommitWidget(const QList<VcsBase::VcsBaseClient::StatusItem> &status);
|
||||||
void commitFromEditor();
|
void commitFromEditor();
|
||||||
void diffFromEditorSelected(const QStringList &files);
|
void diffFromEditorSelected(const QStringList &files);
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void testDiffFileResolving_data();
|
||||||
|
void testDiffFileResolving();
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
||||||
|
@@ -51,6 +51,12 @@ ClearCaseEditor::ClearCaseEditor(const VcsBase::VcsBaseEditorParameters *type,
|
|||||||
m_versionNumberPattern(QLatin1String("[\\\\/]main[\\\\/][^ \t\n\"]*"))
|
m_versionNumberPattern(QLatin1String("[\\\\/]main[\\\\/][^ \t\n\"]*"))
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_versionNumberPattern.isValid(), return);
|
QTC_ASSERT(m_versionNumberPattern.isValid(), return);
|
||||||
|
// Diff formats:
|
||||||
|
// "+++ D:\depot\...\mainwindow.cpp@@\main\3" (versioned)
|
||||||
|
// "+++ D:\depot\...\mainwindow.cpp[TAB]Sun May 01 14:22:37 2011" (local)
|
||||||
|
QRegExp diffFilePattern(QLatin1String("^[-+]{3} ([^\\t]+)(?:@@|\\t)"));
|
||||||
|
diffFilePattern.setMinimal(true);
|
||||||
|
setDiffFilePattern(diffFilePattern);
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate version \"%1\""));
|
setAnnotateRevisionTextFormat(tr("Annotate version \"%1\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,41 +93,8 @@ QString ClearCaseEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Diff header format (on Windows, native separators are used after the @@)
|
|
||||||
--- main.cpp@@\main\2
|
|
||||||
+++ main.cpp@@\main\1
|
|
||||||
@@ -6,6 +6,5 @@
|
|
||||||
*/
|
|
||||||
QRegExp ClearCaseEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return QRegExp(QLatin1String("^[-+][-+][-+] "));
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *ClearCaseEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *ClearCaseEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new ClearCaseAnnotationHighlighter(changes, bg);
|
return new ClearCaseAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ClearCaseEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// "+++ D:\depot\...\mainwindow.cpp@@\main\3"
|
|
||||||
// "+++ D:\depot\...\mainwindow.cpp[TAB]Sun May 01 14:22:37 2011"
|
|
||||||
// Go back chunks
|
|
||||||
const QString diffIndicator = QLatin1String("+++ ");
|
|
||||||
for (QTextBlock block = inBlock; block.isValid() ; block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(diffIndicator)) {
|
|
||||||
diffFileName.remove(0, diffIndicator.size());
|
|
||||||
const int tabIndex = diffFileName.indexOf(QRegExp(QLatin1String("@@|\t")));
|
|
||||||
if (tabIndex != -1)
|
|
||||||
diffFileName.truncate(tabIndex);
|
|
||||||
const QString rc = findDiffFile(diffFileName);
|
|
||||||
if (ClearCase::Constants::debug)
|
|
||||||
qDebug() << Q_FUNC_INFO << diffFileName << rc << source();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
@@ -49,11 +49,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &) const;
|
QString changeUnderCursor(const QTextCursor &) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
|
|
||||||
|
|
||||||
mutable QRegExp m_versionNumberPattern;
|
QRegExp m_versionNumberPattern;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -96,7 +96,9 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
#include <QTest>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace ClearCase {
|
namespace ClearCase {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -1943,6 +1945,26 @@ void ClearCasePlugin::sync(QFutureInterface<void> &future, QString topLevel, QSt
|
|||||||
ccSync.run(future, topLevel, files);
|
ccSync.run(future, topLevel, files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void ClearCasePlugin::testDiffFileResolving_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>("header");
|
||||||
|
QTest::addColumn<QByteArray>("fileName");
|
||||||
|
|
||||||
|
QTest::newRow("Modified") << QByteArray(
|
||||||
|
"--- src/plugins/clearcase/clearcaseeditor.cpp@@/main/1\t2013-01-20 23:45:48.549615210 +0200\n"
|
||||||
|
"+++ src/plugins/clearcase/clearcaseeditor.cpp@@/main/2\t2013-01-20 23:45:53.217604679 +0200\n"
|
||||||
|
"@@ -58,6 +58,10 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/clearcase/clearcaseeditor.cpp");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearCasePlugin::testDiffFileResolving()
|
||||||
|
{
|
||||||
|
ClearCaseEditor editor(editorParameters + 3, 0);
|
||||||
|
VcsBase::VcsBaseEditorWidget::testDiffFileResolving(&editor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClearCase
|
} // namespace ClearCase
|
||||||
|
|
||||||
|
@@ -192,6 +192,10 @@ private slots:
|
|||||||
void syncSlot();
|
void syncSlot();
|
||||||
void closing();
|
void closing();
|
||||||
void updateStatusActions();
|
void updateStatusActions();
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void testDiffFileResolving_data();
|
||||||
|
void testDiffFileResolving();
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
||||||
|
@@ -55,6 +55,15 @@ CvsEditor::CvsEditor(const VcsBase::VcsBaseEditorParameters *type,
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_revisionAnnotationPattern.isValid(), return);
|
QTC_ASSERT(m_revisionAnnotationPattern.isValid(), return);
|
||||||
QTC_ASSERT(m_revisionLogPattern.isValid(), return);
|
QTC_ASSERT(m_revisionLogPattern.isValid(), return);
|
||||||
|
/* Diff format:
|
||||||
|
\code
|
||||||
|
cvs diff -d -u -r1.1 -r1.2:
|
||||||
|
--- mainwindow.cpp<\t>13 Jul 2009 13:50:15 -0000<tab>1.1
|
||||||
|
+++ mainwindow.cpp<\t>14 Jul 2009 07:09:24 -0000<tab>1.2
|
||||||
|
@@ -6,6 +6,5 @@
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String("^[-+]{3} ([^\\t]+)")));
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\""));
|
setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,42 +122,12 @@ QString CvsEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* \code
|
|
||||||
cvs diff -d -u -r1.1 -r1.2:
|
|
||||||
--- mainwindow.cpp<\t>13 Jul 2009 13:50:15 -0000 <\t>1.1
|
|
||||||
+++ mainwindow.cpp<\t>14 Jul 2009 07:09:24 -0000<\t>1.2
|
|
||||||
@@ -6,6 +6,5 @@
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
QRegExp CvsEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return QRegExp(QLatin1String("^[-+][-+][-+] .*1\\.[\\d\\.]+$"));
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *CvsEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *CvsEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new CvsAnnotationHighlighter(changes, bg);
|
return new CvsAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CvsEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// "+++ mainwindow.cpp<\t>13 Jul 2009 13:50:15 -0000 1.1"
|
|
||||||
// Go back chunks
|
|
||||||
const QString diffIndicator = QLatin1String("+++ ");
|
|
||||||
for (QTextBlock block = inBlock; block.isValid() ; block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(diffIndicator)) {
|
|
||||||
diffFileName.remove(0, diffIndicator.size());
|
|
||||||
const int tabIndex = diffFileName.indexOf(QLatin1Char('\t'));
|
|
||||||
if (tabIndex != -1)
|
|
||||||
diffFileName.truncate(tabIndex);
|
|
||||||
return findDiffFile(diffFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList CvsEditor::annotationPreviousVersions(const QString &revision) const
|
QStringList CvsEditor::annotationPreviousVersions(const QString &revision) const
|
||||||
{
|
{
|
||||||
if (isFirstRevision(revision))
|
if (isFirstRevision(revision))
|
||||||
|
@@ -48,9 +48,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &) const;
|
QString changeUnderCursor(const QTextCursor &) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
|
|
||||||
QStringList annotationPreviousVersions(const QString &revision) const;
|
QStringList annotationPreviousVersions(const QString &revision) const;
|
||||||
|
|
||||||
mutable QRegExp m_revisionAnnotationPattern;
|
mutable QRegExp m_revisionAnnotationPattern;
|
||||||
|
@@ -66,6 +66,13 @@ GitEditor::GitEditor(const VcsBase::VcsBaseEditorParameters *type,
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_changeNumberPattern8.isValid(), return);
|
QTC_ASSERT(m_changeNumberPattern8.isValid(), return);
|
||||||
QTC_ASSERT(m_changeNumberPattern40.isValid(), return);
|
QTC_ASSERT(m_changeNumberPattern40.isValid(), return);
|
||||||
|
/* Diff format:
|
||||||
|
diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp
|
||||||
|
index 40997ff..4e49337 100644
|
||||||
|
--- a/src/plugins/git/giteditor.cpp
|
||||||
|
+++ b/src/plugins/git/giteditor.cpp
|
||||||
|
*/
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String("^(?:diff --git a/|index |[+-]{3} (?:/dev/null|[ab]/(.+$)))")));
|
||||||
setAnnotateRevisionTextFormat(tr("Blame %1"));
|
setAnnotateRevisionTextFormat(tr("Blame %1"));
|
||||||
setAnnotatePreviousRevisionTextFormat(tr("Blame Parent Revision %1"));
|
setAnnotatePreviousRevisionTextFormat(tr("Blame Parent Revision %1"));
|
||||||
}
|
}
|
||||||
@@ -107,46 +114,12 @@ QString GitEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp GitEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return QRegExp(QLatin1String("^(diff --git a/|index |[+-][+-][+-] [ab/]).*$"));
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *GitEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *GitEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new GitAnnotationHighlighter(changes, bg);
|
return new GitAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GitEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// Check for "+++ b/src/plugins/git/giteditor.cpp" (blame and diff)
|
|
||||||
// as well as "--- a/src/plugins/git/giteditor.cpp".
|
|
||||||
// Go back chunks.
|
|
||||||
bool checkForOld = false;
|
|
||||||
|
|
||||||
const QString oldFileIndicator = QLatin1String("--- a/");
|
|
||||||
const QString newFileIndicator = QLatin1String("+++ ");
|
|
||||||
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(oldFileIndicator) && checkForOld) {
|
|
||||||
diffFileName.remove(0, oldFileIndicator.size());
|
|
||||||
checkForOld = false;
|
|
||||||
return diffFileName;
|
|
||||||
} else if (diffFileName.startsWith(newFileIndicator)) {
|
|
||||||
diffFileName.remove(0, newFileIndicator.size());
|
|
||||||
if (diffFileName == QLatin1String("/dev/null")) {
|
|
||||||
checkForOld = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
diffFileName.remove(0, 2); // remove "b/"
|
|
||||||
return findDiffFile(diffFileName);
|
|
||||||
}
|
|
||||||
checkForOld = false;
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the date specification from annotation, which is tabular:
|
/* Remove the date specification from annotation, which is tabular:
|
||||||
\code
|
\code
|
||||||
8ca887aa (author YYYY-MM-DD HH:MM:SS <offset> <line>)<content>
|
8ca887aa (author YYYY-MM-DD HH:MM:SS <offset> <line>)<content>
|
||||||
|
@@ -57,9 +57,7 @@ public slots:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &) const;
|
QString changeUnderCursor(const QTextCursor &) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
|
|
||||||
QString decorateVersion(const QString &revision) const;
|
QString decorateVersion(const QString &revision) const;
|
||||||
QStringList annotationPreviousVersions(const QString &revision) const;
|
QStringList annotationPreviousVersions(const QString &revision) const;
|
||||||
bool isValidRevision(const QString &revision) const;
|
bool isValidRevision(const QString &revision) const;
|
||||||
|
@@ -1253,8 +1253,14 @@ GitClient *GitPlugin::gitClient() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
|
#include "giteditor.h"
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
#include <QTextBlock>
|
||||||
|
#include <QTextDocument>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(FileStates)
|
Q_DECLARE_METATYPE(FileStates)
|
||||||
|
|
||||||
void GitPlugin::testStatusParsing_data()
|
void GitPlugin::testStatusParsing_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<FileStates>("first");
|
QTest::addColumn<FileStates>("first");
|
||||||
@@ -1301,6 +1307,42 @@ void GitPlugin::testStatusParsing()
|
|||||||
else
|
else
|
||||||
QCOMPARE(data.files.at(1).first, second);
|
QCOMPARE(data.files.at(1).first, second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GitPlugin::testDiffFileResolving_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>("header");
|
||||||
|
QTest::addColumn<QByteArray>("fileName");
|
||||||
|
|
||||||
|
QTest::newRow("New") << QByteArray(
|
||||||
|
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"new file mode 100644\n"
|
||||||
|
"index 0000000..40997ff\n"
|
||||||
|
"--- /dev/null\n"
|
||||||
|
"+++ b/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"@@ -0,0 +1,281 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/git/giteditor.cpp");
|
||||||
|
QTest::newRow("Deleted") << QByteArray(
|
||||||
|
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"deleted file mode 100644\n"
|
||||||
|
"index 40997ff..0000000\n"
|
||||||
|
"--- a/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"+++ /dev/null\n"
|
||||||
|
"@@ -1,281 +0,0 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/git/giteditor.cpp");
|
||||||
|
QTest::newRow("Normal") << QByteArray(
|
||||||
|
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"index 69e0b52..8fc974d 100644\n"
|
||||||
|
"--- a/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"+++ b/src/plugins/git/giteditor.cpp\n"
|
||||||
|
"@@ -49,6 +49,8 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/git/giteditor.cpp");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitPlugin::testDiffFileResolving()
|
||||||
|
{
|
||||||
|
GitEditor editor(editorParameters + 3, 0);
|
||||||
|
VcsBase::VcsBaseEditorWidget::testDiffFileResolving(&editor);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Q_EXPORT_PLUGIN(GitPlugin)
|
Q_EXPORT_PLUGIN(GitPlugin)
|
||||||
|
@@ -144,6 +144,8 @@ private slots:
|
|||||||
#ifdef WITH_TESTS
|
#ifdef WITH_TESTS
|
||||||
void testStatusParsing_data();
|
void testStatusParsing_data();
|
||||||
void testStatusParsing();
|
void testStatusParsing();
|
||||||
|
void testDiffFileResolving_data();
|
||||||
|
void testDiffFileResolving();
|
||||||
#endif
|
#endif
|
||||||
protected:
|
protected:
|
||||||
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
||||||
|
@@ -42,7 +42,7 @@ const char CHANGESETID12[] = " ([a-f0-9]{12,12}) "; //match 12 hex chars and cap
|
|||||||
const char CHANGESETID40[] = " ([a-f0-9]{40,40}) ";
|
const char CHANGESETID40[] = " ([a-f0-9]{40,40}) ";
|
||||||
const char CHANGEIDEXACT12[] = "[a-f0-9]{12,12}"; //match 12 hex chars a
|
const char CHANGEIDEXACT12[] = "[a-f0-9]{12,12}"; //match 12 hex chars a
|
||||||
const char CHANGEIDEXACT40[] = "[a-f0-9]{40,40}";
|
const char CHANGEIDEXACT40[] = "[a-f0-9]{40,40}";
|
||||||
const char DIFFIDENTIFIER[] = "^[-+]{3,3} [ab]{1,1}.*"; // match e.g. +++ b/filename
|
const char DIFFIDENTIFIER[] = "^[-+]{3} [ab]/(.+)$"; // match e.g. +++ b/filename
|
||||||
|
|
||||||
// Base editor parameters
|
// Base editor parameters
|
||||||
const char COMMANDLOG_ID[] = "Mercurial Command Log Editor";
|
const char COMMANDLOG_ID[] = "Mercurial Command Log Editor";
|
||||||
|
@@ -51,9 +51,9 @@ MercurialEditor::MercurialEditor(const VcsBase::VcsBaseEditorParameters *type, Q
|
|||||||
exactIdentifier12(QLatin1String(Constants::CHANGEIDEXACT12)),
|
exactIdentifier12(QLatin1String(Constants::CHANGEIDEXACT12)),
|
||||||
exactIdentifier40(QLatin1String(Constants::CHANGEIDEXACT40)),
|
exactIdentifier40(QLatin1String(Constants::CHANGEIDEXACT40)),
|
||||||
changesetIdentifier12(QLatin1String(Constants::CHANGESETID12)),
|
changesetIdentifier12(QLatin1String(Constants::CHANGESETID12)),
|
||||||
changesetIdentifier40(QLatin1String(Constants::CHANGESETID40)),
|
changesetIdentifier40(QLatin1String(Constants::CHANGESETID40))
|
||||||
diffIdentifier(QLatin1String(Constants::DIFFIDENTIFIER))
|
|
||||||
{
|
{
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String(Constants::DIFFIDENTIFIER)));
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate %1"));
|
setAnnotateRevisionTextFormat(tr("Annotate %1"));
|
||||||
setAnnotatePreviousRevisionTextFormat(tr("Annotate parent revision %1"));
|
setAnnotatePreviousRevisionTextFormat(tr("Annotate parent revision %1"));
|
||||||
}
|
}
|
||||||
@@ -88,33 +88,12 @@ QString MercurialEditor::changeUnderCursor(const QTextCursor &cursorIn) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp MercurialEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return diffIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *MercurialEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *MercurialEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new MercurialAnnotationHighlighter(changes, bg);
|
return new MercurialAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MercurialEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// git-compatible format: check for "+++ b/src/plugins/git/giteditor.cpp" (blame and diff)
|
|
||||||
// Go back chunks.
|
|
||||||
const QString newFileIndicator = QLatin1String("+++ b/");
|
|
||||||
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(newFileIndicator)) {
|
|
||||||
diffFileName.remove(0, newFileIndicator.size());
|
|
||||||
return findDiffFile(diffFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MercurialEditor::decorateVersion(const QString &revision) const
|
QString MercurialEditor::decorateVersion(const QString &revision) const
|
||||||
{
|
{
|
||||||
const QFileInfo fi(source());
|
const QFileInfo fi(source());
|
||||||
|
@@ -46,9 +46,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &cursor) const;
|
QString changeUnderCursor(const QTextCursor &cursor) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const;
|
|
||||||
QString decorateVersion(const QString &revision) const;
|
QString decorateVersion(const QString &revision) const;
|
||||||
QStringList annotationPreviousVersions(const QString &revision) const;
|
QStringList annotationPreviousVersions(const QString &revision) const;
|
||||||
|
|
||||||
@@ -56,7 +54,6 @@ private:
|
|||||||
mutable QRegExp exactIdentifier40;
|
mutable QRegExp exactIdentifier40;
|
||||||
mutable QRegExp changesetIdentifier12;
|
mutable QRegExp changesetIdentifier12;
|
||||||
const QRegExp changesetIdentifier40;
|
const QRegExp changesetIdentifier40;
|
||||||
const QRegExp diffIdentifier;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -63,6 +63,10 @@ PerforceEditor::PerforceEditor(const VcsBase::VcsBaseEditorParameters *type,
|
|||||||
m_plugin(PerforcePlugin::perforcePluginInstance())
|
m_plugin(PerforcePlugin::perforcePluginInstance())
|
||||||
{
|
{
|
||||||
QTC_CHECK(m_changeNumberPattern.isValid());
|
QTC_CHECK(m_changeNumberPattern.isValid());
|
||||||
|
// Diff format:
|
||||||
|
// 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ====" (created by p4 diff)
|
||||||
|
// 2) "==== //depot/.../mainwindow.cpp#15 (text) ====" (created by p4 describe)
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String("^==== (.+)#\\d")));
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
|
setAnnotateRevisionTextFormat(tr("Annotate change list \"%1\""));
|
||||||
if (Perforce::Constants::debug)
|
if (Perforce::Constants::debug)
|
||||||
qDebug() << "PerforceEditor::PerforceEditor" << type->type << type->id;
|
qDebug() << "PerforceEditor::PerforceEditor" << type->type << type->id;
|
||||||
@@ -103,57 +107,19 @@ QString PerforceEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
return m_changeNumberPattern.exactMatch(change) ? change : QString();
|
return m_changeNumberPattern.exactMatch(change) ? change : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRegExp PerforceEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return QRegExp(QLatin1String("^====.*"));
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *PerforceEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *PerforceEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new PerforceAnnotationHighlighter(changes, bg);
|
return new PerforceAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PerforceEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
QString PerforceEditor::findDiffFile(const QString &f) const
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
const QString diffIndicator = QLatin1String("==== ");
|
const QString fileName = m_plugin->fileNameFromPerforceName(f.trimmed(), false, &errorMessage);
|
||||||
const QString diffEndIndicator = QLatin1String(" ====");
|
|
||||||
// Go back chunks. Note that for 'describe', an extra, empty line
|
|
||||||
// occurs.
|
|
||||||
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(diffIndicator) && diffFileName.endsWith(diffEndIndicator)) {
|
|
||||||
// Split:
|
|
||||||
// 1) "==== //depot/.../mainwindow.cpp#2 - /depot/.../mainwindow.cpp ===="
|
|
||||||
// (as created by p4 diff) or
|
|
||||||
// 2) "==== //depot/.../mainwindow.cpp#15 (text) ===="
|
|
||||||
// (as created by p4 describe).
|
|
||||||
diffFileName.remove(0, diffIndicator.size());
|
|
||||||
diffFileName.truncate(diffFileName.size() - diffEndIndicator.size());
|
|
||||||
const int separatorPos = diffFileName.indexOf(QLatin1String(" - "));
|
|
||||||
if (separatorPos == -1) {
|
|
||||||
// ==== depot path (text) ==== (p4 describe)
|
|
||||||
const int blankPos = diffFileName.indexOf(QLatin1Char(' '));
|
|
||||||
if (blankPos == -1)
|
|
||||||
return QString();
|
|
||||||
diffFileName.truncate(blankPos);
|
|
||||||
} else {
|
|
||||||
// ==== depot path - local path ==== (p4 diff)
|
|
||||||
diffFileName.truncate(separatorPos);
|
|
||||||
}
|
|
||||||
// Split off revision "#4"
|
|
||||||
const int revisionPos = diffFileName.lastIndexOf(QLatin1Char('#'));
|
|
||||||
if (revisionPos != -1 && revisionPos < diffFileName.length() - 1)
|
|
||||||
diffFileName.truncate(revisionPos);
|
|
||||||
// Ask plugin to map back
|
|
||||||
const QString fileName = m_plugin->fileNameFromPerforceName(diffFileName.trimmed(), false, &errorMessage);
|
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
qWarning("%s", qPrintable(errorMessage));
|
qWarning("%s", qPrintable(errorMessage));
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList PerforceEditor::annotationPreviousVersions(const QString &v) const
|
QStringList PerforceEditor::annotationPreviousVersions(const QString &v) const
|
||||||
|
@@ -50,9 +50,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &) const;
|
QString changeUnderCursor(const QTextCursor &) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
|
QString findDiffFile(const QString &f) const;
|
||||||
QStringList annotationPreviousVersions(const QString &v) const;
|
QStringList annotationPreviousVersions(const QString &v) const;
|
||||||
|
|
||||||
mutable QRegExp m_changeNumberPattern;
|
mutable QRegExp m_changeNumberPattern;
|
||||||
|
@@ -52,6 +52,16 @@ SubversionEditor::SubversionEditor(const VcsBase::VcsBaseEditorParameters *type,
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_changeNumberPattern.isValid(), return);
|
QTC_ASSERT(m_changeNumberPattern.isValid(), return);
|
||||||
QTC_ASSERT(m_revisionNumberPattern.isValid(), return);
|
QTC_ASSERT(m_revisionNumberPattern.isValid(), return);
|
||||||
|
/* Diff pattern:
|
||||||
|
\code
|
||||||
|
Index: main.cpp
|
||||||
|
===================================================================
|
||||||
|
--- main.cpp<tab>(revision 2)
|
||||||
|
+++ main.cpp<tab>(working copy)
|
||||||
|
@@ -6,6 +6,5 @@
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
setDiffFilePattern(QRegExp(QLatin1String("^[-+]{3} ([^\\t]+)|^Index: .*|^=+$")));
|
||||||
setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\""));
|
setAnnotateRevisionTextFormat(tr("Annotate revision \"%1\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,46 +108,12 @@ QString SubversionEditor::changeUnderCursor(const QTextCursor &c) const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* code:
|
|
||||||
Index: main.cpp
|
|
||||||
===================================================================
|
|
||||||
--- main.cpp (revision 2)
|
|
||||||
+++ main.cpp (working copy)
|
|
||||||
@@ -6,6 +6,5 @@
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
QRegExp SubversionEditor::diffFilePattern() const
|
|
||||||
{
|
|
||||||
return QRegExp(QLatin1String("^[-+][-+][-+] .*|^Index: .*|^==*$"));
|
|
||||||
}
|
|
||||||
|
|
||||||
VcsBase::BaseAnnotationHighlighter *SubversionEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
VcsBase::BaseAnnotationHighlighter *SubversionEditor::createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const
|
const QColor &bg) const
|
||||||
{
|
{
|
||||||
return new SubversionAnnotationHighlighter(changes, bg);
|
return new SubversionAnnotationHighlighter(changes, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SubversionEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
|
||||||
{
|
|
||||||
// "+++ /depot/.../mainwindow.cpp<tab>(revision 3)"
|
|
||||||
// Go back chunks
|
|
||||||
const QString diffIndicator = QLatin1String("+++ ");
|
|
||||||
for (QTextBlock block = inBlock; block.isValid() ; block = block.previous()) {
|
|
||||||
QString diffFileName = block.text();
|
|
||||||
if (diffFileName.startsWith(diffIndicator)) {
|
|
||||||
diffFileName.remove(0, diffIndicator.size());
|
|
||||||
const int tabIndex = diffFileName.lastIndexOf(QLatin1Char('\t'));
|
|
||||||
if (tabIndex != -1)
|
|
||||||
diffFileName.truncate(tabIndex);
|
|
||||||
const QString rc = findDiffFile(diffFileName);
|
|
||||||
if (Subversion::Constants::debug)
|
|
||||||
qDebug() << Q_FUNC_INFO << diffFileName << rc << source();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList SubversionEditor::annotationPreviousVersions(const QString &v) const
|
QStringList SubversionEditor::annotationPreviousVersions(const QString &v) const
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
|
@@ -48,9 +48,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QSet<QString> annotationChanges() const;
|
QSet<QString> annotationChanges() const;
|
||||||
QString changeUnderCursor(const QTextCursor &) const;
|
QString changeUnderCursor(const QTextCursor &) const;
|
||||||
QRegExp diffFilePattern() const;
|
|
||||||
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
|
||||||
QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
|
|
||||||
QStringList annotationPreviousVersions(const QString &) const;
|
QStringList annotationPreviousVersions(const QString &) const;
|
||||||
|
|
||||||
mutable QRegExp m_changeNumberPattern;
|
mutable QRegExp m_changeNumberPattern;
|
||||||
|
@@ -77,6 +77,10 @@
|
|||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
#include <QTest>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Subversion {
|
namespace Subversion {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -1389,6 +1393,42 @@ SubversionControl *SubversionPlugin::subVersionControl() const
|
|||||||
return static_cast<SubversionControl *>(versionControl());
|
return static_cast<SubversionControl *>(versionControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void SubversionPlugin::testDiffFileResolving_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>("header");
|
||||||
|
QTest::addColumn<QByteArray>("fileName");
|
||||||
|
|
||||||
|
QTest::newRow("New") << QByteArray(
|
||||||
|
"Index: src/plugins/subversion/subversioneditor.cpp\n"
|
||||||
|
"===================================================================\n"
|
||||||
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 0)\n"
|
||||||
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(revision 0)\n"
|
||||||
|
"@@ -0,0 +125 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/subversion/subversioneditor.cpp");
|
||||||
|
QTest::newRow("Deleted") << QByteArray(
|
||||||
|
"Index: src/plugins/subversion/subversioneditor.cpp\n"
|
||||||
|
"===================================================================\n"
|
||||||
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 42)\n"
|
||||||
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(working copy)\n"
|
||||||
|
"@@ -1,125 +0,0 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/subversion/subversioneditor.cpp");
|
||||||
|
QTest::newRow("Normal") << QByteArray(
|
||||||
|
"Index: src/plugins/subversion/subversioneditor.cpp\n"
|
||||||
|
"===================================================================\n"
|
||||||
|
"--- src/plugins/subversion/subversioneditor.cpp\t(revision 42)\n"
|
||||||
|
"+++ src/plugins/subversion/subversioneditor.cpp\t(working copy)\n"
|
||||||
|
"@@ -120,7 +120,7 @@\n\n")
|
||||||
|
<< QByteArray("src/plugins/subversion/subversioneditor.cpp");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubversionPlugin::testDiffFileResolving()
|
||||||
|
{
|
||||||
|
SubversionEditor editor(editorParameters + 3, 0);
|
||||||
|
VcsBase::VcsBaseEditorWidget::testDiffFileResolving(&editor);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
} // Subversion
|
} // Subversion
|
||||||
|
|
||||||
|
@@ -136,6 +136,10 @@ private slots:
|
|||||||
void diffRepository();
|
void diffRepository();
|
||||||
void statusRepository();
|
void statusRepository();
|
||||||
void updateRepository();
|
void updateRepository();
|
||||||
|
#ifdef WITH_TESTS
|
||||||
|
void testDiffFileResolving_data();
|
||||||
|
void testDiffFileResolving();
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
void updateActions(VcsBase::VcsBasePlugin::ActionState);
|
||||||
|
@@ -116,7 +116,7 @@ DiffFormats DiffHighlighterPrivate::analyzeLine(const QString &text) const
|
|||||||
{
|
{
|
||||||
// Do not match on git "--- a/" as a deleted line, check
|
// Do not match on git "--- a/" as a deleted line, check
|
||||||
// file first
|
// file first
|
||||||
if (m_filePattern.exactMatch(text))
|
if (m_filePattern.indexIn(text) == 0)
|
||||||
return DiffFileFormat;
|
return DiffFileFormat;
|
||||||
if (text.startsWith(m_diffInIndicator))
|
if (text.startsWith(m_diffInIndicator))
|
||||||
return DiffInFormat;
|
return DiffInFormat;
|
||||||
|
@@ -668,17 +668,23 @@ VcsBaseEditorWidget::VcsBaseEditorWidget(const VcsBaseEditorParameters *type, QW
|
|||||||
setMimeType(QLatin1String(d->m_parameters->mimeType));
|
setMimeType(QLatin1String(d->m_parameters->mimeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VcsBaseEditorWidget::setDiffFilePattern(const QRegExp &pattern)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(pattern.isValid() && pattern.captureCount() >= 1, return);
|
||||||
|
d->m_diffFilePattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
void VcsBaseEditorWidget::init()
|
void VcsBaseEditorWidget::init()
|
||||||
{
|
{
|
||||||
switch (d->m_parameters->type) {
|
switch (d->m_parameters->type) {
|
||||||
case RegularCommandOutput:
|
case RegularCommandOutput:
|
||||||
case LogOutput:
|
case LogOutput:
|
||||||
|
break;
|
||||||
case AnnotateOutput:
|
case AnnotateOutput:
|
||||||
// Annotation highlighting depends on contents, which is set later on
|
// Annotation highlighting depends on contents, which is set later on
|
||||||
connect(this, SIGNAL(textChanged()), this, SLOT(slotActivateAnnotation()));
|
connect(this, SIGNAL(textChanged()), this, SLOT(slotActivateAnnotation()));
|
||||||
break;
|
break;
|
||||||
case DiffOutput: {
|
case DiffOutput: {
|
||||||
d->m_diffFilePattern = diffFilePattern();
|
|
||||||
DiffHighlighter *dh = new DiffHighlighter(d->m_diffFilePattern);
|
DiffHighlighter *dh = new DiffHighlighter(d->m_diffFilePattern);
|
||||||
setCodeFoldingSupported(true);
|
setCodeFoldingSupported(true);
|
||||||
baseTextDocument()->setSyntaxHighlighter(dh);
|
baseTextDocument()->setSyntaxHighlighter(dh);
|
||||||
@@ -1429,6 +1435,20 @@ bool VcsBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const
|
|||||||
return VcsBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
|
return VcsBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VcsBaseEditorWidget::fileNameFromDiffSpecification(const QTextBlock &inBlock) const
|
||||||
|
{
|
||||||
|
// Go back chunks
|
||||||
|
for (QTextBlock block = inBlock; block.isValid(); block = block.previous()) {
|
||||||
|
const QString line = block.text();
|
||||||
|
if (d->m_diffFilePattern.indexIn(line) != -1) {
|
||||||
|
QString cap = d->m_diffFilePattern.cap(1);
|
||||||
|
if (!cap.isEmpty())
|
||||||
|
return findDiffFile(cap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
QString VcsBaseEditorWidget::decorateVersion(const QString &revision) const
|
QString VcsBaseEditorWidget::decorateVersion(const QString &revision) const
|
||||||
{
|
{
|
||||||
return revision;
|
return revision;
|
||||||
@@ -1502,4 +1522,18 @@ Core::IEditor* VcsBaseEditorWidget::locateEditorByTag(const QString &tag)
|
|||||||
|
|
||||||
} // namespace VcsBase
|
} // namespace VcsBase
|
||||||
|
|
||||||
|
#if WITH_TESTS
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
void VcsBase::VcsBaseEditorWidget::testDiffFileResolving(VcsBaseEditorWidget *editor)
|
||||||
|
{
|
||||||
|
QFETCH(QByteArray, header);
|
||||||
|
QFETCH(QByteArray, fileName);
|
||||||
|
QTextDocument doc(QString::fromLatin1(header));
|
||||||
|
editor->init();
|
||||||
|
QTextBlock block = doc.lastBlock();
|
||||||
|
QVERIFY(editor->fileNameFromDiffSpecification(block).endsWith(QString::fromLatin1(fileName)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "vcsbaseeditor.moc"
|
#include "vcsbaseeditor.moc"
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QAction;
|
class QAction;
|
||||||
|
class QRegExp;
|
||||||
class QTextCodec;
|
class QTextCodec;
|
||||||
class QTextCursor;
|
class QTextCursor;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -99,6 +100,9 @@ protected:
|
|||||||
// virtual functions).
|
// virtual functions).
|
||||||
explicit VcsBaseEditorWidget(const VcsBaseEditorParameters *type,
|
explicit VcsBaseEditorWidget(const VcsBaseEditorParameters *type,
|
||||||
QWidget *parent);
|
QWidget *parent);
|
||||||
|
// Pattern for diff header. File name must be in the first capture group
|
||||||
|
void setDiffFilePattern(const QRegExp &pattern);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
@@ -180,6 +184,10 @@ public:
|
|||||||
bool setConfigurationWidget(QWidget *w);
|
bool setConfigurationWidget(QWidget *w);
|
||||||
QWidget *configurationWidget() const;
|
QWidget *configurationWidget() const;
|
||||||
|
|
||||||
|
// Returns a local file name from the diff file specification
|
||||||
|
// (text cursor at position above change hunk)
|
||||||
|
QString fileNameFromDiffSpecification(const QTextBlock &inBlock) const;
|
||||||
|
|
||||||
/* Tagging editors: Sometimes, an editor should be re-used, for example, when showing
|
/* Tagging editors: Sometimes, an editor should be re-used, for example, when showing
|
||||||
* a diff of the same file with different diff-options. In order to be able to find
|
* a diff of the same file with different diff-options. In order to be able to find
|
||||||
* the editor, they get a 'tag' containing type and parameters (dynamic property string). */
|
* the editor, they get a 'tag' containing type and parameters (dynamic property string). */
|
||||||
@@ -187,7 +195,6 @@ public:
|
|||||||
static Core::IEditor* locateEditorByTag(const QString &tag);
|
static Core::IEditor* locateEditorByTag(const QString &tag);
|
||||||
static QString editorTag(EditorContentType t, const QString &workingDirectory, const QStringList &files,
|
static QString editorTag(EditorContentType t, const QString &workingDirectory, const QStringList &files,
|
||||||
const QString &revision = QString());
|
const QString &revision = QString());
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// These signals also exist in the opaque editable (IEditor) that is
|
// These signals also exist in the opaque editable (IEditor) that is
|
||||||
// handled by the editor manager for convenience. They are emitted
|
// handled by the editor manager for convenience. They are emitted
|
||||||
@@ -227,25 +234,20 @@ protected:
|
|||||||
/* A helper that can be used to locate a file in a diff in case it
|
/* A helper that can be used to locate a file in a diff in case it
|
||||||
* is relative. Tries to derive the directory from base directory,
|
* is relative. Tries to derive the directory from base directory,
|
||||||
* source and version control. */
|
* source and version control. */
|
||||||
QString findDiffFile(const QString &f) const;
|
virtual QString findDiffFile(const QString &f) const;
|
||||||
|
|
||||||
virtual bool canApplyDiffChunk(const DiffChunk &dc) const;
|
virtual bool canApplyDiffChunk(const DiffChunk &dc) const;
|
||||||
// Revert a patch chunk. Default implementation uses patch.exe
|
// Revert a patch chunk. Default implementation uses patch.exe
|
||||||
virtual bool applyDiffChunk(const DiffChunk &dc, bool revert = false) const;
|
virtual bool applyDiffChunk(const DiffChunk &dc, bool revert = false) const;
|
||||||
|
|
||||||
private:
|
|
||||||
// Implement to return a set of change identifiers in
|
// Implement to return a set of change identifiers in
|
||||||
// annotation mode
|
// annotation mode
|
||||||
virtual QSet<QString> annotationChanges() const = 0;
|
virtual QSet<QString> annotationChanges() const = 0;
|
||||||
// Implement to identify a change number at the cursor position
|
// Implement to identify a change number at the cursor position
|
||||||
virtual QString changeUnderCursor(const QTextCursor &) const = 0;
|
virtual QString changeUnderCursor(const QTextCursor &) const = 0;
|
||||||
// Factory functions for highlighters
|
// Factory functions for highlighters
|
||||||
virtual QRegExp diffFilePattern() const = 0;
|
|
||||||
virtual BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes,
|
virtual BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes,
|
||||||
const QColor &bg) const = 0;
|
const QColor &bg) const = 0;
|
||||||
// Implement to return a local file name from the diff file specification
|
|
||||||
// (text cursor at position above change hunk)
|
|
||||||
virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const = 0;
|
|
||||||
// Implement to return decorated annotation change for "Annotate version"
|
// Implement to return decorated annotation change for "Annotate version"
|
||||||
virtual QString decorateVersion(const QString &revision) const;
|
virtual QString decorateVersion(const QString &revision) const;
|
||||||
// Implement to return the previous version[s] of an annotation change
|
// Implement to return the previous version[s] of an annotation change
|
||||||
@@ -253,6 +255,8 @@ private:
|
|||||||
virtual QStringList annotationPreviousVersions(const QString &revision) const;
|
virtual QStringList annotationPreviousVersions(const QString &revision) const;
|
||||||
// Implement to validate revisions
|
// Implement to validate revisions
|
||||||
virtual bool isValidRevision(const QString &revision) const;
|
virtual bool isValidRevision(const QString &revision) const;
|
||||||
|
|
||||||
|
private:
|
||||||
// cut out chunk and determine file name.
|
// cut out chunk and determine file name.
|
||||||
DiffChunk diffChunk(QTextCursor cursor) const;
|
DiffChunk diffChunk(QTextCursor cursor) const;
|
||||||
|
|
||||||
@@ -260,6 +264,11 @@ private:
|
|||||||
|
|
||||||
friend class Internal::ChangeTextCursorHandler;
|
friend class Internal::ChangeTextCursorHandler;
|
||||||
Internal::VcsBaseEditorWidgetPrivate *const d;
|
Internal::VcsBaseEditorWidgetPrivate *const d;
|
||||||
|
|
||||||
|
#if WITH_TESTS
|
||||||
|
public:
|
||||||
|
static void testDiffFileResolving(VcsBaseEditorWidget *editor);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VcsBase
|
} // namespace VcsBase
|
||||||
|
Reference in New Issue
Block a user