mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
remove extra encapsulations
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
323c25d83b
commit
e0b8d6e0fc
28 changed files with 517 additions and 925 deletions
|
|
@ -975,8 +975,10 @@ SET(LAUNCHER_SOURCES
|
|||
ui/pages/modplatform/ResourcePackModel.cpp
|
||||
|
||||
# Needed for MOC to find them without a corresponding .cpp
|
||||
ui/pages/modplatform/TexturePackPage.cpp
|
||||
ui/pages/modplatform/TexturePackPage.h
|
||||
ui/pages/modplatform/TexturePackModel.cpp
|
||||
ui/pages/modplatform/TexturePackModel.h
|
||||
|
||||
ui/pages/modplatform/ShaderPackPage.cpp
|
||||
ui/pages/modplatform/ShaderPackModel.cpp
|
||||
|
|
|
|||
|
|
@ -156,4 +156,8 @@ class ResourceAPI {
|
|||
*/
|
||||
|
||||
virtual void loadExtraPackInfo(ModPlatform::IndexedPack&, QJsonObject&) const = 0;
|
||||
|
||||
virtual std::pair<Task::Ptr, QByteArray*> getModCategories() = 0;
|
||||
|
||||
virtual QList<ModPlatform::Category> loadModCategories(const QByteArray& response) = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include <QList>
|
||||
#include <cstdint>
|
||||
#include "BuildConfig.h"
|
||||
#include "Json.h"
|
||||
#include "Version.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
|
@ -29,12 +28,12 @@ class FlameAPI : public ResourceAPI {
|
|||
std::pair<Task::Ptr, QByteArray*> getFile(const QString& addonId, const QString& fileId) const;
|
||||
|
||||
static std::pair<Task::Ptr, QByteArray*> getCategories(ModPlatform::ResourceType type);
|
||||
static std::pair<Task::Ptr, QByteArray*> getModCategories();
|
||||
static QList<ModPlatform::Category> loadModCategories(const QByteArray& response);
|
||||
std::pair<Task::Ptr, QByteArray*> getModCategories() override;
|
||||
QList<ModPlatform::Category> loadModCategories(const QByteArray& response) override;
|
||||
|
||||
QList<ResourceAPI::SortingMethod> getSortingMethods() const override;
|
||||
|
||||
static inline bool validateModLoaders(ModPlatform::ModLoaderTypes loaders)
|
||||
static bool validateModLoaders(ModPlatform::ModLoaderTypes loaders)
|
||||
{
|
||||
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt);
|
||||
}
|
||||
|
|
@ -84,7 +83,7 @@ class FlameAPI : public ResourceAPI {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types)
|
||||
static QStringList getModLoaderStrings(const ModPlatform::ModLoaderTypes types)
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt }) {
|
||||
|
|
@ -95,7 +94,7 @@ class FlameAPI : public ResourceAPI {
|
|||
return l;
|
||||
}
|
||||
|
||||
static const QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; }
|
||||
static QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; }
|
||||
|
||||
public:
|
||||
std::optional<QString> getSearchURL(const SearchArgs& args) const override
|
||||
|
|
@ -104,22 +103,27 @@ class FlameAPI : public ResourceAPI {
|
|||
get_arguments.append(QString("classId=%1").arg(getClassId(args.type)));
|
||||
get_arguments.append(QString("index=%1").arg(args.offset));
|
||||
get_arguments.append("pageSize=25");
|
||||
if (args.search.has_value())
|
||||
if (args.search.has_value()) {
|
||||
get_arguments.append(QString("searchFilter=%1").arg(args.search.value()));
|
||||
if (args.sorting.has_value())
|
||||
}
|
||||
if (args.sorting.has_value()) {
|
||||
get_arguments.append(QString("sortField=%1").arg(args.sorting.value().index));
|
||||
}
|
||||
get_arguments.append("sortOrder=desc");
|
||||
if (args.loaders.has_value()) {
|
||||
ModPlatform::ModLoaderTypes loaders = args.loaders.value();
|
||||
loaders &= ~static_cast<std::uint16_t>(ModPlatform::ModLoaderType::DataPack);
|
||||
if (loaders != 0)
|
||||
if (loaders != 0) {
|
||||
get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(loaders)));
|
||||
}
|
||||
}
|
||||
if (args.categoryIds.has_value() && !args.categoryIds->empty())
|
||||
if (args.categoryIds.has_value() && !args.categoryIds->empty()) {
|
||||
get_arguments.append(QString("categoryIds=[%1]").arg(args.categoryIds->join(",")));
|
||||
}
|
||||
|
||||
if (args.versions.has_value() && !args.versions.value().empty())
|
||||
if (args.versions.has_value() && !args.versions.value().empty()) {
|
||||
get_arguments.append(QString("gameVersion=%1").arg(args.versions.value().front().toString()));
|
||||
}
|
||||
|
||||
return BuildConfig.FLAME_BASE_URL + "/mods/search?gameId=432&" + get_arguments.join('&');
|
||||
}
|
||||
|
|
@ -129,8 +133,9 @@ class FlameAPI : public ResourceAPI {
|
|||
auto addonId = args.pack->addonId.toString();
|
||||
QString url = QString(BuildConfig.FLAME_BASE_URL + "/mods/%1/files?pageSize=10000").arg(addonId);
|
||||
|
||||
if (args.mcVersions.has_value())
|
||||
if (args.mcVersions.has_value()) {
|
||||
url += QString("&gameVersion=%1").arg(args.mcVersions.value().front().toString());
|
||||
}
|
||||
|
||||
if (args.loaders.has_value() && args.loaders.value() != ModPlatform::ModLoaderType::DataPack &&
|
||||
ModPlatform::hasSingleModLoaderSelected(args.loaders.value())) {
|
||||
|
|
@ -157,7 +162,7 @@ class FlameAPI : public ResourceAPI {
|
|||
}
|
||||
return {};
|
||||
};
|
||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, [[maybe_unused]] QJsonObject&) const override { FlameMod::loadBody(m); }
|
||||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, [[maybe_unused]] QJsonObject& /*unused*/) const override { FlameMod::loadBody(m); }
|
||||
|
||||
private:
|
||||
std::optional<QString> getInfoURL(const QString& id) const override { return QString(BuildConfig.FLAME_BASE_URL + "/mods/%1").arg(id); }
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ class ModrinthAPI : public ResourceAPI {
|
|||
|
||||
std::pair<Task::Ptr, QByteArray*> getProjects(QStringList addonIds) const override;
|
||||
|
||||
static std::pair<Task::Ptr, QByteArray*> getModCategories();
|
||||
static QList<ModPlatform::Category> loadCategories(const QByteArray& response, const QString& projectType);
|
||||
static QList<ModPlatform::Category> loadModCategories(const QByteArray& response);
|
||||
std::pair<Task::Ptr, QByteArray*> getModCategories() override;
|
||||
static QList<ModPlatform::Category> loadCategories(const QByteArray& response, QString projectType);
|
||||
QList<ModPlatform::Category> loadModCategories(const QByteArray& response) override;
|
||||
|
||||
public:
|
||||
auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||
|
|
@ -180,7 +180,7 @@ class ModrinthAPI : public ResourceAPI {
|
|||
return BuildConfig.MODRINTH_PROD_URL + "/project/" + id;
|
||||
};
|
||||
|
||||
auto getMultipleModInfoURL(const QStringList& ids) const -> QString
|
||||
static auto getMultipleModInfoURL(const QStringList& ids) -> QString
|
||||
{
|
||||
return BuildConfig.MODRINTH_PROD_URL + QString("/projects?ids=[\"%1\"]").arg(ids.join("\",\""));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -308,12 +308,12 @@ QList<BasePage*> ModDownloadDialog::getPages()
|
|||
auto loaders = static_cast<MinecraftInstance*>(m_instance)->getPackProfile()->getSupportedModLoaders().value();
|
||||
|
||||
if (ModrinthAPI::validateModLoaders(loaders)) {
|
||||
auto* page = ModrinthModPage::create(this, *m_instance);
|
||||
auto* page = Modrinth::createModPage(this, *m_instance);
|
||||
page->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(page);
|
||||
}
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders)) {
|
||||
auto* page = FlameModPage::create(this, *m_instance);
|
||||
auto* page = Flame::createModPage(this, *m_instance);
|
||||
page->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(page);
|
||||
}
|
||||
|
|
@ -356,11 +356,11 @@ QList<BasePage*> ResourcePackDownloadDialog::getPages()
|
|||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* modrinthPage = ModrinthResourcePackPage::create(this, *m_instance);
|
||||
auto* modrinthPage = Modrinth::createResourcePackResourcePage(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameResourcePackPage::create(this, *m_instance);
|
||||
auto* flamePage = Flame::createResourcePackResourcePage(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
|
@ -388,11 +388,11 @@ QList<BasePage*> TexturePackDownloadDialog::getPages()
|
|||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* modrinthPage = ModrinthTexturePackPage::create(this, *m_instance);
|
||||
auto* modrinthPage =Modrinth::createTexturePackResourcePage(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameTexturePackPage::create(this, *m_instance);
|
||||
auto* flamePage = Flame::createTexturePackResourcePage(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
|
@ -419,11 +419,11 @@ ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent,
|
|||
QList<BasePage*> ShaderPackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
auto* modrinthPage = ModrinthShaderPackPage::create(this, *m_instance);
|
||||
auto* modrinthPage = Modrinth::createShaderPackResourcePage(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameShaderPackPage::create(this, *m_instance);
|
||||
auto* flamePage = Flame::createShaderPackResourcePage(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
|
@ -467,11 +467,11 @@ DataPackDownloadDialog::DataPackDownloadDialog(QWidget* parent,
|
|||
QList<BasePage*> DataPackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
auto* modrinthPage = ModrinthDataPackPage::create(this, *m_instance);
|
||||
auto* modrinthPage =Modrinth::createDataPackResourcePage(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameDataPackPage::create(this, *m_instance);
|
||||
auto* flamePage = Flame::createDataPackResourcePage(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,52 @@
|
|||
|
||||
namespace ResourceDownload {
|
||||
|
||||
DataPackResourcePage::DataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) {}
|
||||
static ResourceDescriptor prepareDataPackDescriptor()
|
||||
{
|
||||
QMap<QString, QString> urlHandlers;
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return {
|
||||
.helpPage = {},
|
||||
//: The singular version of 'data packs'
|
||||
.resourceString = QObject::tr("data pack"),
|
||||
//: The plural version of 'data pack'
|
||||
.resourcesString = QObject::tr("data packs"),
|
||||
.supportsFiltering = false,
|
||||
.isIndexed = true,
|
||||
.urlHandlers = urlHandlers,
|
||||
};
|
||||
}
|
||||
|
||||
DataPackResourcePage::DataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api)
|
||||
: ResourcePage(dialog, instance, prepareDataPackDescriptor(), p)
|
||||
{
|
||||
m_model = new DataPackResourceModel(instance, api, debugName(), metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_model, &ResourceModel::versionListUpdated, this, &ResourcePage::versionListUpdated);
|
||||
connect(m_model, &ResourceModel::projectInfoUpdated, this, &ResourcePage::updateUi);
|
||||
connect(m_model, &QAbstractListModel::modelReset, this, &ResourcePage::modelReset);
|
||||
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &DataPackResourcePage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &DataPackResourcePage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &DataPackResourcePage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &DataPackResourcePage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||
|
||||
void DataPackResourcePage::triggerSearch()
|
||||
{
|
||||
m_ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
|
@ -30,14 +70,4 @@ void DataPackResourcePage::triggerSearch()
|
|||
m_fetchProgress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
QMap<QString, QString> DataPackResourcePage::urlHandlers() const
|
||||
{
|
||||
QMap<QString, QString> map;
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return map;
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -5,45 +5,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/DataPackModel.h"
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class DataPackDownloadDialog;
|
||||
|
||||
class DataPackResourcePage : public ResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(DataPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto model = static_cast<DataPackResourceModel*>(page->getModel());
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
connect(model, &QAbstractListModel::modelReset, page, &ResourcePage::modelReset);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
//: The plural version of 'data pack'
|
||||
inline QString resourcesString() const override { return tr("data packs"); }
|
||||
//: The singular version of 'data packs'
|
||||
inline QString resourceString() const override { return tr("data pack"); }
|
||||
|
||||
bool supportsFiltering() const override { return false; };
|
||||
|
||||
QMap<QString, QString> urlHandlers() const override;
|
||||
|
||||
protected:
|
||||
DataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
DataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api);
|
||||
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
|
|
|
|||
|
|
@ -40,38 +40,75 @@
|
|||
#include "ModPage.h"
|
||||
#include "ui_ResourcePage.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QKeyEvent>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance)
|
||||
namespace {
|
||||
ResourceDownload::ResourceDescriptor prepareModDescriptor()
|
||||
{
|
||||
QMap<QString, QString> urlHandlers;
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern(R"((?:www\.)?modrinth\.com\/mod\/([^\/]+)\/?)"), "modrinth");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern(R"((?:www\.)?curseforge\.com\/minecraft\/mc-mods\/([^\/]+)\/?)"), "curseforge");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern(R"(minecraft\.curseforge\.com\/projects\/([^\/]+)\/?)"), "curseforge");
|
||||
return {
|
||||
.helpPage = "Mod-platform",
|
||||
//: The singular version of 'mods'
|
||||
.resourceString = QObject::tr("mod"),
|
||||
//: The plural version of 'mod'
|
||||
.resourcesString = QObject::tr("mods"),
|
||||
.supportsFiltering = true,
|
||||
.isIndexed = true,
|
||||
.urlHandlers = urlHandlers,
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace ResourceDownload {
|
||||
ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api, ModFilterWidget* filterWidget)
|
||||
: ResourcePage(dialog, instance, prepareModDescriptor(), std::move(p)), m_api(api)
|
||||
{
|
||||
auto* model = new ModModel(instance, api, debugName(), metaEntryBase());
|
||||
m_model = model;
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
setFilterWidget(filterWidget);
|
||||
model->setFilter(getFilter());
|
||||
|
||||
connect(m_model, &ResourceModel::versionListUpdated, this, &ResourcePage::versionListUpdated);
|
||||
connect(m_model, &ResourceModel::projectInfoUpdated, this, &ResourcePage::updateUi);
|
||||
connect(m_model, &QAbstractListModel::modelReset, this, &ResourcePage::modelReset);
|
||||
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
connect(m_ui->resourceFilterButton, &QPushButton::clicked, this, &ModPage::filterMods);
|
||||
}
|
||||
|
||||
void ModPage::setFilterWidget(std::unique_ptr<ModFilterWidget>& widget)
|
||||
void ModPage::setFilterWidget(ModFilterWidget* widget)
|
||||
{
|
||||
if (m_filter_widget) {
|
||||
disconnect(m_filter_widget.get(), nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
auto* old = m_ui->splitter->replaceWidget(0, widget.get());
|
||||
auto* old = m_ui->splitter->replaceWidget(0, widget);
|
||||
// because we replaced the widget we also need to delete it
|
||||
if (old) {
|
||||
old->deleteLater();
|
||||
}
|
||||
|
||||
delete old;
|
||||
|
||||
m_filter_widget.swap(widget);
|
||||
m_filter_widget.reset(widget);
|
||||
|
||||
m_filter = m_filter_widget->getFilter();
|
||||
|
||||
|
|
@ -100,24 +137,14 @@ void ModPage::triggerSearch()
|
|||
m_fetchProgress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
QMap<QString, QString> ModPage::urlHandlers() const
|
||||
void ModPage::prepareProviderCategories()
|
||||
{
|
||||
QMap<QString, QString> map;
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/mod\\/([^\\/]+)\\/?"), "modrinth");
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)\\/?"), "curseforge");
|
||||
map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return map;
|
||||
}
|
||||
|
||||
/******** Make changes to the UI ********/
|
||||
|
||||
void ModPage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack,
|
||||
ModPlatform::IndexedVersion& version,
|
||||
ResourceFolderModel* baseModel,
|
||||
QString downloadReason)
|
||||
{
|
||||
bool isIndexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||
m_model->addPack(pack, version, baseModel, isIndexed, downloadReason);
|
||||
}
|
||||
|
||||
auto [task, response] = m_api->getModCategories();
|
||||
m_categoriesTask = task;
|
||||
connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
|
||||
auto categories = m_api->loadModCategories(*response);
|
||||
m_filter_widget->setCategories(categories);
|
||||
});
|
||||
m_categoriesTask->start();
|
||||
};
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -6,16 +6,10 @@
|
|||
|
||||
#include <QWidget>
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "ui/pages/modplatform/ModModel.h"
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
#include "ui/widgets/ModFilterWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ModDownloadDialog;
|
||||
|
|
@ -25,45 +19,13 @@ class ModPage : public ResourcePage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto* model = static_cast<ModModel*>(page->getModel());
|
||||
auto getFilter() const -> const std::shared_ptr<ModFilterWidget::Filter> { return m_filter; }
|
||||
|
||||
auto filterWidget = page->createFilterWidget();
|
||||
page->setFilterWidget(filterWidget);
|
||||
model->setFilter(page->getFilter());
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
connect(model, &QAbstractListModel::modelReset, page, &ResourcePage::modelReset);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
//: The plural version of 'mod'
|
||||
QString resourcesString() const override { return tr("mods"); }
|
||||
//: The singular version of 'mods'
|
||||
QString resourceString() const override { return tr("mod"); }
|
||||
|
||||
QMap<QString, QString> urlHandlers() const override;
|
||||
|
||||
void addResourceToPage(ModPlatform::IndexedPack::Ptr /*unused*/,
|
||||
ModPlatform::IndexedVersion& /*unused*/,
|
||||
ResourceFolderModel* /*unused*/,
|
||||
QString downloadReason = "standalone") override;
|
||||
|
||||
virtual std::unique_ptr<ModFilterWidget> createFilterWidget() = 0;
|
||||
|
||||
bool supportsFiltering() const override { return true; };
|
||||
auto getFilter() const -> std::shared_ptr<ModFilterWidget::Filter> { return m_filter; }
|
||||
void setFilterWidget(std::unique_ptr<ModFilterWidget>&);
|
||||
ModPage(ModDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api, ModFilterWidget* filterWidget);
|
||||
|
||||
protected:
|
||||
ModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
|
||||
virtual void prepareProviderCategories() {};
|
||||
void prepareProviderCategories();
|
||||
void setFilterWidget(ModFilterWidget*);
|
||||
|
||||
protected slots:
|
||||
virtual void filterMods();
|
||||
|
|
@ -72,6 +34,8 @@ class ModPage : public ResourcePage {
|
|||
protected:
|
||||
std::unique_ptr<ModFilterWidget> m_filter_widget;
|
||||
std::shared_ptr<ModFilterWidget::Filter> m_filter;
|
||||
Task::Ptr m_categoriesTask;
|
||||
ResourceAPI* m_api = nullptr;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -13,8 +13,49 @@
|
|||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance)
|
||||
{}
|
||||
static ResourceDescriptor prepareResourcePackDescriptor()
|
||||
{
|
||||
QMap<QString, QString> urlHandlers;
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return {
|
||||
.helpPage = {},
|
||||
//: The singular version of 'resource packs'
|
||||
.resourceString = QObject::tr("resource pack"),
|
||||
//: The plural version of 'resource pack'
|
||||
.resourcesString = QObject::tr("resource packs"),
|
||||
.supportsFiltering = false,
|
||||
.isIndexed = true,
|
||||
.urlHandlers = urlHandlers,
|
||||
};
|
||||
}
|
||||
|
||||
ResourcePackResourcePage::ResourcePackResourcePage(ResourceDownloadDialog* dialog,
|
||||
BaseInstance& instance,
|
||||
ResourceProviderData p,
|
||||
ResourceAPI* api)
|
||||
: ResourcePage(dialog, instance, prepareResourcePackDescriptor(), p)
|
||||
{
|
||||
m_model = new ResourcePackResourceModel(instance, api, debugName(), metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_model, &ResourceModel::versionListUpdated, this, &ResourcePage::versionListUpdated);
|
||||
connect(m_model, &ResourceModel::projectInfoUpdated, this, &ResourcePage::updateUi);
|
||||
connect(m_model, &QAbstractListModel::modelReset, this, &ResourcePage::modelReset);
|
||||
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ResourcePackResourcePage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ResourcePackResourcePage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ResourcePackResourcePage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ResourcePackResourcePage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||
|
||||
|
|
@ -31,14 +72,4 @@ void ResourcePackResourcePage::triggerSearch()
|
|||
m_fetchProgress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
QMap<QString, QString> ResourcePackResourcePage::urlHandlers() const
|
||||
{
|
||||
QMap<QString, QString> map;
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
map.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return map;
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -4,13 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ResourcePackModel.h"
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ResourcePackDownloadDialog;
|
||||
|
|
@ -19,32 +14,7 @@ class ResourcePackResourcePage : public ResourcePage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto model = static_cast<ResourcePackResourceModel*>(page->getModel());
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
connect(model, &QAbstractListModel::modelReset, page, &ResourcePage::modelReset);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
//: The plural version of 'resource pack'
|
||||
inline QString resourcesString() const override { return tr("resource packs"); }
|
||||
//: The singular version of 'resource packs'
|
||||
inline QString resourceString() const override { return tr("resource pack"); }
|
||||
|
||||
bool supportsFiltering() const override { return false; };
|
||||
|
||||
QMap<QString, QString> urlHandlers() const override;
|
||||
|
||||
inline auto helpPage() const -> QString override { return "resourcepack-platform"; }
|
||||
|
||||
protected:
|
||||
ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
ResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api);
|
||||
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
|
|
|
|||
|
|
@ -57,8 +57,17 @@
|
|||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourcePage::ResourcePage(ResourceDownloadDialog* parent, BaseInstance& baseInstance)
|
||||
: QWidget(parent), m_baseInstance(baseInstance), m_ui(new Ui::ResourcePage), m_parentDialog(parent), m_fetchProgress(this, false)
|
||||
ResourcePage::ResourcePage(ResourceDownloadDialog* parent,
|
||||
BaseInstance& baseInstance,
|
||||
ResourceDescriptor desc,
|
||||
ResourceProviderData provider)
|
||||
: QWidget(parent)
|
||||
, m_baseInstance(baseInstance)
|
||||
, m_ui(new Ui::ResourcePage)
|
||||
, m_parentDialog(parent)
|
||||
, m_fetchProgress(this, false)
|
||||
, m_desc(std::move(desc))
|
||||
, m_provider(std::move(provider))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
|
|
@ -400,7 +409,7 @@ void ResourcePage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack,
|
|||
ResourceFolderModel* baseModel,
|
||||
QString downloadReason)
|
||||
{
|
||||
bool isIndexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||
bool isIndexed = m_desc.isIndexed && !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||
m_model->addPack(std::move(pack), ver, baseModel, isIndexed, std::move(downloadReason));
|
||||
}
|
||||
|
||||
|
|
@ -488,8 +497,18 @@ void ResourcePage::onResourceToggle(const QModelIndex& index)
|
|||
}
|
||||
}
|
||||
|
||||
void ResourcePage::openUrl(const QUrl& url)
|
||||
void ResourcePage::openUrl(const QUrl& _url)
|
||||
{
|
||||
auto url = _url;
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
url = QUrl::fromPercentEncoding(query.toUtf8()); // double decoding is necessary
|
||||
}
|
||||
}
|
||||
// do not allow other url schemes for security reasons
|
||||
if (!(url.scheme() == "http" || url.scheme() == "https")) {
|
||||
qWarning() << "Unsupported scheme" << url.scheme();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,24 @@ namespace ResourceDownload {
|
|||
class ResourceDownloadDialog;
|
||||
class ResourceModel;
|
||||
|
||||
struct ResourceProviderData {
|
||||
QString displayName;
|
||||
QIcon icon;
|
||||
QString id;
|
||||
QString metaEntryBase;
|
||||
QString debugName;
|
||||
};
|
||||
|
||||
struct ResourceDescriptor {
|
||||
QString helpPage;
|
||||
QString resourceString = QObject::tr("resource");
|
||||
QString resourcesString = QObject::tr("resources");
|
||||
|
||||
bool supportsFiltering = false;
|
||||
bool isIndexed = true;
|
||||
QMap<QString, QString> urlHandlers;
|
||||
};
|
||||
|
||||
class ResourcePage : public QWidget, public BasePage {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
|
@ -32,23 +50,23 @@ class ResourcePage : public QWidget, public BasePage {
|
|||
~ResourcePage() override;
|
||||
|
||||
/* Affects what the user sees */
|
||||
auto displayName() const -> QString override = 0;
|
||||
auto icon() const -> QIcon override = 0;
|
||||
auto id() const -> QString override = 0;
|
||||
auto helpPage() const -> QString override = 0;
|
||||
bool shouldDisplay() const override = 0;
|
||||
auto displayName() const -> QString override { return m_provider.displayName; };
|
||||
auto icon() const -> QIcon override { return m_provider.icon; };
|
||||
auto id() const -> QString override { return m_provider.id; };
|
||||
auto helpPage() const -> QString override { return m_desc.helpPage; };
|
||||
bool shouldDisplay() const override { return true; };
|
||||
|
||||
/* Used internally */
|
||||
virtual auto metaEntryBase() const -> QString = 0;
|
||||
virtual auto debugName() const -> QString = 0;
|
||||
virtual auto metaEntryBase() const -> QString { return m_provider.metaEntryBase; };
|
||||
virtual auto debugName() const -> QString { return m_provider.debugName; };
|
||||
|
||||
//: The plural version of 'resource'
|
||||
virtual QString resourcesString() const { return tr("resources"); }
|
||||
virtual QString resourcesString() const { return m_desc.resourcesString; }
|
||||
//: The singular version of 'resources'
|
||||
virtual QString resourceString() const { return tr("resource"); }
|
||||
virtual QString resourceString() const { return m_desc.resourceString; }
|
||||
|
||||
/* Features this resource's page supports */
|
||||
virtual bool supportsFiltering() const = 0;
|
||||
virtual bool supportsFiltering() const { return m_desc.supportsFiltering; };
|
||||
|
||||
void retranslate() override;
|
||||
void openedImpl() override;
|
||||
|
|
@ -65,7 +83,10 @@ class ResourcePage : public QWidget, public BasePage {
|
|||
auto getModel() const -> ResourceModel* { return m_model; }
|
||||
|
||||
protected:
|
||||
ResourcePage(ResourceDownloadDialog* parent, BaseInstance&);
|
||||
ResourcePage(ResourceDownloadDialog* parent,
|
||||
BaseInstance& baseInstance,
|
||||
ResourceDescriptor desc = {},
|
||||
ResourceProviderData provider = {});
|
||||
|
||||
void addSortings();
|
||||
|
||||
|
|
@ -100,7 +121,7 @@ class ResourcePage : public QWidget, public BasePage {
|
|||
void onResourceToggle(const QModelIndex& index);
|
||||
|
||||
/** Associates regex expressions to pages in the order they're given in the map. */
|
||||
virtual QMap<QString, QString> urlHandlers() const = 0;
|
||||
virtual QMap<QString, QString> urlHandlers() const { return m_desc.urlHandlers; };
|
||||
virtual void openUrl(const QUrl&);
|
||||
|
||||
public:
|
||||
|
|
@ -123,6 +144,9 @@ class ResourcePage : public QWidget, public BasePage {
|
|||
|
||||
QSet<int> m_enableQueue;
|
||||
|
||||
ResourceDescriptor m_desc;
|
||||
ResourceProviderData m_provider;
|
||||
|
||||
private:
|
||||
bool m_suppressInitialSearch = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,19 +3,59 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include "ShaderPackPage.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "ui_ResourcePage.h"
|
||||
|
||||
#include "ShaderPackModel.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance) : ResourcePage(dialog, instance) {}
|
||||
static ResourceDescriptor prepareShaderPackDescriptor()
|
||||
{
|
||||
QMap<QString, QString> urlHandlers;
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/shaders\\/([^\\/]+)\\/?"), "modrinth");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/customization\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return {
|
||||
.helpPage = {},
|
||||
//: The singular version of 'shader packs'
|
||||
.resourceString = QObject::tr("shader pack"),
|
||||
//: The plural version of 'shader pack'
|
||||
.resourcesString = QObject::tr("shader packs"),
|
||||
.supportsFiltering = false,
|
||||
.isIndexed = true,
|
||||
.urlHandlers = urlHandlers,
|
||||
};
|
||||
}
|
||||
|
||||
ShaderPackResourcePage::ShaderPackResourcePage(ShaderPackDownloadDialog* dialog,
|
||||
BaseInstance& instance,
|
||||
ResourceProviderData p,
|
||||
ResourceAPI* api)
|
||||
: ResourcePage(dialog, instance, prepareShaderPackDescriptor(), p)
|
||||
{
|
||||
m_model = new ShaderPackResourceModel(instance, api, debugName(), metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_model, &ResourceModel::versionListUpdated, this, &ResourcePage::versionListUpdated);
|
||||
connect(m_model, &ResourceModel::projectInfoUpdated, this, &ResourcePage::updateUi);
|
||||
connect(m_model, &QAbstractListModel::modelReset, this, &ResourcePage::modelReset);
|
||||
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ShaderPackResourcePage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ShaderPackResourcePage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ShaderPackResourcePage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ShaderPackResourcePage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||
|
||||
|
|
@ -32,22 +72,4 @@ void ShaderPackResourcePage::triggerSearch()
|
|||
m_fetchProgress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
QMap<QString, QString> ShaderPackResourcePage::urlHandlers() const
|
||||
{
|
||||
QMap<QString, QString> map;
|
||||
map.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/shaders\\/([^\\/]+)\\/?"), "modrinth");
|
||||
map.insert(QRegularExpression::anchoredPattern(R"((?:www\.)?curseforge\.com\/minecraft\/customization\/([^\/]+)\/?)"), "curseforge");
|
||||
map.insert(QRegularExpression::anchoredPattern(R"(minecraft\.curseforge\.com\/projects\/([^\/]+)\/?)"), "curseforge");
|
||||
return map;
|
||||
}
|
||||
|
||||
void ShaderPackResourcePage::addResourceToPage(ModPlatform::IndexedPack::Ptr pack,
|
||||
ModPlatform::IndexedVersion& version,
|
||||
ResourceFolderModel* baseModel,
|
||||
QString downloadReason)
|
||||
{
|
||||
bool isIndexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool();
|
||||
m_model->addPack(pack, version, baseModel, isIndexed, downloadReason);
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
#include "ui/pages/modplatform/ShaderPackModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
|
|
@ -19,37 +14,7 @@ class ShaderPackResourcePage : public ResourcePage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto* model = static_cast<ShaderPackResourceModel*>(page->getModel());
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
connect(model, &QAbstractListModel::modelReset, page, &ResourcePage::modelReset);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
//: The plural version of 'shader pack'
|
||||
QString resourcesString() const override { return tr("shader packs"); }
|
||||
//: The singular version of 'shader packs'
|
||||
QString resourceString() const override { return tr("shader pack"); }
|
||||
|
||||
bool supportsFiltering() const override { return false; };
|
||||
|
||||
void addResourceToPage(ModPlatform::IndexedPack::Ptr /*unused*/,
|
||||
ModPlatform::IndexedVersion& /*unused*/,
|
||||
ResourceFolderModel* /*unused*/,
|
||||
QString downloadReason = "standalone") override;
|
||||
|
||||
QMap<QString, QString> urlHandlers() const override;
|
||||
|
||||
auto helpPage() const -> QString override { return "shaderpack-platform"; }
|
||||
|
||||
protected:
|
||||
ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
ShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api);
|
||||
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
|
|
|
|||
79
launcher/ui/pages/modplatform/TexturePackPage.cpp
Normal file
79
launcher/ui/pages/modplatform/TexturePackPage.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// SPDX-FileCopyrightText: 2023 flowln <flowlnlnln@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include "TexturePackPage.h"
|
||||
#include "ui_ResourcePage.h"
|
||||
|
||||
#include "TexturePackModel.h"
|
||||
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
static ResourceDescriptor prepareResourcePackDescriptor()
|
||||
{
|
||||
QMap<QString, QString> urlHandlers;
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/resourcepack\\/([^\\/]+)\\/?"), "modrinth");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/texture-packs\\/([^\\/]+)\\/?"),
|
||||
"curseforge");
|
||||
urlHandlers.insert(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?"), "curseforge");
|
||||
return {
|
||||
.helpPage = {},
|
||||
//: The singular version of 'texture packs'
|
||||
.resourceString = QObject::tr("texture pack"),
|
||||
//: The plural version of 'texture pack'
|
||||
.resourcesString = QObject::tr("texture packs"),
|
||||
.supportsFiltering = false,
|
||||
.isIndexed = true,
|
||||
.urlHandlers = urlHandlers,
|
||||
};
|
||||
}
|
||||
|
||||
TexturePackResourcePage::TexturePackResourcePage(TexturePackDownloadDialog* dialog,
|
||||
BaseInstance& instance,
|
||||
ResourceProviderData p,
|
||||
ResourceAPI* api,
|
||||
TexturePackResourceModel* model)
|
||||
: ResourcePage(dialog, instance, prepareResourcePackDescriptor(), p)
|
||||
{
|
||||
m_model = model;
|
||||
if (!m_model) {
|
||||
m_model = new TexturePackResourceModel(instance, api, debugName(), metaEntryBase());
|
||||
}
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_model, &ResourceModel::versionListUpdated, this, &ResourcePage::versionListUpdated);
|
||||
connect(m_model, &ResourceModel::projectInfoUpdated, this, &ResourcePage::updateUi);
|
||||
connect(m_model, &QAbstractListModel::modelReset, this, &ResourcePage::modelReset);
|
||||
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &TexturePackResourcePage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TexturePackResourcePage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &TexturePackResourcePage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &TexturePackResourcePage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||
|
||||
void TexturePackResourcePage::triggerSearch()
|
||||
{
|
||||
m_ui->packView->selectionModel()->setCurrentIndex({}, QItemSelectionModel::SelectionFlag::ClearAndSelect);
|
||||
m_ui->packView->clearSelection();
|
||||
m_ui->packDescription->clear();
|
||||
m_ui->versionSelectionBox->clear();
|
||||
|
||||
updateSelectionButton();
|
||||
|
||||
static_cast<ResourcePackResourceModel*>(m_model)->searchWithTerm(getSearchTerm(), m_ui->sortByBox->currentData().toUInt());
|
||||
m_fetchProgress.watch(m_model->activeSearchJob().get());
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
@ -4,43 +4,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||
#include "ui/pages/modplatform/TexturePackModel.h"
|
||||
#include "ui_ResourcePage.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class TexturePackDownloadDialog;
|
||||
class TexturePackResourceModel;
|
||||
|
||||
class TexturePackResourcePage : public ResourcePackResourcePage {
|
||||
class TexturePackResourcePage : public ResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static T* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
auto page = new T(dialog, instance);
|
||||
auto model = static_cast<TexturePackResourceModel*>(page->getModel());
|
||||
TexturePackResourcePage(TexturePackDownloadDialog* dialog,
|
||||
BaseInstance& instance,
|
||||
ResourceProviderData p,
|
||||
ResourceAPI* api,
|
||||
TexturePackResourceModel* model = nullptr);
|
||||
|
||||
connect(model, &ResourceModel::versionListUpdated, page, &ResourcePage::versionListUpdated);
|
||||
connect(model, &ResourceModel::projectInfoUpdated, page, &ResourcePage::updateUi);
|
||||
connect(model, &QAbstractListModel::modelReset, page, &ResourcePage::modelReset);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
//: The plural version of 'texture pack'
|
||||
inline QString resourcesString() const override { return tr("texture packs"); }
|
||||
//: The singular version of 'texture packs'
|
||||
inline QString resourceString() const override { return tr("texture pack"); }
|
||||
|
||||
protected:
|
||||
TexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance) : ResourcePackResourcePage(dialog, instance) {}
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -51,14 +51,12 @@
|
|||
#include "ui/dialogs/NewInstanceDialog.h"
|
||||
#include "ui/widgets/ProjectItem.h"
|
||||
|
||||
static FlameAPI api;
|
||||
|
||||
FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent), m_ui(new Ui::FlamePage), m_dialog(dialog), m_fetch_progress(this, false)
|
||||
: QWidget(parent), m_ui(new Ui::FlamePage), m_dialog(dialog), m_listModel(new Flame::ListModel(this)), m_fetch_progress(this, false)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->searchEdit->installEventFilter(this);
|
||||
m_listModel = new Flame::ListModel(this);
|
||||
|
||||
m_ui->packView->setModel(m_listModel);
|
||||
|
||||
m_ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
|
@ -101,17 +99,17 @@ FlamePage::~FlamePage()
|
|||
bool FlamePage::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
if (watched == m_ui->searchEdit && event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
auto* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Return) {
|
||||
triggerSearch();
|
||||
keyEvent->accept();
|
||||
return true;
|
||||
} else {
|
||||
if (m_search_timer.isActive())
|
||||
m_search_timer.stop();
|
||||
|
||||
m_search_timer.start(350);
|
||||
}
|
||||
if (m_search_timer.isActive()) {
|
||||
m_search_timer.stop();
|
||||
}
|
||||
|
||||
m_search_timer.start(350);
|
||||
}
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
|
@ -171,8 +169,9 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde
|
|||
m_current->versions = doc;
|
||||
m_current->versionsLoaded = true;
|
||||
auto pred = [this](const ModPlatform::IndexedVersion& v) {
|
||||
if (auto filter = m_filterWidget->getFilter())
|
||||
if (auto filter = m_filterWidget->getFilter()) {
|
||||
return !filter->checkModpackFilters(v);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
|
||||
|
|
@ -184,15 +183,16 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde
|
|||
else
|
||||
++it;
|
||||
#endif
|
||||
for (auto version : m_current->versions) {
|
||||
for (const auto& version : m_current->versions) {
|
||||
m_ui->versionSelectionBox->addItem(version.getVersionDisplayString(), QVariant(version.downloadUrl));
|
||||
}
|
||||
|
||||
QVariant current_updated;
|
||||
current_updated.setValue(m_current);
|
||||
|
||||
if (!m_listModel->setData(curr, current_updated, Qt::UserRole))
|
||||
if (!m_listModel->setData(curr, current_updated, Qt::UserRole)) {
|
||||
qWarning() << "Failed to cache versions for the current pack!";
|
||||
}
|
||||
|
||||
// TODO: Check whether it's a connection issue or the project disabled 3rd-party distribution.
|
||||
if (m_current->versionsLoaded && m_ui->versionSelectionBox->count() < 1) {
|
||||
|
|
@ -200,16 +200,16 @@ void FlamePage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelInde
|
|||
}
|
||||
suggestCurrent();
|
||||
};
|
||||
callbacks.on_fail = [this](QString reason, int) {
|
||||
callbacks.on_fail = [this](const QString& reason, int) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec();
|
||||
};
|
||||
|
||||
auto netJob = api.getProjectVersions({ m_current, {}, {}, ModPlatform::ResourceType::Modpack }, std::move(callbacks));
|
||||
auto netJob = FlameAPI().getProjectVersions({ m_current, {}, {}, ModPlatform::ResourceType::Modpack }, std::move(callbacks));
|
||||
|
||||
m_job = netJob;
|
||||
netJob->start();
|
||||
} else {
|
||||
for (auto version : m_current->versions) {
|
||||
for (const auto& version : m_current->versions) {
|
||||
m_ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl));
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ void FlamePage::suggestCurrent()
|
|||
m_dialog->setSuggestedPack(m_current->name, new InstanceImportTask(version.downloadUrl, this, std::move(extra_info)));
|
||||
QString editedLogoName = "curseforge_" + m_current->logoName;
|
||||
m_listModel->getLogo(m_current->logoName, m_current->logoUrl,
|
||||
[this, editedLogoName](QString logo) { m_dialog->setSuggestedIconFromFile(logo, editedLogoName); });
|
||||
[this, editedLogoName](const QString& logo) { m_dialog->setSuggestedIconFromFile(logo, editedLogoName); });
|
||||
}
|
||||
|
||||
void FlamePage::onVersionSelectionChanged(int index)
|
||||
|
|
@ -269,10 +269,11 @@ void FlamePage::updateUi()
|
|||
QString text = "";
|
||||
QString name = m_current->name;
|
||||
|
||||
if (m_current->websiteUrl.isEmpty())
|
||||
if (m_current->websiteUrl.isEmpty()) {
|
||||
text = name;
|
||||
else
|
||||
} else {
|
||||
text = "<a href=\"" + m_current->websiteUrl + "\">" + name + "</a>";
|
||||
}
|
||||
if (!m_current->authors.empty()) {
|
||||
auto authorToStr = [](ModPlatform::ModpackAuthor& author) {
|
||||
if (author.url.isEmpty()) {
|
||||
|
|
@ -293,16 +294,19 @@ void FlamePage::updateUi()
|
|||
text += "<br><br>" + tr("External links:") + "<br>";
|
||||
}
|
||||
|
||||
if (!m_current->extraData.issuesUrl.isEmpty())
|
||||
if (!m_current->extraData.issuesUrl.isEmpty()) {
|
||||
text += "- " + tr("Issues: <a href=%1>%1</a>").arg(m_current->extraData.issuesUrl) + "<br>";
|
||||
if (!m_current->extraData.wikiUrl.isEmpty())
|
||||
}
|
||||
if (!m_current->extraData.wikiUrl.isEmpty()) {
|
||||
text += "- " + tr("Wiki: <a href=%1>%1</a>").arg(m_current->extraData.wikiUrl) + "<br>";
|
||||
if (!m_current->extraData.sourceUrl.isEmpty())
|
||||
}
|
||||
if (!m_current->extraData.sourceUrl.isEmpty()) {
|
||||
text += "- " + tr("Source code: <a href=%1>%1</a>").arg(m_current->extraData.sourceUrl) + "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
text += "<hr>";
|
||||
text += api.getModDescription(m_current->addonId.toInt()).toUtf8();
|
||||
text += FlameAPI().getModDescription(m_current->addonId.toInt()).toUtf8();
|
||||
|
||||
m_ui->packDescription->setHtml(StringUtils::htmlListPatch(text + m_current->description));
|
||||
m_ui->packDescription->flush();
|
||||
|
|
@ -319,12 +323,12 @@ void FlamePage::setSearchTerm(QString term)
|
|||
|
||||
void FlamePage::createFilterWidget()
|
||||
{
|
||||
auto widget = ModFilterWidget::create(nullptr, false);
|
||||
m_filterWidget.swap(widget);
|
||||
auto old = m_ui->splitter->replaceWidget(0, m_filterWidget.get());
|
||||
auto* widget = ModFilterWidget::create(nullptr, false);
|
||||
m_filterWidget.reset(widget);
|
||||
auto* old = m_ui->splitter->replaceWidget(0, m_filterWidget.get());
|
||||
// because we replaced the widget we also need to delete it
|
||||
if (old) {
|
||||
delete old;
|
||||
old->deleteLater();
|
||||
}
|
||||
|
||||
connect(m_ui->filterButton, &QPushButton::clicked, this, [this] { m_filterWidget->setHidden(!m_filterWidget->isHidden()); });
|
||||
|
|
@ -333,7 +337,7 @@ void FlamePage::createFilterWidget()
|
|||
auto [task, response] = FlameAPI::getCategories(ModPlatform::ResourceType::Modpack);
|
||||
m_categoriesTask = task;
|
||||
connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
|
||||
auto categories = FlameAPI::loadModCategories(*response);
|
||||
auto categories = FlameAPI().loadModCategories(*response);
|
||||
m_filterWidget->setCategories(categories);
|
||||
});
|
||||
m_categoriesTask->start();
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class FlamePage : public QWidget, public ModpackProviderBasePage {
|
|||
|
||||
private slots:
|
||||
void triggerSearch();
|
||||
void onSelectionChanged(QModelIndex first, QModelIndex second);
|
||||
void onSelectionChanged(QModelIndex curr, QModelIndex prev);
|
||||
void onVersionSelectionChanged(int index);
|
||||
void createFilterWidget();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ModModel.h"
|
||||
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
|
||||
#include "ui/pages/modplatform/TexturePackModel.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
|
|
@ -19,9 +18,6 @@ class FlameTexturePackModel : public TexturePackResourceModel {
|
|||
bool optedOut(const ModPlatform::IndexedVersion& ver) const override;
|
||||
|
||||
private:
|
||||
QString debugName() const override { return Flame::debugName() + " (Model)"; }
|
||||
QString metaEntryBase() const override { return Flame::metaEntryBase(); }
|
||||
|
||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||
ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,221 +38,48 @@
|
|||
*/
|
||||
|
||||
#include "FlameResourcePages.h"
|
||||
#include <QList>
|
||||
#include <memory>
|
||||
|
||||
#include "modplatform/flame/FlameAPI.h"
|
||||
#include "../ui_ResourcePage.h"
|
||||
|
||||
#include "FlameResourceModels.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ModPage(dialog, instance)
|
||||
static ResourceProviderData prepareFlame()
|
||||
{
|
||||
m_model = new ModModel(instance, new FlameAPI(), Flame::debugName(), Flame::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's contructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &FlameModPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameModPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &FlameModPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameModPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return {
|
||||
.displayName = Flame::displayName(),
|
||||
.icon = Flame::icon(),
|
||||
.id = Flame::id(),
|
||||
.metaEntryBase = Flame::metaEntryBase(),
|
||||
.debugName = Flame::debugName(),
|
||||
};
|
||||
}
|
||||
|
||||
void FlameModPage::openUrl(const QUrl& url)
|
||||
ShaderPackResourcePage* Flame::createShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
ModPage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ModPage::openUrl(url);
|
||||
return new ShaderPackResourcePage(dialog, instance, prepareFlame(), new FlameAPI());
|
||||
}
|
||||
|
||||
FlameResourcePackPage::FlameResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ResourcePackResourcePage(dialog, instance)
|
||||
DataPackResourcePage* Flame::createDataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new ResourcePackResourceModel(instance, new FlameAPI(), Flame::debugName(), Flame::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's contructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &FlameResourcePackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameResourcePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &FlameResourcePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameResourcePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new DataPackResourcePage(dialog, instance, prepareFlame(), new FlameAPI());
|
||||
}
|
||||
|
||||
void FlameResourcePackPage::openUrl(const QUrl& url)
|
||||
ResourcePackResourcePage* Flame::createResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
ResourcePackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ResourcePackResourcePage::openUrl(url);
|
||||
return new ResourcePackResourcePage(dialog, instance, prepareFlame(), new FlameAPI());
|
||||
}
|
||||
|
||||
FlameTexturePackPage::FlameTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: TexturePackResourcePage(dialog, instance)
|
||||
TexturePackResourcePage* Flame::createTexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new FlameTexturePackModel(instance);
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's contructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &FlameTexturePackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameTexturePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &FlameTexturePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameTexturePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new TexturePackResourcePage(dialog, instance, prepareFlame(), new FlameAPI(), new FlameTexturePackModel(instance));
|
||||
}
|
||||
|
||||
void FlameTexturePackPage::openUrl(const QUrl& url)
|
||||
ModPage* Flame::createModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
ResourcePackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TexturePackResourcePage::openUrl(url);
|
||||
return new ModPage(dialog, instance, prepareFlame(), new FlameAPI(),
|
||||
ModFilterWidget::create(&static_cast<MinecraftInstance&>(instance), false));
|
||||
}
|
||||
|
||||
void FlameDataPackPage::openUrl(const QUrl& url)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
DataPackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DataPackResourcePage::openUrl(url);
|
||||
}
|
||||
|
||||
FlameShaderPackPage::FlameShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ShaderPackResourcePage(dialog, instance)
|
||||
{
|
||||
m_model = new ShaderPackResourceModel(instance, new FlameAPI(), Flame::debugName(), Flame::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &FlameShaderPackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameShaderPackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &FlameShaderPackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameShaderPackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
FlameDataPackPage::FlameDataPackPage(DataPackDownloadDialog* dialog, BaseInstance& instance) : DataPackResourcePage(dialog, instance)
|
||||
{
|
||||
m_model = new DataPackResourceModel(instance, new FlameAPI(), Flame::debugName(), Flame::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &FlameDataPackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameDataPackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &FlameDataPackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &FlameDataPackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
}
|
||||
|
||||
void FlameShaderPackPage::openUrl(const QUrl& url)
|
||||
{
|
||||
if (url.scheme().isEmpty()) {
|
||||
QString query = url.query(QUrl::FullyDecoded);
|
||||
|
||||
if (query.startsWith("remoteUrl=")) {
|
||||
// attempt to resolve url from warning page
|
||||
query.remove(0, 10);
|
||||
ShaderPackResourcePage::openUrl({ QUrl::fromPercentEncoding(query.toUtf8()) }); // double decoding is necessary
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderPackResourcePage::openUrl(url);
|
||||
}
|
||||
|
||||
// I don't know why, but doing this on the parent class makes it so that
|
||||
// other mod providers start loading before being selected, at least with
|
||||
// my Qt, so we need to implement this in every derived class...
|
||||
auto FlameModPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto FlameResourcePackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto FlameTexturePackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto FlameShaderPackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto FlameDataPackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<ModFilterWidget> FlameModPage::createFilterWidget()
|
||||
{
|
||||
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_baseInstance), false);
|
||||
}
|
||||
|
||||
void FlameModPage::prepareProviderCategories()
|
||||
{
|
||||
auto [task, response] = FlameAPI::getModCategories();
|
||||
m_categoriesTask = task;
|
||||
connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
|
||||
auto categories = FlameAPI::loadModCategories(*response);
|
||||
m_filter_widget->setCategories(categories);
|
||||
});
|
||||
m_categoriesTask->start();
|
||||
};
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -39,12 +39,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <ui/pages/modplatform/DataPackPage.h>
|
||||
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
||||
#include "ui/pages/modplatform/DataPackPage.h"
|
||||
#include "ui/pages/modplatform/ModPage.h"
|
||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
#include "ui/pages/modplatform/ShaderPackPage.h"
|
||||
#include "ui/pages/modplatform/TexturePackPage.h"
|
||||
|
||||
|
|
@ -71,138 +69,12 @@ static inline QString metaEntryBase()
|
|||
{
|
||||
return "FlameMods";
|
||||
}
|
||||
|
||||
ShaderPackResourcePage* createShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
DataPackResourcePage* createDataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
ResourcePackResourcePage* createResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
TexturePackResourcePage* createTexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
ModPage* createModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
} // namespace Flame
|
||||
|
||||
class FlameModPage : public ModPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameModPage* create(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ModPage::create<FlameModPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameModPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
inline auto id() const -> QString override { return Flame::id(); }
|
||||
inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return "Mod-platform"; }
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
std::unique_ptr<ModFilterWidget> createFilterWidget() override;
|
||||
|
||||
protected:
|
||||
virtual void prepareProviderCategories() override;
|
||||
|
||||
private:
|
||||
Task::Ptr m_categoriesTask;
|
||||
};
|
||||
|
||||
class FlameResourcePackPage : public ResourcePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameResourcePackPage* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ResourcePackResourcePage::create<FlameResourcePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameResourcePackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
inline auto id() const -> QString override { return Flame::id(); }
|
||||
inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
class FlameTexturePackPage : public TexturePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameTexturePackPage* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return TexturePackResourcePage::create<FlameTexturePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameTexturePackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
inline auto id() const -> QString override { return Flame::id(); }
|
||||
inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
class FlameShaderPackPage : public ShaderPackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameShaderPackPage* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ShaderPackResourcePage::create<FlameShaderPackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameShaderPackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
inline auto id() const -> QString override { return Flame::id(); }
|
||||
inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
class FlameDataPackPage : public DataPackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static FlameDataPackPage* create(DataPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return DataPackResourcePage::create<FlameDataPackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
FlameDataPackPage(DataPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~FlameDataPackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Flame::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Flame::icon(); }
|
||||
inline auto id() const -> QString override { return Flame::id(); }
|
||||
inline auto debugName() const -> QString override { return Flame::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Flame::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
|
||||
void openUrl(const QUrl& url) override;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -43,28 +43,28 @@
|
|||
|
||||
#include "ModrinthModel.h"
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "InstanceImportTask.h"
|
||||
#include "Json.h"
|
||||
#include "Markdown.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include "ui/widgets/ProjectItem.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QPushButton>
|
||||
|
||||
ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent)
|
||||
: QWidget(parent), m_ui(new Ui::ModrinthPage), m_dialog(dialog), m_fetch_progress(this, false)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ModrinthPage)
|
||||
, m_dialog(dialog)
|
||||
, m_model(new Modrinth::ModpackListModel(this))
|
||||
, m_fetch_progress(this, false)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
createFilterWidget();
|
||||
|
||||
m_ui->searchEdit->installEventFilter(this);
|
||||
m_model = new Modrinth::ModpackListModel(this);
|
||||
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
m_ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
|
|
@ -116,17 +116,17 @@ void ModrinthPage::openedImpl()
|
|||
bool ModrinthPage::eventFilter(QObject* watched, QEvent* event)
|
||||
{
|
||||
if (watched == m_ui->searchEdit && event->type() == QEvent::KeyPress) {
|
||||
auto* keyEvent = reinterpret_cast<QKeyEvent*>(event);
|
||||
auto* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if (keyEvent->key() == Qt::Key_Return) {
|
||||
this->triggerSearch();
|
||||
keyEvent->accept();
|
||||
return true;
|
||||
} else {
|
||||
if (m_search_timer.isActive())
|
||||
m_search_timer.stop();
|
||||
|
||||
m_search_timer.start(350);
|
||||
}
|
||||
if (m_search_timer.isActive()) {
|
||||
m_search_timer.stop();
|
||||
}
|
||||
|
||||
m_search_timer.start(350);
|
||||
}
|
||||
return QObject::eventFilter(watched, event);
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
ResourceAPI::Callback<ModPlatform::IndexedPack::Ptr> callbacks;
|
||||
|
||||
auto id = m_current->addonId;
|
||||
callbacks.on_fail = [this](QString reason, int) {
|
||||
callbacks.on_fail = [this](const QString& reason, int) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec();
|
||||
};
|
||||
callbacks.on_succeed = [this, id, curr](auto& pack) {
|
||||
|
|
@ -161,8 +161,9 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
QVariant current_updated;
|
||||
current_updated.setValue(pack);
|
||||
|
||||
if (!m_model->setData(curr, current_updated, Qt::UserRole))
|
||||
if (!m_model->setData(curr, current_updated, Qt::UserRole)) {
|
||||
qWarning() << "Failed to cache extra info for the current pack!";
|
||||
}
|
||||
|
||||
suggestCurrent();
|
||||
updateUI();
|
||||
|
|
@ -172,8 +173,9 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
m_job->start();
|
||||
}
|
||||
|
||||
} else
|
||||
} else {
|
||||
updateUI();
|
||||
}
|
||||
|
||||
if (!m_current->versionsLoaded || m_filterWidget->changed()) {
|
||||
qDebug() << "Loading modrinth modpack versions";
|
||||
|
|
@ -190,8 +192,9 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
m_current->versions = doc;
|
||||
m_current->versionsLoaded = true;
|
||||
auto pred = [this](const ModPlatform::IndexedVersion& v) {
|
||||
if (auto filter = m_filterWidget->getFilter())
|
||||
if (auto filter = m_filterWidget->getFilter()) {
|
||||
return !filter->checkModpackFilters(v);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
|
||||
|
|
@ -210,12 +213,13 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
QVariant current_updated;
|
||||
current_updated.setValue(m_current);
|
||||
|
||||
if (!m_model->setData(curr, current_updated, Qt::UserRole))
|
||||
if (!m_model->setData(curr, current_updated, Qt::UserRole)) {
|
||||
qWarning() << "Failed to cache versions for the current pack!";
|
||||
}
|
||||
|
||||
suggestCurrent();
|
||||
};
|
||||
callbacks.on_fail = [this](QString reason, int) {
|
||||
callbacks.on_fail = [this](const QString& reason, int) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec();
|
||||
};
|
||||
|
||||
|
|
@ -225,12 +229,13 @@ void ModrinthPage::onSelectionChanged(QModelIndex curr, [[maybe_unused]] QModelI
|
|||
m_job2->start();
|
||||
|
||||
} else {
|
||||
for (auto version : m_current->versions) {
|
||||
if (!version.version.contains(version.version))
|
||||
for (const auto& version : m_current->versions) {
|
||||
if (!version.version.contains(version.version)) {
|
||||
m_ui->versionSelectionBox->addItem(QString("%1 - %2").arg(version.version, version.version_number),
|
||||
QVariant(version.fileId));
|
||||
else
|
||||
} else {
|
||||
m_ui->versionSelectionBox->addItem(version.version, QVariant(version.fileId));
|
||||
}
|
||||
}
|
||||
|
||||
suggestCurrent();
|
||||
|
|
@ -283,14 +288,18 @@ void ModrinthPage::updateUI()
|
|||
text += "<br><br>" + tr("External links:") + "<br>";
|
||||
}
|
||||
|
||||
if (!m_current->extraData.issuesUrl.isEmpty())
|
||||
if (!m_current->extraData.issuesUrl.isEmpty()) {
|
||||
text += "- " + tr("Issues: <a href=%1>%1</a>").arg(m_current->extraData.issuesUrl) + "<br>";
|
||||
if (!m_current->extraData.wikiUrl.isEmpty())
|
||||
}
|
||||
if (!m_current->extraData.wikiUrl.isEmpty()) {
|
||||
text += "- " + tr("Wiki: <a href=%1>%1</a>").arg(m_current->extraData.wikiUrl) + "<br>";
|
||||
if (!m_current->extraData.sourceUrl.isEmpty())
|
||||
}
|
||||
if (!m_current->extraData.sourceUrl.isEmpty()) {
|
||||
text += "- " + tr("Source code: <a href=%1>%1</a>").arg(m_current->extraData.sourceUrl) + "<br>";
|
||||
if (!m_current->extraData.discordUrl.isEmpty())
|
||||
}
|
||||
if (!m_current->extraData.discordUrl.isEmpty()) {
|
||||
text += "- " + tr("Discord: <a href=%1>%1</a>").arg(m_current->extraData.discordUrl) + "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
text += "<hr>";
|
||||
|
|
@ -321,7 +330,7 @@ void ModrinthPage::suggestCurrent()
|
|||
m_dialog->setSuggestedPack(m_current->name, ver.version, new InstanceImportTask(ver.downloadUrl, this, std::move(extra_info)));
|
||||
QString editedLogoName = "modrinth_" + m_current->logoName;
|
||||
m_model->getLogo(m_current->logoName, m_current->logoUrl,
|
||||
[this, editedLogoName](QString logo) { m_dialog->setSuggestedIconFromFile(logo, editedLogoName); });
|
||||
[this, editedLogoName](const QString& logo) { m_dialog->setSuggestedIconFromFile(logo, editedLogoName); });
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -361,18 +370,18 @@ QString ModrinthPage::getSerachTerm() const
|
|||
|
||||
void ModrinthPage::createFilterWidget()
|
||||
{
|
||||
auto widget = ModFilterWidget::create(nullptr, true);
|
||||
m_filterWidget.swap(widget);
|
||||
auto old = m_ui->splitter->replaceWidget(0, m_filterWidget.get());
|
||||
auto* widget = ModFilterWidget::create(nullptr, true);
|
||||
m_filterWidget.reset(widget);
|
||||
auto* old = m_ui->splitter->replaceWidget(0, m_filterWidget.get());
|
||||
// because we replaced the widget we also need to delete it
|
||||
if (old) {
|
||||
delete old;
|
||||
old->deleteLater();
|
||||
}
|
||||
|
||||
connect(m_ui->filterButton, &QPushButton::clicked, this, [this] { m_filterWidget->setHidden(!m_filterWidget->isHidden()); });
|
||||
|
||||
connect(m_filterWidget.get(), &ModFilterWidget::filterChanged, this, &ModrinthPage::triggerSearch);
|
||||
auto [categoriesTask, response] = ModrinthAPI::getModCategories();
|
||||
auto [categoriesTask, response] = ModrinthAPI().getModCategories();
|
||||
m_categoriesTask = categoriesTask;
|
||||
connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
|
||||
auto categories = ModrinthAPI::loadCategories(*response, "modpack");
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ class ModrinthPage : public QWidget, public ModpackProviderBasePage {
|
|||
QString id() const override { return "modrinth"; }
|
||||
QString helpPage() const override { return "Modrinth-platform"; }
|
||||
|
||||
inline QString debugName() const { return "Modrinth"; }
|
||||
inline QString metaEntryBase() const { return "ModrinthModpacks"; };
|
||||
static QString debugName() { return "Modrinth"; }
|
||||
static QString metaEntryBase() { return "ModrinthModpacks"; };
|
||||
|
||||
ModPlatform::IndexedPack::Ptr getCurrent() { return m_current; }
|
||||
void suggestCurrent();
|
||||
|
|
@ -80,12 +80,12 @@ class ModrinthPage : public QWidget, public ModpackProviderBasePage {
|
|||
bool eventFilter(QObject* watched, QEvent* event) override;
|
||||
|
||||
/** Programatically set the term in the search bar. */
|
||||
virtual void setSearchTerm(QString) override;
|
||||
void setSearchTerm(QString) override;
|
||||
/** Get the current term in the search bar. */
|
||||
virtual QString getSerachTerm() const override;
|
||||
QString getSerachTerm() const override;
|
||||
|
||||
private slots:
|
||||
void onSelectionChanged(QModelIndex first, QModelIndex second);
|
||||
void onSelectionChanged(QModelIndex curr, QModelIndex prev);
|
||||
void onVersionSelectionChanged(int index);
|
||||
void triggerSearch();
|
||||
void createFilterWidget();
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
*/
|
||||
|
||||
#include "ModrinthResourcePages.h"
|
||||
#include "ui/pages/modplatform/DataPackModel.h"
|
||||
#include "../ui_ResourcePage.h"
|
||||
|
||||
#include "modplatform/modrinth/ModrinthAPI.h"
|
||||
|
||||
|
|
@ -46,131 +44,40 @@
|
|||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance) : ModPage(dialog, instance)
|
||||
static ResourceProviderData prepareModrinth()
|
||||
{
|
||||
m_model = new ModModel(instance, new ModrinthAPI(), Modrinth::debugName(), Modrinth::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModrinthModPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthModPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModrinthModPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthModPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return {
|
||||
.displayName = Modrinth::displayName(),
|
||||
.icon = Modrinth::icon(),
|
||||
.id = Modrinth::id(),
|
||||
.metaEntryBase = Modrinth::metaEntryBase(),
|
||||
.debugName = Modrinth::debugName(),
|
||||
};
|
||||
}
|
||||
|
||||
ModrinthResourcePackPage::ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ResourcePackResourcePage(dialog, instance)
|
||||
ShaderPackResourcePage* Modrinth::createShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new ResourcePackResourceModel(instance, new ModrinthAPI(), Modrinth::debugName(), Modrinth::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModrinthResourcePackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthResourcePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModrinthResourcePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthResourcePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new ShaderPackResourcePage(dialog, instance, prepareModrinth(), new ModrinthAPI());
|
||||
}
|
||||
|
||||
ModrinthTexturePackPage::ModrinthTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: TexturePackResourcePage(dialog, instance)
|
||||
DataPackResourcePage* Modrinth::createDataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new TexturePackResourceModel(instance, new ModrinthAPI(), Modrinth::debugName(), Modrinth::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModrinthTexturePackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthTexturePackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModrinthTexturePackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthTexturePackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new DataPackResourcePage(dialog, instance, prepareModrinth(), new ModrinthAPI());
|
||||
}
|
||||
|
||||
ModrinthShaderPackPage::ModrinthShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
: ShaderPackResourcePage(dialog, instance)
|
||||
ResourcePackResourcePage* Modrinth::createResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new ShaderPackResourceModel(instance, new ModrinthAPI(), Modrinth::debugName(), Modrinth::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModrinthShaderPackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthShaderPackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModrinthShaderPackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthShaderPackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new ResourcePackResourcePage(dialog, instance, prepareModrinth(), new ModrinthAPI());
|
||||
}
|
||||
|
||||
ModrinthDataPackPage::ModrinthDataPackPage(DataPackDownloadDialog* dialog, BaseInstance& instance) : DataPackResourcePage(dialog, instance)
|
||||
TexturePackResourcePage* Modrinth::createTexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
m_model = new DataPackResourceModel(instance, new ModrinthAPI(), Modrinth::debugName(), Modrinth::metaEntryBase());
|
||||
m_ui->packView->setModel(m_model);
|
||||
|
||||
addSortings();
|
||||
|
||||
// sometimes Qt just ignores virtual slots and doesn't work as intended it seems,
|
||||
// so it's best not to connect them in the parent's constructor...
|
||||
connect(m_ui->sortByBox, &QComboBox::currentIndexChanged, this, &ModrinthDataPackPage::triggerSearch);
|
||||
connect(m_ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthDataPackPage::onSelectionChanged);
|
||||
connect(m_ui->versionSelectionBox, &QComboBox::currentIndexChanged, this, &ModrinthDataPackPage::onVersionSelectionChanged);
|
||||
connect(m_ui->resourceSelectionButton, &QPushButton::clicked, this, &ModrinthDataPackPage::onResourceSelected);
|
||||
|
||||
m_ui->packDescription->setMetaEntry(metaEntryBase());
|
||||
return new TexturePackResourcePage(dialog, instance, prepareModrinth(), new ModrinthAPI());
|
||||
}
|
||||
|
||||
// I don't know why, but doing this on the parent class makes it so that
|
||||
// other mod providers start loading before being selected, at least with
|
||||
// my Qt, so we need to implement this in every derived class...
|
||||
auto ModrinthModPage::shouldDisplay() const -> bool
|
||||
ModPage* Modrinth::createModPage(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return true;
|
||||
return new ModPage(dialog, instance, prepareModrinth(), new ModrinthAPI(),
|
||||
ModFilterWidget::create(&static_cast<MinecraftInstance&>(instance), true));
|
||||
}
|
||||
auto ModrinthResourcePackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto ModrinthTexturePackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto ModrinthShaderPackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
auto ModrinthDataPackPage::shouldDisplay() const -> bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<ModFilterWidget> ModrinthModPage::createFilterWidget()
|
||||
{
|
||||
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_baseInstance), true);
|
||||
}
|
||||
|
||||
void ModrinthModPage::prepareProviderCategories()
|
||||
{
|
||||
auto [categoriesTask, response] = ModrinthAPI::getModCategories();
|
||||
m_categoriesTask = categoriesTask;
|
||||
connect(m_categoriesTask.get(), &Task::succeeded, [this, response]() {
|
||||
auto categories = ModrinthAPI::loadModCategories(*response);
|
||||
m_filter_widget->setCategories(categories);
|
||||
});
|
||||
m_categoriesTask->start();
|
||||
};
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
|
||||
#include "ui/pages/modplatform/DataPackPage.h"
|
||||
#include "ui/pages/modplatform/ModPage.h"
|
||||
#include "ui/pages/modplatform/ResourcePackPage.h"
|
||||
|
|
@ -69,127 +67,12 @@ static inline QString metaEntryBase()
|
|||
{
|
||||
return "ModrinthPacks";
|
||||
}
|
||||
|
||||
ShaderPackResourcePage* createShaderPackResourcePage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
DataPackResourcePage* createDataPackResourcePage(DataPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
ResourcePackResourcePage* createResourcePackResourcePage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
TexturePackResourcePage* createTexturePackResourcePage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
ModPage* createModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
} // namespace Modrinth
|
||||
|
||||
class ModrinthModPage : public ModPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthModPage* create(ModDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ModPage::create<ModrinthModPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthModPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return "Mod-platform"; }
|
||||
|
||||
std::unique_ptr<ModFilterWidget> createFilterWidget() override;
|
||||
|
||||
protected:
|
||||
virtual void prepareProviderCategories() override;
|
||||
Task::Ptr m_categoriesTask;
|
||||
};
|
||||
|
||||
class ModrinthResourcePackPage : public ResourcePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthResourcePackPage* create(ResourcePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ResourcePackResourcePage::create<ModrinthResourcePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthResourcePackPage(ResourcePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthResourcePackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
};
|
||||
|
||||
class ModrinthTexturePackPage : public TexturePackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthTexturePackPage* create(TexturePackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return TexturePackResourcePage::create<ModrinthTexturePackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthTexturePackPage(TexturePackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthTexturePackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
};
|
||||
|
||||
class ModrinthShaderPackPage : public ShaderPackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthShaderPackPage* create(ShaderPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return ShaderPackResourcePage::create<ModrinthShaderPackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthShaderPackPage(ShaderPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthShaderPackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
};
|
||||
|
||||
class ModrinthDataPackPage : public DataPackResourcePage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static ModrinthDataPackPage* create(DataPackDownloadDialog* dialog, BaseInstance& instance)
|
||||
{
|
||||
return DataPackResourcePage::create<ModrinthDataPackPage>(dialog, instance);
|
||||
}
|
||||
|
||||
ModrinthDataPackPage(DataPackDownloadDialog* dialog, BaseInstance& instance);
|
||||
~ModrinthDataPackPage() override = default;
|
||||
|
||||
bool shouldDisplay() const override;
|
||||
|
||||
inline auto displayName() const -> QString override { return Modrinth::displayName(); }
|
||||
inline auto icon() const -> QIcon override { return Modrinth::icon(); }
|
||||
inline auto id() const -> QString override { return Modrinth::id(); }
|
||||
inline auto debugName() const -> QString override { return Modrinth::debugName(); }
|
||||
inline auto metaEntryBase() const -> QString override { return Modrinth::metaEntryBase(); }
|
||||
|
||||
inline auto helpPage() const -> QString override { return ""; }
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
#include <QComboBox>
|
||||
#include <QListWidget>
|
||||
#include <algorithm>
|
||||
#include <list>
|
||||
#include "BaseVersionList.h"
|
||||
#include "Json.h"
|
||||
#include "Version.h"
|
||||
|
|
@ -50,9 +49,9 @@
|
|||
#include "Application.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
|
||||
std::unique_ptr<ModFilterWidget> ModFilterWidget::create(MinecraftInstance* instance, bool extended)
|
||||
ModFilterWidget* ModFilterWidget::create(MinecraftInstance* instance, bool extended)
|
||||
{
|
||||
return std::unique_ptr<ModFilterWidget>(new ModFilterWidget(instance, extended));
|
||||
return new ModFilterWidget(instance, extended);
|
||||
}
|
||||
|
||||
class VersionBasicModel : public QIdentityProxyModel {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class ModFilterWidget : public QTabWidget {
|
|||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<ModFilterWidget> create(MinecraftInstance* instance, bool extended);
|
||||
static ModFilterWidget* create(MinecraftInstance* instance, bool extended);
|
||||
virtual ~ModFilterWidget();
|
||||
|
||||
auto getFilter() -> std::shared_ptr<Filter>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue