forked from qt-creator/qt-creator
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 <tobias.hunger@qt.io>
This commit is contained in:
@@ -43,7 +43,6 @@
|
|||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/iversioncontrol.h>
|
#include <coreplugin/iversioncontrol.h>
|
||||||
#include <coreplugin/vcsmanager.h>
|
#include <coreplugin/vcsmanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/asconst.h>
|
#include <utils/asconst.h>
|
||||||
@@ -54,9 +53,9 @@
|
|||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
#include <utils/synchronousprocess.h>
|
#include <utils/synchronousprocess.h>
|
||||||
#include <utils/temporaryfile.h>
|
#include <utils/temporaryfile.h>
|
||||||
#include <utils/runextensions.h>
|
|
||||||
|
|
||||||
#include <vcsbase/submitfilemodel.h>
|
#include <vcsbase/submitfilemodel.h>
|
||||||
|
#include <vcsbase/vcsbasediffeditorcontroller.h>
|
||||||
#include <vcsbase/vcsbaseeditor.h>
|
#include <vcsbase/vcsbaseeditor.h>
|
||||||
#include <vcsbase/vcsbaseeditorconfig.h>
|
#include <vcsbase/vcsbaseeditorconfig.h>
|
||||||
#include <vcsbase/vcsbaseplugin.h>
|
#include <vcsbase/vcsbaseplugin.h>
|
||||||
@@ -112,138 +111,31 @@ const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging
|
|||||||
| VcsCommand::SuppressStdErr
|
| VcsCommand::SuppressStdErr
|
||||||
| VcsCommand::SuppressFailMessage);
|
| VcsCommand::SuppressFailMessage);
|
||||||
|
|
||||||
static void readPatch(QFutureInterface<QList<FileData>> &futureInterface,
|
class GitDiffEditorController : public VcsBaseDiffEditorController
|
||||||
const QString &patch)
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
const QList<FileData> &fileDataList = DiffUtils::readPatch(patch, &ok);
|
|
||||||
futureInterface.reportResult(fileDataList);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
|
||||||
|
|
||||||
class BaseController : public DiffEditorController
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BaseController(IDocument *document, const QString &dir);
|
GitDiffEditorController(IDocument *document, const QString &workingDirectory);
|
||||||
~BaseController();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void runCommand(const QList<QStringList> &args, QTextCodec *codec = 0);
|
void runCommand(const QList<QStringList> &args, QTextCodec *codec = nullptr);
|
||||||
virtual void processCommandOutput(const QString &output);
|
|
||||||
|
|
||||||
QStringList addConfigurationArguments(const QStringList &args) const;
|
QStringList addConfigurationArguments(const QStringList &args) const;
|
||||||
QStringList addHeadWhenCommandInProgress() 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<VcsCommand> m_command;
|
|
||||||
QFutureWatcher<QList<FileData>> m_processWatcher;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BaseController::BaseController(IDocument *document, const QString &dir) :
|
GitDiffEditorController::GitDiffEditorController(IDocument *document, const QString &workingDirectory) :
|
||||||
DiffEditorController(document),
|
VcsBaseDiffEditorController(document, GitPlugin::client(), workingDirectory)
|
||||||
m_directory(dir),
|
|
||||||
m_command(0)
|
|
||||||
{
|
{
|
||||||
connect(&m_processWatcher, &QFutureWatcher<QList<FileData>>::finished,
|
|
||||||
this, &BaseController::processingFinished);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseController::~BaseController()
|
void GitDiffEditorController::runCommand(const QList<QStringList> &args, QTextCodec *codec)
|
||||||
{
|
{
|
||||||
cancelReload();
|
VcsBaseDiffEditorController::runCommand(args, diffExecutionFlags(), codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseController::cancelReload()
|
QStringList GitDiffEditorController::addConfigurationArguments(const QStringList &args) const
|
||||||
{
|
|
||||||
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<QList<FileData>>());
|
|
||||||
}
|
|
||||||
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<QStringList> &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<FileData> fileDataList = m_processWatcher.future().result();
|
|
||||||
|
|
||||||
setDiffFiles(fileDataList, directory(), startupFile());
|
|
||||||
reloadFinished(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList BaseController::addConfigurationArguments(const QStringList &args) const
|
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!args.isEmpty(), return args);
|
QTC_ASSERT(!args.isEmpty(), return args);
|
||||||
|
|
||||||
@@ -261,23 +153,23 @@ QStringList BaseController::addConfigurationArguments(const QStringList &args) c
|
|||||||
return realArgs;
|
return realArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList BaseController::addHeadWhenCommandInProgress() const
|
QStringList GitDiffEditorController::addHeadWhenCommandInProgress() const
|
||||||
{
|
{
|
||||||
// This is workaround for lack of support for merge commits and resolving conflicts,
|
// 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
|
// we compare the current state of working tree to the HEAD of current branch
|
||||||
// instead of showing unsupported combined diff format.
|
// 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)
|
if (commandInProgress != GitClient::NoCommand)
|
||||||
return {HEAD};
|
return {HEAD};
|
||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
class RepositoryDiffController : public BaseController
|
class RepositoryDiffController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
RepositoryDiffController(IDocument *document, const QString &dir) :
|
RepositoryDiffController(IDocument *document, const QString &dir) :
|
||||||
BaseController(document, dir)
|
GitDiffEditorController(document, dir)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void reload() override;
|
void reload() override;
|
||||||
@@ -290,12 +182,12 @@ void RepositoryDiffController::reload()
|
|||||||
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileDiffController : public BaseController
|
class FileDiffController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
FileDiffController(IDocument *document, const QString &dir, const QString &fileName) :
|
FileDiffController(IDocument *document, const QString &dir, const QString &fileName) :
|
||||||
BaseController(document, dir),
|
GitDiffEditorController(document, dir),
|
||||||
m_fileName(fileName)
|
m_fileName(fileName)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -314,13 +206,13 @@ void FileDiffController::reload()
|
|||||||
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
class FileListDiffController : public BaseController
|
class FileListDiffController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
FileListDiffController(IDocument *document, const QString &dir,
|
FileListDiffController(IDocument *document, const QString &dir,
|
||||||
const QStringList &stagedFiles, const QStringList &unstagedFiles) :
|
const QStringList &stagedFiles, const QStringList &unstagedFiles) :
|
||||||
BaseController(document, dir),
|
GitDiffEditorController(document, dir),
|
||||||
m_stagedFiles(stagedFiles),
|
m_stagedFiles(stagedFiles),
|
||||||
m_unstagedFiles(unstagedFiles)
|
m_unstagedFiles(unstagedFiles)
|
||||||
{ }
|
{ }
|
||||||
@@ -351,13 +243,13 @@ void FileListDiffController::reload()
|
|||||||
runCommand(argLists);
|
runCommand(argLists);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProjectDiffController : public BaseController
|
class ProjectDiffController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ProjectDiffController(IDocument *document, const QString &dir,
|
ProjectDiffController(IDocument *document, const QString &dir,
|
||||||
const QStringList &projectPaths) :
|
const QStringList &projectPaths) :
|
||||||
BaseController(document, dir),
|
GitDiffEditorController(document, dir),
|
||||||
m_projectPaths(projectPaths)
|
m_projectPaths(projectPaths)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -374,13 +266,13 @@ void ProjectDiffController::reload()
|
|||||||
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
class BranchDiffController : public BaseController
|
class BranchDiffController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
BranchDiffController(IDocument *document, const QString &dir,
|
BranchDiffController(IDocument *document, const QString &dir,
|
||||||
const QString &branch) :
|
const QString &branch) :
|
||||||
BaseController(document, dir),
|
GitDiffEditorController(document, dir),
|
||||||
m_branch(branch)
|
m_branch(branch)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -397,12 +289,12 @@ void BranchDiffController::reload()
|
|||||||
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShowController : public BaseController
|
class ShowController : public GitDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ShowController(IDocument *document, const QString &dir, const QString &id) :
|
ShowController(IDocument *document, const QString &dir, const QString &id) :
|
||||||
BaseController(document, dir),
|
GitDiffEditorController(document, dir),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_state(Idle)
|
m_state(Idle)
|
||||||
{ }
|
{ }
|
||||||
@@ -421,7 +313,7 @@ void ShowController::reload()
|
|||||||
// stage 1
|
// stage 1
|
||||||
m_state = GettingDescription;
|
m_state = GettingDescription;
|
||||||
const QStringList args = {"show", "-s", noColorOption, showFormatC, m_id};
|
const QStringList args = {"show", "-s", noColorOption, showFormatC, m_id};
|
||||||
runCommand(QList<QStringList>() << args, GitPlugin::client()->encoding(directory(), "i18n.commitEncoding"));
|
runCommand(QList<QStringList>() << args, GitPlugin::client()->encoding(workingDirectory(), "i18n.commitEncoding"));
|
||||||
setStartupFile(VcsBasePlugin::source(document()));
|
setStartupFile(VcsBasePlugin::source(document()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,7 +321,7 @@ void ShowController::processCommandOutput(const QString &output)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_state != Idle, return);
|
QTC_ASSERT(m_state != Idle, return);
|
||||||
if (m_state == GettingDescription) {
|
if (m_state == GettingDescription) {
|
||||||
setDescription(GitPlugin::client()->extendedShowDescription(directory(), output));
|
setDescription(GitPlugin::client()->extendedShowDescription(workingDirectory(), output));
|
||||||
// stage 2
|
// stage 2
|
||||||
m_state = GettingDiff;
|
m_state = GettingDiff;
|
||||||
const QStringList args = {"show", "--format=format:", // omit header, already generated
|
const QStringList args = {"show", "--format=format:", // omit header, already generated
|
||||||
@@ -437,7 +329,7 @@ void ShowController::processCommandOutput(const QString &output)
|
|||||||
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
runCommand(QList<QStringList>() << addConfigurationArguments(args));
|
||||||
} else if (m_state == GettingDiff) {
|
} else if (m_state == GettingDiff) {
|
||||||
m_state = Idle;
|
m_state = Idle;
|
||||||
BaseController::processCommandOutput(output);
|
GitDiffEditorController::processCommandOutput(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <vcsbase/vcscommand.h>
|
#include <vcsbase/vcscommand.h>
|
||||||
#include <vcsbase/vcsbaseconstants.h>
|
#include <vcsbase/vcsbaseconstants.h>
|
||||||
|
#include <vcsbase/vcsbasediffeditorcontroller.h>
|
||||||
#include <vcsbase/vcsbaseeditor.h>
|
#include <vcsbase/vcsbaseeditor.h>
|
||||||
#include <vcsbase/vcsbaseeditorconfig.h>
|
#include <vcsbase/vcsbaseeditorconfig.h>
|
||||||
#include <vcsbase/vcsbaseplugin.h>
|
#include <vcsbase/vcsbaseplugin.h>
|
||||||
@@ -167,46 +168,40 @@ QStringList SubversionClient::escapeFiles(const QStringList &files)
|
|||||||
return Utils::transform(files, &SubversionClient::escapeFile);
|
return Utils::transform(files, &SubversionClient::escapeFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DiffController : public DiffEditorController
|
class SubversionDiffEditorController : public VcsBaseDiffEditorController
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DiffController(IDocument *document, const SubversionClient *client, const QString &directory);
|
SubversionDiffEditorController(IDocument *document,
|
||||||
|
const QString &workingDirectory);
|
||||||
|
|
||||||
void setFilesList(const QStringList &filesList);
|
void setFilesList(const QStringList &filesList);
|
||||||
void setChangeNumber(int changeNumber);
|
void setChangeNumber(int changeNumber);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reload() override;
|
void reload() override;
|
||||||
|
void processCommandOutput(const QString &output) override;
|
||||||
private slots:
|
|
||||||
void slotTextualDiffOutputReceived(const QString &contents);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString getDescription() const;
|
void requestDescription();
|
||||||
void postCollectTextualDiffOutput();
|
void requestDiff();
|
||||||
QProcessEnvironment processEnvironment() const;
|
|
||||||
|
|
||||||
const SubversionClient *m_client;
|
enum State { Idle, GettingDescription, GettingDiff };
|
||||||
QString m_workingDirectory;
|
State m_state;
|
||||||
QStringList m_filesList;
|
QStringList m_filesList;
|
||||||
int m_changeNumber = 0;
|
int m_changeNumber = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
DiffController::DiffController(IDocument *document, const SubversionClient *client, const QString &directory) :
|
SubversionDiffEditorController::SubversionDiffEditorController(
|
||||||
DiffEditorController(document),
|
IDocument *document,
|
||||||
m_client(client),
|
const QString &workingDirectory)
|
||||||
m_workingDirectory(directory)
|
: VcsBaseDiffEditorController(document, SubversionPlugin::instance()->client(), workingDirectory)
|
||||||
|
, m_state(Idle)
|
||||||
{
|
{
|
||||||
forceContextLineCount(3); // SVN can not change that when using internal diff
|
forceContextLineCount(3); // SVN can not change that when using internal diff
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcessEnvironment DiffController::processEnvironment() const
|
void SubversionDiffEditorController::setFilesList(const QStringList &filesList)
|
||||||
{
|
|
||||||
return m_client->processEnvironment();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiffController::setFilesList(const QStringList &filesList)
|
|
||||||
{
|
{
|
||||||
if (isReloading())
|
if (isReloading())
|
||||||
return;
|
return;
|
||||||
@@ -214,7 +209,7 @@ void DiffController::setFilesList(const QStringList &filesList)
|
|||||||
m_filesList = SubversionClient::escapeFiles(filesList);
|
m_filesList = SubversionClient::escapeFiles(filesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffController::setChangeNumber(int changeNumber)
|
void SubversionDiffEditorController::setChangeNumber(int changeNumber)
|
||||||
{
|
{
|
||||||
if (isReloading())
|
if (isReloading())
|
||||||
return;
|
return;
|
||||||
@@ -222,33 +217,24 @@ void DiffController::setChangeNumber(int changeNumber)
|
|||||||
m_changeNumber = qMax(changeNumber, 0);
|
m_changeNumber = qMax(changeNumber, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DiffController::getDescription() const
|
void SubversionDiffEditorController::requestDescription()
|
||||||
{
|
{
|
||||||
|
m_state = GettingDescription;
|
||||||
|
|
||||||
QStringList args(QLatin1String("log"));
|
QStringList args(QLatin1String("log"));
|
||||||
args << SubversionClient::addAuthenticationOptions(m_client->settings());
|
args << SubversionClient::addAuthenticationOptions(client()->settings());
|
||||||
args << QLatin1String("-r");
|
args << QLatin1String("-r");
|
||||||
args << QString::number(m_changeNumber);
|
args << QString::number(m_changeNumber);
|
||||||
const SubversionResponse logResponse =
|
runCommand(QList<QStringList>() << args, VcsCommand::SshPasswordPrompt);
|
||||||
SubversionPlugin::instance()->runSvn(m_workingDirectory, args,
|
|
||||||
m_client->vcsTimeoutS(),
|
|
||||||
VcsCommand::SshPasswordPrompt);
|
|
||||||
|
|
||||||
if (logResponse.error)
|
|
||||||
return QString();
|
|
||||||
|
|
||||||
return logResponse.stdOut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffController::postCollectTextualDiffOutput()
|
void SubversionDiffEditorController::requestDiff()
|
||||||
{
|
{
|
||||||
auto command = new VcsCommand(m_workingDirectory, processEnvironment());
|
m_state = GettingDiff;
|
||||||
command->setCodec(EditorManager::defaultTextCodec());
|
|
||||||
connect(command, &VcsCommand::stdOutText, this, &DiffController::slotTextualDiffOutputReceived);
|
|
||||||
// command->addFlags(diffExecutionFlags());
|
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
args << QLatin1String("diff");
|
args << QLatin1String("diff");
|
||||||
args << m_client->addAuthenticationOptions(m_client->settings());
|
args << SubversionClient::addAuthenticationOptions(client()->settings());
|
||||||
args << QLatin1String("--internal-diff");
|
args << QLatin1String("--internal-diff");
|
||||||
if (ignoreWhitespace())
|
if (ignoreWhitespace())
|
||||||
args << QLatin1String("-x") << QLatin1String("-uw");
|
args << QLatin1String("-x") << QLatin1String("-uw");
|
||||||
@@ -258,40 +244,43 @@ void DiffController::postCollectTextualDiffOutput()
|
|||||||
} else {
|
} else {
|
||||||
args << m_filesList;
|
args << m_filesList;
|
||||||
}
|
}
|
||||||
|
runCommand(QList<QStringList>() << args, 0);
|
||||||
command->addJob(m_client->vcsBinary(), args, m_client->vcsTimeoutS());
|
|
||||||
command->execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffController::slotTextualDiffOutputReceived(const QString &contents)
|
void SubversionDiffEditorController::reload()
|
||||||
{
|
{
|
||||||
bool ok;
|
if (m_changeNumber) {
|
||||||
QList<FileData> fileDataList
|
requestDescription();
|
||||||
= DiffUtils::readPatch(contents, &ok);
|
} else {
|
||||||
setDiffFiles(fileDataList, m_workingDirectory);
|
requestDiff();
|
||||||
|
}
|
||||||
reloadFinished(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffController::reload()
|
void SubversionDiffEditorController::processCommandOutput(const QString &output)
|
||||||
{
|
{
|
||||||
const QString description = m_changeNumber
|
QTC_ASSERT(m_state != Idle, return);
|
||||||
? getDescription() : QString();
|
if (m_state == GettingDescription) {
|
||||||
postCollectTextualDiffOutput();
|
setDescription(output);
|
||||||
setDescription(description);
|
|
||||||
|
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 &source,
|
||||||
const QString &title,
|
const QString &title,
|
||||||
const QString &workingDirectory) const
|
const QString &workingDirectory) const
|
||||||
{
|
{
|
||||||
IDocument *document = DiffEditorController::findOrCreateDocument(documentId, title);
|
IDocument *document = DiffEditorController::findOrCreateDocument(documentId, title);
|
||||||
DiffController *controller = qobject_cast<DiffController *>(
|
SubversionDiffEditorController *controller = qobject_cast<SubversionDiffEditorController *>(
|
||||||
DiffEditorController::controller(document));
|
DiffEditorController::controller(document));
|
||||||
if (!controller)
|
if (!controller)
|
||||||
controller = new DiffController(document, this, workingDirectory);
|
controller = new SubversionDiffEditorController(document, workingDirectory);
|
||||||
VcsBasePlugin::setSource(document, source);
|
VcsBasePlugin::setSource(document, source);
|
||||||
|
EditorManager::activateEditorForDocument(document);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +293,7 @@ void SubversionClient::diff(const QString &workingDirectory, const QStringList &
|
|||||||
+ QLatin1String(".Diff.") + VcsBaseEditor::getTitleId(workingDirectory, files);
|
+ QLatin1String(".Diff.") + VcsBaseEditor::getTitleId(workingDirectory, files);
|
||||||
const QString title = vcsEditorTitle(vcsCmdString, documentId);
|
const QString title = vcsEditorTitle(vcsCmdString, documentId);
|
||||||
|
|
||||||
DiffController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title,
|
SubversionDiffEditorController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title,
|
||||||
workingDirectory);
|
workingDirectory);
|
||||||
controller->setFilesList(files);
|
controller->setFilesList(files);
|
||||||
controller->requestReload();
|
controller->requestReload();
|
||||||
@@ -335,7 +324,7 @@ void SubversionClient::describe(const QString &workingDirectory, int changeNumbe
|
|||||||
QStringList(),
|
QStringList(),
|
||||||
QString::number(changeNumber));
|
QString::number(changeNumber));
|
||||||
|
|
||||||
DiffController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, workingDirectory);
|
SubversionDiffEditorController *controller = findOrCreateDiffEditor(documentId, workingDirectory, title, workingDirectory);
|
||||||
controller->setChangeNumber(changeNumber);
|
controller->setChangeNumber(changeNumber);
|
||||||
controller->requestReload();
|
controller->requestReload();
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@ namespace Subversion {
|
|||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class SubversionSettings;
|
class SubversionSettings;
|
||||||
class DiffController;
|
class SubversionDiffEditorController;
|
||||||
|
|
||||||
class SubversionClient : public VcsBase::VcsBaseClient
|
class SubversionClient : public VcsBase::VcsBaseClient
|
||||||
{
|
{
|
||||||
@@ -78,7 +78,7 @@ protected:
|
|||||||
Core::Id vcsEditorKind(VcsCommandTag cmd) const override;
|
Core::Id vcsEditorKind(VcsCommandTag cmd) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DiffController *findOrCreateDiffEditor(const QString &documentId, const QString &source,
|
SubversionDiffEditorController *findOrCreateDiffEditor(const QString &documentId, const QString &source,
|
||||||
const QString &title, const QString &workingDirectory) const;
|
const QString &title, const QString &workingDirectory) const;
|
||||||
|
|
||||||
mutable Utils::FileName m_svnVersionBinary;
|
mutable Utils::FileName m_svnVersionBinary;
|
||||||
|
@@ -27,7 +27,8 @@ HEADERS += vcsbase_global.h \
|
|||||||
vcsbaseclientsettings.h \
|
vcsbaseclientsettings.h \
|
||||||
vcsbaseeditorconfig.h \
|
vcsbaseeditorconfig.h \
|
||||||
submitfieldwidget.h \
|
submitfieldwidget.h \
|
||||||
submiteditorwidget.h
|
submiteditorwidget.h \
|
||||||
|
vcsbasediffeditorcontroller.h
|
||||||
|
|
||||||
SOURCES += vcsplugin.cpp \
|
SOURCES += vcsplugin.cpp \
|
||||||
vcsbaseplugin.cpp \
|
vcsbaseplugin.cpp \
|
||||||
@@ -54,7 +55,8 @@ SOURCES += vcsplugin.cpp \
|
|||||||
vcsbaseclientsettings.cpp \
|
vcsbaseclientsettings.cpp \
|
||||||
vcsbaseeditorconfig.cpp \
|
vcsbaseeditorconfig.cpp \
|
||||||
submitfieldwidget.cpp \
|
submitfieldwidget.cpp \
|
||||||
submiteditorwidget.cpp
|
submiteditorwidget.cpp \
|
||||||
|
vcsbasediffeditorcontroller.cpp
|
||||||
|
|
||||||
RESOURCES += vcsbase.qrc
|
RESOURCES += vcsbase.qrc
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ QtcPlugin {
|
|||||||
Depends { name: "TextEditor" }
|
Depends { name: "TextEditor" }
|
||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
Depends { name: "CppTools" }
|
Depends { name: "CppTools" }
|
||||||
|
Depends { name: "DiffEditor" }
|
||||||
|
|
||||||
pluginRecommends: [
|
pluginRecommends: [
|
||||||
"CodePaster"
|
"CodePaster"
|
||||||
@@ -53,6 +54,8 @@ QtcPlugin {
|
|||||||
"vcsbaseclientsettings.cpp",
|
"vcsbaseclientsettings.cpp",
|
||||||
"vcsbaseclientsettings.h",
|
"vcsbaseclientsettings.h",
|
||||||
"vcsbaseconstants.h",
|
"vcsbaseconstants.h",
|
||||||
|
"vcsbasediffeditorcontroller.cpp",
|
||||||
|
"vcsbasediffeditorcontroller.h",
|
||||||
"vcsbaseeditor.cpp",
|
"vcsbaseeditor.cpp",
|
||||||
"vcsbaseeditor.h",
|
"vcsbaseeditor.h",
|
||||||
"vcsbaseeditorconfig.cpp",
|
"vcsbaseeditorconfig.cpp",
|
||||||
|
@@ -8,6 +8,7 @@ QTC_PLUGIN_DEPENDS += \
|
|||||||
coreplugin \
|
coreplugin \
|
||||||
texteditor \
|
texteditor \
|
||||||
projectexplorer \
|
projectexplorer \
|
||||||
cpptools
|
cpptools \
|
||||||
|
diffeditor
|
||||||
QTC_PLUGIN_RECOMMENDS += \
|
QTC_PLUGIN_RECOMMENDS += \
|
||||||
cpaster
|
cpaster
|
||||||
|
195
src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
Normal file
195
src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
Normal file
@@ -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 <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
#include <diffeditor/diffutils.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/runextensions.h>
|
||||||
|
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
using namespace DiffEditor;
|
||||||
|
using namespace Core;
|
||||||
|
|
||||||
|
namespace VcsBase {
|
||||||
|
|
||||||
|
static void readPatch(QFutureInterface<QList<FileData>> &futureInterface,
|
||||||
|
const QString &patch)
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
const QList<FileData> &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<VcsCommand> m_command;
|
||||||
|
QFutureWatcher<QList<FileData>> m_processWatcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
VcsBaseDiffEditorControllerPrivate::VcsBaseDiffEditorControllerPrivate(VcsBaseDiffEditorController *controller,
|
||||||
|
VcsBaseClientImpl *client,
|
||||||
|
const QString &workingDirectory)
|
||||||
|
: q(controller)
|
||||||
|
, m_client(client)
|
||||||
|
, m_directory(workingDirectory)
|
||||||
|
{
|
||||||
|
QObject::connect(&m_processWatcher, &QFutureWatcher<QList<FileData>>::finished, q,
|
||||||
|
[this] () { processingFinished(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
|
||||||
|
{
|
||||||
|
cancelReload();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VcsBaseDiffEditorControllerPrivate::processingFinished()
|
||||||
|
{
|
||||||
|
const QList<FileData> 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<QList<FileData>>());
|
||||||
|
}
|
||||||
|
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<QStringList> &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
|
62
src/plugins/vcsbase/vcsbasediffeditorcontroller.h
Normal file
62
src/plugins/vcsbase/vcsbasediffeditorcontroller.h
Normal file
@@ -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 <diffeditor/diffeditorcontroller.h>
|
||||||
|
|
||||||
|
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<QStringList> &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
|
Reference in New Issue
Block a user