aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui/dialogs
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui/dialogs')
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.cpp3
-rw-r--r--launcher/ui/dialogs/ExportPackDialog.cpp81
-rw-r--r--launcher/ui/dialogs/ExportPackDialog.ui86
-rw-r--r--launcher/ui/dialogs/InstallLoaderDialog.cpp4
-rw-r--r--launcher/ui/dialogs/LoginDialog.cpp115
-rw-r--r--launcher/ui/dialogs/LoginDialog.h56
-rw-r--r--launcher/ui/dialogs/LoginDialog.ui77
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.cpp85
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.h2
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp33
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.cpp4
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.h1
-rw-r--r--launcher/ui/dialogs/SkinUploadDialog.ui6
13 files changed, 204 insertions, 349 deletions
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index 727c0614..5a1a2f80 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -44,7 +44,8 @@
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)
: QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
{
- m_hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
+ m_hashing_task = shared_qobject_ptr<ConcurrentTask>(
+ new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));
connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
ui->setupUi(this);
diff --git a/launcher/ui/dialogs/ExportPackDialog.cpp b/launcher/ui/dialogs/ExportPackDialog.cpp
index ad8db5ff..5af24b1b 100644
--- a/launcher/ui/dialogs/ExportPackDialog.cpp
+++ b/launcher/ui/dialogs/ExportPackDialog.cpp
@@ -37,15 +37,21 @@
ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPlatform::ResourceProvider provider)
: QDialog(parent), instance(instance), ui(new Ui::ExportPackDialog), m_provider(provider)
{
+ Q_ASSERT(m_provider == ModPlatform::ResourceProvider::MODRINTH || m_provider == ModPlatform::ResourceProvider::FLAME);
+
ui->setupUi(this);
- ui->name->setText(instance->name());
+ ui->name->setPlaceholderText(instance->name());
+ ui->name->setText(instance->settings()->get("ExportName").toString());
+ ui->version->setText(instance->settings()->get("ExportVersion").toString());
+ ui->optionalFiles->setChecked(instance->settings()->get("ExportOptionalFiles").toBool());
+
if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
- ui->summary->setText(instance->notes().split(QRegularExpression("\\r?\\n"))[0]);
- setWindowTitle("Export Modrinth Pack");
+ setWindowTitle(tr("Export Modrinth Pack"));
+ ui->summary->setText(instance->settings()->get("ExportSummary").toString());
} else {
- setWindowTitle("Export CurseForge Pack");
- ui->version->setText("");
- ui->summaryLabel->setText("Author");
+ setWindowTitle(tr("Export CurseForge Pack"));
+ ui->summaryLabel->setText(tr("&Author"));
+ ui->summary->setText(instance->settings()->get("ExportAuthor").toString());
}
// ensure a valid pack is generated
@@ -75,20 +81,19 @@ ExportPackDialog::ExportPackDialog(InstancePtr instance, QWidget* parent, ModPla
MinecraftInstance* mcInstance = dynamic_cast<MinecraftInstance*>(instance.get());
if (mcInstance) {
- mcInstance->loaderModList()->update();
const QDir index = mcInstance->loaderModList()->indexDir();
if (index.exists())
- proxy->blockedPaths().insert(root.relativeFilePath(index.absolutePath()));
+ proxy->ignoreFilesWithPath().insert(root.relativeFilePath(index.absolutePath()));
}
- ui->treeView->setModel(proxy);
- ui->treeView->setRootIndex(proxy->mapFromSource(model->index(instance->gameRoot())));
- ui->treeView->sortByColumn(0, Qt::AscendingOrder);
+ ui->files->setModel(proxy);
+ ui->files->setRootIndex(proxy->mapFromSource(model->index(instance->gameRoot())));
+ ui->files->sortByColumn(0, Qt::AscendingOrder);
model->setFilter(filter);
model->setRootPath(instance->gameRoot());
- QHeaderView* headerView = ui->treeView->header();
+ QHeaderView* headerView = ui->files->header();
headerView->setSectionResizeMode(QHeaderView::ResizeToContents);
headerView->setSectionResizeMode(0, QHeaderView::Stretch);
}
@@ -100,26 +105,41 @@ ExportPackDialog::~ExportPackDialog()
void ExportPackDialog::done(int result)
{
+ auto settings = instance->settings();
+ settings->set("ExportName", ui->name->text());
+ settings->set("ExportVersion", ui->version->text());
+ settings->set(m_provider == ModPlatform::ResourceProvider::FLAME ? "ExportAuthor" : "ExportSummary", ui->summary->text());
+ settings->set("ExportOptionalFiles", ui->optionalFiles->isChecked());
+
if (result == Accepted) {
- const QString filename = FS::RemoveInvalidFilenameChars(ui->name->text());
+ const QString name = ui->name->text().isEmpty() ? instance->name() : ui->name->text();
+ const QString filename = FS::RemoveInvalidFilenameChars(name);
+
QString output;
- if (m_provider == ModPlatform::ResourceProvider::MODRINTH)
- output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()),
- FS::PathCombine(QDir::homePath(), filename + ".mrpack"), "Modrinth pack (*.mrpack *.zip)",
- nullptr);
- else
- output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(ui->name->text()),
- FS::PathCombine(QDir::homePath(), filename + ".zip"), "CurseForge pack (*.zip)", nullptr);
-
- if (output.isEmpty())
- return;
+ if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
+ output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".mrpack"),
+ "Modrinth pack (*.mrpack *.zip)", nullptr);
+ if (output.isEmpty())
+ return;
+ if (!(output.endsWith(".zip") || output.endsWith(".mrpack")))
+ output.append(".mrpack");
+ } else {
+ output = QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + ".zip"),
+ "CurseForge pack (*.zip)", nullptr);
+ if (output.isEmpty())
+ return;
+ if (!output.endsWith(".zip"))
+ output.append(".zip");
+ }
+
Task* task;
- if (m_provider == ModPlatform::ResourceProvider::MODRINTH)
- task = new ModrinthPackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output,
- std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
- else
- task = new FlamePackExportTask(ui->name->text(), ui->version->text(), ui->summary->text(), instance, output,
+ if (m_provider == ModPlatform::ResourceProvider::MODRINTH) {
+ task = new ModrinthPackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance,
+ output, std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
+ } else {
+ task = new FlamePackExportTask(name, ui->version->text(), ui->summary->text(), ui->optionalFiles->isChecked(), instance, output,
std::bind(&FileIgnoreProxy::filterFile, proxy, std::placeholders::_1));
+ }
connect(task, &Task::failed,
[this](const QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); });
@@ -140,7 +160,6 @@ void ExportPackDialog::done(int result)
void ExportPackDialog::validate()
{
- const bool invalid =
- ui->name->text().isEmpty() || ((m_provider == ModPlatform::ResourceProvider::MODRINTH) && ui->version->text().isEmpty());
- ui->buttonBox->button(QDialogButtonBox::Ok)->setDisabled(invalid);
+ ui->buttonBox->button(QDialogButtonBox::Ok)
+ ->setDisabled(m_provider == ModPlatform::ResourceProvider::MODRINTH && ui->version->text().isEmpty());
}
diff --git a/launcher/ui/dialogs/ExportPackDialog.ui b/launcher/ui/dialogs/ExportPackDialog.ui
index 3976e28f..09dea72a 100644
--- a/launcher/ui/dialogs/ExportPackDialog.ui
+++ b/launcher/ui/dialogs/ExportPackDialog.ui
@@ -7,12 +7,9 @@
<x>0</x>
<y>0</y>
<width>650</width>
- <height>413</height>
+ <height>510</height>
</rect>
</property>
- <property name="windowTitle">
- <string>Export Pack</string>
- </property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
@@ -20,13 +17,16 @@
<item>
<widget class="QGroupBox" name="information">
<property name="title">
- <string>Information</string>
+ <string>&amp;Description</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QLabel" name="summaryLabel">
<property name="text">
- <string>Summary</string>
+ <string>&amp;Summary</string>
+ </property>
+ <property name="buddy">
+ <cstring>summary</cstring>
</property>
</widget>
</item>
@@ -36,14 +36,20 @@
<item row="0" column="0">
<widget class="QLabel" name="nameLabel">
<property name="text">
- <string>Name</string>
+ <string>&amp;Name</string>
+ </property>
+ <property name="buddy">
+ <cstring>name</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="versionLabel">
<property name="text">
- <string>Version</string>
+ <string>&amp;Version</string>
+ </property>
+ <property name="buddy">
+ <cstring>version</cstring>
</property>
</widget>
</item>
@@ -57,31 +63,52 @@
</property>
</widget>
</item>
-
</layout>
</widget>
</item>
<item>
- <widget class="QLabel" name="filesLabel">
- <property name="text">
- <string>Files</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTreeView" name="treeView">
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
+ <widget class="QGroupBox" name="options">
+ <property name="title">
+ <string>&amp;Options</string>
</property>
- <attribute name="headerStretchLastSection">
- <bool>false</bool>
- </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="filesLabel">
+ <property name="text">
+ <string>&amp;Files</string>
+ </property>
+ <property name="buddy">
+ <cstring>files</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeView" name="files">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="optionalFiles">
+ <property name="text">
+ <string>&amp;Mark disabled files as optional</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
<item>
@@ -97,7 +124,8 @@
<tabstop>name</tabstop>
<tabstop>version</tabstop>
<tabstop>summary</tabstop>
- <tabstop>treeView</tabstop>
+ <tabstop>files</tabstop>
+ <tabstop>optionalFiles</tabstop>
</tabstops>
<resources/>
<connections>
diff --git a/launcher/ui/dialogs/InstallLoaderDialog.cpp b/launcher/ui/dialogs/InstallLoaderDialog.cpp
index 840a328f..541119d1 100644
--- a/launcher/ui/dialogs/InstallLoaderDialog.cpp
+++ b/launcher/ui/dialogs/InstallLoaderDialog.cpp
@@ -129,7 +129,9 @@ InstallLoaderDialog::InstallLoaderDialog(std::shared_ptr<PackProfile> profile, c
QList<BasePage*> InstallLoaderDialog::getPages()
{
- return { // Forge
+ return { // NeoForge
+ new InstallLoaderPage("net.neoforged", "neoforged", tr("NeoForge"), {}, profile),
+ // Forge
new InstallLoaderPage("net.minecraftforge", "forge", tr("Forge"), {}, profile),
// Fabric
new InstallLoaderPage("net.fabricmc.fabric-loader", "fabricmc", tr("Fabric"), Version("1.14"), profile),
diff --git a/launcher/ui/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp
deleted file mode 100644
index 7296a13e..00000000
--- a/launcher/ui/dialogs/LoginDialog.cpp
+++ /dev/null
@@ -1,115 +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.
- */
-
-#include "LoginDialog.h"
-#include "ui_LoginDialog.h"
-
-#include "minecraft/auth/AccountTask.h"
-
-#include <QtWidgets/QPushButton>
-
-LoginDialog::LoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::LoginDialog)
-{
- ui->setupUi(this);
- ui->progressBar->setVisible(false);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-
- connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
-}
-
-LoginDialog::~LoginDialog()
-{
- delete ui;
-}
-
-// Stage 1: User interaction
-void LoginDialog::accept()
-{
- setUserInputsEnabled(false);
- ui->progressBar->setVisible(true);
-
- // Setup the login task and start it
- m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text());
- m_loginTask = m_account->login(ui->passTextBox->text());
- connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
- connect(m_loginTask.get(), &Task::succeeded, this, &LoginDialog::onTaskSucceeded);
- connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
- connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress);
- m_loginTask->start();
-}
-
-void LoginDialog::setUserInputsEnabled(bool enable)
-{
- ui->userTextBox->setEnabled(enable);
- ui->passTextBox->setEnabled(enable);
- ui->buttonBox->setEnabled(enable);
-}
-
-// Enable the OK button only when both textboxes contain something.
-void LoginDialog::on_userTextBox_textEdited(const QString& newText)
-{
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
-}
-void LoginDialog::on_passTextBox_textEdited(const QString& newText)
-{
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
-}
-
-void LoginDialog::onTaskFailed(const QString& reason)
-{
- // Set message
- auto lines = reason.split('\n');
- QString processed;
- for (auto line : lines) {
- if (line.size()) {
- processed += "<font color='red'>" + line + "</font><br />";
- } else {
- processed += "<br />";
- }
- }
- ui->label->setText(processed);
-
- // Re-enable user-interaction
- setUserInputsEnabled(true);
- ui->progressBar->setVisible(false);
-}
-
-void LoginDialog::onTaskSucceeded()
-{
- QDialog::accept();
-}
-
-void LoginDialog::onTaskStatus(const QString& status)
-{
- ui->label->setText(status);
-}
-
-void LoginDialog::onTaskProgress(qint64 current, qint64 total)
-{
- ui->progressBar->setMaximum(total);
- ui->progressBar->setValue(current);
-}
-
-// Public interface
-MinecraftAccountPtr LoginDialog::newAccount(QWidget* parent, QString msg)
-{
- LoginDialog dlg(parent);
- dlg.ui->label->setText(msg);
- if (dlg.exec() == QDialog::Accepted) {
- return dlg.m_account;
- }
- return nullptr;
-}
diff --git a/launcher/ui/dialogs/LoginDialog.h b/launcher/ui/dialogs/LoginDialog.h
deleted file mode 100644
index 601b5fa7..00000000
--- a/launcher/ui/dialogs/LoginDialog.h
+++ /dev/null
@@ -1,56 +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 <QtCore/QEventLoop>
-#include <QtWidgets/QDialog>
-
-#include "minecraft/auth/MinecraftAccount.h"
-#include "tasks/Task.h"
-
-namespace Ui {
-class LoginDialog;
-}
-
-class LoginDialog : public QDialog {
- Q_OBJECT
-
- public:
- ~LoginDialog();
-
- static MinecraftAccountPtr newAccount(QWidget* parent, QString message);
-
- private:
- explicit LoginDialog(QWidget* parent = 0);
-
- void setUserInputsEnabled(bool enable);
-
- protected slots:
- void accept();
-
- void onTaskFailed(const QString& reason);
- void onTaskSucceeded();
- void onTaskStatus(const QString& status);
- void onTaskProgress(qint64 current, qint64 total);
-
- void on_userTextBox_textEdited(const QString& newText);
- void on_passTextBox_textEdited(const QString& newText);
-
- private:
- Ui::LoginDialog* ui;
- MinecraftAccountPtr m_account;
- Task::Ptr m_loginTask;
-};
diff --git a/launcher/ui/dialogs/LoginDialog.ui b/launcher/ui/dialogs/LoginDialog.ui
deleted file mode 100644
index 8fa4a45d..00000000
--- a/launcher/ui/dialogs/LoginDialog.ui
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LoginDialog</class>
- <widget class="QDialog" name="LoginDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>421</width>
- <height>198</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>Add Account</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string notr="true">Message label placeholder.</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="userTextBox">
- <property name="placeholderText">
- <string>Email</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="passTextBox">
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- <property name="placeholderText">
- <string>Password</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QProgressBar" name="progressBar">
- <property name="value">
- <number>24</number>
- </property>
- <property name="textVisible">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index 0af1ec59..1a70ea59 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -3,10 +3,11 @@
#include "CustomMessageBox.h"
#include "ProgressDialog.h"
#include "ScrollMessageBox.h"
+#include "minecraft/mod/tasks/GetModDependenciesTask.h"
+#include "modplatform/ModIndex.h"
+#include "modplatform/flame/FlameAPI.h"
#include "ui_ReviewMessageBox.h"
-#include "FileSystem.h"
-#include "Json.h"
#include "Markdown.h"
#include "tasks/ConcurrentTask.h"
@@ -30,9 +31,9 @@ static std::list<Version> mcVersions(BaseInstance* inst)
return { static_cast<MinecraftInstance*>(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion() };
}
-static std::optional<ResourceAPI::ModLoaderTypes> mcLoaders(BaseInstance* inst)
+static std::optional<ModPlatform::ModLoaderTypes> mcLoaders(BaseInstance* inst)
{
- return { static_cast<MinecraftInstance*>(inst)->getPackProfile()->getModLoaders() };
+ return { static_cast<MinecraftInstance*>(inst)->getPackProfile()->getSupportedModLoaders() };
}
ModUpdateDialog::ModUpdateDialog(QWidget* parent,
@@ -43,7 +44,8 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent,
, m_parent(parent)
, m_mod_model(mods)
, m_candidates(search_for)
- , m_second_try_metadata(new ConcurrentTask())
+ , m_second_try_metadata(
+ new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
, m_instance(instance)
{
ReviewMessageBox::setGeometry(0, 0, 800, 600);
@@ -126,6 +128,8 @@ void ModUpdateDialog::checkCandidates()
return;
}
+ QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
+
// Add found updates for Modrinth
if (m_modrinth_check_task) {
auto modrinth_updates = m_modrinth_check_task->getUpdatable();
@@ -135,6 +139,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download);
}
+ selectedVers.append(m_modrinth_check_task->getDependencies());
}
// Add found updated for Flame
@@ -146,6 +151,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download);
}
+ selectedVers.append(m_flame_check_task->getDependencies());
}
// Report failed update checking
@@ -180,6 +186,49 @@ void ModUpdateDialog::checkCandidates()
}
}
+ { // dependencies
+ auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, m_mod_model.get(), selectedVers);
+
+ connect(depTask.get(), &Task::failed, this,
+ [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
+
+ connect(depTask.get(), &Task::succeeded, this, [&]() {
+ QStringList warnings = depTask->warnings();
+ if (warnings.count()) {
+ CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec();
+ }
+ });
+
+ ProgressDialog progress_dialog_deps(m_parent);
+ progress_dialog_deps.setSkipButton(true, tr("Abort"));
+ progress_dialog_deps.setWindowTitle(tr("Checking for dependencies..."));
+ auto dret = progress_dialog_deps.execWithTask(depTask.get());
+
+ // If the dialog was skipped / some download error happened
+ if (dret == QDialog::DialogCode::Rejected) {
+ m_aborted = true;
+ QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection);
+ return;
+ }
+ static FlameAPI api;
+
+ auto getRequiredBy = depTask->getRequiredBy();
+
+ for (auto dep : depTask->getDependecies()) {
+ auto changelog = dep->version.changelog;
+ if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
+ changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
+ auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_mod_model);
+ CheckUpdateTask::UpdatableMod updatable = {
+ dep->pack->name, dep->version.hash, "", dep->version.version, dep->version.version_type,
+ changelog, dep->pack->provider, download_task
+ };
+
+ appendMod(updatable, getRequiredBy.value(dep->version.addonId.toString()));
+ m_tasks.insert(updatable.name, updatable.download);
+ }
+ }
+
// If there's no mod to be updated
if (ui->modTreeWidget->topLevelItemCount() == 0) {
m_no_updates = true;
@@ -238,6 +287,10 @@ auto ModUpdateDialog::ensureMetadata() -> bool
if (skip_rest)
continue;
+ if (candidate->type() == ResourceType::FOLDER) {
+ continue;
+ }
+
if (confirm_rest) {
addToTmp(candidate, provider_rest);
should_try_others.insert(candidate->internal_id(), try_others_rest);
@@ -348,7 +401,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R
}
}
-void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
+void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStringList requiredBy)
{
auto item_top = new QTreeWidgetItem(ui->modTreeWidget);
item_top->setCheckState(0, Qt::CheckState::Checked);
@@ -364,6 +417,26 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
auto new_version_item = new QTreeWidgetItem(item_top);
new_version_item->setText(0, tr("New version: %1").arg(info.new_version));
+ if (info.new_version_type.has_value()) {
+ auto new_version_type_itme = new QTreeWidgetItem(item_top);
+ new_version_type_itme->setText(0, tr("New Version Type: %1").arg(info.new_version_type.value().toString()));
+ }
+
+ if (!requiredBy.isEmpty()) {
+ auto requiredByItem = new QTreeWidgetItem(item_top);
+ if (requiredBy.length() == 1) {
+ requiredByItem->setText(0, tr("Required by: %1").arg(requiredBy.back()));
+ } else {
+ requiredByItem->setText(0, tr("Required by:"));
+ auto i = 0;
+ for (auto req : requiredBy) {
+ auto reqItem = new QTreeWidgetItem(requiredByItem);
+ reqItem->setText(0, req);
+ reqItem->insertChildren(i++, { reqItem });
+ }
+ }
+ }
+
auto changelog_item = new QTreeWidgetItem(item_top);
changelog_item->setText(0, tr("Changelog of the latest version"));
diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h
index 12dddf5e..b79aa494 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.h
+++ b/launcher/ui/dialogs/ModUpdateDialog.h
@@ -23,7 +23,7 @@ class ModUpdateDialog final : public ReviewMessageBox {
void checkCandidates();
- void appendMod(const CheckUpdateTask::UpdatableMod& info);
+ void appendMod(const CheckUpdateTask::UpdatableMod& info, QStringList requiredBy = {});
const QList<ResourceDownloadTask::Ptr> getTasks();
auto indexDir() const -> QDir { return m_mod_model->indexDir(); }
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
index 4b82c0c5..dc7cfff0 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
@@ -127,35 +127,12 @@ void ResourceDownloadDialog::connectButtons()
static ModPlatform::ProviderCapabilities ProviderCaps;
-QStringList getRequiredBy(QList<ResourceDownloadDialog::DownloadTaskPtr> tasks, ResourceDownloadDialog::DownloadTaskPtr pack)
-{
- auto addonId = pack->getPack()->addonId;
- auto provider = pack->getPack()->provider;
- auto version = pack->getVersionID();
- auto req = QStringList();
- for (auto& task : tasks) {
- if (provider != task->getPack()->provider)
- continue;
- auto deps = task->getVersion().dependencies;
- if (auto dep = std::find_if(deps.begin(), deps.end(),
- [addonId, provider, version](const ModPlatform::Dependency& d) {
- return d.type == ModPlatform::DependencyType::REQUIRED &&
- (provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty()
- ? version == d.version
- : d.addonId == addonId);
- });
- dep != deps.end()) {
- req.append(task->getName());
- }
- }
- return req;
-}
-
void ResourceDownloadDialog::confirm()
{
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
confirm_dialog->retranslateUi(resourcesString());
+ QHash<QString, QStringList> getRequiredBy;
if (auto task = getModDependenciesTask(); task) {
connect(task.get(), &Task::failed, this,
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
@@ -180,6 +157,7 @@ void ResourceDownloadDialog::confirm()
} else {
for (auto dep : task->getDependecies())
addResource(dep->pack, dep->version);
+ getRequiredBy = task->getRequiredBy();
}
}
@@ -189,7 +167,8 @@ void ResourceDownloadDialog::confirm()
});
for (auto& task : selected) {
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
- ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task) });
+ ProviderCaps.name(task->getProvider()), getRequiredBy.value(task->getPack()->addonId.toString()),
+ task->getVersion().version_type.toString() });
}
if (confirm_dialog->exec()) {
@@ -279,7 +258,7 @@ QList<BasePage*> ModDownloadDialog::getPages()
{
QList<BasePage*> pages;
- auto loaders = static_cast<MinecraftInstance*>(m_instance)->getPackProfile()->getModLoaders().value();
+ auto loaders = static_cast<MinecraftInstance*>(m_instance)->getPackProfile()->getSupportedModLoaders().value();
if (ModrinthAPI::validateModLoaders(loaders))
pages.append(ModrinthModPage::create(this, *m_instance));
@@ -370,6 +349,8 @@ QList<BasePage*> ShaderPackDownloadDialog::getPages()
{
QList<BasePage*> pages;
pages.append(ModrinthShaderPackPage::create(this, *m_instance));
+ if (APPLICATION->capabilities() & Application::SupportsFlame)
+ pages.append(FlameShaderPackPage::create(this, *m_instance));
return pages;
}
diff --git a/launcher/ui/dialogs/ReviewMessageBox.cpp b/launcher/ui/dialogs/ReviewMessageBox.cpp
index 78c2542f..aa668f8c 100644
--- a/launcher/ui/dialogs/ReviewMessageBox.cpp
+++ b/launcher/ui/dialogs/ReviewMessageBox.cpp
@@ -77,6 +77,10 @@ void ReviewMessageBox::appendResource(ResourceInformation&& info)
itemTop->insertChildren(childIndx++, { requiredByItem });
}
+ auto versionTypeItem = new QTreeWidgetItem(itemTop);
+ versionTypeItem->setText(0, tr("Version Type: %1").arg(info.version_type));
+ itemTop->insertChildren(childIndx++, { versionTypeItem });
+
ui->modTreeWidget->addTopLevelItem(itemTop);
}
diff --git a/launcher/ui/dialogs/ReviewMessageBox.h b/launcher/ui/dialogs/ReviewMessageBox.h
index a520cc2a..596f39c8 100644
--- a/launcher/ui/dialogs/ReviewMessageBox.h
+++ b/launcher/ui/dialogs/ReviewMessageBox.h
@@ -18,6 +18,7 @@ class ReviewMessageBox : public QDialog {
QString custom_file_path{};
QString provider;
QStringList required_by;
+ QString version_type;
};
void appendResource(ResourceInformation&& info);
diff --git a/launcher/ui/dialogs/SkinUploadDialog.ui b/launcher/ui/dialogs/SkinUploadDialog.ui
index 2c81a7fe..c6df92df 100644
--- a/launcher/ui/dialogs/SkinUploadDialog.ui
+++ b/launcher/ui/dialogs/SkinUploadDialog.ui
@@ -35,12 +35,6 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="maximumSize">
- <size>
- <width>28</width>
- <height>16777215</height>
- </size>
- </property>
<property name="text">
<string>Browse</string>
</property>