aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/BaseInstance.cpp36
-rw-r--r--launcher/BaseInstance.h6
-rw-r--r--launcher/InstanceCopyTask.cpp2
-rw-r--r--launcher/InstanceList.cpp10
-rw-r--r--launcher/InstanceList.h2
-rw-r--r--launcher/settings/INIFile.cpp18
-rw-r--r--launcher/settings/INIFile.h35
-rw-r--r--launcher/settings/SettingsObject.cpp13
-rw-r--r--launcher/settings/SettingsObject.h41
-rw-r--r--launcher/ui/MainWindow.cpp14
-rw-r--r--tests/INIFile_test.cpp38
11 files changed, 213 insertions, 2 deletions
diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp
index 8680361c..6428be43 100644
--- a/launcher/BaseInstance.cpp
+++ b/launcher/BaseInstance.cpp
@@ -40,6 +40,8 @@
#include <QDir>
#include <QDebug>
#include <QRegularExpression>
+#include <QJsonDocument>
+#include <QJsonObject>
#include "settings/INISettingsObject.h"
#include "settings/Setting.h"
@@ -64,6 +66,8 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
m_settings->registerSetting("totalTimePlayed", 0);
m_settings->registerSetting("lastTimePlayed", 0);
+ m_settings->registerSetting("linkedInstancesList", "[]");
+
// Game time override
auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
@@ -182,6 +186,38 @@ bool BaseInstance::shouldStopOnConsoleOverflow() const
return m_settings->get("ConsoleOverflowStop").toBool();
}
+QStringList BaseInstance::getLinkedInstances() const
+{
+ return m_settings->getList<QString>("linkedInstancesList");
+}
+
+void BaseInstance::setLinkedInstances(const QStringList& list)
+{
+ auto linkedInstancesList = m_settings->getList<QString>("linkedInstancesList");
+ m_settings->setList("linkedInstancesList", list);
+}
+
+void BaseInstance::addLinkedInstanceId(const QString& id)
+{
+ auto linkedInstancesList = m_settings->getList<QString>("linkedInstancesList");
+ linkedInstancesList.append(id);
+ setLinkedInstances(linkedInstancesList);
+}
+
+bool BaseInstance::removeLinkedInstanceId(const QString& id)
+{
+ auto linkedInstancesList = m_settings->getList<QString>("linkedInstancesList");
+ int numRemoved = linkedInstancesList.removeAll(id);
+ setLinkedInstances(linkedInstancesList);
+ return numRemoved > 0;
+}
+
+bool BaseInstance::isLinkedToInstanceId(const QString& id) const
+{
+ auto linkedInstancesList = m_settings->getList<QString>("linkedInstancesList");
+ return linkedInstancesList.contains(id);
+}
+
void BaseInstance::iconUpdated(QString key)
{
if(iconKey() == key)
diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h
index a2a4f824..83a8064f 100644
--- a/launcher/BaseInstance.h
+++ b/launcher/BaseInstance.h
@@ -282,6 +282,12 @@ public:
int getConsoleMaxLines() const;
bool shouldStopOnConsoleOverflow() const;
+ QStringList getLinkedInstances() const;
+ void setLinkedInstances(const QStringList& list);
+ void addLinkedInstanceId(const QString& id);
+ bool removeLinkedInstanceId(const QString& id);
+ bool isLinkedToInstanceId(const QString& id) const;
+
protected:
void changeStatus(Status newStatus);
diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp
index 40babd0f..e0a4de0b 100644
--- a/launcher/InstanceCopyTask.cpp
+++ b/launcher/InstanceCopyTask.cpp
@@ -137,6 +137,8 @@ void InstanceCopyTask::copyFinished()
if(!m_keepPlaytime) {
inst->resetTimePlayed();
}
+ if (m_useLinks)
+ inst->addLinkedInstanceId(m_origInstance->id());
emitSucceeded();
}
diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp
index 1ca16ae9..179bfb9a 100644
--- a/launcher/InstanceList.cpp
+++ b/launcher/InstanceList.cpp
@@ -129,6 +129,16 @@ QMimeData* InstanceList::mimeData(const QModelIndexList& indexes) const
return mimeData;
}
+QStringList InstanceList::getLinkedInstancesById(const QString &id) const
+{
+ QStringList linkedInstances;
+ for (auto inst : m_instances) {
+ if (inst->isLinkedToInstanceId(id))
+ linkedInstances.append(inst->id());
+ }
+ return linkedInstances;
+}
+
int InstanceList::rowCount(const QModelIndex& parent) const
{
Q_UNUSED(parent);
diff --git a/launcher/InstanceList.h b/launcher/InstanceList.h
index edacba3c..48bede07 100644
--- a/launcher/InstanceList.h
+++ b/launcher/InstanceList.h
@@ -154,6 +154,8 @@ public:
QStringList mimeTypes() const override;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
+ QStringList getLinkedInstancesById(const QString &id) const;
+
signals:
void dataIsInvalid();
void instancesChanged();
diff --git a/launcher/settings/INIFile.cpp b/launcher/settings/INIFile.cpp
index 733cd444..e48e6f47 100644
--- a/launcher/settings/INIFile.cpp
+++ b/launcher/settings/INIFile.cpp
@@ -183,3 +183,21 @@ void INIFile::set(QString key, QVariant val)
{
this->operator[](key) = val;
}
+
+void INIFile::setList(QString key, QVariantList val)
+{
+ QString stringList = QJsonDocument(QVariant(val).toJsonArray()).toJson(QJsonDocument::Compact);
+
+ this->operator[](key) = stringList;
+}
+
+QVariantList INIFile::getList(QString key, QVariantList def) const
+{
+ if (this->contains(key)) {
+ auto src = this->operator[](key);
+
+ return QJsonDocument::fromJson(src.toByteArray()).toVariant().toList();
+ }
+
+ return def;
+}
diff --git a/launcher/settings/INIFile.h b/launcher/settings/INIFile.h
index 4313e829..86bf0898 100644
--- a/launcher/settings/INIFile.h
+++ b/launcher/settings/INIFile.h
@@ -19,6 +19,9 @@
#include <QVariant>
#include <QIODevice>
+#include <QJsonDocument>
+#include <QJsonArray>
+
// Sectionless INI parser (for instance config files)
class INIFile : public QMap<QString, QVariant>
{
@@ -33,4 +36,36 @@ public:
void set(QString key, QVariant val);
static QString unescape(QString orig);
static QString escape(QString orig);
+
+ void setList(QString key, QVariantList val);
+ template <typename T> void setList(QString key, QList<T> val)
+ {
+ QVariantList variantList;
+ variantList.reserve(val.size());
+ for (const T& v : val)
+ {
+ variantList.append(v);
+ }
+
+ this->setList(key, variantList);
+ }
+
+ QVariantList getList(QString key, QVariantList def) const;
+ template <typename T> QList<T> getList(QString key, QList<T> def) const
+ {
+ if (this->contains(key)) {
+ QVariant src = this->operator[](key);
+ QVariantList variantList = QJsonDocument::fromJson(src.toByteArray()).toVariant().toList();
+
+ QList<T>TList;
+ TList.reserve(variantList.size());
+ for (const QVariant& v : variantList)
+ {
+ TList.append(v.value<T>());
+ }
+ return TList;
+ }
+
+ return def;
+ }
};
diff --git a/launcher/settings/SettingsObject.cpp b/launcher/settings/SettingsObject.cpp
index 8a0bc045..4c51d6e9 100644
--- a/launcher/settings/SettingsObject.cpp
+++ b/launcher/settings/SettingsObject.cpp
@@ -121,6 +121,19 @@ bool SettingsObject::contains(const QString &id)
return m_settings.contains(id);
}
+bool SettingsObject::setList(const QString &id, QVariantList value)
+{
+ QString stringList = QJsonDocument(QVariant(value).toJsonArray()).toJson(QJsonDocument::Compact);
+
+ return set(id, stringList);
+}
+
+QVariantList SettingsObject::getList(const QString &id)
+{
+ QVariant value = this->get(id);
+ return QJsonDocument::fromJson(value.toByteArray()).toVariant().toList();
+}
+
bool SettingsObject::reload()
{
for (auto setting : m_settings.values())
diff --git a/launcher/settings/SettingsObject.h b/launcher/settings/SettingsObject.h
index 6200bc3a..ff430172 100644
--- a/launcher/settings/SettingsObject.h
+++ b/launcher/settings/SettingsObject.h
@@ -19,6 +19,8 @@
#include <QMap>
#include <QStringList>
#include <QVariant>
+#include <QJsonDocument>
+#include <QJsonArray>
#include <memory>
class Setting;
@@ -143,6 +145,45 @@ public:
bool contains(const QString &id);
/*!
+ * \brief Sets the value of the setting with the given ID with a json list.
+ * If no setting with the given ID exists, returns false
+ * \param id The ID of the setting to change.
+ * \param value The new value of the setting.
+ */
+ bool setList(const QString &id, QVariantList value);
+ template <typename T> bool setList(const QString &id, QList<T> val)
+ {
+ QVariantList variantList;
+ variantList.reserve(val.size());
+ for (const T& v : val)
+ {
+ variantList.append(v);
+ }
+
+ return setList(id, variantList);
+ }
+
+ /**
+ * \brief Gets the value of the setting with the given ID as if it were a json list.
+ * \param id The ID of the setting to change.
+ * \return The setting's value as a QVariantList.
+ * If no setting with the given ID exists, returns an empty QVariantList.
+ */
+ QVariantList getList(const QString &id);
+ template <typename T> QList<T> getList(const QString &id)
+ {
+ QVariantList variantList = this->getList(id);
+
+ QList<T>TList;
+ TList.reserve(variantList.size());
+ for (const QVariant& v : variantList)
+ {
+ TList.append(v.value<T>());
+ }
+ return TList;
+ }
+
+ /*!
* \brief Reloads the settings and emit signals for changed settings
* \return True if reloading was successful
*/
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 8490b292..a6aa8320 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -1337,6 +1337,20 @@ void MainWindow::on_actionDeleteInstance_triggered()
if (response != QMessageBox::Yes)
return;
+ auto linkedInstances = APPLICATION->instances()->getLinkedInstancesById(id);
+ if (!linkedInstances.empty()) {
+ response = CustomMessageBox::selectable(
+ this, tr("There are linked instances"),
+ tr("The folowing Instance(s) might reference files in this instance:\n\n"
+ "%1\n\n"
+ "Deleting it could break the other instance(s), \n\n"
+ "Are you sure?").arg(linkedInstances.join("\n")),
+ QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No
+ )->exec();
+ if (response != QMessageBox::Yes)
+ return;
+ }
+
if (APPLICATION->instances()->trashInstance(id)) {
ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
return;
diff --git a/tests/INIFile_test.cpp b/tests/INIFile_test.cpp
index b64b031b..d13937c0 100644
--- a/tests/INIFile_test.cpp
+++ b/tests/INIFile_test.cpp
@@ -1,7 +1,10 @@
#include <QTest>
+#include <QList>
+#include <QVariant>
#include <settings/INIFile.h>
+
class IniFileTest : public QObject
{
Q_OBJECT
@@ -52,8 +55,39 @@ slots:
// load
INIFile f2;
f2.loadFile(filename);
- QCOMPARE(a, f2.get("a","NOT SET").toString());
- QCOMPARE(b, f2.get("b","NOT SET").toString());
+ QCOMPARE(f2.get("a","NOT SET").toString(), a);
+ QCOMPARE(f2.get("b","NOT SET").toString(), b);
+ }
+
+ void test_SaveLoadLists()
+ {
+ QString slist_strings = "[\"a\",\"b\",\"c\"]";
+ QStringList list_strings = {"a", "b", "c"};
+
+ QString slist_numbers = "[1,2,3,10]";
+ QList<int> list_numbers = {1, 2, 3, 10};
+
+ QString filename = "test_SaveLoadLists.ini";
+
+ INIFile f;
+ f.setList("list_strings", list_strings);
+ f.setList("list_numbers", list_numbers);
+ f.saveFile(filename);
+
+ // load
+ INIFile f2;
+ f2.loadFile(filename);
+
+ QStringList out_list_strings = f2.getList<QString>("list_strings", QStringList());
+ qDebug() << "OutStringList" << out_list_strings;
+
+ QList<int> out_list_numbers = f2.getList<int>("list_numbers", QList<int>());
+ qDebug() << "OutNumbersList" << out_list_numbers;
+
+ QCOMPARE(f2.get("list_strings","NOT SET").toString(), slist_strings);
+ QCOMPARE(out_list_strings, list_strings);
+ QCOMPARE(f2.get("list_numbers","NOT SET").toString(), slist_numbers);
+ QCOMPARE(out_list_numbers, list_numbers);
}
};