summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOrgad Shaneh <orgad.shaneh@audiocodes.com>2013-08-26 23:14:44 +0300
committerOrgad Shaneh <orgads@gmail.com>2013-08-30 12:19:25 +0200
commitfc6ff05472b1196edbd8c7744e9386d7770e6e70 (patch)
treeba4d1e367cce2cdc0dae95e297b78b77d53964d7 /src
parent6c582e0180b7c1bce243e4ac88bcdc7983bdb4ec (diff)
downloadqt-creator-fc6ff05472b1196edbd8c7744e9386d7770e6e70.tar.gz
VCS: Update progress bar for commands that output progress
Change-Id: I643df94c72068259817092d7d48f71984288fdb5 Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/git/gitclient.cpp22
-rw-r--r--src/plugins/vcsbase/command.cpp76
-rw-r--r--src/plugins/vcsbase/command.h23
3 files changed, 118 insertions, 3 deletions
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index eb9d562005..c9ce5894ea 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -829,6 +829,26 @@ private:
QStringList m_files;
};
+class ProgressParser : public VcsBase::ProgressParser
+{
+public:
+ ProgressParser() :
+ m_progressExp(QLatin1String("\\((\\d+)/(\\d+)\\)")) // e.g. Rebasing (7/42)
+ {
+ }
+
+protected:
+ void parseProgress(const QString &text)
+ {
+ if (m_progressExp.lastIndexIn(text) != -1)
+ setProgressAndMaximum(m_progressExp.cap(1).toInt(), m_progressExp.cap(2).toInt());
+ }
+
+private:
+ QRegExp m_progressExp;
+};
+
+
Core::IEditor *locateEditor(const char *property, const QString &entry)
{
@@ -3487,6 +3507,7 @@ void GitClient::rebase(const QString &workingDirectory, const QString &baseBranc
arguments);
VcsBase::Command *command = createCommand(workingDirectory, 0, true);
new ConflictHandler(command, workingDirectory, gitCommand);
+ command->setProgressParser(new ProgressParser);
command->addJob(arguments, -1);
command->execute();
}
@@ -3532,6 +3553,7 @@ void GitClient::interactiveRebase(const QString &workingDirectory, const QString
m_disableEditor = true;
VcsBase::Command *command = createCommand(workingDirectory, 0, true);
new ConflictHandler(command, workingDirectory, QLatin1String("rebase"));
+ command->setProgressParser(new ProgressParser);
command->addJob(arguments, -1);
command->execute();
command->setCookie(workingDirectory);
diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp
index 2170117448..57d36c3575 100644
--- a/src/plugins/vcsbase/command.cpp
+++ b/src/plugins/vcsbase/command.cpp
@@ -37,6 +37,7 @@
#include <vcsbase/vcsbaseoutputwindow.h>
#include <utils/synchronousprocess.h>
#include <utils/runextensions.h>
+#include <utils/qtcassert.h>
#include <QDebug>
#include <QProcess>
@@ -48,11 +49,29 @@
#include <QVariant>
#include <QStringList>
#include <QTextCodec>
+#include <QMutex>
Q_DECLARE_METATYPE(QVariant)
enum { debugExecution = 0 };
+/*!
+ \fn void VcsBase::ProgressParser::parseProgress(const QString &text)
+
+ Reimplement to parse progress as it appears in the standard output.
+ If a progress string is detected, call \c setProgressAndMaximum() to update
+ the progress bar accordingly.
+
+ \sa VcsBase::ProgressParser::setProgressAndMaximum()
+*/
+
+/*!
+ \fn void VcsBase::ProgressParser::setProgressAndMaximum(int value, int maximum)
+
+ Sets progress \a value and \a maximum for current command. Called by \c parseProgress()
+ when a progress string is detected.
+*/
+
namespace VcsBase {
namespace Internal {
@@ -69,6 +88,7 @@ public:
CommandPrivate(const QString &binary,
const QString &workingDirectory,
const QProcessEnvironment &environment);
+ ~CommandPrivate();
const QString m_binaryPath;
const QString m_workingDirectory;
@@ -78,6 +98,7 @@ public:
unsigned m_flags;
QTextCodec *m_codec;
const QString m_sshPasswordPrompt;
+ ProgressParser *m_progressParser;
QList<Job> m_jobs;
@@ -95,11 +116,17 @@ CommandPrivate::CommandPrivate(const QString &binary,
m_flags(0),
m_codec(0),
m_sshPasswordPrompt(VcsBasePlugin::sshPrompt()),
+ m_progressParser(0),
m_lastExecSuccess(false),
m_lastExecExitCode(-1)
{
}
+CommandPrivate::~CommandPrivate()
+{
+ delete m_progressParser;
+}
+
CommandPrivate::Job::Job(const QStringList &a, int t) :
arguments(a),
timeout(t)
@@ -207,6 +234,8 @@ void Command::run(QFutureInterface<void> &future)
QString stdOut;
QString stdErr;
+ if (d->m_progressParser)
+ d->m_progressParser->setFuture(&future);
const int count = d->m_jobs.size();
d->m_lastExecExitCode = -1;
d->m_lastExecSuccess = true;
@@ -233,6 +262,8 @@ void Command::run(QFutureInterface<void> &future)
emit success(cookie());
}
+ if (d->m_progressParser)
+ d->m_progressParser->setFuture(0);
// As it is used asynchronously, we need to delete ourselves
this->deleteLater();
}
@@ -342,10 +373,10 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments,
}
// connect stdout to the output window if desired
- if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow) {
- process.setStdOutBufferedSignalsEnabled(true);
+ process.setStdOutBufferedSignalsEnabled(true);
+ connect(&process, SIGNAL(stdOutBuffered(QString,bool)), this, SLOT(bufferedOutput(QString)));
+ if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow)
connect(&process, SIGNAL(stdOutBuffered(QString,bool)), outputWindow, SLOT(append(QString)));
- }
process.setTimeOutMessageBoxEnabled(true);
@@ -479,6 +510,12 @@ bool Command::runFullySynchronous(const QStringList &arguments, int timeoutMS,
return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
}
+void Command::bufferedOutput(const QString &text)
+{
+ if (d->m_progressParser)
+ d->m_progressParser->parseProgress(text);
+}
+
const QVariant &Command::cookie() const
{
return d->m_cookie;
@@ -499,6 +536,39 @@ void Command::setCodec(QTextCodec *codec)
d->m_codec = codec;
}
+//! Use \a parser to parse progress data from stdout. Command takes ownership of \a parser
+void Command::setProgressParser(ProgressParser *parser)
+{
+ QTC_ASSERT(!d->m_progressParser, return);
+ d->m_progressParser = parser;
+}
+
+ProgressParser::ProgressParser() :
+ m_future(0),
+ m_futureMutex(new QMutex)
+{
+}
+
+ProgressParser::~ProgressParser()
+{
+ delete m_futureMutex;
+}
+
+void ProgressParser::setProgressAndMaximum(int value, int maximum)
+{
+ QMutexLocker lock(m_futureMutex);
+ if (!m_future)
+ return;
+ m_future->setProgressRange(0, maximum);
+ m_future->setProgressValue(value);
+}
+
+void ProgressParser::setFuture(QFutureInterface<void> *future)
+{
+ QMutexLocker lock(m_futureMutex);
+ m_future = future;
+}
+
} // namespace VcsBase
#include "command.moc"
diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h
index 84b4d7c398..7931cc974e 100644
--- a/src/plugins/vcsbase/command.h
+++ b/src/plugins/vcsbase/command.h
@@ -37,6 +37,7 @@
#include <QObject>
QT_BEGIN_NAMESPACE
+class QMutex;
class QStringList;
class QVariant;
class QProcessEnvironment;
@@ -48,6 +49,24 @@ namespace VcsBase {
namespace Internal { class CommandPrivate; }
+class VCSBASE_EXPORT ProgressParser
+{
+public:
+ ProgressParser();
+ virtual ~ProgressParser();
+
+protected:
+ virtual void parseProgress(const QString &text) = 0;
+ void setProgressAndMaximum(int value, int maximum);
+
+private:
+ void setFuture(QFutureInterface<void> *future);
+
+ QFutureInterface<void> *m_future;
+ QMutex *m_futureMutex;
+ friend class Command;
+};
+
class VCSBASE_EXPORT Command : public QObject
{
Q_OBJECT
@@ -80,6 +99,7 @@ public:
QTextCodec *codec() const;
void setCodec(QTextCodec *codec);
+ void setProgressParser(ProgressParser *parser);
Utils::SynchronousProcessResponse runVcs(const QStringList &arguments, int timeoutMS);
// Make sure to not pass through the event loop at all:
@@ -90,6 +110,9 @@ private:
void run(QFutureInterface<void> &future);
Utils::SynchronousProcessResponse runSynchronous(const QStringList &arguments, int timeoutMS);
+private slots:
+ void bufferedOutput(const QString &text);
+
signals:
void output(const QString &);
void errorText(const QString &);