summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2020-06-08 09:35:25 +0200
committerEike Ziller <eike.ziller@qt.io>2020-06-15 07:45:10 +0000
commit18ee72ac3f73f76b8c94b428ec4b72cb29d03f1c (patch)
treec75e59a782c2514aa07c4a5950476941b73aa2ef
parent7cedde2a0ae4776dfba4ea3643a2ef8e76e54dfc (diff)
downloadqt-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.cpp100
-rw-r--r--src/libs/utils/archive.h19
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