From d13f6bb870cdda71257f665367be8ef9fca86255 Mon Sep 17 00:00:00 2001 From: MikaĆ«l Capelle Date: Tue, 17 May 2022 11:47:01 +0200 Subject: Apply clang-format. --- src/installationmanager.cpp | 579 +++++++++++++++++++++++--------------------- 1 file changed, 300 insertions(+), 279 deletions(-) (limited to 'src/installationmanager.cpp') diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 0c6af11d..8c2ce78d 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -21,33 +21,32 @@ along with Mod Organizer. If not, see . #include "installationmanager.h" -#include "filesystemutilities.h" -#include "report.h" #include "categories.h" -#include "questionboxmemory.h" -#include "settings.h" -#include "queryoverwritedialog.h" -#include "messagedialog.h" -#include "iplugininstallersimple.h" +#include "filesystemutilities.h" #include "iplugininstallercustom.h" +#include "iplugininstallersimple.h" +#include "messagedialog.h" +#include "modinfo.h" #include "nexusinterface.h" +#include "queryoverwritedialog.h" +#include "questionboxmemory.h" +#include "report.h" #include "selectiondialog.h" -#include "modinfo.h" +#include "settings.h" #include #include -#include +#include +#include +#include +#include +#include #include -#include #include -#include +#include #include -#include #include -#include -#include -#include -#include +#include #include #include @@ -58,19 +57,16 @@ along with Mod Organizer. If not, see . #include "archivefiletree.h" - using namespace MOBase; using namespace MOShared; - -InstallationResult::InstallationResult(IPluginInstaller::EInstallResult result) : - m_result(result), m_name(), m_iniTweaks(false), m_backup(false), m_merged(false), m_replaced(false) -{ -} - +InstallationResult::InstallationResult(IPluginInstaller::EInstallResult result) + : m_result(result), m_name(), m_iniTweaks(false), m_backup(false), m_merged(false), + m_replaced(false) +{} template -static T resolveFunction(QLibrary &lib, const char *name) +static T resolveFunction(QLibrary& lib, const char* name) { T temp = reinterpret_cast(lib.resolve(name)); if (temp == nullptr) { @@ -82,10 +78,8 @@ static T resolveFunction(QLibrary &lib, const char *name) return temp; } -InstallationManager::InstallationManager() - : - m_ParentWidget(nullptr), - m_IsRunning(false) { +InstallationManager::InstallationManager() : m_ParentWidget(nullptr), m_IsRunning(false) +{ m_ArchiveHandler = CreateArchive(); if (!m_ArchiveHandler->isValid()) { throw MyException(getErrorString(m_ArchiveHandler->getLastError())); @@ -108,18 +102,16 @@ InstallationManager::InstallationManager() } }); - // Connect the query password slot - This is the only way I found to be able to query user - // from a separate thread. We use a BlockingQueuedConnection so that calling passwordRequested() - // will block until the end of the slot. - connect(this, &InstallationManager::passwordRequested, - this, &InstallationManager::queryPassword, Qt::BlockingQueuedConnection); + // Connect the query password slot - This is the only way I found to be able to query + // user from a separate thread. We use a BlockingQueuedConnection so that calling + // passwordRequested() will block until the end of the slot. + connect(this, &InstallationManager::passwordRequested, this, + &InstallationManager::queryPassword, Qt::BlockingQueuedConnection); } -InstallationManager::~InstallationManager() -{ -} +InstallationManager::~InstallationManager() {} -void InstallationManager::setParentWidget(QWidget *widget) +void InstallationManager::setParentWidget(QWidget* widget) { m_ParentWidget = widget; } @@ -129,12 +121,14 @@ void InstallationManager::setPluginContainer(const PluginContainer* pluginContai m_PluginContainer = pluginContainer; } -void InstallationManager::queryPassword() { +void InstallationManager::queryPassword() +{ m_Password = QInputDialog::getText(m_ParentWidget, tr("Password required"), - tr("Password"), QLineEdit::Password); + tr("Password"), QLineEdit::Password); } -bool InstallationManager::extractFiles(QString extractPath, QString title, bool showFilenames, bool silent) +bool InstallationManager::extractFiles(QString extractPath, QString title, + bool showFilenames, bool silent) { TimeThis tt("InstallationManager::extractFiles"); @@ -150,24 +144,19 @@ bool InstallationManager::extractFiles(QString extractPath, QString title, bool if (silent) { future = QtConcurrent::run([&]() -> bool { - return m_ArchiveHandler->extract( - extractPath.toStdWString(), - nullptr, - nullptr, - errorCallback - ); + return m_ArchiveHandler->extract(extractPath.toStdWString(), nullptr, nullptr, + errorCallback); }); future.waitForFinished(); - } - else { + } else { QProgressDialog* installationProgress = new QProgressDialog(m_ParentWidget); ON_BLOCK_EXIT([=]() { installationProgress->cancel(); installationProgress->hide(); installationProgress->deleteLater(); }); - installationProgress->setWindowFlags( - installationProgress->windowFlags() & (~Qt::WindowContextHelpButtonHint)); + installationProgress->setWindowFlags(installationProgress->windowFlags() & + (~Qt::WindowContextHelpButtonHint)); if (!title.isEmpty()) { installationProgress->setWindowTitle(title); } @@ -176,27 +165,32 @@ bool InstallationManager::extractFiles(QString extractPath, QString title, bool // 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... + // 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); - // Note: Using a loop with a progressUpdate() that only wake-up the loop. The event-loop - // will be used in a loop and not via exec() because connecting to QProgressDialog::setValue - // and using .exec() creates huge recursion that leads to stack-overflow. - // See https://bugreports.qt.io/browse/QTBUG-10561 + // Note: Using a loop with a progressUpdate() that only wake-up the loop. The + // event-loop will be used in a loop and not via exec() because connecting to + // QProgressDialog::setValue and using .exec() creates huge recursion that leads to + // stack-overflow. See https://bugreports.qt.io/browse/QTBUG-10561 QEventLoop loop; - connect(this, &InstallationManager::progressUpdate, &loop, &QEventLoop::wakeUp, Qt::QueuedConnection); + connect(this, &InstallationManager::progressUpdate, &loop, &QEventLoop::wakeUp, + Qt::QueuedConnection); - // Cancelling progress only cancel the extraction, we do not force exiting the event-loop: - connect(installationProgress, &QProgressDialog::canceled, [this]() { m_ArchiveHandler->cancel(); }); + // Cancelling progress only cancel the extraction, we do not force exiting the + // event-loop: + connect(installationProgress, &QProgressDialog::canceled, [this]() { + m_ArchiveHandler->cancel(); + }); std::mutex mutex; int currentProgress = 0; QString currentFileName; // The callbacks: - auto progressCallback = [this, ¤tProgress, &mutex](auto progressType, uint64_t current, uint64_t total) { + auto progressCallback = [this, ¤tProgress, &mutex]( + auto progressType, uint64_t current, uint64_t total) { if (progressType == Archive::ProgressType::EXTRACTION) { { std::scoped_lock guard(mutex); @@ -205,28 +199,25 @@ bool InstallationManager::extractFiles(QString extractPath, QString title, bool emit progressUpdate(); } }; - Archive::FileChangeCallback fileChangeCallback = [this, ¤tFileName, &mutex](auto changeType, std::wstring const& file) { - if (changeType == Archive::FileChangeType::EXTRACTION_START) { - { - std::scoped_lock guard(mutex); - currentFileName = QString::fromStdWString(file); - } - emit progressUpdate(); - } - }; + Archive::FileChangeCallback fileChangeCallback = + [this, ¤tFileName, &mutex](auto changeType, std::wstring const& file) { + if (changeType == Archive::FileChangeType::EXTRACTION_START) { + { + std::scoped_lock guard(mutex); + currentFileName = QString::fromStdWString(file); + } + emit progressUpdate(); + } + }; // unpack only the files we need for the installer QFutureWatcher futureWatcher; - connect(&futureWatcher, &QFutureWatcher::finished, - &loop, &QEventLoop::wakeUp, - Qt::QueuedConnection); + connect(&futureWatcher, &QFutureWatcher::finished, &loop, &QEventLoop::wakeUp, + Qt::QueuedConnection); futureWatcher.setFuture(QtConcurrent::run([&]() -> bool { - return m_ArchiveHandler->extract( - extractPath.toStdWString(), - progressCallback, - showFilenames ? fileChangeCallback : nullptr, - errorCallback - ); + return m_ArchiveHandler->extract(extractPath.toStdWString(), progressCallback, + showFilenames ? fileChangeCallback : nullptr, + errorCallback); })); installationProgress->setModal(true); @@ -253,31 +244,34 @@ bool InstallationManager::extractFiles(QString extractPath, QString title, bool if (m_ArchiveHandler->getLastError() == Archive::Error::ERROR_EXTRACT_CANCELLED) { if (!errorMessage.isEmpty()) { throw MyException(tr("Extraction failed: %1").arg(errorMessage)); - } - else { + } else { return false; } - } - else { - throw MyException(tr("Extraction failed: %1").arg(static_cast(m_ArchiveHandler->getLastError()))); + } else { + throw MyException(tr("Extraction failed: %1") + .arg(static_cast(m_ArchiveHandler->getLastError()))); } } return true; } -QString InstallationManager::extractFile(std::shared_ptr entry, bool silent) +QString InstallationManager::extractFile(std::shared_ptr entry, + bool silent) { - QStringList result = this->extractFiles({ entry }, silent); + QStringList result = this->extractFiles({entry}, silent); return result.isEmpty() ? QString() : result[0]; } -QStringList InstallationManager::extractFiles(std::vector> const& entries, bool silent) +QStringList InstallationManager::extractFiles( + std::vector> const& entries, bool silent) { // Remove the directory since mapToArchive would add them: std::vector> files; std::copy_if(entries.begin(), entries.end(), std::back_inserter(files), - [](auto const& entry) { return entry->isFile(); }); + [](auto const& entry) { + return entry->isFile(); + }); // Update the archive: ArchiveFileTree::mapToArchive(*m_ArchiveHandler, files); @@ -285,7 +279,7 @@ QStringList InstallationManager::extractFiles(std::vectorpath(); result.append(QDir::tempPath().append("/").append(path)); m_TempFilesToDelete.insert(path); @@ -298,11 +292,12 @@ QStringList InstallationManager::extractFiles(std::vector entry) +QString +InstallationManager::createFile(std::shared_ptr entry) { // Use QTemporaryFile to create the temporary file with the given template: - QTemporaryFile tempFile(QDir::cleanPath(QDir::tempPath() + QDir::separator() + "mo2-install")); + QTemporaryFile tempFile( + QDir::cleanPath(QDir::tempPath() + QDir::separator() + "mo2-install")); // Turn-off autoRemove otherwise the file is deleted when destructor is called: tempFile.setAutoRemove(false); @@ -323,10 +318,11 @@ QString InstallationManager::createFile(std::shared_ptr fileTree) +void InstallationManager::cleanCreatedFiles( + std::shared_ptr fileTree) { // We simply have to check if all the entries have fileTree as a parent: - for (auto it = std::begin(m_CreatedFiles); it != std::end(m_CreatedFiles); ) { + for (auto it = std::begin(m_CreatedFiles); it != std::end(m_CreatedFiles);) { // Find the parent - Could this be in FileTreeEntry? bool found = false; @@ -335,38 +331,38 @@ void InstallationManager::cleanCreatedFiles(std::shared_ptrparent(); } } } - // If the parent was not found, we remove the entry, otherwize we move to the next one: + // If the parent was not found, we remove the entry, otherwize we move to the next + // one: if (!found) { it = m_CreatedFiles.erase(it); - } - else { + } else { ++it; } } } - -IPluginInstaller::EInstallResult InstallationManager::installArchive(GuessedValue &modName, const QString &archiveName, int modId) +IPluginInstaller::EInstallResult +InstallationManager::installArchive(GuessedValue& modName, + const QString& archiveName, int modId) { - // in earlier versions the modName was copied here and the copy passed to install. I don't know why I did this and it causes - // a problem if this is called by the bundle installer and the bundled installer adds additional names that then end up being used, - // because the caller will then not have the right name. + // in earlier versions the modName was copied here and the copy passed to install. I + // don't know why I did this and it causes a problem if this is called by the bundle + // installer and the bundled installer adds additional names that then end up being + // used, because the caller will then not have the right name. return install(archiveName, modName, modId).result(); } - -QString InstallationManager::generateBackupName(const QString &directoryName) const +QString InstallationManager::generateBackupName(const QString& directoryName) const { QString backupName = directoryName + "_backup"; if (QDir(backupName).exists()) { - int idx = 2; + int idx = 2; QString temp = backupName + QString::number(idx); while (QDir(temp).exists()) { ++idx; @@ -377,21 +373,21 @@ QString InstallationManager::generateBackupName(const QString &directoryName) co return backupName; } - -InstallationResult InstallationManager::testOverwrite(GuessedValue &modName) +InstallationResult InstallationManager::testOverwrite(GuessedValue& modName) { - QString targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory + "\\" + modName); + QString targetDirectory = + QDir::fromNativeSeparators(m_ModsDirectory + "\\" + modName); // this is only returned on success - InstallationResult result{ IPluginInstaller::RESULT_SUCCESS }; + InstallationResult result{IPluginInstaller::RESULT_SUCCESS}; while (QDir(targetDirectory).exists()) { - Settings &settings(Settings::instance()); + Settings& settings(Settings::instance()); const bool backup = settings.keepBackupOnInstall(); - QueryOverwriteDialog overwriteDialog( - m_ParentWidget, - backup ? QueryOverwriteDialog::BACKUP_YES : QueryOverwriteDialog::BACKUP_NO); + QueryOverwriteDialog overwriteDialog(m_ParentWidget, + backup ? QueryOverwriteDialog::BACKUP_YES + : QueryOverwriteDialog::BACKUP_NO); if (overwriteDialog.exec()) { settings.setKeepBackupOnInstall(overwriteDialog.backup()); @@ -400,22 +396,22 @@ InstallationResult InstallationManager::testOverwrite(GuessedValue &mod QString backupDirectory = generateBackupName(targetDirectory); if (!copyDir(targetDirectory, backupDirectory, false)) { reportError(tr("Failed to create backup")); - return { IPluginInstaller::RESULT_FAILED }; + return {IPluginInstaller::RESULT_FAILED}; } } - result.m_merged = overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE; + result.m_merged = overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE; result.m_replaced = overwriteDialog.action() == QueryOverwriteDialog::ACT_REPLACE; - result.m_backup = overwriteDialog.backup(); + result.m_backup = overwriteDialog.backup(); if (overwriteDialog.action() == QueryOverwriteDialog::ACT_RENAME) { - bool ok = false; + bool ok = false; QString name = QInputDialog::getText(m_ParentWidget, tr("Mod Name"), tr("Name"), QLineEdit::Normal, modName, &ok); if (ok && !name.isEmpty()) { modName.update(name, GUESS_USER); if (!ensureValidModName(modName)) { - return { IPluginInstaller::RESULT_FAILED }; + return {IPluginInstaller::RESULT_FAILED}; } targetDirectory = QDir::fromNativeSeparators(m_ModsDirectory) + "/" + modName; } @@ -438,8 +434,8 @@ InstallationResult InstallationManager::testOverwrite(GuessedValue &mod // remove the directory with all content, then recreate it empty shellDelete(QStringList(targetDirectory)); if (!QDir().mkdir(targetDirectory)) { - // windows may keep the directory around for a moment, preventing its re-creation. Not sure - // if this still happens with shellDelete + // windows may keep the directory around for a moment, preventing its + // re-creation. Not sure if this still happens with shellDelete Sleep(100); QDir().mkdir(targetDirectory); } @@ -453,11 +449,12 @@ InstallationResult InstallationManager::testOverwrite(GuessedValue &mod return result; } else if (overwriteDialog.action() == QueryOverwriteDialog::ACT_MERGE) { return result; - } else /* if (overwriteDialog.action() == QueryOverwriteDialog::ACT_NONE) */ { - return { IPluginInstaller::RESULT_CANCELED }; + } else /* if (overwriteDialog.action() == QueryOverwriteDialog::ACT_NONE) */ + { + return {IPluginInstaller::RESULT_CANCELED}; } } else { - return { IPluginInstaller::RESULT_CANCELED }; + return {IPluginInstaller::RESULT_CANCELED}; } } @@ -466,15 +463,16 @@ InstallationResult InstallationManager::testOverwrite(GuessedValue &mod return result; } - -bool InstallationManager::ensureValidModName(GuessedValue &name) const +bool InstallationManager::ensureValidModName(GuessedValue& name) const { while (name->isEmpty()) { bool ok; - name.update(QInputDialog::getText(m_ParentWidget, tr("Invalid name"), - tr("The name you entered is invalid, please enter a different one."), - QLineEdit::Normal, "", &ok), - GUESS_USER); + name.update( + QInputDialog::getText( + m_ParentWidget, tr("Invalid name"), + tr("The name you entered is invalid, please enter a different one."), + QLineEdit::Normal, "", &ok), + GUESS_USER); if (!ok) { return false; } @@ -482,13 +480,15 @@ bool InstallationManager::ensureValidModName(GuessedValue &name) const return true; } -InstallationResult InstallationManager::doInstall( - GuessedValue &modName, QString gameName, int modID, - const QString &version, const QString &newestVersion, - int categoryID, int fileCategoryID, const QString &repository) +InstallationResult InstallationManager::doInstall(GuessedValue& modName, + QString gameName, int modID, + const QString& version, + const QString& newestVersion, + int categoryID, int fileCategoryID, + const QString& repository) { if (!ensureValidModName(modName)) { - return { IPluginInstaller::RESULT_FAILED }; + return {IPluginInstaller::RESULT_FAILED}; } bool merge = false; @@ -500,17 +500,18 @@ InstallationResult InstallationManager::doInstall( result.m_name = modName; - QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath(); + QString targetDirectory = QDir(m_ModsDirectory + "/" + modName).canonicalPath(); QString targetDirectoryNative = QDir::toNativeSeparators(targetDirectory); log::debug("installing to \"{}\"", targetDirectoryNative); if (!extractFiles(targetDirectory, "", true, false)) { - return { IPluginInstaller::RESULT_CANCELED }; + return {IPluginInstaller::RESULT_CANCELED}; } // Copy the created files: for (auto& p : m_CreatedFiles) { - QString destPath = QDir::cleanPath(targetDirectory + QDir::separator() + p.first->path()); + QString destPath = + QDir::cleanPath(targetDirectory + QDir::separator() + p.first->path()); log::debug("Moving {} to {}.", p.second, destPath); // We need to remove the path if it exists: @@ -528,7 +529,8 @@ InstallationResult InstallationManager::doInstall( QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat); - // overwrite settings only if they are actually are available or haven't been set before + // overwrite settings only if they are actually are available or haven't been set + // before if ((gameName != "") || !settingsFile.contains("gameName")) { settingsFile.setValue("gameName", gameName); } @@ -537,7 +539,8 @@ InstallationResult InstallationManager::doInstall( } if (!settingsFile.contains("version") || (!version.isEmpty() && - (!merge || (VersionInfo(version) >= VersionInfo(settingsFile.value("version").toString()))))) { + (!merge || (VersionInfo(version) >= + VersionInfo(settingsFile.value("version").toString()))))) { settingsFile.setValue("version", version); } if (!newestVersion.isEmpty() || !settingsFile.contains("newestVersion")) { @@ -552,8 +555,9 @@ InstallationResult InstallationManager::doInstall( settingsFile.setValue("repository", repository); if (!merge) { - // this does not clear the list we have in memory but the mod is going to have to be re-read anyway - // btw.: installedFiles were written with beginWriteArray but we can still clear it with beginGroup. nice + // this does not clear the list we have in memory but the mod is going to have to be + // re-read anyway btw.: installedFiles were written with beginWriteArray but we can + // still clear it with beginGroup. nice settingsFile.beginGroup("installedFiles"); settingsFile.remove(""); settingsFile.endGroup(); @@ -562,7 +566,6 @@ InstallationResult InstallationManager::doInstall( return result; } - bool InstallationManager::wasCancelled() const { return m_ArchiveHandler->getLastError() == Archive::Error::ERROR_EXTRACT_CANCELLED; @@ -573,7 +576,6 @@ bool InstallationManager::isRunning() const return m_IsRunning; } - void InstallationManager::postInstallCleanup() { // Clear the list of created files: @@ -582,21 +584,27 @@ void InstallationManager::postInstallCleanup() // Close the archive: m_ArchiveHandler->close(); - // directories we may want to remove. sorted from longest to shortest to ensure we remove subdirectories first. - auto longestFirst = [](const QString &LHS, const QString &RHS) -> bool { - if (LHS.size() != RHS.size()) return LHS.size() > RHS.size(); - else return LHS < RHS; - }; + // directories we may want to remove. sorted from longest to shortest to ensure we + // remove subdirectories first. + auto longestFirst = [](const QString& LHS, const QString& RHS) -> bool { + if (LHS.size() != RHS.size()) + return LHS.size() > RHS.size(); + else + return LHS < RHS; + }; - std::set> directoriesToRemove(longestFirst); + std::set> + directoriesToRemove(longestFirst); // clean up temp files - // TODO: this doesn't yet remove directories. Also, the files may be left there if this point isn't reached - for (const QString &tempFile : m_TempFilesToDelete) { + // TODO: this doesn't yet remove directories. Also, the files may be left there if + // this point isn't reached + for (const QString& tempFile : m_TempFilesToDelete) { QFileInfo fileInfo(QDir::tempPath() + "/" + tempFile); if (fileInfo.exists()) { if (!fileInfo.isReadable() || !fileInfo.isWritable()) { - QFile::setPermissions(fileInfo.absoluteFilePath(), QFile::ReadOther | QFile::WriteOther); + QFile::setPermissions(fileInfo.absoluteFilePath(), + QFile::ReadOther | QFile::WriteOther); } if (!QFile::remove(fileInfo.absoluteFilePath())) { log::warn("Unable to delete {}", fileInfo.absoluteFilePath()); @@ -607,17 +615,21 @@ void InstallationManager::postInstallCleanup() m_TempFilesToDelete.clear(); - // try to delete each directory we had temporary files in. the call fails for non-empty directories which is ok - for (const QString &dir : directoriesToRemove) { + // try to delete each directory we had temporary files in. the call fails for + // non-empty directories which is ok + for (const QString& dir : directoriesToRemove) { QDir().rmdir(dir); } } -InstallationResult InstallationManager::install( - const QString &fileName, GuessedValue &modName, int modID) +InstallationResult InstallationManager::install(const QString& fileName, + GuessedValue& modName, + int modID) { m_IsRunning = true; - ON_BLOCK_EXIT([this]() { m_IsRunning = false; }); + ON_BLOCK_EXIT([this]() { + m_IsRunning = false; + }); QFileInfo fileInfo(fileName); if (!getSupportedExtensions().contains(fileInfo.suffix(), Qt::CaseInsensitive)) { @@ -630,41 +642,43 @@ InstallationResult InstallationManager::install( modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK); // read out meta information from the download if available - QString gameName = ""; - QString version = ""; + QString gameName = ""; + QString version = ""; QString newestVersion = ""; - int categoryID = 0; - int fileCategoryID = 1; - QString repository = "Nexus"; + int categoryID = 0; + int fileCategoryID = 1; + QString repository = "Nexus"; QString metaName = fileName + ".meta"; if (QFile(metaName).exists()) { QSettings metaFile(metaName, QSettings::IniFormat); gameName = metaFile.value("gameName", "").toString(); - modID = metaFile.value("modID", 0).toInt(); + modID = metaFile.value("modID", 0).toInt(); QTextDocument doc; doc.setHtml(metaFile.value("name", "").toString()); modName.update(doc.toPlainText(), GUESS_FALLBACK); modName.update(metaFile.value("modName", "").toString(), GUESS_META); - version = metaFile.value("version", "").toString(); - newestVersion = metaFile.value("newestVersion", "").toString(); + version = metaFile.value("version", "").toString(); + newestVersion = metaFile.value("newestVersion", "").toString(); unsigned int categoryIndex = CategoryFactory::instance().resolveNexusID( metaFile.value("category", 0).toInt()); - categoryID = CategoryFactory::instance().getCategoryID(categoryIndex); - repository = metaFile.value("repository", "").toString(); + categoryID = CategoryFactory::instance().getCategoryID(categoryIndex); + repository = metaFile.value("repository", "").toString(); fileCategoryID = metaFile.value("fileCategory", 1).toInt(); } if (version.isEmpty()) { QDateTime lastMod = fileInfo.lastModified(); - version = "d" + lastMod.toString("yyyy.M.d"); + version = "d" + lastMod.toString("yyyy.M.d"); } - { // guess the mod name and mod if from the file name if there was no meta information + { // guess the mod name and mod if from the file name if there was no meta + // information QString guessedModName; int guessedModID = modID; - NexusInterface::interpretNexusFileName(QFileInfo(fileName).fileName(), guessedModName, guessedModID, false); + NexusInterface::interpretNexusFileName(QFileInfo(fileName).fileName(), + guessedModName, guessedModID, false); if ((modID == 0) && (guessedModID != -1)) { modID = guessedModID; } else if (modID != guessedModID) { @@ -678,52 +692,54 @@ InstallationResult InstallationManager::install( if (fileInfo.dir() == QDir(m_DownloadsDirectory)) { m_CurrentFile = fileInfo.fileName(); } - log::debug("using mod name \"{}\" (id {}) -> {}", QString(modName), modID, m_CurrentFile); + log::debug("using mod name \"{}\" (id {}) -> {}", QString(modName), modID, + m_CurrentFile); - //If there's an archive already open, close it. This happens with the bundle - //installer when it uncompresses a split archive, then finds it has a real archive - //to deal with. + // If there's an archive already open, close it. This happens with the bundle + // installer when it uncompresses a split archive, then finds it has a real archive + // to deal with. m_ArchiveHandler->close(); // open the archive and construct the directory tree the installers work on - bool archiveOpen = m_ArchiveHandler->open( - fileName.toStdWString(), [this]() -> std::wstring { - m_Password = QString(); - - // Note: If we are not in the Qt event thread, we cannot use queryPassword() directly, - // so we emit passwordRequested() that is connected to queryPassword(). The connection is - // made using Qt::BlockingQueuedConnection, so the emit "call" is actually blocking. We - // cannot use emit if we are in the even thread, otherwize we have a deadlock. - if (QThread::currentThread() != QApplication::instance()->thread()) { - emit passwordRequested(); - } - else { - queryPassword(); - } - return m_Password.toStdWString(); - }); + bool archiveOpen = + m_ArchiveHandler->open(fileName.toStdWString(), [this]() -> std::wstring { + m_Password = QString(); + + // Note: If we are not in the Qt event thread, we cannot use queryPassword() + // directly, so we emit passwordRequested() that is connected to + // queryPassword(). The connection is made using Qt::BlockingQueuedConnection, + // so the emit "call" is actually blocking. We cannot use emit if we are in the + // even thread, otherwize we have a deadlock. + if (QThread::currentThread() != QApplication::instance()->thread()) { + emit passwordRequested(); + } else { + queryPassword(); + } + return m_Password.toStdWString(); + }); if (!archiveOpen) { - log::debug("integrated archiver can't open {}: {} ({})", - fileName, - getErrorString(m_ArchiveHandler->getLastError()), - m_ArchiveHandler->getLastError()); + log::debug("integrated archiver can't open {}: {} ({})", fileName, + getErrorString(m_ArchiveHandler->getLastError()), + m_ArchiveHandler->getLastError()); } ON_BLOCK_EXIT(std::bind(&InstallationManager::postInstallCleanup, this)); std::shared_ptr filesTree = - archiveOpen ? ArchiveFileTree::makeTree(*m_ArchiveHandler) : nullptr; + archiveOpen ? ArchiveFileTree::makeTree(*m_ArchiveHandler) : nullptr; auto installers = m_PluginContainer->plugins(); - std::sort(installers.begin(), installers.end(), [] (IPluginInstaller* lhs, IPluginInstaller* rhs) { - return lhs->priority() > rhs->priority(); - }); + std::sort(installers.begin(), installers.end(), + [](IPluginInstaller* lhs, IPluginInstaller* rhs) { + return lhs->priority() > rhs->priority(); + }); InstallationResult installResult(IPluginInstaller::RESULT_NOTATTEMPTED); - for (IPluginInstaller *installer : installers) { - // don't use inactive installers (installer can't be null here but vc static code analysis thinks it could) + for (IPluginInstaller* installer : installers) { + // don't use inactive installers (installer can't be null here but vc static code + // analysis thinks it could) if ((installer == nullptr) || !m_PluginContainer->isEnabled(installer)) { continue; } @@ -738,13 +754,13 @@ InstallationResult InstallationManager::install( } try { - { // simple case - IPluginInstallerSimple *installerSimple - = dynamic_cast(installer); - if ((installerSimple != nullptr) && (filesTree != nullptr) - && (installer->isArchiveSupported(filesTree))) { - installResult.m_result - = installerSimple->install(modName, filesTree, version, modID); + { // simple case + IPluginInstallerSimple* installerSimple = + dynamic_cast(installer); + if ((installerSimple != nullptr) && (filesTree != nullptr) && + (installer->isArchiveSupported(filesTree))) { + installResult.m_result = + installerSimple->install(modName, filesTree, version, modID); if (installResult) { // Downcast to an actual ArchiveFileTree and map to the archive. Test if @@ -752,7 +768,8 @@ InstallationResult InstallationManager::install( // did some bad stuff. ArchiveFileTree* p = dynamic_cast(filesTree.get()); if (p == nullptr) { - throw IncompatibilityException(tr("Invalid file tree returned by plugin.")); + throw IncompatibilityException( + tr("Invalid file tree returned by plugin.")); } // Detach the file tree (this ensure the parent is null and call to path() @@ -766,25 +783,23 @@ InstallationResult InstallationManager::install( // the simple installer only prepares the installation, the rest // works the same for all installers - installResult = doInstall(modName, gameName, modID, version, - newestVersion, categoryID, fileCategoryID, repository); + installResult = doInstall(modName, gameName, modID, version, newestVersion, + categoryID, fileCategoryID, repository); } } } - if (installResult.result() != IPluginInstaller::RESULT_CANCELED) { // custom case - IPluginInstallerCustom *installerCustom - = dynamic_cast(installer); - if ((installerCustom != nullptr) - && (((filesTree != nullptr) - && installer->isArchiveSupported(filesTree)) - || ((filesTree == nullptr) - && installerCustom->isArchiveSupported(fileName)))) { - std::set installerExt - = installerCustom->supportedExtensions(); + if (installResult.result() != IPluginInstaller::RESULT_CANCELED) { // custom case + IPluginInstallerCustom* installerCustom = + dynamic_cast(installer); + if ((installerCustom != nullptr) && + (((filesTree != nullptr) && installer->isArchiveSupported(filesTree)) || + ((filesTree == nullptr) && + installerCustom->isArchiveSupported(fileName)))) { + std::set installerExt = installerCustom->supportedExtensions(); if (installerExt.find(fileInfo.suffix()) != installerExt.end()) { - installResult.m_result - = installerCustom->install(modName, gameName, fileName, version, modID); + installResult.m_result = + installerCustom->install(modName, gameName, fileName, version, modID); unsigned int idx = ModInfo::getIndex(modName); if (idx != UINT_MAX) { ModInfo::Ptr info = ModInfo::getByIndex(idx); @@ -793,40 +808,42 @@ InstallationResult InstallationManager::install( } } } - } catch (const IncompatibilityException &e) { + } catch (const IncompatibilityException& e) { log::error("plugin \"{}\" incompatible: {}", installer->name(), e.what()); } // act upon the installation result. at this point the files have already been // extracted to the correct location switch (installResult.result()) { - case IPluginInstaller::RESULT_FAILED: { - QMessageBox::information(qApp->activeWindow(), tr("Installation failed"), - tr("Something went wrong while installing this mod."), - QMessageBox::Ok); - return installResult; - } break; - case IPluginInstaller::RESULT_SUCCESS: - case IPluginInstaller::RESULT_SUCCESSCANCEL: { - if (filesTree != nullptr) { - auto iniTweakEntry = filesTree->find("INI Tweaks", FileTreeEntry::DIRECTORY); - installResult.m_iniTweaks = iniTweakEntry != nullptr - && !iniTweakEntry->astree()->empty(); - } - installResult.m_result = IPluginInstaller::RESULT_SUCCESS; - return installResult; - } break; - case IPluginInstaller::RESULT_NOTATTEMPTED: - case IPluginInstaller::RESULT_MANUALREQUESTED: { - continue; + case IPluginInstaller::RESULT_FAILED: { + QMessageBox::information(qApp->activeWindow(), tr("Installation failed"), + tr("Something went wrong while installing this mod."), + QMessageBox::Ok); + return installResult; + } break; + case IPluginInstaller::RESULT_SUCCESS: + case IPluginInstaller::RESULT_SUCCESSCANCEL: { + if (filesTree != nullptr) { + auto iniTweakEntry = filesTree->find("INI Tweaks", FileTreeEntry::DIRECTORY); + installResult.m_iniTweaks = + iniTweakEntry != nullptr && !iniTweakEntry->astree()->empty(); } - default: - return installResult; + installResult.m_result = IPluginInstaller::RESULT_SUCCESS; + return installResult; + } break; + case IPluginInstaller::RESULT_NOTATTEMPTED: + case IPluginInstaller::RESULT_MANUALREQUESTED: { + continue; + } + default: + return installResult; } } if (installResult.result() == IPluginInstaller::RESULT_NOTATTEMPTED) { - reportError(tr("None of the available installer plugins were able to handle that archive.\n" - "This is likely due to a corrupted or incompatible download or unrecognized archive format.")); + reportError( + tr("None of the available installer plugins were able to handle that archive.\n" + "This is likely due to a corrupted or incompatible download or unrecognized " + "archive format.")); } return installResult; @@ -835,40 +852,41 @@ InstallationResult InstallationManager::install( QString InstallationManager::getErrorString(Archive::Error errorCode) { switch (errorCode) { - case Archive::Error::ERROR_NONE: { - return tr("no error"); - } break; - case Archive::Error::ERROR_LIBRARY_NOT_FOUND: { - return tr("7z.dll not found"); - } break; - case Archive::Error::ERROR_LIBRARY_INVALID: { - return tr("7z.dll isn't valid"); - } break; - case Archive::Error::ERROR_ARCHIVE_NOT_FOUND: { - return tr("archive not found"); - } break; - case Archive::Error::ERROR_FAILED_TO_OPEN_ARCHIVE: { - return tr("failed to open archive"); - } break; - case Archive::Error::ERROR_INVALID_ARCHIVE_FORMAT: { - return tr("unsupported archive type"); - } break; - case Archive::Error::ERROR_LIBRARY_ERROR: { - return tr("internal library error"); - } break; - case Archive::Error::ERROR_ARCHIVE_INVALID: { - return tr("archive invalid"); - } break; - default: { - // this probably means the archiver.dll is newer than this - return tr("unknown archive error"); - } break; + case Archive::Error::ERROR_NONE: { + return tr("no error"); + } break; + case Archive::Error::ERROR_LIBRARY_NOT_FOUND: { + return tr("7z.dll not found"); + } break; + case Archive::Error::ERROR_LIBRARY_INVALID: { + return tr("7z.dll isn't valid"); + } break; + case Archive::Error::ERROR_ARCHIVE_NOT_FOUND: { + return tr("archive not found"); + } break; + case Archive::Error::ERROR_FAILED_TO_OPEN_ARCHIVE: { + return tr("failed to open archive"); + } break; + case Archive::Error::ERROR_INVALID_ARCHIVE_FORMAT: { + return tr("unsupported archive type"); + } break; + case Archive::Error::ERROR_LIBRARY_ERROR: { + return tr("internal library error"); + } break; + case Archive::Error::ERROR_ARCHIVE_INVALID: { + return tr("archive invalid"); + } break; + default: { + // this probably means the archiver.dll is newer than this + return tr("unknown archive error"); + } break; } } QStringList InstallationManager::getSupportedExtensions() const { - std::set supportedExtensions({ "zip", "rar", "7z", "fomod", "001" }); + std::set supportedExtensions( + {"zip", "rar", "7z", "fomod", "001"}); for (auto* installer : m_PluginContainer->plugins()) { if (m_PluginContainer->isEnabled(installer)) { if (auto* installerCustom = dynamic_cast(installer)) { @@ -880,7 +898,9 @@ QStringList InstallationManager::getSupportedExtensions() const return QStringList(supportedExtensions.begin(), supportedExtensions.end()); } -void InstallationManager::notifyInstallationStart(QString const& archive, bool reinstallation, ModInfo::Ptr currentMod) +void InstallationManager::notifyInstallationStart(QString const& archive, + bool reinstallation, + ModInfo::Ptr currentMod) { auto& installers = m_PluginContainer->plugins(); for (auto* installer : installers) { @@ -890,7 +910,8 @@ void InstallationManager::notifyInstallationStart(QString const& archive, bool r } } -void InstallationManager::notifyInstallationEnd(const InstallationResult& result, ModInfo::Ptr newMod) +void InstallationManager::notifyInstallationEnd(const InstallationResult& result, + ModInfo::Ptr newMod) { auto& installers = m_PluginContainer->plugins(); for (auto* installer : installers) { -- cgit v1.3.1