forked from qt-creator/qt-creator
DiffEditor: Stage and unstage selected lines for Git
Fixes: QTCREATORBUG-19071 Change-Id: I560ba208e68e477ea865e499847d819cfdfeb6f3 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
committed by
Jarek Kobus
parent
2758682723
commit
1766832918
@@ -71,9 +71,10 @@ bool DiffEditorController::ignoreWhitespace() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString DiffEditorController::makePatch(int fileIndex, int chunkIndex,
|
QString DiffEditorController::makePatch(int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection,
|
||||||
PatchOptions options) const
|
PatchOptions options) const
|
||||||
{
|
{
|
||||||
return m_document->makePatch(fileIndex, chunkIndex,
|
return m_document->makePatch(fileIndex, chunkIndex, selection,
|
||||||
options & Revert, options & AddPrefix);
|
options & Revert, options & AddPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,9 +144,10 @@ void DiffEditorController::reloadFinished(bool success)
|
|||||||
m_isReloading = false;
|
m_isReloading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffEditorController::requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex)
|
void DiffEditorController::requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
emit chunkActionsRequested(menu, fileIndex, chunkIndex);
|
emit chunkActionsRequested(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiffEditorController::chunkExists(int fileIndex, int chunkIndex) const
|
bool DiffEditorController::chunkExists(int fileIndex, int chunkIndex) const
|
||||||
|
@@ -38,6 +38,8 @@ namespace DiffEditor {
|
|||||||
|
|
||||||
namespace Internal { class DiffEditorDocument; }
|
namespace Internal { class DiffEditorDocument; }
|
||||||
|
|
||||||
|
class ChunkSelection;
|
||||||
|
|
||||||
class DIFFEDITOR_EXPORT DiffEditorController : public QObject
|
class DIFFEDITOR_EXPORT DiffEditorController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -58,18 +60,21 @@ public:
|
|||||||
AddPrefix = 2
|
AddPrefix = 2
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(PatchOptions, PatchOption)
|
Q_DECLARE_FLAGS(PatchOptions, PatchOption)
|
||||||
QString makePatch(int fileIndex, int chunkIndex, PatchOptions options) const;
|
QString makePatch(int fileIndex, int chunkIndex, const ChunkSelection &selection,
|
||||||
|
PatchOptions options) const;
|
||||||
|
|
||||||
static Core::IDocument *findOrCreateDocument(const QString &vcsId,
|
static Core::IDocument *findOrCreateDocument(const QString &vcsId,
|
||||||
const QString &displayName);
|
const QString &displayName);
|
||||||
static DiffEditorController *controller(Core::IDocument *document);
|
static DiffEditorController *controller(Core::IDocument *document);
|
||||||
|
|
||||||
void requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex);
|
void requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection);
|
||||||
bool chunkExists(int fileIndex, int chunkIndex) const;
|
bool chunkExists(int fileIndex, int chunkIndex) const;
|
||||||
Core::IDocument *document() const;
|
Core::IDocument *document() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
|
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// reloadFinished() should be called
|
// reloadFinished() should be called
|
||||||
|
@@ -76,7 +76,39 @@ DiffEditorController *DiffEditorDocument::controller() const
|
|||||||
return m_controller;
|
return m_controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChunkData DiffEditorDocument::filterChunk(const ChunkData &data,
|
||||||
|
const ChunkSelection &selection, bool revert)
|
||||||
|
{
|
||||||
|
if (selection.isNull())
|
||||||
|
return data;
|
||||||
|
|
||||||
|
ChunkData chunk(data);
|
||||||
|
for (int i = 0; i < chunk.rows.count(); ++i) {
|
||||||
|
RowData &row = chunk.rows[i];
|
||||||
|
if (i < selection.startRow || i >= selection.startRow + selection.selectedRowsCount) {
|
||||||
|
if (revert)
|
||||||
|
row.leftLine = row.rightLine;
|
||||||
|
else
|
||||||
|
row.rightLine = row.leftLine;
|
||||||
|
row.equal = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < chunk.rows.count(); ) {
|
||||||
|
const RowData &row = chunk.rows[i];
|
||||||
|
const bool isSeparator = row.leftLine.textLineType == TextLineData::Separator
|
||||||
|
&& row.rightLine.textLineType == TextLineData::Separator;
|
||||||
|
if (isSeparator)
|
||||||
|
chunk.rows.removeAt(i);
|
||||||
|
else
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
QString DiffEditorDocument::makePatch(int fileIndex, int chunkIndex,
|
QString DiffEditorDocument::makePatch(int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection,
|
||||||
bool revert, bool addPrefix,
|
bool revert, bool addPrefix,
|
||||||
const QString &overriddenFileName) const
|
const QString &overriddenFileName) const
|
||||||
{
|
{
|
||||||
@@ -90,7 +122,7 @@ QString DiffEditorDocument::makePatch(int fileIndex, int chunkIndex,
|
|||||||
if (chunkIndex >= fileData.chunks.count())
|
if (chunkIndex >= fileData.chunks.count())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
const ChunkData &chunkData = fileData.chunks.at(chunkIndex);
|
const ChunkData chunkData = filterChunk(fileData.chunks.at(chunkIndex), selection, revert);
|
||||||
const bool lastChunk = (chunkIndex == fileData.chunks.count() - 1);
|
const bool lastChunk = (chunkIndex == fileData.chunks.count() - 1);
|
||||||
|
|
||||||
const QString fileName = !overriddenFileName.isEmpty()
|
const QString fileName = !overriddenFileName.isEmpty()
|
||||||
|
@@ -34,6 +34,7 @@ QT_FORWARD_DECLARE_CLASS(QMenu)
|
|||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
class DiffEditorController;
|
class DiffEditorController;
|
||||||
|
class ChunkSelection;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -52,7 +53,9 @@ public:
|
|||||||
LoadFailed
|
LoadFailed
|
||||||
};
|
};
|
||||||
|
|
||||||
QString makePatch(int fileIndex, int chunkIndex,
|
static ChunkData filterChunk(const ChunkData &data,
|
||||||
|
const ChunkSelection &selection, bool revert);
|
||||||
|
QString makePatch(int fileIndex, int chunkIndex, const ChunkSelection &selection,
|
||||||
bool revert, bool addPrefix = false,
|
bool revert, bool addPrefix = false,
|
||||||
const QString &overriddenFileName = QString()) const;
|
const QString &overriddenFileName = QString()) const;
|
||||||
|
|
||||||
|
@@ -610,6 +610,7 @@ void DiffEditorPlugin::diffExternalFiles()
|
|||||||
|
|
||||||
Q_DECLARE_METATYPE(DiffEditor::ChunkData)
|
Q_DECLARE_METATYPE(DiffEditor::ChunkData)
|
||||||
Q_DECLARE_METATYPE(DiffEditor::FileData)
|
Q_DECLARE_METATYPE(DiffEditor::FileData)
|
||||||
|
Q_DECLARE_METATYPE(DiffEditor::ChunkSelection)
|
||||||
|
|
||||||
static inline QString _(const char *string) { return QString::fromLatin1(string); }
|
static inline QString _(const char *string) { return QString::fromLatin1(string); }
|
||||||
|
|
||||||
@@ -1430,6 +1431,140 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiffEditor::Internal::DiffEditorPlugin::testFilterPatch_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<ChunkData>("chunk");
|
||||||
|
QTest::addColumn<QStringList>("rightLines");
|
||||||
|
QTest::addColumn<ChunkSelection>("selection");
|
||||||
|
|
||||||
|
auto createChunk = []() {
|
||||||
|
ChunkData chunk;
|
||||||
|
chunk.contextInfo = "void DiffEditor::ctor()";
|
||||||
|
chunk.contextChunk = false;
|
||||||
|
chunk.leftStartingLineNumber = 49;
|
||||||
|
chunk.rightStartingLineNumber = 49;
|
||||||
|
return chunk;
|
||||||
|
};
|
||||||
|
auto appendRow = [](ChunkData *chunk, const QString &left, const QString &right) {
|
||||||
|
RowData row;
|
||||||
|
row.equal = (left == right);
|
||||||
|
row.leftLine.text = left;
|
||||||
|
row.leftLine.textLineType = left.isEmpty() ? TextLineData::Separator : TextLineData::TextLine;
|
||||||
|
row.rightLine.text = right;
|
||||||
|
row.rightLine.textLineType = right.isEmpty() ? TextLineData::Separator : TextLineData::TextLine;
|
||||||
|
chunk->rows.append(row);
|
||||||
|
};
|
||||||
|
ChunkData chunk;
|
||||||
|
QStringList rightLines;
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "", "B"); // 51 +
|
||||||
|
appendRow(&chunk, "C", "C"); // 52
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C"
|
||||||
|
};
|
||||||
|
QTest::newRow("one added") << chunk << rightLines << ChunkSelection();
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "B", ""); // 51 -
|
||||||
|
appendRow(&chunk, "C", "C"); // 52
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"",
|
||||||
|
"C"
|
||||||
|
};
|
||||||
|
QTest::newRow("one removed") << chunk << rightLines << ChunkSelection();
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "", "B"); // 51
|
||||||
|
appendRow(&chunk, "", "C"); // 52 +
|
||||||
|
appendRow(&chunk, "", "D"); // 53 +
|
||||||
|
appendRow(&chunk, "", "E"); // 54
|
||||||
|
appendRow(&chunk, "F", "F"); // 55
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
"F",
|
||||||
|
};
|
||||||
|
QTest::newRow("stage selected added") << chunk << rightLines << ChunkSelection(2, 2);
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "", "B"); // 51 +
|
||||||
|
appendRow(&chunk, "C", "D"); // 52
|
||||||
|
appendRow(&chunk, "E", "E"); // 53
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"C",
|
||||||
|
"E",
|
||||||
|
};
|
||||||
|
QTest::newRow("stage selected added keep changed") << chunk << rightLines << ChunkSelection(1, 1);
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "B", ""); // 51
|
||||||
|
appendRow(&chunk, "C", ""); // 52 -
|
||||||
|
appendRow(&chunk, "D", ""); // 53 -
|
||||||
|
appendRow(&chunk, "E", ""); // 54
|
||||||
|
appendRow(&chunk, "F", "F"); // 55
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"E",
|
||||||
|
"F",
|
||||||
|
};
|
||||||
|
QTest::newRow("stage selected removed") << chunk << rightLines << ChunkSelection(2, 2);
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "B", ""); // 51
|
||||||
|
appendRow(&chunk, "C", ""); // 52 -
|
||||||
|
appendRow(&chunk, "", "D"); // 53 +
|
||||||
|
appendRow(&chunk, "", "E"); // 54
|
||||||
|
appendRow(&chunk, "F", "F"); // 55
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"B",
|
||||||
|
"",
|
||||||
|
"D",
|
||||||
|
"F",
|
||||||
|
};
|
||||||
|
QTest::newRow("stage selected added/removed") << chunk << rightLines << ChunkSelection(2, 2);
|
||||||
|
|
||||||
|
chunk = createChunk();
|
||||||
|
appendRow(&chunk, "A", "A"); // 50
|
||||||
|
appendRow(&chunk, "B", "C"); // 51 -/+
|
||||||
|
appendRow(&chunk, "D", "D"); // 52
|
||||||
|
rightLines = QStringList {
|
||||||
|
"A",
|
||||||
|
"C",
|
||||||
|
"D",
|
||||||
|
};
|
||||||
|
QTest::newRow("stage modified row") << chunk << rightLines << ChunkSelection(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiffEditor::Internal::DiffEditorPlugin::testFilterPatch()
|
||||||
|
{
|
||||||
|
QFETCH(ChunkData, chunk);
|
||||||
|
QFETCH(QStringList, rightLines);
|
||||||
|
QFETCH(ChunkSelection, selection);
|
||||||
|
|
||||||
|
ChunkData result = DiffEditorDocument::filterChunk(chunk, selection, false);
|
||||||
|
QCOMPARE(result.rows.size(), rightLines.size());
|
||||||
|
for (int i = 0; i < rightLines.size(); ++i) {
|
||||||
|
QCOMPARE(result.rows.at(i).rightLine.text, rightLines.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
#include "diffeditorplugin.moc"
|
#include "diffeditorplugin.moc"
|
||||||
|
@@ -73,6 +73,8 @@ private slots:
|
|||||||
void testMakePatch();
|
void testMakePatch();
|
||||||
void testReadPatch_data();
|
void testReadPatch_data();
|
||||||
void testReadPatch();
|
void testReadPatch();
|
||||||
|
void testFilterPatch_data();
|
||||||
|
void testFilterPatch();
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -158,7 +158,7 @@ void DiffEditorWidgetController::patch(bool revert, int fileIndex, int chunkInde
|
|||||||
if (patchBehaviour == DiffFileInfo::PatchFile) {
|
if (patchBehaviour == DiffFileInfo::PatchFile) {
|
||||||
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
||||||
|
|
||||||
const QString patch = m_document->makePatch(fileIndex, chunkIndex, revert);
|
const QString patch = m_document->makePatch(fileIndex, chunkIndex, ChunkSelection(), revert);
|
||||||
|
|
||||||
if (patch.isEmpty())
|
if (patch.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -183,8 +183,9 @@ void DiffEditorWidgetController::patch(bool revert, int fileIndex, int chunkInde
|
|||||||
const QString contentsCopyFileName = contentsCopy.fileName();
|
const QString contentsCopyFileName = contentsCopy.fileName();
|
||||||
const QString contentsCopyDir = QFileInfo(contentsCopyFileName).absolutePath();
|
const QString contentsCopyDir = QFileInfo(contentsCopyFileName).absolutePath();
|
||||||
|
|
||||||
const QString patch = m_document->makePatch(fileIndex,
|
const QString patch = m_document->makePatch(fileIndex, chunkIndex,
|
||||||
chunkIndex, revert, false, QFileInfo(contentsCopyFileName).fileName());
|
ChunkSelection(), revert, false,
|
||||||
|
QFileInfo(contentsCopyFileName).fileName());
|
||||||
|
|
||||||
if (patch.isEmpty())
|
if (patch.isEmpty())
|
||||||
return;
|
return;
|
||||||
@@ -244,6 +245,24 @@ bool DiffEditorWidgetController::chunkExists(int fileIndex, int chunkIndex) cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChunkData DiffEditorWidgetController::chunkData(int fileIndex, int chunkIndex) const
|
||||||
|
{
|
||||||
|
if (!m_document)
|
||||||
|
return ChunkData();
|
||||||
|
|
||||||
|
if (fileIndex < 0 || chunkIndex < 0)
|
||||||
|
return ChunkData();
|
||||||
|
|
||||||
|
if (fileIndex >= m_contextFileData.count())
|
||||||
|
return ChunkData();
|
||||||
|
|
||||||
|
const FileData fileData = m_contextFileData.at(fileIndex);
|
||||||
|
if (chunkIndex >= fileData.chunks.count())
|
||||||
|
return ChunkData();
|
||||||
|
|
||||||
|
return fileData.chunks.at(chunkIndex);
|
||||||
|
}
|
||||||
|
|
||||||
bool DiffEditorWidgetController::fileNamesAreDifferent(int fileIndex) const
|
bool DiffEditorWidgetController::fileNamesAreDifferent(int fileIndex) const
|
||||||
{
|
{
|
||||||
const FileData fileData = m_contextFileData.at(fileIndex);
|
const FileData fileData = m_contextFileData.at(fileIndex);
|
||||||
@@ -268,10 +287,11 @@ void DiffEditorWidgetController::addRevertAction(QMenu *menu, int fileIndex, int
|
|||||||
revertAction->setEnabled(chunkExists(fileIndex, chunkIndex));
|
revertAction->setEnabled(chunkExists(fileIndex, chunkIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffEditorWidgetController::addExtraActions(QMenu *menu, int fileIndex, int chunkIndex)
|
void DiffEditorWidgetController::addExtraActions(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
if (DiffEditorController *controller = m_document->controller())
|
if (DiffEditorController *controller = m_document->controller())
|
||||||
controller->requestChunkActions(menu, fileIndex, chunkIndex);
|
controller->requestChunkActions(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkIndex)
|
void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkIndex)
|
||||||
@@ -283,7 +303,8 @@ void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkI
|
|||||||
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
||||||
QTC_ASSERT(pasteService, return);
|
QTC_ASSERT(pasteService, return);
|
||||||
|
|
||||||
const QString patch = m_document->makePatch(fileIndex, chunkIndex, false);
|
const QString patch = m_document->makePatch(fileIndex, chunkIndex,
|
||||||
|
ChunkSelection(), false);
|
||||||
|
|
||||||
if (patch.isEmpty())
|
if (patch.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@@ -39,6 +39,8 @@ namespace Utils { class ProgressIndicator; }
|
|||||||
|
|
||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
|
class ChunkSelection;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class DiffEditorDocument;
|
class DiffEditorDocument;
|
||||||
@@ -58,7 +60,9 @@ public:
|
|||||||
void addCodePasterAction(QMenu *menu, int fileIndex, int chunkIndex);
|
void addCodePasterAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||||
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
|
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||||
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
|
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||||
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex);
|
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection);
|
||||||
|
|
||||||
|
ChunkData chunkData(int fileIndex, int chunkIndex) const;
|
||||||
|
|
||||||
bool m_ignoreCurrentIndexChange = false;
|
bool m_ignoreCurrentIndexChange = false;
|
||||||
QList<FileData> m_contextFileData; // ultimate data to be shown
|
QList<FileData> m_contextFileData; // ultimate data to be shown
|
||||||
|
@@ -99,6 +99,15 @@ public:
|
|||||||
bool contextChunk = false;
|
bool contextChunk = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DIFFEDITOR_EXPORT ChunkSelection {
|
||||||
|
public:
|
||||||
|
ChunkSelection() {}
|
||||||
|
ChunkSelection(int s, int c) : startRow(s), selectedRowsCount(c) {}
|
||||||
|
bool isNull() const { return selectedRowsCount <= 0; }
|
||||||
|
int startRow = -1;
|
||||||
|
int selectedRowsCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class DIFFEDITOR_EXPORT FileData {
|
class DIFFEDITOR_EXPORT FileData {
|
||||||
public:
|
public:
|
||||||
enum FileOperation {
|
enum FileOperation {
|
||||||
|
@@ -79,6 +79,8 @@ public:
|
|||||||
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 chunkIndexForBlockNumber(int blockNumber) const;
|
||||||
|
int chunkRowForBlockNumber(int blockNumber) const;
|
||||||
|
int chunkRowsCountForBlockNumber(int blockNumber) const;
|
||||||
bool isChunkLine(int blockNumber) const {
|
bool isChunkLine(int blockNumber) const {
|
||||||
return m_skippedLines.contains(blockNumber);
|
return m_skippedLines.contains(blockNumber);
|
||||||
}
|
}
|
||||||
@@ -97,7 +99,8 @@ signals:
|
|||||||
int columnNumber);
|
int columnNumber);
|
||||||
void contextMenuRequested(QMenu *menu,
|
void contextMenuRequested(QMenu *menu,
|
||||||
int diffFileIndex,
|
int diffFileIndex,
|
||||||
int chunkIndex);
|
int chunkIndex,
|
||||||
|
const ChunkSelection &selection);
|
||||||
void foldChanged(int blockNumber, bool folded);
|
void foldChanged(int blockNumber, bool folded);
|
||||||
void gotDisplaySettings();
|
void gotDisplaySettings();
|
||||||
void gotFocus();
|
void gotFocus();
|
||||||
@@ -355,6 +358,40 @@ int SideDiffEditorWidget::chunkIndexForBlockNumber(int blockNumber) const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SideDiffEditorWidget::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 SideDiffEditorWidget::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)
|
||||||
{
|
{
|
||||||
setBlockSelection(false);
|
setBlockSelection(false);
|
||||||
@@ -446,11 +483,40 @@ void SideDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
{
|
{
|
||||||
QPointer<QMenu> menu = createStandardContextMenu();
|
QPointer<QMenu> menu = createStandardContextMenu();
|
||||||
|
|
||||||
|
const QTextCursor tc = textCursor();
|
||||||
|
QTextCursor start = tc;
|
||||||
|
start.setPosition(tc.selectionStart());
|
||||||
|
QTextCursor end = tc;
|
||||||
|
end.setPosition(tc.selectionEnd());
|
||||||
|
const int startBlockNumber = start.blockNumber();
|
||||||
|
const int endBlockNumber = end.blockNumber();
|
||||||
|
|
||||||
QTextCursor cursor = cursorForPosition(e->pos());
|
QTextCursor cursor = cursorForPosition(e->pos());
|
||||||
const int blockNumber = cursor.blockNumber();
|
const int blockNumber = cursor.blockNumber();
|
||||||
|
|
||||||
|
const int fileIndex = fileIndexForBlockNumber(blockNumber);
|
||||||
|
const int chunkIndex = chunkIndexForBlockNumber(blockNumber);
|
||||||
|
|
||||||
|
const int selectionStartFileIndex = fileIndexForBlockNumber(startBlockNumber);
|
||||||
|
const int selectionStartChunkIndex = chunkIndexForBlockNumber(startBlockNumber);
|
||||||
|
const int selectionEndFileIndex = fileIndexForBlockNumber(endBlockNumber);
|
||||||
|
const int selectionEndChunkIndex = chunkIndexForBlockNumber(endBlockNumber);
|
||||||
|
|
||||||
|
const int selectionStart = selectionStartFileIndex == fileIndex
|
||||||
|
&& selectionStartChunkIndex == chunkIndex
|
||||||
|
? chunkRowForBlockNumber(startBlockNumber)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
const int selectionEnd = selectionEndFileIndex == fileIndex
|
||||||
|
&& selectionEndChunkIndex == chunkIndex
|
||||||
|
? chunkRowForBlockNumber(endBlockNumber)
|
||||||
|
: chunkRowsCountForBlockNumber(blockNumber);
|
||||||
|
|
||||||
|
const ChunkSelection selection(selectionStart, selectionEnd - selectionStart + 1);
|
||||||
|
|
||||||
emit contextMenuRequested(menu, fileIndexForBlockNumber(blockNumber),
|
emit contextMenuRequested(menu, fileIndexForBlockNumber(blockNumber),
|
||||||
chunkIndexForBlockNumber(blockNumber));
|
chunkIndexForBlockNumber(blockNumber),
|
||||||
|
selection);
|
||||||
|
|
||||||
connect(this, &SideDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater);
|
connect(this, &SideDiffEditorWidget::destroyed, menu.data(), &QMenu::deleteLater);
|
||||||
menu->exec(e->globalPos());
|
menu->exec(e->globalPos());
|
||||||
@@ -1067,24 +1133,26 @@ void SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested(
|
|||||||
|
|
||||||
void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
|
void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
|
||||||
int fileIndex,
|
int fileIndex,
|
||||||
int chunkIndex)
|
int chunkIndex,
|
||||||
|
const ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
|
void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
|
||||||
int fileIndex,
|
int fileIndex,
|
||||||
int chunkIndex)
|
int chunkIndex,
|
||||||
|
const ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SideBySideDiffEditorWidget::leftVSliderChanged()
|
void SideBySideDiffEditorWidget::leftVSliderChanged()
|
||||||
|
@@ -85,9 +85,9 @@ private:
|
|||||||
void slotRightJumpToOriginalFileRequested(int diffFileIndex,
|
void slotRightJumpToOriginalFileRequested(int diffFileIndex,
|
||||||
int lineNumber, int columnNumber);
|
int lineNumber, int columnNumber);
|
||||||
void slotLeftContextMenuRequested(QMenu *menu, int fileIndex,
|
void slotLeftContextMenuRequested(QMenu *menu, int fileIndex,
|
||||||
int chunkIndex);
|
int chunkIndex, const ChunkSelection &selection);
|
||||||
void slotRightContextMenuRequested(QMenu *menu, int fileIndex,
|
void slotRightContextMenuRequested(QMenu *menu, int fileIndex,
|
||||||
int chunkIndex);
|
int chunkIndex, const ChunkSelection &selection);
|
||||||
void leftVSliderChanged();
|
void leftVSliderChanged();
|
||||||
void rightVSliderChanged();
|
void rightVSliderChanged();
|
||||||
void leftHSliderChanged();
|
void leftHSliderChanged();
|
||||||
|
@@ -178,11 +178,57 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
{
|
{
|
||||||
QPointer<QMenu> menu = createStandardContextMenu();
|
QPointer<QMenu> menu = createStandardContextMenu();
|
||||||
|
|
||||||
|
const QTextCursor tc = textCursor();
|
||||||
|
QTextCursor start = tc;
|
||||||
|
start.setPosition(tc.selectionStart());
|
||||||
|
QTextCursor end = tc;
|
||||||
|
end.setPosition(tc.selectionEnd());
|
||||||
|
const int startBlockNumber = start.blockNumber();
|
||||||
|
const int endBlockNumber = end.blockNumber();
|
||||||
|
|
||||||
QTextCursor cursor = cursorForPosition(e->pos());
|
QTextCursor cursor = cursorForPosition(e->pos());
|
||||||
const int blockNumber = cursor.blockNumber();
|
const int blockNumber = cursor.blockNumber();
|
||||||
|
|
||||||
|
const int fileIndex = fileIndexForBlockNumber(blockNumber);
|
||||||
|
const int chunkIndex = chunkIndexForBlockNumber(blockNumber);
|
||||||
|
|
||||||
|
const ChunkData chunkData = m_controller.chunkData(fileIndex, chunkIndex);
|
||||||
|
|
||||||
|
int selectionStart = -1;
|
||||||
|
int selectionEnd = -1;
|
||||||
|
|
||||||
|
for (int i = startBlockNumber; i <= endBlockNumber; ++i) {
|
||||||
|
const int currentFileIndex = fileIndexForBlockNumber(i);
|
||||||
|
if (currentFileIndex < fileIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (currentFileIndex > fileIndex)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int currentChunkIndex = chunkIndexForBlockNumber(i);
|
||||||
|
if (currentChunkIndex < chunkIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (currentChunkIndex > chunkIndex)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int leftRow = m_leftLineNumbers.value(i, qMakePair(-1, -1)).second;
|
||||||
|
const int rightRow = m_rightLineNumbers.value(i, qMakePair(-1, -1)).second;
|
||||||
|
const int row = leftRow >= 0 ? leftRow : rightRow;
|
||||||
|
|
||||||
|
if (row < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (selectionStart < 0 || selectionStart > row)
|
||||||
|
selectionStart = row;
|
||||||
|
if (selectionEnd < 0 || selectionEnd < row)
|
||||||
|
selectionEnd = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChunkSelection selection(selectionStart, selectionEnd - selectionStart + 1);
|
||||||
|
|
||||||
addContextMenuActions(menu, fileIndexForBlockNumber(blockNumber),
|
addContextMenuActions(menu, fileIndexForBlockNumber(blockNumber),
|
||||||
chunkIndexForBlockNumber(blockNumber));
|
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());
|
||||||
@@ -191,14 +237,15 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
|
|
||||||
void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu,
|
void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu,
|
||||||
int fileIndex,
|
int fileIndex,
|
||||||
int chunkIndex)
|
int chunkIndex,
|
||||||
|
const ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
|
|
||||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
||||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
m_controller.addExtraActions(menu, fileIndex, chunkIndex, selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnifiedDiffEditorWidget::clear(const QString &message)
|
void UnifiedDiffEditorWidget::clear(const QString &message)
|
||||||
@@ -228,7 +275,7 @@ QString UnifiedDiffEditorWidget::lineNumber(int blockNumber) const
|
|||||||
|
|
||||||
if (leftLineExists || rightLineExists) {
|
if (leftLineExists || rightLineExists) {
|
||||||
const QString leftLine = leftLineExists
|
const QString leftLine = leftLineExists
|
||||||
? QString::number(m_leftLineNumbers.value(blockNumber))
|
? QString::number(m_leftLineNumbers.value(blockNumber).first)
|
||||||
: QString();
|
: QString();
|
||||||
lineNumberString += QString(m_leftLineNumberDigits - leftLine.count(),
|
lineNumberString += QString(m_leftLineNumberDigits - leftLine.count(),
|
||||||
' ') + leftLine;
|
' ') + leftLine;
|
||||||
@@ -236,7 +283,7 @@ QString UnifiedDiffEditorWidget::lineNumber(int blockNumber) const
|
|||||||
lineNumberString += '|';
|
lineNumberString += '|';
|
||||||
|
|
||||||
const QString rightLine = rightLineExists
|
const QString rightLine = rightLineExists
|
||||||
? QString::number(m_rightLineNumbers.value(blockNumber))
|
? QString::number(m_rightLineNumbers.value(blockNumber).first)
|
||||||
: QString();
|
: QString();
|
||||||
lineNumberString += QString(m_rightLineNumberDigits - rightLine.count(),
|
lineNumberString += QString(m_rightLineNumberDigits - rightLine.count(),
|
||||||
' ') + rightLine;
|
' ') + rightLine;
|
||||||
@@ -249,18 +296,20 @@ int UnifiedDiffEditorWidget::lineNumberDigits() const
|
|||||||
return m_leftLineNumberDigits + m_rightLineNumberDigits + 1;
|
return m_leftLineNumberDigits + m_rightLineNumberDigits + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnifiedDiffEditorWidget::setLeftLineNumber(int blockNumber, int lineNumber)
|
void UnifiedDiffEditorWidget::setLeftLineNumber(int blockNumber, int lineNumber,
|
||||||
|
int rowNumberInChunk)
|
||||||
{
|
{
|
||||||
const QString lineNumberString = QString::number(lineNumber);
|
const QString lineNumberString = QString::number(lineNumber);
|
||||||
m_leftLineNumbers.insert(blockNumber, lineNumber);
|
m_leftLineNumbers.insert(blockNumber, qMakePair(lineNumber, rowNumberInChunk));
|
||||||
m_leftLineNumberDigits = qMax(m_leftLineNumberDigits,
|
m_leftLineNumberDigits = qMax(m_leftLineNumberDigits,
|
||||||
lineNumberString.count());
|
lineNumberString.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnifiedDiffEditorWidget::setRightLineNumber(int blockNumber, int lineNumber)
|
void UnifiedDiffEditorWidget::setRightLineNumber(int blockNumber, int lineNumber,
|
||||||
|
int rowNumberInChunk)
|
||||||
{
|
{
|
||||||
const QString lineNumberString = QString::number(lineNumber);
|
const QString lineNumberString = QString::number(lineNumber);
|
||||||
m_rightLineNumbers.insert(blockNumber, lineNumber);
|
m_rightLineNumbers.insert(blockNumber, qMakePair(lineNumber, rowNumberInChunk));
|
||||||
m_rightLineNumberDigits = qMax(m_rightLineNumberDigits,
|
m_rightLineNumberDigits = qMax(m_rightLineNumberDigits,
|
||||||
lineNumberString.count());
|
lineNumberString.count());
|
||||||
}
|
}
|
||||||
@@ -307,6 +356,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
int blockCount = 0;
|
int blockCount = 0;
|
||||||
int charCount = 0;
|
int charCount = 0;
|
||||||
QList<TextLineData> leftBuffer, rightBuffer;
|
QList<TextLineData> leftBuffer, rightBuffer;
|
||||||
|
QList<int> leftRowsBuffer, rightRowsBuffer;
|
||||||
|
|
||||||
(*selections)[*blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
(*selections)[*blockNumber].append(DiffSelection(&m_controller.m_chunkLineFormat));
|
||||||
|
|
||||||
@@ -356,7 +406,8 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
if (!line.isEmpty()) {
|
if (!line.isEmpty()) {
|
||||||
setLeftLineNumber(*blockNumber + blockCount + 1,
|
setLeftLineNumber(*blockNumber + blockCount + 1,
|
||||||
chunkData.leftStartingLineNumber
|
chunkData.leftStartingLineNumber
|
||||||
+ leftLineCount + 1);
|
+ leftLineCount + 1,
|
||||||
|
leftRowsBuffer.at(j));
|
||||||
blockCount += blockDelta;
|
blockCount += blockDelta;
|
||||||
++leftLineCount;
|
++leftLineCount;
|
||||||
}
|
}
|
||||||
@@ -366,6 +417,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
charCount += line.count();
|
charCount += line.count();
|
||||||
}
|
}
|
||||||
leftBuffer.clear();
|
leftBuffer.clear();
|
||||||
|
leftRowsBuffer.clear();
|
||||||
}
|
}
|
||||||
if (rightBuffer.count()) {
|
if (rightBuffer.count()) {
|
||||||
for (int j = 0; j < rightBuffer.count(); j++) {
|
for (int j = 0; j < rightBuffer.count(); j++) {
|
||||||
@@ -396,7 +448,8 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
if (!line.isEmpty()) {
|
if (!line.isEmpty()) {
|
||||||
setRightLineNumber(*blockNumber + blockCount + 1,
|
setRightLineNumber(*blockNumber + blockCount + 1,
|
||||||
chunkData.rightStartingLineNumber
|
chunkData.rightStartingLineNumber
|
||||||
+ rightLineCount + 1);
|
+ rightLineCount + 1,
|
||||||
|
rightRowsBuffer.at(j));
|
||||||
blockCount += blockDelta;
|
blockCount += blockDelta;
|
||||||
++rightLineCount;
|
++rightLineCount;
|
||||||
}
|
}
|
||||||
@@ -406,6 +459,7 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
charCount += line.count();
|
charCount += line.count();
|
||||||
}
|
}
|
||||||
rightBuffer.clear();
|
rightBuffer.clear();
|
||||||
|
rightRowsBuffer.clear();
|
||||||
}
|
}
|
||||||
if (i < chunkData.rows.count()) {
|
if (i < chunkData.rows.count()) {
|
||||||
const QString line = DiffUtils::makePatchLine(' ',
|
const QString line = DiffUtils::makePatchLine(' ',
|
||||||
@@ -416,10 +470,12 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
if (!line.isEmpty()) {
|
if (!line.isEmpty()) {
|
||||||
setLeftLineNumber(*blockNumber + blockCount + 1,
|
setLeftLineNumber(*blockNumber + blockCount + 1,
|
||||||
chunkData.leftStartingLineNumber
|
chunkData.leftStartingLineNumber
|
||||||
+ leftLineCount + 1);
|
+ leftLineCount + 1,
|
||||||
|
i);
|
||||||
setRightLineNumber(*blockNumber + blockCount + 1,
|
setRightLineNumber(*blockNumber + blockCount + 1,
|
||||||
chunkData.rightStartingLineNumber
|
chunkData.rightStartingLineNumber
|
||||||
+ rightLineCount + 1);
|
+ rightLineCount + 1,
|
||||||
|
i);
|
||||||
blockCount += line.count('\n');
|
blockCount += line.count('\n');
|
||||||
++leftLineCount;
|
++leftLineCount;
|
||||||
++rightLineCount;
|
++rightLineCount;
|
||||||
@@ -430,10 +486,14 @@ QString UnifiedDiffEditorWidget::showChunk(const ChunkData &chunkData,
|
|||||||
charCount += line.count();
|
charCount += line.count();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
if (rowData.leftLine.textLineType == TextLineData::TextLine) {
|
||||||
leftBuffer.append(rowData.leftLine);
|
leftBuffer.append(rowData.leftLine);
|
||||||
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
leftRowsBuffer.append(i);
|
||||||
|
}
|
||||||
|
if (rowData.rightLine.textLineType == TextLineData::TextLine) {
|
||||||
rightBuffer.append(rowData.rightLine);
|
rightBuffer.append(rowData.rightLine);
|
||||||
|
rightRowsBuffer.append(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,13 +644,13 @@ void UnifiedDiffEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
|||||||
|
|
||||||
const int columnNumber = cursor.positionInBlock() - 1; // -1 for the first character in line
|
const int columnNumber = cursor.positionInBlock() - 1; // -1 for the first character in line
|
||||||
|
|
||||||
const int rightLineNumber = m_rightLineNumbers.value(blockNumber, -1);
|
const int rightLineNumber = m_rightLineNumbers.value(blockNumber, qMakePair(-1, 0)).first;
|
||||||
if (rightLineNumber >= 0) {
|
if (rightLineNumber >= 0) {
|
||||||
m_controller.jumpToOriginalFile(rightFileName, rightLineNumber, columnNumber);
|
m_controller.jumpToOriginalFile(rightFileName, rightLineNumber, columnNumber);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int leftLineNumber = m_leftLineNumbers.value(blockNumber, -1);
|
const int leftLineNumber = m_leftLineNumbers.value(blockNumber, qMakePair(-1, 0)).first;
|
||||||
if (leftLineNumber >= 0) {
|
if (leftLineNumber >= 0) {
|
||||||
if (leftFileName == rightFileName) {
|
if (leftFileName == rightFileName) {
|
||||||
for (const ChunkData &chunkData : fileData.chunks) {
|
for (const ChunkData &chunkData : fileData.chunks) {
|
||||||
|
@@ -39,6 +39,7 @@ namespace DiffEditor {
|
|||||||
|
|
||||||
class ChunkData;
|
class ChunkData;
|
||||||
class FileData;
|
class FileData;
|
||||||
|
class ChunkSelection;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -79,8 +80,8 @@ private:
|
|||||||
|
|
||||||
void slotCursorPositionChangedInEditor();
|
void slotCursorPositionChangedInEditor();
|
||||||
|
|
||||||
void setLeftLineNumber(int blockNumber, int lineNumber);
|
void setLeftLineNumber(int blockNumber, int lineNumber, int rowNumberInChunk);
|
||||||
void setRightLineNumber(int blockNumber, int lineNumber);
|
void setRightLineNumber(int blockNumber, int lineNumber, int rowNumberInChunk);
|
||||||
void setFileInfo(int blockNumber,
|
void setFileInfo(int blockNumber,
|
||||||
const DiffFileInfo &leftFileInfo,
|
const DiffFileInfo &leftFileInfo,
|
||||||
const DiffFileInfo &rightFileInfo);
|
const DiffFileInfo &rightFileInfo);
|
||||||
@@ -97,11 +98,12 @@ private:
|
|||||||
void jumpToOriginalFile(const QTextCursor &cursor);
|
void jumpToOriginalFile(const QTextCursor &cursor);
|
||||||
void addContextMenuActions(QMenu *menu,
|
void addContextMenuActions(QMenu *menu,
|
||||||
int fileIndex,
|
int fileIndex,
|
||||||
int chunkIndex);
|
int chunkIndex,
|
||||||
|
const ChunkSelection &selection);
|
||||||
|
|
||||||
// block number, visual line number.
|
// block number, visual line number, chunk row number
|
||||||
QMap<int, int> m_leftLineNumbers;
|
QMap<int, QPair<int, int> > m_leftLineNumbers;
|
||||||
QMap<int, int> m_rightLineNumbers;
|
QMap<int, QPair<int, int> > m_rightLineNumbers;
|
||||||
|
|
||||||
DiffEditorWidgetController m_controller;
|
DiffEditorWidgetController m_controller;
|
||||||
|
|
||||||
|
@@ -852,38 +852,58 @@ QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &s
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GitClient::chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex)
|
void GitClient::chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const DiffEditor::ChunkSelection &selection)
|
||||||
{
|
{
|
||||||
QPointer<DiffEditor::DiffEditorController> diffController
|
QPointer<DiffEditor::DiffEditorController> diffController
|
||||||
= qobject_cast<DiffEditorController *>(sender());
|
= qobject_cast<DiffEditorController *>(sender());
|
||||||
|
|
||||||
auto stageChunk = [this](QPointer<DiffEditor::DiffEditorController> diffController,
|
auto stageChunk = [this](QPointer<DiffEditor::DiffEditorController> diffController,
|
||||||
int fileIndex, int chunkIndex, bool revert) {
|
int fileIndex, int chunkIndex, DiffEditorController::PatchOptions options,
|
||||||
|
const DiffEditor::ChunkSelection &selection) {
|
||||||
if (diffController.isNull())
|
if (diffController.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DiffEditorController::PatchOptions options = DiffEditorController::AddPrefix;
|
options |= DiffEditorController::AddPrefix;
|
||||||
if (revert)
|
const QString patch = diffController->makePatch(fileIndex, chunkIndex, selection, options);
|
||||||
options |= DiffEditorController::Revert;
|
stage(diffController, patch, options & Revert);
|
||||||
const QString patch = diffController->makePatch(fileIndex, chunkIndex, options);
|
|
||||||
stage(diffController, patch, revert);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
QAction *stageChunkAction = menu->addAction(tr("Stage Chunk"));
|
QAction *stageChunkAction = menu->addAction(tr("Stage Chunk"));
|
||||||
connect(stageChunkAction, &QAction::triggered, this,
|
connect(stageChunkAction, &QAction::triggered, this,
|
||||||
[stageChunk, diffController, fileIndex, chunkIndex]() {
|
[stageChunk, diffController, fileIndex, chunkIndex]() {
|
||||||
stageChunk(diffController, fileIndex, chunkIndex, false);
|
stageChunk(diffController, fileIndex, chunkIndex,
|
||||||
|
DiffEditorController::NoOption, DiffEditor::ChunkSelection());
|
||||||
|
});
|
||||||
|
QAction *stageLinesAction = menu->addAction(tr("Stage %n Line(s)", "", selection.selectedRowsCount));
|
||||||
|
connect(stageLinesAction, &QAction::triggered, this,
|
||||||
|
[stageChunk, diffController, fileIndex, chunkIndex, selection]() {
|
||||||
|
stageChunk(diffController, fileIndex, chunkIndex,
|
||||||
|
DiffEditorController::NoOption, selection);
|
||||||
});
|
});
|
||||||
QAction *unstageChunkAction = menu->addAction(tr("Unstage Chunk"));
|
QAction *unstageChunkAction = menu->addAction(tr("Unstage Chunk"));
|
||||||
connect(unstageChunkAction, &QAction::triggered, this,
|
connect(unstageChunkAction, &QAction::triggered, this,
|
||||||
[stageChunk, diffController, fileIndex, chunkIndex]() {
|
[stageChunk, diffController, fileIndex, chunkIndex]() {
|
||||||
stageChunk(diffController, fileIndex, chunkIndex, true);
|
stageChunk(diffController, fileIndex, chunkIndex,
|
||||||
|
DiffEditorController::Revert, DiffEditor::ChunkSelection());
|
||||||
});
|
});
|
||||||
|
QAction *unstageLinesAction = menu->addAction(tr("Unstage %n Line(s)", "", selection.selectedRowsCount));
|
||||||
|
connect(unstageLinesAction, &QAction::triggered, this,
|
||||||
|
[stageChunk, diffController, fileIndex, chunkIndex, selection]() {
|
||||||
|
stageChunk(diffController, fileIndex, chunkIndex,
|
||||||
|
DiffEditorController::Revert,
|
||||||
|
selection);
|
||||||
|
});
|
||||||
|
if (selection.isNull()) {
|
||||||
|
stageLinesAction->setVisible(false);
|
||||||
|
unstageLinesAction->setVisible(false);
|
||||||
|
}
|
||||||
if (!diffController || !diffController->chunkExists(fileIndex, chunkIndex)) {
|
if (!diffController || !diffController->chunkExists(fileIndex, chunkIndex)) {
|
||||||
stageChunkAction->setEnabled(false);
|
stageChunkAction->setEnabled(false);
|
||||||
|
stageLinesAction->setEnabled(false);
|
||||||
unstageChunkAction->setEnabled(false);
|
unstageChunkAction->setEnabled(false);
|
||||||
|
unstageLinesAction->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,6 +54,7 @@ namespace VcsBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
class ChunkSelection;
|
||||||
class DiffEditorController;
|
class DiffEditorController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +334,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void finishSubmoduleUpdate();
|
void finishSubmoduleUpdate();
|
||||||
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
|
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex,
|
||||||
|
const DiffEditor::ChunkSelection &selection);
|
||||||
|
|
||||||
void stage(DiffEditor::DiffEditorController *diffController,
|
void stage(DiffEditor::DiffEditorController *diffController,
|
||||||
const QString &patch, bool revert);
|
const QString &patch, bool revert);
|
||||||
|
Reference in New Issue
Block a user