chore(clang-tidy): fix clang tidy warnings

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2026-05-08 22:28:29 +03:00
parent 9f175a4a4d
commit 21b74dd6d1
No known key found for this signature in database
GPG key ID: 55EF5DA53DB36318
14 changed files with 411 additions and 507 deletions

View file

@ -46,13 +46,10 @@
#include "Application.h"
#include "Json.h"
#include "launch/LaunchTask.h"
#include "settings/INISettingsObject.h"
#include "settings/OverrideSetting.h"
#include "settings/Setting.h"
#include "BuildConfig.h"
#include "Commandline.h"
#include "FileSystem.h"
int getConsoleMaxLines(SettingsObject* settings)
{
@ -71,20 +68,18 @@ bool shouldStopOnConsoleOverflow(SettingsObject* settings)
return settings->get("ConsoleOverflowStop").toBool();
}
BaseInstance::BaseInstance(SettingsObject* globalSettings, std::unique_ptr<SettingsObject> settings, const QString& rootDir) : QObject()
BaseInstance::BaseInstance(SettingsObject* globalSettings, std::unique_ptr<SettingsObject> settings, const QString& rootDir)
: m_rootDir(rootDir), m_settings(std::move(settings)), m_global_settings(globalSettings)
{
m_settings = std::move(settings);
m_global_settings = globalSettings;
m_rootDir = rootDir;
m_settings->registerSetting("name", "Unnamed Instance");
m_settings->registerSetting("iconKey", "default");
m_settings->registerSetting("notes", "");
m_settings->registerSetting("lastLaunchTime", 0);
m_settings->registerSetting("totalTimePlayed", 0);
if (m_settings->get("totalTimePlayed").toLongLong() < 0)
if (m_settings->get("totalTimePlayed").toLongLong() < 0) {
m_settings->reset("totalTimePlayed");
}
m_settings->registerSetting("lastTimePlayed", 0);
m_settings->registerSetting("linkedInstances", "[]");
@ -97,8 +92,9 @@ BaseInstance::BaseInstance(SettingsObject* globalSettings, std::unique_ptr<Setti
// NOTE: Sometimees InstanceType is already registered, as it was used to identify the type of
// a locally stored instance
if (!m_settings->getSetting("InstanceType"))
if (!m_settings->getSetting("InstanceType")) {
m_settings->registerSetting("InstanceType", "");
}
// Custom Commands
auto commandSetting = m_settings->registerSetting({ "OverrideCommands", "OverrideLaunchCmd" }, false);
@ -128,8 +124,6 @@ BaseInstance::BaseInstance(SettingsObject* globalSettings, std::unique_ptr<Setti
m_settings->registerSetting("Profiler", "");
}
BaseInstance::~BaseInstance() {}
QString BaseInstance::getPreLaunchCommand()
{
return settings()->get("PreLaunchCommand").toString();
@ -210,7 +204,7 @@ void BaseInstance::addLinkedInstanceId(const QString& id)
bool BaseInstance::removeLinkedInstanceId(const QString& id)
{
auto linkedInstances = getLinkedInstances();
int numRemoved = linkedInstances.removeAll(id);
auto numRemoved = linkedInstances.removeAll(id);
setLinkedInstances(linkedInstances);
return numRemoved > 0;
}
@ -221,7 +215,7 @@ bool BaseInstance::isLinkedToInstanceId(const QString& id) const
return linkedInstances.contains(id);
}
void BaseInstance::iconUpdated(QString key)
void BaseInstance::iconUpdated(const QString& key)
{
if (iconKey() == key) {
emit propertiesChanged(this);
@ -260,8 +254,9 @@ bool BaseInstance::isRunning() const
void BaseInstance::setRunning(bool running)
{
if (running == m_isRunning)
if (running == m_isRunning) {
return;
}
m_isRunning = running;
@ -352,7 +347,7 @@ void BaseInstance::setLastLaunch(qint64 val)
emit propertiesChanged(this);
}
void BaseInstance::setNotes(QString val)
void BaseInstance::setNotes(const QString& val)
{
// FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("notes", val);
@ -363,7 +358,7 @@ QString BaseInstance::notes() const
return m_settings->get("notes").toString();
}
void BaseInstance::setIconKey(QString val)
void BaseInstance::setIconKey(const QString& val)
{
// FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("iconKey", val);
@ -375,7 +370,7 @@ QString BaseInstance::iconKey() const
return m_settings->get("iconKey").toString();
}
void BaseInstance::setName(QString val)
void BaseInstance::setName(const QString& val)
{
// FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("name", val);
@ -414,19 +409,23 @@ QList<ShortcutData> BaseInstance::shortcuts() const
auto data = m_settings->get("shortcuts").toString().toUtf8();
QJsonParseError parseError;
auto document = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError || !document.isArray())
if (parseError.error != QJsonParseError::NoError || !document.isArray()) {
return {};
}
QList<ShortcutData> results;
for (const auto& elem : document.array()) {
if (!elem.isObject())
if (!elem.isObject()) {
continue;
}
auto dict = elem.toObject();
if (!dict.contains("name") || !dict.contains("filePath") || !dict.contains("target"))
if (!dict.contains("name") || !dict.contains("filePath") || !dict.contains("target")) {
continue;
}
int value = dict["target"].toInt(-1);
if (!dict["name"].isString() || !dict["filePath"].isString() || value < 0 || value >= 3)
if (!dict["name"].isString() || !dict["filePath"].isString() || value < 0 || value >= 3) {
continue;
}
QString shortcutName = dict["name"].toString();
QString filePath = dict["filePath"].toString();
@ -465,7 +464,7 @@ void BaseInstance::updateRuntimeContext()
// NOOP
}
bool BaseInstance::isLegacy()
bool BaseInstance::isLegacy() const
{
return traits().contains("legacyLaunch") || traits().contains("alphaLaunch");
}

View file

@ -45,16 +45,12 @@
#include <QObject>
#include <QProcess>
#include <QSet>
#include <cstdint>
#include "QObjectPtr.h"
#include "settings/SettingsObject.h"
#include "BaseVersionList.h"
#include "MessageLevel.h"
#include "minecraft/auth/MinecraftAccount.h"
#include "settings/INIFile.h"
#include "net/Mode.h"
#include "RuntimeContext.h"
#include "minecraft/launch/MinecraftTarget.h"
@ -65,7 +61,7 @@ class LaunchTask;
class BaseInstance;
/// Shortcut saving target representations
enum class ShortcutTarget { Desktop, Applications, Other };
enum class ShortcutTarget : std::uint8_t { Desktop, Applications, Other };
/// Shortcut data representation
struct ShortcutData {
@ -93,14 +89,14 @@ class BaseInstance : public QObject {
BaseInstance(SettingsObject* globalSettings, std::unique_ptr<SettingsObject> settings, const QString& rootDir);
public: /* types */
enum class Status {
enum class Status : std::uint8_t {
Present,
Gone // either nuked or invalidated
};
public:
/// virtual destructor to make sure the destruction is COMPLETE
virtual ~BaseInstance();
~BaseInstance() override = default;
virtual void saveNow() = 0;
@ -136,7 +132,7 @@ class BaseInstance : public QObject {
virtual QString modsRoot() const = 0;
QString name() const;
void setName(QString val);
void setName(const QString& val);
/// Sync name and rename instance dir accordingly; returns true if successful
bool syncInstanceDirName(const QString& newRoot) const;
@ -150,10 +146,10 @@ class BaseInstance : public QObject {
QString windowTitle() const;
QString iconKey() const;
void setIconKey(QString val);
void setIconKey(const QString& val);
QString notes() const;
void setNotes(QString val);
void setNotes(const QString& val);
QString getPreLaunchCommand();
QString getPostExitCommand();
@ -277,7 +273,7 @@ class BaseInstance : public QObject {
bool removeLinkedInstanceId(const QString& id);
bool isLinkedToInstanceId(const QString& id) const;
bool isLegacy();
bool isLegacy() const;
protected:
void changeStatus(Status newStatus);
@ -302,7 +298,7 @@ class BaseInstance : public QObject {
void statusChanged(Status from, Status to);
protected slots:
void iconUpdated(QString key);
void iconUpdated(const QString& key);
protected: /* data */
QString m_rootDir;

View file

@ -41,8 +41,6 @@ set(CORE_SOURCES
PSaveFile.h
# Basic instance manipulation tasks (derived from InstanceTask)
InstanceCreationTask.h
InstanceCreationTask.cpp
InstanceCopyPrefs.h
InstanceCopyPrefs.cpp
InstanceCopyTask.h

View file

@ -1,86 +0,0 @@
#include "InstanceCreationTask.h"
#include <QDebug>
#include <QFile>
#include "Application.h"
#include "InstanceTask.h"
#include "minecraft/MinecraftLoadAndCheck.h"
#include "tasks/SequentialTask.h"
bool InstanceCreationTask::abort()
{
if (!canAbort()) {
return false;
}
m_abort = true;
return InstanceTask::abort();
}
void InstanceCreationTask::executeTask()
{
setAbortable(true);
if (updateInstance()) {
emitSucceeded();
return;
}
// When the user aborted in the update stage.
if (m_abort) {
emitAborted();
return;
}
auto instance = createInstance();
if (!instance) {
if (m_abort) {
return;
}
qWarning() << "Instance creation failed!";
if (!m_error_message.isEmpty()) {
qWarning() << "Reason:" << m_error_message;
emitFailed(tr("Error while creating new instance:\n%1").arg(m_error_message));
} else {
emitFailed(tr("Error while creating new instance."));
}
return;
}
// If this is set, it means we're updating an instance. So, we now need to remove the
// files scheduled to, and we'd better not let the user abort in the middle of it, since it'd
// put the instance in an invalid state.
if (shouldOverride()) {
bool deleteFailed = false;
setAbortable(false);
setStatus(tr("Removing old conflicting files..."));
qDebug() << "Removing old files";
for (const QString& path : m_filesToRemove) {
if (!QFile::exists(path)) {
continue;
}
qDebug() << "Removing" << path;
if (!QFile::remove(path)) {
qCritical() << "Could not remove" << path;
deleteFailed = true;
}
}
if (deleteFailed) {
emitFailed(tr("Failed to remove old conflicting files."));
return;
}
}
if (!m_abort) {
downloadFiles(instance.get());
}
}

View file

@ -1,46 +0,0 @@
#pragma once
#include "InstanceTask.h"
#include "minecraft/MinecraftInstance.h"
class InstanceCreationTask : public InstanceTask {
Q_OBJECT
public:
InstanceCreationTask() = default;
~InstanceCreationTask() override = default;
bool abort() override;
protected:
void executeTask() final;
/**
* Tries to update an already existing instance.
*
* This can be implemented by subclasses to provide a way of updating an already existing
* instance, according to that implementation's concept of 'identity' (i.e. instances that
* are updates / downgrades of one another).
*
* If this returns true, createInstance() will not run, so you should do all update steps in here.
* Otherwise, createInstance() is run as normal.
*/
virtual bool updateInstance() { return false; };
/**
* Creates a new instance.
*
* Returns the instance if it was created or nullptr otherwise.
*/
virtual std::unique_ptr<MinecraftInstance> createInstance() { return nullptr; }
QString getError() const { return m_error_message; }
protected:
void setError(const QString& message) { m_error_message = message; };
protected:
bool m_abort = false;
private:
QString m_error_message;
};

View file

@ -58,19 +58,22 @@
#include <QFileInfo>
#include <QtConcurrentRun>
#include <memory>
#include <utility>
InstanceImportTask::InstanceImportTask(const QUrl& sourceUrl, QWidget* parent, QMap<QString, QString>&& extra_info)
: m_sourceUrl(sourceUrl), m_extra_info(extra_info), m_parent(parent)
InstanceImportTask::InstanceImportTask(QUrl sourceUrl, QWidget* parent, QMap<QString, QString> extraInfo)
: m_sourceUrl(std::move(sourceUrl)), m_extra_info(std::move(extraInfo)), m_parent(parent)
{}
bool InstanceImportTask::abort()
{
if (!canAbort())
if (!canAbort()) {
return false;
}
bool wasAborted = false;
if (m_task)
if (m_task) {
wasAborted = m_task->abort();
}
return wasAborted;
}
@ -107,16 +110,20 @@ void InstanceImportTask::downloadFromUrl()
m_task.reset(filesNetJob);
filesNetJob->start();
}
namespace {
QString cleanPath(QString path)
QString cleanPath(const QString& path)
{
if (path == ".")
if (path == ".") {
return QString();
}
QString result = path;
if (result.startsWith("./"))
if (result.startsWith("./")) {
result = result.mid(2);
}
return result;
}
} // namespace
void InstanceImportTask::processZipPack()
{
@ -187,7 +194,7 @@ void InstanceImportTask::processZipPack()
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
progressStep->state = TaskStepState::Failed;
stepProgress(*progressStep);
emitFailed(reason);
emitFailed(std::move(reason));
});
connect(zipTask.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
@ -196,7 +203,7 @@ void InstanceImportTask::processZipPack()
stepProgress(*progressStep);
});
connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) {
progressStep->status = status;
progressStep->status = std::move(status);
stepProgress(*progressStep);
});
connect(zipTask.get(), &Task::warningLogged, this, [this](const QString& line) { m_Warnings.append(line); });
@ -251,16 +258,20 @@ void InstanceImportTask::extractFinished()
}
}
bool installIcon(QString root, QString instIconKey)
namespace {
bool installIcon(const QString& root, const QString& instIconKey)
{
auto importIconPath = IconUtils::findBestIconIn(root, instIconKey);
if (importIconPath.isNull() || !QFile::exists(importIconPath))
if (importIconPath.isNull() || !QFile::exists(importIconPath)) {
importIconPath = IconUtils::findBestIconIn(root, "icon.png");
if (importIconPath.isNull() || !QFile::exists(importIconPath))
}
if (importIconPath.isNull() || !QFile::exists(importIconPath)) {
importIconPath = IconUtils::findBestIconIn(FS::PathCombine(root, "overrides"), "icon.png");
}
if (!importIconPath.isNull() && QFile::exists(importIconPath)) {
// import icon
auto iconList = APPLICATION->icons();
auto* iconList = APPLICATION->icons();
if (iconList->iconFileExists(instIconKey)) {
iconList->deleteIcon(instIconKey);
}
@ -269,33 +280,35 @@ bool installIcon(QString root, QString instIconKey)
}
return false;
}
} // namespace
void InstanceImportTask::processFlame()
{
shared_qobject_ptr<FlameCreationTask> inst_creation_task = nullptr;
shared_qobject_ptr<FlameCreationTask> instCreationTask = nullptr;
if (!m_extra_info.isEmpty()) {
auto pack_id_it = m_extra_info.constFind("pack_id");
Q_ASSERT(pack_id_it != m_extra_info.constEnd());
auto pack_id = pack_id_it.value();
auto packIdIt = m_extra_info.constFind("pack_id");
Q_ASSERT(packIdIt != m_extra_info.constEnd());
const auto& packId = packIdIt.value();
auto pack_version_id_it = m_extra_info.constFind("pack_version_id");
Q_ASSERT(pack_version_id_it != m_extra_info.constEnd());
auto pack_version_id = pack_version_id_it.value();
auto packVersionIdIt = m_extra_info.constFind("pack_version_id");
Q_ASSERT(packVersionIdIt != m_extra_info.constEnd());
const auto& packVersionId = packVersionIdIt.value();
QString original_instance_id;
auto original_instance_id_it = m_extra_info.constFind("original_instance_id");
if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value();
QString originalInstanceId;
auto originalInstanceIdIt = m_extra_info.constFind("original_instance_id");
if (originalInstanceIdIt != m_extra_info.constEnd()) {
originalInstanceId = originalInstanceIdIt.value();
}
inst_creation_task =
makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
instCreationTask =
makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, packId, packVersionId, originalInstanceId);
} else {
// FIXME: Find a way to get IDs in directly imported ZIPs
inst_creation_task = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString());
instCreationTask = makeShared<FlameCreationTask>(m_stagingPath, m_globalSettings, m_parent, QString(), QString());
}
inst_creation_task->setName(modifiedName());
inst_creation_task->setOriginalName(originalName(), version());
instCreationTask->setName(modifiedName());
instCreationTask->setOriginalName(originalName(), version());
// if the icon was specified by user, use that. otherwise pull icon from the pack
if (m_instIcon == "default") {
auto iconKey = QString("Flame_%1_Icon").arg(name());
@ -304,30 +317,30 @@ void InstanceImportTask::processFlame()
m_instIcon = iconKey;
}
}
inst_creation_task->setIcon(m_instIcon);
inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
instCreationTask->setIcon(m_instIcon);
instCreationTask->setGroup(m_instGroup);
instCreationTask->setConfirmUpdate(shouldConfirmUpdate());
auto weak = inst_creation_task.toWeakRef();
connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
auto weak = instCreationTask.toWeakRef();
connect(instCreationTask.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded();
});
connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(instCreationTask.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(instCreationTask.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(instCreationTask.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(instCreationTask.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(instCreationTask.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(inst_creation_task.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(inst_creation_task.get(), &Task::abortButtonTextChanged, this, &Task::setAbortButtonText);
connect(instCreationTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(instCreationTask.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(instCreationTask.get(), &Task::abortButtonTextChanged, this, &Task::setAbortButtonText);
connect(inst_creation_task.get(), &Task::warningLogged, this, [this](const QString& line) { m_Warnings.append(line); });
connect(instCreationTask.get(), &Task::warningLogged, this, [this](const QString& line) { m_Warnings.append(line); });
m_task.reset(inst_creation_task);
m_task.reset(instCreationTask);
setAbortable(true);
m_task->start();
}
@ -366,37 +379,39 @@ void InstanceImportTask::processMultiMC()
void InstanceImportTask::processModrinth()
{
shared_qobject_ptr<ModrinthCreationTask> inst_creation_task = nullptr;
shared_qobject_ptr<ModrinthCreationTask> instCreationTask = nullptr;
if (!m_extra_info.isEmpty()) {
auto pack_id_it = m_extra_info.constFind("pack_id");
Q_ASSERT(pack_id_it != m_extra_info.constEnd());
auto pack_id = pack_id_it.value();
auto packIdIt = m_extra_info.constFind("pack_id");
Q_ASSERT(packIdIt != m_extra_info.constEnd());
const auto& packId = packIdIt.value();
QString pack_version_id;
auto pack_version_id_it = m_extra_info.constFind("pack_version_id");
if (pack_version_id_it != m_extra_info.constEnd())
pack_version_id = pack_version_id_it.value();
QString packVersionId;
auto packVersionIdIt = m_extra_info.constFind("pack_version_id");
if (packVersionIdIt != m_extra_info.constEnd()) {
packVersionId = packVersionIdIt.value();
}
QString original_instance_id;
auto original_instance_id_it = m_extra_info.constFind("original_instance_id");
if (original_instance_id_it != m_extra_info.constEnd())
original_instance_id = original_instance_id_it.value();
QString originalInstanceId;
auto originalInstanceIdIt = m_extra_info.constFind("original_instance_id");
if (originalInstanceIdIt != m_extra_info.constEnd()) {
originalInstanceId = originalInstanceIdIt.value();
}
inst_creation_task =
makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id, pack_version_id, original_instance_id);
instCreationTask =
makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, packId, packVersionId, originalInstanceId);
} else {
QString pack_id;
QString packId;
if (!m_sourceUrl.isEmpty()) {
static const QRegularExpression s_regex(R"(data\/([^\/]*)\/versions)");
pack_id = s_regex.match(m_sourceUrl.toString()).captured(1);
packId = s_regex.match(m_sourceUrl.toString()).captured(1);
}
// FIXME: Find a way to get the ID in directly imported ZIPs
inst_creation_task = makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, pack_id);
instCreationTask = makeShared<ModrinthCreationTask>(m_stagingPath, m_globalSettings, m_parent, packId);
}
inst_creation_task->setName(modifiedName());
inst_creation_task->setOriginalName(originalName(), version());
instCreationTask->setName(modifiedName());
instCreationTask->setOriginalName(originalName(), version());
// if the icon was specified by user, use that. otherwise pull icon from the pack
if (m_instIcon == "default") {
auto iconKey = QString("Modrinth_%1_Icon").arg(name());
@ -405,30 +420,30 @@ void InstanceImportTask::processModrinth()
m_instIcon = iconKey;
}
}
inst_creation_task->setIcon(m_instIcon);
inst_creation_task->setGroup(m_instGroup);
inst_creation_task->setConfirmUpdate(shouldConfirmUpdate());
instCreationTask->setIcon(m_instIcon);
instCreationTask->setGroup(m_instGroup);
instCreationTask->setConfirmUpdate(shouldConfirmUpdate());
auto weak = inst_creation_task.toWeakRef();
connect(inst_creation_task.get(), &Task::succeeded, this, [this, weak] {
auto weak = instCreationTask.toWeakRef();
connect(instCreationTask.get(), &Task::succeeded, this, [this, weak] {
if (auto sp = weak.lock()) {
setOverride(sp->shouldOverride(), sp->originalInstanceID());
}
emitSucceeded();
});
connect(inst_creation_task.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(inst_creation_task.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(inst_creation_task.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(inst_creation_task.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(inst_creation_task.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(instCreationTask.get(), &Task::failed, this, &InstanceImportTask::emitFailed);
connect(instCreationTask.get(), &Task::progress, this, &InstanceImportTask::setProgress);
connect(instCreationTask.get(), &Task::stepProgress, this, &InstanceImportTask::propagateStepProgress);
connect(instCreationTask.get(), &Task::status, this, &InstanceImportTask::setStatus);
connect(instCreationTask.get(), &Task::details, this, &InstanceImportTask::setDetails);
connect(inst_creation_task.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(inst_creation_task.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(inst_creation_task.get(), &Task::abortButtonTextChanged, this, &Task::setAbortButtonText);
connect(instCreationTask.get(), &Task::aborted, this, &InstanceImportTask::emitAborted);
connect(instCreationTask.get(), &Task::abortStatusChanged, this, &Task::setAbortable);
connect(instCreationTask.get(), &Task::abortButtonTextChanged, this, &Task::setAbortButtonText);
connect(inst_creation_task.get(), &Task::warningLogged, this, [this](const QString& line) { m_Warnings.append(line); });
connect(instCreationTask.get(), &Task::warningLogged, this, [this](const QString& line) { m_Warnings.append(line); });
m_task.reset(inst_creation_task);
m_task.reset(instCreationTask);
setAbortable(true);
m_task->start();
}

View file

@ -43,19 +43,20 @@
class InstanceImportTask : public InstanceTask {
Q_OBJECT
public:
explicit InstanceImportTask(const QUrl& sourceUrl, QWidget* parent = nullptr, QMap<QString, QString>&& extra_info = {});
virtual ~InstanceImportTask() = default;
explicit InstanceImportTask(QUrl sourceUrl, QWidget* parent = nullptr, QMap<QString, QString> extraInfo = {});
~InstanceImportTask() override = default;
bool abort() override;
protected:
//! Entry point for tasks.
virtual void executeTask() override;
void executeTask() override;
private:
void processMultiMC();
void processTechnic();
void processFlame();
void processModrinth();
void downloadFromUrl();
private slots:
void processZipPack();
@ -65,7 +66,7 @@ class InstanceImportTask : public InstanceTask {
QUrl m_sourceUrl;
QString m_archivePath;
Task::Ptr m_task;
enum class ModpackType {
enum class ModpackType : std::uint8_t {
Unknown,
MultiMC,
Technic,
@ -79,5 +80,4 @@ class InstanceImportTask : public InstanceTask {
// FIXME: nuke
QWidget* m_parent;
void downloadFromUrl();
};

View file

@ -47,6 +47,7 @@
#include <QStack>
#include <QTimer>
#include <QUuid>
#include <algorithm>
#include "BaseInstance.h"
#include "ExponentialSeries.h"
@ -62,7 +63,7 @@
#include <windows.h>
#endif
const static int GROUP_FILE_FORMAT_VERSION = 1;
const static int g_GROUP_FILE_FORMAT_VERSION = 1;
InstanceList::InstanceList(SettingsObject* settings, const QString& instDir, QObject* parent)
: QAbstractListModel(parent), m_globalSettings(settings)
@ -82,8 +83,6 @@ InstanceList::InstanceList(SettingsObject* settings, const QString& instDir, QOb
m_watcher->addPath(m_instDir);
}
InstanceList::~InstanceList() {}
Qt::DropActions InstanceList::supportedDragActions() const
{
return Qt::MoveAction;
@ -100,10 +99,7 @@ bool InstanceList::canDropMimeData(const QMimeData* data,
[[maybe_unused]] int column,
[[maybe_unused]] const QModelIndex& parent) const
{
if (data && data->hasFormat("application/x-instanceid")) {
return true;
}
return false;
return (data != nullptr) && data->hasFormat("application/x-instanceid");
}
bool InstanceList::dropMimeData(const QMimeData* data,
@ -112,10 +108,7 @@ bool InstanceList::dropMimeData(const QMimeData* data,
[[maybe_unused]] int column,
[[maybe_unused]] const QModelIndex& parent)
{
if (data && data->hasFormat("application/x-instanceid")) {
return true;
}
return false;
return (data != nullptr) && data->hasFormat("application/x-instanceid");
}
QStringList InstanceList::mimeTypes() const
@ -127,7 +120,7 @@ QStringList InstanceList::mimeTypes() const
QMimeData* InstanceList::mimeData(const QModelIndexList& indexes) const
{
auto mimeData = QAbstractListModel::mimeData(indexes);
auto* mimeData = QAbstractListModel::mimeData(indexes);
if (indexes.size() == 1) {
auto instanceId = data(indexes[0], InstanceIDRole).toString();
mimeData->setData("application/x-instanceid", instanceId.toUtf8());
@ -138,9 +131,10 @@ QMimeData* InstanceList::mimeData(const QModelIndexList& indexes) const
QStringList InstanceList::getLinkedInstancesById(const QString& id) const
{
QStringList linkedInstances;
for (auto& inst : m_instances) {
if (inst->isLinkedToInstanceId(id))
for (const auto& inst : m_instances) {
if (inst->isLinkedToInstanceId(id)) {
linkedInstances.append(inst->id());
}
}
return linkedInstances;
}
@ -154,8 +148,9 @@ int InstanceList::rowCount(const QModelIndex& parent) const
QModelIndex InstanceList::index(int row, int column, const QModelIndex& parent) const
{
Q_UNUSED(parent);
if (row < 0 || row >= count())
return QModelIndex();
if (row < 0 || row >= count()) {
return {};
}
return createIndex(row, column, m_instances.at(row).get());
}
@ -164,7 +159,7 @@ QVariant InstanceList::data(const QModelIndex& index, int role) const
if (!index.isValid()) {
return QVariant();
}
BaseInstance* pdata = static_cast<BaseInstance*>(index.internalPointer());
auto* pdata = static_cast<BaseInstance*>(index.internalPointer());
switch (role) {
case InstancePointerRole: {
QVariant v = QVariant::fromValue((void*)pdata);
@ -204,7 +199,7 @@ bool InstanceList::setData(const QModelIndex& index, const QVariant& value, int
if (role != Qt::EditRole) {
return false;
}
BaseInstance* pdata = static_cast<BaseInstance*>(index.internalPointer());
auto* pdata = static_cast<BaseInstance*>(index.internalPointer());
auto newName = value.toString();
if (pdata->name() == newName) {
return true;
@ -224,23 +219,24 @@ Qt::ItemFlags InstanceList::flags(const QModelIndex& index) const
GroupId InstanceList::getInstanceGroup(const InstanceId& id) const
{
auto inst = getInstanceById(id);
auto* inst = getInstanceById(id);
if (!inst) {
return GroupId();
return {};
}
auto iter = m_instanceGroupIndex.find(inst->id());
if (iter != m_instanceGroupIndex.end()) {
return *iter;
}
return GroupId();
return {};
}
void InstanceList::setInstanceGroup(const InstanceId& id, GroupId name)
{
if (name.isEmpty() && !name.isNull())
if (name.isEmpty() && !name.isNull()) {
name = QString();
}
auto inst = getInstanceById(id);
auto* inst = getInstanceById(id);
if (!inst) {
qDebug() << "Attempt to set a null instance's group";
return;
@ -287,19 +283,22 @@ void InstanceList::deleteGroup(const GroupId& name)
qDebug() << "Remove" << instID << "from group" << name;
removed = true;
auto idx = getInstIndex(instance.get());
if (idx >= 0)
if (idx >= 0) {
emit dataChanged(index(idx), index(idx), { GroupRole });
}
}
}
if (removed)
if (removed) {
saveGroupList();
}
}
void InstanceList::renameGroup(const QString& src, const QString& dst)
{
m_groupNameCache.remove(src);
if (m_collapsedGroups.remove(src))
if (m_collapsedGroups.remove(src)) {
m_collapsedGroups.insert(dst);
}
bool modified = false;
qDebug() << "Rename group" << src << "to" << dst;
@ -312,12 +311,14 @@ void InstanceList::renameGroup(const QString& src, const QString& dst)
qDebug() << "Set" << instID << "group to" << dst;
modified = true;
auto idx = getInstIndex(instance.get());
if (idx >= 0)
if (idx >= 0) {
emit dataChanged(index(idx), index(idx), { GroupRole });
}
}
}
if (modified)
if (modified) {
saveGroupList();
}
}
bool InstanceList::isGroupCollapsed(const QString& group)
@ -327,7 +328,7 @@ bool InstanceList::isGroupCollapsed(const QString& group)
bool InstanceList::trashInstance(const InstanceId& id)
{
auto inst = getInstanceById(id);
auto* inst = getInstanceById(id);
if (!inst) {
qWarning() << "Cannot trash instance" << id << ". No such instance is present (deleted externally?).";
return false;
@ -338,7 +339,7 @@ bool InstanceList::trashInstance(const InstanceId& id)
qDebug() << "Will trash instance" << id;
QString trashedLoc;
if (m_instanceGroupIndex.remove(id)) {
if (m_instanceGroupIndex.remove(id) != 0) {
decreaseGroupCount(cachedGroupId);
saveGroupList();
}
@ -422,7 +423,7 @@ bool InstanceList::undoTrashInstance()
void InstanceList::deleteInstance(const InstanceId& id)
{
auto inst = getInstanceById(id);
auto* inst = getInstanceById(id);
if (!inst) {
qWarning() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?).";
return;
@ -430,7 +431,7 @@ void InstanceList::deleteInstance(const InstanceId& id)
QString cachedGroupId = m_instanceGroupIndex[id];
if (m_instanceGroupIndex.remove(id)) {
if (m_instanceGroupIndex.remove(id) != 0) {
decreaseGroupCount(cachedGroupId);
saveGroupList();
}
@ -452,11 +453,12 @@ void InstanceList::deleteInstance(const InstanceId& id)
}
}
static QMap<InstanceId, InstanceLocator> getIdMapping(const std::vector<std::unique_ptr<BaseInstance>>& list)
namespace {
QMap<InstanceId, InstanceLocator> getIdMapping(const std::vector<std::unique_ptr<BaseInstance>>& list)
{
QMap<InstanceId, InstanceLocator> out;
int i = 0;
for (auto& item : list) {
for (const auto& item : list) {
auto id = item->id();
if (out.contains(id)) {
qWarning() << "Duplicate ID" << id << "in instance list";
@ -466,6 +468,7 @@ static QMap<InstanceId, InstanceLocator> getIdMapping(const std::vector<std::uni
}
return out;
}
} // namespace
QList<InstanceId> InstanceList::discoverInstances()
{
@ -475,8 +478,9 @@ QList<InstanceId> InstanceList::discoverInstances()
while (iter.hasNext()) {
QString subDir = iter.next();
QFileInfo dirInfo(subDir);
if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists())
if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists()) {
continue;
}
// if it is a symlink, ignore it if it goes to the instance folder
if (dirInfo.isSymLink()) {
QFileInfo targetInfo(dirInfo.symLinkTarget());
@ -490,7 +494,7 @@ QList<InstanceId> InstanceList::discoverInstances()
out.append(id);
qInfo() << "Found instance ID" << id;
}
instanceSet = QSet<QString>(out.begin(), out.end());
m_instanceSet = QSet<QString>(out.begin(), out.end());
m_instancesProbed = true;
return out;
}
@ -518,38 +522,38 @@ InstanceList::InstListError InstanceList::loadList()
// get the list of removed instances and sort it by their original index, from last to first
auto deadList = existingIds.values();
auto orderSortPredicate = [](const InstanceLocator& a, const InstanceLocator& b) -> bool { return a.second > b.second; };
std::sort(deadList.begin(), deadList.end(), orderSortPredicate);
std::ranges::sort(deadList, orderSortPredicate);
// remove the contiguous ranges of rows
int front_bookmark = -1;
int back_bookmark = -1;
int frontBookmark = -1;
int backBookmark = -1;
int currentItem = -1;
auto removeNow = [this, &front_bookmark, &back_bookmark, &currentItem]() {
beginRemoveRows(QModelIndex(), front_bookmark, back_bookmark);
m_instances.erase(m_instances.begin() + front_bookmark, m_instances.begin() + back_bookmark + 1);
auto removeNow = [this, &frontBookmark, &backBookmark, &currentItem]() {
beginRemoveRows(QModelIndex(), frontBookmark, backBookmark);
m_instances.erase(m_instances.begin() + frontBookmark, m_instances.begin() + backBookmark + 1);
endRemoveRows();
front_bookmark = -1;
back_bookmark = currentItem;
frontBookmark = -1;
backBookmark = currentItem;
};
for (auto& removedItem : deadList) {
auto instPtr = removedItem.first;
auto* instPtr = removedItem.first;
instPtr->invalidate();
currentItem = removedItem.second;
if (back_bookmark == -1) {
if (backBookmark == -1) {
// no bookmark yet
back_bookmark = currentItem;
} else if (currentItem == front_bookmark - 1) {
backBookmark = currentItem;
} else if (currentItem == frontBookmark - 1) {
// part of contiguous sequence, continue
} else {
// seam between previous and current item
removeNow();
}
front_bookmark = currentItem;
frontBookmark = currentItem;
}
if (back_bookmark != -1) {
if (backBookmark != -1) {
removeNow();
}
}
if (newList.size()) {
if (newList.size() != 0U) {
add(newList);
}
m_dirty = false;
@ -559,9 +563,9 @@ InstanceList::InstListError InstanceList::loadList()
void InstanceList::updateTotalPlayTime()
{
totalPlayTime = 0;
m_totalPlayTime = 0;
for (const auto& itr : m_instances) {
totalPlayTime += itr->totalTimePlayed();
m_totalPlayTime += itr->totalTimePlayed();
}
}
@ -607,11 +611,12 @@ void InstanceList::providerUpdated()
}
}
BaseInstance* InstanceList::getInstanceById(QString instId) const
BaseInstance* InstanceList::getInstanceById(const QString& instId) const
{
if (instId.isEmpty())
if (instId.isEmpty()) {
return nullptr;
for (auto& inst : m_instances) {
}
for (const auto& inst : m_instances) {
if (inst->id() == instId) {
return inst.get();
}
@ -619,14 +624,16 @@ BaseInstance* InstanceList::getInstanceById(QString instId) const
return nullptr;
}
BaseInstance* InstanceList::getInstanceByManagedName(const QString& managed_name) const
BaseInstance* InstanceList::getInstanceByManagedName(const QString& managedName) const
{
if (managed_name.isEmpty())
if (managedName.isEmpty()) {
return {};
}
for (auto& instance : m_instances) {
if (instance->getManagedPackName() == managed_name)
for (const auto& instance : m_instances) {
if (instance->getManagedPackName() == managedName) {
return instance.get();
}
}
return {};
@ -669,11 +676,11 @@ std::unique_ptr<BaseInstance> InstanceList::loadInstance(const InstanceId& id)
instanceSettings->registerSetting("InstanceType", "");
QString inst_type = instanceSettings->get("InstanceType").toString();
QString instType = instanceSettings->get("InstanceType").toString();
// NOTE: Some launcher versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a
// OneSix instance
if (inst_type == "OneSix" || inst_type.isEmpty()) {
if (instType == "OneSix" || instType.isEmpty()) {
inst.reset(new MinecraftInstance(m_globalSettings, std::move(instanceSettings), instanceRoot));
} else {
inst.reset(new NullInstance(m_globalSettings, std::move(instanceSettings), instanceRoot));
@ -681,24 +688,27 @@ std::unique_ptr<BaseInstance> InstanceList::loadInstance(const InstanceId& id)
qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot();
auto shortcut = inst->shortcuts();
if (!shortcut.isEmpty())
if (!shortcut.isEmpty()) {
qDebug() << "Loaded" << shortcut.size() << "shortcut(s) for instance" << inst->name();
}
return inst;
}
void InstanceList::increaseGroupCount(const QString& group)
{
if (group.isEmpty())
if (group.isEmpty()) {
return;
}
++m_groupNameCache[group];
}
void InstanceList::decreaseGroupCount(const QString& group)
{
if (group.isEmpty())
if (group.isEmpty()) {
return;
}
if (--m_groupNameCache[group] < 1) {
m_groupNameCache.remove(group);
@ -718,15 +728,16 @@ void InstanceList::saveGroupList()
QMap<QString, QSet<QString>> reverseGroupMap;
for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++) {
const QString& id = iter.key();
QString group = iter.value();
if (group.isEmpty())
const QString& group = iter.value();
if (group.isEmpty()) {
continue;
if (!instanceSet.contains(id)) {
}
if (!m_instanceSet.contains(id)) {
qDebug() << "Skipping saving missing instance" << id << "to groups list.";
continue;
}
if (!reverseGroupMap.count(group)) {
if (!reverseGroupMap.contains(group)) {
QSet<QString> set;
set.insert(id);
reverseGroupMap[group] = set;
@ -740,11 +751,11 @@ void InstanceList::saveGroupList()
QJsonObject groupsArr;
for (auto iter = reverseGroupMap.begin(); iter != reverseGroupMap.end(); iter++) {
auto list = iter.value();
auto name = iter.key();
const auto& name = iter.key();
QJsonObject groupObj;
QJsonArray instanceArr;
groupObj.insert("hidden", QJsonValue(m_collapsedGroups.contains(name)));
for (auto item : list) {
for (const auto& item : list) {
instanceArr.append(QJsonValue(item));
}
groupObj.insert("instances", instanceArr);
@ -773,8 +784,9 @@ void InstanceList::loadGroupList()
QString groupFileName = m_instDir + "/instgroups.json";
// if there's no group file, fail
if (!QFileInfo(groupFileName).exists())
if (!QFileInfo(groupFileName).exists()) {
return;
}
QByteArray jsonData;
try {
@ -804,8 +816,9 @@ void InstanceList::loadGroupList()
QJsonObject rootObj = jsonDoc.object();
// Make sure the format version matches, otherwise fail.
if (rootObj.value("formatVersion").toVariant().toInt() != GROUP_FILE_FORMAT_VERSION)
if (rootObj.value("formatVersion").toVariant().toInt() != g_GROUP_FILE_FORMAT_VERSION) {
return;
}
// Get the groups. if it's not an object, fail
if (!rootObj.value("groups").isObject()) {
@ -841,8 +854,9 @@ void InstanceList::loadGroupList()
}
auto hidden = groupObj.value("hidden").toBool(false);
if (hidden)
if (hidden) {
m_collapsedGroups.insert(groupName);
}
// Iterate through the list of instances in the group.
QJsonArray instancesArray = groupObj.value("instances").toArray();
@ -872,7 +886,7 @@ void InstanceList::instanceDirContentsChanged(const QString& path)
emit instancesChanged();
}
void InstanceList::on_InstFolderChanged([[maybe_unused]] const Setting& setting, QVariant value)
void InstanceList::on_InstFolderChanged([[maybe_unused]] const Setting& setting, const QVariant value)
{
QString newInstDir = QDir(value.toString()).canonicalPath();
if (newInstDir != m_instDir) {
@ -899,13 +913,16 @@ void InstanceList::on_GroupStateChanged(const QString& group, bool collapsed)
saveGroupList();
}
namespace {
class InstanceStaging : public Task {
Q_OBJECT
const unsigned minBackoff = 1;
const unsigned maxBackoff = 16;
public:
InstanceStaging(InstanceList* parent, InstanceTask* child, SettingsObject* settings) : m_parent(parent), backoff(minBackoff, maxBackoff)
InstanceStaging(InstanceList* parent, InstanceTask* child, SettingsObject* settings)
: m_parent(parent), m_backoff(minBackoff, maxBackoff)
{
m_stagingPath = parent->getStagedInstancePath();
@ -954,7 +971,7 @@ class InstanceStaging : public Task {
private slots:
void childSucceeded()
{
unsigned sleepTime = backoff();
unsigned sleepTime = m_backoff();
if (m_parent->commitStagedInstance(m_stagingPath, *m_child, m_child->group())) {
m_backoffTimer.stop();
emitSucceeded();
@ -990,11 +1007,12 @@ class InstanceStaging : public Task {
* Basically, it starts messing things up while the launcher is extracting/creating instances
* and causes that horrible failure that is NTFS to lock files in place because they are open.
*/
ExponentialSeries backoff;
ExponentialSeries m_backoff;
QString m_stagingPath;
std::unique_ptr<InstanceTask> m_child;
QTimer m_backoffTimer;
};
} // namespace
Task* InstanceList::wrapInstanceTask(InstanceTask* task)
{
@ -1009,15 +1027,17 @@ QString InstanceList::getStagedInstancePath()
int tries = 0;
do {
if (++tries > 256)
if (++tries > 256) {
return {};
}
const QString key = QUuid::createUuid().toString(QUuid::Id128).left(6);
result = FS::PathCombine(tempRoot, key);
} while (QFileInfo::exists(result));
if (!QDir::current().mkpath(result))
if (!QDir::current().mkpath(result)) {
return {};
}
#ifdef Q_OS_WIN32
SetFileAttributesA(tempRoot.toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
#endif
@ -1061,7 +1081,7 @@ bool InstanceList::commitStagedInstance(const QString& path, const InstanceTask&
increaseGroupCount(groupName);
}
instanceSet.insert(instID);
m_instanceSet.insert(instID);
emit instancesChanged();
emit instanceSelectRequest(instID);
@ -1074,7 +1094,7 @@ bool InstanceList::commitStagedInstance(const QString& path, const InstanceTask&
int InstanceList::getTotalPlayTime()
{
updateTotalPlayTime();
return totalPlayTime;
return m_totalPlayTime;
}
#include "InstanceList.moc"

View file

@ -41,6 +41,7 @@
#include <QPair>
#include <QSet>
#include <QStack>
#include <cstdint>
#include "BaseInstance.h"
@ -51,9 +52,9 @@ using InstanceId = QString;
using GroupId = QString;
using InstanceLocator = std::pair<BaseInstance*, int>;
enum class InstCreateError { NoCreateError = 0, NoSuchVersion, UnknownCreateError, InstExists, CantCreateDir };
enum class InstCreateError : std::uint8_t { NoCreateError = 0, NoSuchVersion, UnknownCreateError, InstExists, CantCreateDir };
enum class GroupsState { NotLoaded, Steady, Dirty };
enum class GroupsState : std::uint8_t { NotLoaded, Steady, Dirty };
struct TrashShortcutItem {
ShortcutData data;
@ -72,8 +73,8 @@ class InstanceList : public QAbstractListModel {
Q_OBJECT
public:
explicit InstanceList(SettingsObject* settings, const QString& instDir, QObject* parent = 0);
virtual ~InstanceList();
explicit InstanceList(SettingsObject* settings, const QString& instDir, QObject* parent = nullptr);
~InstanceList() override = default;
public:
QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const override;
@ -93,7 +94,7 @@ class InstanceList : public QAbstractListModel {
* NoError Indicates that no error occurred.
* UnknownError indicates that an unspecified error occurred.
*/
enum InstListError { NoError = 0, UnknownError };
enum InstListError : std::uint8_t { NoError = 0, UnknownError };
BaseInstance* at(int i) const { return m_instances.at(i).get(); }
@ -103,9 +104,9 @@ class InstanceList : public QAbstractListModel {
void saveNow();
/* O(n) */
BaseInstance* getInstanceById(QString id) const;
BaseInstance* getInstanceById(const QString& id) const;
/* O(n) */
BaseInstance* getInstanceByManagedName(const QString& managed_name) const;
BaseInstance* getInstanceByManagedName(const QString& managedName) const;
QModelIndex getInstanceIndexById(const QString& id) const;
QStringList getGroups();
bool isGroupCollapsed(const QString& groupName);
@ -183,7 +184,7 @@ class InstanceList : public QAbstractListModel {
private:
int m_watchLevel = 0;
int totalPlayTime = 0;
int m_totalPlayTime = 0;
bool m_dirty = false;
std::vector<std::unique_ptr<BaseInstance>> m_instances;
// id -> refs
@ -195,7 +196,7 @@ class InstanceList : public QAbstractListModel {
// FIXME: this is so inefficient that looking at it is almost painful.
QSet<QString> m_collapsedGroups;
QMap<InstanceId, GroupId> m_instanceGroupIndex;
QSet<InstanceId> instanceSet;
QSet<InstanceId> m_instanceSet;
bool m_groupsLoaded = false;
bool m_instancesProbed = false;

View file

@ -1,20 +1,20 @@
#include "PackManifest.h"
#include "Json.h"
static void loadFileV1(Flame::File& f, QJsonObject& file)
namespace {
void loadFileV1(Flame::File& f, QJsonObject& file)
{
f.projectId = Json::requireInteger(file, "projectID");
f.fileId = Json::requireInteger(file, "fileID");
f.required = file["required"].toBool(true);
}
static void loadModloaderV1(Flame::Modloader& m, QJsonObject& modLoader)
void loadModloaderV1(Flame::Modloader& m, QJsonObject& modLoader)
{
m.id = Json::requireString(modLoader, "id");
m.primary = modLoader["primary"].toBool();
}
static void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft)
void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft)
{
m.version = Json::requireString(minecraft, "version");
// extra libraries... apparently only used for a custom Minecraft launcher in the 1.2.5 FTB retro pack
@ -30,7 +30,7 @@ static void loadMinecraftV1(Flame::Minecraft& m, QJsonObject& minecraft)
m.recommendedRAM = minecraft["recommendedRam"].toInt();
}
static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest)
void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest)
{
auto mc = Json::requireObject(manifest, "minecraft");
@ -54,6 +54,7 @@ static void loadManifestV1(Flame::Manifest& pack, QJsonObject& manifest)
pack.isLoaded = true;
}
} // namespace
void Flame::loadManifest(Flame::Manifest& m, const QString& filepath)
{

View file

@ -46,7 +46,6 @@
#include <tasks/Task.h>
#include "IconPickerDialog.h"
#include "ProgressDialog.h"
#include "VersionSelectDialog.h"
#include <QDialogButtonBox>
@ -69,20 +68,19 @@
NewInstanceDialog::NewInstanceDialog(const QString& initialGroup,
const QString& url,
const QMap<QString, QString>& extra_info,
const QMap<QString, QString>& extraInfo,
QWidget* parent)
: QDialog(parent), ui(new Ui::NewInstanceDialog)
: QDialog(parent), ui(new Ui::NewInstanceDialog), m_instIconKey("default")
{
ui->setupUi(this);
setWindowIcon(QIcon::fromTheme("new"));
InstIconKey = "default";
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(m_instIconKey));
QStringList groups = APPLICATION->instances()->getGroups();
groups.prepend("");
int index = groups.indexOf(initialGroup);
auto index = groups.indexOf(initialGroup);
if (index == -1) {
index = 1;
groups.insert(index, initialGroup);
@ -102,35 +100,35 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup,
ui->verticalLayout->insertWidget(2, m_container);
m_container->addButtons(m_buttons);
connect(m_container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* selected) {
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(creationTask && !instName().isEmpty());
connect(m_container, &PageContainer::selectedPageChanged, this, [this](BasePage* /*previous*/, BasePage* /*selected*/) {
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(m_creationTask && !instName().isEmpty());
});
// Bonk Qt over its stupid head and make sure it understands which button is the default one...
// See: https://stackoverflow.com/questions/24556831/qbuttonbox-set-default-button
auto OkButton = m_buttons->button(QDialogButtonBox::Ok);
OkButton->setDefault(true);
OkButton->setAutoDefault(true);
OkButton->setText(tr("OK"));
connect(OkButton, &QPushButton::clicked, this, &NewInstanceDialog::accept);
auto* okButton = m_buttons->button(QDialogButtonBox::Ok);
okButton->setDefault(true);
okButton->setAutoDefault(true);
okButton->setText(tr("OK"));
connect(okButton, &QPushButton::clicked, this, &NewInstanceDialog::accept);
auto CancelButton = m_buttons->button(QDialogButtonBox::Cancel);
CancelButton->setDefault(false);
CancelButton->setAutoDefault(false);
CancelButton->setText(tr("Cancel"));
connect(CancelButton, &QPushButton::clicked, this, &NewInstanceDialog::reject);
auto* cancelButton = m_buttons->button(QDialogButtonBox::Cancel);
cancelButton->setDefault(false);
cancelButton->setAutoDefault(false);
cancelButton->setText(tr("Cancel"));
connect(cancelButton, &QPushButton::clicked, this, &NewInstanceDialog::reject);
auto HelpButton = m_buttons->button(QDialogButtonBox::Help);
HelpButton->setDefault(false);
HelpButton->setAutoDefault(false);
HelpButton->setText(tr("Help"));
connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help);
auto* helpButton = m_buttons->button(QDialogButtonBox::Help);
helpButton->setDefault(false);
helpButton->setAutoDefault(false);
helpButton->setText(tr("Help"));
connect(helpButton, &QPushButton::clicked, m_container, &PageContainer::help);
if (!url.isEmpty()) {
QUrl actualUrl(url);
m_container->selectPage("import");
importPage->setUrl(url);
importPage->setExtraInfo(extra_info);
m_importPage->setUrl(url);
m_importPage->setExtraInfo(extraInfo);
}
updateDialogState();
@ -138,7 +136,7 @@ NewInstanceDialog::NewInstanceDialog(const QString& initialGroup,
if (APPLICATION->settings()->get("NewInstanceGeometry").isValid()) {
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("NewInstanceGeometry").toString().toUtf8()));
} else {
auto screen = parent->screen();
auto* screen = parent->screen();
auto geometry = screen->availableSize();
resize(width(), qMin(geometry.height() - 50, 710));
}
@ -171,13 +169,14 @@ QList<BasePage*> NewInstanceDialog::getPages()
{
QList<BasePage*> pages;
importPage = new ImportPage(this);
m_importPage = new ImportPage(this);
pages.append(new CustomPage(this));
pages.append(importPage);
pages.append(m_importPage);
pages.append(new AtlPage(this));
if (APPLICATION->capabilities() & Application::SupportsFlame)
if (APPLICATION->capabilities() & Application::SupportsFlame) {
pages.append(new FlamePage(this));
}
pages.append(new FtbPage(this));
pages.append(new LegacyFTB::Page(this));
pages.append(new FTBImportAPP::ImportFTBPage(this));
@ -199,41 +198,41 @@ NewInstanceDialog::~NewInstanceDialog()
void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task)
{
creationTask.reset(task);
m_creationTask.reset(task);
ui->instNameTextBox->setPlaceholderText(name);
importVersion.clear();
m_importVersion.clear();
if (!task) {
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
importIcon = false;
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(m_instIconKey));
m_importIcon = false;
}
auto allowOK = task && !instName().isEmpty();
auto allowOK = (task != nullptr) && !instName().isEmpty();
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, InstanceTask* task)
{
creationTask.reset(task);
m_creationTask.reset(task);
ui->instNameTextBox->setPlaceholderText(name);
importVersion = std::move(version);
m_importVersion = std::move(version);
if (!task) {
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
importIcon = false;
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(m_instIconKey));
m_importIcon = false;
}
auto allowOK = task && !instName().isEmpty();
auto allowOK = (task != nullptr) && !instName().isEmpty();
m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
}
void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QString& name)
{
importIcon = true;
importIconPath = path;
importIconName = name;
m_importIcon = true;
m_importIconPath = path;
m_importIconName = name;
// Hmm, for some reason they can be to small
ui->iconButton->setIcon(QIcon(path));
@ -241,21 +240,22 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QStr
void NewInstanceDialog::setSuggestedIcon(const QString& key)
{
if (key == "default")
if (key == "default") {
return;
}
auto icon = APPLICATION->icons()->getIcon(key);
importIcon = false;
m_importIcon = false;
ui->iconButton->setIcon(icon);
}
InstanceTask* NewInstanceDialog::extractTask()
{
InstanceTask* extracted = creationTask.release();
InstanceTask* extracted = m_creationTask.release();
extracted->setName(ui->instNameTextBox->text().trimmed());
extracted->setOriginalName(ui->instNameTextBox->placeholderText().trimmed(), importVersion);
extracted->setOriginalName(ui->instNameTextBox->placeholderText().trimmed(), m_importVersion);
extracted->setGroup(instGroup());
extracted->setIcon(iconKey());
@ -264,21 +264,21 @@ InstanceTask* NewInstanceDialog::extractTask()
void NewInstanceDialog::updateDialogState()
{
auto allowOK = creationTask && !instName().isEmpty();
auto OkButton = m_buttons->button(QDialogButtonBox::Ok);
if (OkButton->isEnabled() != allowOK) {
OkButton->setEnabled(allowOK);
auto allowOK = m_creationTask && !instName().isEmpty();
auto* okButton = m_buttons->button(QDialogButtonBox::Ok);
if (okButton->isEnabled() != allowOK) {
okButton->setEnabled(allowOK);
}
}
QString NewInstanceDialog::instName() const
{
auto result = ui->instNameTextBox->text().trimmed();
if (result.size()) {
if (result.size() != 0) {
return result;
}
result = ui->instNameTextBox->placeholderText().trimmed();
if (result.size()) {
if (result.size() != 0) {
return result;
}
return QString();
@ -290,19 +290,19 @@ QString NewInstanceDialog::instGroup() const
}
QString NewInstanceDialog::iconKey() const
{
return InstIconKey;
return m_instIconKey;
}
void NewInstanceDialog::on_iconButton_clicked()
{
importIconNow(); // so the user can switch back
IconPickerDialog dlg(this);
dlg.execWithSelection(InstIconKey);
dlg.execWithSelection(m_instIconKey);
if (dlg.result() == QDialog::Accepted) {
InstIconKey = dlg.selectedIconKey;
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
importIcon = false;
m_instIconKey = dlg.selectedIconKey;
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(m_instIconKey));
m_importIcon = false;
}
}
@ -313,22 +313,22 @@ void NewInstanceDialog::on_instNameTextBox_textChanged([[maybe_unused]] const QS
void NewInstanceDialog::importIconNow()
{
if (importIcon) {
APPLICATION->icons()->installIcon(importIconPath, importIconName);
InstIconKey = importIconName.mid(0, importIconName.lastIndexOf('.'));
importIcon = false;
if (m_importIcon) {
APPLICATION->icons()->installIcon(m_importIconPath, m_importIconName);
m_instIconKey = m_importIconName.mid(0, m_importIconName.lastIndexOf('.'));
m_importIcon = false;
}
APPLICATION->settings()->set("NewInstanceGeometry", QString::fromUtf8(saveGeometry().toBase64()));
}
void NewInstanceDialog::selectedPageChanged(BasePage* previous, BasePage* selected)
{
auto prevPage = dynamic_cast<ModpackProviderBasePage*>(previous);
auto* prevPage = dynamic_cast<ModpackProviderBasePage*>(previous);
if (prevPage) {
m_searchTerm = prevPage->getSerachTerm();
}
auto nextPage = dynamic_cast<ModpackProviderBasePage*>(selected);
auto* nextPage = dynamic_cast<ModpackProviderBasePage*>(selected);
if (nextPage) {
nextPage->setSearchTerm(m_searchTerm);
}

View file

@ -55,9 +55,9 @@ class NewInstanceDialog : public QDialog, public BasePageProvider {
public:
explicit NewInstanceDialog(const QString& initialGroup,
const QString& url = QString(),
const QMap<QString, QString>& extra_info = {},
QWidget* parent = 0);
~NewInstanceDialog();
const QMap<QString, QString>& extraInfo = {},
QWidget* parent = nullptr);
~NewInstanceDialog() override;
void updateDialogState();
@ -84,22 +84,23 @@ class NewInstanceDialog : public QDialog, public BasePageProvider {
void on_instNameTextBox_textChanged(const QString& arg1);
void selectedPageChanged(BasePage* previous, BasePage* selected);
private:
void importIconNow();
private:
Ui::NewInstanceDialog* ui = nullptr;
PageContainer* m_container = nullptr;
QDialogButtonBox* m_buttons = nullptr;
QString InstIconKey;
ImportPage* importPage = nullptr;
std::unique_ptr<InstanceTask> creationTask;
QString m_instIconKey;
ImportPage* m_importPage = nullptr;
std::unique_ptr<InstanceTask> m_creationTask;
bool importIcon = false;
QString importIconPath;
QString importIconName;
bool m_importIcon = false;
QString m_importIconPath;
QString m_importIconName;
QString importVersion;
QString m_importVersion;
QString m_searchTerm;
void importIconNow();
};

View file

@ -17,11 +17,9 @@
#include <memory>
#include "Application.h"
#include "BuildConfig.h"
#include "InstanceImportTask.h"
#include "InstanceList.h"
#include "InstanceTask.h"
#include "Json.h"
#include "Markdown.h"
#include "StringUtils.h"
@ -29,11 +27,10 @@
#include "ui/dialogs/CustomMessageBox.h"
#include "ui/dialogs/ProgressDialog.h"
#include "net/ApiDownload.h"
/** This is just to override the combo box popup behavior so that the combo box doesn't take the whole screen.
* ... thanks Qt.
*/
namespace {
class NoBigComboBoxStyle : public QProxyStyle {
Q_OBJECT
@ -41,8 +38,9 @@ class NoBigComboBoxStyle : public QProxyStyle {
// clang-format off
int styleHint(QStyle::StyleHint hint, const QStyleOption* option = nullptr, const QWidget* widget = nullptr, QStyleHintReturn* returnData = nullptr) const override
{
if (hint == QStyle::SH_ComboBox_Popup)
return false;
if (hint == QStyle::SH_ComboBox_Popup) {
return 0;
}
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
@ -58,39 +56,42 @@ class NoBigComboBoxStyle : public QProxyStyle {
public:
static NoBigComboBoxStyle* getInstance(QStyle* style)
{
static QHash<QStyle*, NoBigComboBoxStyle*> s_singleton_instances_ = {};
static std::mutex s_singleton_instances_mutex_;
static QHash<QStyle*, NoBigComboBoxStyle*> s_singleton_instances = {};
static std::mutex s_singleton_instances_mutex;
std::lock_guard<std::mutex> lock(s_singleton_instances_mutex_);
auto inst_iter = s_singleton_instances_.constFind(style);
std::lock_guard<std::mutex> lock(s_singleton_instances_mutex);
auto instIter = s_singleton_instances.constFind(style);
NoBigComboBoxStyle* inst = nullptr;
if (inst_iter == s_singleton_instances_.constEnd() || *inst_iter == nullptr) {
if (instIter == s_singleton_instances.constEnd() || *instIter == nullptr) {
inst = new NoBigComboBoxStyle(style);
inst->setParent(APPLICATION);
s_singleton_instances_.insert(style, inst);
s_singleton_instances.insert(style, inst);
qDebug() << "QProxyStyle NoBigComboBox created for" << style->objectName() << style;
} else {
inst = *inst_iter;
inst = *instIter;
}
return inst;
}
private:
NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {}
explicit NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {}
};
} // namespace
ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent)
ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, const QString& type, QWidget* parent)
{
if (type == "modrinth")
if (type == "modrinth") {
return new ModrinthManagedPackPage(inst, nullptr, parent);
if (type == "flame" && (APPLICATION->capabilities() & Application::SupportsFlame))
}
if (type == "flame" && ((APPLICATION->capabilities() & Application::SupportsFlame) != 0U)) {
return new FlameManagedPackPage(inst, nullptr, parent);
}
return new GenericManagedPackPage(inst, nullptr, parent);
}
ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent)
: QWidget(parent), m_instance_window(instance_window), ui(new Ui::ManagedPackPage), m_inst(inst)
ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent)
: QWidget(parent), m_instanceWindow(instanceWindow), ui(new Ui::ManagedPackPage), m_inst(inst)
{
Q_ASSERT(inst);
@ -99,7 +100,7 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi
// NOTE: GTK2 themes crash with the proxy style.
// This seems like an upstream bug, so there's not much else that can be done.
if (!QStyleFactory::keys().contains("gtk2")) {
auto comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style());
auto* comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style());
ui->versionsComboBox->setStyle(comboStyle);
}
@ -115,21 +116,22 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi
openedImpl();
});
connect(ui->changelogTextBrowser, &QTextBrowser::anchorClicked, this, [](const QUrl url) {
connect(ui->changelogTextBrowser, &QTextBrowser::anchorClicked, this, [](const QUrl& url) {
if (url.scheme().isEmpty()) {
auto querry =
QUrlQuery(url.query()).queryItemValue("remoteUrl", QUrl::FullyDecoded); // curseforge workaround for linkout?remoteUrl=
auto decoded = QUrl::fromPercentEncoding(querry.toUtf8());
auto newUrl = QUrl(decoded);
if (newUrl.isValid() && (newUrl.scheme() == "http" || newUrl.scheme() == "https"))
if (newUrl.isValid() && (newUrl.scheme() == "http" || newUrl.scheme() == "https")) {
QDesktopServices ::openUrl(newUrl);
}
return;
}
QDesktopServices::openUrl(url);
});
connect(ui->urlLine, &QLineEdit::textChanged, this,
[this](QString text) { m_inst->settings()->set("ManagedPackURL", text.trimmed()); });
[this](const QString& text) { m_inst->settings()->set("ManagedPackURL", text.trimmed()); });
}
ManagedPackPage::~ManagedPackPage()
@ -170,10 +172,12 @@ void ManagedPackPage::openedImpl()
QString ManagedPackPage::displayName() const
{
auto type = m_inst->getManagedPackType();
if (type.isEmpty())
if (type.isEmpty()) {
return {};
if (type == "flame")
}
if (type == "flame") {
type = "CurseForge";
}
return type.replace(0, 1, type[0].toUpper());
}
@ -201,26 +205,26 @@ bool ManagedPackPage::runUpdateTask(InstanceTask* task)
{
Q_ASSERT(task);
unique_qobject_ptr<Task> wrapped_task(APPLICATION->instances()->wrapInstanceTask(task));
unique_qobject_ptr<Task> wrappedTask(APPLICATION->instances()->wrapInstanceTask(task));
connect(wrapped_task.get(), &Task::failed,
connect(wrappedTask.get(), &Task::failed,
[this](const QString& reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
connect(wrapped_task.get(), &Task::succeeded, [this, task]() {
connect(wrappedTask.get(), &Task::succeeded, [this, task]() {
QStringList warnings = task->warnings();
if (warnings.count()) {
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
}
});
connect(wrapped_task.get(), &Task::aborted, [this] {
connect(wrappedTask.get(), &Task::aborted, [this] {
CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information)
->show();
});
ProgressDialog loadDialog(this);
loadDialog.setSkipButton(true, tr("Abort"));
loadDialog.execWithTask(wrapped_task.get());
loadDialog.execWithTask(wrappedTask.get());
return wrapped_task->wasSuccessful();
return wrappedTask->wasSuccessful();
}
void ManagedPackPage::suggestVersion()
@ -247,8 +251,8 @@ void ManagedPackPage::setFailState()
ui->reloadButton->setVisible(true);
}
ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent)
: ManagedPackPage(inst, instance_window, parent)
ModrinthManagedPackPage::ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent)
: ManagedPackPage(inst, instanceWindow, parent)
{
Q_ASSERT(inst->isManagedPack());
connect(ui->versionsComboBox, &QComboBox::currentIndexChanged, this, &ModrinthManagedPackPage::suggestVersion);
@ -266,8 +270,8 @@ void ModrinthManagedPackPage::parseManagedPack()
return;
}
if (m_fetch_job && m_fetch_job->isRunning()) {
m_fetch_job->abort();
if (m_fetchJob && m_fetchJob->isRunning()) {
m_fetchJob->abort();
}
ResourceAPI::Callback<QVector<ModPlatform::IndexedVersion>> callbacks{};
@ -301,16 +305,16 @@ void ModrinthManagedPackPage::parseManagedPack()
};
callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); };
callbacks.on_abort = [this]() { setFailState(); };
m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
.mcVersions = {},
.loaders = {},
.resourceType = ModPlatform::ResourceType::Modpack,
.includeChangelog = true },
std::move(callbacks));
m_fetchJob = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
.mcVersions = {},
.loaders = {},
.resourceType = ModPlatform::ResourceType::Modpack,
.includeChangelog = true },
std::move(callbacks));
ui->changelogTextBrowser->setText(tr("Fetching changelogs..."));
m_fetch_job->start();
m_fetchJob->start();
}
QString ModrinthManagedPackPage::url() const
@ -335,12 +339,13 @@ void ModrinthManagedPackPage::suggestVersion()
/// @brief Called when the update task has completed.
/// Internally handles the closing of the instance window if the update was successful and shows a message box.
/// @param did_succeed Whether the update task was successful.
void ManagedPackPage::onUpdateTaskCompleted(bool did_succeed) const
void ManagedPackPage::onUpdateTaskCompleted(bool didSucceed) const
{
// Close the window if the update was successful
if (did_succeed) {
if (m_instance_window != nullptr)
m_instance_window->close();
if (didSucceed) {
if (m_instanceWindow != nullptr) {
m_instanceWindow->close();
}
CustomMessageBox::selectable(nullptr, tr("Update Successful"),
tr("The instance updated to pack version %1 successfully.").arg(m_inst->getManagedPackVersionName()),
@ -376,15 +381,16 @@ void ModrinthManagedPackPage::update()
void ModrinthManagedPackPage::updateFromFile()
{
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("Modrinth pack") + " (*.mrpack *.zip)");
if (output.isEmpty())
if (output.isEmpty()) {
return;
}
updatePack(output);
}
// FLAME
FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent)
: ManagedPackPage(inst, instance_window, parent)
FlameManagedPackPage::FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent)
: ManagedPackPage(inst, instanceWindow, parent)
{
Q_ASSERT(inst->isManagedPack());
connect(ui->versionsComboBox, &QComboBox::currentIndexChanged, this, &FlameManagedPackPage::suggestVersion);
@ -419,8 +425,8 @@ void FlameManagedPackPage::parseManagedPack()
return;
}
if (m_fetch_job && m_fetch_job->isRunning()) {
m_fetch_job->abort();
if (m_fetchJob && m_fetchJob->isRunning()) {
m_fetchJob->abort();
}
QString id = m_inst->getManagedPackID();
@ -454,14 +460,14 @@ void FlameManagedPackPage::parseManagedPack()
};
callbacks.on_fail = [this](const QString& /*reason*/, int) { setFailState(); };
callbacks.on_abort = [this]() { setFailState(); };
m_fetch_job = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
.mcVersions = {},
.loaders = {},
.resourceType = ModPlatform::ResourceType::Modpack,
.includeChangelog = true },
std::move(callbacks));
m_fetchJob = m_api.getProjectVersions({ .pack = std::make_shared<ModPlatform::IndexedPack>(m_pack),
.mcVersions = {},
.loaders = {},
.resourceType = ModPlatform::ResourceType::Modpack,
.includeChangelog = true },
std::move(callbacks));
m_fetch_job->start();
m_fetchJob->start();
}
QString FlameManagedPackPage::url() const
@ -505,21 +511,22 @@ void FlameManagedPackPage::update()
void FlameManagedPackPage::updateFromFile()
{
auto output = QFileDialog::getOpenFileUrl(this, tr("Choose update file"), QDir::homePath(), tr("CurseForge pack") + " (*.zip)");
if (output.isEmpty())
if (output.isEmpty()) {
return;
}
updatePack(output);
}
void ManagedPackPage::updatePack(const QUrl& url, QString versionID, QString versionName)
void ManagedPackPage::updatePack(const QUrl& url, const QString& versionID, const QString& versionName)
{
QMap<QString, QString> extra_info;
QMap<QString, QString> extraInfo;
// NOTE: Don't use 'm_pack.id' here, since we didn't completely parse all the metadata for the pack, including this field.
extra_info.insert("pack_id", m_inst->getManagedPackID());
extra_info.insert("pack_version_id", versionID);
extra_info.insert("original_instance_id", m_inst->id());
extraInfo.insert("pack_id", m_inst->getManagedPackID());
extraInfo.insert("pack_version_id", versionID);
extraInfo.insert("original_instance_id", m_inst->id());
auto extracted = new InstanceImportTask(url, this, std::move(extra_info));
auto* extracted = new InstanceImportTask(url, this, std::move(extraInfo));
if (versionName.isEmpty()) {
extracted->setName(m_inst->name());
@ -532,8 +539,8 @@ void ManagedPackPage::updatePack(const QUrl& url, QString versionID, QString ver
extracted->setConfirmUpdate(false);
// Run our task then handle the result
auto did_succeed = runUpdateTask(extracted);
onUpdateTaskCompleted(did_succeed);
auto didSucceed = runUpdateTask(extracted);
onUpdateTaskCompleted(didSucceed);
}
#include "ManagedPackPage.moc"

View file

@ -11,8 +11,6 @@
#include "modplatform/flame/FlameAPI.h"
#include "net/NetJob.h"
#include "ui/pages/BasePage.h"
#include <QWidget>
@ -28,12 +26,12 @@ class ManagedPackPage : public QWidget, public BasePage {
Q_OBJECT
public:
inline static ManagedPackPage* createPage(BaseInstance* inst, QWidget* parent = nullptr)
static ManagedPackPage* createPage(BaseInstance* inst, QWidget* parent = nullptr)
{
return ManagedPackPage::createPage(inst, inst->getManagedPackType(), parent);
}
static ManagedPackPage* createPage(BaseInstance* inst, QString type, QWidget* parent = nullptr);
static ManagedPackPage* createPage(BaseInstance* inst, const QString& type, QWidget* parent = nullptr);
~ManagedPackPage() override;
QString displayName() const override;
@ -56,7 +54,7 @@ class ManagedPackPage : public QWidget, public BasePage {
*/
virtual QString url() const { return {}; };
void setInstanceWindow(InstanceWindow* window) { m_instance_window = window; }
void setInstanceWindow(InstanceWindow* window) { m_instanceWindow = window; }
public slots:
/** Gets the current version selection and update the UI, including the update button and the changelog.
@ -77,7 +75,7 @@ class ManagedPackPage : public QWidget, public BasePage {
void setFailState();
protected:
ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr);
ManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent = nullptr);
/** Run the InstanceTask, with a progress dialog and all.
* Similar to MainWindow::instanceFromInstanceTask
@ -86,17 +84,17 @@ class ManagedPackPage : public QWidget, public BasePage {
*/
bool runUpdateTask(InstanceTask*);
void updatePack(const QUrl& url, QString versionID = {}, QString versionName = {});
void updatePack(const QUrl& url, const QString& versionID = {}, const QString& versionName = {});
void onUpdateTaskCompleted(bool didSucceed) const;
protected:
InstanceWindow* m_instance_window = nullptr;
InstanceWindow* m_instanceWindow = nullptr;
Ui::ManagedPackPage* ui;
BaseInstance* m_inst;
bool m_loaded = false;
void onUpdateTaskCompleted(bool did_succeed) const;
};
/** Simple page for when we aren't a managed pack. */
@ -104,8 +102,8 @@ class GenericManagedPackPage final : public ManagedPackPage {
Q_OBJECT
public:
GenericManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr)
: ManagedPackPage(inst, instance_window, parent)
GenericManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent = nullptr)
: ManagedPackPage(inst, instanceWindow, parent)
{}
~GenericManagedPackPage() override = default;
@ -117,7 +115,7 @@ class ModrinthManagedPackPage final : public ManagedPackPage {
Q_OBJECT
public:
ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr);
ModrinthManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent = nullptr);
~ModrinthManagedPackPage() override = default;
void parseManagedPack() override;
@ -131,7 +129,7 @@ class ModrinthManagedPackPage final : public ManagedPackPage {
void updateFromFile() override;
private:
Task::Ptr m_fetch_job = nullptr;
Task::Ptr m_fetchJob = nullptr;
ModPlatform::IndexedPack m_pack;
ModrinthAPI m_api;
@ -141,7 +139,7 @@ class FlameManagedPackPage final : public ManagedPackPage {
Q_OBJECT
public:
FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instance_window, QWidget* parent = nullptr);
FlameManagedPackPage(BaseInstance* inst, InstanceWindow* instanceWindow, QWidget* parent = nullptr);
~FlameManagedPackPage() override = default;
void parseManagedPack() override;
@ -155,7 +153,7 @@ class FlameManagedPackPage final : public ManagedPackPage {
void updateFromFile() override;
private:
Task::Ptr m_fetch_job = nullptr;
Task::Ptr m_fetchJob = nullptr;
ModPlatform::IndexedPack m_pack;
FlameAPI m_api;