summaryrefslogtreecommitdiff
path: root/src/libs/utils/archive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils/archive.cpp')
-rw-r--r--src/libs/utils/archive.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/libs/utils/archive.cpp b/src/libs/utils/archive.cpp
new file mode 100644
index 0000000000..daab53451f
--- /dev/null
+++ b/src/libs/utils/archive.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "archive.h"
+
+#include "algorithm.h"
+#include "checkablemessagebox.h"
+#include "environment.h"
+#include "mimetypes/mimedatabase.h"
+#include "qtcassert.h"
+#include "synchronousprocess.h"
+
+#include <QDir>
+#include <QPushButton>
+
+namespace {
+
+struct Tool
+{
+ Utils::FilePath executable;
+ QStringList arguments;
+};
+
+Utils::optional<Tool> unzipTool(const Utils::FilePath &src, const Utils::FilePath &dest)
+{
+ const Utils::FilePath unzip = Utils::Environment::systemEnvironment().searchInPath(
+ Utils::HostOsInfo::withExecutableSuffix("unzip"));
+ if (!unzip.isEmpty())
+ return Tool{unzip, {"-o", src.toString(), "-d", dest.toString()}};
+
+ const Utils::FilePath sevenzip = Utils::Environment::systemEnvironment().searchInPath(
+ Utils::HostOsInfo::withExecutableSuffix("7z"));
+ if (!sevenzip.isEmpty())
+ return Tool{sevenzip, {"x", QString("-o") + dest.toString(), "-y", src.toString()}};
+
+ const Utils::FilePath cmake = Utils::Environment::systemEnvironment().searchInPath(
+ Utils::HostOsInfo::withExecutableSuffix("cmake"));
+ if (!cmake.isEmpty())
+ return Tool{cmake, {"-E", "tar", "xvf", src.toString()}};
+
+ return {};
+}
+
+} // namespace
+
+namespace Utils {
+
+bool Archive::supportsFile(const FilePath &filePath, QString *reason)
+{
+ const QList<MimeType> mimeType = mimeTypesForFileName(filePath.toString());
+ if (!anyOf(mimeType, [](const MimeType &mt) { return mt.inherits("application/zip"); })) {
+ if (reason)
+ *reason = tr("File format not supported.");
+ return false;
+ }
+ if (!unzipTool({}, {})) {
+ if (reason)
+ *reason = tr("Could not find unzip, 7z, or cmake executable in PATH.");
+ return false;
+ }
+ return true;
+}
+
+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(".");
+ CheckableMessageBox box(parent);
+ box.setIcon(QMessageBox::Information);
+ box.setWindowTitle(tr("Unzipping File"));
+ box.setText(tr("Unzipping \"%1\" to \"%2\".").arg(src.toUserOutput(), dest.toUserOutput()));
+ 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(&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);
+ });
+ process.setProgram(tool->executable.toString());
+ process.setArguments(tool->arguments);
+ process.setWorkingDirectory(workingDirectory);
+ process.start(QProcess::ReadOnly);
+ box.exec();
+ return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
+}
+
+} // namespace Utils