mirror of
https://github.com/ModOrganizer2/modorganizer-installer_fomod_csharp.git
synced 2026-07-27 14:07:20 -07:00
Format files and add .gitattributes and .clang-format.
This commit is contained in:
@@ -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']
|
||||
@@ -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
|
||||
+3
-1
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include "base_script.h"
|
||||
|
||||
#include <filesystem>
|
||||
@@ -678,4 +680,4 @@ namespace CSharp {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+10
-8
@@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License
|
||||
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef BASE_SCRIPT_H
|
||||
#define BASE_SCRIPT_H
|
||||
|
||||
@@ -268,7 +270,7 @@ namespace CSharp {
|
||||
/// The items, previews, and descriptions are repectively ordered. In other words,
|
||||
/// the i-th item in <paramref name="p_strItems"/> uses the i-th preview in
|
||||
/// <paramref name="p_strPreviewPaths"/> and the i-th description in <paramref name="p_strDescriptions"/>.
|
||||
///
|
||||
///
|
||||
/// Similarly, the idices return as results correspond to the indices of the items in
|
||||
/// <paramref name="p_strItems"/>.
|
||||
/// </remarks>
|
||||
@@ -294,7 +296,7 @@ namespace CSharp {
|
||||
/// The items, previews, and descriptions are repectively ordered. In other words,
|
||||
/// the i-th item in <paramref name="p_strItems"/> uses the i-th preview in
|
||||
/// <paramref name="p_imgPreviews"/> and the i-th description in <paramref name="p_strDescriptions"/>.
|
||||
///
|
||||
///
|
||||
/// Similarly, the idices return as results correspond to the indices of the items in
|
||||
/// <paramref name="p_strItems"/>.
|
||||
/// </remarks>
|
||||
@@ -492,7 +494,7 @@ namespace CSharp {
|
||||
/// <returns>The specified value as a string.</returns>
|
||||
/// <seealso cref="GetPrefsIniInt(string, string)"/>
|
||||
static String^ GetPrefsIniString(String^ p_strSection, String^ p_strKey) {
|
||||
// This looks wrong? Yes! But that's what used in other mod managers...
|
||||
// This looks wrong? Yes! But that's what used in other mod managers...
|
||||
return GetIniString("FalloutPrefs.ini", p_strSection, p_strKey);
|
||||
}
|
||||
|
||||
@@ -504,7 +506,7 @@ namespace CSharp {
|
||||
/// <returns>The specified value as an integer.</returns>
|
||||
/// <seealso cref="GetPrefsIniString(string, string)"/>
|
||||
static int GetPrefsIniInt(String^ p_strSection, String^ p_strKey) {
|
||||
// This looks wrong? Yes! But that's what used in other mod managers...
|
||||
// This looks wrong? Yes! But that's what used in other mod managers...
|
||||
return GetIniInt("FalloutPrefs.ini", p_strSection, p_strKey);
|
||||
}
|
||||
|
||||
@@ -520,7 +522,7 @@ namespace CSharp {
|
||||
static bool EditIni(String^ p_strSettingsFileName, String^ p_strSection, String^ p_strKey, String^ p_strValue);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified value in the Fallout.ini file to the given value.
|
||||
/// Sets the specified value in the Fallout.ini file to the given value.
|
||||
/// </summary>
|
||||
/// <param name="p_strSection">The section in the Ini file to edit.</param>
|
||||
/// <param name="p_strKey">The key in the Ini file to edit.</param>
|
||||
@@ -541,10 +543,10 @@ namespace CSharp {
|
||||
}
|
||||
|
||||
// BaseScript cannot be in a namespace:
|
||||
public ref struct SelectOption: public CSharp::SelectOption {
|
||||
SelectOption(System::String^ item, System::String^ preview, System::String^ desc) :
|
||||
public ref struct SelectOption: public CSharp::SelectOption {
|
||||
SelectOption(System::String^ item, System::String^ preview, System::String^ desc) :
|
||||
CSharp::SelectOption(item, preview, desc) { }
|
||||
};
|
||||
public ref class BaseScript: public CSharp::BaseScriptImpl { };
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// clang-format off
|
||||
|
||||
#include "csharp_interface.h"
|
||||
|
||||
#include <fstream>
|
||||
@@ -153,4 +155,4 @@ namespace CSharp {
|
||||
return postInstall(tree);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+27
-27
@@ -6,35 +6,35 @@
|
||||
#include "ifiletree.h"
|
||||
#include "iplugininstaller.h"
|
||||
|
||||
namespace CSharp {
|
||||
namespace CSharp
|
||||
{
|
||||
|
||||
void init(MOBase::IOrganizer* moInfo);
|
||||
void init(MOBase::IOrganizer* moInfo);
|
||||
|
||||
/**
|
||||
* @brief Initialize the C# interface before starting an installation.
|
||||
*
|
||||
* @param installer The FOMOD C# installer.
|
||||
* @param manager The installation manager from the installer.
|
||||
* @param parentWidget The parent widget from the installer.
|
||||
* @param tree The archive tree.
|
||||
* @param extractedEntries A map from extracted entries to their extracted path.
|
||||
*/
|
||||
void beforeInstall(
|
||||
MOBase::IPlugin const* installer,
|
||||
MOBase::IInstallationManager* manager,
|
||||
QWidget* parentWidget,
|
||||
std::shared_ptr<MOBase::IFileTree> tree,
|
||||
/**
|
||||
* @brief Initialize the C# interface before starting an installation.
|
||||
*
|
||||
* @param installer The FOMOD C# installer.
|
||||
* @param manager The installation manager from the installer.
|
||||
* @param parentWidget The parent widget from the installer.
|
||||
* @param tree The archive tree.
|
||||
* @param extractedEntries A map from extracted entries to their extracted path.
|
||||
*/
|
||||
void beforeInstall(
|
||||
MOBase::IPlugin const* installer, MOBase::IInstallationManager* manager,
|
||||
QWidget* parentWidget, std::shared_ptr<MOBase::IFileTree> tree,
|
||||
std::map<std::shared_ptr<const MOBase::FileTreeEntry>, QString> extractedEntries);
|
||||
|
||||
/**
|
||||
* @brief Clear the C# interface after an installation.
|
||||
*
|
||||
* @param scriptPath Path to the script to execute.
|
||||
* @param tree Reference where the final tree will be stored (in case of success.
|
||||
*
|
||||
* @return the installation result after performing post-installation.
|
||||
*/
|
||||
MOBase::IPluginInstaller::EInstallResult executeCSharpScript(QString scriptPath, std::shared_ptr<MOBase::IFileTree>& tree);
|
||||
/**
|
||||
* @brief Clear the C# interface after an installation.
|
||||
*
|
||||
* @param scriptPath Path to the script to execute.
|
||||
* @param tree Reference where the final tree will be stored (in case of success.
|
||||
*
|
||||
* @return the installation result after performing post-installation.
|
||||
*/
|
||||
MOBase::IPluginInstaller::EInstallResult
|
||||
executeCSharpScript(QString scriptPath, std::shared_ptr<MOBase::IFileTree>& tree);
|
||||
|
||||
}
|
||||
#endif
|
||||
} // namespace CSharp
|
||||
#endif
|
||||
|
||||
+4
-2
@@ -1,3 +1,5 @@
|
||||
// clang-format off
|
||||
|
||||
#ifndef CSHARP_UTILS_H
|
||||
#define CSHARP_UTILS_H
|
||||
|
||||
@@ -17,7 +19,7 @@ namespace CSharp {
|
||||
*/
|
||||
inline std::string to_string(System::String^ value) {
|
||||
return msclr::interop::marshal_as<std::string>(value);
|
||||
}
|
||||
}
|
||||
inline std::wstring to_wstring(System::String^ value) {
|
||||
return msclr::interop::marshal_as<std::wstring>(value);
|
||||
}
|
||||
@@ -36,4 +38,4 @@ namespace CSharp {
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,20 +17,22 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "iinstallationmanager.h"
|
||||
|
||||
#include "csharp_interface.h"
|
||||
#include "installer_fomod_csharp.h"
|
||||
#include "installer_fomod_predialog.h"
|
||||
#include "xml_info_reader.h"
|
||||
#include "installer_fomod_csharp.h"
|
||||
#include "csharp_interface.h"
|
||||
|
||||
using namespace MOBase;
|
||||
|
||||
bool InstallerFomodCSharp::init(IOrganizer* moInfo) {
|
||||
bool InstallerFomodCSharp::init(IOrganizer* moInfo)
|
||||
{
|
||||
m_MOInfo = moInfo;
|
||||
CSharp::init(moInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<const IFileTree> InstallerFomodCSharp::findFomodDirectory(std::shared_ptr<const IFileTree> tree) const
|
||||
std::shared_ptr<const IFileTree>
|
||||
InstallerFomodCSharp::findFomodDirectory(std::shared_ptr<const IFileTree> tree) const
|
||||
{
|
||||
auto entry = tree->find("fomod", FileTreeEntry::DIRECTORY);
|
||||
|
||||
@@ -55,7 +57,9 @@ std::shared_ptr<const IFileTree> InstallerFomodCSharp::findFomodDirectory(std::s
|
||||
return findFomodDirectory(tree->at(0)->astree());
|
||||
}
|
||||
|
||||
std::shared_ptr<const FileTreeEntry> InstallerFomodCSharp::findScriptFile(std::shared_ptr<const IFileTree> tree) const {
|
||||
std::shared_ptr<const FileTreeEntry>
|
||||
InstallerFomodCSharp::findScriptFile(std::shared_ptr<const IFileTree> tree) const
|
||||
{
|
||||
auto fomodDirectory = findFomodDirectory(tree);
|
||||
|
||||
if (fomodDirectory == nullptr) {
|
||||
@@ -71,7 +75,9 @@ std::shared_ptr<const FileTreeEntry> InstallerFomodCSharp::findScriptFile(std::s
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<const FileTreeEntry> InstallerFomodCSharp::findInfoFile(std::shared_ptr<const IFileTree> tree) const {
|
||||
std::shared_ptr<const FileTreeEntry>
|
||||
InstallerFomodCSharp::findInfoFile(std::shared_ptr<const IFileTree> tree) const
|
||||
{
|
||||
auto fomodDirectory = findFomodDirectory(tree);
|
||||
|
||||
if (fomodDirectory == nullptr) {
|
||||
@@ -87,14 +93,19 @@ std::shared_ptr<const FileTreeEntry> InstallerFomodCSharp::findInfoFile(std::sha
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool InstallerFomodCSharp::isArchiveSupported(std::shared_ptr<const MOBase::IFileTree> tree) const {
|
||||
bool InstallerFomodCSharp::isArchiveSupported(
|
||||
std::shared_ptr<const MOBase::IFileTree> tree) const
|
||||
{
|
||||
return findScriptFile(tree) != nullptr;
|
||||
}
|
||||
|
||||
InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::GuessedValue<QString>& modName, std::shared_ptr<MOBase::IFileTree>& tree,
|
||||
QString& version, int& modID)
|
||||
InstallerFomodCSharp::EInstallResult
|
||||
InstallerFomodCSharp::install(MOBase::GuessedValue<QString>& modName,
|
||||
std::shared_ptr<MOBase::IFileTree>& tree,
|
||||
QString& version, int& modID)
|
||||
{
|
||||
static std::set<QString, FileNameComparator> imageSuffixes{ "png", "jpg", "jpeg", "gif", "bmp" };
|
||||
static std::set<QString, FileNameComparator> imageSuffixes{"png", "jpg", "jpeg",
|
||||
"gif", "bmp"};
|
||||
|
||||
// Extract the script file:
|
||||
auto scriptFile = findScriptFile(tree);
|
||||
@@ -106,7 +117,7 @@ InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::Guess
|
||||
auto infoFile = findInfoFile(tree);
|
||||
|
||||
// Set containing everything to extract except the script and the info file:
|
||||
std::set<std::shared_ptr<const FileTreeEntry>> toExtractSet{ scriptFile };
|
||||
std::set<std::shared_ptr<const FileTreeEntry>> toExtractSet{scriptFile};
|
||||
|
||||
if (infoFile != nullptr) {
|
||||
toExtractSet.insert(infoFile);
|
||||
@@ -118,7 +129,7 @@ InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::Guess
|
||||
toExtractSet.insert(entry);
|
||||
}
|
||||
return IFileTree::WalkReturn::CONTINUE;
|
||||
});
|
||||
});
|
||||
|
||||
// Extract everything from the fomod/ folder:
|
||||
auto fomodFolder = findFomodDirectory(tree);
|
||||
@@ -127,7 +138,7 @@ InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::Guess
|
||||
toExtractSet.insert(entry);
|
||||
}
|
||||
return IFileTree::WalkReturn::CONTINUE;
|
||||
});
|
||||
});
|
||||
|
||||
// Convert to vector:
|
||||
std::vector toExtract(std::begin(toExtractSet), std::end(toExtractSet));
|
||||
@@ -166,8 +177,7 @@ InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::Guess
|
||||
if (dialog.manualRequested()) {
|
||||
modName.update(dialog.getName(), GUESS_USER);
|
||||
return EInstallResult::RESULT_MANUALREQUESTED;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return EInstallResult::RESULT_CANCELED;
|
||||
}
|
||||
}
|
||||
@@ -175,6 +185,9 @@ InstallerFomodCSharp::EInstallResult InstallerFomodCSharp::install(MOBase::Guess
|
||||
|
||||
// Run the C# script:
|
||||
const QString scriptPath = entryToPath[scriptFile];
|
||||
CSharp::beforeInstall(this, manager(), parentWidget(), std::const_pointer_cast<IFileTree>(scriptFile->parent()->parent()), std::move(entryToPath));
|
||||
CSharp::beforeInstall(
|
||||
this, manager(), parentWidget(),
|
||||
std::const_pointer_cast<IFileTree>(scriptFile->parent()->parent()),
|
||||
std::move(entryToPath));
|
||||
return CSharp::executeCSharpScript(scriptPath, tree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,67 +20,65 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "iplugininstallersimple.h"
|
||||
|
||||
class InstallerFomodCSharp : public MOBase::IPluginInstallerSimple
|
||||
class InstallerFomodCSharp : public MOBase::IPluginInstallerSimple
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller MOBase::IPluginInstallerSimple)
|
||||
Q_PLUGIN_METADATA(IID "org.holt59.InstallerFomodCSharp")
|
||||
|
||||
public:
|
||||
|
||||
InstallerFomodCSharp() { }
|
||||
InstallerFomodCSharp() {}
|
||||
|
||||
virtual bool init(MOBase::IOrganizer* moInfo) override;
|
||||
|
||||
virtual QString name() const override {
|
||||
return "Fomod Installer C#";
|
||||
}
|
||||
virtual QString name() const override { return "Fomod Installer C#"; }
|
||||
|
||||
virtual QString localizedName() const override {
|
||||
return tr("Fomod Installer C#");
|
||||
}
|
||||
virtual QString localizedName() const override { return tr("Fomod Installer C#"); }
|
||||
|
||||
virtual QString author() const override {
|
||||
return "Holt59";
|
||||
}
|
||||
virtual QString author() const override { return "Holt59"; }
|
||||
|
||||
virtual QString description() const override {
|
||||
virtual QString description() const override
|
||||
{
|
||||
return tr("Installer for C# based FOMOD archives.");
|
||||
}
|
||||
|
||||
virtual MOBase::VersionInfo version() const override {
|
||||
virtual MOBase::VersionInfo version() const override
|
||||
{
|
||||
return MOBase::VersionInfo(1, 0, 0, MOBase::VersionInfo::RELEASE_BETA);
|
||||
}
|
||||
|
||||
virtual QList<MOBase::PluginSetting> settings() const override {
|
||||
virtual QList<MOBase::PluginSetting> settings() const override
|
||||
{
|
||||
return {
|
||||
MOBase::PluginSetting("enabled", "check to enable this plugin", QVariant(true)),
|
||||
MOBase::PluginSetting("prefer", "prefer this over the NCC based plugin", QVariant(true))
|
||||
};
|
||||
MOBase::PluginSetting("enabled", "check to enable this plugin", QVariant(true)),
|
||||
MOBase::PluginSetting("prefer", "prefer this over the NCC based plugin",
|
||||
QVariant(true))};
|
||||
}
|
||||
|
||||
virtual unsigned int priority() const override {
|
||||
virtual unsigned int priority() const override
|
||||
{
|
||||
// It's the same priority as the FOMOD installer but those should never conflict:
|
||||
return m_MOInfo->pluginSetting(name(), "prefer").toBool() ? 110 : 90;
|
||||
}
|
||||
|
||||
virtual bool isManualInstaller() const override {
|
||||
return false;
|
||||
}
|
||||
virtual bool isManualInstaller() const override { return false; }
|
||||
|
||||
virtual bool isArchiveSupported(std::shared_ptr<const MOBase::IFileTree> tree) const override;
|
||||
virtual bool
|
||||
isArchiveSupported(std::shared_ptr<const MOBase::IFileTree> tree) const override;
|
||||
|
||||
virtual EInstallResult install(MOBase::GuessedValue<QString>& modName, std::shared_ptr<MOBase::IFileTree>& tree,
|
||||
QString& version, int& modID) override;
|
||||
virtual EInstallResult install(MOBase::GuessedValue<QString>& modName,
|
||||
std::shared_ptr<MOBase::IFileTree>& tree,
|
||||
QString& version, int& modID) override;
|
||||
|
||||
private:
|
||||
|
||||
MOBase::IOrganizer* m_MOInfo;
|
||||
|
||||
std::shared_ptr<const MOBase::IFileTree> findFomodDirectory(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
std::shared_ptr<const MOBase::FileTreeEntry> findScriptFile(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
std::shared_ptr<const MOBase::FileTreeEntry> findInfoFile(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
|
||||
std::shared_ptr<const MOBase::IFileTree>
|
||||
findFomodDirectory(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
std::shared_ptr<const MOBase::FileTreeEntry>
|
||||
findScriptFile(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
std::shared_ptr<const MOBase::FileTreeEntry>
|
||||
findInfoFile(std::shared_ptr<const MOBase::IFileTree> tree) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -16,8 +16,8 @@ class InstallerFomodPostDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
enum class Result {
|
||||
enum class Result
|
||||
{
|
||||
APPLY,
|
||||
DISCARD,
|
||||
MOVE,
|
||||
@@ -29,13 +29,14 @@ public:
|
||||
* @param preset suggested name for the mod
|
||||
* @param parent parent widget
|
||||
**/
|
||||
explicit InstallerFomodPostDialog(QWidget* parent = 0) :
|
||||
QDialog(parent), ui(new Ui::FomodCSharpPostDialog) {
|
||||
explicit InstallerFomodPostDialog(QWidget* parent = 0)
|
||||
: QDialog(parent), ui(new Ui::FomodCSharpPostDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
}
|
||||
|
||||
~InstallerFomodPostDialog() { }
|
||||
~InstallerFomodPostDialog() {}
|
||||
|
||||
/**
|
||||
* @return the result of this dialog if the user did not cancel.
|
||||
@@ -45,7 +46,8 @@ public:
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void setIniSettings(std::map<QString, PSettings> const& settings) {
|
||||
void setIniSettings(std::map<QString, PSettings> const& settings)
|
||||
{
|
||||
for (auto p : settings) {
|
||||
QTextEdit* widget = new QTextEdit(this);
|
||||
widget->append(p.second.toString());
|
||||
@@ -56,29 +58,30 @@ public:
|
||||
|
||||
private slots:
|
||||
|
||||
void on_discardBtn_clicked() {
|
||||
void on_discardBtn_clicked()
|
||||
{
|
||||
m_Result = Result::DISCARD;
|
||||
this->accept();
|
||||
}
|
||||
|
||||
void on_applyBtn_clicked() {
|
||||
void on_applyBtn_clicked()
|
||||
{
|
||||
m_Result = Result::APPLY;
|
||||
this->accept();
|
||||
}
|
||||
|
||||
void on_moveBtn_clicked() {
|
||||
void on_moveBtn_clicked()
|
||||
{
|
||||
m_Result = Result::MOVE;
|
||||
this->accept();
|
||||
}
|
||||
|
||||
void on_cancelBtn_clicked() {
|
||||
this->reject();
|
||||
}
|
||||
void on_cancelBtn_clicked() { this->reject(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::FomodCSharpPostDialog> ui;
|
||||
|
||||
Result m_Result{ Result::APPLY };
|
||||
Result m_Result{Result::APPLY};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <QCompleter>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Dialog for the installation of a simple archive
|
||||
* a simple archive is one that doesn't require any manual changes to work correctly
|
||||
@@ -23,13 +22,16 @@ public:
|
||||
* @param preset suggested name for the mod
|
||||
* @param parent parent widget
|
||||
**/
|
||||
explicit InstallerFomodPredialog(const MOBase::GuessedValue<QString>& preset, QWidget* parent = 0) :
|
||||
QDialog(parent), ui(new Ui::FomodCSharpPredialog), m_Manual(false) {
|
||||
explicit InstallerFomodPredialog(const MOBase::GuessedValue<QString>& preset,
|
||||
QWidget* parent = 0)
|
||||
: QDialog(parent), ui(new Ui::FomodCSharpPredialog), m_Manual(false)
|
||||
{
|
||||
|
||||
ui->setupUi(this);
|
||||
setWindowTitle(preset + " - " + windowTitle());
|
||||
|
||||
for (auto iter = preset.variants().begin(); iter != preset.variants().end(); ++iter) {
|
||||
for (auto iter = preset.variants().begin(); iter != preset.variants().end();
|
||||
++iter) {
|
||||
ui->nameCombo->addItem(*iter);
|
||||
}
|
||||
|
||||
@@ -38,7 +40,7 @@ public:
|
||||
ui->nameCombo->completer()->setCaseSensitivity(Qt::CaseSensitive);
|
||||
}
|
||||
|
||||
~InstallerFomodPredialog() { }
|
||||
~InstallerFomodPredialog() {}
|
||||
|
||||
/**
|
||||
* @return true if the user requested a manual installation.
|
||||
@@ -52,15 +54,12 @@ public:
|
||||
|
||||
private slots:
|
||||
|
||||
void on_okBtn_clicked() {
|
||||
this->accept();
|
||||
}
|
||||
void on_okBtn_clicked() { this->accept(); }
|
||||
|
||||
void on_cancelBtn_clicked() {
|
||||
this->reject();
|
||||
}
|
||||
void on_cancelBtn_clicked() { this->reject(); }
|
||||
|
||||
void on_manualBtn_clicked() {
|
||||
void on_manualBtn_clicked()
|
||||
{
|
||||
m_Manual = true;
|
||||
this->reject();
|
||||
}
|
||||
@@ -70,4 +69,4 @@ private:
|
||||
bool m_Manual;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+20
-17
@@ -1,9 +1,9 @@
|
||||
#ifndef PSETTINGS_H
|
||||
#define PSETTINGS_H
|
||||
|
||||
#include <map>
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* This is a small class that can be used to store INI settings in memory since
|
||||
@@ -11,15 +11,15 @@
|
||||
*
|
||||
* It is a much simpler structure since it stores everything as string.
|
||||
*/
|
||||
struct PSettings {
|
||||
struct PSettings
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
PSettings() = default;
|
||||
|
||||
public: // Value read/write.
|
||||
|
||||
public: // Value read/write.
|
||||
/**
|
||||
* @brief Set the value of the given section/key.
|
||||
*
|
||||
@@ -27,7 +27,8 @@ public: // Value read/write.
|
||||
* @param key The key of the value.
|
||||
* @param value The value to set.
|
||||
*/
|
||||
void setValue(QString section, QString key, QString value) {
|
||||
void setValue(QString section, QString key, QString value)
|
||||
{
|
||||
m_Values[std::make_pair(section, key)] = value;
|
||||
}
|
||||
|
||||
@@ -37,9 +38,11 @@ public: // Value read/write.
|
||||
* @param section The section of the value.
|
||||
* @param key The key of the value.
|
||||
*
|
||||
* @return the corresponding value, or an empty string if the section/key does not exist.
|
||||
* @return the corresponding value, or an empty string if the section/key does not
|
||||
* exist.
|
||||
*/
|
||||
QString value(QString section, QString key) const {
|
||||
QString value(QString section, QString key) const
|
||||
{
|
||||
auto it = m_Values.find(std::make_pair(section, key));
|
||||
return it == m_Values.end() ? QString() : it->second;
|
||||
}
|
||||
@@ -52,19 +55,20 @@ public: // Value read/write.
|
||||
*
|
||||
* @return true if the section/key exist.
|
||||
*/
|
||||
bool hasValue(QString section, QString key) const {
|
||||
bool hasValue(QString section, QString key) const
|
||||
{
|
||||
return m_Values.find(std::make_pair(section, key)) != m_Values.end();
|
||||
}
|
||||
|
||||
public: // Output:
|
||||
|
||||
public: // Output:
|
||||
/**
|
||||
* @brief Convert this PSettings to a string.
|
||||
*
|
||||
* @return a string representing the content of a valid INI file corresponding
|
||||
* to this PSettings.
|
||||
*/
|
||||
QString toString() const {
|
||||
QString toString() const
|
||||
{
|
||||
QString result = "";
|
||||
QString cSection;
|
||||
for (auto& p : m_Values) {
|
||||
@@ -85,12 +89,12 @@ public: // Output:
|
||||
*
|
||||
* @param settings The settings to update.
|
||||
*/
|
||||
void update(QSettings& settings) const {
|
||||
void update(QSettings& settings) const
|
||||
{
|
||||
for (auto& p : m_Values) {
|
||||
if (p.first.first == "General") {
|
||||
settings.setValue(p.first.second, p.second);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
settings.setValue(p.first.first + "/" + p.first.second, p.second);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +103,6 @@ public: // Output:
|
||||
private:
|
||||
// Map from <section, key> to value:
|
||||
std::map<std::pair<QString, QString>, QString> m_Values;
|
||||
|
||||
};
|
||||
|
||||
#endif // !PSETTINGS_H
|
||||
#endif // !PSETTINGS_H
|
||||
|
||||
+50
-50
@@ -1,36 +1,37 @@
|
||||
#ifndef XML_INFO_READER_H
|
||||
#define XML_INFO_READER_H
|
||||
|
||||
#include <QString>
|
||||
#include <QIODevice>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QTextStream>
|
||||
#include <QFile>
|
||||
#include <QIODevice>
|
||||
#include <QString>
|
||||
#include <QStringEncoder>
|
||||
#include <QTextStream>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
#include "utility.h"
|
||||
#include "log.h"
|
||||
#include "utility.h"
|
||||
|
||||
// This is from installer_fomod, but should probably not be duplicated here.
|
||||
|
||||
struct FomodInfoReader: QObject {
|
||||
struct FomodInfoReader : QObject
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
struct XmlParseError : MOBase::Exception {
|
||||
XmlParseError(const QString& message): MOBase::Exception(message) {}
|
||||
struct XmlParseError : MOBase::Exception
|
||||
{
|
||||
XmlParseError(const QString& message) : MOBase::Exception(message) {}
|
||||
};
|
||||
|
||||
static QByteArray skipXmlHeader(QIODevice& file)
|
||||
{
|
||||
static const unsigned char UTF16LE_BOM[] = { 0xFF, 0xFE };
|
||||
static const unsigned char UTF16BE_BOM[] = { 0xFE, 0xFF };
|
||||
static const unsigned char UTF8_BOM[] = { 0xEF, 0xBB, 0xBF };
|
||||
static const unsigned char UTF16LE[] = { 0x3C, 0x00, 0x3F, 0x00 };
|
||||
static const unsigned char UTF16BE[] = { 0x00, 0x3C, 0x00, 0x3F };
|
||||
static const unsigned char UTF8[] = { 0x3C, 0x3F, 0x78, 0x6D };
|
||||
static const unsigned char UTF16LE_BOM[] = {0xFF, 0xFE};
|
||||
static const unsigned char UTF16BE_BOM[] = {0xFE, 0xFF};
|
||||
static const unsigned char UTF8_BOM[] = {0xEF, 0xBB, 0xBF};
|
||||
static const unsigned char UTF16LE[] = {0x3C, 0x00, 0x3F, 0x00};
|
||||
static const unsigned char UTF16BE[] = {0x00, 0x3C, 0x00, 0x3F};
|
||||
static const unsigned char UTF8[] = {0x3C, 0x3F, 0x78, 0x6D};
|
||||
|
||||
file.seek(0);
|
||||
QByteArray rawBytes = file.read(4);
|
||||
@@ -39,24 +40,19 @@ public:
|
||||
if (rawBytes.startsWith((const char*)UTF16LE_BOM)) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf16LE);
|
||||
bom = 2;
|
||||
}
|
||||
else if (rawBytes.startsWith((const char*)UTF16BE_BOM)) {
|
||||
} else if (rawBytes.startsWith((const char*)UTF16BE_BOM)) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf16BE);
|
||||
bom = 2;
|
||||
}
|
||||
else if (rawBytes.startsWith((const char*)UTF8_BOM)) {
|
||||
} else if (rawBytes.startsWith((const char*)UTF8_BOM)) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf8);
|
||||
bom = 3;
|
||||
}
|
||||
else if (rawBytes.startsWith(QByteArray((const char*)UTF16LE, 4))) {
|
||||
} else if (rawBytes.startsWith(QByteArray((const char*)UTF16LE, 4))) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf16LE);
|
||||
}
|
||||
else if (rawBytes.startsWith(QByteArray((const char*)UTF16BE, 4))) {
|
||||
} else if (rawBytes.startsWith(QByteArray((const char*)UTF16BE, 4))) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf16BE);
|
||||
}
|
||||
else if (rawBytes.startsWith(QByteArray((const char*)UTF8, 4))) {
|
||||
} else if (rawBytes.startsWith(QByteArray((const char*)UTF8, 4))) {
|
||||
stream.setEncoding(QStringEncoder::Encoding::Utf8);
|
||||
} // otherwise maybe the textstream knows the encoding?
|
||||
} // otherwise maybe the textstream knows the encoding?
|
||||
|
||||
stream.seek(bom);
|
||||
QString header = stream.readLine();
|
||||
@@ -70,18 +66,20 @@ public:
|
||||
}
|
||||
|
||||
template <class Fn>
|
||||
static auto readXml(QFile& file, Fn &&fn)
|
||||
static auto readXml(QFile& file, Fn&& fn)
|
||||
{
|
||||
// List of encodings to try:
|
||||
static const std::vector<QStringConverter::Encoding> encodings{ QStringConverter::Utf16, QStringConverter::Utf8, QStringConverter::Latin1 };
|
||||
static const std::vector<QStringConverter::Encoding> encodings{
|
||||
QStringConverter::Utf16, QStringConverter::Utf8, QStringConverter::Latin1};
|
||||
|
||||
std::string errorMessage;
|
||||
try {
|
||||
QXmlStreamReader reader(&file);
|
||||
return fn(reader);
|
||||
}
|
||||
catch (const XmlParseError& e) {
|
||||
MOBase::log::warn("The {} in this file is incorrectly encoded ({}). Applying heuristics...", file.fileName(), e.what());
|
||||
} catch (const XmlParseError& e) {
|
||||
MOBase::log::warn(
|
||||
"The {} in this file is incorrectly encoded ({}). Applying heuristics...",
|
||||
file.fileName(), e.what());
|
||||
}
|
||||
|
||||
// nmm's xml parser is less strict than the one from qt and allows files with
|
||||
@@ -91,50 +89,52 @@ public:
|
||||
|
||||
// try parsing the file with several encodings to support broken files
|
||||
for (auto encoding : encodings) {
|
||||
MOBase::log::debug("Trying encoding {} for {}... ", QStringConverter::nameForEncoding(encoding), file.fileName());
|
||||
MOBase::log::debug("Trying encoding {} for {}... ",
|
||||
QStringConverter::nameForEncoding(encoding), file.fileName());
|
||||
try {
|
||||
QStringEncoder encoder(encoding);
|
||||
QXmlStreamReader reader(encoder.encode(QString("<?xml version=\"1.0\" encoding=\"%1\" ?>").arg(encoder.name())) + headerlessData);
|
||||
QXmlStreamReader reader(
|
||||
encoder.encode(QString("<?xml version=\"1.0\" encoding=\"%1\" ?>")
|
||||
.arg(encoder.name())) +
|
||||
headerlessData);
|
||||
MOBase::log::debug("Interpreting {} as {}.", file.fileName(), encoder.name());
|
||||
return fn(reader);
|
||||
}
|
||||
catch (const XmlParseError& e) {
|
||||
MOBase::log::debug("Not {}: {}.", QStringConverter::nameForEncoding(encoding), e.what());
|
||||
} catch (const XmlParseError& e) {
|
||||
MOBase::log::debug("Not {}: {}.", QStringConverter::nameForEncoding(encoding),
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
|
||||
throw XmlParseError(tr("Failed to parse %1. See console for details.").arg(file.fileName()));
|
||||
throw XmlParseError(
|
||||
tr("Failed to parse %1. See console for details.").arg(file.fileName()));
|
||||
}
|
||||
|
||||
static std::tuple<QString, int, QString> parseInfo(QXmlStreamReader& reader)
|
||||
{
|
||||
std::tuple<QString, int, QString> info{ "", -1, "" };
|
||||
std::tuple<QString, int, QString> info{"", -1, ""};
|
||||
while (!reader.atEnd()) {
|
||||
switch (reader.readNext()) {
|
||||
case QXmlStreamReader::StartElement: {
|
||||
if (reader.name().toString() == "Name") {
|
||||
std::get<0>(info) = reader.readElementText();
|
||||
}
|
||||
else if (reader.name().toString() == "Author") {
|
||||
}
|
||||
else if (reader.name().toString() == "Version") {
|
||||
} else if (reader.name().toString() == "Author") {
|
||||
} else if (reader.name().toString() == "Version") {
|
||||
std::get<2>(info) = reader.readElementText();
|
||||
}
|
||||
else if (reader.name().toString() == "Id") {
|
||||
} else if (reader.name().toString() == "Id") {
|
||||
std::get<1>(info) = reader.readElementText().toInt();
|
||||
}
|
||||
else if (reader.name().toString() == "Website") {
|
||||
} else if (reader.name().toString() == "Website") {
|
||||
}
|
||||
} break;
|
||||
default: {} break;
|
||||
default: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if (reader.hasError()) {
|
||||
throw XmlParseError(QString("%1 in line %2").arg(reader.errorString()).arg(reader.lineNumber()));
|
||||
throw XmlParseError(
|
||||
QString("%1 in line %2").arg(reader.errorString()).arg(reader.lineNumber()));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user