From 4bea049c457470cf678cdf5ec6d36bc78145af84 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 30 Jun 2017 14:50:28 +0200 Subject: [PATCH] VcsBase: Create common base diff editor controller Reuse it in subversion and git plugins. It makes subversion diff more asynchronous than before. Make VcsBase plugin dependand on DiffEditor plugin. Change-Id: Iafea2941b890a95a269362e022af2dc03cdea550 Reviewed-by: Tobias Hunger --- src/plugins/git/gitclient.cpp | 160 +++----------- src/plugins/subversion/subversionclient.cpp | 105 +++++----- src/plugins/subversion/subversionclient.h | 4 +- src/plugins/vcsbase/vcsbase.pro | 6 +- src/plugins/vcsbase/vcsbase.qbs | 3 + src/plugins/vcsbase/vcsbase_dependencies.pri | 3 +- .../vcsbase/vcsbasediffeditorcontroller.cpp | 195 ++++++++++++++++++ .../vcsbase/vcsbasediffeditorcontroller.h | 62 ++++++ 8 files changed, 341 insertions(+), 197 deletions(-) create mode 100644 src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp create mode 100644 src/plugins/vcsbase/vcsbasediffeditorcontroller.h diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index d4f8b706932..74fd2ba37d8 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -54,9 +53,9 @@ #include #include #include -#include #include +#include #include #include #include @@ -112,138 +111,31 @@ const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging | VcsCommand::SuppressStdErr | VcsCommand::SuppressFailMessage); -static void readPatch(QFutureInterface> &futureInterface, - const QString &patch) -{ - bool ok; - const QList &fileDataList = DiffUtils::readPatch(patch, &ok); - futureInterface.reportResult(fileDataList); -} - -///////////////////////////////////// - -class BaseController : public DiffEditorController +class GitDiffEditorController : public VcsBaseDiffEditorController { Q_OBJECT public: - BaseController(IDocument *document, const QString &dir); - ~BaseController(); + GitDiffEditorController(IDocument *document, const QString &workingDirectory); protected: - void runCommand(const QList &args, QTextCodec *codec = 0); - virtual void processCommandOutput(const QString &output); + void runCommand(const QList &args, QTextCodec *codec = nullptr); QStringList addConfigurationArguments(const QStringList &args) const; QStringList addHeadWhenCommandInProgress() const; - - void setStartupFile(const QString &startupFile) { m_startupFile = startupFile; } - QString startupFile() const { return m_startupFile; } - QString directory() const { return m_directory; } - -private: - void processDiff(const QString &patch); - void storeOutput(const QString &output); - void cancelReload(); - void commandFinished(bool success); - void processingFinished(); - - const QString m_directory; - QString m_startupFile; - QString m_output; - QPointer m_command; - QFutureWatcher> m_processWatcher; }; -BaseController::BaseController(IDocument *document, const QString &dir) : - DiffEditorController(document), - m_directory(dir), - m_command(0) +GitDiffEditorController::GitDiffEditorController(IDocument *document, const QString &workingDirectory) : + VcsBaseDiffEditorController(document, GitPlugin::client(), workingDirectory) { - connect(&m_processWatcher, &QFutureWatcher>::finished, - this, &BaseController::processingFinished); } -BaseController::~BaseController() +void GitDiffEditorController::runCommand(const QList &args, QTextCodec *codec) { - cancelReload(); + VcsBaseDiffEditorController::runCommand(args, diffExecutionFlags(), codec); } -void BaseController::cancelReload() -{ - if (m_command) { - m_command->disconnect(); - m_command->cancel(); - m_command.clear(); - } - - if (m_processWatcher.future().isRunning()) { - m_processWatcher.future().cancel(); - m_processWatcher.setFuture(QFuture>()); - } - m_output = QString(); -} - -void BaseController::commandFinished(bool success) -{ - if (m_command) - m_command.clear(); - - if (!success) { - cancelReload(); - reloadFinished(success); - return; - } - - processCommandOutput(m_output); -} - -void BaseController::runCommand(const QList &args, QTextCodec *codec) -{ - cancelReload(); - - m_command = new VcsCommand(directory(), GitPlugin::client()->processEnvironment()); - m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec()); - connect(m_command.data(), &VcsCommand::stdOutText, this, &BaseController::storeOutput); - connect(m_command.data(), &VcsCommand::finished, this, &BaseController::commandFinished); - m_command->addFlags(diffExecutionFlags()); - - for (const QStringList &arg : args) { - QTC_ASSERT(!arg.isEmpty(), continue); - - m_command->addJob(GitPlugin::client()->vcsBinary(), arg, GitPlugin::client()->vcsTimeoutS()); - } - - m_command->execute(); -} - -void BaseController::storeOutput(const QString &output) -{ - m_output = output; -} - -void BaseController::processCommandOutput(const QString &output) -{ - processDiff(output); -} - -void BaseController::processDiff(const QString &patch) -{ - m_processWatcher.setFuture(Utils::runAsync(&readPatch, patch)); - - Core::ProgressManager::addTask(m_processWatcher.future(), - tr("Processing diff"), "DiffEditor"); -} - -void BaseController::processingFinished() -{ - const QList fileDataList = m_processWatcher.future().result(); - - setDiffFiles(fileDataList, directory(), startupFile()); - reloadFinished(true); -} - -QStringList BaseController::addConfigurationArguments(const QStringList &args) const +QStringList GitDiffEditorController::addConfigurationArguments(const QStringList &args) const { QTC_ASSERT(!args.isEmpty(), return args); @@ -261,23 +153,23 @@ QStringList BaseController::addConfigurationArguments(const QStringList &args) c return realArgs; } -QStringList BaseController::addHeadWhenCommandInProgress() const +QStringList GitDiffEditorController::addHeadWhenCommandInProgress() const { // This is workaround for lack of support for merge commits and resolving conflicts, // we compare the current state of working tree to the HEAD of current branch // instead of showing unsupported combined diff format. - GitClient::CommandInProgress commandInProgress = GitPlugin::client()->checkCommandInProgress(directory()); + GitClient::CommandInProgress commandInProgress = GitPlugin::client()->checkCommandInProgress(workingDirectory()); if (commandInProgress != GitClient::NoCommand) return {HEAD}; return QStringList(); } -class RepositoryDiffController : public BaseController +class RepositoryDiffController : public GitDiffEditorController { Q_OBJECT public: RepositoryDiffController(IDocument *document, const QString &dir) : - BaseController(document, dir) + GitDiffEditorController(document, dir) { } void reload() override; @@ -290,12 +182,12 @@ void RepositoryDiffController::reload() runCommand(QList() << addConfigurationArguments(args)); } -class FileDiffController : public BaseController +class FileDiffController : public GitDiffEditorController { Q_OBJECT public: FileDiffController(IDocument *document, const QString &dir, const QString &fileName) : - BaseController(document, dir), + GitDiffEditorController(document, dir), m_fileName(fileName) { } @@ -314,13 +206,13 @@ void FileDiffController::reload() runCommand(QList() << addConfigurationArguments(args)); } -class FileListDiffController : public BaseController +class FileListDiffController : public GitDiffEditorController { Q_OBJECT public: FileListDiffController(IDocument *document, const QString &dir, const QStringList &stagedFiles, const QStringList &unstagedFiles) : - BaseController(document, dir), + GitDiffEditorController(document, dir), m_stagedFiles(stagedFiles), m_unstagedFiles(unstagedFiles) { } @@ -351,13 +243,13 @@ void FileListDiffController::reload() runCommand(argLists); } -class ProjectDiffController : public BaseController +class ProjectDiffController : public GitDiffEditorController { Q_OBJECT public: ProjectDiffController(IDocument *document, const QString &dir, const QStringList &projectPaths) : - BaseController(document, dir), + GitDiffEditorController(document, dir), m_projectPaths(projectPaths) { } @@ -374,13 +266,13 @@ void ProjectDiffController::reload() runCommand(QList() << addConfigurationArguments(args)); } -class BranchDiffController : public BaseController +class BranchDiffController : public GitDiffEditorController { Q_OBJECT public: BranchDiffController(IDocument *document, const QString &dir, const QString &branch) : - BaseController(document, dir), + GitDiffEditorController(document, dir), m_branch(branch) { } @@ -397,12 +289,12 @@ void BranchDiffController::reload() runCommand(QList() << addConfigurationArguments(args)); } -class ShowController : public BaseController +class ShowController : public GitDiffEditorController { Q_OBJECT public: ShowController(IDocument *document, const QString &dir, const QString &id) : - BaseController(document, dir), + GitDiffEditorController(document, dir), m_id(id), m_state(Idle) { } @@ -421,7 +313,7 @@ void ShowController::reload() // stage 1 m_state = GettingDescription; const QStringList args = {"show", "-s", noColorOption, showFormatC, m_id}; - runCommand(QList() << args, GitPlugin::client()->encoding(directory(), "i18n.commitEncoding")); + runCommand(QList() << args, GitPlugin::client()->encoding(workingDirectory(), "i18n.commitEncoding")); setStartupFile(VcsBasePlugin::source(document())); } @@ -429,7 +321,7 @@ void ShowController::processCommandOutput(const QString &output) { QTC_ASSERT(m_state != Idle, return); if (m_state == GettingDescription) { - setDescription(GitPlugin::client()->extendedShowDescription(directory(), output)); + setDescription(GitPlugin::client()->extendedShowDescription(workingDirectory(), output)); // stage 2 m_state = GettingDiff; const QStringList args = {"show", "--format=format:", // omit header, already generated @@ -437,7 +329,7 @@ void ShowController::processCommandOutput(const QString &output) runCommand(QList() << addConfigurationArguments(args)); } else if (m_state == GettingDiff) { m_state = Idle; - BaseController::processCommandOutput(output); + GitDiffEditorController::processCommandOutput(output); } } diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index d6b4c89e51f..185a76c1a52 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -167,46 +168,40 @@ QStringList SubversionClient::escapeFiles(const QStringList &files) return Utils::transform(files, &SubversionClient::escapeFile); } -class DiffController : public DiffEditorController +class SubversionDiffEditorController : public VcsBaseDiffEditorController { Q_OBJECT public: - DiffController(IDocument *document, const SubversionClient *client, const QString &directory); + SubversionDiffEditorController(IDocument *document, + const QString &workingDirectory); void setFilesList(const QStringList &filesList); void setChangeNumber(int changeNumber); protected: void reload() override; - -private slots: - void slotTextualDiffOutputReceived(const QString &contents); + void processCommandOutput(const QString &output) override; private: - QString getDescription() const; - void postCollectTextualDiffOutput(); - QProcessEnvironment processEnvironment() const; + void requestDescription(); + void requestDiff(); - const SubversionClient *m_client; - QString m_workingDirectory; + enum State { Idle, GettingDescription, GettingDiff }; + State m_state; QStringList m_filesList; int m_changeNumber = 0; }; -DiffController::DiffController(IDocument *document, const SubversionClient *client, const QString &directory) : - DiffEditorController(document), - m_client(client), - m_workingDirectory(directory) +SubversionDiffEditorController::SubversionDiffEditorController( + IDocument *document, + const QString &workingDirectory) + : VcsBaseDiffEditorController(document, SubversionPlugin::instance()->client(), workingDirectory) + , m_state(Idle) { forceContextLineCount(3); // SVN can not change that when using internal diff } -QProcessEnvironment DiffController::processEnvironment() const -{ - return m_client->processEnvironment(); -} - -void DiffController::setFilesList(const QStringList &filesList) +void SubversionDiffEditorController::setFilesList(const QStringList &filesList) { if (isReloading()) return; @@ -214,7 +209,7 @@ void DiffController::setFilesList(const QStringList &filesList) m_filesList = SubversionClient::escapeFiles(filesList); } -void DiffController::setChangeNumber(int changeNumber) +void SubversionDiffEditorController::setChangeNumber(int changeNumber) { if (isReloading()) return; @@ -222,33 +217,24 @@ void DiffController::setChangeNumber(int changeNumber) m_changeNumber = qMax(changeNumber, 0); } -QString DiffController::getDescription() const +void SubversionDiffEditorController::requestDescription() { + m_state = GettingDescription; + QStringList args(QLatin1String("log")); - args << SubversionClient::addAuthenticationOptions(m_client->settings()); + args << SubversionClient::addAuthenticationOptions(client()->settings()); args << QLatin1String("-r"); args << QString::number(m_changeNumber); - const SubversionResponse logResponse = - SubversionPlugin::instance()->runSvn(m_workingDirectory, args, - m_client->vcsTimeoutS(), - VcsCommand::SshPasswordPrompt); - - if (logResponse.error) - return QString(); - - return logResponse.stdOut; + runCommand(QList() << args, VcsCommand::SshPasswordPrompt); } -void DiffController::postCollectTextualDiffOutput() +void SubversionDiffEditorController::requestDiff() { - auto command = new VcsCommand(m_workingDirectory, processEnvironment()); - command->setCodec(EditorManager::defaultTextCodec()); - connect(command, &VcsCommand::stdOutText, this, &DiffController::slotTextualDiffOutputReceived); -// command->addFlags(diffExecutionFlags()); + m_state = GettingDiff; QStringList args; args << QLatin1String("diff"); - args << m_client->addAuthenticationOptions(m_client->settings()); + args << SubversionClient::addAuthenticationOptions(client()->settings()); args << QLatin1String("--internal-diff"); if (ignoreWhitespace()) args << QLatin1String("-x") << QLatin1String("-uw"); @@ -258,40 +244,43 @@ void DiffController::postCollectTextualDiffOutput() } else { args << m_filesList; } - - command->addJob(m_client->vcsBinary(), args, m_client->vcsTimeoutS()); - command->execute(); + runCommand(QList() << args, 0); } -void DiffController::slotTextualDiffOutputReceived(const QString &contents) +void SubversionDiffEditorController::reload() { - bool ok; - QList fileDataList - = DiffUtils::readPatch(contents, &ok); - setDiffFiles(fileDataList, m_workingDirectory); - - reloadFinished(true); + if (m_changeNumber) { + requestDescription(); + } else { + requestDiff(); + } } -void DiffController::reload() +void SubversionDiffEditorController::processCommandOutput(const QString &output) { - const QString description = m_changeNumber - ? getDescription() : QString(); - postCollectTextualDiffOutput(); - setDescription(description); + QTC_ASSERT(m_state != Idle, return); + if (m_state == GettingDescription) { + setDescription(output); + + requestDiff(); + } else if (m_state == GettingDiff) { + m_state = Idle; + VcsBaseDiffEditorController::processCommandOutput(output); + } } -DiffController *SubversionClient::findOrCreateDiffEditor(const QString &documentId, +SubversionDiffEditorController *SubversionClient::findOrCreateDiffEditor(const QString &documentId, const QString &source, const QString &title, const QString &workingDirectory) const { IDocument *document = DiffEditorController::findOrCreateDocument(documentId, title); - DiffController *controller = qobject_cast( + SubversionDiffEditorController *controller = qobject_cast( DiffEditorController::controller(document)); if (!controller) - controller = new DiffController(document, this, workingDirectory); + controller = new SubversionDiffEditorController(document, workingDirectory); VcsBasePlugin::setSource(document, source); + EditorManager::activateEditorForDocument(document); return controller; } @@ -304,7 +293,7 @@ void SubversionClient::diff(const QString &workingDirectory, const QStringList & + QLatin1String(".Diff.") + VcsBaseEditor::getTitleId(workingDirectory, files); const QString title = vcsEditorTitle(vcsCmdString, documentId); - DiffController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, + SubversionDiffEditorController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, workingDirectory); controller->setFilesList(files); controller->requestReload(); @@ -335,7 +324,7 @@ void SubversionClient::describe(const QString &workingDirectory, int changeNumbe QStringList(), QString::number(changeNumber)); - DiffController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, workingDirectory); + SubversionDiffEditorController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, workingDirectory); controller->setChangeNumber(changeNumber); controller->requestReload(); } diff --git a/src/plugins/subversion/subversionclient.h b/src/plugins/subversion/subversionclient.h index 7cc287f210f..b3ed32c2c20 100644 --- a/src/plugins/subversion/subversionclient.h +++ b/src/plugins/subversion/subversionclient.h @@ -35,7 +35,7 @@ namespace Subversion { namespace Internal { class SubversionSettings; -class DiffController; +class SubversionDiffEditorController; class SubversionClient : public VcsBase::VcsBaseClient { @@ -78,7 +78,7 @@ protected: Core::Id vcsEditorKind(VcsCommandTag cmd) const override; private: - DiffController *findOrCreateDiffEditor(const QString &documentId, const QString &source, + SubversionDiffEditorController *findOrCreateDiffEditor(const QString &documentId, const QString &source, const QString &title, const QString &workingDirectory) const; mutable Utils::FileName m_svnVersionBinary; diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro index 461dc152c02..90ba9e848de 100644 --- a/src/plugins/vcsbase/vcsbase.pro +++ b/src/plugins/vcsbase/vcsbase.pro @@ -27,7 +27,8 @@ HEADERS += vcsbase_global.h \ vcsbaseclientsettings.h \ vcsbaseeditorconfig.h \ submitfieldwidget.h \ - submiteditorwidget.h + submiteditorwidget.h \ + vcsbasediffeditorcontroller.h SOURCES += vcsplugin.cpp \ vcsbaseplugin.cpp \ @@ -54,7 +55,8 @@ SOURCES += vcsplugin.cpp \ vcsbaseclientsettings.cpp \ vcsbaseeditorconfig.cpp \ submitfieldwidget.cpp \ - submiteditorwidget.cpp + submiteditorwidget.cpp \ + vcsbasediffeditorcontroller.cpp RESOURCES += vcsbase.qrc diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs index deeb41a4c72..db5c5a37393 100644 --- a/src/plugins/vcsbase/vcsbase.qbs +++ b/src/plugins/vcsbase/vcsbase.qbs @@ -12,6 +12,7 @@ QtcPlugin { Depends { name: "TextEditor" } Depends { name: "ProjectExplorer" } Depends { name: "CppTools" } + Depends { name: "DiffEditor" } pluginRecommends: [ "CodePaster" @@ -53,6 +54,8 @@ QtcPlugin { "vcsbaseclientsettings.cpp", "vcsbaseclientsettings.h", "vcsbaseconstants.h", + "vcsbasediffeditorcontroller.cpp", + "vcsbasediffeditorcontroller.h", "vcsbaseeditor.cpp", "vcsbaseeditor.h", "vcsbaseeditorconfig.cpp", diff --git a/src/plugins/vcsbase/vcsbase_dependencies.pri b/src/plugins/vcsbase/vcsbase_dependencies.pri index bff0f1dcf4b..f398e2926be 100644 --- a/src/plugins/vcsbase/vcsbase_dependencies.pri +++ b/src/plugins/vcsbase/vcsbase_dependencies.pri @@ -8,6 +8,7 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ texteditor \ projectexplorer \ - cpptools + cpptools \ + diffeditor QTC_PLUGIN_RECOMMENDS += \ cpaster diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp new file mode 100644 index 00000000000..edaeafb4651 --- /dev/null +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "vcsbasediffeditorcontroller.h" +#include "vcsbaseclient.h" +#include "vcscommand.h" + +#include +#include +#include +#include +#include + +#include + +using namespace DiffEditor; +using namespace Core; + +namespace VcsBase { + +static void readPatch(QFutureInterface> &futureInterface, + const QString &patch) +{ + bool ok; + const QList &fileDataList = DiffUtils::readPatch(patch, &ok); + futureInterface.reportResult(fileDataList); +} + +class VcsBaseDiffEditorControllerPrivate +{ +public: + VcsBaseDiffEditorControllerPrivate(VcsBaseDiffEditorController *controller, + VcsBaseClientImpl *client, + const QString &workingDirectory); + ~VcsBaseDiffEditorControllerPrivate(); + + void processingFinished(); + void processDiff(const QString &patch); + void cancelReload(); + void commandFinished(bool success); + + VcsBaseDiffEditorController *q; + VcsBaseClientImpl *m_client; + const QString m_directory; + QString m_startupFile; + QString m_output; + QPointer m_command; + QFutureWatcher> m_processWatcher; +}; + +VcsBaseDiffEditorControllerPrivate::VcsBaseDiffEditorControllerPrivate(VcsBaseDiffEditorController *controller, + VcsBaseClientImpl *client, + const QString &workingDirectory) + : q(controller) + , m_client(client) + , m_directory(workingDirectory) +{ + QObject::connect(&m_processWatcher, &QFutureWatcher>::finished, q, + [this] () { processingFinished(); }); +} + +VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate() +{ + cancelReload(); +} + +void VcsBaseDiffEditorControllerPrivate::processingFinished() +{ + const QList fileDataList = m_processWatcher.future().result(); + + q->setDiffFiles(fileDataList, q->workingDirectory(), q->startupFile()); + q->reloadFinished(true); +} + +void VcsBaseDiffEditorControllerPrivate::processDiff(const QString &patch) +{ + m_processWatcher.setFuture(Utils::runAsync(&readPatch, patch)); + + ProgressManager::addTask(m_processWatcher.future(), + q->tr("Processing diff"), "DiffEditor"); +} + +void VcsBaseDiffEditorControllerPrivate::cancelReload() +{ + if (m_command) { + m_command->disconnect(); + m_command->cancel(); + m_command.clear(); + } + + if (m_processWatcher.future().isRunning()) { + m_processWatcher.future().cancel(); + m_processWatcher.setFuture(QFuture>()); + } + m_output = QString(); +} + +void VcsBaseDiffEditorControllerPrivate::commandFinished(bool success) +{ + if (m_command) + m_command.clear(); + + if (!success) { + cancelReload(); + q->reloadFinished(success); + return; + } + + q->processCommandOutput(m_output); +} + +///////////////////// + +VcsBaseDiffEditorController::VcsBaseDiffEditorController(IDocument *document, + VcsBaseClientImpl *client, + const QString &workingDirectory) + : DiffEditorController(document) + , d(new VcsBaseDiffEditorControllerPrivate(this, client, workingDirectory)) +{ +} + +VcsBaseDiffEditorController::~VcsBaseDiffEditorController() +{ + delete d; +} + +void VcsBaseDiffEditorController::runCommand(const QList &args, unsigned flags, QTextCodec *codec) +{ + d->cancelReload(); + + d->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment()); + d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec()); + connect(d->m_command.data(), &VcsCommand::stdOutText, this, + [this] (const QString &output) { d->m_output = output; }); + connect(d->m_command.data(), &VcsCommand::finished, this, + [this] (bool success) { d->commandFinished(success); }); + d->m_command->addFlags(flags); + + for (const QStringList &arg : args) { + QTC_ASSERT(!arg.isEmpty(), continue); + + d->m_command->addJob(d->m_client->vcsBinary(), arg, d->m_client->vcsTimeoutS()); + } + + d->m_command->execute(); +} + +void VcsBaseDiffEditorController::processCommandOutput(const QString &output) +{ + d->processDiff(output); +} + +VcsBaseClientImpl *VcsBaseDiffEditorController::client() const +{ + return d->m_client; +} + +QString VcsBaseDiffEditorController::workingDirectory() const +{ + return d->m_directory; +} + +void VcsBaseDiffEditorController::setStartupFile(const QString &startupFile) +{ + d->m_startupFile = startupFile; +} + +QString VcsBaseDiffEditorController::startupFile() const +{ + return d->m_startupFile; +} + +} // namespace VcsBase diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.h b/src/plugins/vcsbase/vcsbasediffeditorcontroller.h new file mode 100644 index 00000000000..97a7dbeff23 --- /dev/null +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "vcsbase_global.h" +#include + +namespace Core { class IDocument; } + +namespace VcsBase { + +class VcsBaseClientImpl; +class VcsBaseDiffEditorControllerPrivate; + +class VCSBASE_EXPORT VcsBaseDiffEditorController : public DiffEditor::DiffEditorController +{ + Q_OBJECT + +public: + VcsBaseDiffEditorController(Core::IDocument *document, + VcsBaseClientImpl *client, + const QString &workingDirectory); + ~VcsBaseDiffEditorController(); + +protected: + void runCommand(const QList &args, unsigned flags, QTextCodec *codec = nullptr); + virtual void processCommandOutput(const QString &output); + + VcsBaseClientImpl *client() const; + QString workingDirectory() const; + void setStartupFile(const QString &startupFile); + QString startupFile() const; + +private: + friend class VcsBaseDiffEditorControllerPrivate; + VcsBaseDiffEditorControllerPrivate *d; +}; + +} //namespace VcsBase