From 6a462d0778e27379c3b22b3a1a0339093819d3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 3 Dec 2017 15:48:25 +0100 Subject: [PATCH] GH-1082 allow disabling components Currently only ones that are removable and aren't dep-only --- api/logic/minecraft/Component.cpp | 31 ++++++++++++ api/logic/minecraft/Component.h | 7 +++ api/logic/minecraft/ComponentList.cpp | 70 +++++++++++++++++++++++---- api/logic/minecraft/ComponentList.h | 8 +++ 4 files changed, 107 insertions(+), 9 deletions(-) diff --git a/api/logic/minecraft/Component.cpp b/api/logic/minecraft/Component.cpp index db523142..50a2ae16 100644 --- a/api/logic/minecraft/Component.cpp +++ b/api/logic/minecraft/Component.cpp @@ -50,6 +50,11 @@ std::shared_ptr Component::getMeta() void Component::applyTo(LaunchProfile* profile) { + // do not apply disabled components + if(!isEnabled()) + { + return; + } auto vfile = getVersionFile(); if(vfile) { @@ -137,6 +142,32 @@ QDateTime Component::getReleaseDateTime() return QDateTime::currentDateTime(); } +bool Component::isEnabled() +{ + return !canBeDisabled() || !m_disabled; +}; + +bool Component::canBeDisabled() +{ + return isRemovable() && !m_dependencyOnly; +} + +bool Component::setEnabled(bool state) +{ + bool intendedDisabled = !state; + if (!canBeDisabled()) + { + intendedDisabled = false; + } + if(intendedDisabled != m_disabled) + { + m_disabled = intendedDisabled; + emit dataChanged(); + return true; + } + return false; +} + bool Component::isCustom() { return m_file != nullptr; diff --git a/api/logic/minecraft/Component.h b/api/logic/minecraft/Component.h index 4917149b..778fbb18 100644 --- a/api/logic/minecraft/Component.h +++ b/api/logic/minecraft/Component.h @@ -31,6 +31,10 @@ public: virtual ~Component(){}; void applyTo(LaunchProfile *profile); + bool isEnabled(); + bool setEnabled (bool state); + bool canBeDisabled(); + bool isMoveable(); bool isCustomizable(); bool isRevertible(); @@ -55,6 +59,7 @@ public: void setImportant (bool state); + const QList getProblems() const override; ProblemSeverity getProblemSeverity() const override; @@ -79,6 +84,8 @@ public: /* data */ bool m_dependencyOnly = false; /// if true, the component is either the main component of the instance, or otherwise important and cannot be removed. bool m_important = false; + /// if true, the component is disabled + bool m_disabled = false; /// cached name for display purposes, taken from the version file (meta or local override) QString m_cachedName; diff --git a/api/logic/minecraft/ComponentList.cpp b/api/logic/minecraft/ComponentList.cpp index 342c10b3..99a2fc82 100644 --- a/api/logic/minecraft/ComponentList.cpp +++ b/api/logic/minecraft/ComponentList.cpp @@ -76,6 +76,10 @@ static QJsonObject componentToJsonV1(ComponentPtr component) { obj.insert("important", true); } + if(component->m_disabled) + { + obj.insert("disabled", true); + } // cached if(!component->m_cachedVersion.isEmpty()) @@ -112,6 +116,8 @@ static ComponentPtr componentFromJsonV1(ComponentList * parent, const QString & Meta::parseRequires(obj, &component->m_cachedRequires, "cachedRequires"); Meta::parseRequires(obj, &component->m_cachedConflicts, "cachedConflicts"); component->m_cachedVolatile = Json::ensureBoolean(obj.value("volatile"), false); + bool disabled = Json::ensureBoolean(obj.value("disabled"), false); + component->setEnabled(!disabled); return component; } @@ -803,13 +809,25 @@ QVariant ComponentList::data(const QModelIndex &index, int role) const auto patch = d->components.at(row); - if (role == Qt::DisplayRole) + switch (role) + { + case Qt::CheckStateRole: { switch (column) { - case 0: + case NameColumn: + return d->components.at(row)->isEnabled() ? Qt::Checked : Qt::Unchecked; + default: + return QVariant(); + } + } + case Qt::DisplayRole: + { + switch (column) + { + case NameColumn: return d->components.at(row)->getName(); - case 1: + case VersionColumn: { if(patch->isCustom()) { @@ -824,11 +842,11 @@ QVariant ComponentList::data(const QModelIndex &index, int role) const return QVariant(); } } - if(role == Qt::DecorationRole) + case Qt::DecorationRole: { switch(column) { - case 0: + case NameColumn: { auto severity = patch->getProblemSeverity(); switch (severity) @@ -847,8 +865,28 @@ QVariant ComponentList::data(const QModelIndex &index, int role) const } } } + } return QVariant(); } + +bool ComponentList::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if (!index.isValid() || index.row() < 0 || index.row() >= rowCount(index)) + { + return false; + } + + if (role == Qt::CheckStateRole) + { + auto component = d->components[index.row()]; + if (component->setEnabled(!component->isEnabled())) + { + return true; + } + } + return false; +} + QVariant ComponentList::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) @@ -857,9 +895,9 @@ QVariant ComponentList::headerData(int section, Qt::Orientation orientation, int { switch (section) { - case 0: + case NameColumn: return tr("Name"); - case 1: + case VersionColumn: return tr("Version"); default: return QVariant(); @@ -872,7 +910,21 @@ Qt::ItemFlags ComponentList::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; - return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + Qt::ItemFlags outFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + int row = index.row(); + + if (row < 0 || row >= d->components.size()) + return Qt::NoItemFlags; + + auto patch = d->components.at(row); + // TODO: this will need fine-tuning later... + if(patch->canBeDisabled()) + { + outFlags |= Qt::ItemIsUserCheckable; + } + return outFlags; } int ComponentList::rowCount(const QModelIndex &parent) const @@ -882,7 +934,7 @@ int ComponentList::rowCount(const QModelIndex &parent) const int ComponentList::columnCount(const QModelIndex &parent) const { - return 2; + return NUM_COLUMNS; } void ComponentList::move(const int index, const MoveDirection direction) diff --git a/api/logic/minecraft/ComponentList.h b/api/logic/minecraft/ComponentList.h index 7971650d..9cce111b 100644 --- a/api/logic/minecraft/ComponentList.h +++ b/api/logic/minecraft/ComponentList.h @@ -39,10 +39,18 @@ class MULTIMC_LOGIC_EXPORT ComponentList : public QAbstractListModel Q_OBJECT friend ComponentUpdateTask; public: + enum Columns + { + NameColumn = 0, + VersionColumn, + NUM_COLUMNS + }; + explicit ComponentList(MinecraftInstance * instance); virtual ~ComponentList(); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual int columnCount(const QModelIndex &parent) const override;