PrismLauncher/application/pages/modplatform/flame/FlamePage.cpp
phit f7c144c393 GH-3720 Fix UI inconsistencies with Modplatforms
Fixes GH-3118
Fixes GH-3720
Fixes GH-3731

Icons and Ok button state will now switch consistently when moving
between tabs. ATLaunchers packlist is now no longer redownloaded
each time you open its Tab. All lists are striped now. And all
search and filter fields now have a placeholder text.
2021-06-20 01:03:17 +02:00

187 lines
5.7 KiB
C++

#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->setMaxVisibleItems(10);
// fix height for themes that dont respect max visible like fusion
ui->versionSelectionBox->setStyleSheet("combobox-popup: 0;");
// 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();
}