aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui/pages
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui/pages')
-rw-r--r--launcher/ui/pages/instance/LegacyUpgradePage.cpp51
-rw-r--r--launcher/ui/pages/instance/LegacyUpgradePage.h64
-rw-r--r--launcher/ui/pages/instance/LegacyUpgradePage.ui54
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp3
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModPage.cpp344
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModPage.h3
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModPage.ui179
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp318
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.h3
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui179
10 files changed, 542 insertions, 656 deletions
diff --git a/launcher/ui/pages/instance/LegacyUpgradePage.cpp b/launcher/ui/pages/instance/LegacyUpgradePage.cpp
deleted file mode 100644
index cb78af02..00000000
--- a/launcher/ui/pages/instance/LegacyUpgradePage.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "LegacyUpgradePage.h"
-#include "ui_LegacyUpgradePage.h"
-
-#include "InstanceList.h"
-#include "minecraft/legacy/LegacyInstance.h"
-#include "minecraft/legacy/LegacyUpgradeTask.h"
-#include "Application.h"
-
-#include "ui/dialogs/CustomMessageBox.h"
-#include "ui/dialogs/ProgressDialog.h"
-
-LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
-{
- ui->setupUi(this);
-}
-
-LegacyUpgradePage::~LegacyUpgradePage()
-{
- delete ui;
-}
-
-void LegacyUpgradePage::runModalTask(Task *task)
-{
- connect(task, &Task::failed, [this](QString reason)
- {
- CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
- });
- ProgressDialog loadDialog(this);
- loadDialog.setSkipButton(true, tr("Abort"));
- if(loadDialog.execWithTask(task) == QDialog::Accepted)
- {
- m_container->requestClose();
- }
-}
-
-void LegacyUpgradePage::on_upgradeButton_clicked()
-{
- QString newName = tr("%1 (Migrated)").arg(m_inst->name());
- auto upgradeTask = new LegacyUpgradeTask(m_inst);
- upgradeTask->setName(newName);
- upgradeTask->setGroup(APPLICATION->instances()->getInstanceGroup(m_inst->id()));
- upgradeTask->setIcon(m_inst->iconKey());
- unique_qobject_ptr<Task> task(APPLICATION->instances()->wrapInstanceTask(upgradeTask));
- runModalTask(task.get());
-}
-
-bool LegacyUpgradePage::shouldDisplay() const
-{
- return !m_inst->isRunning();
-}
diff --git a/launcher/ui/pages/instance/LegacyUpgradePage.h b/launcher/ui/pages/instance/LegacyUpgradePage.h
deleted file mode 100644
index 7c51956b..00000000
--- a/launcher/ui/pages/instance/LegacyUpgradePage.h
+++ /dev/null
@@ -1,64 +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 "minecraft/legacy/LegacyInstance.h"
-#include "ui/pages/BasePage.h"
-#include <Application.h>
-#include "tasks/Task.h"
-
-namespace Ui
-{
-class LegacyUpgradePage;
-}
-
-class LegacyUpgradePage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
- virtual ~LegacyUpgradePage();
- virtual QString displayName() const override
- {
- return tr("Upgrade");
- }
- virtual QIcon icon() const override
- {
- return APPLICATION->getThemedIcon("checkupdate");
- }
- virtual QString id() const override
- {
- return "upgrade";
- }
- virtual QString helpPage() const override
- {
- return "Legacy-upgrade";
- }
- virtual bool shouldDisplay() const override;
-
-private slots:
- void on_upgradeButton_clicked();
-
-private:
- void runModalTask(Task *task);
-
-private:
- Ui::LegacyUpgradePage *ui;
- InstancePtr m_inst;
-};
diff --git a/launcher/ui/pages/instance/LegacyUpgradePage.ui b/launcher/ui/pages/instance/LegacyUpgradePage.ui
deleted file mode 100644
index b22c03e5..00000000
--- a/launcher/ui/pages/instance/LegacyUpgradePage.ui
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LegacyUpgradePage</class>
- <widget class="QWidget" name="LegacyUpgradePage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>546</width>
- <height>405</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTextBrowser" name="textBrowser">
- <property name="html">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;h1 style=&quot; margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:xx-large; font-weight:600;&quot;&gt;Upgrade is required&lt;/span&gt;&lt;/h1&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;PolyMC now supports old Minecraft versions and all the required features in the new (OneSix) instance format. As a consequence, the old (Legacy) format has been entirely disabled and old instances need to be upgraded.&lt;/p&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The upgrade will create a new instance with the same contents as the current one, in the new format. The original instance will remain untouched, in case anything goes wrong in the process.&lt;/p&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Please report any issues on our &lt;a href=&quot;https://github.com/PolyMC/PolyMC/issues&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#3584e4;&quot;&gt;github issues page&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCommandLinkButton" name="upgradeButton">
- <property name="text">
- <string>Upgrade the instance</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp
index 494d32f0..b342accf 100644
--- a/launcher/ui/pages/instance/ModFolderPage.cpp
+++ b/launcher/ui/pages/instance/ModFolderPage.cpp
@@ -365,8 +365,7 @@ void ModFolderPage::on_actionInstall_mods_triggered()
}
ModDownloadDialog mdownload(m_mods, this, m_inst);
if(mdownload.exec()) {
- ModDownloadTask *task = mdownload.getTask();
- if (task) {
+ for(auto task : mdownload.getTasks()){
connect(task, &Task::failed, [this, task](QString reason) {
task->deleteLater();
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp
index a816c681..6d33a6ac 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp
@@ -4,193 +4,211 @@
#include <QKeyEvent>
#include "Application.h"
-#include "Json.h"
-#include "ui/dialogs/ModDownloadDialog.h"
-#include "InstanceImportTask.h"
#include "FlameModModel.h"
+#include "InstanceImportTask.h"
+#include "Json.h"
#include "ModDownloadTask.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
+#include "ui/dialogs/ModDownloadDialog.h"
FlameModPage::FlameModPage(ModDownloadDialog *dialog, BaseInstance *instance)
- : QWidget(dialog), m_instance(instance), ui(new Ui::FlameModPage), dialog(dialog)
-{
- ui->setupUi(this);
- connect(ui->searchButton, &QPushButton::clicked, this, &FlameModPage::triggerSearch);
- ui->searchEdit->installEventFilter(this);
- listModel = new FlameMod::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 flame 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 Downloads"));
-
- connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameModPage::onSelectionChanged);
- connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlameModPage::onVersionSelectionChanged);
+ : QWidget(dialog), m_instance(instance), ui(new Ui::FlameModPage),
+ dialog(dialog) {
+ ui->setupUi(this);
+ connect(ui->searchButton, &QPushButton::clicked, this,
+ &FlameModPage::triggerSearch);
+ ui->searchEdit->installEventFilter(this);
+ listModel = new FlameMod::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 flame 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 Downloads"));
+
+ connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(triggerSearch()));
+ connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &FlameModPage::onSelectionChanged);
+ connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this,
+ &FlameModPage::onVersionSelectionChanged);
+ connect(ui->modSelectionButton, &QPushButton::clicked, this,
+ &FlameModPage::onModSelected);
}
-FlameModPage::~FlameModPage()
-{
- delete ui;
-}
+FlameModPage::~FlameModPage() { delete ui; }
-bool FlameModPage::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 FlameModPage::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 FlameModPage::shouldDisplay() const
-{
- return true;
-}
+bool FlameModPage::shouldDisplay() const { return true; }
-void FlameModPage::openedImpl()
-{
- suggestCurrent();
- triggerSearch();
+void FlameModPage::openedImpl() {
+ updateSelectionButton();
+ triggerSearch();
}
-void FlameModPage::triggerSearch()
-{
- listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex());
+void FlameModPage::triggerSearch() {
+ listModel->searchWithTerm(ui->searchEdit->text(),
+ ui->sortByBox->currentIndex());
}
-void FlameModPage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- ui->versionSelectionBox->clear();
-
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedMod();
- }
- return;
+void FlameModPage::onSelectionChanged(QModelIndex first, QModelIndex second) {
+ ui->versionSelectionBox->clear();
+
+ if (!first.isValid()) {
+ return;
+ }
+
+ current = listModel->data(first, Qt::UserRole).value<FlameMod::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 = [](FlameMod::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));
}
-
- current = listModel->data(first, Qt::UserRole).value<FlameMod::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 = [](FlameMod::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) {
+ qDebug() << "Loading flame mod versions";
+
+ ui->modSelectionButton->setText(tr("Loading versions..."));
+ ui->modSelectionButton->setEnabled(false);
+
+ auto netJob =
+ new NetJob(QString("Flame::ModVersions(%1)").arg(current.name),
+ APPLICATION->network());
+ auto response = new QByteArray();
+ int addonId = current.addonId;
+ netJob->addNetAction(Net::Download::makeByteArray(
+ QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files")
+ .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 Flame at "
+ << parse_error.offset
+ << " reason: " << parse_error.errorString();
+ qWarning() << *response;
+ return;
+ }
+ QJsonArray arr = doc.array();
+ try {
+ FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(),
+ m_instance);
+ } catch (const JSONValidationError &e) {
+ qDebug() << *response;
+ qWarning() << "Error while reading Flame 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)) {
+ continue;
}
- text += "<br>" + tr(" by ") + authorStrs.join(", ");
- }
- text += "<br><br>";
-
- ui->packDescription->setHtml(text + current.description);
-
- if (!current.versionsLoaded)
- {
- qDebug() << "Loading flame mod versions";
- auto netJob = new NetJob(QString("Flame::ModVersions(%1)").arg(current.name), APPLICATION->network());
- 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, netJob]
- {
- netJob->deleteLater();
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from Flame at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << *response;
- return;
- }
- QJsonArray arr = doc.array();
- try
- {
- FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance);
- }
- catch(const JSONValidationError &e)
- {
- qDebug() << *response;
- qWarning() << "Error while reading Flame 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)){
- continue;
- }
- ui->versionSelectionBox->addItem(version.version, QVariant(i));
- }
- if(ui->versionSelectionBox->count() == 0){
- ui->versionSelectionBox->addItem(tr("No Valid Version found!"), QVariant(-1));
- }
-
- suggestCurrent();
- });
- netJob->start();
+ 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));
}
- 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));
- }
- suggestCurrent();
+ if (ui->versionSelectionBox->count() == 0) {
+ ui->versionSelectionBox->addItem(tr("No Valid Version found!"),
+ QVariant(-1));
}
-}
-void FlameModPage::suggestCurrent()
-{
- if(!isOpened)
- {
- return;
- }
+ updateSelectionButton();
+ }
+}
- if (selectedVersion == -1)
- {
- dialog->setSuggestedMod();
- return;
- }
+void FlameModPage::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"));
+ }
+}
- auto version = current.versions[selectedVersion];
- dialog->setSuggestedMod(current.name, new ModDownloadTask(version.downloadUrl, version.fileName , dialog->mods));
+void FlameModPage::onVersionSelectionChanged(QString data) {
+ if (data.isNull() || data.isEmpty()) {
+ selectedVersion = -1;
+ return;
+ }
+ selectedVersion = ui->versionSelectionBox->currentData().toInt();
+ updateSelectionButton();
}
-void FlameModPage::onVersionSelectionChanged(QString data)
-{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = -1;
- return;
- }
- selectedVersion = ui->versionSelectionBox->currentData().toInt();
- suggestCurrent();
+void FlameModPage::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/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h
index 8fa3248a..b5b19a4f 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModPage.h
+++ b/launcher/ui/pages/modplatform/flame/FlameModPage.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::FlameModPage *ui = nullptr;
diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.ui b/launcher/ui/pages/modplatform/flame/FlameModPage.ui
index 7da0bb4a..36df7e8a 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModPage.ui
+++ b/launcher/ui/pages/modplatform/flame/FlameModPage.ui
@@ -1,90 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>FlameModPage</class>
- <widget class="QWidget" name="FlameModPage">
- <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>FlameModPage</class>
+ <widget class="QWidget" name="FlameModPage">
+ <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="2" column="0" colspan="2">
+ <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0,0,0" columnminimumwidth="0,0,0">
+ <item row="1" column="2">
+ <widget class="QComboBox" name="versionSelectionBox"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QComboBox" name="sortByBox"/>
+ </item>
+ <item row="1" 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="2" column="2">
+ <widget class="QPushButton" name="modSelectionButton">
+ <property name="text">
+ <string>Select mod for download</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/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLineEdit" name="searchEdit">
+ <property name="placeholderText">
+ <string>Search and filter ...</string>
+ </property>
+ </widget>
+ </item>
+ <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="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>
+ <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="0" column="1">
+ <widget class="QPushButton" name="searchButton">
+ <property name="text">
+ <string>Search</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>
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
index c5a54c29..fc6aff96 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
@@ -4,177 +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());
- std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
- QString addonId = current.addonId;
- netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), response.get()));
-
- QObject::connect(netJob, &NetJob::succeeded, this, [this, response, netJob]
- {
- netJob->deleteLater();
- 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();
- });
- 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>