Implement persistence by storing shortcut in settings

Signed-off-by: Yihe Li <winmikedows@hotmail.com>
This commit is contained in:
Yihe Li 2025-06-01 14:16:40 +08:00
parent d3f337d6ef
commit 7c3a810d3d
No known key found for this signature in database
4 changed files with 52 additions and 15 deletions

View file

@ -69,6 +69,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("lastTimePlayed", 0); m_settings->registerSetting("lastTimePlayed", 0);
m_settings->registerSetting("linkedInstances", "[]"); m_settings->registerSetting("linkedInstances", "[]");
m_settings->registerSetting("shortcuts", QVariant::fromValue(QList<ShortcutData>{}));
// Game time override // Game time override
auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false); auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
@ -400,13 +401,21 @@ bool BaseInstance::syncInstanceDirName(const QString& newRoot) const
void BaseInstance::registerShortcut(const ShortcutData& data) void BaseInstance::registerShortcut(const ShortcutData& data)
{ {
m_shortcuts.append(data); auto currentShortcuts = shortcuts();
currentShortcuts.append(data);
qDebug() << "Registering shortcut for instance" << id() << "with name" << data.name << "and path" << data.filePath; qDebug() << "Registering shortcut for instance" << id() << "with name" << data.name << "and path" << data.filePath;
setShortcuts(currentShortcuts);
} }
QList<ShortcutData>& BaseInstance::getShortcuts() void BaseInstance::setShortcuts(const QList<ShortcutData>& shortcuts)
{ {
return m_shortcuts; // FIXME: if no change, do not set. setting involves saving a file.
m_settings->set("shortcuts", QVariant::fromValue(shortcuts));
}
QList<ShortcutData> BaseInstance::shortcuts() const
{
return m_settings->get("shortcuts").value<QList<ShortcutData>>();
} }
QString BaseInstance::name() const QString BaseInstance::name() const

View file

@ -38,6 +38,7 @@
#pragma once #pragma once
#include <cassert> #include <cassert>
#include <QDataStream>
#include <QDateTime> #include <QDateTime>
#include <QList> #include <QList>
#include <QMenu> #include <QMenu>
@ -74,7 +75,18 @@ enum class ShortcutTarget { Desktop, Applications, Other };
struct ShortcutData { struct ShortcutData {
QString name; QString name;
QString filePath; QString filePath;
ShortcutTarget target; ShortcutTarget target = ShortcutTarget::Other;
friend QDataStream& operator<<(QDataStream& out, const ShortcutData& data)
{
out << data.name << data.filePath << data.target;
return out;
}
friend QDataStream& operator>>(QDataStream& in, ShortcutData& data)
{
in >> data.name >> data.filePath >> data.target;
return in;
}
}; };
/*! /*!
@ -142,7 +154,8 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
/// Register a created shortcut /// Register a created shortcut
void registerShortcut(const ShortcutData& data); void registerShortcut(const ShortcutData& data);
QList<ShortcutData>& getShortcuts(); QList<ShortcutData> shortcuts() const;
void setShortcuts(const QList<ShortcutData>& shortcuts);
/// Value used for instance window titles /// Value used for instance window titles
QString windowTitle() const; QString windowTitle() const;
@ -323,10 +336,9 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
SettingsObjectWeakPtr m_global_settings; SettingsObjectWeakPtr m_global_settings;
bool m_specific_settings_loaded = false; bool m_specific_settings_loaded = false;
QList<ShortcutData> m_shortcuts;
}; };
Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>) Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>)
Q_DECLARE_METATYPE(ShortcutData)
// Q_DECLARE_METATYPE(BaseInstance::InstanceFlag) // Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
// Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags) // Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags)

View file

@ -357,25 +357,20 @@ bool InstanceList::trashInstance(const InstanceId& id)
m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId }); m_trashHistory.push({ id, inst->instanceRoot(), trashedLoc, cachedGroupId });
// Also trash all of its shortcuts; we remove the shortcuts if trash fails since it is invalid anyway // Also trash all of its shortcuts; we remove the shortcuts if trash fails since it is invalid anyway
auto& shortcuts = inst->getShortcuts(); for (const auto& [name, filePath, target] : inst->shortcuts()) {
for (auto it = shortcuts.begin(); it != shortcuts.end();) {
const auto& [name, filePath, target] = *it;
if (!FS::trash(filePath, &trashedLoc)) { if (!FS::trash(filePath, &trashedLoc)) {
qWarning() << "Trash of shortcut" << name << "at path" << filePath << "for instance" << id qWarning() << "Trash of shortcut" << name << "at path" << filePath << "for instance" << id
<< "has not been successful, trying to delete it instead..."; << "has not been successful, trying to delete it instead...";
if (!FS::deletePath(filePath)) { if (!FS::deletePath(filePath)) {
qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id
<< "has not been successful, given up..."; << "has not been successful, given up...";
++it;
} else { } else {
qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher."; qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been deleted by the launcher.";
it = shortcuts.erase(it);
} }
continue; continue;
} }
qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been trashed by the launcher."; qDebug() << "Shortcut" << name << "at path" << filePath << "for instance" << id << "has been trashed by the launcher.";
m_trashHistory.top().shortcuts.append({ *it, trashedLoc }); m_trashHistory.top().shortcuts.append({ { name, filePath, target }, trashedLoc });
it = shortcuts.erase(it);
} }
return true; return true;
@ -453,7 +448,7 @@ void InstanceList::deleteInstance(const InstanceId& id)
qDebug() << "Instance" << id << "has been deleted by the launcher."; qDebug() << "Instance" << id << "has been deleted by the launcher.";
for (const auto& [name, filePath, target] : inst->getShortcuts()) { for (const auto& [name, filePath, target] : inst->shortcuts()) {
if (!FS::deletePath(filePath)) { if (!FS::deletePath(filePath)) {
qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful..."; qWarning() << "Deletion of shortcut" << name << "at path" << filePath << "for instance" << id << "has not been successful...";
continue; continue;
@ -675,6 +670,7 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
} }
auto instanceRoot = FS::PathCombine(m_instDir, id); auto instanceRoot = FS::PathCombine(m_instDir, id);
qRegisterMetaType<QList<ShortcutData>>("QList<ShortcutData>");
auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg")); auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg"));
InstancePtr inst; InstancePtr inst;
@ -690,6 +686,22 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id)
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));
} }
qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot(); qDebug() << "Loaded instance" << inst->name() << "from" << inst->instanceRoot();
// Fixup the shortcuts by pruning all non-existing links
auto shortcut = inst->shortcuts();
for (auto it = shortcut.begin(); it != shortcut.end();) {
const auto& [name, filePath, target] = *it;
if (!QDir(filePath).exists()) {
qWarning() << "Shortcut" << name << "have non-existent path" << filePath;
it = shortcut.erase(it);
continue;
}
++it;
}
inst->setShortcuts(shortcut);
if (!shortcut.isEmpty())
qDebug() << "Loaded" << shortcut.size() << "shortcut(s) for instance" << inst->name();
return inst; return inst;
} }

View file

@ -1040,6 +1040,10 @@ QString MinecraftInstance::getStatusbarDescription()
.arg(Time::prettifyDuration(totalTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); .arg(Time::prettifyDuration(totalTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool())));
} }
} }
auto currentShortcuts = shortcuts();
if (!currentShortcuts.isEmpty()) {
description.append(tr(", %n shortcut(s) registered", "", currentShortcuts.size()));
}
if (hasCrashed()) { if (hasCrashed()) {
description.append(tr(", has crashed.")); description.append(tr(", has crashed."));
} }