mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-07-04 04:16:57 +03:00
chore(clang-tidy): fix clang tidy warnings
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
9f175a4a4d
commit
21b74dd6d1
14 changed files with 411 additions and 507 deletions
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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, ¤tItem]() {
|
||||
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, ¤tItem]() {
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue