diff options
| author | Eike Ziller <eike.ziller@qt.io> | 2020-06-08 09:35:25 +0200 |
|---|---|---|
| committer | Eike Ziller <eike.ziller@qt.io> | 2020-06-15 07:45:10 +0000 |
| commit | 18ee72ac3f73f76b8c94b428ec4b72cb29d03f1c (patch) | |
| tree | c75e59a782c2514aa07c4a5950476941b73aa2ef | |
| parent | 7cedde2a0ae4776dfba4ea3643a2ef8e76e54dfc (diff) | |
| download | qt-creator-18ee72ac3f73f76b8c94b428ec4b72cb29d03f1c.tar.gz | |
Utils/Archive: Add simple async API
So we can integrate it deeper into the plugin wizard.
Change-Id: I7f7a9eb8e07d3eeab6a4ecf92161f7d04f5fa5c2
Reviewed-by: David Schulz <david.schulz@qt.io>
| -rw-r--r-- | src/libs/utils/archive.cpp | 100 | ||||
| -rw-r--r-- | src/libs/utils/archive.h | 19 |
2 files changed, 93 insertions, 26 deletions
diff --git a/src/libs/utils/archive.cpp b/src/libs/utils/archive.cpp index 74c24c7f86..11b9570ef9 100644 --- a/src/libs/utils/archive.cpp +++ b/src/libs/utils/archive.cpp @@ -128,10 +128,9 @@ bool Archive::supportsFile(const FilePath &filePath, QString *reason) bool Archive::unarchive(const FilePath &src, const FilePath &dest, QWidget *parent) { - const Utils::optional<Tool> tool = unzipTool(src, dest); - QTC_ASSERT(tool, return false); - const QString workingDirectory = dest.toFileInfo().absoluteFilePath(); - QDir(workingDirectory).mkpath("."); + Archive *archive = unarchive(src, dest); + QTC_ASSERT(archive, return false); + CheckableMessageBox box(parent); box.setIcon(QMessageBox::Information); box.setWindowTitle(tr("Unarchiving File")); @@ -139,29 +138,82 @@ bool Archive::unarchive(const FilePath &src, const FilePath &dest, QWidget *pare box.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); box.button(QDialogButtonBox::Ok)->setEnabled(false); box.setCheckBoxVisible(false); - box.setDetailedText( - tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>") - .arg(CommandLine(tool->executable, tool->arguments).toUserOutput(), workingDirectory)); - QProcess process; - process.setProcessChannelMode(QProcess::MergedChannels); - QObject::connect(&process, &QProcess::readyReadStandardOutput, &box, [&box, &process]() { - box.setDetailedText(box.detailedText() + QString::fromUtf8(process.readAllStandardOutput())); + QObject::connect(archive, &Archive::outputReceived, &box, [&box](const QString &output) { + box.setDetailedText(box.detailedText() + output); }); - QObject::connect(&process, - QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), - [&box](int, QProcess::ExitStatus) { - box.button(QDialogButtonBox::Ok)->setEnabled(true); - box.button(QDialogButtonBox::Cancel)->setEnabled(false); - }); - QObject::connect(&box, &QMessageBox::rejected, &process, [&process] { - SynchronousProcess::stopProcess(process); + bool success = false; + QObject::connect(archive, &Archive::finished, [&box, &success](bool ret) { + box.button(QDialogButtonBox::Ok)->setEnabled(true); + box.button(QDialogButtonBox::Cancel)->setEnabled(false); + success = ret; }); - process.setProgram(tool->executable); - process.setArguments(tool->arguments); - process.setWorkingDirectory(workingDirectory); - process.start(QProcess::ReadOnly); + QObject::connect(&box, &QMessageBox::rejected, archive, &Archive::cancel); box.exec(); - return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0; + return success; +} + +Archive *Archive::unarchive(const FilePath &src, const FilePath &dest) +{ + const Utils::optional<Tool> tool = unzipTool(src, dest); + QTC_ASSERT(tool, return nullptr); + + auto archive = new Archive; + + const QString workingDirectory = dest.toFileInfo().absoluteFilePath(); + QDir(workingDirectory).mkpath("."); + + archive->m_process = new QProcess; + archive->m_process->setProcessChannelMode(QProcess::MergedChannels); + QObject::connect( + archive->m_process, + &QProcess::readyReadStandardOutput, + archive, + [archive]() { + archive->outputReceived(QString::fromUtf8(archive->m_process->readAllStandardOutput())); + }, + Qt::QueuedConnection); + QObject::connect( + archive->m_process, + QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), + archive, + [archive](int, QProcess::ExitStatus) { + archive->finished(archive->m_process->exitStatus() == QProcess::NormalExit + && archive->m_process->exitCode() == 0); + archive->m_process->deleteLater(); + archive->m_process = nullptr; + archive->deleteLater(); + }, + Qt::QueuedConnection); + QObject::connect( + archive->m_process, + &QProcess::errorOccurred, + archive, + [archive](QProcess::ProcessError) { + archive->outputReceived(tr("Command failed.")); + archive->finished(false); + archive->m_process->deleteLater(); + archive->m_process = nullptr; + archive->deleteLater(); + }, + Qt::QueuedConnection); + QTimer::singleShot(0, archive, [archive, tool, workingDirectory] { + archive->outputReceived( + tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>") + .arg(CommandLine(tool->executable, tool->arguments).toUserOutput(), + workingDirectory)); + }); + archive->m_process->setProgram(tool->executable); + archive->m_process->setArguments(tool->arguments); + archive->m_process->setWorkingDirectory(workingDirectory); + archive->m_process->start(QProcess::ReadOnly); + return archive; +} + +void Archive::cancel() +{ + if (!m_process) + return; + SynchronousProcess::stopProcess(*m_process); } } // namespace Utils diff --git a/src/libs/utils/archive.h b/src/libs/utils/archive.h index 1447b9898a..324a473ba3 100644 --- a/src/libs/utils/archive.h +++ b/src/libs/utils/archive.h @@ -29,14 +29,29 @@ #include "fileutils.h" +#include <QObject> +#include <QProcess> + namespace Utils { -class QTCREATOR_UTILS_EXPORT Archive +class QTCREATOR_UTILS_EXPORT Archive : public QObject { - Q_DECLARE_TR_FUNCTIONS(Utils::Archive) + Q_OBJECT public: static bool supportsFile(const FilePath &filePath, QString *reason = nullptr); static bool unarchive(const FilePath &src, const FilePath &dest, QWidget *parent); + static Archive *unarchive(const FilePath &src, const FilePath &dest); + + void cancel(); + +signals: + void outputReceived(const QString &output); + void finished(bool success); + +private: + Archive() = default; + + QProcess *m_process = nullptr; }; } // namespace Utils |
