diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index 59c7f97fd0d..6ea2099211e 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -42,6 +42,8 @@ #include #include +#include + /*! \fn void Utils::ProgressParser::parseProgress(const QString &text) @@ -241,6 +243,14 @@ void ShellCommand::addTask(QFuture &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; diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h index ce5957c40af..c8bf38af111 100644 --- a/src/libs/utils/shellcommand.h +++ b/src/libs/utils/shellcommand.h @@ -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 &factory); @@ -161,6 +162,7 @@ signals: protected: virtual unsigned processFlags() const; virtual void addTask(QFuture &future); + int timeoutS() const; QString workDirectory(const QString &wd) const; private: diff --git a/src/plugins/coreplugin/shellcommand.cpp b/src/plugins/coreplugin/shellcommand.cpp index 4f6a028e51c..a236c906e4d 100644 --- a/src/plugins/coreplugin/shellcommand.cpp +++ b/src/plugins/coreplugin/shellcommand.cpp @@ -28,6 +28,9 @@ #include "icore.h" #include "progressmanager/progressmanager.h" +#include +#include + 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 &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(); + auto watcher = new QFutureWatcher(); + 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()