From b677fbe9927043e8993d06f2d522f3dbda792e36 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 29 Sep 2022 19:13:12 +0200 Subject: [PATCH] DiffUtils: Introduce DiffChunkInfo Avoid code repetition. Change-Id: Iea9acef8f8b27793528fa7eaf7044e12dcd21d10 Reviewed-by: Orgad Shaneh --- src/plugins/diffeditor/diffutils.cpp | 36 +++++++++ src/plugins/diffeditor/diffutils.h | 17 ++++- .../diffeditor/sidebysidediffeditorwidget.cpp | 75 +++---------------- .../diffeditor/sidebysidediffeditorwidget.h | 11 +-- .../diffeditor/unifieddiffeditorwidget.cpp | 32 ++------ .../diffeditor/unifieddiffeditorwidget.h | 10 +-- 6 files changed, 73 insertions(+), 108 deletions(-) diff --git a/src/plugins/diffeditor/diffutils.cpp b/src/plugins/diffeditor/diffutils.cpp index 44006e46fbe..07c4f31bd6e 100644 --- a/src/plugins/diffeditor/diffutils.cpp +++ b/src/plugins/diffeditor/diffutils.cpp @@ -15,6 +15,42 @@ using namespace Utils; namespace DiffEditor { +static int forBlockNumber(const QMap> &chunkInfo, int blockNumber, + const std::function &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 { return Utils::toSet(selection[LeftSide]).unite(Utils::toSet(selection[RightSide])).size(); diff --git a/src/plugins/diffeditor/diffutils.h b/src/plugins/diffeditor/diffutils.h index 4e09e679dd5..460674d4b03 100644 --- a/src/plugins/diffeditor/diffutils.h +++ b/src/plugins/diffeditor/diffutils.h @@ -21,7 +21,7 @@ namespace Utils { class Diff; } namespace DiffEditor { -class DIFFEDITOR_EXPORT DiffFileInfo { +class DiffFileInfo { public: enum PatchBehaviour { PatchFile, @@ -38,6 +38,21 @@ public: using DiffFileInfoArray = std::array; +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> m_chunkInfo; +}; + class DIFFEDITOR_EXPORT TextLineData { public: enum TextLineType { diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp index 8cabbac1e31..4403f2285c3 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp @@ -348,8 +348,9 @@ SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface &fi, int pr blockNumber++; } - output.side[LeftSide].diffData.setChunkIndex(blockNumber, chunkData.rows.count(), j); - output.side[RightSide].diffData.setChunkIndex(blockNumber, chunkData.rows.count(), j); + const int rows = chunkData.rows.count(); + 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) { addRowLine(LeftSide, rowData, &leftLineNumber, &lastLeftLineNumber); @@ -406,11 +407,6 @@ void SideDiffData::setFileInfo(int blockNumber, const DiffFileInfo &fileInfo) 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 { if (fileIndex < 0 || fileIndex >= m_fileInfo.count()) @@ -430,57 +426,6 @@ int SideDiffData::fileIndexForBlockNumber(int blockNumber) const 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) { clear(); @@ -572,22 +517,22 @@ void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e) const int blockNumber = cursor.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 selectionStartChunkIndex = m_data.chunkIndexForBlockNumber(startBlockNumber); + const int selectionStartChunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(startBlockNumber); 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 && selectionStartChunkIndex == chunkIndex - ? m_data.chunkRowForBlockNumber(startBlockNumber) + ? m_data.m_chunkInfo.chunkRowForBlockNumber(startBlockNumber) : 0; const int selectionEnd = selectionEndFileIndex == fileIndex && selectionEndChunkIndex == chunkIndex - ? m_data.chunkRowForBlockNumber(endBlockNumber) - : m_data.chunkRowsCountForBlockNumber(blockNumber); + ? m_data.m_chunkInfo.chunkRowForBlockNumber(endBlockNumber) + : m_data.m_chunkInfo.chunkRowsCountForBlockNumber(blockNumber); QList rows; for (int i = selectionStart; i <= selectionEnd; ++i) @@ -596,7 +541,7 @@ void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e) const ChunkSelection selection(rows, rows); emit contextMenuRequested(menu, m_data.fileIndexForBlockNumber(blockNumber), - m_data.chunkIndexForBlockNumber(blockNumber), + m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber), selection); connect(this, &SideDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater); diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.h b/src/plugins/diffeditor/sidebysidediffeditorwidget.h index 93ec377f0f2..2c1e30f4d11 100644 --- a/src/plugins/diffeditor/sidebysidediffeditorwidget.h +++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.h @@ -38,14 +38,13 @@ public: static SideBySideDiffOutput diffOutput(QFutureInterface &fi, int progressMin, int progressMax, const DiffEditorInput &input); - // block number, visual line number. - QMap m_lineNumbers; + DiffChunkInfo m_chunkInfo; // block number, fileInfo. Set for file lines only. QMap m_fileInfo; + // block number, visual line number. + QMap m_lineNumbers; // block number, skipped lines and context info. Set for chunk lines only. QMap> m_skippedLines; - // start block number, block count of a chunk, chunk index inside a file. - QMap> m_chunkInfo; // block number, separator. Set for file, chunk or span line. QMap m_separators; @@ -55,9 +54,6 @@ public: bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); } int blockNumberForFileIndex(int fileIndex) const; int fileIndexForBlockNumber(int blockNumber) const; - int chunkIndexForBlockNumber(int blockNumber) const; - int chunkRowForBlockNumber(int blockNumber) const; - int chunkRowsCountForBlockNumber(int blockNumber) const; private: void setLineNumber(int blockNumber, int lineNumber); @@ -66,7 +62,6 @@ private: m_skippedLines[blockNumber] = {skippedLines, contextInfo}; setSeparator(blockNumber, true); } - void setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex); void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; } }; diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp index da14adfc767..c2b4eef06c1 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.cpp +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.cpp @@ -172,7 +172,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e) const int blockNumber = cursor.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); @@ -186,7 +186,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e) if (currentFileIndex > fileIndex) break; - const int currentChunkIndex = chunkIndexForBlockNumber(i); + const int currentChunkIndex = m_data.m_chunkInfo.chunkIndexForBlockNumber(i); if (currentChunkIndex < chunkIndex) continue; @@ -205,7 +205,7 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e) const ChunkSelection selection(leftSelection, rightSelection); addContextMenuActions(menu, fileIndexForBlockNumber(blockNumber), - chunkIndexForBlockNumber(blockNumber), selection); + m_data.m_chunkInfo.chunkIndexForBlockNumber(blockNumber), selection); connect(this, &UnifiedDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater); 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()); } -void UnifiedDiffData::setChunkIndex(int startBlockNumber, int blockCount, int chunkIndex) -{ - m_chunkInfo.insert(startBlockNumber, qMakePair(blockCount, chunkIndex)); -} - void UnifiedDiffEditorWidget::setDiff(const QList &diffFileList) { const GuardLocker locker(m_controller.m_ignoreChanges); @@ -445,7 +440,7 @@ UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterface &fi, int pr output.diffText += binaryLine; } else { for (int j = 0; j < fileData.chunks.count(); j++) { - const int oldBlockNumber = blockNumber; + const int oldBlock = blockNumber; output.foldingIndent.insert(blockNumber, 2); output.diffText += output.diffData.setChunk(input, fileData.chunks.at(j), (j == fileData.chunks.count() - 1) @@ -453,7 +448,7 @@ UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterface &fi, int pr &blockNumber, &output.selections); 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)); @@ -569,23 +564,6 @@ int UnifiedDiffEditorWidget::fileIndexForBlockNumber(int blockNumber) const 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) { if (m_data.m_fileInfo.isEmpty()) diff --git a/src/plugins/diffeditor/unifieddiffeditorwidget.h b/src/plugins/diffeditor/unifieddiffeditorwidget.h index 848f5c0e383..48d55665ee9 100644 --- a/src/plugins/diffeditor/unifieddiffeditorwidget.h +++ b/src/plugins/diffeditor/unifieddiffeditorwidget.h @@ -32,19 +32,16 @@ public: static UnifiedDiffOutput diffOutput(QFutureInterface &fi, int progressMin, int progressMax, const DiffEditorInput &input); + DiffChunkInfo m_chunkInfo; + // block number, visual line number. + QMap m_fileInfo; // block number, visual line number, chunk row number using LineNumbers = QMap>; std::array m_lineNumbers{}; std::array m_lineNumberDigits{1, 1}; - // block number, visual line number. - QMap m_fileInfo; - // start block number, block count of a chunk, chunk index inside a file. - QMap> m_chunkInfo; - private: 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, bool lastChunk, int *blockNumber, DiffSelections *selections); }; @@ -100,7 +97,6 @@ private: void showDiff(); int blockNumberForFileIndex(int fileIndex) const; int fileIndexForBlockNumber(int blockNumber) const; - int chunkIndexForBlockNumber(int blockNumber) const; void jumpToOriginalFile(const QTextCursor &cursor); void addContextMenuActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection);