ShellCommand: Show some progress information without progress parser

Show magically timed progress when running a shell command without a
progress parser. The assumption is that the timeout is much larger than
the expected runtime, but still an indicator for how long it might take.
Progress manager does its magic on top of that.

This is e.g. used for the update info plugin, for which checking for
updates might take quite some while.

Change-Id: Ib3d3d37b86fac17816fe592e39e26a3d484bba26
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Eike Ziller
2017-09-07 11:17:27 +02:00
parent 4342eeab33
commit c4b5048836
3 changed files with 37 additions and 1 deletions

View File

@@ -42,6 +42,8 @@
#include <QThread>
#include <QVariant>
#include <numeric>
/*!
\fn void Utils::ProgressParser::parseProgress(const QString &text)
@@ -241,6 +243,14 @@ void ShellCommand::addTask(QFuture<void> &future)
Q_UNUSED(future);
}
int ShellCommand::timeoutS() const
{
return std::accumulate(d->m_jobs.cbegin(), d->m_jobs.cend(), 0,
[](int sum, const Internal::ShellCommandPrivate::Job &job) {
return sum + job.timeoutS;
});
}
QString ShellCommand::workDirectory(const QString &wd) const
{
if (!wd.isEmpty())
@@ -474,6 +484,11 @@ void ShellCommand::setProgressParser(ProgressParser *parser)
d->m_progressParser = parser;
}
bool ShellCommand::hasProgressParser() const
{
return d->m_progressParser;
}
void ShellCommand::setProgressiveOutput(bool progressive)
{
d->m_progressiveOutput = progressive;

View File

@@ -136,6 +136,7 @@ public:
void setCodec(QTextCodec *codec);
void setProgressParser(ProgressParser *parser);
bool hasProgressParser() const;
void setProgressiveOutput(bool progressive);
void setOutputProxyFactory(const std::function<OutputProxy *()> &factory);
@@ -161,6 +162,7 @@ signals:
protected:
virtual unsigned processFlags() const;
virtual void addTask(QFuture<void> &future);
int timeoutS() const;
QString workDirectory(const QString &wd) const;
private:

View File

@@ -28,6 +28,9 @@
#include "icore.h"
#include "progressmanager/progressmanager.h"
#include <QFutureInterface>
#include <QFutureWatcher>
namespace Core {
ShellCommand::ShellCommand(const QString &workingDirectory, const QProcessEnvironment &environment) :
@@ -40,7 +43,23 @@ ShellCommand::ShellCommand(const QString &workingDirectory, const QProcessEnviro
void ShellCommand::addTask(QFuture<void> &future)
{
const QString name = displayName();
Core::ProgressManager::addTask(future, name, Core::Id::fromString(name + QLatin1String(".action")));
const auto id = Core::Id::fromString(name + QLatin1String(".action"));
if (hasProgressParser()) {
ProgressManager::addTask(future, name, id);
} else {
// add a timed tasked based on timeout
// we cannot access the future interface directly, so we need to create a new one
// with the same lifetime
auto fi = new QFutureInterface<void>();
auto watcher = new QFutureWatcher<void>();
connect(watcher, &QFutureWatcherBase::finished, [fi, watcher] {
fi->reportFinished();
delete fi;
watcher->deleteLater();
});
watcher->setFuture(future);
ProgressManager::addTimedTask(*fi, name, id, qMax(2, timeoutS() / 5)/*itsmagic*/);
}
}
void ShellCommand::coreAboutToClose()