From b8c6a42f498823151a61b5d56c8cc587fd88c728 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sat, 14 Nov 2020 18:06:27 +0000 Subject: NOISSUE Add sorting options to FTB pack install page --- .../pages/modplatform/ftb/FtbFilterModel.cpp | 64 +++++ application/pages/modplatform/ftb/FtbFilterModel.h | 33 +++ application/pages/modplatform/ftb/FtbListModel.cpp | 310 +++++++++++++++++++++ application/pages/modplatform/ftb/FtbListModel.h | 68 +++++ application/pages/modplatform/ftb/FtbModel.cpp | 310 --------------------- application/pages/modplatform/ftb/FtbModel.h | 68 ----- application/pages/modplatform/ftb/FtbPage.cpp | 34 ++- application/pages/modplatform/ftb/FtbPage.h | 7 +- application/pages/modplatform/ftb/FtbPage.ui | 41 +-- 9 files changed, 529 insertions(+), 406 deletions(-) create mode 100644 application/pages/modplatform/ftb/FtbFilterModel.cpp create mode 100644 application/pages/modplatform/ftb/FtbFilterModel.h create mode 100644 application/pages/modplatform/ftb/FtbListModel.cpp create mode 100644 application/pages/modplatform/ftb/FtbListModel.h delete mode 100644 application/pages/modplatform/ftb/FtbModel.cpp delete mode 100644 application/pages/modplatform/ftb/FtbModel.h (limited to 'application/pages/modplatform/ftb') diff --git a/application/pages/modplatform/ftb/FtbFilterModel.cpp b/application/pages/modplatform/ftb/FtbFilterModel.cpp new file mode 100644 index 00000000..dec3a017 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbFilterModel.cpp @@ -0,0 +1,64 @@ +#include "FtbFilterModel.h" + +#include + +#include "modplatform/modpacksch/FTBPackManifest.h" +#include + +namespace Ftb { + +FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent) +{ + currentSorting = Sorting::ByPlays; + sortings.insert(tr("Sort by plays"), Sorting::ByPlays); + sortings.insert(tr("Sort by installs"), Sorting::ByInstalls); + sortings.insert(tr("Sort by name"), Sorting::ByName); +} + +const QMap FilterModel::getAvailableSortings() +{ + return sortings; +} + +QString FilterModel::translateCurrentSorting() +{ + return sortings.key(currentSorting); +} + +void FilterModel::setSorting(Sorting sorting) +{ + currentSorting = sorting; + invalidate(); +} + +FilterModel::Sorting FilterModel::getCurrentSorting() +{ + return currentSorting; +} + +bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + return true; +} + +bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + ModpacksCH::Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value(); + ModpacksCH::Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value(); + + if (currentSorting == ByPlays) { + return leftPack.plays < rightPack.plays; + } + else if (currentSorting == ByInstalls) { + return leftPack.installs < rightPack.installs; + } + else if (currentSorting == ByName) { + return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + } + + // Invalid sorting set, somehow... + qWarning() << "Invalid sorting set!"; + return true; +} + +} diff --git a/application/pages/modplatform/ftb/FtbFilterModel.h b/application/pages/modplatform/ftb/FtbFilterModel.h new file mode 100644 index 00000000..4fe2a274 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbFilterModel.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace Ftb { + +class FilterModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + FilterModel(QObject* parent = Q_NULLPTR); + enum Sorting { + ByPlays, + ByInstalls, + ByName, + }; + const QMap getAvailableSortings(); + QString translateCurrentSorting(); + void setSorting(Sorting sorting); + Sorting getCurrentSorting(); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + +private: + QMap sortings; + Sorting currentSorting; + +}; + +} diff --git a/application/pages/modplatform/ftb/FtbListModel.cpp b/application/pages/modplatform/ftb/FtbListModel.cpp new file mode 100644 index 00000000..e53f1134 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbListModel.cpp @@ -0,0 +1,310 @@ +#include "FtbListModel.h" + +#include "BuildConfig.h" +#include "Env.h" +#include "MultiMC.h" +#include "Json.h" + +#include + +namespace Ftb { + +ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) +{ +} + +ListModel::~ListModel() +{ +} + +int ListModel::rowCount(const QModelIndex &parent) const +{ + return modpacks.size(); +} + +int ListModel::columnCount(const QModelIndex &parent) const +{ + return 1; +} + +QVariant ListModel::data(const QModelIndex &index, int role) const +{ + int pos = index.row(); + if(pos >= modpacks.size() || pos < 0 || !index.isValid()) + { + return QString("INVALID INDEX %1").arg(pos); + } + + ModpacksCH::Modpack pack = modpacks.at(pos); + if(role == Qt::DisplayRole) + { + return pack.name; + } + else if (role == Qt::ToolTipRole) + { + return pack.synopsis; + } + else if(role == Qt::DecorationRole) + { + QIcon placeholder = MMC->getThemedIcon("screenshot-placeholder"); + + auto iter = m_logoMap.find(pack.name); + if (iter != m_logoMap.end()) { + auto & logo = *iter; + if(!logo.result.isNull()) { + return logo.result; + } + return placeholder; + } + + for(auto art : pack.art) { + if(art.type == "square") { + ((ListModel *)this)->requestLogo(pack.name, art.url); + } + } + return placeholder; + } + else if(role == Qt::UserRole) + { + QVariant v; + v.setValue(pack); + return v; + } + + return QVariant(); +} + +void ListModel::performSearch() +{ + auto *netJob = new NetJob("Ftb::Search"); + QString searchUrl; + if(currentSearchTerm.isEmpty()) { + searchUrl = BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all"; + } + else { + searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/search/25?term=%1") + .arg(currentSearchTerm); + } + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + jobPtr = netJob; + jobPtr->start(); + QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); + QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); +} + +void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) +{ + if(m_logoMap.contains(logo)) + { + callback(ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + } + else + { + requestLogo(logo, logoUrl); + } +} + +void ListModel::searchWithTerm(const QString &term) +{ + if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { + return; + } + currentSearchTerm = term; + if(jobPtr) { + jobPtr->abort(); + searchState = ResetRequested; + return; + } + else { + beginResetModel(); + modpacks.clear(); + endResetModel(); + searchState = None; + } + performSearch(); +} + +void ListModel::searchRequestFinished() +{ + jobPtr.reset(); + remainingPacks.clear(); + + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); + if(parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << response; + return; + } + + auto packs = doc.object().value("packs").toArray(); + for(auto pack : packs) { + auto packId = pack.toInt(); + remainingPacks.append(packId); + } + + if(!remainingPacks.isEmpty()) { + currentPack = remainingPacks.at(0); + requestPack(); + } +} + +void ListModel::searchRequestFailed(QString reason) +{ + jobPtr.reset(); + remainingPacks.clear(); + + if(searchState == ResetRequested) { + beginResetModel(); + modpacks.clear(); + endResetModel(); + + performSearch(); + } else { + searchState = Finished; + } +} + +void ListModel::requestPack() +{ + auto *netJob = new NetJob("Ftb::Search"); + auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1") + .arg(currentPack); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + jobPtr = netJob; + jobPtr->start(); + + QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished); + QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed); +} + +void ListModel::packRequestFinished() +{ + jobPtr.reset(); + remainingPacks.removeOne(currentPack); + + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); + + if(parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString(); + qWarning() << response; + return; + } + + auto obj = doc.object(); + + ModpacksCH::Modpack pack; + try + { + ModpacksCH::loadModpack(pack, obj); + } + catch (const JSONValidationError &e) + { + qDebug() << QString::fromUtf8(response); + qWarning() << "Error while reading pack manifest from FTB: " << e.cause(); + return; + } + + // Since there is no guarantee that packs have a version, this will just + // ignore those "dud" packs. + if (pack.versions.empty()) + { + qWarning() << "FTB Pack " << pack.id << " ignored. reason: lacking any versions"; + return; + } + + beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); + modpacks.append(pack); + endInsertRows(); + + if(!remainingPacks.isEmpty()) { + currentPack = remainingPacks.at(0); + requestPack(); + } +} + +void ListModel::packRequestFailed(QString reason) +{ + jobPtr.reset(); + remainingPacks.removeOne(currentPack); +} + +void ListModel::logoLoaded(QString logo, bool stale) +{ + auto & logoObj = m_logoMap[logo]; + logoObj.downloadJob.reset(); + QString smallPath = logoObj.fullpath + ".small"; + + QFileInfo smallInfo(smallPath); + + if(stale || !smallInfo.exists()) { + QImage image(logoObj.fullpath); + if (image.isNull()) + { + logoObj.failed = true; + return; + } + QImage small; + if (image.width() > image.height()) { + small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); + } + else { + small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); + } + QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); + QImage square(QSize(256, 256), QImage::Format_ARGB32); + square.fill(Qt::transparent); + + QPainter painter(&square); + painter.drawImage(offset, small); + painter.end(); + + square.save(logoObj.fullpath + ".small", "PNG"); + } + + logoObj.result = QIcon(logoObj.fullpath + ".small"); + for(int i = 0; i < modpacks.size(); i++) { + if(modpacks[i].name == logo) { + emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); + } + } +} + +void ListModel::logoFailed(QString logo) +{ + m_logoMap[logo].failed = true; + m_logoMap[logo].downloadJob.reset(); +} + +void ListModel::requestLogo(QString logo, QString url) +{ + if(m_logoMap.contains(logo)) { + return; + } + + MetaEntryPtr entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); + + bool stale = entry->isStale(); + + NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo)); + job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); + + auto fullPath = entry->getFullPath(); + QObject::connect(job, &NetJob::finished, this, [this, logo, fullPath, stale] + { + logoLoaded(logo, stale); + }); + + QObject::connect(job, &NetJob::failed, this, [this, logo] + { + logoFailed(logo); + }); + + auto &newLogoEntry = m_logoMap[logo]; + newLogoEntry.downloadJob = job; + newLogoEntry.fullpath = fullPath; + job->start(); +} + +} diff --git a/application/pages/modplatform/ftb/FtbListModel.h b/application/pages/modplatform/ftb/FtbListModel.h new file mode 100644 index 00000000..9c057d73 --- /dev/null +++ b/application/pages/modplatform/ftb/FtbListModel.h @@ -0,0 +1,68 @@ +#pragma once + +#include + +#include "modplatform/modpacksch/FTBPackManifest.h" +#include "net/NetJob.h" +#include + +namespace Ftb { + +struct Logo { + QString fullpath; + NetJobPtr downloadJob; + QIcon result; + bool failed = false; +}; + +typedef QMap LogoMap; +typedef std::function LogoCallback; + +class ListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + ListModel(QObject *parent); + virtual ~ListModel(); + + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + + void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); + void searchWithTerm(const QString & term); + +private slots: + void performSearch(); + void searchRequestFinished(); + void searchRequestFailed(QString reason); + + void requestPack(); + void packRequestFinished(); + void packRequestFailed(QString reason); + + void logoFailed(QString logo); + void logoLoaded(QString logo, bool stale); + +private: + void requestLogo(QString file, QString url); + +private: + QList modpacks; + LogoMap m_logoMap; + + QString currentSearchTerm; + enum SearchState { + None, + CanPossiblyFetchMore, + ResetRequested, + Finished + } searchState = None; + NetJobPtr jobPtr; + int currentPack; + QList remainingPacks; + QByteArray response; +}; + +} diff --git a/application/pages/modplatform/ftb/FtbModel.cpp b/application/pages/modplatform/ftb/FtbModel.cpp deleted file mode 100644 index 972c5040..00000000 --- a/application/pages/modplatform/ftb/FtbModel.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "FtbModel.h" - -#include "BuildConfig.h" -#include "Env.h" -#include "MultiMC.h" -#include "Json.h" - -#include - -namespace Ftb { - -ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) -{ -} - -ListModel::~ListModel() -{ -} - -int ListModel::rowCount(const QModelIndex &parent) const -{ - return modpacks.size(); -} - -int ListModel::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -QVariant ListModel::data(const QModelIndex &index, int role) const -{ - int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { - return QString("INVALID INDEX %1").arg(pos); - } - - ModpacksCH::Modpack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { - return pack.name; - } - else if (role == Qt::ToolTipRole) - { - return pack.synopsis; - } - else if(role == Qt::DecorationRole) - { - QIcon placeholder = MMC->getThemedIcon("screenshot-placeholder"); - - auto iter = m_logoMap.find(pack.name); - if (iter != m_logoMap.end()) { - auto & logo = *iter; - if(!logo.result.isNull()) { - return logo.result; - } - return placeholder; - } - - for(auto art : pack.art) { - if(art.type == "square") { - ((ListModel *)this)->requestLogo(pack.name, art.url); - } - } - return placeholder; - } - else if(role == Qt::UserRole) - { - QVariant v; - v.setValue(pack); - return v; - } - - return QVariant(); -} - -void ListModel::performSearch() -{ - auto *netJob = new NetJob("Ftb::Search"); - QString searchUrl; - if(currentSearchTerm.isEmpty()) { - searchUrl = BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all"; - } - else { - searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/search/25?term=%1") - .arg(currentSearchTerm); - } - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); - jobPtr = netJob; - jobPtr->start(); - QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); -} - -void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) -{ - if(m_logoMap.contains(logo)) - { - callback(ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { - requestLogo(logo, logoUrl); - } -} - -void ListModel::searchWithTerm(const QString &term) -{ - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) { - return; - } - currentSearchTerm = term; - if(jobPtr) { - jobPtr->abort(); - searchState = ResetRequested; - return; - } - else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; - } - performSearch(); -} - -void ListModel::searchRequestFinished() -{ - jobPtr.reset(); - remainingPacks.clear(); - - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; - return; - } - - auto packs = doc.object().value("packs").toArray(); - for(auto pack : packs) { - auto packId = pack.toInt(); - remainingPacks.append(packId); - } - - if(!remainingPacks.isEmpty()) { - currentPack = remainingPacks.at(0); - requestPack(); - } -} - -void ListModel::searchRequestFailed(QString reason) -{ - jobPtr.reset(); - remainingPacks.clear(); - - if(searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); - - performSearch(); - } else { - searchState = Finished; - } -} - -void ListModel::requestPack() -{ - auto *netJob = new NetJob("Ftb::Search"); - auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1") - .arg(currentPack); - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); - jobPtr = netJob; - jobPtr->start(); - - QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed); -} - -void ListModel::packRequestFinished() -{ - jobPtr.reset(); - remainingPacks.removeOne(currentPack); - - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; - return; - } - - auto obj = doc.object(); - - ModpacksCH::Modpack pack; - try - { - ModpacksCH::loadModpack(pack, obj); - } - catch (const JSONValidationError &e) - { - qDebug() << QString::fromUtf8(response); - qWarning() << "Error while reading pack manifest from FTB: " << e.cause(); - return; - } - - // Since there is no guarantee that packs have a version, this will just - // ignore those "dud" packs. - if (pack.versions.empty()) - { - qWarning() << "FTB Pack " << pack.id << " ignored. reason: lacking any versions"; - return; - } - - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); - modpacks.append(pack); - endInsertRows(); - - if(!remainingPacks.isEmpty()) { - currentPack = remainingPacks.at(0); - requestPack(); - } -} - -void ListModel::packRequestFailed(QString reason) -{ - jobPtr.reset(); - remainingPacks.removeOne(currentPack); -} - -void ListModel::logoLoaded(QString logo, bool stale) -{ - auto & logoObj = m_logoMap[logo]; - logoObj.downloadJob.reset(); - QString smallPath = logoObj.fullpath + ".small"; - - QFileInfo smallInfo(smallPath); - - if(stale || !smallInfo.exists()) { - QImage image(logoObj.fullpath); - if (image.isNull()) - { - logoObj.failed = true; - return; - } - QImage small; - if (image.width() > image.height()) { - small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); - } - else { - small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); - } - QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); - QImage square(QSize(256, 256), QImage::Format_ARGB32); - square.fill(Qt::transparent); - - QPainter painter(&square); - painter.drawImage(offset, small); - painter.end(); - - square.save(logoObj.fullpath + ".small", "PNG"); - } - - logoObj.result = QIcon(logoObj.fullpath + ".small"); - for(int i = 0; i < modpacks.size(); i++) { - if(modpacks[i].name == logo) { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); - } - } -} - -void ListModel::logoFailed(QString logo) -{ - m_logoMap[logo].failed = true; - m_logoMap[logo].downloadJob.reset(); -} - -void ListModel::requestLogo(QString logo, QString url) -{ - if(m_logoMap.contains(logo)) { - return; - } - - MetaEntryPtr entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); - - bool stale = entry->isStale(); - - NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo)); - job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); - - auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::finished, this, [this, logo, fullPath, stale] - { - logoLoaded(logo, stale); - }); - - QObject::connect(job, &NetJob::failed, this, [this, logo] - { - logoFailed(logo); - }); - - auto &newLogoEntry = m_logoMap[logo]; - newLogoEntry.downloadJob = job; - newLogoEntry.fullpath = fullPath; - job->start(); -} - -} diff --git a/application/pages/modplatform/ftb/FtbModel.h b/application/pages/modplatform/ftb/FtbModel.h deleted file mode 100644 index 9c057d73..00000000 --- a/application/pages/modplatform/ftb/FtbModel.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include - -#include "modplatform/modpacksch/FTBPackManifest.h" -#include "net/NetJob.h" -#include - -namespace Ftb { - -struct Logo { - QString fullpath; - NetJobPtr downloadJob; - QIcon result; - bool failed = false; -}; - -typedef QMap LogoMap; -typedef std::function LogoCallback; - -class ListModel : public QAbstractListModel -{ - Q_OBJECT - -public: - ListModel(QObject *parent); - virtual ~ListModel(); - - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString & term); - -private slots: - void performSearch(); - void searchRequestFinished(); - void searchRequestFailed(QString reason); - - void requestPack(); - void packRequestFinished(); - void packRequestFailed(QString reason); - - void logoFailed(QString logo); - void logoLoaded(QString logo, bool stale); - -private: - void requestLogo(QString file, QString url); - -private: - QList modpacks; - LogoMap m_logoMap; - - QString currentSearchTerm; - enum SearchState { - None, - CanPossiblyFetchMore, - ResetRequested, - Finished - } searchState = None; - NetJobPtr jobPtr; - int currentPack; - QList remainingPacks; - QByteArray response; -}; - -} diff --git a/application/pages/modplatform/ftb/FtbPage.cpp b/application/pages/modplatform/ftb/FtbPage.cpp index c82508b3..60294de0 100644 --- a/application/pages/modplatform/ftb/FtbPage.cpp +++ b/application/pages/modplatform/ftb/FtbPage.cpp @@ -10,12 +10,26 @@ FtbPage::FtbPage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::FtbPage), dialog(dialog) { ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, &FtbPage::triggerSearch); + + filterModel = new Ftb::FilterModel(this); + listModel = new Ftb::ListModel(this); + filterModel->setSourceModel(listModel); + ui->packView->setModel(filterModel); + ui->packView->setSortingEnabled(true); + ui->packView->header()->hide(); + ui->packView->setIndentation(0); + ui->searchEdit->installEventFilter(this); - model = new Ftb::ListModel(this); - ui->packView->setModel(model); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FtbPage::onSelectionChanged); + for(int i = 0; i < filterModel->getAvailableSortings().size(); i++) + { + ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i)); + } + ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting()); + + connect(ui->searchButton, &QPushButton::clicked, this, &FtbPage::triggerSearch); + connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FtbPage::onSortingSelectionChanged); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FtbPage::onSelectionChanged); connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FtbPage::onVersionSelectionChanged); } @@ -59,7 +73,7 @@ void FtbPage::suggestCurrent() QString editedLogoName; editedLogoName = selected.name; - model->getLogo(selected.name, art.url, [this, editedLogoName](QString logo) + listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo) { dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName); }); @@ -70,7 +84,13 @@ void FtbPage::suggestCurrent() void FtbPage::triggerSearch() { - model->searchWithTerm(ui->searchEdit->text()); + listModel->searchWithTerm(ui->searchEdit->text()); +} + +void FtbPage::onSortingSelectionChanged(QString data) +{ + auto toSet = filterModel->getAvailableSortings().value(data); + filterModel->setSorting(toSet); } void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second) @@ -86,7 +106,7 @@ void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second) return; } - selected = model->data(first, Qt::UserRole).value(); + selected = filterModel->data(first, Qt::UserRole).value(); // reverse foreach, so that the newest versions are first for (auto i = selected.versions.size(); i--;) { diff --git a/application/pages/modplatform/ftb/FtbPage.h b/application/pages/modplatform/ftb/FtbPage.h index 80f152c6..b31e1c9e 100644 --- a/application/pages/modplatform/ftb/FtbPage.h +++ b/application/pages/modplatform/ftb/FtbPage.h @@ -15,7 +15,8 @@ #pragma once -#include "FtbModel.h" +#include "FtbFilterModel.h" +#include "FtbListModel.h" #include @@ -64,13 +65,15 @@ private: private slots: void triggerSearch(); + void onSortingSelectionChanged(QString data); void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); private: Ui::FtbPage *ui = nullptr; NewInstanceDialog* dialog = nullptr; - Ftb::ListModel* model = nullptr; + Ftb::ListModel* listModel = nullptr; + Ftb::FilterModel* filterModel = nullptr; ModpacksCH::Modpack selected; QString selectedVersion; diff --git a/application/pages/modplatform/ftb/FtbPage.ui b/application/pages/modplatform/ftb/FtbPage.ui index 772b0276..3a2203db 100644 --- a/application/pages/modplatform/ftb/FtbPage.ui +++ b/application/pages/modplatform/ftb/FtbPage.ui @@ -11,22 +11,6 @@ - - - - true - - - - 48 - 48 - - - - true - - - @@ -38,19 +22,38 @@ - - + + - + Version selected: + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + true + + + + 48 + 48 + + + + -- cgit From 5eace10d51d862efa944418c4473fb053b5b04b4 Mon Sep 17 00:00:00 2001 From: Jamie Mansfield Date: Sun, 29 Nov 2020 13:58:20 +0000 Subject: NOISSUE Continue requesting packs after ignoring one This was a mishap on my part, fortunately quickly exposed as the combination of GH-3463 and GH-3464 made no packs visible. --- application/pages/modplatform/ftb/FtbListModel.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'application/pages/modplatform/ftb') diff --git a/application/pages/modplatform/ftb/FtbListModel.cpp b/application/pages/modplatform/ftb/FtbListModel.cpp index e53f1134..63236827 100644 --- a/application/pages/modplatform/ftb/FtbListModel.cpp +++ b/application/pages/modplatform/ftb/FtbListModel.cpp @@ -211,12 +211,13 @@ void ListModel::packRequestFinished() if (pack.versions.empty()) { qWarning() << "FTB Pack " << pack.id << " ignored. reason: lacking any versions"; - return; } - - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); - modpacks.append(pack); - endInsertRows(); + else + { + beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size()); + modpacks.append(pack); + endInsertRows(); + } if(!remainingPacks.isEmpty()) { currentPack = remainingPacks.at(0); -- cgit