mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-08-04 03:47:57 -04:00
feat: add requireBy and requires columns
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
bc383abfda
commit
2b62b4281f
@ -106,6 +106,20 @@ int Mod::compare(const Resource& other, SortType type) const
|
|||||||
return compare_result;
|
return compare_result;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SortType::REQUIRED_BY: {
|
||||||
|
if (requiredByCount() > cast_other->requiredByCount())
|
||||||
|
return 1;
|
||||||
|
if (requiredByCount() < cast_other->requiredByCount())
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SortType::REQUIRES: {
|
||||||
|
if (requiresCount() > cast_other->requiresCount())
|
||||||
|
return 1;
|
||||||
|
if (requiresCount() < cast_other->requiresCount())
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -289,3 +303,19 @@ QStringList Mod::dependencies() const
|
|||||||
{
|
{
|
||||||
return details().dependencies;
|
return details().dependencies;
|
||||||
}
|
}
|
||||||
|
int Mod::requiredByCount() const
|
||||||
|
{
|
||||||
|
return m_requiredByCount;
|
||||||
|
}
|
||||||
|
int Mod::requiresCount() const
|
||||||
|
{
|
||||||
|
return m_requiresCount;
|
||||||
|
}
|
||||||
|
void Mod::setRequiredByCount(int value)
|
||||||
|
{
|
||||||
|
m_requiredByCount = value;
|
||||||
|
}
|
||||||
|
void Mod::setRequiresCount(int value)
|
||||||
|
{
|
||||||
|
m_requiresCount = value;
|
||||||
|
}
|
||||||
|
@ -74,6 +74,12 @@ class Mod : public Resource {
|
|||||||
auto releaseType() const -> QString;
|
auto releaseType() const -> QString;
|
||||||
QStringList dependencies() const;
|
QStringList dependencies() const;
|
||||||
|
|
||||||
|
int requiredByCount() const;
|
||||||
|
int requiresCount() const;
|
||||||
|
|
||||||
|
void setRequiredByCount(int value);
|
||||||
|
void setRequiresCount(int value);
|
||||||
|
|
||||||
/** Get the intneral path to the mod's icon file*/
|
/** Get the intneral path to the mod's icon file*/
|
||||||
QString iconPath() const { return m_local_details.icon_file; }
|
QString iconPath() const { return m_local_details.icon_file; }
|
||||||
/** Gets the icon of the mod, converted to a QPixmap for drawing, and scaled to size. */
|
/** Gets the icon of the mod, converted to a QPixmap for drawing, and scaled to size. */
|
||||||
@ -105,4 +111,7 @@ class Mod : public Resource {
|
|||||||
bool wasEverUsed = false;
|
bool wasEverUsed = false;
|
||||||
bool wasReadAttempt = false;
|
bool wasReadAttempt = false;
|
||||||
} mutable m_packImageCacheKey;
|
} mutable m_packImageCacheKey;
|
||||||
|
|
||||||
|
int m_requiredByCount = 0;
|
||||||
|
int m_requiresCount = 0;
|
||||||
};
|
};
|
||||||
|
@ -48,25 +48,31 @@
|
|||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
#include "minecraft/mod/tasks/LocalModParseTask.h"
|
#include "minecraft/mod/tasks/LocalModParseTask.h"
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent)
|
ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent)
|
||||||
: ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent)
|
: ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent)
|
||||||
{
|
{
|
||||||
m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Size", "Side", "Loaders",
|
m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider", "Size", "Side", "Loaders",
|
||||||
"Minecraft Versions", "Release Type" });
|
"Minecraft Versions", "Release Type", "Requires", "Required by" });
|
||||||
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"),
|
m_column_names_translated =
|
||||||
tr("Size"), tr("Side"), tr("Loaders"), tr("Minecraft Versions"), tr("Release Type") });
|
QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider"), tr("Size"), tr("Side"),
|
||||||
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION,
|
tr("Loaders"), tr("Minecraft Versions"), tr("Release Type"), tr("Requires "), tr("Required by") });
|
||||||
SortType::DATE, SortType::PROVIDER, SortType::SIZE, SortType::SIDE,
|
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE,
|
||||||
SortType::LOADERS, SortType::MC_VERSIONS, SortType::RELEASE_TYPE };
|
SortType::PROVIDER, SortType::SIZE, SortType::SIDE, SortType::LOADERS, SortType::MC_VERSIONS,
|
||||||
|
SortType::RELEASE_TYPE, SortType::REQUIRES, SortType::REQUIRED_BY };
|
||||||
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
|
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
|
||||||
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive,
|
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive,
|
||||||
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive };
|
QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive,
|
||||||
m_columnsHideable = { false, true, false, true, true, true, true, true, true, true, true };
|
QHeaderView::Interactive };
|
||||||
|
m_columnsHideable = { false, true, false, true, true, true, true, true, true, true, true, true, true };
|
||||||
|
|
||||||
|
connect(this, &ModFolderModel::parseFinished, this, &ModFolderModel::onParseFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant ModFolderModel::data(const QModelIndex& index, int role) const
|
QVariant ModFolderModel::data(const QModelIndex& index, int role) const
|
||||||
@ -110,8 +116,15 @@ QVariant ModFolderModel::data(const QModelIndex& index, int role) const
|
|||||||
case ReleaseTypeColumn: {
|
case ReleaseTypeColumn: {
|
||||||
return at(row).releaseType();
|
return at(row).releaseType();
|
||||||
}
|
}
|
||||||
case SizeColumn:
|
case SizeColumn: {
|
||||||
return at(row).sizeStr();
|
return at(row).sizeStr();
|
||||||
|
}
|
||||||
|
case RequiredByColumn: {
|
||||||
|
return at(row).requiredByCount();
|
||||||
|
}
|
||||||
|
case RequiresColumn: {
|
||||||
|
return at(row).requiresCount();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -168,6 +181,8 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio
|
|||||||
case McVersionsColumn:
|
case McVersionsColumn:
|
||||||
case ReleaseTypeColumn:
|
case ReleaseTypeColumn:
|
||||||
case SizeColumn:
|
case SizeColumn:
|
||||||
|
case RequiredByColumn:
|
||||||
|
case RequiresColumn:
|
||||||
return columnNames().at(section);
|
return columnNames().at(section);
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -195,6 +210,10 @@ QVariant ModFolderModel::headerData(int section, [[maybe_unused]] Qt::Orientatio
|
|||||||
return tr("The release type.");
|
return tr("The release type.");
|
||||||
case SizeColumn:
|
case SizeColumn:
|
||||||
return tr("The size of the mod.");
|
return tr("The size of the mod.");
|
||||||
|
case RequiredByColumn:
|
||||||
|
return tr("Number of mods for what this is needed.");
|
||||||
|
case RequiresColumn:
|
||||||
|
return tr("Number of mods that this requires.");
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -240,3 +259,64 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id)
|
|||||||
|
|
||||||
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModFolderModel::onParseFinished()
|
||||||
|
{
|
||||||
|
if (hasPendingParseTasks()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto mods = allMods();
|
||||||
|
|
||||||
|
auto findById = [mods](QString modId) -> Mod* {
|
||||||
|
auto found = std::find_if(mods.begin(), mods.end(), [modId](Mod* m) { return m->mod_id() == modId; });
|
||||||
|
return found != mods.end() ? *found : nullptr;
|
||||||
|
};
|
||||||
|
auto findByProjectID = [mods](QVariant modId, ModPlatform::ResourceProvider provider) -> Mod* {
|
||||||
|
auto found = std::find_if(mods.begin(), mods.end(), [modId, provider](Mod* m) {
|
||||||
|
return m->metadata()->provider == provider && m->metadata()->project_id == modId;
|
||||||
|
});
|
||||||
|
return found != mods.end() ? *found : nullptr;
|
||||||
|
};
|
||||||
|
for (auto mod : mods) {
|
||||||
|
auto id = mod->internal_id();
|
||||||
|
for (auto dep : mod->dependencies()) {
|
||||||
|
auto d = findById(dep);
|
||||||
|
if (d) {
|
||||||
|
m_requires[id] << d;
|
||||||
|
m_requiredBy[d->internal_id()] << mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto dep : mod->metadata()->dependencies) {
|
||||||
|
auto d = findByProjectID(dep.addonId, mod->metadata()->provider);
|
||||||
|
if (d) {
|
||||||
|
m_requires[id] << d;
|
||||||
|
m_requiredBy[d->internal_id()] << mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto removeDuplicates = [](QList<Mod*>& list) {
|
||||||
|
std::set<QString> seen;
|
||||||
|
auto it = std::remove_if(list.begin(), list.end(), [&seen](Mod* m) {
|
||||||
|
auto id = m->internal_id();
|
||||||
|
if (seen.count(id) > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
seen.insert(id);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
list.erase(it, list.end());
|
||||||
|
};
|
||||||
|
for (auto key : m_requiredBy.keys()) {
|
||||||
|
removeDuplicates(m_requiredBy[key]);
|
||||||
|
}
|
||||||
|
for (auto key : m_requires.keys()) {
|
||||||
|
removeDuplicates(m_requires[key]);
|
||||||
|
}
|
||||||
|
for (auto mod : mods) {
|
||||||
|
auto id = mod->internal_id();
|
||||||
|
mod->setRequiredByCount(m_requiredBy[id].count());
|
||||||
|
mod->setRequiresCount(m_requires[id].count());
|
||||||
|
int row = m_resources_index[id];
|
||||||
|
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
@ -46,6 +47,7 @@
|
|||||||
|
|
||||||
#include "Mod.h"
|
#include "Mod.h"
|
||||||
#include "ResourceFolderModel.h"
|
#include "ResourceFolderModel.h"
|
||||||
|
#include "minecraft/mod/Resource.h"
|
||||||
|
|
||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
class QFileSystemWatcher;
|
class QFileSystemWatcher;
|
||||||
@ -69,6 +71,8 @@ class ModFolderModel : public ResourceFolderModel {
|
|||||||
LoadersColumn,
|
LoadersColumn,
|
||||||
McVersionsColumn,
|
McVersionsColumn,
|
||||||
ReleaseTypeColumn,
|
ReleaseTypeColumn,
|
||||||
|
RequiresColumn,
|
||||||
|
RequiredByColumn,
|
||||||
NUM_COLUMNS
|
NUM_COLUMNS
|
||||||
};
|
};
|
||||||
ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr);
|
ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent = nullptr);
|
||||||
@ -89,4 +93,9 @@ class ModFolderModel : public ResourceFolderModel {
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onParseSucceeded(int ticket, QString resource_id) override;
|
void onParseSucceeded(int ticket, QString resource_id) override;
|
||||||
|
void onParseFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<QString, QList<Mod*>> m_requiredBy;
|
||||||
|
QHash<QString, QList<Mod*>> m_requires;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,21 @@ enum class ResourceStatus {
|
|||||||
UNKNOWN, // Default status
|
UNKNOWN, // Default status
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SortType { NAME, DATE, VERSION, ENABLED, PACK_FORMAT, PROVIDER, SIZE, SIDE, MC_VERSIONS, LOADERS, RELEASE_TYPE };
|
enum class SortType {
|
||||||
|
NAME,
|
||||||
|
DATE,
|
||||||
|
VERSION,
|
||||||
|
ENABLED,
|
||||||
|
PACK_FORMAT,
|
||||||
|
PROVIDER,
|
||||||
|
SIZE,
|
||||||
|
SIDE,
|
||||||
|
MC_VERSIONS,
|
||||||
|
LOADERS,
|
||||||
|
RELEASE_TYPE,
|
||||||
|
REQUIRES,
|
||||||
|
REQUIRED_BY,
|
||||||
|
};
|
||||||
|
|
||||||
enum class EnableAction { ENABLE, DISABLE, TOGGLE };
|
enum class EnableAction { ENABLE, DISABLE, TOGGLE };
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user