aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
authorTrial97 <alexandru.tripon97@gmail.com>2023-05-03 00:49:54 +0300
committerTrial97 <alexandru.tripon97@gmail.com>2023-05-03 00:49:54 +0300
commitf8bf71e152aba15d23b5b92382bb112de125d4d1 (patch)
tree682a197fc2801257578c3e431468ed968f86070e /launcher
parent61a235561896fc82a19da00126e361bb56d61c69 (diff)
downloadPrismLauncher-f8bf71e152aba15d23b5b92382bb112de125d4d1.tar.gz
PrismLauncher-f8bf71e152aba15d23b5b92382bb112de125d4d1.tar.bz2
PrismLauncher-f8bf71e152aba15d23b5b92382bb112de125d4d1.zip
Moved the selected resources to one list
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
Diffstat (limited to 'launcher')
-rw-r--r--launcher/ResourceDownloadTask.cpp11
-rw-r--r--launcher/ResourceDownloadTask.h25
-rw-r--r--launcher/modplatform/ModIndex.h1
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp59
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.h9
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp7
-rw-r--r--launcher/ui/pages/modplatform/ModPage.h2
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.cpp29
-rw-r--r--launcher/ui/pages/modplatform/ResourceModel.h14
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.cpp17
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.h13
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackPage.cpp10
-rw-r--r--launcher/ui/pages/modplatform/ShaderPackPage.h2
13 files changed, 124 insertions, 75 deletions
diff --git a/launcher/ResourceDownloadTask.cpp b/launcher/ResourceDownloadTask.cpp
index 98bcf259..f7d3487a 100644
--- a/launcher/ResourceDownloadTask.cpp
+++ b/launcher/ResourceDownloadTask.cpp
@@ -27,8 +27,9 @@
ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack pack,
ModPlatform::IndexedVersion version,
const std::shared_ptr<ResourceFolderModel> packs,
- bool is_indexed)
- : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs)
+ bool is_indexed,
+ QString custom_target_folder)
+ : m_pack(std::move(pack)), m_pack_version(std::move(version)), m_pack_model(packs), m_custom_target_folder(custom_target_folder)
{
if (auto model = dynamic_cast<ModFolderModel*>(m_pack_model.get()); model && is_indexed) {
m_update_task.reset(new LocalModUpdateTask(model->indexDir(), m_pack, m_pack_version));
@@ -40,13 +41,13 @@ ResourceDownloadTask::ResourceDownloadTask(ModPlatform::IndexedPack pack,
m_filesNetJob.reset(new NetJob(tr("Resource download"), APPLICATION->network()));
m_filesNetJob->setStatus(tr("Downloading resource:\n%1").arg(m_pack_version.downloadUrl));
- QDir dir { m_pack_model->dir() };
+ QDir dir{ m_pack_model->dir() };
{
// FIXME: Make this more generic. May require adding additional info to IndexedVersion,
// or adquiring a reference to the base instance.
- if (!m_pack_version.custom_target_folder.isEmpty()) {
+ if (!m_custom_target_folder.isEmpty()) {
dir.cdUp();
- dir.cd(m_pack_version.custom_target_folder);
+ dir.cd(m_custom_target_folder);
}
}
diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h
index 73ad2d07..fe41170a 100644
--- a/launcher/ResourceDownloadTask.h
+++ b/launcher/ResourceDownloadTask.h
@@ -22,23 +22,31 @@
#include "net/NetJob.h"
#include "tasks/SequentialTask.h"
-#include "modplatform/ModIndex.h"
#include "minecraft/mod/tasks/LocalModUpdateTask.h"
+#include "modplatform/ModIndex.h"
class ResourceFolderModel;
class ResourceDownloadTask : public SequentialTask {
Q_OBJECT
-public:
- explicit ResourceDownloadTask(ModPlatform::IndexedPack pack, ModPlatform::IndexedVersion version, const std::shared_ptr<ResourceFolderModel> packs, bool is_indexed = true);
+ public:
+ explicit ResourceDownloadTask(ModPlatform::IndexedPack pack,
+ ModPlatform::IndexedVersion version,
+ const std::shared_ptr<ResourceFolderModel> packs,
+ bool is_indexed = true,
+ QString custom_target_folder = {});
const QString& getFilename() const { return m_pack_version.fileName; }
- const QString& getCustomPath() const { return m_pack_version.custom_target_folder; }
+ const QString& getCustomPath() const { return m_custom_target_folder; }
const QVariant& getVersionID() const { return m_pack_version.fileId; }
+ const QString& getName() const { return m_pack.name; }
+ ModPlatform::IndexedPack& getPack() { return m_pack; }
+ // void setSelectedVersion(ModPlatform::IndexedVersion version) { m_pack_version = std::move(version); }
-private:
+ private:
ModPlatform::IndexedPack m_pack;
ModPlatform::IndexedVersion m_pack_version;
const std::shared_ptr<ResourceFolderModel> m_pack_model;
+ QString m_custom_target_folder;
NetJob::Ptr m_filesNetJob;
LocalModUpdateTask::Ptr m_update_task;
@@ -47,11 +55,8 @@ private:
void downloadFailed(QString reason);
void downloadSucceeded();
- std::tuple<QString, QString> to_delete {"", ""};
+ std::tuple<QString, QString> to_delete{ "", "" };
-private slots:
+ private slots:
void hasOldResource(QString name, QString filename);
};
-
-
-
diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h
index 40f1efc4..1b99a88e 100644
--- a/launcher/modplatform/ModIndex.h
+++ b/launcher/modplatform/ModIndex.h
@@ -68,7 +68,6 @@ struct IndexedVersion {
// For internal use, not provided by APIs
bool is_currently_selected = false;
- QString custom_target_folder;
};
struct ExtraPackData {
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
index 4ba38374..ef3200a2 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
@@ -20,6 +20,7 @@
#include "ResourceDownloadDialog.h"
#include <QPushButton>
+#include <algorithm>
#include "Application.h"
#include "ResourceDownloadTask.h"
@@ -118,21 +119,24 @@ void ResourceDownloadDialog::connectButtons()
void ResourceDownloadDialog::confirm()
{
- auto keys = m_selected.keys();
- keys.sort(Qt::CaseInsensitive);
+ auto selected = getTasks();
+ std::sort(selected.begin(), selected.end(), [](const DownloadTaskPtr& a, const DownloadTaskPtr& b) {
+ return QString::compare(a->getName(), b->getName(), Qt::CaseInsensitive) < 0;
+ });
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
confirm_dialog->retranslateUi(resourcesString());
- for (auto& task : keys) {
- auto selected = m_selected.constFind(task).value();
- confirm_dialog->appendResource({ task, selected->getFilename(), selected->getCustomPath() });
+ for (auto& task : selected) {
+ confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath() });
}
if (confirm_dialog->exec()) {
auto deselected = confirm_dialog->deselectedResources();
- for (auto name : deselected) {
- m_selected.remove(name);
+ for (auto page : m_container->getPages()) {
+ auto res = static_cast<ResourcePage*>(page);
+ for (auto name : deselected)
+ res->removeResourceFromPage(name);
}
this->accept();
@@ -149,32 +153,39 @@ ResourcePage* ResourceDownloadDialog::getSelectedPage()
return m_selectedPage;
}
-void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver, bool is_indexed)
+void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver)
{
- removeResource(pack, ver);
-
- ver.is_currently_selected = true;
- m_selected.insert(pack.name, makeShared<ResourceDownloadTask>(pack, ver, getBaseModel(), is_indexed));
-
- m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
+ removeResource(pack.name);
+ m_selectedPage->addResourceToPage(pack, ver, getBaseModel());
+ setButtonStatus();
}
-void ResourceDownloadDialog::removeResource(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& ver)
+void ResourceDownloadDialog::removeResource(const QString& pack_name)
{
- for (auto page : m_container->getPages())
- static_cast<ResourcePage*>(page)->removeResourceFromPage(pack.name);
-
- // Deselect the new version too, since all versions of that pack got removed.
- ver.is_currently_selected = false;
-
- m_selected.remove(pack.name);
+ for (auto page : m_container->getPages()) {
+ static_cast<ResourcePage*>(page)->removeResourceFromPage(pack_name);
+ }
+ setButtonStatus();
+}
- m_buttons.button(QDialogButtonBox::Ok)->setEnabled(!m_selected.isEmpty());
+void ResourceDownloadDialog::setButtonStatus()
+{
+ bool selected;
+ for (auto page : m_container->getPages()) {
+ auto res = static_cast<ResourcePage*>(page);
+ selected = selected || res->hasSelectedPacks();
+ }
+ m_buttons.button(QDialogButtonBox::Ok)->setEnabled(selected);
}
const QList<ResourceDownloadDialog::DownloadTaskPtr> ResourceDownloadDialog::getTasks()
{
- return m_selected.values();
+ QList<DownloadTaskPtr> selected;
+ for (auto page : m_container->getPages()) {
+ auto res = static_cast<ResourcePage*>(page);
+ selected.append(res->selectedPacks());
+ }
+ return selected;
}
void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* selected)
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.h b/launcher/ui/dialogs/ResourceDownloadDialog.h
index 5678dc8b..204e870f 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.h
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.h
@@ -62,8 +62,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
bool selectPage(QString pageId);
ResourcePage* getSelectedPage();
- void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, bool is_indexed = false);
- void removeResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
+ void addResource(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
+ void removeResource(const QString&);
const QList<DownloadTaskPtr> getTasks();
[[nodiscard]] const std::shared_ptr<ResourceFolderModel> getBaseModel() const { return m_base_model; }
@@ -79,6 +79,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
protected:
[[nodiscard]] virtual QString geometrySaveKey() const { return ""; }
+ void setButtonStatus();
protected:
const std::shared_ptr<ResourceFolderModel> m_base_model;
@@ -88,12 +89,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
QDialogButtonBox m_buttons;
QVBoxLayout m_vertical_layout;
-
- QHash<QString, DownloadTaskPtr> m_selected;
};
-
-
class ModDownloadDialog final : public ResourceDownloadDialog {
Q_OBJECT
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 8a4f55cb..a6186d89 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -145,11 +145,12 @@ void ModPage::updateVersionList()
updateSelectionButton();
}
-void ModPage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
+void ModPage::addResourceToPage(ModPlatform::IndexedPack& pack,
+ ModPlatform::IndexedVersion& version,
+ const std::shared_ptr<ResourceFolderModel> base_model)
{
bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
- m_parent_dialog->addResource(pack, version, is_indexed);
- m_model->addPack(pack);
+ m_model->addPack(pack, version, base_model, is_indexed);
}
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h
index c3b58cd6..6ecf8a94 100644
--- a/launcher/ui/pages/modplatform/ModPage.h
+++ b/launcher/ui/pages/modplatform/ModPage.h
@@ -50,7 +50,7 @@ class ModPage : public ResourcePage {
[[nodiscard]] QMap<QString, QString> urlHandlers() const override;
- void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&) override;
+ void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr<ResourceFolderModel>) override;
virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, std::optional<ResourceAPI::ModLoaderTypes> loaders = {}) const -> bool = 0;
diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp
index b83cad0d..056b28cc 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.cpp
+++ b/launcher/ui/pages/modplatform/ResourceModel.cpp
@@ -337,14 +337,15 @@ void ResourceModel::searchRequestSucceeded(QJsonDocument& doc)
ModPlatform::IndexedPack pack;
try {
loadIndexedPack(pack, packObj);
- if (auto sel = std::find_if(
- m_selected.begin(), m_selected.end(),
- [&pack](const ModPlatform::IndexedPack& i) { return i.provider == pack.provider && i.addonId == pack.addonId; });
+ if (auto sel = std::find_if(m_selected.begin(), m_selected.end(),
+ [&pack](const DownloadTaskPtr i) {
+ const auto ipack = i->getPack();
+ return ipack.provider == pack.provider && ipack.addonId == pack.addonId;
+ });
sel != m_selected.end()) {
- pack.versionsLoaded = sel->versionsLoaded;
- pack.versions = sel->versions;
- }
- newList.append(pack);
+ newList.append(sel->get()->getPack());
+ } else
+ newList.append(pack);
} catch (const JSONValidationError& e) {
qWarning() << "Error while loading resource from " << debugName() << ": " << e.cause();
continue;
@@ -450,9 +451,19 @@ void ResourceModel::infoRequestSucceeded(QJsonDocument& doc, ModPlatform::Indexe
emit projectInfoUpdated();
}
-void ResourceModel::removePack(QString& rem)
+void ResourceModel::addPack(ModPlatform::IndexedPack& pack,
+ ModPlatform::IndexedVersion& version,
+ const std::shared_ptr<ResourceFolderModel> packs,
+ bool is_indexed,
+ QString custom_target_folder)
+{
+ version.is_currently_selected = true;
+ m_selected.append(makeShared<ResourceDownloadTask>(pack, version, packs, is_indexed, custom_target_folder));
+}
+
+void ResourceModel::removePack(const QString& rem)
{
- auto pred = [&rem](const ModPlatform::IndexedPack& i) { return rem == i.name; };
+ auto pred = [&rem](const DownloadTaskPtr i) { return rem == i->getName(); };
#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
m_selected.removeIf(pred);
#else
diff --git a/launcher/ui/pages/modplatform/ResourceModel.h b/launcher/ui/pages/modplatform/ResourceModel.h
index 5eb63901..735d1687 100644
--- a/launcher/ui/pages/modplatform/ResourceModel.h
+++ b/launcher/ui/pages/modplatform/ResourceModel.h
@@ -10,6 +10,7 @@
#include "QObjectPtr.h"
+#include "ResourceDownloadTask.h"
#include "modplatform/ResourceAPI.h"
#include "tasks/ConcurrentTask.h"
@@ -29,6 +30,8 @@ class ResourceModel : public QAbstractListModel {
Q_PROPERTY(QString search_term MEMBER m_search_term WRITE setSearchTerm)
public:
+ using DownloadTaskPtr = shared_qobject_ptr<ResourceDownloadTask>;
+
ResourceModel(ResourceAPI* api);
~ResourceModel() override;
@@ -80,8 +83,13 @@ class ResourceModel : public QAbstractListModel {
/** Gets the icon at the URL for the given index. If it's not fetched yet, fetch it and update when fisinhed. */
std::optional<QIcon> getIcon(QModelIndex&, const QUrl&);
- void addPack(ModPlatform::IndexedPack& add) { m_selected.append(add); }
- void removePack(QString& rem);
+ void addPack(ModPlatform::IndexedPack& pack,
+ ModPlatform::IndexedVersion& version,
+ const std::shared_ptr<ResourceFolderModel> packs,
+ bool is_indexed = false,
+ QString custom_target_folder = {});
+ void removePack(const QString& rem);
+ QList<DownloadTaskPtr> selectedPacks() { return m_selected; }
protected:
/** Resets the model's data. */
@@ -127,7 +135,7 @@ class ResourceModel : public QAbstractListModel {
QSet<QUrl> m_failed_icon_actions;
QList<ModPlatform::IndexedPack> m_packs;
- QList<ModPlatform::IndexedPack> m_selected;
+ QList<DownloadTaskPtr> m_selected;
// HACK: We need this to prevent callbacks from calling the model after it has already been deleted.
// This leaks a tiny bit of memory per time the user has opened a resource dialog. How to make this better?
diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp
index d41503e8..4ebdea56 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.cpp
+++ b/launcher/ui/pages/modplatform/ResourcePage.cpp
@@ -37,6 +37,7 @@
*/
#include "ResourcePage.h"
+#include "modplatform/ModIndex.h"
#include "ui_ResourcePage.h"
#include <QDesktopServices>
@@ -309,15 +310,21 @@ void ResourcePage::onVersionSelectionChanged(QString data)
void ResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
{
m_parent_dialog->addResource(pack, version);
- m_model->addPack(pack);
}
-void ResourcePage::removeResourceFromDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
+void ResourcePage::removeResourceFromDialog(const QString& pack_name)
{
- m_parent_dialog->removeResource(pack, version);
+ m_parent_dialog->removeResource(pack_name);
}
-void ResourcePage::removeResourceFromPage(QString& name)
+void ResourcePage::addResourceToPage(ModPlatform::IndexedPack& pack,
+ ModPlatform::IndexedVersion& ver,
+ const std::shared_ptr<ResourceFolderModel> base_model)
+{
+ m_model->addPack(pack, ver, base_model);
+}
+
+void ResourcePage::removeResourceFromPage(const QString& name)
{
m_model->removePack(name);
}
@@ -333,7 +340,7 @@ void ResourcePage::onResourceSelected()
auto& version = current_pack.versions[m_selected_version_index];
if (version.is_currently_selected)
- removeResourceFromDialog(current_pack, version);
+ removeResourceFromDialog(current_pack.name);
else
addResourceToDialog(current_pack, version);
diff --git a/launcher/ui/pages/modplatform/ResourcePage.h b/launcher/ui/pages/modplatform/ResourcePage.h
index a9db52e3..df68e6fd 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.h
+++ b/launcher/ui/pages/modplatform/ResourcePage.h
@@ -7,10 +7,12 @@
#include <QTimer>
#include <QWidget>
+#include "ResourceDownloadTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/ResourceAPI.h"
#include "ui/pages/BasePage.h"
+#include "ui/pages/modplatform/ResourceModel.h"
#include "ui/widgets/ProgressWidget.h"
namespace Ui {
@@ -27,6 +29,7 @@ class ResourceModel;
class ResourcePage : public QWidget, public BasePage {
Q_OBJECT
public:
+ using DownloadTaskPtr = shared_qobject_ptr<ResourceDownloadTask>;
~ResourcePage() override;
/* Affects what the user sees */
@@ -72,9 +75,13 @@ class ResourcePage : public QWidget, public BasePage {
virtual void updateSelectionButton();
virtual void updateVersionList();
- virtual void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
- virtual void removeResourceFromDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
- virtual void removeResourceFromPage(QString& name);
+ void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&);
+ void removeResourceFromDialog(const QString& pack_name);
+ virtual void removeResourceFromPage(const QString& name);
+ virtual void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr<ResourceFolderModel>);
+
+ QList<DownloadTaskPtr> selectedPacks() { return m_model->selectedPacks(); }
+ bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); }
protected slots:
virtual void triggerSearch() {}
diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.cpp b/launcher/ui/pages/modplatform/ShaderPackPage.cpp
index 729e714c..c7a69418 100644
--- a/launcher/ui/pages/modplatform/ShaderPackPage.cpp
+++ b/launcher/ui/pages/modplatform/ShaderPackPage.cpp
@@ -43,12 +43,14 @@ QMap<QString, QString> ShaderPackResourcePage::urlHandlers() const
return map;
}
-void ShaderPackResourcePage::addResourceToDialog(ModPlatform::IndexedPack& pack, ModPlatform::IndexedVersion& version)
+void ShaderPackResourcePage::addResourceToPage(ModPlatform::IndexedPack& pack,
+ ModPlatform::IndexedVersion& version,
+ const std::shared_ptr<ResourceFolderModel> base_model)
{
+ QString custom_target_folder;
if (version.loaders.contains(QStringLiteral("canvas")))
- version.custom_target_folder = QStringLiteral("resourcepacks");
- m_parent_dialog->addResource(pack, version);
- m_model->addPack(pack);
+ custom_target_folder = QStringLiteral("resourcepacks");
+ m_model->addPack(pack, version, base_model, false, custom_target_folder);
}
} // namespace ResourceDownload
diff --git a/launcher/ui/pages/modplatform/ShaderPackPage.h b/launcher/ui/pages/modplatform/ShaderPackPage.h
index 972419a8..8a293f74 100644
--- a/launcher/ui/pages/modplatform/ShaderPackPage.h
+++ b/launcher/ui/pages/modplatform/ShaderPackPage.h
@@ -40,7 +40,7 @@ class ShaderPackResourcePage : public ResourcePage {
[[nodiscard]] bool supportsFiltering() const override { return false; };
- void addResourceToDialog(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&) override;
+ void addResourceToPage(ModPlatform::IndexedPack&, ModPlatform::IndexedVersion&, const std::shared_ptr<ResourceFolderModel>) override;
[[nodiscard]] QMap<QString, QString> urlHandlers() const override;