diff options
Diffstat (limited to 'launcher')
36 files changed, 2127 insertions, 20 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp index b605e54b..7050e5dc 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -717,6 +717,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // pastebin URL m_settings->registerSetting("PastebinURL", "https://0x0.st"); + m_settings->registerSetting("CloseAfterLaunch", false); + // Init page provider { m_globalSettingsProvider = std::make_shared<GenericPageProvider>(tr("Settings")); diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index ed9d8e65..54b6132e 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -37,6 +37,10 @@ set(CORE_SOURCES InstanceImportTask.h InstanceImportTask.cpp + # Mod downloading task + ModDownloadTask.h + ModDownloadTask.cpp + # Use tracking separate from memory management Usable.h @@ -501,12 +505,19 @@ set(FLAME_SOURCES # Flame modplatform/flame/FlamePackIndex.cpp modplatform/flame/FlamePackIndex.h + modplatform/flame/FlameModIndex.cpp + modplatform/flame/FlameModIndex.h modplatform/flame/PackManifest.h modplatform/flame/PackManifest.cpp modplatform/flame/FileResolvingTask.h modplatform/flame/FileResolvingTask.cpp ) +set(MODRINTH_SOURCES + modplatform/modrinth/ModrinthPackIndex.cpp + modplatform/modrinth/ModrinthPackIndex.h +) + set(MODPACKSCH_SOURCES modplatform/modpacksch/FTBPackInstallTask.h modplatform/modpacksch/FTBPackInstallTask.cpp @@ -561,6 +572,7 @@ set(LOGIC_SOURCES ${ICONS_SOURCES} ${FTB_SOURCES} ${FLAME_SOURCES} + ${MODRINTH_SOURCES} ${MODPACKSCH_SOURCES} ${TECHNIC_SOURCES} ${ATLAUNCHER_SOURCES} @@ -734,6 +746,10 @@ SET(LAUNCHER_SOURCES ui/pages/modplatform/flame/FlameModel.h ui/pages/modplatform/flame/FlamePage.cpp ui/pages/modplatform/flame/FlamePage.h + ui/pages/modplatform/flame/FlameModModel.cpp + ui/pages/modplatform/flame/FlameModModel.h + ui/pages/modplatform/flame/FlameModPage.cpp + ui/pages/modplatform/flame/FlameModPage.h ui/pages/modplatform/technic/TechnicModel.cpp ui/pages/modplatform/technic/TechnicModel.h @@ -743,6 +759,11 @@ SET(LAUNCHER_SOURCES ui/pages/modplatform/ImportPage.cpp ui/pages/modplatform/ImportPage.h + ui/pages/modplatform/modrinth/ModrinthModel.cpp + ui/pages/modplatform/modrinth/ModrinthModel.h + ui/pages/modplatform/modrinth/ModrinthPage.cpp + ui/pages/modplatform/modrinth/ModrinthPage.h + # GUI - dialogs ui/dialogs/AboutDialog.cpp ui/dialogs/AboutDialog.h @@ -782,6 +803,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/VersionSelectDialog.h ui/dialogs/SkinUploadDialog.cpp ui/dialogs/SkinUploadDialog.h + ui/dialogs/ModDownloadDialog.cpp + ui/dialogs/ModDownloadDialog.h # GUI - widgets @@ -858,10 +881,12 @@ qt5_wrap_ui(LAUNCHER_UI ui/pages/modplatform/atlauncher/AtlPage.ui ui/pages/modplatform/VanillaPage.ui ui/pages/modplatform/flame/FlamePage.ui + ui/pages/modplatform/flame/FlameModPage.ui ui/pages/modplatform/legacy_ftb/Page.ui ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/ftb/FtbPage.ui ui/pages/modplatform/technic/TechnicPage.ui + ui/pages/modplatform/modrinth/ModrinthPage.ui ui/widgets/InstanceCardWidget.ui ui/widgets/CustomCommands.ui ui/widgets/MCModInfoFrame.ui diff --git a/launcher/ModDownloadTask.cpp b/launcher/ModDownloadTask.cpp new file mode 100644 index 00000000..08a02d29 --- /dev/null +++ b/launcher/ModDownloadTask.cpp @@ -0,0 +1,39 @@ +#include "ModDownloadTask.h" +#include "Application.h" + +ModDownloadTask::ModDownloadTask(const QUrl sourceUrl,const QString filename, const std::shared_ptr<ModFolderModel> mods) +: m_sourceUrl(sourceUrl), mods(mods), filename(filename) { +} + +void ModDownloadTask::executeTask() { + setStatus(tr("Downloading mod:\n%1").arg(m_sourceUrl.toString())); + + m_filesNetJob.reset(new NetJob(tr("Mod download"), APPLICATION->network())); + m_filesNetJob->addNetAction(Net::Download::makeFile(m_sourceUrl, mods->dir().absoluteFilePath(filename))); + connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ModDownloadTask::downloadSucceeded); + connect(m_filesNetJob.get(), &NetJob::progress, this, &ModDownloadTask::downloadProgressChanged); + connect(m_filesNetJob.get(), &NetJob::failed, this, &ModDownloadTask::downloadFailed); + m_filesNetJob->start(); +} + +void ModDownloadTask::downloadSucceeded() +{ + emitSucceeded(); + m_filesNetJob.reset(); +} + +void ModDownloadTask::downloadFailed(QString reason) +{ + emitFailed(reason); + m_filesNetJob.reset(); +} + +void ModDownloadTask::downloadProgressChanged(qint64 current, qint64 total) +{ + emit progress(current, total); +} + +bool ModDownloadTask::abort() { + return m_filesNetJob->abort(); +} + diff --git a/launcher/ModDownloadTask.h b/launcher/ModDownloadTask.h new file mode 100644 index 00000000..7e4f1b7d --- /dev/null +++ b/launcher/ModDownloadTask.h @@ -0,0 +1,34 @@ +#pragma once +#include "QObjectPtr.h" +#include "tasks/Task.h" +#include "minecraft/mod/ModFolderModel.h" +#include "net/NetJob.h" +#include <QUrl> + + +class ModDownloadTask : public Task { + Q_OBJECT +public: + explicit ModDownloadTask(const QUrl sourceUrl, const QString filename, const std::shared_ptr<ModFolderModel> mods); + +public slots: + bool abort() override; +protected: + //! Entry point for tasks. + void executeTask() override; + +private: + QUrl m_sourceUrl; + NetJob::Ptr m_filesNetJob; + const std::shared_ptr<ModFolderModel> mods; + const QString filename; + + void downloadProgressChanged(qint64 current, qint64 total); + + void downloadFailed(QString reason); + + void downloadSucceeded(); +}; + + + diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp index 8fd11eca..f461b847 100644 --- a/launcher/minecraft/launch/LauncherPartLaunch.cpp +++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp @@ -25,6 +25,19 @@ LauncherPartLaunch::LauncherPartLaunch(LaunchTask *parent) : LaunchStep(parent) { + if (APPLICATION->settings()->get("CloseAfterLaunch").toBool()) + { + std::shared_ptr<QMetaObject::Connection> connection{new QMetaObject::Connection}; + *connection = connect(&m_process, &LoggedProcess::log, this, [=](QStringList lines, MessageLevel::Enum level) { + qDebug() << lines; + if (lines.filter(QRegularExpression(".*Setting user.+", QRegularExpression::CaseInsensitiveOption)).length() != 0) + { + APPLICATION->closeAllWindows(); + disconnect(*connection); + } + }); + } + connect(&m_process, &LoggedProcess::log, this, &LauncherPartLaunch::logLines); connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state); } @@ -155,6 +168,8 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state) } case LoggedProcess::Finished: { + if (APPLICATION->settings()->get("CloseAfterLaunch").toBool()) + APPLICATION->showMainWindow(); m_parent->setPid(-1); // if the exit code wasn't 0, report this as a crash auto exitCode = m_process.exitCode(); diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp new file mode 100644 index 00000000..a8b2495a --- /dev/null +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -0,0 +1,100 @@ +#include <QObject> +#include "FlameModIndex.h" +#include "Json.h" +#include "net/NetJob.h" +#include "BaseInstance.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" + + +void FlameMod::loadIndexedPack(FlameMod::IndexedPack & pack, QJsonObject & obj) +{ + pack.addonId = Json::requireInteger(obj, "id"); + pack.name = Json::requireString(obj, "name"); + pack.websiteUrl = Json::ensureString(obj, "websiteUrl", ""); + pack.description = Json::ensureString(obj, "summary", ""); + + bool thumbnailFound = false; + auto attachments = Json::requireArray(obj, "attachments"); + for(auto attachmentRaw: attachments) { + auto attachmentObj = Json::requireObject(attachmentRaw); + bool isDefault = attachmentObj.value("isDefault").toBool(false); + if(isDefault) { + thumbnailFound = true; + pack.logoName = Json::requireString(attachmentObj, "title"); + pack.logoUrl = Json::requireString(attachmentObj, "thumbnailUrl"); + break; + } + } + + if(!thumbnailFound) { + throw JSONValidationError(QString("Pack without an icon, skipping: %1").arg(pack.name)); + } + + + auto authors = Json::requireArray(obj, "authors"); + for(auto authorIter: authors) { + auto author = Json::requireObject(authorIter); + FlameMod::ModpackAuthor packAuthor; + packAuthor.name = Json::requireString(author, "name"); + packAuthor.url = Json::requireString(author, "url"); + pack.authors.append(packAuthor); + } +} + +void FlameMod::loadIndexedPackVersions(FlameMod::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr<QNetworkAccessManager>& network, BaseInstance * inst) +{ + QVector<FlameMod::IndexedVersion> unsortedVersions; + bool hasFabric = !((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = ((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.minecraft"); + + for(auto versionIter: arr) { + auto obj = versionIter.toObject(); + FlameMod::IndexedVersion file; + file.addonId = pack.addonId; + file.fileId = Json::requireInteger(obj, "id"); + file.date = Json::requireString(obj, "fileDate"); + auto versionArray = Json::requireArray(obj, "gameVersion"); + if (versionArray.empty()) { + continue; + } + for(auto mcVer : versionArray){ + file.mcVersion.append(mcVer.toString()); + } + + file.version = Json::requireString(obj, "displayName"); + file.downloadUrl = Json::requireString(obj, "downloadUrl"); + file.fileName = Json::requireString(obj, "fileName"); + + auto modules = Json::requireArray(obj, "modules"); + bool valid = false; + for(auto m : modules){ + auto fname = Json::requireString(m.toObject(),"foldername"); + if(hasFabric){ + if(fname == "fabric.mod.json"){ + valid = true; + break; + } + }else{ + //this cannot check for the recent mcmod.toml formats + if(fname == "mcmod.info"){ + valid = true; + break; + } + } + } + if(!valid && hasFabric){ + continue; + } + + unsortedVersions.append(file); + } + auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool + { + //dates are in RFC 3339 format + return a.date > b.date; + }; + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + pack.versions = unsortedVersions; + pack.versionsLoaded = true; +} diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h new file mode 100644 index 00000000..0293bb23 --- /dev/null +++ b/launcher/modplatform/flame/FlameModIndex.h @@ -0,0 +1,50 @@ +// +// Created by timoreo on 16/01/2022. +// + +#pragma once +#include <QList> +#include <QMetaType> +#include <QString> +#include <QVector> +#include <QNetworkAccessManager> +#include <QObjectPtr.h> +#include "net/NetJob.h" +#include "BaseInstance.h" + +namespace FlameMod { + struct ModpackAuthor { + QString name; + QString url; + }; + + struct IndexedVersion { + int addonId; + int fileId; + QString version; + QVector<QString> mcVersion; + QString downloadUrl; + QString date; + QString fileName; + }; + + struct IndexedPack + { + int addonId; + QString name; + QString description; + QList<ModpackAuthor> authors; + QString logoName; + QString logoUrl; + QString websiteUrl; + + bool versionsLoaded = false; + QVector<IndexedVersion> versions; + }; + + void loadIndexedPack(IndexedPack & m, QJsonObject & obj); + void loadIndexedPackVersions(IndexedPack &pack, QJsonArray &arr, const shared_qobject_ptr<QNetworkAccessManager> &network, BaseInstance *inst); + +} + +Q_DECLARE_METATYPE(FlameMod::IndexedPack) diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp new file mode 100644 index 00000000..9017eb67 --- /dev/null +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -0,0 +1,95 @@ +#include <QObject> +#include "ModrinthPackIndex.h" + +#include "Json.h" +#include "net/NetJob.h" +#include "BaseInstance.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" + + +void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) +{ + pack.addonId = Json::requireString(obj, "project_id"); + pack.name = Json::requireString(obj, "title"); + pack.websiteUrl = Json::ensureString(obj, "page_url", ""); + pack.description = Json::ensureString(obj, "description", ""); + + pack.logoUrl = Json::requireString(obj, "icon_url"); + pack.logoName = pack.addonId; + + Modrinth::ModpackAuthor modAuthor; + modAuthor.name = Json::requireString(obj, "author"); + modAuthor.url = "https://modrinth.com/user/"+modAuthor.name; + pack.author = modAuthor; +} + +void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr<QNetworkAccessManager>& network, BaseInstance * inst) +{ + QVector<Modrinth::IndexedVersion> unsortedVersions; + bool hasFabric = !((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = ((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.minecraft"); + + for(auto versionIter: arr) { + auto obj = versionIter.toObject(); + Modrinth::IndexedVersion file; + file.addonId = Json::requireString(obj,"project_id") ; + file.fileId = Json::requireString(obj, "id"); + file.date = Json::requireString(obj, "date_published"); + auto versionArray = Json::requireArray(obj, "game_versions"); + if (versionArray.empty()) { + continue; + } + for(auto mcVer : versionArray){ + file.mcVersion.append(mcVer.toString()); + } + auto loaders = Json::requireArray(obj,"loaders"); + for(auto loader : loaders){ + file.loaders.append(loader.toString()); + } + file.version = Json::requireString(obj, "name"); + + auto files = Json::requireArray(obj, "files"); + int i = 0; + while (files.count() > 1 && i < files.count()){ + //try to resolve the correct file + auto parent = files[i].toObject(); + auto fileName = Json::requireString(parent, "filename"); + //avoid grabbing "dev" files + if(fileName.contains("javadocs",Qt::CaseInsensitive) || fileName.contains("sources",Qt::CaseInsensitive)){ + i++; + continue; + } + //grab the correct mod loader + if(fileName.contains("forge",Qt::CaseInsensitive) || fileName.contains("fabric",Qt::CaseInsensitive) ){ + if(hasFabric){ + if(fileName.contains("forge",Qt::CaseInsensitive)){ + i++; + continue; + } + }else{ + if(fileName.contains("fabric",Qt::CaseInsensitive)){ + i++; + continue; + } + } + } + break; + } + auto parent = files[i].toObject(); + if(parent.contains("url")) { + file.downloadUrl = Json::requireString(parent, "url"); + file.fileName = Json::requireString(parent, "filename"); + + unsortedVersions.append(file); + } + } + auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool + { + //dates are in RFC 3339 format + return a.date > b.date; + }; + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + pack.versions = unsortedVersions; + pack.versionsLoaded = true; +} diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h new file mode 100644 index 00000000..3a4cd270 --- /dev/null +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -0,0 +1,48 @@ +#pragma once + +#include <QList> +#include <QMetaType> +#include <QString> +#include <QVector> +#include <QNetworkAccessManager> +#include <QObjectPtr.h> +#include "net/NetJob.h" +#include "BaseInstance.h" + +namespace Modrinth { + +struct ModpackAuthor { + QString name; + QString url; +}; + +struct IndexedVersion { + QString addonId; + QString fileId; + QString version; + QVector<QString> mcVersion; + QString downloadUrl; + QString date; + QString fileName; + QVector<QString> loaders; +}; + +struct IndexedPack +{ + QString addonId; + QString name; + QString description; + ModpackAuthor author; + QString logoName; + QString logoUrl; + QString websiteUrl; + + bool versionsLoaded = false; + QVector<IndexedVersion> versions; +}; + +void loadIndexedPack(IndexedPack & m, QJsonObject & obj); +void loadIndexedPackVersions(IndexedPack &pack, QJsonArray &arr, const shared_qobject_ptr<QNetworkAccessManager> &network, BaseInstance *inst); +} + +Q_DECLARE_METATYPE(Modrinth::IndexedPack) diff --git a/launcher/resources/multimc/128x128/instances/modrinth.png b/launcher/resources/multimc/128x128/instances/modrinth.png Binary files differnew file mode 100644 index 00000000..740bc8f0 --- /dev/null +++ b/launcher/resources/multimc/128x128/instances/modrinth.png diff --git a/launcher/resources/multimc/32x32/instances/modrinth.png b/launcher/resources/multimc/32x32/instances/modrinth.png Binary files differnew file mode 100644 index 00000000..025ed065 --- /dev/null +++ b/launcher/resources/multimc/32x32/instances/modrinth.png diff --git a/launcher/resources/multimc/multimc.qrc b/launcher/resources/multimc/multimc.qrc index 58b1d763..ef29cf9b 100644 --- a/launcher/resources/multimc/multimc.qrc +++ b/launcher/resources/multimc/multimc.qrc @@ -268,6 +268,9 @@ <file>32x32/instances/flame.png</file> <file>128x128/instances/flame.png</file> + <file>32x32/instances/modrinth.png</file> + <file>128x128/instances/modrinth.png</file> + <file>32x32/instances/gear.png</file> <file>128x128/instances/gear.png</file> diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index 46d2f429..ef96cc23 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -32,8 +32,14 @@ QString getCreditsHtml() QTextStream stream(&output); stream.setCodec(QTextCodec::codecForName("UTF-8")); stream << "<center>\n"; + + stream << "<h3>" << QObject::tr("PolyMC Developers", "About Credits") << "</h3>\n"; + stream << "<p>swirl <<a href='mailto:swurl@swurl.xyz'>swurl@swurl.xyz </a>></p>\n"; + stream << "<p>LennyMcLennington <<a href='mailto:lenny@sneed.church'>lenny@sneed.church</a>></p>\n"; + stream << "<br />\n"; + // TODO: possibly retrieve from git history at build time? - stream << "<h3>" << QObject::tr("Developers", "About Credits") << "</h3>\n"; + stream << "<h3>" << QObject::tr("MultiMC Developers", "About Credits") << "</h3>\n"; stream << "<p>Andrew Okin <<a href='mailto:forkk@forkk.net'>forkk@forkk.net</a>></p>\n"; stream << "<p>Petr Mrázek <<a href='mailto:peterix@gmail.com'>peterix@gmail.com</a>></p>\n"; stream << "<p>Sky Welch <<a href='mailto:multimc@bunnies.io'>multimc@bunnies.io</a>></p>\n"; @@ -47,6 +53,7 @@ QString getCreditsHtml() stream << "<p>Kilobyte <<a href='mailto:stiepen22@gmx.de'>stiepen22@gmx.de</a>></p>\n"; stream << "<p>Rootbear75 <<a href='https://twitter.com/rootbear75'>@rootbear75</a>></p>\n"; stream << "<p>Zeker Zhayard <<a href='https://twitter.com/zeker_zhayard'>@Zeker_Zhayard</a>></p>\n"; + stream << "<p>Everyone else who <a href='https://github.com/PolyMC/PolyMC/graphs/contributors'>contributed</a>!</p>\n"; stream << "<br />\n"; stream << "</center>\n"; @@ -83,8 +90,12 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->icon->setPixmap(APPLICATION->getThemedIcon("logo").pixmap(64)); ui->title->setText(launcherName); - ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); - ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM); + ui->versionLabel->setText(BuildConfig.printableVersionString()); + + if (!BuildConfig.BUILD_PLATFORM.isEmpty()) + ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM); + else + ui->platformLabel->setVisible(false); if (BuildConfig.VERSION_BUILD >= 0) ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD)); diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui index 822c6f58..58275c66 100644 --- a/launcher/ui/dialogs/AboutDialog.ui +++ b/launcher/ui/dialogs/AboutDialog.ui @@ -87,6 +87,13 @@ </property> </widget> </item> + <item> + <widget class="QLabel" name="versionLabel"> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> <item> <widget class="QTabWidget" name="tabWidget"> <property name="currentIndex"> @@ -152,16 +159,6 @@ </widget> </item> <item> - <widget class="QLabel" name="versionLabel"> - <property name="text"> - <string>Version:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> <widget class="QLabel" name="platformLabel"> <property name="text"> <string>Platform:</string> diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp new file mode 100644 index 00000000..6b807b8c --- /dev/null +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -0,0 +1,98 @@ +#include "ModDownloadDialog.h" + +#include <BaseVersion.h> +#include <icons/IconList.h> +#include <InstanceList.h> + +#include "ProgressDialog.h" + +#include <QLayout> +#include <QPushButton> +#include <QValidator> +#include <QDialogButtonBox> + +#include "ui/widgets/PageContainer.h" +#include "ui/pages/modplatform/modrinth/ModrinthPage.h" +#include "ModDownloadTask.h" + + +ModDownloadDialog::ModDownloadDialog(const std::shared_ptr<ModFolderModel> &mods, QWidget *parent, + BaseInstance *instance) + : QDialog(parent), mods(mods), m_instance(instance) +{ + setObjectName(QStringLiteral("ModDownloadDialog")); + resize(400, 347); + m_verticalLayout = new QVBoxLayout(this); + m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); + + setWindowIcon(APPLICATION->getThemedIcon("new")); + // NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not move this below. + m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + m_container = new PageContainer(this); + m_container->setSizePolicy(QSizePolicy::Policy::Pre |
