summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/installationmanager.cpp157
-rw-r--r--src/installationmanager.h8
2 files changed, 91 insertions, 74 deletions
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index 9d64a6f3..f57872fe 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -132,82 +132,99 @@ void InstallationManager::queryPassword() {
tr("Password"), QLineEdit::Password);
}
-bool InstallationManager::extractFiles(QString extractPath, QString title, bool showFilenames)
+bool InstallationManager::extractFiles(QString extractPath, QString title, bool showFilenames, bool silent)
{
- QProgressDialog *installationProgress = new QProgressDialog(m_ParentWidget);
- ON_BLOCK_EXIT([=]() {
- installationProgress->cancel();
- installationProgress->hide();
- installationProgress->deleteLater();
- });
- installationProgress->setWindowFlags(
- installationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
- if (!title.isEmpty()) {
- installationProgress->setWindowTitle(title);
- }
- installationProgress->setWindowModality(Qt::WindowModal);
- installationProgress->setFixedSize(600, 100);
-
- // Turn off auto-reset otherwize the progress dialog is reset before the end. This
- // is kind of annoying because updateProgress consider percentage of progression
- // through the archive (pack), while we are waiting for extracting archive entries, so
- // the percentage of in updateProgress is not really related to the percentage of files
- // extracted...
- installationProgress->setAutoReset(false);
-
- // Connect signals emitted by the extraction callback to the progress dialog slots:
- connect(this, &InstallationManager::progressUpdate, installationProgress, &QProgressDialog::setValue);
- connect(this, &InstallationManager::progressFileChange, installationProgress, &QProgressDialog::setLabelText);
+ TimeThis tt("InstallationManager::extractFiles");
- // Cancelling progress only cancel the extraction, we do not force exiting the event-loop:
- connect(installationProgress, &QProgressDialog::canceled, [this]() { m_ArchiveHandler->cancel(); });
-
- installationProgress->show();
-
- // Variable updated by the callbacks:
+ // Callback for errors:
QString errorMessage;
-
- // The callbacks:
- auto progressCallback = [this](auto progressType, uint64_t current, uint64_t total) {
- if (progressType == Archive::ProgressType::EXTRACTION) {
- int progress = static_cast<int>(100 * current / total);
- emit progressUpdate(progress);
- }
- };
- Archive::FileChangeCallback fileChangeCallback = [this](auto changeType, std::wstring const& file) {
- if (changeType == Archive::FileChangeType::EXTRACTION_START) {
- emit progressFileChange(QString::fromStdWString(file));
- }
- };
auto errorCallback = [&errorMessage, this](std::wstring const& message) {
m_ArchiveHandler->cancel();
errorMessage = QString::fromStdWString(message);
};
- auto start = std::chrono::system_clock::now();
+ // The future that will hold the result:
+ QFuture<bool> future;
+
+ if (silent) {
+ future = QtConcurrent::run([&]() -> bool {
+ return m_ArchiveHandler->extract(
+ extractPath.toStdWString(),
+ nullptr,
+ nullptr,
+ errorCallback
+ );
+ });
+ future.waitForFinished();
+ }
+ else {
+ QProgressDialog* installationProgress = new QProgressDialog(m_ParentWidget);
+ ON_BLOCK_EXIT([=]() {
+ installationProgress->cancel();
+ installationProgress->hide();
+ installationProgress->deleteLater();
+ });
+ installationProgress->setWindowFlags(
+ installationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint));
+ if (!title.isEmpty()) {
+ installationProgress->setWindowTitle(title);
+ }
+ installationProgress->setWindowModality(Qt::WindowModal);
+ installationProgress->setFixedSize(600, 100);
+
+ // Turn off auto-reset otherwize the progress dialog is reset before the end. This
+ // is kind of annoying because updateProgress consider percentage of progression
+ // through the archive (pack), while we are waiting for extracting archive entries, so
+ // the percentage of in updateProgress is not really related to the percentage of files
+ // extracted...
+ installationProgress->setAutoReset(false);
- // Future watcher to exit the loop:
- QFutureWatcher<bool> futureWatcher;
+ // Connect signals emitted by the extraction callback to the progress dialog slots:
+ connect(this, &InstallationManager::progressUpdate, installationProgress, &QProgressDialog::setValue);
+ connect(this, &InstallationManager::progressFileChange, installationProgress, &QProgressDialog::setLabelText);
- QEventLoop loop(this);
- connect(
- &futureWatcher, &QFutureWatcher<bool>::finished,
- &loop, &QEventLoop::quit,
- Qt::QueuedConnection);
+ // Cancelling progress only cancel the extraction, we do not force exiting the event-loop:
+ connect(installationProgress, &QProgressDialog::canceled, [this]() { m_ArchiveHandler->cancel(); });
- // unpack only the files we need for the installer
- futureWatcher.setFuture(QtConcurrent::run([&]() -> bool {
- return m_ArchiveHandler->extract(
- extractPath.toStdWString(),
- progressCallback,
- showFilenames ? fileChangeCallback : nullptr,
- errorCallback
- );
- }));
+ installationProgress->show();
+
+ // The callbacks:
+ auto progressCallback = [this](auto progressType, uint64_t current, uint64_t total) {
+ if (progressType == Archive::ProgressType::EXTRACTION) {
+ int progress = static_cast<int>(100 * current / total);
+ emit progressUpdate(progress);
+ }
+ };
+ Archive::FileChangeCallback fileChangeCallback = [this](auto changeType, std::wstring const& file) {
+ if (changeType == Archive::FileChangeType::EXTRACTION_START) {
+ emit progressFileChange(QString::fromStdWString(file));
+ }
+ };
- // Wait for future to complete:
- loop.exec();
- auto future = futureWatcher.future();
+ // Future watcher to exit the loop:
+ QFutureWatcher<bool> futureWatcher;
+
+ QEventLoop loop(this);
+ connect(
+ &futureWatcher, &QFutureWatcher<bool>::finished,
+ &loop, &QEventLoop::quit,
+ Qt::QueuedConnection);
+
+ // unpack only the files we need for the installer
+ futureWatcher.setFuture(QtConcurrent::run([&]() -> bool {
+ return m_ArchiveHandler->extract(
+ extractPath.toStdWString(),
+ progressCallback,
+ showFilenames ? fileChangeCallback : nullptr,
+ errorCallback
+ );
+ }));
+
+ // Wait for future to complete:
+ loop.exec();
+
+ future = futureWatcher.future();
+ }
// Check the result:
if (!future.result()) {
@@ -224,18 +241,16 @@ bool InstallationManager::extractFiles(QString extractPath, QString title, bool
}
}
- log::debug("Extraction took {:.3f}s.", std::chrono::duration<double>(std::chrono::system_clock::now() - start).count());
-
return true;
}
-QString InstallationManager::extractFile(std::shared_ptr<const FileTreeEntry> entry)
+QString InstallationManager::extractFile(std::shared_ptr<const FileTreeEntry> entry, bool silent)
{
- QStringList result = this->extractFiles({ entry });
+ QStringList result = this->extractFiles({ entry }, silent);
return result.isEmpty() ? QString() : result[0];
}
-QStringList InstallationManager::extractFiles(std::vector<std::shared_ptr<const FileTreeEntry>> const& entries)
+QStringList InstallationManager::extractFiles(std::vector<std::shared_ptr<const FileTreeEntry>> const& entries, bool silent)
{
// Remove the directory since mapToArchive would add them:
std::vector<std::shared_ptr<const FileTreeEntry>> files;
@@ -254,7 +269,7 @@ QStringList InstallationManager::extractFiles(std::vector<std::shared_ptr<const
m_TempFilesToDelete.insert(path);
}
- if (!extractFiles(QDir::tempPath(), tr("Extracting files"), false)) {
+ if (!extractFiles(QDir::tempPath(), tr("Extracting files"), false, silent)) {
return QStringList();
}
@@ -451,7 +466,7 @@ IPluginInstaller::EInstallResult InstallationManager::doInstall(GuessedValue<QSt
QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory);
log::debug("installing to \"{}\"", targetDirectoryNative);
- if (!extractFiles(targetDirectory, "", true)) {
+ if (!extractFiles(targetDirectory, "", true, false)) {
return IPluginInstaller::RESULT_CANCELED;
}
diff --git a/src/installationmanager.h b/src/installationmanager.h
index 1d94151f..3da74ec4 100644
--- a/src/installationmanager.h
+++ b/src/installationmanager.h
@@ -121,6 +121,7 @@ public:
* This method cannot be used to extract directory.
*
* @param entry Entry corresponding to the file to extract.
+ * @param silent If true, the dialog showing extraction progress will not be shown.
*
* @return the absolute path to the temporary file.
*
@@ -129,7 +130,7 @@ public:
* @note The temporary file is automatically cleaned up after the installation.
* @note This call can be very slow if the archive is large and "solid".
*/
- virtual QString extractFile(std::shared_ptr<const MOBase::FileTreeEntry> entry) override;
+ virtual QString extractFile(std::shared_ptr<const MOBase::FileTreeEntry> entry, bool silent = false) override;
/**
* @brief Extract the specified files from the currently opened archive to a temporary location.
@@ -137,6 +138,7 @@ public:
* This method cannot be used to extract directory.
*
* @param entres Entries corresponding to the files to extract.
+ * @param silent If true, the dialog showing extraction progress will not be shown.
*
* @return the list of absolute paths to the temporary files.
*
@@ -151,7 +153,7 @@ public:
* IFileTree and thus to given a list of entries flattened (this was not possible with the
* QStringList version since these were based on the name of the file inside the archive).
*/
- virtual QStringList extractFiles(std::vector<std::shared_ptr<const MOBase::FileTreeEntry>> const& entries) override;
+ virtual QStringList extractFiles(std::vector<std::shared_ptr<const MOBase::FileTreeEntry>> const& entries, bool silent = false) override;
/**
* @brief Create a new file on the disk corresponding to the given entry.
@@ -255,7 +257,7 @@ private:
* @return true if the extraction was successful, false if the extraciton was
* cancelled. If an error occured, an exception is thrown.
*/
- bool extractFiles(QString extractPath, QString title, bool showFilenames);
+ bool extractFiles(QString extractPath, QString title, bool showFilenames, bool silent);
private: