diff options
Diffstat (limited to 'application/pages/modplatform/flame')
-rw-r--r-- | application/pages/modplatform/flame/FlameModel.cpp | 259 | ||||
-rw-r--r-- | application/pages/modplatform/flame/FlameModel.h | 76 | ||||
-rw-r--r-- | application/pages/modplatform/flame/FlamePage.cpp | 185 | ||||
-rw-r--r-- | application/pages/modplatform/flame/FlamePage.h | 80 | ||||
-rw-r--r-- | application/pages/modplatform/flame/FlamePage.ui | 90 |
5 files changed, 0 insertions, 690 deletions
diff --git a/application/pages/modplatform/flame/FlameModel.cpp b/application/pages/modplatform/flame/FlameModel.cpp deleted file mode 100644 index 228a88c5..00000000 --- a/application/pages/modplatform/flame/FlameModel.cpp +++ /dev/null @@ -1,259 +0,0 @@ -#include "FlameModel.h" -#include "MultiMC.h" -#include <Json.h> - -#include <MMCStrings.h> -#include <Version.h> - -#include <QtMath> -#include <QLabel> - -#include <RWStorage.h> -#include <Env.h> - -namespace Flame { - -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); - } - - IndexedPack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { - return pack.name; - } - else if (role == Qt::ToolTipRole) - { - if(pack.description.length() > 100) - { - //some magic to prevent to long tooltips and replace html linebreaks - QString edit = pack.description.left(97); - edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("..."); - return edit; - - } - return pack.description; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.logoName)) - { - return (m_logoMap.value(pack.logoName)); - } - QIcon icon = MMC->getThemedIcon("screenshot-placeholder"); - ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); - return icon; - } - else if(role == Qt::UserRole) - { - QVariant v; - v.setValue(pack); - return v; - } - - return QVariant(); -} - -void ListModel::logoLoaded(QString logo, QIcon out) -{ - m_loadingLogos.removeAll(logo); - m_logoMap.insert(logo, out); - for(int i = 0; i < modpacks.size(); i++) { - if(modpacks[i].logoName == logo) { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); - } - } -} - -void ListModel::logoFailed(QString logo) -{ - m_failedLogos.append(logo); - m_loadingLogos.removeAll(logo); -} - -void ListModel::requestLogo(QString logo, QString url) -{ - if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) - { - return; - } - - MetaEntryPtr entry = ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0))); - NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo)); - job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); - - auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath] - { - emit logoLoaded(logo, QIcon(fullPath)); - if(waitingCallbacks.contains(logo)) - { - waitingCallbacks.value(logo)(fullPath); - } - }); - - QObject::connect(job, &NetJob::failed, this, [this, logo] - { - emit logoFailed(logo); - }); - - job->start(); - - m_loadingLogos.append(logo); -} - -void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) -{ - if(m_logoMap.contains(logo)) - { - callback(ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { - requestLogo(logo, logoUrl); - } -} - -Qt::ItemFlags ListModel::flags(const QModelIndex &index) const -{ - return QAbstractListModel::flags(index); -} - -bool ListModel::canFetchMore(const QModelIndex& parent) const -{ - return searchState == CanPossiblyFetchMore; -} - -void ListModel::fetchMore(const QModelIndex& parent) -{ - if (parent.isValid()) - return; - if(nextSearchOffset == 0) { - qWarning() << "fetchMore with 0 offset is wrong..."; - return; - } - performPaginatedSearch(); -} - -void ListModel::performPaginatedSearch() -{ - NetJob *netJob = new NetJob("Flame::Search"); - auto searchUrl = QString( - "https://addons-ecs.forgesvc.net/api/v2/addon/search?" - "categoryId=0&" - "gameId=432&" - "index=%1&" - "pageSize=25&" - "searchFilter=%2&" - "sectionId=4471&" - "sort=%3" - ).arg(nextSearchOffset).arg(currentSearchTerm).arg(currentSort); - 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::searchWithTerm(const QString& term, int sort) -{ - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { - return; - } - currentSearchTerm = term; - currentSort = sort; - if(jobPtr) { - jobPtr->abort(); - searchState = ResetRequested; - return; - } - else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; - } - nextSearchOffset = 0; - performPaginatedSearch(); -} - -void Flame::ListModel::searchRequestFinished() -{ - jobPtr.reset(); - - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; - return; - } - - QList<Flame::IndexedPack> newList; - auto packs = doc.array(); - for(auto packRaw : packs) { - auto packObj = packRaw.toObject(); - - Flame::IndexedPack pack; - try - { - Flame::loadIndexedPack(pack, packObj); - newList.append(pack); - } - catch(const JSONValidationError &e) - { - qWarning() << "Error while loading pack from CurseForge: " << e.cause(); - continue; - } - } - if(packs.size() < 25) { - searchState = Finished; - } else { - nextSearchOffset += 25; - searchState = CanPossiblyFetchMore; - } - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1); - modpacks.append(newList); - endInsertRows(); -} - -void Flame::ListModel::searchRequestFailed(QString reason) -{ - jobPtr.reset(); - - if(searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); - - nextSearchOffset = 0; - performPaginatedSearch(); - } else { - searchState = Finished; - } -} - -} - diff --git a/application/pages/modplatform/flame/FlameModel.h b/application/pages/modplatform/flame/FlameModel.h deleted file mode 100644 index 24383db0..00000000 --- a/application/pages/modplatform/flame/FlameModel.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include <RWStorage.h> - -#include <QAbstractListModel> -#include <QSortFilterProxyModel> -#include <QThreadPool> -#include <QIcon> -#include <QStyledItemDelegate> -#include <QList> -#include <QString> -#include <QStringList> -#include <QMetaType> - -#include <functional> -#include <net/NetJob.h> - -#include <modplatform/flame/FlamePackIndex.h> - -namespace Flame { - - -typedef QMap<QString, QIcon> LogoMap; -typedef std::function<void(QString)> 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; - Qt::ItemFlags flags(const QModelIndex &index) const override; - bool canFetchMore(const QModelIndex & parent) const override; - void fetchMore(const QModelIndex & parent) override; - - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString & term, const int sort); - -private slots: - void performPaginatedSearch(); - - void logoFailed(QString logo); - void logoLoaded(QString logo, QIcon out); - - void searchRequestFinished(); - void searchRequestFailed(QString reason); - -private: - void requestLogo(QString file, QString url); - -private: - QList<IndexedPack> modpacks; - QStringList m_failedLogos; - QStringList m_loadingLogos; - LogoMap m_logoMap; - QMap<QString, LogoCallback> waitingCallbacks; - - QString currentSearchTerm; - int currentSort = 0; - int nextSearchOffset = 0; - enum SearchState { - None, - CanPossiblyFetchMore, - ResetRequested, - Finished - } searchState = None; - NetJobPtr jobPtr; - QByteArray response; -}; - -} diff --git a/application/pages/modplatform/flame/FlamePage.cpp b/application/pages/modplatform/flame/FlamePage.cpp deleted file mode 100644 index ade58431..00000000 --- a/application/pages/modplatform/flame/FlamePage.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "FlamePage.h" -#include "ui_FlamePage.h" - -#include "MultiMC.h" -#include <Json.h> -#include "dialogs/NewInstanceDialog.h" -#include <InstanceImportTask.h> -#include "FlameModel.h" -#include <QKeyEvent> - -FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget *parent) - : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog) -{ - ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, &FlamePage::triggerSearch); - ui->searchEdit->installEventFilter(this); - listModel = new Flame::ListModel(this); - ui->packView->setModel(listModel); - - ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); - - // index is used to set the sorting with the curseforge api - ui->sortByBox->addItem(tr("Sort by featured")); - ui->sortByBox->addItem(tr("Sort by popularity")); - ui->sortByBox->addItem(tr("Sort by last updated")); - ui->sortByBox->addItem(tr("Sort by name")); - ui->sortByBox->addItem(tr("Sort by author")); - ui->sortByBox->addItem(tr("Sort by total downloads")); - - connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged); - connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlamePage::onVersionSelectionChanged); -} - -FlamePage::~FlamePage() -{ - delete ui; -} - -bool FlamePage::eventFilter(QObject* watched, QEvent* event) -{ - if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { - QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); - if (keyEvent->key() == Qt::Key_Return) { - triggerSearch(); - keyEvent->accept(); - return true; - } - } - return QWidget::eventFilter(watched, event); -} - -bool FlamePage::shouldDisplay() const -{ - return true; -} - -void FlamePage::openedImpl() -{ - suggestCurrent(); - triggerSearch(); -} - -void FlamePage::triggerSearch() -{ - listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex()); -} - -void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second) -{ - ui->versionSelectionBox->clear(); - - if(!first.isValid()) - { - if(isOpened) - { - dialog->setSuggestedPack(); - } - return; - } - - current = listModel->data(first, Qt::UserRole).value<Flame::IndexedPack>(); - QString text = ""; - QString name = current.name; - - if (current.websiteUrl.isEmpty()) - text = name; - else - text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>"; - if (!current.authors.empty()) { - auto authorToStr = [](Flame::ModpackAuthor & author) { - if(author.url.isEmpty()) { - return author.name; - } - return QString("<a href=\"%1\">%2</a>").arg(author.url, author.name); - }; - QStringList authorStrs; - for(auto & author: current.authors) { - authorStrs.push_back(authorToStr(author)); - } - text += "<br>" + tr(" by ") + authorStrs.join(", "); - } - text += "<br><br>"; - - ui->packDescription->setHtml(text + current.description); - - if (current.versionsLoaded == false) - { - qDebug() << "Loading flame modpack versions"; - NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name)); - std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>(); - int addonId = current.addonId; - netJob->addNetAction(Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response.get())); - - QObject::connect(netJob, &NetJob::succeeded, this, [this, response] - { - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *response; - return; - } - QJsonArray arr = doc.array(); - try - { - Flame::loadIndexedPackVersions(current, arr); - } - catch(const JSONValidationError &e) - { - qDebug() << *response; - qWarning() << "Error while reading flame modpack version: " << e.cause(); - } - - for(auto version : current.versions) { - ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl)); - } - - suggestCurrent(); - }); - netJob->start(); - } - else - { - for(auto version : current.versions) { - ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl)); - } - - suggestCurrent(); - } -} - -void FlamePage::suggestCurrent() -{ - if(!isOpened) - { - return; - } - - if (selectedVersion.isEmpty()) - { - dialog->setSuggestedPack(); - return; - } - - dialog->setSuggestedPack(current.name, new InstanceImportTask(selectedVersion)); - QString editedLogoName; - editedLogoName = "curseforge_" + current.logoName.section(".", 0, 0); - listModel->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo) - { - dialog->setSuggestedIconFromFile(logo, editedLogoName); - }); -} - -void FlamePage::onVersionSelectionChanged(QString data) -{ - if(data.isNull() || data.isEmpty()) - { - selectedVersion = ""; - return; - } - selectedVersion = ui->versionSelectionBox->currentData().toString(); - suggestCurrent(); -} diff --git a/application/pages/modplatform/flame/FlamePage.h b/application/pages/modplatform/flame/FlamePage.h deleted file mode 100644 index 467bb44b..00000000 --- a/application/pages/modplatform/flame/FlamePage.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2013-2021 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <QWidget> - -#include "pages/BasePage.h" -#include <MultiMC.h> -#include "tasks/Task.h" -#include <modplatform/flame/FlamePackIndex.h> - -namespace Ui -{ -class FlamePage; -} - -class NewInstanceDialog; - -namespace Flame { - class ListModel; -} - -class FlamePage : public QWidget, public BasePage -{ - Q_OBJECT - -public: - explicit FlamePage(NewInstanceDialog* dialog, QWidget *parent = 0); - virtual ~FlamePage(); - virtual QString displayName() const override - { - return tr("CurseForge"); - } - virtual QIcon icon() const override - { - return MMC->getThemedIcon("flame"); - } - virtual QString id() const override - { - return "flame"; - } - virtual QString helpPage() const override - { - return "Flame-platform"; - } - virtual bool shouldDisplay() const override; - - void openedImpl() override; - - bool eventFilter(QObject * watched, QEvent * event) override; - -private: - void suggestCurrent(); - -private slots: - void triggerSearch(); - void onSelectionChanged(QModelIndex first, QModelIndex second); - void onVersionSelectionChanged(QString data); - -private: - Ui::FlamePage *ui = nullptr; - NewInstanceDialog* dialog = nullptr; - Flame::ListModel* listModel = nullptr; - Flame::IndexedPack current; - - QString selectedVersion; -}; diff --git a/application/pages/modplatform/flame/FlamePage.ui b/application/pages/modplatform/flame/FlamePage.ui deleted file mode 100644 index 9723815a..00000000 --- a/application/pages/modplatform/flame/FlamePage.ui +++ /dev/null @@ -1,90 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>FlamePage</class> - <widget class="QWidget" name="FlamePage"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>837</width> - <height>685</height> - </rect> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0" colspan="2"> - <layout class="QGridLayout" name="gridLayout_3"> - <item row="1" column="0"> - <widget class="QListView" name="packView"> - <property name="iconSize"> - <size> - <width>48</width> - <height>48</height> - </size> - </property> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAlwaysOff</enum> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QTextBrowser" name="packDescription"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - <property name="openLinks"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item row="2" column="0" colspan="2"> - <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0"> - <item row="0" column="2"> - <widget class="QComboBox" name="versionSelectionBox"/> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Version selected:</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QComboBox" name="sortByBox"/> - </item> - </layout> - </item> - <item row="0" column="1"> - <widget class="QPushButton" name="searchButton"> - <property name="text"> - <string>Search</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLineEdit" name="searchEdit"> - <property name="placeholderText"> - <string>Search and filter ...</string> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>searchEdit</tabstop> - <tabstop>searchButton</tabstop> - <tabstop>packView</tabstop> - <tabstop>packDescription</tabstop> - <tabstop>sortByBox</tabstop> - <tabstop>versionSelectionBox</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> |