diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6098e1f --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +# We'll use defaults from the LLVM style, but with 4 columns indentation. +BasedOnStyle: LLVM +IndentWidth: 2 +--- +Language: Cpp +DeriveLineEnding: false +UseCRLF: true +DerivePointerAlignment: false +PointerAlignment: Left +AlignConsecutiveAssignments: true +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: Empty +AlwaysBreakTemplateDeclarations: Yes +AccessModifierOffset: -2 +AlignTrailingComments: true +SpacesBeforeTrailingComments: 2 +NamespaceIndentation: Inner +MaxEmptyLinesToKeep: 1 +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true +ColumnLimit: 88 +ForEachMacros: ['Q_FOREACH', 'foreach'] diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..b2ed96a --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1 @@ +988523cac10641c510fd711d80d59c82d473f6a5 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f869712 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.cpp text eol=crlf +*.h text eol=crlf diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f4b1230 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,16 @@ +name: Build Installer Bundle Plugin + +on: + push: + branches: master + pull_request: + types: [opened, synchronize, reopened] + +jobs: + build: + runs-on: windows-2022 + steps: + - name: Build Installer Bundle Plugin + uses: ModOrganizer2/build-with-mob-action@master + with: + mo2-dependencies: cmake_common uibase diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 0000000..31c504d --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,16 @@ +name: Lint Installer Bundle Plugin + +on: + push: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Check format + uses: ModOrganizer2/check-formatting-action@master + with: + check-path: "." diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index ca6eec6..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,40 +0,0 @@ -version: 1.0.{build} -skip_branch_with_pr: true -image: Visual Studio 2019 -environment: - WEBHOOK_URL: - secure: gOKbXaZM9ImtMD5XrYITvdyZUW/az082G9OIN1EC1Vbg57wBaeLhi49uGjxPw5GVujHku6kxN6ab89zhbS5GVeluR76GM83IbKV4Sh7udXzoYZZdg6YudtYHzdhCgUeiedpswbuczTq9ceIkkfSEWZuh/lMAAVVwvcGsJAnoPFw= -build_script: -- pwsh: >- - $ErrorActionPreference = 'Stop' - - git clone --depth=1 --no-single-branch https://github.com/ModOrganizer2/modorganizer-umbrella.git c:\projects\modorganizer-umbrella - - New-Item -ItemType Directory -Path c:\projects\modorganizer-build - - cd c:\projects\modorganizer-umbrella - - ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH -eq $null) ? ($branch = $env:APPVEYOR_REPO_BRANCH) : ($branch = $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) - - git checkout $(git show-ref --verify --quiet refs/remotes/origin/${branch} || echo '-b') ${branch} - - C:\Python37-x64\python.exe unimake.py -d c:\projects\modorganizer-build -s Appveyor_Build=True ${env:APPVEYOR_PROJECT_NAME} - - if($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode ) } -artifacts: -- path: vsbuild\src\RelWithDebInfo\installer_bundle.dll - name: installer_bundle_dll -- path: vsbuild\src\RelWithDebInfo\installer_bundle.pdb - name: installer_bundle_pdb -- path: vsbuild\src\RelWithDebInfo\installer_bundle.lib - name: installer_bundle_lib -on_success: - - ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER - - ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1 - - ps: ./send.ps1 success $env:WEBHOOK_URL -on_failure: - - ps: Set-Location -Path $env:APPVEYOR_BUILD_FOLDER - - ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stdout.log - - ps: Push-AppveyorArtifact ${env:APPVEYOR_BUILD_FOLDER}\stderr.log - - ps: Invoke-RestMethod https://raw.githubusercontent.com/DiscordHooks/appveyor-discord-webhook/master/send.ps1 -o send.ps1 - - ps: ./send.ps1 failure $env:WEBHOOK_URL \ No newline at end of file diff --git a/src/installerbundle.cpp b/src/installerbundle.cpp index e7b3da2..6fe205f 100644 --- a/src/installerbundle.cpp +++ b/src/installerbundle.cpp @@ -26,13 +26,9 @@ along with Mod Organizer. If not, see . using namespace MOBase; +InstallerBundle::InstallerBundle() {} -InstallerBundle::InstallerBundle() -{ -} - - -bool InstallerBundle::init(IOrganizer *organizer) +bool InstallerBundle::init(IOrganizer* organizer) { m_Organizer = organizer; return true; @@ -65,9 +61,10 @@ VersionInfo InstallerBundle::version() const QList InstallerBundle::settings() const { - return { - PluginSetting("auto_reinstall", "when reinstalling from an archive containing multiple mods, automatically select the previously installed", true) - }; + return {PluginSetting("auto_reinstall", + "when reinstalling from an archive containing multiple mods, " + "automatically select the previously installed", + true)}; } unsigned int InstallerBundle::priority() const @@ -80,13 +77,14 @@ bool InstallerBundle::isManualInstaller() const return false; } -void InstallerBundle::onInstallationStart(QString const& archive, bool reinstallation, IModInterface* currentMod) +void InstallerBundle::onInstallationStart(QString const& archive, bool reinstallation, + IModInterface* currentMod) { // We reset some field and fetch the previously installed file: m_InstallationFile = archive; - m_InstallerUsed = false; - m_SelectedFile = ""; - m_PreviousFile = ""; + m_InstallerUsed = false; + m_SelectedFile = ""; + m_PreviousFile = ""; if (reinstallation && m_Organizer->pluginSetting(name(), "auto_reinstall").toBool()) { m_PreviousFile = currentMod->pluginSetting(name(), "archive", QString()).toString(); @@ -102,7 +100,8 @@ void InstallerBundle::onInstallationEnd(EInstallResult result, IModInterface* ne } } -std::vector> InstallerBundle::findObjects(std::shared_ptr tree) const +std::vector> +InstallerBundle::findObjects(std::shared_ptr tree) const { std::vector> entries; // Check if we have an archive: @@ -112,11 +111,11 @@ std::vector> InstallerBundle::findO int nDirs = 0; for (auto entry : *tree) { if (entry->isFile()) { - if (managerExtensions.contains(entry->suffix(), FileNameComparator::CaseSensitivity)) { + if (managerExtensions.contains(entry->suffix(), + FileNameComparator::CaseSensitivity)) { entries.push_back(entry); } - } - else { + } else { nDirs++; } } @@ -140,8 +139,9 @@ bool InstallerBundle::isArchiveSupported(std::shared_ptr tree) return !findObjects(tree).empty(); } -IPluginInstaller::EInstallResult InstallerBundle::install( - GuessedValue& modName, std::shared_ptr& tree, QString&, int &modId) +IPluginInstaller::EInstallResult +InstallerBundle::install(GuessedValue& modName, + std::shared_ptr& tree, QString&, int& modId) { // Find a valid "object": auto entries = findObjects(tree); @@ -152,8 +152,7 @@ IPluginInstaller::EInstallResult InstallerBundle::install( std::shared_ptr entry = nullptr; if (entries.size() == 1) { entry = entries[0]; - } - else { + } else { if (!m_PreviousFile.isEmpty()) { entry = tree->find(m_PreviousFile); } @@ -161,14 +160,12 @@ IPluginInstaller::EInstallResult InstallerBundle::install( if (entry == nullptr) { MultiArchiveDialog dialog(entries, parentWidget()); if (dialog.exec() == QDialog::Accepted) { - entry = dialog.selectedEntry(); + entry = dialog.selectedEntry(); m_SelectedFile = entry->pathFrom(tree); - } - else { + } else { if (dialog.manualRequested()) { return IPluginInstaller::RESULT_MANUALREQUESTED; - } - else { + } else { return IPluginInstaller::RESULT_CANCELED; } } @@ -183,13 +180,14 @@ IPluginInstaller::EInstallResult InstallerBundle::install( // Extract it: QString tempFile = manager()->extractFile(entry); - IPluginInstaller::EInstallResult res = manager()->installArchive(modName, tempFile, modId); + IPluginInstaller::EInstallResult res = + manager()->installArchive(modName, tempFile, modId); if (res == IPluginInstaller::RESULT_SUCCESS) { res = IPluginInstaller::RESULT_SUCCESSCANCEL; } return res; } -#if QT_VERSION < QT_VERSION_CHECK(5,0,0) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) Q_EXPORT_PLUGIN2(installerBundle, InstallerBundle) #endif diff --git a/src/installerbundle.h b/src/installerbundle.h index bfd1466..885c6e9 100644 --- a/src/installerbundle.h +++ b/src/installerbundle.h @@ -1,89 +1,88 @@ -/* -Copyright (C) 2012 Sebastian Herbord. All rights reserved. - -This file is part of Mod Organizer. - -Mod Organizer is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Mod Organizer is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Mod Organizer. If not, see . -*/ - -#ifndef INSTALLERBUNDLE_H -#define INSTALLERBUNDLE_H - - -#include - -class InstallerBundle : public MOBase::IPluginInstallerSimple -{ - - Q_OBJECT - Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller MOBase::IPluginInstallerSimple) -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - Q_PLUGIN_METADATA(IID "org.tannin.InstallerBundle" FILE "installerbundle.json") -#endif - -public: - - InstallerBundle(); - - virtual bool init(MOBase::IOrganizer* moInfo) override; - virtual QString name() const override; - virtual QString localizedName() const override; - virtual QString author() const override; - virtual QString description() const override; - virtual MOBase::VersionInfo version() const override; - virtual QList settings() const override; - - virtual unsigned int priority() const override; - virtual bool isManualInstaller() const override; - - virtual void onInstallationStart(QString const& archive, bool reinstallation, MOBase::IModInterface* currentMod) override; - virtual void onInstallationEnd(EInstallResult result, MOBase::IModInterface* newMod) override; - - virtual bool isArchiveSupported(std::shared_ptr tree) const override; - virtual EInstallResult install(MOBase::GuessedValue &modName, - std::shared_ptr &tree, - QString &version, int &modID) override; - -private: - - /** - * @brief Find the entries that can be extracted from this archive. - * - * @param tree The tree to look the entry in. - * - * @return the entry, if one was found, or a null pointer. - */ - std::vector> findObjects(std::shared_ptr tree) const; - -private: - - MOBase::IOrganizer* m_Organizer; - - // The archive being installed: - QString m_InstallationFile; - - // Indicates if this installer was used during the installation process: - bool m_InstallerUsed; - - // Contains the file installed (when multiple archives are present), or an - // empty string: - QString m_SelectedFile; - - // Contains the file previously installed (when multiple archives are present), or an - // empty string: - QString m_PreviousFile; -}; - - -#endif // INSTALLERBUNDLE_H +/* +Copyright (C) 2012 Sebastian Herbord. All rights reserved. + +This file is part of Mod Organizer. + +Mod Organizer is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Mod Organizer is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Mod Organizer. If not, see . +*/ + +#ifndef INSTALLERBUNDLE_H +#define INSTALLERBUNDLE_H + +#include + +class InstallerBundle : public MOBase::IPluginInstallerSimple +{ + + Q_OBJECT + Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller MOBase::IPluginInstallerSimple) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + Q_PLUGIN_METADATA(IID "org.tannin.InstallerBundle" FILE "installerbundle.json") +#endif + +public: + InstallerBundle(); + + virtual bool init(MOBase::IOrganizer* moInfo) override; + virtual QString name() const override; + virtual QString localizedName() const override; + virtual QString author() const override; + virtual QString description() const override; + virtual MOBase::VersionInfo version() const override; + virtual QList settings() const override; + + virtual unsigned int priority() const override; + virtual bool isManualInstaller() const override; + + virtual void onInstallationStart(QString const& archive, bool reinstallation, + MOBase::IModInterface* currentMod) override; + virtual void onInstallationEnd(EInstallResult result, + MOBase::IModInterface* newMod) override; + + virtual bool + isArchiveSupported(std::shared_ptr tree) const override; + virtual EInstallResult install(MOBase::GuessedValue& modName, + std::shared_ptr& tree, + QString& version, int& modID) override; + +private: + /** + * @brief Find the entries that can be extracted from this archive. + * + * @param tree The tree to look the entry in. + * + * @return the entry, if one was found, or a null pointer. + */ + std::vector> + findObjects(std::shared_ptr tree) const; + +private: + MOBase::IOrganizer* m_Organizer; + + // The archive being installed: + QString m_InstallationFile; + + // Indicates if this installer was used during the installation process: + bool m_InstallerUsed; + + // Contains the file installed (when multiple archives are present), or an + // empty string: + QString m_SelectedFile; + + // Contains the file previously installed (when multiple archives are present), or an + // empty string: + QString m_PreviousFile; +}; + +#endif // INSTALLERBUNDLE_H diff --git a/src/multiarchivedialog.cpp b/src/multiarchivedialog.cpp index 485640f..03774f6 100644 --- a/src/multiarchivedialog.cpp +++ b/src/multiarchivedialog.cpp @@ -1,13 +1,12 @@ #include "multiarchivedialog.h" #include "ui_multiarchivedialog.h" - using namespace MOBase; - MultiArchiveDialog::MultiArchiveDialog( - std::vector> entries, QWidget* parent) - : QDialog(parent), ui(new Ui::MultiArchiveDialog), m_Manual(false), m_SelectedEntry(nullptr) + std::vector> entries, QWidget* parent) + : QDialog(parent), ui(new Ui::MultiArchiveDialog), m_Manual(false), + m_SelectedEntry(nullptr) { ui->setupUi(this); @@ -24,21 +23,18 @@ MultiArchiveDialog::MultiArchiveDialog( } } - MultiArchiveDialog::~MultiArchiveDialog() { delete ui; } - void MultiArchiveDialog::on_cancelBtn_clicked() { this->reject(); } - void MultiArchiveDialog::on_manualBtn_clicked() { m_Manual = true; this->reject(); -} \ No newline at end of file +} diff --git a/src/multiarchivedialog.h b/src/multiarchivedialog.h index 52ddbca..8995869 100644 --- a/src/multiarchivedialog.h +++ b/src/multiarchivedialog.h @@ -26,29 +26,32 @@ along with Mod Organizer. If not, see . #include "ifiletree.h" -namespace Ui { - class MultiArchiveDialog; +namespace Ui +{ +class MultiArchiveDialog; } - - /** * **/ -class MultiArchiveDialog: public QDialog +class MultiArchiveDialog : public QDialog { Q_OBJECT - + public: - /** - * @brief Constructor - * - * @param tree the directory tree of the archive. The caller is resonsible to verify this actually qualifies as a bain installer - * @param modName proposed name for the mod. The dialog allows the user to change this - * @param packageTXT path to the extracted package.txt file or an empty string if there is none - * @param parent parent widget - **/ - explicit MultiArchiveDialog(std::vector> entries, QWidget *parent); + /** + * @brief Constructor + * + * @param tree the directory tree of the archive. The caller is resonsible to verify + *this actually qualifies as a bain installer + * @param modName proposed name for the mod. The dialog allows the user to change this + * @param packageTXT path to the extracted package.txt file or an empty string if + *there is none + * @param parent parent widget + **/ + explicit MultiArchiveDialog( + std::vector> entries, + QWidget* parent); ~MultiArchiveDialog(); /** @@ -67,11 +70,9 @@ private slots: void on_cancelBtn_clicked(); private: - - Ui::MultiArchiveDialog *ui; + Ui::MultiArchiveDialog* ui; bool m_Manual; std::shared_ptr m_SelectedEntry; - }; -#endif // BAINCOMPLEXINSTALLERDIALOG_H +#endif // BAINCOMPLEXINSTALLERDIALOG_H