mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
Merge 3435c6de48 into 9c2c641531
This commit is contained in:
commit
55ce074f8c
50 changed files with 766 additions and 1292 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
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ int DataPack::compare(const Resource& other, SortType type) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool DataPack::applyFilter(QRegularExpression filter) const
|
||||
bool DataPack::applyFilter(const QRegularExpression& filter) const
|
||||
{
|
||||
if (filter.match(description()).hasMatch()) {
|
||||
return true;
|
||||
|
|
@ -279,7 +279,7 @@ QString DataPack::packFormatStr() const
|
|||
auto min_version = min_bound.first;
|
||||
auto max_version = max_bound.second;
|
||||
if (min_version.isEmpty() || max_version.isEmpty()) {
|
||||
return tr("Unrecognized");
|
||||
return QObject::tr("Unrecognized");
|
||||
}
|
||||
auto str = QString("[") + QString::number(m_min_format.first);
|
||||
if (m_min_format.second != 0) {
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ class Version;
|
|||
* */
|
||||
|
||||
class DataPack : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPack(QObject* parent = nullptr) : Resource(parent) {}
|
||||
DataPack(QFileInfo file_info) : Resource(file_info) {}
|
||||
|
||||
/** Gets the numerical ID of the pack format. */
|
||||
|
|
@ -61,7 +59,7 @@ class DataPack : public Resource {
|
|||
bool valid() const override;
|
||||
|
||||
[[nodiscard]] int compare(const Resource& other, SortType type) const override;
|
||||
[[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
|
||||
[[nodiscard]] bool applyFilter(const QRegularExpression& filter) const override;
|
||||
|
||||
QString packFormatStr() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ int Mod::compare(const Resource& other, SortType type) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool Mod::applyFilter(QRegularExpression filter) const
|
||||
bool Mod::applyFilter(const QRegularExpression& filter) const
|
||||
{
|
||||
if (filter.match(description()).hasMatch())
|
||||
return true;
|
||||
|
|
@ -225,8 +225,8 @@ auto Mod::authors() const -> QStringList
|
|||
|
||||
void Mod::finishResolvingWithDetails(ModDetails&& details)
|
||||
{
|
||||
m_is_resolving = false;
|
||||
m_is_resolved = true;
|
||||
m_isResolving = false;
|
||||
m_isResolved = true;
|
||||
|
||||
m_local_details = std::move(details);
|
||||
if (!iconPath().isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -48,12 +48,7 @@
|
|||
#include "Resource.h"
|
||||
|
||||
class Mod : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<Mod>;
|
||||
using WeakPtr = QPointer<Mod>;
|
||||
|
||||
Mod() = default;
|
||||
Mod(const QFileInfo& file);
|
||||
Mod(QString file_path) : Mod(QFileInfo(file_path)) {}
|
||||
|
||||
|
|
@ -90,7 +85,7 @@ class Mod : public Resource {
|
|||
bool valid() const override;
|
||||
|
||||
[[nodiscard]] int compare(const Resource& other, SortType type) const override;
|
||||
[[nodiscard]] bool applyFilter(QRegularExpression filter) const override;
|
||||
[[nodiscard]] bool applyFilter(const QRegularExpression& filter) const override;
|
||||
|
||||
// Delete all the files of this mod
|
||||
auto destroy(QDir& index_dir, bool preserve_metadata = false, bool attempt_trash = true) -> bool;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "Resource.h"
|
||||
#include <qobject.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
|
@ -11,16 +13,14 @@
|
|||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
|
||||
Resource::Resource(QObject* parent) : QObject(parent), m_size_info(0) {}
|
||||
|
||||
Resource::Resource(QFileInfo fileInfo) : m_size_info(0)
|
||||
Resource::Resource(const QFileInfo& fileInfo)
|
||||
{
|
||||
setFile(fileInfo);
|
||||
}
|
||||
|
||||
void Resource::setFile(QFileInfo fileInfo)
|
||||
{
|
||||
m_file_info = std::move(fileInfo);
|
||||
m_fileInfo = std::move(fileInfo);
|
||||
parseFile();
|
||||
}
|
||||
|
||||
|
|
@ -37,23 +37,23 @@ std::tuple<QString, qint64> calculateFileSize(const QFileInfo& file)
|
|||
}
|
||||
return { QString("%1 %2").arg(QString::number(count), str), count };
|
||||
}
|
||||
return { StringUtils::humanReadableFileSize(file.size(), true), file.size() };
|
||||
return { StringUtils::humanReadableFileSize(static_cast<double>(file.size()), true), file.size() };
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Resource::parseFile()
|
||||
{
|
||||
QString fileName{ m_file_info.fileName() };
|
||||
QString fileName{ m_fileInfo.fileName() };
|
||||
|
||||
m_type = ResourceType::UNKNOWN;
|
||||
|
||||
m_internal_id = fileName;
|
||||
m_internalId = fileName;
|
||||
|
||||
std::tie(m_size_str, m_size_info) = calculateFileSize(m_file_info);
|
||||
if (m_file_info.isDir()) {
|
||||
std::tie(m_sizeStr, m_sizeInfo) = calculateFileSize(m_fileInfo);
|
||||
if (m_fileInfo.isDir()) {
|
||||
m_type = ResourceType::FOLDER;
|
||||
m_name = fileName;
|
||||
} else if (m_file_info.isFile()) {
|
||||
} else if (m_fileInfo.isFile()) {
|
||||
if (fileName.endsWith(".disabled")) {
|
||||
fileName.chop(9);
|
||||
m_enabled = false;
|
||||
|
|
@ -75,7 +75,7 @@ void Resource::parseFile()
|
|||
m_name = fileName;
|
||||
}
|
||||
|
||||
m_changed_date_time = m_file_info.lastModified();
|
||||
m_changedDateTime = m_fileInfo.lastModified();
|
||||
}
|
||||
|
||||
auto Resource::name() const -> QString
|
||||
|
|
@ -102,7 +102,7 @@ auto Resource::provider() const -> QString
|
|||
return ModPlatform::ProviderCapabilities::readableName(metadata()->provider);
|
||||
}
|
||||
|
||||
return tr("Unknown");
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
|
||||
auto Resource::homepage() const -> QString
|
||||
|
|
@ -120,7 +120,7 @@ void Resource::setMetadata(std::shared_ptr<Metadata::ModStruct>&& metadata)
|
|||
setStatus(ResourceStatus::Installed);
|
||||
}
|
||||
|
||||
m_metadata = metadata;
|
||||
m_metadata = std::move(metadata);
|
||||
}
|
||||
|
||||
QStringList Resource::issues() const
|
||||
|
|
@ -129,7 +129,7 @@ QStringList Resource::issues() const
|
|||
result.reserve(m_issues.length());
|
||||
|
||||
for (const char* issue : m_issues) {
|
||||
result.append(tr(issue));
|
||||
result.append(QObject::tr(issue));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -221,7 +221,7 @@ int Resource::compare(const Resource& other, SortType type) const
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool Resource::applyFilter(QRegularExpression filter) const
|
||||
bool Resource::applyFilter(const QRegularExpression& filter) const
|
||||
{
|
||||
if (filter.match(name()).hasMatch()) {
|
||||
return true;
|
||||
|
|
@ -238,7 +238,7 @@ bool Resource::enable(EnableAction action)
|
|||
return false;
|
||||
}
|
||||
|
||||
QString path = m_file_info.absoluteFilePath();
|
||||
QString path = m_fileInfo.absoluteFilePath();
|
||||
QFile file(path);
|
||||
|
||||
bool enable = true;
|
||||
|
|
@ -291,7 +291,7 @@ auto Resource::destroy(const QDir& indexDir, bool preserveMetadata, bool attempt
|
|||
destroyMetadata(indexDir);
|
||||
}
|
||||
|
||||
return (attemptTrash && FS::trash(m_file_info.filePath())) || FS::deletePath(m_file_info.filePath());
|
||||
return (attemptTrash && FS::trash(m_fileInfo.filePath())) || FS::deletePath(m_fileInfo.filePath());
|
||||
}
|
||||
|
||||
auto Resource::destroyMetadata(const QDir& indexDir) -> void
|
||||
|
|
@ -313,20 +313,20 @@ bool Resource::isSymLinkUnder(const QString& instPath) const
|
|||
|
||||
auto instDir = QDir(instPath);
|
||||
|
||||
auto relAbsPath = instDir.relativeFilePath(m_file_info.absoluteFilePath());
|
||||
auto relCanonPath = instDir.relativeFilePath(m_file_info.canonicalFilePath());
|
||||
auto relAbsPath = instDir.relativeFilePath(m_fileInfo.absoluteFilePath());
|
||||
auto relCanonPath = instDir.relativeFilePath(m_fileInfo.canonicalFilePath());
|
||||
|
||||
return relAbsPath != relCanonPath;
|
||||
}
|
||||
|
||||
bool Resource::isMoreThanOneHardLink() const
|
||||
{
|
||||
return FS::hardLinkCount(m_file_info.absoluteFilePath()) > 1;
|
||||
return FS::hardLinkCount(m_fileInfo.absoluteFilePath()) > 1;
|
||||
}
|
||||
|
||||
auto Resource::getOriginalFileName() const -> QString
|
||||
{
|
||||
auto fileName = m_file_info.fileName();
|
||||
auto fileName = m_fileInfo.fileName();
|
||||
if (!m_enabled) {
|
||||
fileName.chop(9);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,9 +39,9 @@
|
|||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <memory>
|
||||
|
||||
#include "MetadataHandler.h"
|
||||
#include "QObjectPtr.h"
|
||||
|
||||
class BaseInstance;
|
||||
|
||||
|
|
@ -88,29 +88,30 @@ enum class EnableAction : std::uint8_t { ENABLE, DISABLE, TOGGLE };
|
|||
*
|
||||
* Subclass it to add additional data / behavior, such as Mods or Resource packs.
|
||||
*/
|
||||
class Resource : public QObject {
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Resource)
|
||||
class Resource {
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<Resource>;
|
||||
Resource(const Resource&) = delete;
|
||||
Resource& operator=(const Resource&) = delete;
|
||||
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Resource>;
|
||||
Resource(const QFileInfo& fileInfo);
|
||||
|
||||
Resource(QObject* parent = nullptr);
|
||||
Resource(QFileInfo fileInfo);
|
||||
Resource(const QString& filePath) : Resource(QFileInfo(filePath)) {}
|
||||
|
||||
~Resource() override = default;
|
||||
virtual ~Resource() = default;
|
||||
|
||||
void setFile(QFileInfo fileInfo);
|
||||
void parseFile();
|
||||
|
||||
auto fileinfo() const -> QFileInfo { return m_file_info; }
|
||||
auto dateTimeChanged() const -> QDateTime { return m_changed_date_time; }
|
||||
auto internalId() const -> QString { return m_internal_id; }
|
||||
auto fileinfo() const -> QFileInfo { return m_fileInfo; }
|
||||
auto dateTimeChanged() const -> QDateTime { return m_changedDateTime; }
|
||||
auto internalId() const -> QString { return m_internalId; }
|
||||
auto type() const -> ResourceType { return m_type; }
|
||||
bool enabled() const { return m_enabled; }
|
||||
auto getOriginalFileName() const -> QString;
|
||||
QString sizeStr() const { return m_size_str; }
|
||||
qint64 sizeInfo() const { return m_size_info; }
|
||||
QString sizeStr() const { return m_sizeStr; }
|
||||
qint64 sizeInfo() const { return m_sizeInfo; }
|
||||
|
||||
virtual auto name() const -> QString;
|
||||
virtual bool valid() const { return m_type != ResourceType::UNKNOWN; }
|
||||
|
|
@ -143,7 +144,7 @@ class Resource : public QObject {
|
|||
/** Returns whether the given filter should filter out 'this' (false),
|
||||
* or if such filter includes the Resource (true).
|
||||
*/
|
||||
virtual bool applyFilter(QRegularExpression filter) const;
|
||||
virtual bool applyFilter(const QRegularExpression& filter) const;
|
||||
|
||||
/** Changes the enabled property, according to 'action'.
|
||||
*
|
||||
|
|
@ -151,15 +152,15 @@ class Resource : public QObject {
|
|||
*/
|
||||
bool enable(EnableAction action);
|
||||
|
||||
auto shouldResolve() const -> bool { return !m_is_resolving && !m_is_resolved; }
|
||||
auto isResolving() const -> bool { return m_is_resolving; }
|
||||
auto isResolved() const -> bool { return m_is_resolved; }
|
||||
auto resolutionTicket() const -> int { return m_resolution_ticket; }
|
||||
auto shouldResolve() const -> bool { return !m_isResolving && !m_isResolved; }
|
||||
auto isResolving() const -> bool { return m_isResolving; }
|
||||
auto isResolved() const -> bool { return m_isResolved; }
|
||||
auto resolutionTicket() const -> int { return m_resolutionTicket; }
|
||||
|
||||
void setResolving(bool resolving, int resolutionTicket)
|
||||
{
|
||||
m_is_resolving = resolving;
|
||||
m_resolution_ticket = resolutionTicket;
|
||||
m_isResolving = resolving;
|
||||
m_resolutionTicket = resolutionTicket;
|
||||
}
|
||||
|
||||
// Delete all files of this resource.
|
||||
|
|
@ -167,7 +168,7 @@ class Resource : public QObject {
|
|||
// Delete the metadata only.
|
||||
auto destroyMetadata(const QDir& indexDir) -> void;
|
||||
|
||||
auto isSymLink() const -> bool { return m_file_info.isSymLink(); }
|
||||
auto isSymLink() const -> bool { return m_fileInfo.isSymLink(); }
|
||||
|
||||
/**
|
||||
* @brief Take a instance path, checks if the file pointed to by the resource is a symlink or under a symlink in that instance
|
||||
|
|
@ -182,12 +183,12 @@ class Resource : public QObject {
|
|||
|
||||
protected:
|
||||
/* The file corresponding to this resource. */
|
||||
QFileInfo m_file_info;
|
||||
QFileInfo m_fileInfo{};
|
||||
/* The cached date when this file was last changed. */
|
||||
QDateTime m_changed_date_time;
|
||||
QDateTime m_changedDateTime;
|
||||
|
||||
/* Internal ID for internal purposes. Properties such as human-readability should not be assumed. */
|
||||
QString m_internal_id;
|
||||
QString m_internalId;
|
||||
/* Name as reported via the file name. In the absence of a better name, this is shown to the user. */
|
||||
QString m_name;
|
||||
|
||||
|
|
@ -205,9 +206,9 @@ class Resource : public QObject {
|
|||
QList<const char*> m_issues;
|
||||
|
||||
/* Used to keep trach of pending / concluded actions on the resource. */
|
||||
bool m_is_resolving = false;
|
||||
bool m_is_resolved = false;
|
||||
int m_resolution_ticket = 0;
|
||||
QString m_size_str;
|
||||
qint64 m_size_info;
|
||||
bool m_isResolving = false;
|
||||
bool m_isResolved = false;
|
||||
int m_resolutionTicket = 0;
|
||||
QString m_sizeStr;
|
||||
qint64 m_sizeInfo = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -890,7 +890,7 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
|
|||
}
|
||||
}
|
||||
|
||||
m_resources[row].reset(newResource);
|
||||
m_resources[row].swap(newResource);
|
||||
newResource->updateIssues(m_instance);
|
||||
|
||||
resolveResource(m_resources.at(row));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "Resource.h"
|
||||
#include "minecraft/mod/DataPack.h"
|
||||
|
||||
#include <QImage>
|
||||
|
|
@ -16,9 +15,7 @@ class Version;
|
|||
* */
|
||||
|
||||
class ResourcePack : public DataPack {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResourcePack(QObject* parent = nullptr) : DataPack(parent) {}
|
||||
ResourcePack(QFileInfo file_info) : DataPack(file_info) {}
|
||||
|
||||
/** Gets, respectively, the lower and upper versions supported by the set pack format. */
|
||||
|
|
|
|||
|
|
@ -41,13 +41,9 @@
|
|||
enum class ShaderPackFormat { VALID, INVALID };
|
||||
|
||||
class ShaderPack : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<Resource>;
|
||||
|
||||
ShaderPackFormat packFormat() const { return m_pack_format; }
|
||||
|
||||
ShaderPack(QObject* parent = nullptr) : Resource(parent) {}
|
||||
ShaderPack(QFileInfo file_info) : Resource(file_info) {}
|
||||
|
||||
/** Thread-safe. */
|
||||
|
|
|
|||
|
|
@ -29,11 +29,7 @@
|
|||
class Version;
|
||||
|
||||
class TexturePack : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<Resource>;
|
||||
|
||||
TexturePack(QObject* parent = nullptr) : Resource(parent) {}
|
||||
TexturePack(QFileInfo file_info) : Resource(file_info) {}
|
||||
|
||||
/** Gets the description of the texture pack. */
|
||||
|
|
|
|||
|
|
@ -30,11 +30,7 @@ class Version;
|
|||
enum class WorldSaveFormat { SINGLE, MULTI, INVALID };
|
||||
|
||||
class WorldSave : public Resource {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using Ptr = shared_qobject_ptr<Resource>;
|
||||
|
||||
WorldSave(QObject* parent = nullptr) : Resource(parent) {}
|
||||
WorldSave(QFileInfo file_info) : Resource(file_info) {}
|
||||
|
||||
/** Gets the format of the save. */
|
||||
|
|
|
|||
|
|
@ -125,10 +125,6 @@ void ResourceFolderLoadTask::executeTask()
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& mod : m_result->resources) {
|
||||
mod->moveToThread(m_thread_to_spawn_into);
|
||||
}
|
||||
|
||||
if (m_aborted) {
|
||||
emit finished();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -85,7 +84,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 }) {
|
||||
|
|
@ -96,7 +95,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
|
||||
|
|
@ -105,22 +104,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('&');
|
||||
}
|
||||
|
|
@ -130,8 +134,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())) {
|
||||
|
|
@ -158,7 +163,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();
|
||||
std::pair<Task::Ptr, QByteArray*> getModCategories() override;
|
||||
static QList<ModPlatform::Category> loadCategories(const QByteArray& response, const QString& projectType);
|
||||
static QList<ModPlatform::Category> loadModCategories(const QByteArray& response);
|
||||
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("\",\""));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@
|
|||
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "minecraft/mod/ResourcePackFolderModel.h"
|
||||
#include "minecraft/mod/ShaderPackFolderModel.h"
|
||||
#include "minecraft/mod/TexturePackFolderModel.h"
|
||||
|
||||
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
|
@ -50,12 +47,20 @@
|
|||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, ResourceFolderModel* baseModel, bool suppressInitialSearch)
|
||||
ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent,
|
||||
ResourceFolderModel* baseModel,
|
||||
BaseInstance* instance,
|
||||
QString resourcesString,
|
||||
QString geometrySaveKey,
|
||||
bool suppressInitialSearch)
|
||||
: QDialog(parent)
|
||||
, m_base_model(baseModel)
|
||||
, m_buttons(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel)
|
||||
, m_vertical_layout(this)
|
||||
, m_suppressInitialSearch(suppressInitialSearch)
|
||||
, m_instance(instance)
|
||||
, m_resourcesString(std::move(resourcesString))
|
||||
, m_geometrySaveKey(std::move(geometrySaveKey))
|
||||
{
|
||||
setObjectName(QStringLiteral("ResourceDownloadDialog"));
|
||||
|
||||
|
|
@ -85,6 +90,8 @@ ResourceDownloadDialog::ResourceDownloadDialog(QWidget* parent, ResourceFolderMo
|
|||
helpButton->setAutoDefault(false);
|
||||
|
||||
setWindowModality(Qt::WindowModal);
|
||||
|
||||
setWindowTitle(dialogTitle());
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::accept()
|
||||
|
|
@ -288,148 +295,6 @@ void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* s
|
|||
result->setSearchTerm(prevPage->getSearchTerm());
|
||||
}
|
||||
|
||||
ModDownloadDialog::ModDownloadDialog(QWidget* parent, ModFolderModel* mods, BaseInstance* instance, bool suppressInitialSearch)
|
||||
: ResourceDownloadDialog(parent, mods, suppressInitialSearch), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toString().toUtf8()));
|
||||
}
|
||||
}
|
||||
|
||||
QList<BasePage*> ModDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto loaders = static_cast<MinecraftInstance*>(m_instance)->getPackProfile()->getSupportedModLoaders().value();
|
||||
|
||||
if (ModrinthAPI::validateModLoaders(loaders)) {
|
||||
auto* page = ModrinthModPage::create(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);
|
||||
page->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(page);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask()
|
||||
{
|
||||
if (!APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies
|
||||
if (auto* model = dynamic_cast<ModFolderModel*>(getBaseModel()); model) {
|
||||
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
|
||||
for (const auto& selected : getTasks()) {
|
||||
selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion()));
|
||||
}
|
||||
|
||||
return makeShared<GetModDependenciesTask>(m_instance, model, selectedVers);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent,
|
||||
ResourcePackFolderModel* resourcePacks,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
: ResourceDownloadDialog(parent, resourcePacks, suppressInitialSearch), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toString().toUtf8()));
|
||||
}
|
||||
}
|
||||
|
||||
QList<BasePage*> ResourcePackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* modrinthPage = ModrinthResourcePackPage::create(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameResourcePackPage::create(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
TexturePackDownloadDialog::TexturePackDownloadDialog(QWidget* parent,
|
||||
TexturePackFolderModel* resourcePacks,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
: ResourceDownloadDialog(parent, resourcePacks, suppressInitialSearch), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toString().toUtf8()));
|
||||
}
|
||||
}
|
||||
|
||||
QList<BasePage*> TexturePackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* modrinthPage = ModrinthTexturePackPage::create(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameTexturePackPage::create(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent,
|
||||
ShaderPackFolderModel* shaders,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
: ResourceDownloadDialog(parent, shaders, suppressInitialSearch), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toString().toUtf8()));
|
||||
}
|
||||
}
|
||||
|
||||
QList<BasePage*> ShaderPackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
auto* modrinthPage = ModrinthShaderPackPage::create(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameShaderPackPage::create(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::setResourceMetadata(const std::shared_ptr<Metadata::ModStruct>& meta)
|
||||
{
|
||||
switch (meta->provider) {
|
||||
|
|
@ -448,34 +313,138 @@ void ResourceDownloadDialog::setResourceMetadata(const std::shared_ptr<Metadata:
|
|||
page->openProject(meta->project_id);
|
||||
}
|
||||
|
||||
DataPackDownloadDialog::DataPackDownloadDialog(QWidget* parent,
|
||||
DataPackFolderModel* dataPacks,
|
||||
GetModDependenciesTask::Ptr ResourceDownloadDialog::getModDependenciesTask()
|
||||
{
|
||||
if (!APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies
|
||||
if (auto* model = dynamic_cast<ModFolderModel*>(getBaseModel()); model) {
|
||||
QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
|
||||
for (auto& selected : getTasks()) {
|
||||
selectedVers.append(std::make_shared<GetModDependenciesTask::PackDependency>(selected->getPack(), selected->getVersion()));
|
||||
}
|
||||
|
||||
return makeShared<GetModDependenciesTask>(m_instance, model, selectedVers);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ResourceDownloadDialog* ResourceDownloadDialog::createMod(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
: ResourceDownloadDialog(parent, dataPacks, suppressInitialSearch), m_instance(instance)
|
||||
{
|
||||
setWindowTitle(dialogTitle());
|
||||
auto* dialog = new ResourceDownloadDialog(parent, mods, instance, tr("mods"), "ModDownloadGeometry", suppressInitialSearch);
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto loaders = static_cast<MinecraftInstance*>(instance)->getPackProfile()->getSupportedModLoaders().value();
|
||||
|
||||
if (ModrinthAPI::validateModLoaders(loaders)) {
|
||||
auto* page = Modrinth::createModPage(dialog, *instance);
|
||||
page->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(page);
|
||||
}
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders)) {
|
||||
auto* flamePage = Flame::createModPage(dialog, *instance);
|
||||
flamePage->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
dialog->initPages(pages);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ResourceDownloadDialog* ResourceDownloadDialog::createResourcePack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
{
|
||||
auto* dialog = new ResourceDownloadDialog(parent, mods, instance, tr("resource packs"), "RPDownloadGeometry", suppressInitialSearch);
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* page = Modrinth::createResourcePackResourcePage(dialog, *instance);
|
||||
page->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(page);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = Flame::createResourcePackResourcePage(dialog, *instance);
|
||||
flamePage->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
dialog->initPages(pages);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ResourceDownloadDialog* ResourceDownloadDialog::createTexturePack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
{
|
||||
auto* dialog = new ResourceDownloadDialog(parent, mods, instance, tr("texture packs"), "TPDownloadGeometry", suppressInitialSearch);
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* page = Modrinth::createTexturePackResourcePage(dialog, *instance);
|
||||
page->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(page);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = Flame::createTexturePackResourcePage(dialog, *instance);
|
||||
flamePage->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
dialog->initPages(pages);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ResourceDownloadDialog* ResourceDownloadDialog::createShaderPack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
{
|
||||
auto* dialog = new ResourceDownloadDialog(parent, mods, instance, tr("shader packs"), "ShaderDownloadGeometry", suppressInitialSearch);
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* page = Modrinth::createShaderPackResourcePage(dialog, *instance);
|
||||
page->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(page);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = Flame::createShaderPackResourcePage(dialog, *instance);
|
||||
flamePage->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
dialog->initPages(pages);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
ResourceDownloadDialog* ResourceDownloadDialog::createDataPack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch)
|
||||
{
|
||||
auto* dialog = new ResourceDownloadDialog(parent, mods, instance, tr("data packs"), "DataPackDownloadGeometry", suppressInitialSearch);
|
||||
QList<BasePage*> pages;
|
||||
|
||||
auto* page = Modrinth::createDataPackResourcePage(dialog, *instance);
|
||||
page->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(page);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = Flame::createDataPackResourcePage(dialog, *instance);
|
||||
flamePage->setSuppressInitialSearch(suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
dialog->initPages(pages);
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
void ResourceDownloadDialog::initPages(QList<BasePage*> pages)
|
||||
{
|
||||
m_pages = std::move(pages);
|
||||
|
||||
initializeContainer();
|
||||
connectButtons();
|
||||
|
||||
if (!geometrySaveKey().isEmpty()) {
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toByteArray()));
|
||||
restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get(geometrySaveKey()).toString().toUtf8()));
|
||||
}
|
||||
}
|
||||
|
||||
QList<BasePage*> DataPackDownloadDialog::getPages()
|
||||
{
|
||||
QList<BasePage*> pages;
|
||||
auto* modrinthPage = ModrinthDataPackPage::create(this, *m_instance);
|
||||
modrinthPage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(modrinthPage);
|
||||
if (APPLICATION->capabilities() & Application::SupportsFlame) {
|
||||
auto* flamePage = FlameDataPackPage::create(this, *m_instance);
|
||||
flamePage->setSuppressInitialSearch(m_suppressInitialSearch);
|
||||
pages.append(flamePage);
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#include <QLayout>
|
||||
|
||||
#include "QObjectPtr.h"
|
||||
#include "minecraft/mod/DataPackFolderModel.h"
|
||||
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "ui/pages/BasePageProvider.h"
|
||||
|
|
@ -51,13 +50,32 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||
public:
|
||||
using DownloadTaskPtr = shared_qobject_ptr<ResourceDownloadTask>;
|
||||
|
||||
ResourceDownloadDialog(QWidget* parent, ResourceFolderModel* baseModel, bool suppressInitialSearch = false);
|
||||
static ResourceDownloadDialog* createMod(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
static ResourceDownloadDialog* createResourcePack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
static ResourceDownloadDialog* createTexturePack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
static ResourceDownloadDialog* createShaderPack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
static ResourceDownloadDialog* createDataPack(QWidget* parent,
|
||||
ResourceFolderModel* mods,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
|
||||
void initializeContainer();
|
||||
void connectButtons();
|
||||
|
||||
//: String that gets appended to the download dialog title ("Download " + resourcesString())
|
||||
virtual QString resourcesString() const { return tr("resources"); }
|
||||
QString resourcesString() const { return m_resourcesString; }
|
||||
|
||||
QString dialogTitle() override { return tr("Download %1").arg(resourcesString()); };
|
||||
|
||||
|
|
@ -72,6 +90,8 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||
|
||||
void setResourceMetadata(const std::shared_ptr<Metadata::ModStruct>& meta);
|
||||
|
||||
QList<BasePage*> getPages() override { return m_pages; };
|
||||
|
||||
public slots:
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
|
|
@ -82,10 +102,19 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||
virtual void confirm();
|
||||
|
||||
protected:
|
||||
virtual QString geometrySaveKey() const { return ""; }
|
||||
ResourceDownloadDialog(QWidget* parent,
|
||||
ResourceFolderModel* baseModel,
|
||||
BaseInstance* instance,
|
||||
QString resourcesString = tr("resources"),
|
||||
QString geometrySaveKey = "",
|
||||
bool suppressInitialSearch = false);
|
||||
|
||||
QString geometrySaveKey() const { return m_geometrySaveKey; }
|
||||
void setButtonStatus();
|
||||
|
||||
virtual GetModDependenciesTask::Ptr getModDependenciesTask() { return nullptr; }
|
||||
GetModDependenciesTask::Ptr getModDependenciesTask();
|
||||
|
||||
void initPages(QList<BasePage*> pages);
|
||||
|
||||
protected:
|
||||
ResourceFolderModel* m_base_model;
|
||||
|
|
@ -97,104 +126,11 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
|
|||
|
||||
protected:
|
||||
bool m_suppressInitialSearch = false;
|
||||
};
|
||||
|
||||
class ModDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModDownloadDialog(QWidget* parent, ModFolderModel* mods, BaseInstance* instance, bool suppressInitialSearch = false);
|
||||
~ModDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the mod download dialog title ("Download " + resourcesString())
|
||||
QString resourcesString() const override { return tr("mods"); }
|
||||
QString geometrySaveKey() const override { return "ModDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
GetModDependenciesTask::Ptr getModDependenciesTask() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
class ResourcePackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ResourcePackDownloadDialog(QWidget* parent,
|
||||
ResourcePackFolderModel* resourcePacks,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
~ResourcePackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the resource pack download dialog title ("Download " + resourcesString())
|
||||
QString resourcesString() const override { return tr("resource packs"); }
|
||||
QString geometrySaveKey() const override { return "RPDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
class TexturePackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TexturePackDownloadDialog(QWidget* parent,
|
||||
TexturePackFolderModel* resourcePacks,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
~TexturePackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the texture pack download dialog title ("Download " + resourcesString())
|
||||
QString resourcesString() const override { return tr("texture packs"); }
|
||||
QString geometrySaveKey() const override { return "TPDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
class ShaderPackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ShaderPackDownloadDialog(QWidget* parent,
|
||||
ShaderPackFolderModel* shaders,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
~ShaderPackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the shader pack download dialog title ("Download " + resourcesString())
|
||||
QString resourcesString() const override { return tr("shader packs"); }
|
||||
QString geometrySaveKey() const override { return "ShaderDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
};
|
||||
|
||||
class DataPackDownloadDialog final : public ResourceDownloadDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DataPackDownloadDialog(QWidget* parent,
|
||||
DataPackFolderModel* dataPacks,
|
||||
BaseInstance* instance,
|
||||
bool suppressInitialSearch = false);
|
||||
~DataPackDownloadDialog() override = default;
|
||||
|
||||
//: String that gets appended to the data pack download dialog title ("Download " + resourcesString())
|
||||
QString resourcesString() const override { return tr("data packs"); }
|
||||
QString geometrySaveKey() const override { return "DataPackDownloadGeometry"; }
|
||||
|
||||
QList<BasePage*> getPages() override;
|
||||
|
||||
private:
|
||||
BaseInstance* m_instance;
|
||||
QString m_resourcesString;
|
||||
QString m_geometrySaveKey;
|
||||
QList<BasePage*> m_pages;
|
||||
};
|
||||
|
||||
} // namespace ResourceDownload
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void DataPackPage::downloadDataPacks()
|
|||
return; // this is a null instance or a legacy instance
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::DataPackDownloadDialog(this, m_model, m_instance);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createDataPack(this, m_model, m_instance);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &DataPackPage::downloadDialogFinished);
|
||||
|
||||
|
|
@ -242,9 +242,9 @@ void DataPackPage::changeDataPackVersion()
|
|||
return;
|
||||
}
|
||||
|
||||
ResourceDownload::DataPackDownloadDialog mdownload(this, m_model, m_instance, true);
|
||||
mdownload.setResourceMetadata(resource.metadata());
|
||||
if (mdownload.exec() != 0) {
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createDataPack(this, m_model, m_instance, true);
|
||||
m_downloadDialog->setResourceMetadata(resource.metadata());
|
||||
if (m_downloadDialog->exec() != 0) {
|
||||
auto* tasks = new ConcurrentTask("Download Data Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
connect(tasks, &Task::failed, [this, tasks](const QString& reason) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||
|
|
@ -263,7 +263,7 @@ void DataPackPage::changeDataPackVersion()
|
|||
tasks->deleteLater();
|
||||
});
|
||||
|
||||
for (auto& task : mdownload.getTasks()) {
|
||||
for (auto& task : m_downloadDialog->getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class DataPackPage : public ExternalResourcesPage {
|
|||
|
||||
private:
|
||||
DataPackFolderModel* m_model;
|
||||
QPointer<ResourceDownload::DataPackDownloadDialog> m_downloadDialog;
|
||||
QPointer<ResourceDownload::ResourceDownloadDialog> m_downloadDialog;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ void ModFolderPage::downloadMods()
|
|||
}
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ModDownloadDialog(this, m_model, m_instance);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createMod(this, m_model, m_instance);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ModFolderPage::downloadDialogFinished);
|
||||
|
||||
|
|
@ -352,7 +352,7 @@ void ModFolderPage::changeModVersion()
|
|||
return;
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ModDownloadDialog(this, m_model, m_instance, true);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createMod(this, m_model, m_instance, true);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ModFolderPage::downloadDialogFinished);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class ModFolderPage : public ExternalResourcesPage {
|
|||
|
||||
protected:
|
||||
ModFolderModel* m_model;
|
||||
QPointer<ResourceDownload::ModDownloadDialog> m_downloadDialog;
|
||||
QPointer<ResourceDownload::ResourceDownloadDialog> m_downloadDialog;
|
||||
};
|
||||
|
||||
class CoreModFolderPage : public ModFolderPage {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ void ResourcePackPage::downloadResourcePacks()
|
|||
return; // this is a null instance or a legacy instance
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ResourcePackDownloadDialog(this, m_model, m_instance);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createResourcePack(this, m_model, m_instance);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ResourcePackPage::downloadDialogFinished);
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ void ResourcePackPage::changeResourcePackVersion()
|
|||
return;
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ResourcePackDownloadDialog(this, m_model, m_instance, true);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createResourcePack(this, m_model, m_instance, true);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ResourcePackPage::downloadDialogFinished);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@
|
|||
#include "ShaderPackPage.h"
|
||||
#include "ui_ExternalResourcesPage.h"
|
||||
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/mod/ShaderPackFolderModel.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
|
|
@ -82,7 +80,7 @@ void ShaderPackPage::downloadShaderPack()
|
|||
return; // this is a null instance or a legacy instance
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ShaderPackDownloadDialog(this, m_model, m_instance);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createShaderPack(this, m_model, m_instance);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ShaderPackPage::downloadDialogFinished);
|
||||
|
||||
|
|
@ -256,7 +254,7 @@ void ShaderPackPage::changeShaderPackVersion()
|
|||
return;
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::ShaderPackDownloadDialog(this, m_model, m_instance, true);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createShaderPack(this, m_model, m_instance, true);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &ShaderPackPage::downloadDialogFinished);
|
||||
|
||||
|
|
|
|||
|
|
@ -63,5 +63,5 @@ class ShaderPackPage : public ExternalResourcesPage {
|
|||
|
||||
private:
|
||||
ShaderPackFolderModel* m_model;
|
||||
QPointer<ResourceDownload::ShaderPackDownloadDialog> m_downloadDialog;
|
||||
QPointer<ResourceDownload::ResourceDownloadDialog> m_downloadDialog;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@
|
|||
|
||||
#include "TexturePackPage.h"
|
||||
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/mod/TexturePack.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
|
|
@ -91,7 +87,7 @@ void TexturePackPage::downloadTexturePacks()
|
|||
return; // this is a null instance or a legacy instance
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::TexturePackDownloadDialog(this, m_model, m_instance);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createTexturePack(this, m_model, m_instance);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &TexturePackPage::downloadDialogFinished);
|
||||
m_downloadDialog->open();
|
||||
|
|
@ -264,7 +260,7 @@ void TexturePackPage::changeTexturePackVersion()
|
|||
return;
|
||||
}
|
||||
|
||||
m_downloadDialog = new ResourceDownload::TexturePackDownloadDialog(this, m_model, m_instance, true);
|
||||
m_downloadDialog = ResourceDownload::ResourceDownloadDialog::createTexturePack(this, m_model, m_instance, true);
|
||||
connect(this, &QObject::destroyed, m_downloadDialog, &QDialog::close);
|
||||
connect(m_downloadDialog, &QDialog::finished, this, &TexturePackPage::downloadDialogFinished);
|
||||
|
||||
|
|
|
|||
|
|
@ -67,5 +67,5 @@ class TexturePackPage : public ExternalResourcesPage {
|
|||
|
||||
private:
|
||||
TexturePackFolderModel* m_model;
|
||||
QPointer<ResourceDownload::TexturePackDownloadDialog> m_downloadDialog;
|
||||
QPointer<ResourceDownload::ResourceDownloadDialog> m_downloadDialog;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(ResourceDownloadDialog* 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(ResourceDownloadDialog* dialog, BaseInstance& instance, ResourceProviderData p, ResourceAPI* api);
|
||||
|
||||
protected slots:
|
||||
void triggerSearch() override;
|
||||
|
|
|
|||
|
|
@ -40,38 +40,79 @@
|
|||
#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(ResourceDownloadDialog* 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 +141,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,64 +6,30 @@
|
|||
|
||||
#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;
|
||||
class ResourceDownloadDialog;
|
||||
|
||||
/* This page handles most logic related to browsing and selecting mods to download. */
|
||||
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(ResourceDownloadDialog* 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 +38,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(ResourceDownloadDialog* 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,51 +5,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "ui/pages/modplatform/ResourcePage.h"
|
||||
#include "ui/pages/modplatform/ShaderPackModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class ResourcePage;
|
||||
}
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
class ShaderPackDownloadDialog;
|
||||
class ResourceDownloadDialog;
|
||||
|
||||
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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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,18 +99,18 @@ 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())
|
||||
}
|
||||
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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
DataPackResourcePage* createDataPackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
ResourcePackResourcePage* createResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
TexturePackResourcePage* createTexturePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
ModPage* createModPage(ResourceDownloadDialog* 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,18 +116,18 @@ 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())
|
||||
}
|
||||
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,13 +229,14 @@ 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,15 +288,19 @@ 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* 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(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
DataPackResourcePage* createDataPackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
ResourcePackResourcePage* createResourcePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
TexturePackResourcePage* createTexturePackResourcePage(ResourceDownloadDialog* dialog, BaseInstance& instance);
|
||||
ModPage* createModPage(ResourceDownloadDialog* 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