Prepare for patch generation, fix internals.

Change-Id: Ib3b7c5c433f9f9230eb14d23a3029681841e2e68
Reviewed-by: Jarek Kobus <jaroslaw.kobus@digia.com>
This commit is contained in:
jkobus
2014-02-27 16:16:11 +01:00
committed by Jarek Kobus
parent 5d2cd2e56d
commit 0ba55199b2
4 changed files with 129 additions and 83 deletions

View File

@@ -97,6 +97,7 @@ public:
ChunkData() : contextChunk(false) {}
QList<RowData> rows;
bool contextChunk;
// start position, end position, TextLineData::Separator lines not taken into account
QMap<int, int> changedLeftPositions; // counting from the beginning of the chunk
QMap<int, int> changedRightPositions; // counting from the beginning of the chunk
};
@@ -113,49 +114,16 @@ public:
//////////////////////
static QList<TextLineData> assemblyRows(const QStringList &lines,
const QMap<int, int> &lineSpans,
const QMap<int, int> &changedPositions,
QMap<int, int> *outputChangedPositions)
const QMap<int, int> &lineSpans)
{
QList<TextLineData> data;
int previousSpanOffset = 0;
int spanOffset = 0;
int pos = 0;
bool usePreviousSpanOffsetForStartPosition = false;
QMap<int, int>::ConstIterator changedIt = changedPositions.constBegin();
QMap<int, int>::ConstIterator changedEnd = changedPositions.constEnd();
const int lineCount = lines.count();
for (int i = 0; i <= lineCount; i++) {
for (int j = 0; j < lineSpans.value(i); j++) {
for (int j = 0; j < lineSpans.value(i); j++)
data.append(TextLineData(TextLineData::Separator));
spanOffset++;
}
if (i < lineCount) {
const int textLength = lines.at(i).count() + 1;
pos += textLength;
if (i < lineCount)
data.append(lines.at(i));
}
while (changedIt != changedEnd) {
if (changedIt.key() >= pos)
break;
if (changedIt.value() >= pos) {
usePreviousSpanOffsetForStartPosition = true;
previousSpanOffset = spanOffset;
break;
}
const int startSpanOffset = usePreviousSpanOffsetForStartPosition
? previousSpanOffset : spanOffset;
usePreviousSpanOffsetForStartPosition = false;
const int startPos = changedIt.key() + startSpanOffset;
const int endPos = changedIt.value() + spanOffset;
if (outputChangedPositions)
outputChangedPositions->insert(startPos, endPos);
++changedIt;
}
}
return data;
}
@@ -221,9 +189,6 @@ static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
QStringList leftLines;
QStringList rightLines;
// <start position, end position>
QMap<int, int> leftChangedPositions;
QMap<int, int> rightChangedPositions;
// <line number, span count>
QMap<int, int> leftSpans;
QMap<int, int> rightSpans;
@@ -248,13 +213,13 @@ static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
if (leftDiff.command == Diff::Delete) {
// process delete
handleDifference(leftDiff.text, &leftLines, &leftChangedPositions, &leftLineNumber, &leftCharNumber);
handleDifference(leftDiff.text, &leftLines, &chunkData.changedLeftPositions, &leftLineNumber, &leftCharNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines);
i++;
}
if (rightDiff.command == Diff::Insert) {
// process insert
handleDifference(rightDiff.text, &rightLines, &rightChangedPositions, &rightLineNumber, &rightCharNumber);
handleDifference(rightDiff.text, &rightLines, &chunkData.changedRightPositions, &rightLineNumber, &rightCharNumber);
lastLineEqual = lastLinesEqual(leftLines, rightLines);
j++;
}
@@ -326,13 +291,9 @@ static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
}
QList<TextLineData> leftData = assemblyRows(leftLines,
leftSpans,
leftChangedPositions,
&chunkData.changedLeftPositions);
leftSpans);
QList<TextLineData> rightData = assemblyRows(rightLines,
rightSpans,
rightChangedPositions,
&chunkData.changedRightPositions);
rightSpans);
// fill ending separators
for (int i = leftData.count(); i < rightData.count(); i++)
@@ -1230,6 +1191,8 @@ FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &origi
int rightCharCounter = 0;
QMap<int, int>::ConstIterator leftChangedIt = originalData.changedLeftPositions.constBegin();
QMap<int, int>::ConstIterator rightChangedIt = originalData.changedRightPositions.constBegin();
const QMap<int, int>::ConstIterator leftChangedItEnd = originalData.changedLeftPositions.constEnd();
const QMap<int, int>::ConstIterator rightChangedItEnd = originalData.changedRightPositions.constEnd();
while (i < originalData.rows.count()) {
if (!hiddenRows.contains(i)) {
ChunkData chunkData;
@@ -1242,11 +1205,13 @@ FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &origi
RowData rowData = originalData.rows.at(i);
chunkData.rows.append(rowData);
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
if (rowData.leftLine.textLineType == TextLineData::TextLine)
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
if (rowData.rightLine.textLineType == TextLineData::TextLine)
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
i++;
}
while (leftChangedIt != originalData.changedLeftPositions.constEnd()) {
while (leftChangedIt != leftChangedItEnd) {
if (leftChangedIt.key() < leftOffset
|| leftChangedIt.key() > leftCharCounter)
break;
@@ -1256,7 +1221,7 @@ FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &origi
chunkData.changedLeftPositions.insert(startPos - leftOffset, endPos - leftOffset);
leftChangedIt++;
}
while (rightChangedIt != originalData.changedRightPositions.constEnd()) {
while (rightChangedIt != rightChangedItEnd) {
if (rightChangedIt.key() < rightOffset
|| rightChangedIt.key() > rightCharCounter)
break;
@@ -1276,8 +1241,10 @@ FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &origi
RowData rowData = originalData.rows.at(i);
chunkData.rows.append(rowData);
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
if (rowData.leftLine.textLineType == TextLineData::TextLine)
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
if (rowData.rightLine.textLineType == TextLineData::TextLine)
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
i++;
}
fileData.chunks.append(chunkData);
@@ -1446,6 +1413,86 @@ QList<QTextEdit::ExtraSelection> SideBySideDiffEditorWidget::colorPositions(
return lineSelections;
}
void fixPositions(QMap<int, int>::ConstIterator *it,
const QMap<int, int>::ConstIterator &itEnd,
int fileOffset,
int charCounter,
int spanCounter,
int *lastSpanCounter,
QMap<int, int> *changedPositions)
{
while (*it != itEnd) {
if (it->key() >= charCounter)
break;
if (it->value() >= charCounter) {
if (*lastSpanCounter != -1)
break;
*lastSpanCounter = spanCounter;
break;
}
const int startSpanOffset = *lastSpanCounter != -1
? *lastSpanCounter : spanCounter;
*lastSpanCounter = -1;
const int startPos = it->key() + startSpanOffset + fileOffset;
const int endPos = it->value() + spanCounter + fileOffset;
changedPositions->insert(startPos, endPos);
++(*it);
}
}
static void fixPositions(const ChunkData &chunkData,
const int leftFileOffset,
const int rightFileOffset,
QMap<int, int> *leftCharPos,
QMap<int, int> *rightCharPos)
{
QMap<int, int>::ConstIterator leftIt = chunkData.changedLeftPositions.constBegin();
const QMap<int, int>::ConstIterator leftItEnd = chunkData.changedLeftPositions.constEnd();
QMap<int, int>::ConstIterator rightIt = chunkData.changedRightPositions.constBegin();
const QMap<int, int>::ConstIterator rightItEnd = chunkData.changedRightPositions.constEnd();
if (leftIt == leftItEnd && rightIt == rightItEnd)
return;
int leftCharCounter = 0;
int rightCharCounter = 0;
int leftSpanCounter = 0;
int rightSpanCounter = 0;
int leftLastSpanCounter = -1;
int rightLastSpanCounter = -1;
for (int i = 0; i < chunkData.rows.count(); i++) {
const RowData &row = chunkData.rows.at(i);
if (row.leftLine.textLineType == TextLineData::TextLine)
leftCharCounter += row.leftLine.text.count() + 1; // +1 for '\n'
else
++leftSpanCounter;
if (row.rightLine.textLineType == TextLineData::TextLine)
rightCharCounter += row.rightLine.text.count() + 1; // +1 for '\n'
else
++rightSpanCounter;
fixPositions(&leftIt,
leftItEnd,
leftFileOffset,
leftCharCounter,
leftSpanCounter,
&leftLastSpanCounter,
leftCharPos);
fixPositions(&rightIt,
rightItEnd,
rightFileOffset,
rightCharCounter,
rightSpanCounter,
&rightLastSpanCounter,
rightCharPos);
}
}
void SideBySideDiffEditorWidget::colorDiff(const QList<FileData> &fileDataList)
{
QPalette pal = m_leftEditor->extraArea()->palette();
@@ -1494,19 +1541,7 @@ void SideBySideDiffEditorWidget::colorDiff(const QList<FileData> &fileDataList)
leftLastSkippedBlockStartPos = leftPos;
rightLastSkippedBlockStartPos = rightPos;
QMapIterator<int, int> itLeft(chunkData.changedLeftPositions);
while (itLeft.hasNext()) {
itLeft.next();
leftCharPos[itLeft.key() + leftFileOffset] = itLeft.value() + leftFileOffset;
}
QMapIterator<int, int> itRight(chunkData.changedRightPositions);
while (itRight.hasNext()) {
itRight.next();
rightCharPos[itRight.key() + rightFileOffset] = itRight.value() + rightFileOffset;
}
fixPositions(chunkData, leftFileOffset, rightFileOffset, &leftCharPos, &rightCharPos);
for (int k = 0; k < chunkData.rows.count(); k++) {
RowData rowData = chunkData.rows.at(k);
@@ -1840,25 +1875,36 @@ void SideBySideDiffEditorWidget::synchronizeFoldings(SideDiffEditorWidget *sourc
#ifdef WITH_TESTS
#include <QTest>
void DiffEditor::SideBySideDiffEditorWidget::testAssemblyRows()
void DiffEditor::SideBySideDiffEditorWidget::testFixPositions()
{
QStringList lines;
lines << QLatin1String("abcd efgh"); // line 0
lines << QLatin1String("ijkl mnop"); // line 1
ChunkData chunkData;
chunkData.rows.append(RowData(TextLineData(QLatin1String("abcd efgh")), TextLineData(QLatin1String("abcd "))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(TextLineData::Separator), TextLineData(QLatin1String(""))));
chunkData.rows.append(RowData(TextLineData(QLatin1String("ijkl mnop")), TextLineData(QLatin1String(" mnop"))));
QMap<int, int> lineSpans;
lineSpans[1] = 6; // before line 1 insert 6 span lines
chunkData.changedLeftPositions.insert(5, 14); // changed text from position 5 to position 14, occupy 9 characters: "efgh\nijkl"
QMap<int, int> changedPositions;
changedPositions[5] = 14; // changed text from position 5 to position 14, occupy 9 characters: "efgh\nijkl"
QMap<int, int> expectedLeftChangedPositions;
expectedLeftChangedPositions[5] = 20; // "efgh\n[\n\n\n\n\n\n]ijkl" - [\n] means inserted span
QMap<int, int> expectedChangedPositions;
expectedChangedPositions[5] = 20; // "efgh\n[\n\n\n\n\n\n]ijkl" - [\n] means inserted span
QMap<int, int> outputLeftChangedPositions;
QMap<int, int> outputRightChangedPositions;
QMap<int, int> outputChangedPositions;
fixPositions(chunkData, 0, 0, &outputLeftChangedPositions, &outputRightChangedPositions);
QVERIFY(outputLeftChangedPositions == expectedLeftChangedPositions);
assemblyRows(lines, lineSpans, changedPositions, &outputChangedPositions);
QVERIFY(outputChangedPositions == expectedChangedPositions);
QMap<int, int> expectedLeftMovedPositions;
expectedLeftMovedPositions[15] = 30; // moved by 10
outputLeftChangedPositions.clear();
outputRightChangedPositions.clear();
fixPositions(chunkData, 10, 0, &outputLeftChangedPositions, &outputRightChangedPositions);
QVERIFY(outputLeftChangedPositions == expectedLeftMovedPositions);
}
#endif // WITH_TESTS