Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into disablemods

This commit is contained in:
Trial97
2023-11-23 13:38:11 +02:00
221 changed files with 12812 additions and 1331 deletions

View File

@@ -37,9 +37,9 @@
#include "ModFolderModel.h"
#include <FileSystem.h>
#include <qheaderview.h>
#include <QDebug>
#include <QFileSystemWatcher>
#include <QHeaderView>
#include <QIcon>
#include <QMimeData>
#include <QString>
@@ -65,8 +65,8 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool
m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider" });
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch,
QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch,
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true, true, true };
}
@@ -131,6 +131,11 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const
}
return {};
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
switch (column) {
case ActiveColumn:

View File

@@ -4,6 +4,7 @@
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QHeaderView>
#include <QIcon>
#include <QMenu>
#include <QMimeData>
@@ -45,7 +46,7 @@ ResourceFolderModel::~ResourceFolderModel()
QCoreApplication::processEvents();
}
bool ResourceFolderModel::startWatching(const QStringList paths)
bool ResourceFolderModel::startWatching(const QStringList& paths)
{
if (m_is_watching)
return false;
@@ -64,7 +65,7 @@ bool ResourceFolderModel::startWatching(const QStringList paths)
return m_is_watching;
}
bool ResourceFolderModel::stopWatching(const QStringList paths)
bool ResourceFolderModel::stopWatching(const QStringList& paths)
{
if (!m_is_watching)
return false;
@@ -460,9 +461,9 @@ bool ResourceFolderModel::setData(const QModelIndex& index, [[maybe_unused]] con
if (role == Qt::CheckStateRole) {
if (m_instance != nullptr && m_instance->isRunning()) {
auto response =
CustomMessageBox::selectable(nullptr, "Confirm toggle",
"If you enable/disable this resource while the game is running it may crash your game.\n"
"Are you sure you want to do this?",
CustomMessageBox::selectable(nullptr, tr("Confirm toggle"),
tr("If you enable/disable this resource while the game is running it may crash your game.\n"
"Are you sure you want to do this?"),
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
@@ -516,36 +517,22 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column)
act->setText(columnNames().at(column));
}
void ResourceFolderModel::saveHiddenColumn(int column, bool hidden)
void ResourceFolderModel::saveColumns(QTreeView* tree)
{
auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id());
auto const setting_name = QString("UI/%1_Page/Columns").arg(id());
auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name)
: m_instance->settings()->registerSetting(setting_name);
auto hiddenColumns = setting->get().toStringList();
auto name = columnNames(false).at(column);
auto index = hiddenColumns.indexOf(name);
if (index >= 0 && !hidden) {
hiddenColumns.removeAt(index);
} else if (index < 0 && hidden) {
hiddenColumns.append(name);
}
setting->set(hiddenColumns);
setting->set(tree->header()->saveState());
}
void ResourceFolderModel::loadHiddenColumns(QTreeView* tree)
void ResourceFolderModel::loadColumns(QTreeView* tree)
{
auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id());
auto const setting_name = QString("UI/%1_Page/Columns").arg(id());
auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name)
: m_instance->settings()->registerSetting(setting_name);
auto hiddenColumns = setting->get().toStringList();
auto col_names = columnNames(false);
for (auto col_name : hiddenColumns) {
auto index = col_names.indexOf(col_name);
if (index >= 0)
tree->setColumnHidden(index, true);
}
tree->header()->restoreState(setting->get().toByteArray());
}
QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree)
@@ -570,7 +557,7 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree)
if (m_column_resize_modes.at(c) == QHeaderView::ResizeToContents)
tree->resizeColumnToContents(c);
}
saveHiddenColumn(col, !toggled);
saveColumns(tree);
});
menu->addAction(act);

View File

@@ -39,14 +39,14 @@ class ResourceFolderModel : public QAbstractListModel {
* Returns whether starting to watch all the paths was successful.
* If one or more fails, it returns false.
*/
bool startWatching(const QStringList paths);
bool startWatching(const QStringList& paths);
/** Stops watching the paths for changes.
*
* Returns whether stopping to watch all the paths was successful.
* If one or more fails, it returns false.
*/
bool stopWatching(const QStringList paths);
bool stopWatching(const QStringList& paths);
/* Helper methods for subclasses, using a predetermined list of paths. */
virtual bool startWatching() { return startWatching({ m_dir.absolutePath() }); }
@@ -117,8 +117,8 @@ class ResourceFolderModel : public QAbstractListModel {
[[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void setupHeaderAction(QAction* act, int column);
void saveHiddenColumn(int column, bool hidden);
void loadHiddenColumns(QTreeView* tree);
void saveColumns(QTreeView* tree);
void loadColumns(QTreeView* tree);
QMenu* createHeaderContextMenu(QTreeView* tree);
/** This creates a proxy model to filter / sort the model for a UI.
@@ -201,8 +201,7 @@ class ResourceFolderModel : public QAbstractListModel {
QList<SortType> m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE };
QStringList m_column_names = { "Enable", "Name", "Last Modified" };
QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified") };
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch,
QHeaderView::ResizeToContents };
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive };
QList<bool> m_columnsHideable = { false, false, true };
QDir m_dir;

View File

@@ -52,8 +52,8 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc
m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" });
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents,
QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true, true };
}
@@ -117,6 +117,11 @@ QVariant ResourcePackFolderModel::data(const QModelIndex& index, int role) const
}
return m_resources[row]->internal_id();
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
switch (column) {
case ActiveColumn:

View File

@@ -47,8 +47,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance*
m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified" });
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") });
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE };
m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch,
QHeaderView::ResizeToContents };
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive };
m_columnsHideable = { false, true, false, true };
}
@@ -104,6 +103,11 @@ QVariant TexturePackFolderModel::data(const QModelIndex& index, int role) const
}
return {};
}
case Qt::SizeHintRole:
if (column == ImageColumn) {
return QSize(32, 32);
}
return {};
case Qt::CheckStateRole:
if (column == ActiveColumn) {
return m_resources[row]->enabled() ? Qt::Checked : Qt::Unchecked;

View File

@@ -137,10 +137,11 @@ Task::Ptr GetModDependenciesTask::getProjectInfoTask(std::shared_ptr<PackDepende
auto provider = pDep->pack->provider == m_flame_provider.name ? m_flame_provider : m_modrinth_provider;
auto responseInfo = std::make_shared<QByteArray>();
auto info = provider.api->getProject(pDep->pack->addonId.toString(), responseInfo);
QObject::connect(info.get(), &NetJob::succeeded, [responseInfo, provider, pDep] {
QObject::connect(info.get(), &NetJob::succeeded, [this, responseInfo, provider, pDep] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*responseInfo, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
removePack(pDep->pack->addonId);
qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qDebug() << *responseInfo;
@@ -151,6 +152,7 @@ Task::Ptr GetModDependenciesTask::getProjectInfoTask(std::shared_ptr<PackDepende
: Json::requireObject(doc);
provider.mod->loadIndexedPack(*pDep->pack, obj);
} catch (const JSONValidationError& e) {
removePack(pDep->pack->addonId);
qDebug() << doc;
qWarning() << "Error while reading mod info: " << e.cause();
}
@@ -211,11 +213,13 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
pDep->pack->versionsLoaded = true;
} catch (const JSONValidationError& e) {
removePack(dep.addonId);
qDebug() << doc;
qWarning() << "Error while reading mod version: " << e.cause();
return;
}
if (level == 0) {
removePack(dep.addonId);
qWarning() << "Dependency cycle exceeded";
return;
}
@@ -238,7 +242,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
return tasks;
}
void GetModDependenciesTask::removePack(const QVariant addonId)
void GetModDependenciesTask::removePack(const QVariant& addonId)
{
auto pred = [addonId](const std::shared_ptr<PackDependency>& v) { return v->pack->addonId == addonId; };
#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)

View File

@@ -65,13 +65,13 @@ class GetModDependenciesTask : public SequentialTask {
QHash<QString, QStringList> getRequiredBy();
protected slots:
Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int);
Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, ModPlatform::ResourceProvider, int);
QList<ModPlatform::Dependency> getDependenciesForVersion(const ModPlatform::IndexedVersion&,
const ModPlatform::ResourceProvider providerName);
ModPlatform::ResourceProvider providerName);
void prepare();
Task::Ptr getProjectInfoTask(std::shared_ptr<PackDependency> pDep);
ModPlatform::Dependency getOverride(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider providerName);
void removePack(const QVariant addonId);
ModPlatform::Dependency getOverride(const ModPlatform::Dependency&, ModPlatform::ResourceProvider providerName);
void removePack(const QVariant& addonId);
private:
QList<std::shared_ptr<PackDependency>> m_pack_dependencies;

View File

@@ -688,6 +688,7 @@ bool loadIconFile(const Mod& mod)
return png_invalid(); // icon invalid
}
}
return false;
}
case ResourceType::ZIPFILE: {
QuaZip zip(mod.fileinfo().filePath());
@@ -714,6 +715,7 @@ bool loadIconFile(const Mod& mod)
} else {
return png_invalid(); // could not set icon as current file.
}
return false;
}
case ResourceType::LITEMOD: {
return false; // can lightmods even have icons?

View File

@@ -232,10 +232,9 @@ bool processPackPNG(const ResourcePack& pack)
} else {
return png_invalid(); // pack.png does not exists or is not a valid file.
}
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
}
case ResourceType::ZIPFILE: {
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false; // can't open zip file
@@ -259,6 +258,7 @@ bool processPackPNG(const ResourcePack& pack)
} else {
return png_invalid(); // could not set pack.mcmeta as current file.
}
return false; // not processed correctly; https://github.com/PrismLauncher/PrismLauncher/issues/1740
}
default:
qWarning() << "Invalid type for resource pack parse task!";

View File

@@ -186,10 +186,9 @@ bool processPackPNG(const TexturePack& pack)
} else {
return png_invalid(); // pack.png does not exists or is not a valid file.
}
return false;
}
case ResourceType::ZIPFILE: {
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);
QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false; // can't open zip file
@@ -215,6 +214,7 @@ bool processPackPNG(const TexturePack& pack)
zip.close();
return png_invalid(); // could not set pack.mcmeta as current file.
}
return false;
}
default:
qWarning() << "Invalid type for resource pack parse task!";