aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui
diff options
context:
space:
mode:
authorflow <flowlnlnln@gmail.com>2022-12-18 15:41:46 -0300
committerflow <flowlnlnln@gmail.com>2023-01-13 16:23:07 -0300
commit45d1319891ce87cc1546a316ad550f892d411633 (patch)
treea1eaabd0e5fc362a82ebfbe93bfe20697608fe1e /launcher/ui
parent39b7ac90d40eb53d7b88ef99b0fa46fb3e1840b9 (diff)
downloadPrismLauncher-45d1319891ce87cc1546a316ad550f892d411633.tar.gz
PrismLauncher-45d1319891ce87cc1546a316ad550f892d411633.tar.bz2
PrismLauncher-45d1319891ce87cc1546a316ad550f892d411633.zip
refactor(RD): decouple ResourceModels from ResourcePages
This makes it so that we don't need a reference to the parent page in the model. It will be useful once we change the page from a widget-based one to a QML page. It also makes tasks be created in the dialog instead of the page, so that the dialog can also have the necessary information to mark versions as selected / deselected easily. It also makes the task pointers into smart pointers. Signed-off-by: flow <flowlnlnln@gmail.com>
Diffstat (limited to 'launcher/ui')
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp44
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.h13
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp81
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h13
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp4
-rw-r--r--launcher/ui/pages/modplatform/ModPage.h6
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.cpp19
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h18
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.cpp29
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.h4
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp5
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.h8
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp2
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp6
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h6
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp2
16 files changed, 140 insertions, 120 deletions
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
index 523a1636..2eb85928 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
@@ -141,38 +141,44 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage()
return m_selectedPage;
}
-void ResourceDownloadDialog::addResource(QString name, ResourceDownloadTask* task)
+void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed)
{
- removeResource(name);
- m_selected.insert(name, task);
+ removeResource(pack, ver);
+
+ ver.is_currently_selected = true;
+ m_selected.insert(pack.name, new ResourceDownloadTask(pack, ver, getBaseModel(), is_indexed));
m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
}
-void ResourceDownloadDialog::removeResource(QString name)
+static ModPlatform::IndexedVersion& getVersionWithID(ModPlatform::IndexedPack& pack, QVariant id)
{
- if (m_selected.contains(name))
- m_selected.find(name).value()->deleteLater();
- m_selected.remove(name);
-
- m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
+ Q_ASSERT(pack.versionsLoaded);
+ auto it = std::find_if(pack.versions.begin(), pack.versions.end(), [id](auto const& v) { return v.fileId == id; });
+ Q_ASSERT(it != pack.versions.end());
+ return *it;
}
-bool ResourceDownloadDialog::isSelected(QString name, QString filename) const
+void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver)
{
- auto iter = m_selected.constFind(name);
- if (iter == m_selected.constEnd())
- return false;
+ if (auto selected_task_it = m_selected.find(pack.name); selected_task_it != m_selected.end()) {
+ auto selected_task = *selected_task_it;
+ auto old_version_id = selected_task->getVersionID();
- // FIXME: Is there a way to check for versions without checking the filename
- // as a heuristic, other than adding such info to ResourceDownloadTask itself?
- if (!filename.isEmpty())
- return iter.value()->getFilename() == filename;
+ // If the new and old version IDs don't match, search for the old one and deselect it.
+ if (ver.fileId != old_version_id)
+ getVersionWithID(pack, old_version_id).is_currently_selected = false;
+ }
- return true;
+ // Deselect the new version too, since all versions of that pack got removed.
+ ver.is_currently_selected = false;
+
+ m_selected.remove(pack.name);
+
+ m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
}
-const QList<ResourceDownloadTask*> ResourceDownloadDialog::getTasks()
+const QList<ResourceDownloadDialog::DownloadTaskPtr> ResourceDownloadDialog::getTasks()
{
return m_selected.values();
}
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h
index 29813493..95a5e628 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.h
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.h
@@ -23,6 +23,8 @@
#include <QDialogButtonBox>
#include <QLayout>
+#include "QObjectPtr.h"
+#include "modplatform/ModIndex.h"
#include "ui/pages/BasePageProvider.h"
class BaseInstance;
@@ -41,6 +43,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
Q_OBJECT
public:
+ using DownloadTaskPtr = shared_qobject_ptr<ResourceDownloadTask>;
+
ResourceDownloadDialog(QWidget* parent, const std::shared_ptr<ResourceFolderModel> base_model);
void initializeContainer();
@@ -54,11 +58,10 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
bool selectPage(QString pageId);
ResourcePage* getSelectedPage();
- void addResource(QString name, ResourceDownloadTask* task);
- void removeResource(QString name);
- [[nodiscard]] bool isSelected(QString name, QString filename = "") const;
+ void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, bool is_indexed = false);
+ void removeResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
- const QList<ResourceDownloadTask*> getTasks();
+ const QList<DownloadTaskPtr> getTasks();
[[nodiscard]] const std::shared_ptr<ResourceFolderModel> getBaseModel() const { return m_base_model; }
public slots:
@@ -82,7 +85,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
QDialogButtonBox m_buttons;
QVBoxLayout m_vertical_layout;
- QHash<QString, ResourceDownloadTask*> m_selected;
+ QHash<QString, DownloadTaskPtr> m_selected;
};
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index 59399c59..c9dee449 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -1,7 +1,7 @@
#include "ModModel.h"
#include "Json.h"
-#include "ModPage.h"
+
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
@@ -9,15 +9,23 @@
namespace ResourceDownload {
-ModModel::ModModel(ModPage* parent, ResourceAPI* api) : ResourceModel(parent, api) {}
+ModModel::ModModel(BaseInstance const& base_inst, ResourceAPI* api) : ResourceModel(base_inst, api) {}
/******** Make data requests ********/
ResourceAPI::SearchArgs ModModel::createSearchArguments()
{
- auto profile = static_cast<MinecraftInstance&>(m_associated_page->m_base_instance).getPackProfile();
+ auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
+
+ Q_ASSERT(profile);
+ Q_ASSERT(m_filter);
+
+ std::optional<std::list<Version>> versions {};
+ if (!m_filter->versions.empty())
+ versions = m_filter->versions;
+
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term,
- getSorts()[currentSort], profile->getModLoaders(), getMineVersions() };
+ getSorts()[currentSort], profile->getModLoaders(), versions };
}
ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
{
@@ -30,19 +38,24 @@ ResourceAPI::SearchCallbacks ModModel::createSearchCallbacks()
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
{
- auto const& pack = m_packs[entry.row()];
- auto profile = static_cast<MinecraftInstance&>(m_associated_page->m_base_instance).getPackProfile();
+ auto& pack = m_packs[entry.row()];
+ auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
+
+ Q_ASSERT(profile);
+ Q_ASSERT(m_filter);
- return { pack.addonId.toString(), getMineVersions(), profile->getModLoaders() };
+ std::optional<std::list<Version>> versions {};
+ if (!m_filter->versions.empty())
+ versions = m_filter->versions;
+
+ return { pack, versions, profile->getModLoaders() };
}
ResourceAPI::VersionSearchCallbacks ModModel::createVersionsCallbacks(QModelIndex& entry)
{
- auto const& pack = m_packs[entry.row()];
-
- return { [this, pack, entry](auto& doc, auto addonId) {
+ return { [this, entry](auto& doc, auto& pack) {
if (!s_running_models.constFind(this).value())
return;
- versionRequestSucceeded(doc, addonId, entry);
+ versionRequestSucceeded(doc, pack, entry);
} };
}
@@ -87,7 +100,7 @@ void ModModel::searchRequestFinished(QJsonDocument& doc)
loadIndexedPack(pack, packObj);
newList.append(pack);
} catch (const JSONValidationError& e) {
- qWarning() << "Error while loading mod from " << m_associated_page->debugName() << ": " << e.cause();
+ qWarning() << "Error while loading mod from " << debugName() << ": " << e.cause();
continue;
}
}
@@ -127,48 +140,36 @@ void ModModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack&
new_pack.setValue(pack);
if (!setData(index, new_pack, Qt::UserRole)) {
qWarning() << "Failed to cache mod info!";
+ return;
}
+
+ emit projectInfoUpdated();
}
-
- m_associated_page->updateUi();
}
-void ModModel::versionRequestSucceeded(QJsonDocument doc, QString addonId, const QModelIndex& index)
+void ModModel::versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
{
- auto current = m_associated_page->getCurrentPack();
- if (addonId != current.addonId) {
- return;
- }
-
auto arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
try {
- loadIndexedPackVersions(current, arr);
+ loadIndexedPackVersions(pack, arr);
} catch (const JSONValidationError& e) {
qDebug() << doc;
qWarning() << "Error while reading " << debugName() << " mod version: " << e.cause();
}
- // Cache info :^)
- QVariant new_pack;
- new_pack.setValue(current);
- if (!setData(index, new_pack, Qt::UserRole)) {
- qWarning() << "Failed to cache mod versions!";
- }
-
- m_associated_page->updateVersionList();
-}
-
-/******** Helpers ********/
-
-#define MOD_PAGE(x) static_cast<ModPage*>(x)
+ // Check if the index is still valid for this mod or not
+ if (pack.addonId == data(index, Qt::UserRole).value<ModPlatform::IndexedPack>().addonId) {
+ // Cache info :^)
+ QVariant new_pack;
+ new_pack.setValue(pack);
+ if (!setData(index, new_pack, Qt::UserRole)) {
+ qWarning() << "Failed to cache mod versions!";
+ return;
+ }
-auto ModModel::getMineVersions() const -> std::optional<std::list<Version>>
-{
- auto versions = MOD_PAGE(m_associated_page)->getFilter()->versions;
- if (!versions.empty())
- return versions;
- return {};
+ emit versionListUpdated();
+ }
}
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index e3d760a2..39d062f9 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -6,6 +6,7 @@
#include "modplatform/ResourceAPI.h"
#include "ui/pages/modplatform/ResourceModel.h"
+#include "ui/widgets/ModFilterWidget.h"
class Version;
@@ -17,7 +18,7 @@ class ModModel : public ResourceModel {
Q_OBJECT
public:
- ModModel(ModPage* parent, ResourceAPI* api);
+ ModModel(const BaseInstance&, ResourceAPI* api);
/* Ask the API for more information */
void searchWithTerm(const QString& term, const int sort, const bool filter_changed);
@@ -26,12 +27,12 @@ class ModModel : public ResourceModel {
virtual void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0;
virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0;
+ void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
+
public slots:
void searchRequestFinished(QJsonDocument& doc);
-
void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
-
- void versionRequestSucceeded(QJsonDocument doc, QString addonId, const QModelIndex& index);
+ void versionRequestSucceeded(QJsonDocument doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
public slots:
ResourceAPI::SearchArgs createSearchArguments() override;
@@ -47,10 +48,10 @@ class ModModel : public ResourceModel {
virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0;
virtual auto getSorts() const -> const char** = 0;
- inline auto getMineVersions() const -> std::optional<std::list<Version>>;
-
protected:
int currentSort = 0;
+
+ std::shared_ptr<ModFilterWidget::Filter> m_filter = nullptr;
};
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 8d441546..556bd642 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -51,8 +51,6 @@
#include "ui/dialogs/ResourceDownloadDialog.h"
-#include "ui/pages/modplatform/ModModel.h"
-
namespace ResourceDownload {
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance)
@@ -151,7 +149,7 @@ void ModPage::updateVersionList()
void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
{
bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
- m_parent_dialog->addResource(pack.name, new ResourceDownloadTask(pack, version, m_parent_dialog->getBaseModel(), is_indexed));
+ m_parent_dialog->addResource(pack, version, is_indexed);
}
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h
index 137a6046..2fda3b68 100644
--- a/launcher/ui/pages/modplatform/ModPage.h
+++ b/launcher/ui/pages/modplatform/ModPage.h
@@ -5,6 +5,7 @@
#include "modplatform/ModIndex.h"
#include "ui/pages/modplatform/ResourcePage.h"
+#include "ui/pages/modplatform/ModModel.h"
#include "ui/widgets/ModFilterWidget.h"
namespace Ui {
@@ -24,9 +25,14 @@ class ModPage : public ResourcePage {
static T* create(ModDownloadDialog* dialog, BaseInstance& instance)
{
auto page = new T(dialog, instance);
+ auto model = static_cast<ModModel*>(page->getModel());
auto filter_widget = ModFilterWidget::create(static_cast<MinecraftInstance&>(instance).getPackProfile()->getComponentVersion("net.minecraft"), page);
page->setFilterWidget(filter_widget);
+ model->setFilter(page->getFilter());
+
+ connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::updateVersionList);
+ connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
return page;
}
diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp
index e8af0e7a..cf40fef2 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.cpp
+++ b/launcher/ui/pages/modplatform/ResourceModel.cpp
@@ -17,14 +17,13 @@
#include "modplatform/ModIndex.h"
-#include "ui/pages/modplatform/ResourcePage.h"
#include "ui/widgets/ProjectItem.h"
namespace ResourceDownload {
QHash<ResourceModel*, bool> ResourceModel::s_running_models;
-ResourceModel::ResourceModel(ResourcePage* parent, ResourceAPI* api) : QAbstractListModel(), m_api(api), m_associated_page(parent)
+ResourceModel::ResourceModel(BaseInstance const& base_inst, ResourceAPI* api) : QAbstractListModel(), m_base_instance(base_inst), m_api(api)
{
s_running_models.insert(this, true);
}
@@ -72,7 +71,7 @@ auto ResourceModel::data(const QModelIndex& index, int role) const -> QVariant
case UserDataTypes::DESCRIPTION:
return pack.description;
case UserDataTypes::SELECTED:
- return isPackSelected(pack);
+ return pack.isAnyVersionSelected();
default:
break;
}
@@ -87,13 +86,14 @@ bool ResourceModel::setData(const QModelIndex& index, const QVariant& value, int
return false;
m_packs[pos] = value.value<ModPlatform::IndexedPack>();
+ emit dataChanged(index, index);
return true;
}
QString ResourceModel::debugName() const
{
- return m_associated_page->debugName() + " (Model)";
+ return "ResourceDownload (Model)";
}
void ResourceModel::fetchMore(const QModelIndex& parent)
@@ -195,7 +195,7 @@ std::optional<QIcon> ResourceModel::getIcon(QModelIndex& index, const QUrl& url)
return {};
auto cache_entry = APPLICATION->metacache()->resolveEntry(
- m_associated_page->metaEntryBase(),
+ metaEntryBase(),
QString("logos/%1").arg(QString(QCryptographicHash::hash(url.toEncoded(), QCryptographicHash::Algorithm::Sha1).toHex())));
auto icon_fetch_action = Net::Download::makeCached(url, cache_entry);
@@ -222,11 +222,6 @@ std::optional<QIcon> ResourceModel::getIcon(QModelIndex& index, const QUrl& url)
return {};
}
-bool ResourceModel::isPackSelected(const ModPlatform::IndexedPack& pack) const
-{
- return m_associated_page->isPackSelected(pack);
-}
-
void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
{
switch (network_error_code) {
@@ -237,9 +232,7 @@ void ResourceModel::searchRequestFailed(QString reason, int network_error_code)
case 409:
// 409 Gone, notify user to update
QMessageBox::critical(nullptr, tr("Error"),
- //: %1 refers to the launcher itself
- QString("%1 %2")
- .arg(m_associated_page->displayName())
+ QString("%1")
.arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
break;
}
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
index 6a94c399..af33bf55 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.h
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -5,6 +5,7 @@
#include <QAbstractListModel>
#include "QObjectPtr.h"
+#include "BaseInstance.h"
#include "modplatform/ResourceAPI.h"
#include "tasks/ConcurrentTask.h"
@@ -17,19 +18,18 @@ struct IndexedPack;
namespace ResourceDownload {
-class ResourcePage;
-
class ResourceModel : public QAbstractListModel {
Q_OBJECT
public:
- ResourceModel(ResourcePage* parent, ResourceAPI* api);
+ ResourceModel(BaseInstance const&, ResourceAPI* api);
~ResourceModel() override;
[[nodiscard]] auto data(const QModelIndex&, int role) const -> QVariant override;
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
- [[nodiscard]] auto debugName() const -> QString;
+ [[nodiscard]] virtual auto debugName() const -> QString;
+ [[nodiscard]] virtual auto metaEntryBase() const -> QString = 0;
[[nodiscard]] inline int rowCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : m_packs.size(); }
[[nodiscard]] inline int columnCount(const QModelIndex& parent) const override { return parent.isValid() ? 0 : 1; };
@@ -38,6 +38,10 @@ class ResourceModel : public QAbstractListModel {
inline void addActiveJob(Task::Ptr ptr) { m_current_job.addTask(ptr); if (!m_current_job.isRunning()) m_current_job.start(); }
inline Task const& activeJob() { return m_current_job; }
+ signals:
+ void versionListUpdated();
+ void projectInfoUpdated();
+
public slots:
void fetchMore(const QModelIndex& parent) override;
[[nodiscard]] inline bool canFetchMore(const QModelIndex& parent) const override
@@ -72,9 +76,9 @@ class ResourceModel : public QAbstractListModel {
/** Resets the model's data. */
void clearData();
- [[nodiscard]] bool isPackSelected(const ModPlatform::IndexedPack&) const;
-
protected:
+ const BaseInstance& m_base_instance;
+
/* Basic search parameters */
enum class SearchState { None, CanFetchMore, ResetRequested, Finished } m_search_state = SearchState::None;
int m_next_search_offset = 0;
@@ -88,8 +92,6 @@ class ResourceModel : public QAbstractListModel {
QSet<QUrl> m_currently_running_icon_actions;
QSet<QUrl> m_failed_icon_actions;
- ResourcePage* m_associated_page = nullptr;
-
QList<ModPlatform::IndexedPack> m_packs;
// HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp
index 161b5c22..e04278af 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.cpp
+++ b/launcher/ui/pages/modplatform/ResourcePage.cpp
@@ -103,17 +103,16 @@ void ResourcePage::setSearchTerm(QString term)
m_ui->searchEdit->setText(term);
}
-ModPlatform::IndexedPack ResourcePage::getCurrentPack() const
+bool ResourcePage::setCurrentPack(ModPlatform::IndexedPack pack)
{
- return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack>();
+ QVariant v;
+ v.setValue(pack);
+ return m_model->setData(m_ui->packView->currentIndex(), v, Qt::UserRole);
}
-bool ResourcePage::isPackSelected(const ModPlatform::IndexedPack& pack, int version) const
+ModPlatform::IndexedPack ResourcePage::getCurrentPack() const
{
- if (version < 0 || !pack.versionsLoaded)
- return m_parent_dialog->isSelected(pack.name);
-
- return m_parent_dialog->isSelected(pack.name, pack.versions[version].fileName);
+ return m_model->data(m_ui->packView->currentIndex(), Qt::UserRole).value<ModPlatform::IndexedPack>();
}
void ResourcePage::updateUi()
@@ -185,7 +184,7 @@ void ResourcePage::updateSelectionButton()
}
m_ui->resourceSelectionButton->setEnabled(true);
- if (!isPackSelected(getCurrentPack(), m_selected_version_index)) {
+ if (!getCurrentPack().isVersionSelected(m_selected_version_index)) {
m_ui->resourceSelectionButton->setText(tr("Select %1 for download").arg(resourceString()));
} else {
m_ui->resourceSelectionButton->setText(tr("Deselect %1 for download").arg(resourceString()));
@@ -256,12 +255,12 @@ void ResourcePage::onVersionSelectionChanged(QString data)
void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
{
- m_parent_dialog->addResource(pack.name, new ResourceDownloadTask(pack, version, m_parent_dialog->getBaseModel()));
+ m_parent_dialog->addResource(pack, version);
}
-void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion&)
+void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
{
- m_parent_dialog->removeResource(pack.name);
+ m_parent_dialog->removeResource(pack, version);
}
void ResourcePage::onResourceSelected()
@@ -270,13 +269,19 @@ void ResourcePage::onResourceSelected()
return;
auto current_pack = getCurrentPack();
+ if (!current_pack.versionsLoaded)
+ return;
auto& version = current_pack.versions[m_selected_version_index];
- if (m_parent_dialog->isSelected(current_pack.name, version.fileName))
+ if (version.is_currently_selected)
removeResourceFromDialog(current_pack, version);
else
addResourceToDialog(current_pack, version);
+ // Save the modified pack (and prevent warning in release build)
+ [[maybe_unused]] bool set = setCurrentPack(current_pack);
+ Q_ASSERT(set);
+
updateSelectionButton();
/* Force redraw on the resource list when the selection changes */
diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h
index f731cf56..b51c7ccb 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.h
+++ b/launcher/ui/pages/modplatform/ResourcePage.h
@@ -50,11 +50,13 @@ class ResourcePage : public QWidget, public BasePage {
/** Programatically set the term in the search bar. */
void setSearchTerm(QString);
- [[nodiscard]] bool isPackSelected(const ModPlatform::IndexedPack&, int version = -1) const;
+ [[nodiscard]] bool setCurrentPack(ModPlatform::IndexedPack);
[[nodiscard]] auto getCurrentPack() const -> ModPlatform::IndexedPack;
[[nodiscard]] auto getDialog() const -> const ResourceDownloadDialog* { return m_parent_dialog; }
+ [[nodiscard]] auto getModel() const -> ResourceModel* { return m_model; }
+
protected:
ResourcePage(ResourceDownloadDialog* parent, BaseInstance&);
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
index cfe4080a..d0f109de 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp
@@ -2,6 +2,7 @@
#include "Json.h"
+#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
namespace ResourceDownload {
@@ -9,7 +10,7 @@ namespace ResourceDownload {
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
const char* FlameModModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" };
-FlameModModel::FlameModModel(FlameModPage* parent) : ModModel(parent, new FlameAPI) {}
+FlameModModel::FlameModModel(BaseInstance const& base) : ModModel(base, new FlameAPI) {}
void FlameModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
{
@@ -24,7 +25,7 @@ void FlameModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject&
void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_associated_page->m_base_instance);
+ FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
}
auto FlameModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
index 501937e2..7b253dce 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
+++ b/launcher/ui/pages/modplatform/flame/FlameResourceModels.h
@@ -1,9 +1,6 @@
#pragma once
-#include "modplatform/flame/FlameAPI.h"
-
#include "ui/pages/modplatform/ModModel.h"
-
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
namespace ResourceDownload {
@@ -12,10 +9,13 @@ class FlameModModel : public ModModel {
Q_OBJECT
public:
- FlameModModel(FlameModPage* parent);
+ FlameModModel(const BaseInstance&);
~FlameModModel() override = default;
private:
+ [[nodiscard]] QString debugName() const override { return Flame::debugName() + " (Model)"; }
+ [[nodiscard]] QString metaEntryBase() const override { return Flame::metaEntryBase(); }
+
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
diff --git a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
index 2a8ab526..67737a76 100644
--- a/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameResourcePages.cpp
@@ -45,7 +45,7 @@ namespace ResourceDownload {
FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance)
: ModPage(dialog, instance)
{
- m_model = new FlameModModel(this);
+ m_model = new FlameModModel(instance);
m_ui->packView->setModel(m_model);
// index is used to set the sorting with the flame api
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
index ee96f0de..9d26ae05 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp
@@ -18,8 +18,6 @@
#include "ModrinthResourceModels.h"
-#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
-
#include "modplatform/modrinth/ModrinthAPI.h"
#include "modplatform/modrinth/ModrinthPackIndex.h"
@@ -28,7 +26,7 @@ namespace ResourceDownload {
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
const char* ModrinthModModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" };
-ModrinthModModel::ModrinthModModel(ModrinthModPage* parent) : ModModel(parent, new ModrinthAPI){};
+ModrinthModModel::ModrinthModModel(BaseInstance const& base) : ModModel(base, new ModrinthAPI){};
void ModrinthModModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj)
{
@@ -42,7 +40,7 @@ void ModrinthModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObjec
void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
- ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_associated_page->m_base_instance);
+ ::Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
}
auto ModrinthModModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
index b0088a73..798a70e6 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h
@@ -19,6 +19,7 @@
#pragma once
#include "ui/pages/modplatform/ModModel.h"
+#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
namespace ResourceDownload {
@@ -28,10 +29,13 @@ class ModrinthModModel : public ModModel {
Q_OBJECT
public:
- ModrinthModModel(ModrinthModPage* parent);
+ ModrinthModModel(const BaseInstance&);
~ModrinthModModel() override = default;
private:
+ [[nodiscard]] QString debugName() const override { return Modrinth::debugName() + " (Model)"; }
+ [[nodiscard]] QString metaEntryBase() const override { return Modrinth::metaEntryBase(); }
+
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
void loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject& obj) override;
void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override;
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
index 1352e2f6..88621e05 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthResourcePages.cpp
@@ -47,7 +47,7 @@ namespace ResourceDownload {
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance)
: ModPage(dialog, instance)
{
- m_model = new ModrinthModModel(this);
+ m_model = new ModrinthModModel(instance);
m_ui->packView->setModel(m_model);
// index is used to set the sorting with the modrinth api