forked from qt-creator/qt-creator
DiffEditor: Use QtConcurrent invocation for async tasks
Change-Id: I06640837ffee830e60e8dd2a566f9388f8444010 Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
@@ -14,11 +14,10 @@ publication by Neil Fraser: http://neil.fraser.name/writing/diff/
|
||||
#include "utilstr.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QFutureInterfaceBase>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
@@ -937,10 +936,9 @@ QString Diff::toString() const
|
||||
|
||||
///////////////
|
||||
|
||||
Differ::Differ(QFutureInterfaceBase *jobController)
|
||||
: m_jobController(jobController)
|
||||
Differ::Differ(const QFuture<void> &future)
|
||||
: m_future(future)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QList<Diff> Differ::diff(const QString &text1, const QString &text2)
|
||||
@@ -1075,7 +1073,7 @@ QList<Diff> Differ::diffMyers(const QString &text1, const QString &text2)
|
||||
int kMinReverse = -D;
|
||||
int kMaxReverse = D;
|
||||
for (int d = 0; d <= D; d++) {
|
||||
if (m_jobController && m_jobController->isCanceled()) {
|
||||
if (m_future.isCanceled()) {
|
||||
delete [] forwardV;
|
||||
delete [] reverseV;
|
||||
return QList<Diff>();
|
||||
@@ -1193,17 +1191,10 @@ QList<Diff> Differ::diffNonCharMode(const QString &text1, const QString &text2)
|
||||
QString lastDelete;
|
||||
QString lastInsert;
|
||||
QList<Diff> newDiffList;
|
||||
if (m_jobController) {
|
||||
m_jobController->setProgressRange(0, diffList.count());
|
||||
m_jobController->setProgressValue(0);
|
||||
}
|
||||
for (int i = 0; i <= diffList.count(); i++) {
|
||||
if (m_jobController) {
|
||||
if (m_jobController->isCanceled()) {
|
||||
m_currentDiffMode = diffMode;
|
||||
return QList<Diff>();
|
||||
}
|
||||
m_jobController->setProgressValue(i + 1);
|
||||
if (m_future.isCanceled()) {
|
||||
m_currentDiffMode = diffMode;
|
||||
return {};
|
||||
}
|
||||
const Diff diffItem = i < diffList.count()
|
||||
? diffList.at(i)
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QFuture>
|
||||
#include <QString>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
template <class K, class T>
|
||||
class QMap;
|
||||
class QFutureInterfaceBase;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
WordMode,
|
||||
LineMode
|
||||
};
|
||||
Differ(QFutureInterfaceBase *jobController = nullptr);
|
||||
Differ(const QFuture<void> &future = {});
|
||||
QList<Diff> diff(const QString &text1, const QString &text2);
|
||||
QList<Diff> unifiedDiff(const QString &text1, const QString &text2);
|
||||
void setDiffMode(DiffMode mode);
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
int subTextStart);
|
||||
DiffMode m_diffMode = Differ::LineMode;
|
||||
DiffMode m_currentDiffMode = Differ::LineMode;
|
||||
QFutureInterfaceBase *m_jobController = nullptr;
|
||||
QFuture<void> m_future;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
@@ -291,8 +291,8 @@ Core::IDocument::OpenResult DiffEditorDocument::open(QString *errorString, const
|
||||
return OpenResult::ReadError;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
QList<FileData> fileDataList = DiffUtils::readPatch(patch, &ok);
|
||||
const std::optional<QList<FileData>> fileDataList = DiffUtils::readPatch(patch);
|
||||
bool ok = fileDataList.has_value();
|
||||
if (!ok) {
|
||||
*errorString = Tr::tr("Could not parse patch file \"%1\". "
|
||||
"The content is not of unified diff format.")
|
||||
@@ -302,7 +302,7 @@ Core::IDocument::OpenResult DiffEditorDocument::open(QString *errorString, const
|
||||
emit temporaryStateChanged();
|
||||
setFilePath(filePath.absoluteFilePath());
|
||||
setWorkingDirectory(filePath.absoluteFilePath());
|
||||
setDiffFiles(fileDataList);
|
||||
setDiffFiles(*fileDataList);
|
||||
}
|
||||
endReload(ok);
|
||||
if (!ok && readResult == TextFileFormat::ReadEncodingError)
|
||||
|
||||
@@ -47,13 +47,12 @@ public:
|
||||
m_ignoreWhitespace(ignoreWhitespace)
|
||||
{}
|
||||
|
||||
void operator()(QFutureInterface<FileData> &futureInterface,
|
||||
const ReloadInput &reloadInput) const
|
||||
void operator()(QPromise<FileData> &promise, const ReloadInput &reloadInput) const
|
||||
{
|
||||
if (reloadInput.text[LeftSide] == reloadInput.text[RightSide])
|
||||
return; // We show "No difference" in this case, regardless if it's binary or not
|
||||
|
||||
Differ differ(&futureInterface);
|
||||
Differ differ(QFuture<void>(promise.future()));
|
||||
|
||||
FileData fileData;
|
||||
if (!reloadInput.binaryFiles) {
|
||||
@@ -85,7 +84,7 @@ public:
|
||||
fileData.fileInfo = reloadInput.fileInfo;
|
||||
fileData.fileOperation = reloadInput.fileOperation;
|
||||
fileData.binaryFiles = reloadInput.binaryFiles;
|
||||
futureInterface.reportResult(fileData);
|
||||
promise.addResult(fileData);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -115,7 +114,7 @@ DiffFilesController::DiffFilesController(IDocument *document)
|
||||
QList<std::optional<FileData>> *outputList = storage.activeStorage();
|
||||
|
||||
const auto setupDiff = [this](AsyncTask<FileData> &async, const ReloadInput &reloadInput) {
|
||||
async.setAsyncCallData(DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
|
||||
async.setConcurrentCallData(DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
|
||||
async.setFutureSynchronizer(Internal::DiffEditorPlugin::futureSynchronizer());
|
||||
};
|
||||
const auto onDiffDone = [outputList](const AsyncTask<FileData> &async, int i) {
|
||||
@@ -771,13 +770,13 @@ void DiffEditor::Internal::DiffEditorPlugin::testMakePatch()
|
||||
|
||||
QCOMPARE(result, patchText);
|
||||
|
||||
bool ok;
|
||||
QList<FileData> resultList = DiffUtils::readPatch(result, &ok);
|
||||
const std::optional<QList<FileData>> resultList = DiffUtils::readPatch(result);
|
||||
const bool ok = resultList.has_value();
|
||||
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(resultList.count(), 1);
|
||||
for (int i = 0; i < resultList.count(); i++) {
|
||||
const FileData &resultFileData = resultList.at(i);
|
||||
QCOMPARE(resultList->count(), 1);
|
||||
for (int i = 0; i < resultList->count(); i++) {
|
||||
const FileData &resultFileData = resultList->at(i);
|
||||
QCOMPARE(resultFileData.fileInfo[LeftSide].fileName, fileName);
|
||||
QCOMPARE(resultFileData.fileInfo[RightSide].fileName, fileName);
|
||||
QCOMPARE(resultFileData.chunks.count(), 1);
|
||||
@@ -1335,14 +1334,14 @@ void DiffEditor::Internal::DiffEditorPlugin::testReadPatch()
|
||||
QFETCH(QString, sourcePatch);
|
||||
QFETCH(QList<FileData>, fileDataList);
|
||||
|
||||
bool ok;
|
||||
const QList<FileData> &result = DiffUtils::readPatch(sourcePatch, &ok);
|
||||
const std::optional<QList<FileData>> result = DiffUtils::readPatch(sourcePatch);
|
||||
const bool ok = result.has_value();
|
||||
|
||||
QVERIFY(ok);
|
||||
QCOMPARE(result.count(), fileDataList.count());
|
||||
QCOMPARE(result->count(), fileDataList.count());
|
||||
for (int i = 0; i < fileDataList.count(); i++) {
|
||||
const FileData &origFileData = fileDataList.at(i);
|
||||
const FileData &resultFileData = result.at(i);
|
||||
const FileData &resultFileData = result->at(i);
|
||||
QCOMPARE(resultFileData.fileInfo[LeftSide].fileName, origFileData.fileInfo[LeftSide].fileName);
|
||||
QCOMPARE(resultFileData.fileInfo[LeftSide].typeInfo, origFileData.fileInfo[LeftSide].typeInfo);
|
||||
QCOMPARE(resultFileData.fileInfo[RightSide].fileName, origFileData.fileInfo[RightSide].fileName);
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/differ.h>
|
||||
|
||||
#include <QFutureInterfaceBase>
|
||||
#include <QFuture>
|
||||
#include <QPromise>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
@@ -892,7 +893,7 @@ static FileData readDiffHeaderAndChunks(QStringView headerAndChunks, bool *ok)
|
||||
|
||||
}
|
||||
|
||||
static QList<FileData> readDiffPatch(QStringView patch, bool *ok, QFutureInterfaceBase *jobController)
|
||||
static void readDiffPatch(QPromise<QList<FileData>> &promise, QStringView patch)
|
||||
{
|
||||
const QRegularExpression diffRegExp("(?:\\n|^)" // new line of the beginning of a patch
|
||||
"(" // either
|
||||
@@ -911,23 +912,20 @@ static QList<FileData> readDiffPatch(QStringView patch, bool *ok, QFutureInterfa
|
||||
")"); // end of or
|
||||
|
||||
bool readOk = false;
|
||||
|
||||
QList<FileData> fileDataList;
|
||||
|
||||
QRegularExpressionMatch diffMatch = diffRegExp.match(patch);
|
||||
if (diffMatch.hasMatch()) {
|
||||
readOk = true;
|
||||
int lastPos = -1;
|
||||
do {
|
||||
if (jobController && jobController->isCanceled())
|
||||
return {};
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
int pos = diffMatch.capturedStart();
|
||||
if (lastPos >= 0) {
|
||||
QStringView headerAndChunks = patch.mid(lastPos, pos - lastPos);
|
||||
|
||||
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks,
|
||||
&readOk);
|
||||
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks, &readOk);
|
||||
|
||||
if (!readOk)
|
||||
break;
|
||||
@@ -942,21 +940,15 @@ static QList<FileData> readDiffPatch(QStringView patch, bool *ok, QFutureInterfa
|
||||
if (readOk) {
|
||||
QStringView headerAndChunks = patch.mid(lastPos, patch.size() - lastPos - 1);
|
||||
|
||||
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks,
|
||||
&readOk);
|
||||
const FileData fileData = readDiffHeaderAndChunks(headerAndChunks, &readOk);
|
||||
|
||||
if (readOk)
|
||||
fileDataList.append(fileData);
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
*ok = readOk;
|
||||
|
||||
if (!readOk)
|
||||
return {};
|
||||
|
||||
return fileDataList;
|
||||
return;
|
||||
promise.addResult(fileDataList);
|
||||
}
|
||||
|
||||
// The git diff patch format (ChangeFile, NewFile, DeleteFile)
|
||||
@@ -1203,7 +1195,7 @@ static bool detectFileData(QStringView patch, FileData *fileData, QStringView *r
|
||||
return detectIndexAndBinary(*remainingPatch, fileData, remainingPatch);
|
||||
}
|
||||
|
||||
static QList<FileData> readGitPatch(QStringView patch, bool *ok, QFutureInterfaceBase *jobController)
|
||||
static void readGitPatch(QPromise<QList<FileData>> &promise, QStringView patch)
|
||||
{
|
||||
int position = -1;
|
||||
|
||||
@@ -1221,13 +1213,12 @@ static QList<FileData> readGitPatch(QStringView patch, bool *ok, QFutureInterfac
|
||||
};
|
||||
|
||||
const QChar newLine('\n');
|
||||
bool readOk = true;
|
||||
|
||||
QVector<PatchInfo> patches;
|
||||
const int count = startingPositions.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (jobController && jobController->isCanceled())
|
||||
return {};
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
const int diffStart = startingPositions.at(i);
|
||||
const int diffEnd = (i < count - 1)
|
||||
@@ -1242,32 +1233,21 @@ static QList<FileData> readGitPatch(QStringView patch, bool *ok, QFutureInterfac
|
||||
|
||||
FileData fileData;
|
||||
QStringView remainingFileDiff;
|
||||
readOk = detectFileData(fileDiff, &fileData, &remainingFileDiff);
|
||||
|
||||
if (!readOk)
|
||||
break;
|
||||
if (!detectFileData(fileDiff, &fileData, &remainingFileDiff))
|
||||
return;
|
||||
|
||||
patches.append(PatchInfo { remainingFileDiff, fileData });
|
||||
}
|
||||
|
||||
if (!readOk) {
|
||||
if (ok)
|
||||
*ok = readOk;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (jobController)
|
||||
jobController->setProgressRange(0, patches.size());
|
||||
promise.setProgressRange(0, patches.size());
|
||||
|
||||
QList<FileData> fileDataList;
|
||||
readOk = false;
|
||||
bool readOk = false;
|
||||
int i = 0;
|
||||
for (const auto &patchInfo : std::as_const(patches)) {
|
||||
if (jobController) {
|
||||
if (jobController->isCanceled())
|
||||
return {};
|
||||
jobController->setProgressValue(i++);
|
||||
}
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
promise.setProgressValue(i++);
|
||||
|
||||
FileData fileData = patchInfo.fileData;
|
||||
if (!patchInfo.patch.isEmpty() || fileData.fileOperation == FileData::ChangeFile)
|
||||
@@ -1276,31 +1256,27 @@ static QList<FileData> readGitPatch(QStringView patch, bool *ok, QFutureInterfac
|
||||
readOk = true;
|
||||
|
||||
if (!readOk)
|
||||
break;
|
||||
return;
|
||||
|
||||
fileDataList.append(fileData);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
*ok = readOk;
|
||||
|
||||
if (!readOk)
|
||||
return {};
|
||||
|
||||
return fileDataList;
|
||||
promise.addResult(fileDataList);
|
||||
}
|
||||
|
||||
QList<FileData> DiffUtils::readPatch(const QString &patch, bool *ok,
|
||||
QFutureInterfaceBase *jobController)
|
||||
std::optional<QList<FileData>> DiffUtils::readPatch(const QString &patch)
|
||||
{
|
||||
bool readOk = false;
|
||||
QPromise<QList<FileData>> promise;
|
||||
promise.start();
|
||||
readPatchWithPromise(promise, patch);
|
||||
if (promise.future().resultCount() == 0)
|
||||
return {};
|
||||
return promise.future().result();
|
||||
}
|
||||
|
||||
QList<FileData> fileDataList;
|
||||
|
||||
if (jobController) {
|
||||
jobController->setProgressRange(0, 1);
|
||||
jobController->setProgressValue(0);
|
||||
}
|
||||
void DiffUtils::readPatchWithPromise(QPromise<QList<FileData>> &promise, const QString &patch)
|
||||
{
|
||||
promise.setProgressRange(0, 1);
|
||||
promise.setProgressValue(0);
|
||||
QStringView croppedPatch = QStringView(patch);
|
||||
// Crop e.g. "-- \n2.10.2.windows.1\n\n" at end of file
|
||||
const QRegularExpression formatPatchEndingRegExp("(\\n-- \\n\\S*\\n\\n$)");
|
||||
@@ -1308,14 +1284,9 @@ QList<FileData> DiffUtils::readPatch(const QString &patch, bool *ok,
|
||||
if (match.hasMatch())
|
||||
croppedPatch = croppedPatch.left(match.capturedStart() + 1);
|
||||
|
||||
fileDataList = readGitPatch(croppedPatch, &readOk, jobController);
|
||||
if (!readOk)
|
||||
fileDataList = readDiffPatch(croppedPatch, &readOk, jobController);
|
||||
|
||||
if (ok)
|
||||
*ok = readOk;
|
||||
|
||||
return fileDataList;
|
||||
readGitPatch(promise, croppedPatch);
|
||||
if (promise.future().resultCount() == 0)
|
||||
readDiffPatch(promise, croppedPatch);
|
||||
}
|
||||
|
||||
} // namespace DiffEditor
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
#include <array>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFutureInterfaceBase;
|
||||
template <class T>
|
||||
class QPromise;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils { class Diff; }
|
||||
@@ -142,9 +143,8 @@ public:
|
||||
const QString &rightFileName,
|
||||
bool lastChunk = false);
|
||||
static QString makePatch(const QList<FileData> &fileDataList);
|
||||
static QList<FileData> readPatch(const QString &patch,
|
||||
bool *ok = nullptr,
|
||||
QFutureInterfaceBase *jobController = nullptr);
|
||||
static std::optional<QList<FileData>> readPatch(const QString &patch);
|
||||
static void readPatchWithPromise(QPromise<QList<FileData>> &promise, const QString &patch);
|
||||
};
|
||||
|
||||
} // namespace DiffEditor
|
||||
|
||||
@@ -8,14 +8,8 @@
|
||||
#include "diffeditorplugin.h"
|
||||
#include "diffeditortr.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/find/highlightscrollbarcontroller.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/minisplitter.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
|
||||
@@ -29,6 +23,11 @@
|
||||
#include <utils/mathutils.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
using namespace Core;
|
||||
using namespace TextEditor;
|
||||
using namespace Utils;
|
||||
@@ -245,7 +244,7 @@ QString SideDiffEditorWidget::plainTextFromSelection(const QTextCursor &cursor)
|
||||
return TextDocument::convertToPlainText(text);
|
||||
}
|
||||
|
||||
SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterface<void> &fi, int progressMin,
|
||||
SideBySideDiffOutput SideDiffData::diffOutput(QFutureInterfaceBase &fi, int progressMin,
|
||||
int progressMax, const DiffEditorInput &input)
|
||||
{
|
||||
SideBySideDiffOutput output;
|
||||
@@ -914,19 +913,15 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
|
||||
const DiffEditorInput input(&m_controller);
|
||||
|
||||
auto getDocument = [input](QFutureInterface<ShowResults> &futureInterface) {
|
||||
auto cleanup = qScopeGuard([&futureInterface] {
|
||||
if (futureInterface.isCanceled())
|
||||
futureInterface.reportCanceled();
|
||||
});
|
||||
auto getDocument = [input](QPromise<ShowResults> &promise) {
|
||||
const int firstPartMax = 20; // diffOutput is about 4 times quicker than filling document
|
||||
const int leftPartMax = 60;
|
||||
const int rightPartMax = 100;
|
||||
futureInterface.setProgressRange(0, rightPartMax);
|
||||
futureInterface.setProgressValue(0);
|
||||
QFutureInterface<void> fi = futureInterface;
|
||||
promise.setProgressRange(0, rightPartMax);
|
||||
promise.setProgressValue(0);
|
||||
QFutureInterfaceBase fi = QFutureInterfaceBase::get(promise.future());
|
||||
const SideBySideDiffOutput output = SideDiffData::diffOutput(fi, 0, firstPartMax, input);
|
||||
if (futureInterface.isCanceled())
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
const ShowResult leftResult{TextDocumentPtr(new TextDocument("DiffEditor.SideDiffEditor")),
|
||||
@@ -935,7 +930,7 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
output.side[RightSide].diffData, output.side[RightSide].selections};
|
||||
const ShowResults result{leftResult, rightResult};
|
||||
|
||||
auto propagateDocument = [&output, &fi](DiffSide side, const ShowResult &result,
|
||||
auto propagateDocument = [&output, &promise](DiffSide side, const ShowResult &result,
|
||||
int progressMin, int progressMax) {
|
||||
// No need to store the change history
|
||||
result.textDocument->document()->setUndoRedoEnabled(false);
|
||||
@@ -952,8 +947,9 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
const QString package = output.side[side].diffText.mid(currentPos, packageSize);
|
||||
cursor.insertText(package);
|
||||
currentPos += package.size();
|
||||
fi.setProgressValue(MathUtils::interpolateLinear(currentPos, 0, diffSize, progressMin, progressMax));
|
||||
if (fi.isCanceled())
|
||||
promise.setProgressValue(MathUtils::interpolateLinear(currentPos, 0, diffSize,
|
||||
progressMin, progressMax));
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -968,16 +964,16 @@ void SideBySideDiffEditorWidget::showDiff()
|
||||
};
|
||||
|
||||
propagateDocument(LeftSide, leftResult, firstPartMax, leftPartMax);
|
||||
if (fi.isCanceled())
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
propagateDocument(RightSide, rightResult, leftPartMax, rightPartMax);
|
||||
if (fi.isCanceled())
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
futureInterface.reportResult(result);
|
||||
promise.addResult(result);
|
||||
};
|
||||
|
||||
m_asyncTask->setAsyncCallData(getDocument);
|
||||
m_asyncTask->setConcurrentCallData(getDocument);
|
||||
m_asyncTask->start();
|
||||
ProgressManager::addTask(m_asyncTask->future(), Tr::tr("Rendering diff"), "DiffEditor");
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
#include "selectabletexteditorwidget.h" // TODO: we need DiffSelections here only
|
||||
|
||||
#include <QFutureInterface>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Core { class IContext; }
|
||||
@@ -23,6 +22,7 @@ class AsyncTask;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFutureInterfaceBase;
|
||||
class QMenu;
|
||||
class QSplitter;
|
||||
QT_END_NAMESPACE
|
||||
@@ -40,7 +40,7 @@ class SideBySideDiffOutput;
|
||||
class SideDiffData
|
||||
{
|
||||
public:
|
||||
static SideBySideDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin,
|
||||
static SideBySideDiffOutput diffOutput(QFutureInterfaceBase &fi, int progressMin,
|
||||
int progressMax, const DiffEditorInput &input);
|
||||
|
||||
DiffChunkInfo m_chunkInfo;
|
||||
|
||||
@@ -8,23 +8,20 @@
|
||||
#include "diffeditorplugin.h"
|
||||
#include "diffeditortr.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <texteditor/textdocumentlayout.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
|
||||
#include <utils/asynctask.h>
|
||||
#include <utils/mathutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
|
||||
#include <QMenu>
|
||||
#include <QScrollBar>
|
||||
#include <QTextBlock>
|
||||
|
||||
using namespace Core;
|
||||
using namespace TextEditor;
|
||||
@@ -48,10 +45,10 @@ UnifiedDiffEditorWidget::UnifiedDiffEditorWidget(QWidget *parent)
|
||||
connect(this, &QPlainTextEdit::cursorPositionChanged,
|
||||
this, &UnifiedDiffEditorWidget::slotCursorPositionChangedInEditor);
|
||||
|
||||
auto context = new Core::IContext(this);
|
||||
auto context = new IContext(this);
|
||||
context->setWidget(this);
|
||||
context->setContext(Core::Context(Constants::UNIFIED_VIEW_ID));
|
||||
Core::ICore::addContextObject(context);
|
||||
context->setContext(Context(Constants::UNIFIED_VIEW_ID));
|
||||
ICore::addContextObject(context);
|
||||
}
|
||||
|
||||
UnifiedDiffEditorWidget::~UnifiedDiffEditorWidget() = default;
|
||||
@@ -391,7 +388,7 @@ QString UnifiedDiffData::setChunk(const DiffEditorInput &input, const ChunkData
|
||||
return diffText;
|
||||
}
|
||||
|
||||
UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterface<void> &fi, int progressMin,
|
||||
UnifiedDiffOutput UnifiedDiffData::diffOutput(QFutureInterfaceBase &fi, int progressMin,
|
||||
int progressMax, const DiffEditorInput &input)
|
||||
{
|
||||
UnifiedDiffOutput output;
|
||||
@@ -481,18 +478,14 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
|
||||
const DiffEditorInput input(&m_controller);
|
||||
|
||||
auto getDocument = [input](QFutureInterface<ShowResult> &futureInterface) {
|
||||
auto cleanup = qScopeGuard([&futureInterface] {
|
||||
if (futureInterface.isCanceled())
|
||||
futureInterface.reportCanceled();
|
||||
});
|
||||
auto getDocument = [input](QPromise<ShowResult> &promise) {
|
||||
const int progressMax = 100;
|
||||
const int firstPartMax = 20; // diffOutput is about 4 times quicker than filling document
|
||||
futureInterface.setProgressRange(0, progressMax);
|
||||
futureInterface.setProgressValue(0);
|
||||
QFutureInterface<void> fi = futureInterface;
|
||||
promise.setProgressRange(0, progressMax);
|
||||
promise.setProgressValue(0);
|
||||
QFutureInterfaceBase fi = QFutureInterfaceBase::get(promise.future());
|
||||
const UnifiedDiffOutput output = UnifiedDiffData::diffOutput(fi, 0, firstPartMax, input);
|
||||
if (futureInterface.isCanceled())
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
|
||||
const ShowResult result = {TextDocumentPtr(new TextDocument("DiffEditor.UnifiedDiffEditor")),
|
||||
@@ -512,8 +505,9 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
const QString package = output.diffText.mid(currentPos, packageSize);
|
||||
cursor.insertText(package);
|
||||
currentPos += package.size();
|
||||
fi.setProgressValue(MathUtils::interpolateLinear(currentPos, 0, diffSize, firstPartMax, progressMax));
|
||||
if (futureInterface.isCanceled())
|
||||
promise.setProgressValue(MathUtils::interpolateLinear(currentPos, 0, diffSize,
|
||||
firstPartMax, progressMax));
|
||||
if (promise.isCanceled())
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -525,10 +519,10 @@ void UnifiedDiffEditorWidget::showDiff()
|
||||
// to caller's thread. We push it to no thread (make object to have no thread affinity),
|
||||
// and later, in the caller's thread, we pull it back to the caller's thread.
|
||||
result.textDocument->moveToThread(nullptr);
|
||||
futureInterface.reportResult(result);
|
||||
promise.addResult(result);
|
||||
};
|
||||
|
||||
m_asyncTask->setAsyncCallData(getDocument);
|
||||
m_asyncTask->setConcurrentCallData(getDocument);
|
||||
m_asyncTask->start();
|
||||
ProgressManager::addTask(m_asyncTask->future(), Tr::tr("Rendering diff"), "DiffEditor");
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
#include "selectabletexteditorwidget.h"
|
||||
|
||||
#include <QFutureInterface>
|
||||
|
||||
namespace Core { class IContext; }
|
||||
|
||||
namespace TextEditor { class FontSettings; }
|
||||
@@ -17,6 +15,10 @@ template <typename R>
|
||||
class AsyncTask;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFutureInterfaceBase;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DiffEditor {
|
||||
|
||||
class ChunkData;
|
||||
@@ -31,7 +33,7 @@ class UnifiedDiffOutput;
|
||||
class UnifiedDiffData
|
||||
{
|
||||
public:
|
||||
static UnifiedDiffOutput diffOutput(QFutureInterface<void> &fi, int progressMin, int progressMax,
|
||||
static UnifiedDiffOutput diffOutput(QFutureInterfaceBase &fi, int progressMin, int progressMax,
|
||||
const DiffEditorInput &input);
|
||||
|
||||
DiffChunkInfo m_chunkInfo;
|
||||
|
||||
@@ -15,15 +15,6 @@ using namespace Utils;
|
||||
|
||||
namespace VcsBase {
|
||||
|
||||
static void readPatch(QFutureInterface<QList<FileData>> &futureInterface, const QString &patch)
|
||||
{
|
||||
bool ok;
|
||||
const QList<FileData> &fileDataList = DiffUtils::readPatch(patch, &ok, &futureInterface);
|
||||
futureInterface.reportResult(fileDataList);
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
|
||||
class VcsBaseDiffEditorControllerPrivate
|
||||
{
|
||||
public:
|
||||
@@ -61,11 +52,11 @@ Tasking::TaskItem VcsBaseDiffEditorController::postProcessTask()
|
||||
QTC_ASSERT(storage, qWarning("Using postProcessTask() requires putting inputStorage() "
|
||||
"into task tree's root group."));
|
||||
const QString inputData = storage ? *storage : QString();
|
||||
async.setAsyncCallData(readPatch, inputData);
|
||||
async.setConcurrentCallData(&DiffUtils::readPatchWithPromise, inputData);
|
||||
async.setFutureSynchronizer(Internal::VcsPlugin::futureSynchronizer());
|
||||
};
|
||||
const auto onDiffProcessorDone = [this](const AsyncTask<QList<FileData>> &async) {
|
||||
setDiffFiles(async.result());
|
||||
setDiffFiles(async.isResultAvailable() ? async.result() : QList<FileData>());
|
||||
};
|
||||
const auto onDiffProcessorError = [this](const AsyncTask<QList<FileData>> &) {
|
||||
setDiffFiles({});
|
||||
|
||||
Reference in New Issue
Block a user