diff options
Diffstat (limited to 'launcher/ui/pages/modplatform/modrinth')
3 files changed, 265 insertions, 238 deletions
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 577a7bcb..fc6aff96 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -4,180 +4,199 @@ #include <QKeyEvent> #include "Application.h" -#include "Json.h" -#include "ui/dialogs/ModDownloadDialog.h" #include "InstanceImportTask.h" -#include "ModrinthModel.h" +#include "Json.h" #include "ModDownloadTask.h" +#include "ModrinthModel.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" +#include "ui/dialogs/ModDownloadDialog.h" ModrinthPage::ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance) - : QWidget(dialog), m_instance(instance), ui(new Ui::ModrinthPage), dialog(dialog) -{ - ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, &ModrinthPage::triggerSearch); - ui->searchEdit->installEventFilter(this); - listModel = new Modrinth::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 modrinth api - ui->sortByBox->addItem(tr("Sort by Relevence")); - ui->sortByBox->addItem(tr("Sort by Downloads")); - ui->sortByBox->addItem(tr("Sort by Follows")); - ui->sortByBox->addItem(tr("Sort by last updated")); - ui->sortByBox->addItem(tr("Sort by newest")); - - connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthPage::onSelectionChanged); - connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthPage::onVersionSelectionChanged); + : QWidget(dialog), m_instance(instance), ui(new Ui::ModrinthPage), + dialog(dialog) { + ui->setupUi(this); + connect(ui->searchButton, &QPushButton::clicked, this, + &ModrinthPage::triggerSearch); + ui->searchEdit->installEventFilter(this); + listModel = new Modrinth::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 modrinth api + ui->sortByBox->addItem(tr("Sort by Relevence")); + ui->sortByBox->addItem(tr("Sort by Downloads")); + ui->sortByBox->addItem(tr("Sort by Follows")); + ui->sortByBox->addItem(tr("Sort by last updated")); + ui->sortByBox->addItem(tr("Sort by newest")); + + connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(triggerSearch())); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, + this, &ModrinthPage::onSelectionChanged); + connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, + &ModrinthPage::onVersionSelectionChanged); + connect(ui->modSelectionButton, &QPushButton::clicked, this, + &ModrinthPage::onModSelected); } -ModrinthPage::~ModrinthPage() -{ - delete ui; -} +ModrinthPage::~ModrinthPage() { delete ui; } -bool ModrinthPage::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; - } +bool ModrinthPage::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); + } + return QWidget::eventFilter(watched, event); } -bool ModrinthPage::shouldDisplay() const -{ - return true; -} +bool ModrinthPage::shouldDisplay() const { return true; } -void ModrinthPage::openedImpl() -{ - suggestCurrent(); - triggerSearch(); +void ModrinthPage::openedImpl() { + updateSelectionButton(); + triggerSearch(); } -void ModrinthPage::triggerSearch() -{ - listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex()); +void ModrinthPage::triggerSearch() { + listModel->searchWithTerm(ui->searchEdit->text(), + ui->sortByBox->currentIndex()); } -void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) -{ - ui->versionSelectionBox->clear(); - - if(!first.isValid()) - { - if(isOpened) - { - dialog->setSuggestedMod(); - } +void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) { + ui->versionSelectionBox->clear(); + + if (!first.isValid()) { + return; + } + + current = listModel->data(first, Qt::UserRole).value<Modrinth::IndexedPack>(); + QString text = ""; + QString name = current.name; + + if (current.websiteUrl.isEmpty()) + text = name; + else + text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>"; + text += "<br>" + tr(" by ") + "<a href=\"" + current.author.url + "\">" + + current.author.name + "</a><br><br>"; + ui->packDescription->setHtml(text + current.description); + + if (!current.versionsLoaded) { + qDebug() << "Loading Modrinth mod versions"; + + ui->modSelectionButton->setText(tr("Loading versions...")); + ui->modSelectionButton->setEnabled(false); + + auto netJob = + new NetJob(QString("Modrinth::ModVersions(%1)").arg(current.name), + APPLICATION->network()); + auto response = new QByteArray(); + QString addonId = current.addonId; + netJob->addNetAction(Net::Download::makeByteArray( + QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), + response)); + + 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 Modrinth at " + << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; return; - } - - current = listModel->data(first, Qt::UserRole).value<Modrinth::IndexedPack>(); - QString text = ""; - QString name = current.name; - - if (current.websiteUrl.isEmpty()) - text = name; - else - text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>"; - text += "<br>"+ tr(" by ") + "<a href=\""+current.author.url+"\">"+current.author.name+"</a><br><br>"; - ui->packDescription->setHtml(text + current.description); - - if (!current.versionsLoaded) - { - qDebug() << "Loading Modrinth mod versions"; - auto netJob = new NetJob(QString("Modrinth::ModVersions(%1)").arg(current.name), APPLICATION->network()); - auto response = new QByteArray(); - QString addonId = current.addonId; - netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), response)); - - 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 Modrinth at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *response; - return; - } - QJsonArray arr = doc.array(); - try - { - Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); - } - catch(const JSONValidationError &e) - { - qDebug() << *response; - qWarning() << "Error while reading Modrinth mod version: " << e.cause(); - } - auto packProfile = ((MinecraftInstance *)m_instance)->getPackProfile(); - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; - for(int i = 0; i < current.versions.size(); i++) { - auto version = current.versions[i]; - if(!version.mcVersion.contains(mcVersion) || !version.loaders.contains(loaderString)){ - continue; - } - ui->versionSelectionBox->addItem(version.version, QVariant(i)); - } - if(ui->versionSelectionBox->count() == 0){ - ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant(-1)); - } - - suggestCurrent(); - }); - QObject::connect(netJob, &NetJob::finished, this, [response, netJob]{ - netJob->deleteLater(); - delete response; - }); - netJob->start(); - } - else - { - for(int i = 0; i < current.versions.size(); i++) { - ui->versionSelectionBox->addItem(current.versions[i].version, QVariant(i)); - } - if(ui->versionSelectionBox->count() == 0){ - ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant(-1)); + } + QJsonArray arr = doc.array(); + try { + Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), + m_instance); + } catch (const JSONValidationError &e) { + qDebug() << *response; + qWarning() << "Error while reading Modrinth mod version: " << e.cause(); + } + auto packProfile = ((MinecraftInstance *)m_instance)->getPackProfile(); + QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + QString loaderString = + (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) + ? "fabric" + : "forge"; + for (int i = 0; i < current.versions.size(); i++) { + auto version = current.versions[i]; + if (!version.mcVersion.contains(mcVersion) || + !version.loaders.contains(loaderString)) { + continue; } - suggestCurrent(); + ui->versionSelectionBox->addItem(version.version, QVariant(i)); + } + if (ui->versionSelectionBox->count() == 0) { + ui->versionSelectionBox->addItem(tr("No Valid Version found !"), + QVariant(-1)); + } + + ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); + updateSelectionButton(); + }); + + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { + netJob->deleteLater(); + delete response; + }); + + netJob->start(); + } else { + for (int i = 0; i < current.versions.size(); i++) { + ui->versionSelectionBox->addItem(current.versions[i].version, + QVariant(i)); } + if (ui->versionSelectionBox->count() == 0) { + ui->versionSelectionBox->addItem(tr("No Valid Version found !"), + QVariant(-1)); + } + + updateSelectionButton(); + } } -void ModrinthPage::suggestCurrent() -{ - if(!isOpened) - { - return; - } +void ModrinthPage::updateSelectionButton() { + if (!isOpened || selectedVersion < 0) { + ui->modSelectionButton->setEnabled(false); + return; + } + + ui->modSelectionButton->setEnabled(true); + auto &version = current.versions[selectedVersion]; + if (!dialog->isModSelected(current.name, version.fileName)) { + ui->modSelectionButton->setText(tr("Select mod for download")); + } else { + ui->modSelectionButton->setText(tr("Deselect mod for download")); + } +} - if (selectedVersion == -1) - { - dialog->setSuggestedMod(); - return; - } - auto version = current.versions[selectedVersion]; - dialog->setSuggestedMod(current.name, new ModDownloadTask(version.downloadUrl, version.fileName , dialog->mods)); +void ModrinthPage::onVersionSelectionChanged(QString data) { + if (data.isNull() || data.isEmpty()) { + selectedVersion = -1; + return; + } + selectedVersion = ui->versionSelectionBox->currentData().toInt(); + updateSelectionButton(); } -void ModrinthPage::onVersionSelectionChanged(QString data) -{ - if(data.isNull() || data.isEmpty()) - { - selectedVersion = -1; - return; - } - selectedVersion = ui->versionSelectionBox->currentData().toInt(); - suggestCurrent(); +void ModrinthPage::onModSelected() { + auto &version = current.versions[selectedVersion]; + if (dialog->isModSelected(current.name, version.fileName)) { + dialog->removeSelectedMod(current.name); + } else { + dialog->addSelectedMod(current.name, + new ModDownloadTask(version.downloadUrl, + version.fileName, dialog->mods)); + } + + updateSelectionButton(); } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 3c517069..52b538e3 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -50,12 +50,13 @@ public: BaseInstance *m_instance; private: - void suggestCurrent(); + void updateSelectionButton(); private slots: void triggerSearch(); void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); + void onModSelected(); private: Ui::ModrinthPage *ui = nullptr; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui index 6d183de5..d0a8b8f7 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui @@ -1,90 +1,97 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> - <class>ModrinthPage</class> - <widget class="QWidget" name="ModrinthPage"> - <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> + <class>ModrinthPage</class> + <widget class="QWidget" name="ModrinthPage"> + <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="2"> + <widget class="QTextBrowser" name="packDescription"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + <property name="openLinks"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QListView" name="packView"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAlwaysOff</enum> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="iconSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </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/> + </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> + <item row="2" column="0" colspan="2"> + <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,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> + <item row="1" column="2"> + <widget class="QPushButton" name="modSelectionButton"> + <property name="text"> + <string>Select mod for download</string> + </property> + </widget> + </item> + </layout> + </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> |