forked from qt-creator/qt-creator
Prepare for patch generation, fix internals.
Change-Id: Ib3b7c5c433f9f9230eb14d23a3029681841e2e68 Reviewed-by: Jarek Kobus <jaroslaw.kobus@digia.com>
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user