aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp21
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.h5
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.cpp3
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.h3
-rw-r--r--application/CMakeLists.txt5
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp138
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.h60
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui65
-rw-r--r--application/pages/modplatform/atlauncher/AtlPage.cpp7
-rw-r--r--application/pages/modplatform/atlauncher/AtlPage.h1
10 files changed, 305 insertions, 3 deletions
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
index 89c4dfd3..89829c05 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
@@ -457,16 +457,31 @@ void PackInstallTask::extractConfigs()
void PackInstallTask::downloadMods()
{
qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId();
+
+ QVector<ATLauncher::VersionMod> optionalMods;
+ for (const auto& mod : m_version.mods) {
+ if (mod.optional) {
+ optionalMods.push_back(mod);
+ }
+ }
+
+ // Select optional mods, if pack contains any
+ QVector<QString> selectedMods;
+ if (!optionalMods.isEmpty()) {
+ setStatus(tr("Selecting optional mods..."));
+ selectedMods = m_support->chooseOptionalMods(optionalMods);
+ }
+
setStatus(tr("Downloading mods..."));
jarmods.clear();
jobPtr.reset(new NetJob(tr("Mod download")));
for(const auto& mod : m_version.mods) {
// skip non-client mods
- if (!mod.client) continue;
+ if(!mod.client) continue;
- // skip optional mods for now
- if(mod.optional) continue;
+ // skip optional mods that were not selected
+ if(mod.optional && !selectedMods.contains(mod.name)) continue;
QString url;
switch(mod.download) {
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
index 3647e471..8233c376 100644
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
+++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
@@ -19,6 +19,11 @@ class MULTIMC_LOGIC_EXPORT UserInteractionSupport {
public:
/**
+ * Requests a user interaction to select which optional mods should be installed.
+ */
+ virtual QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) = 0;
+
+ /**
* Requests a user interaction to select a component version from a given version list
* and constrained to a given Minecraft version.
*/
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
index 57cc52b6..149cb9c1 100644
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
+++ b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
@@ -143,7 +143,10 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) {
p.decompFile = Json::requireString(obj, "decompFile");
}
+ p.description = Json::ensureString(obj, QString("description"), "");
p.optional = Json::ensureBoolean(obj, QString("optional"), false);
+ p.recommended = Json::ensureBoolean(obj, QString("recommended"), false);
+ p.selected = Json::ensureBoolean(obj, QString("selected"), false);
p.client = Json::ensureBoolean(obj, QString("client"), false);
}
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h
index 937106a5..48e1d344 100644
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.h
+++ b/api/logic/modplatform/atlauncher/ATLPackManifest.h
@@ -86,7 +86,10 @@ struct VersionMod
QString decompType_raw;
QString decompFile;
+ QString description;
bool optional;
+ bool recommended;
+ bool selected;
bool client;
};
diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt
index c5be22d0..ab2b9960 100644
--- a/application/CMakeLists.txt
+++ b/application/CMakeLists.txt
@@ -129,6 +129,8 @@ SET(MULTIMC_SOURCES
pages/modplatform/atlauncher/AtlFilterModel.h
pages/modplatform/atlauncher/AtlListModel.cpp
pages/modplatform/atlauncher/AtlListModel.h
+ pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+ pages/modplatform/atlauncher/AtlOptionalModDialog.h
pages/modplatform/atlauncher/AtlPage.cpp
pages/modplatform/atlauncher/AtlPage.h
@@ -278,6 +280,9 @@ SET(MULTIMC_UIS
pages/modplatform/technic/TechnicPage.ui
pages/modplatform/ImportPage.ui
+ # Platform Dialogs
+ pages/modplatform/atlauncher/AtlOptionalModDialog.ui
+
# Dialogs
dialogs/CopyInstanceDialog.ui
dialogs/NewComponentDialog.ui
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
new file mode 100644
index 00000000..129d9fed
--- /dev/null
+++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -0,0 +1,138 @@
+#include "AtlOptionalModDialog.h"
+#include "ui_AtlOptionalModDialog.h"
+
+AtlOptionalModListModel::AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
+ : QAbstractListModel(parent), m_mods(mods) {
+
+ for (const auto& mod : mods) {
+ m_selection[mod.name] = mod.selected;
+ }
+}
+
+QVector<QString> AtlOptionalModListModel::getResult() {
+ QVector<QString> result;
+
+ for (const auto& mod : m_mods) {
+ if (m_selection[mod.name]) {
+ result.push_back(mod.name);
+ }
+ }
+
+ return result;
+}
+
+int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
+ return m_mods.size();
+}
+
+int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
+ // Enabled, Name, Description
+ return 3;
+}
+
+QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
+ auto row = index.row();
+ auto mod = m_mods.at(row);
+
+ if (role == Qt::DisplayRole) {
+ if (index.column() == NameColumn) {
+ return mod.name;
+ }
+ if (index.column() == DescriptionColumn) {
+ return mod.description;
+ }
+ }
+ else if (role == Qt::ToolTipRole) {
+ if (index.column() == DescriptionColumn) {
+ return mod.description;
+ }
+ }
+ else if (role == Qt::CheckStateRole) {
+ if (index.column() == EnabledColumn) {
+ return m_selection[mod.name] ? Qt::Checked : Qt::Unchecked;
+ }
+ }
+
+ return QVariant();
+}
+
+bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &value, int role) {
+ if (role == Qt::CheckStateRole) {
+ auto row = index.row();
+ auto mod = m_mods.at(row);
+
+ // toggle the state
+ m_selection[mod.name] = !m_selection[mod.name];
+
+ emit dataChanged(AtlOptionalModListModel::index(index.row(), EnabledColumn),
+ AtlOptionalModListModel::index(index.row(), EnabledColumn));
+ return true;
+ }
+
+ return false;
+}
+
+QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orientation, int role) const {
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ switch (section) {
+ case EnabledColumn:
+ return QString();
+ case NameColumn:
+ return QString("Name");
+ case DescriptionColumn:
+ return QString("Description");
+ }
+ }
+
+ return QVariant();
+}
+
+Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const {
+ auto flags = QAbstractListModel::flags(index);
+ if (index.isValid() && index.column() == EnabledColumn) {
+ flags |= Qt::ItemIsUserCheckable;
+ }
+ return flags;
+}
+
+void AtlOptionalModListModel::selectRecommended() {
+ for (const auto& mod : m_mods) {
+ m_selection[mod.name] = mod.recommended;
+ }
+
+ emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
+ AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
+}
+
+void AtlOptionalModListModel::clearAll() {
+ for (const auto& mod : m_mods) {
+ m_selection[mod.name] = false;
+ }
+
+ emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
+ AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
+}
+
+
+AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
+ : QDialog(parent), ui(new Ui::AtlOptionalModDialog) {
+ ui->setupUi(this);
+
+ listModel = new AtlOptionalModListModel(this, mods);
+ ui->treeView->setModel(listModel);
+
+ ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ ui->treeView->header()->setSectionResizeMode(
+ AtlOptionalModListModel::NameColumn, QHeaderView::ResizeToContents);
+ ui->treeView->header()->setSectionResizeMode(
+ AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch);
+
+ connect(ui->selectRecommendedButton, &QPushButton::pressed,
+ listModel, &AtlOptionalModListModel::selectRecommended);
+ connect(ui->clearAllButton, &QPushButton::pressed,
+ listModel, &AtlOptionalModListModel::clearAll);
+}
+
+AtlOptionalModDialog::~AtlOptionalModDialog() {
+ delete ui;
+}
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
new file mode 100644
index 00000000..8b0dbdb6
--- /dev/null
+++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <QDialog>
+#include <QAbstractListModel>
+
+#include "modplatform/atlauncher/ATLPackIndex.h"
+
+namespace Ui {
+class AtlOptionalModDialog;
+}
+
+class AtlOptionalModListModel : public QAbstractListModel {
+ Q_OBJECT
+
+public:
+ enum Columns
+ {
+ EnabledColumn = 0,
+ NameColumn,
+ DescriptionColumn,
+ };
+
+ AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
+
+ QVector<QString> getResult();
+
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+
+ QVariant data(const QModelIndex &index, int role) const override;
+ bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+public slots:
+ void selectRecommended();
+ void clearAll();
+
+private:
+ QVector<ATLauncher::VersionMod> m_mods;
+ QMap<QString, bool> m_selection;
+};
+
+class AtlOptionalModDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
+ ~AtlOptionalModDialog() override;
+
+ QVector<QString> getResult() {
+ return listModel->getResult();
+ }
+
+private:
+ Ui::AtlOptionalModDialog *ui;
+
+ AtlOptionalModListModel *listModel;
+};
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
new file mode 100644
index 00000000..5d3193a4
--- /dev/null
+++ b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AtlOptionalModDialog</class>
+ <widget class="QDialog" name="AtlOptionalModDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>550</width>
+ <height>310</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Select Mods To Install</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="3">
+ <widget class="QPushButton" name="installButton">
+ <property name="text">
+ <string>Install</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="selectRecommendedButton">
+ <property name="text">
+ <string>Select Recommended</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QPushButton" name="shareCodeButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Use Share Code</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="clearAllButton">
+ <property name="text">
+ <string>Clear All</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="4">
+ <widget class="ModListView" name="treeView"/>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ModListView</class>
+ <extends>QTreeView</extends>
+ <header>widgets/ModListView.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/application/pages/modplatform/atlauncher/AtlPage.cpp b/application/pages/modplatform/atlauncher/AtlPage.cpp
index 3c19804f..9fdf111f 100644
--- a/application/pages/modplatform/atlauncher/AtlPage.cpp
+++ b/application/pages/modplatform/atlauncher/AtlPage.cpp
@@ -2,6 +2,7 @@
#include "ui_AtlPage.h"
#include "dialogs/NewInstanceDialog.h"
+#include "AtlOptionalModDialog.h"
#include <modplatform/atlauncher/ATLPackInstallTask.h>
#include <BuildConfig.h>
#include <dialogs/VersionSelectDialog.h>
@@ -131,6 +132,12 @@ void AtlPage::onVersionSelectionChanged(QString data)
suggestCurrent();
}
+QVector<QString> AtlPage::chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) {
+ AtlOptionalModDialog optionalModDialog(this, mods);
+ optionalModDialog.exec();
+ return optionalModDialog.getResult();
+}
+
QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) {
VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false);
if (minecraftVersion != Q_NULLPTR) {
diff --git a/application/pages/modplatform/atlauncher/AtlPage.h b/application/pages/modplatform/atlauncher/AtlPage.h
index 18f8b1c6..932ec6a6 100644
--- a/application/pages/modplatform/atlauncher/AtlPage.h
+++ b/application/pages/modplatform/atlauncher/AtlPage.h
@@ -63,6 +63,7 @@ private:
void suggestCurrent();
QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override;
+ QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) override;
private slots:
void triggerSearch();