DiffUtils: Introduce DiffChunkInfo

Avoid code repetition.

Change-Id: Iea9acef8f8b27793528fa7eaf7044e12dcd21d10
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-09-29 19:13:12 +02:00
parent daa942393a
commit b677fbe992
6 changed files with 73 additions and 108 deletions

View File

@@ -15,6 +15,42 @@ using namespace Utils;
namespace DiffEditor { namespace DiffEditor {
static int forBlockNumber(const QMap<int, QPair<int, int>> &chunkInfo, int blockNumber,
const std::function<int (int, int, int)> &func)
{
if (chunkInfo.isEmpty())
return -1;
auto it = chunkInfo.upperBound(blockNumber);
if (it == chunkInfo.constBegin())
return -1;
--it;
if (blockNumber < it.key() + it.value().first)
return func(it.key(), it.value().first, it.value().second);
return -1;
}
int DiffChunkInfo::chunkRowForBlockNumber(int blockNumber) const
{
return forBlockNumber(m_chunkInfo, blockNumber, [blockNumber](int startBlockNumber, int, int)
{ return blockNumber - startBlockNumber; });
}
int DiffChunkInfo::chunkRowsCountForBlockNumber(int blockNumber) const
{
return forBlockNumber(m_chunkInfo, blockNumber,
[](int, int rowsCount, int) { return rowsCount; });
}
int DiffChunkInfo::chunkIndexForBlockNumber(int blockNumber) const
{
return forBlockNumber(m_chunkInfo, blockNumber,
[](int, int, int chunkIndex) { return chunkIndex; });
}
int ChunkSelection::selectedRowsCount() const int ChunkSelection::selectedRowsCount() const
{ {
return Utils::toSet(selection[LeftSide]).unite(Utils::toSet(selection[RightSide])).size(); return Utils::toSet(selection[LeftSide]).unite(Utils::toSet(selection[RightSide])).size();

View File

@@ -21,7 +21,7 @@ namespace Utils { class Diff; }
namespace DiffEditor { namespace DiffEditor {
class DIFFEDITOR_EXPORT DiffFileInfo { class DiffFileInfo {
public: public:
enum PatchBehaviour { enum PatchBehaviour {
PatchFile, PatchFile,
@@ -38,6 +38,21 @@ public:
using DiffFileInfoArray = std::array<DiffFileInfo, SideCount>; using DiffFileInfoArray = std::array<DiffFileInfo, SideCount>;
class DiffChunkInfo {
public:
int chunkIndexForBlockNumber(int blockNumber) const;
int chunkRowForBlockNumber(int blockNumber) const;
int chunkRowsCountForBlockNumber(int blockNumber) const;
void setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex) {
m_chunkInfo.insert(startBlockNumber, {blockCount, chunkIndex});
}
private:
// start block number, block count of a chunk, chunk index inside a file.
QMap<int, QPair<int, int>> m_chunkInfo;
};
class DIFFEDITOR_EXPORT TextLineData { class DIFFEDITOR_EXPORT TextLineData {
public: public:
enum TextLineType { enum TextLineType {

View File

@@ -348,8 +348,9 @@ SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface<void> &fi, int pr
blockNumber++; blockNumber++;
} }
output.side[LeftSide].diffData.setChunkIndex(blockNumber, chunkData.rows.count(), j); const int rows = chunkData.rows.count();
output.side[RightSide].diffData.setChunkIndex(blockNumber, chunkData.rows.count(), j); output.side[LeftSide].diffData.m_chunkInfo.setChunkIndex(blockNumber, rows, j);
output.side[RightSide].diffData.m_chunkInfo.setChunkIndex(blockNumber, rows, j);
for (const RowData &rowData : chunkData.rows) { for (const RowData &rowData : chunkData.rows) {
addRowLine(LeftSide, rowData, &leftLineNumber, &lastLeftLineNumber); addRowLine(LeftSide, rowData, &leftLineNumber, &lastLeftLineNumber);
@@ -406,11 +407,6 @@ void SideDiffData::setFileInfo(int blockNumber, const DiffFileInfo &fileInfo)
setSeparator(blockNumber, true); setSeparator(blockNumber, true);
} }
void SideDiffData::setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex)
{
m_chunkInfo.insert(startBlockNumber, qMakePair(blockCount, chunkIndex));
}
int SideDiffData::blockNumberForFileIndex(int fileIndex) const int SideDiffData::blockNumberForFileIndex(int fileIndex) const
{ {
if (fileIndex < 0 || fileIndex >= m_fileInfo.count()) if (fileIndex < 0 || fileIndex >= m_fileInfo.count())
@@ -430,57 +426,6 @@ int SideDiffData::fileIndexForBlockNumber(int blockNumber) const
return i; return i;
} }
int SideDiffData::chunkIndexForBlockNumber(int blockNumber) const
{
if (m_chunkInfo.isEmpty())
return -1;
auto it = m_chunkInfo.upperBound(blockNumber);
if (it == m_chunkInfo.constBegin())
return -1;
--it;
if (blockNumber < it.key() + it.value().first)
return it.value().second;
return -1;
}
int SideDiffData::chunkRowForBlockNumber(int blockNumber) const
{
if (m_chunkInfo.isEmpty())
return -1;
auto it = m_chunkInfo.upperBound(blockNumber);
if (it == m_chunkInfo.constBegin())
return -1;
--it;
if (blockNumber < it.key() + it.value().first)
return blockNumber - it.key();
return -1;
}
int SideDiffData::chunkRowsCountForBlockNumber(int blockNumber) const
{
if (m_chunkInfo.isEmpty())
return -1;
auto it = m_chunkInfo.upperBound(blockNumber);
if (it == m_chunkInfo.constBegin())
return -1;
--it;
if (blockNumber < it.key() + it.value().first)
return it.value().first;
return -1;
}
void SideDiffEditorWidget::clearAll(const QString &message) void SideDiffEditorWidget::clearAll(const QString &message)
{ {
clear(); clear();
@@ -572,22 +517,22 @@ void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
const int blockNumber = cursor.blockNumber(); const int blockNumber = cursor.blockNumber();
const int fileIndex = m_data.fileIndexForBlockNumber(blockNumber); const int fileIndex = m_data.fileIndexForBlockNumber(blockNumber);
const int chunkIndex = m_data.chunkIndexForBlockNumber(blockNumber); const int chunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber);
const int selectionStartFileIndex = m_data.fileIndexForBlockNumber(startBlockNumber); const int selectionStartFileIndex = m_data.fileIndexForBlockNumber(startBlockNumber);
const int selectionStartChunkIndex = m_data.chunkIndexForBlockNumber(startBlockNumber); const int selectionStartChunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(startBlockNumber);
const int selectionEndFileIndex = m_data.fileIndexForBlockNumber(endBlockNumber); const int selectionEndFileIndex = m_data.fileIndexForBlockNumber(endBlockNumber);
const int selectionEndChunkIndex = m_data.chunkIndexForBlockNumber(endBlockNumber); const int selectionEndChunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(endBlockNumber);
const int selectionStart = selectionStartFileIndex == fileIndex const int selectionStart = selectionStartFileIndex == fileIndex
&& selectionStartChunkIndex == chunkIndex && selectionStartChunkIndex == chunkIndex
? m_data.chunkRowForBlockNumber(startBlockNumber) ? m_data.m_chunkInfo.chunkRowForBlockNumber(startBlockNumber)
: 0; : 0;
const int selectionEnd = selectionEndFileIndex == fileIndex const int selectionEnd = selectionEndFileIndex == fileIndex
&& selectionEndChunkIndex == chunkIndex && selectionEndChunkIndex == chunkIndex
? m_data.chunkRowForBlockNumber(endBlockNumber) ? m_data.m_chunkInfo.chunkRowForBlockNumber(endBlockNumber)
: m_data.chunkRowsCountForBlockNumber(blockNumber); : m_data.m_chunkInfo.chunkRowsCountForBlockNumber(blockNumber);
QList<int> rows; QList<int> rows;
for (int i = selectionStart; i <= selectionEnd; ++i) for (int i = selectionStart; i <= selectionEnd; ++i)
@@ -596,7 +541,7 @@ void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
const ChunkSelection selection(rows, rows); const ChunkSelection selection(rows, rows);
emit contextMenuRequested(menu, m_data.fileIndexForBlockNumber(blockNumber), emit contextMenuRequested(menu, m_data.fileIndexForBlockNumber(blockNumber),
m_data.chunkIndexForBlockNumber(blockNumber), m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber),
selection); selection);
connect(this, &SideDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater); connect(this, &SideDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater);

View File

@@ -38,14 +38,13 @@ public:
static SideBySideDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin, static SideBySideDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin,
int progressMax, const DiffEditorInput &input); int progressMax, const DiffEditorInput &input);
// block number, visual line number. DiffChunkInfo m_chunkInfo;
QMap<int, int> m_lineNumbers;
// block number, fileInfo. Set for file lines only. // block number, fileInfo. Set for file lines only.
QMap<int, DiffFileInfo> m_fileInfo; QMap<int, DiffFileInfo> m_fileInfo;
// block number, visual line number.
QMap<int, int> m_lineNumbers;
// block number, skipped lines and context info. Set for chunk lines only. // block number, skipped lines and context info. Set for chunk lines only.
QMap<int, QPair<int, QString>> m_skippedLines; QMap<int, QPair<int, QString>> m_skippedLines;
// start block number, block count of a chunk, chunk index inside a file.
QMap<int, QPair<int, int>> m_chunkInfo;
// block number, separator. Set for file, chunk or span line. // block number, separator. Set for file, chunk or span line.
QMap<int, bool> m_separators; QMap<int, bool> m_separators;
@@ -55,9 +54,6 @@ public:
bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); } bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); }
int blockNumberForFileIndex(int fileIndex) const; int blockNumberForFileIndex(int fileIndex) const;
int fileIndexForBlockNumber(int blockNumber) const; int fileIndexForBlockNumber(int blockNumber) const;
int chunkIndexForBlockNumber(int blockNumber) const;
int chunkRowForBlockNumber(int blockNumber) const;
int chunkRowsCountForBlockNumber(int blockNumber) const;
private: private:
void setLineNumber(int blockNumber, int lineNumber); void setLineNumber(int blockNumber, int lineNumber);
@@ -66,7 +62,6 @@ private:
m_skippedLines[blockNumber] = {skippedLines, contextInfo}; m_skippedLines[blockNumber] = {skippedLines, contextInfo};
setSeparator(blockNumber, true); setSeparator(blockNumber, true);
} }
void setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex);
void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; } void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; }
}; };

View File

@@ -172,7 +172,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
const int blockNumber = cursor.blockNumber(); const int blockNumber = cursor.blockNumber();
const int fileIndex = fileIndexForBlockNumber(blockNumber); const int fileIndex = fileIndexForBlockNumber(blockNumber);
const int chunkIndex = chunkIndexForBlockNumber(blockNumber); const int chunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber);
const ChunkData chunkData = m_controller.chunkData(fileIndex, chunkIndex); const ChunkData chunkData = m_controller.chunkData(fileIndex, chunkIndex);
@@ -186,7 +186,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
if (currentFileIndex > fileIndex) if (currentFileIndex > fileIndex)
break; break;
const int currentChunkIndex = chunkIndexForBlockNumber(i); const int currentChunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(i);
if (currentChunkIndex < chunkIndex) if (currentChunkIndex < chunkIndex)
continue; continue;
@@ -205,7 +205,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
const ChunkSelection selection(leftSelection, rightSelection); const ChunkSelection selection(leftSelection, rightSelection);
addContextMenuActions(menu, fileIndexForBlockNumber(blockNumber), addContextMenuActions(menu, fileIndexForBlockNumber(blockNumber),
chunkIndexForBlockNumber(blockNumber), selection); m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber), selection);
connect(this, &UnifiedDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater); connect(this, &UnifiedDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater);
menu->exec(e->globalPos()); menu->exec(e->globalPos());
@@ -274,11 +274,6 @@ void UnifiedDiffData::setLineNumber(DiffSide side, int blockNumber, int lineNumb
m_lineNumberDigits[side] = qMax(m_lineNumberDigits[side], lineNumberString.count()); m_lineNumberDigits[side] = qMax(m_lineNumberDigits[side], lineNumberString.count());
} }
void UnifiedDiffData::setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex)
{
m_chunkInfo.insert(startBlockNumber, qMakePair(blockCount, chunkIndex));
}
void UnifiedDiffEditorWidget::setDiff(const QList<FileData> &diffFileList) void UnifiedDiffEditorWidget::setDiff(const QList<FileData> &diffFileList)
{ {
const GuardLocker locker(m_controller.m_ignoreChanges); const GuardLocker locker(m_controller.m_ignoreChanges);
@@ -445,7 +440,7 @@ UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterface<void> &fi, int pr
output.diffText += binaryLine; output.diffText += binaryLine;
} else { } else {
for (int j = 0; j < fileData.chunks.count(); j++) { for (int j = 0; j < fileData.chunks.count(); j++) {
const int oldBlockNumber = blockNumber; const int oldBlock = blockNumber;
output.foldingIndent.insert(blockNumber, 2); output.foldingIndent.insert(blockNumber, 2);
output.diffText += output.diffData.setChunk(input, fileData.chunks.at(j), output.diffText += output.diffData.setChunk(input, fileData.chunks.at(j),
(j == fileData.chunks.count() - 1) (j == fileData.chunks.count() - 1)
@@ -453,7 +448,7 @@ UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterface<void> &fi, int pr
&blockNumber, &blockNumber,
&output.selections); &output.selections);
if (!fileData.chunks.at(j).contextChunk) if (!fileData.chunks.at(j).contextChunk)
output.diffData.setChunkIndex(oldBlockNumber, blockNumber - oldBlockNumber, j); output.diffData.m_chunkInfo.setChunkIndex(oldBlock, blockNumber - oldBlock, j);
} }
} }
fi.setProgressValue(DiffUtils::interpolate(++i, 0, count, progressMin, progressMax)); fi.setProgressValue(DiffUtils::interpolate(++i, 0, count, progressMin, progressMax));
@@ -569,23 +564,6 @@ int UnifiedDiffEditorWidget::fileIndexForBlockNumber(int blockNumber) const
return i; return i;
} }
int UnifiedDiffEditorWidget::chunkIndexForBlockNumber(int blockNumber) const
{
if (m_data.m_chunkInfo.isEmpty())
return -1;
auto it = m_data.m_chunkInfo.upperBound(blockNumber);
if (it == m_data.m_chunkInfo.constBegin())
return -1;
--it;
if (blockNumber < it.key() + it.value().first)
return it.value().second;
return -1;
}
void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor) void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
{ {
if (m_data.m_fileInfo.isEmpty()) if (m_data.m_fileInfo.isEmpty())

View File

@@ -32,19 +32,16 @@ public:
static UnifiedDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin, int progressMax, static UnifiedDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin, int progressMax,
const DiffEditorInput &input); const DiffEditorInput &input);
DiffChunkInfo m_chunkInfo;
// block number, visual line number.
QMap<int, DiffFileInfoArray> m_fileInfo;
// block number, visual line number, chunk row number // block number, visual line number, chunk row number
using LineNumbers = QMap<int, QPair<int, int>>; using LineNumbers = QMap<int, QPair<int, int>>;
std::array<LineNumbers, SideCount> m_lineNumbers{}; std::array<LineNumbers, SideCount> m_lineNumbers{};
std::array<int, SideCount> m_lineNumberDigits{1, 1}; std::array<int, SideCount> m_lineNumberDigits{1, 1};
// block number, visual line number.
QMap<int, DiffFileInfoArray> m_fileInfo;
// start block number, block count of a chunk, chunk index inside a file.
QMap<int, QPair<int, int>> m_chunkInfo;
private: private:
void setLineNumber(DiffSide side, int blockNumber, int lineNumber, int rowNumberInChunk); void setLineNumber(DiffSide side, int blockNumber, int lineNumber, int rowNumberInChunk);
void setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex);
QString setChunk(const DiffEditorInput &input, const ChunkData &chunkData, QString setChunk(const DiffEditorInput &input, const ChunkData &chunkData,
bool lastChunk, int *blockNumber, DiffSelections *selections); bool lastChunk, int *blockNumber, DiffSelections *selections);
}; };
@@ -100,7 +97,6 @@ private:
void showDiff(); void showDiff();
int blockNumberForFileIndex(int fileIndex) const; int blockNumberForFileIndex(int fileIndex) const;
int fileIndexForBlockNumber(int blockNumber) const; int fileIndexForBlockNumber(int blockNumber) const;
int chunkIndexForBlockNumber(int blockNumber) const;
void jumpToOriginalFile(const QTextCursor &cursor); void jumpToOriginalFile(const QTextCursor &cursor);
void addContextMenuActions(QMenu *menu, int fileIndex, int chunkIndex, void addContextMenuActions(QMenu *menu, int fileIndex, int chunkIndex,
const ChunkSelection &selection); const ChunkSelection &selection);