aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui')
-rw-r--r--launcher/ui/MainWindow.cpp51
-rw-r--r--launcher/ui/MainWindow.h1
-rw-r--r--launcher/ui/MainWindow.ui10
-rw-r--r--launcher/ui/dialogs/ExportToModListDialog.cpp223
-rw-r--r--launcher/ui/dialogs/ExportToModListDialog.h55
-rw-r--r--launcher/ui/dialogs/ExportToModListDialog.ui240
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp9
-rw-r--r--launcher/ui/pages/instance/ManagedPackPage.cpp25
-rw-r--r--launcher/ui/pages/modplatform/ResourcePage.cpp1
-rw-r--r--launcher/ui/widgets/LanguageSelectionWidget.cpp28
-rw-r--r--launcher/ui/widgets/LanguageSelectionWidget.h25
11 files changed, 636 insertions, 32 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 13155e08..da572fc3 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -43,6 +43,7 @@
#include "FileSystem.h"
#include "MainWindow.h"
+#include "ui/dialogs/ExportToModListDialog.h"
#include "ui_MainWindow.h"
#include <QDir>
@@ -202,6 +203,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
exportInstanceMenu->addAction(ui->actionExportInstanceZip);
exportInstanceMenu->addAction(ui->actionExportInstanceMrPack);
exportInstanceMenu->addAction(ui->actionExportInstanceFlamePack);
+ exportInstanceMenu->addAction(ui->actionExportInstanceToModList);
ui->actionExportInstance->setMenu(exportInstanceMenu);
}
@@ -1186,7 +1188,17 @@ void MainWindow::globalSettingsClosed()
void MainWindow::on_actionEditInstance_triggered()
{
- APPLICATION->showInstanceWindow(m_selectedInstance);
+ if (!m_selectedInstance)
+ return;
+
+ if (m_selectedInstance->canEdit()) {
+ APPLICATION->showInstanceWindow(m_selectedInstance);
+ } else {
+ CustomMessageBox::selectable(this, tr("Instance not editable"),
+ tr("This instance is not editable. It may be broken, invalid, or too old. Check logs for details."),
+ QMessageBox::Critical)
+ ->show();
+ }
}
void MainWindow::on_actionManageAccounts_triggered()
@@ -1317,6 +1329,14 @@ void MainWindow::on_actionExportInstanceMrPack_triggered()
}
}
+void MainWindow::on_actionExportInstanceToModList_triggered()
+{
+ if (m_selectedInstance) {
+ ExportToModListDialog dlg(m_selectedInstance, this);
+ dlg.exec();
+ }
+}
+
void MainWindow::on_actionExportInstanceFlamePack_triggered()
{
if (m_selectedInstance) {
@@ -1435,11 +1455,36 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
QString iconPath;
QStringList args;
#if defined(Q_OS_MACOS)
+ appPath = QApplication::applicationFilePath();
if (appPath.startsWith("/private/var/")) {
QMessageBox::critical(this, tr("Create instance shortcut"),
tr("The launcher is in the folder it was extracted from, therefore it cannot create shortcuts."));
return;
}
+
+ auto pIcon = APPLICATION->icons()->icon(m_selectedInstance->iconKey());
+ if (pIcon == nullptr) {
+ pIcon = APPLICATION->icons()->icon("grass");
+ }
+
+ iconPath = FS::PathCombine(m_selectedInstance->instanceRoot(), "Icon.icns");
+
+ QFile iconFile(iconPath);
+ if (!iconFile.open(QFile::WriteOnly)) {
+ QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
+ return;
+ }
+
+ QIcon icon = pIcon->icon();
+
+ bool success = icon.pixmap(1024, 1024).save(iconPath, "ICNS");
+ iconFile.close();
+
+ if (!success) {
+ iconFile.remove();
+ QMessageBox::critical(this, tr("Create instance Application"), tr("Failed to create icon for Application."));
+ return;
+ }
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
if (appPath.startsWith("/tmp/.mount_")) {
// AppImage!
@@ -1522,7 +1567,11 @@ void MainWindow::on_actionCreateInstanceShortcut_triggered()
#endif
args.append({ "--launch", m_selectedInstance->id() });
if (FS::createShortcut(desktopFilePath, appPath, args, m_selectedInstance->name(), iconPath)) {
+#if not defined(Q_OS_MACOS)
QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance on your desktop!"));
+#else
+ QMessageBox::information(this, tr("Create instance shortcut"), tr("Created a shortcut to this instance!"));
+#endif
} else {
#if not defined(Q_OS_MACOS)
iconFile.remove();
diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h
index 5f74b501..27c2756f 100644
--- a/launcher/ui/MainWindow.h
+++ b/launcher/ui/MainWindow.h
@@ -158,6 +158,7 @@ private slots:
void on_actionExportInstanceZip_triggered();
void on_actionExportInstanceMrPack_triggered();
void on_actionExportInstanceFlamePack_triggered();
+ void on_actionExportInstanceToModList_triggered();
void on_actionRenameInstance_triggered();
diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui
index 190219b9..e4421d40 100644
--- a/launcher/ui/MainWindow.ui
+++ b/launcher/ui/MainWindow.ui
@@ -484,7 +484,15 @@
<iconset theme="flame"/>
</property>
<property name="text">
- <string>CurseForge (zip)</string>
+ <string>CurseForge (zip)</string>
+ </property>
+ </action>
+ <action name="actionExportInstanceToModList">
+ <property name="icon">
+ <iconset theme="new"/>
+ </property>
+ <property name="text">
+ <string>Mod List</string>
</property>
</action>
<action name="actionCreateInstanceShortcut">
diff --git a/launcher/ui/dialogs/ExportToModListDialog.cpp b/launcher/ui/dialogs/ExportToModListDialog.cpp
new file mode 100644
index 00000000..c811bfe6
--- /dev/null
+++ b/launcher/ui/dialogs/ExportToModListDialog.cpp
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "ExportToModListDialog.h"
+#include <QCheckBox>
+#include <QComboBox>
+#include <QTextEdit>
+#include "FileSystem.h"
+#include "Markdown.h"
+#include "minecraft/MinecraftInstance.h"
+#include "minecraft/mod/ModFolderModel.h"
+#include "modplatform/helpers/ExportToModList.h"
+#include "ui_ExportToModListDialog.h"
+
+#include <QFileDialog>
+#include <QFileSystemModel>
+#include <QJsonDocument>
+#include <QMessageBox>
+#include <QPushButton>
+
+const QHash<ExportToModList::Formats, QString> ExportToModListDialog::exampleLines = {
+ { ExportToModList::HTML, "<li><a href=\"{url}\">{name}</a> [{version}] by {authors}</li>" },
+ { ExportToModList::MARKDOWN, "[{name}]({url}) [{version}] by {authors}" },
+ { ExportToModList::PLAINTXT, "{name} ({url}) [{version}] by {authors}" },
+ { ExportToModList::JSON, "{\"name\":\"{name}\",\"url\":\"{url}\",\"version\":\"{version}\",\"authors\":\"{authors}\"}," },
+ { ExportToModList::CSV, "{name},{url},{version},\"{authors}\"" },
+};
+
+ExportToModListDialog::ExportToModListDialog(InstancePtr instance, QWidget* parent)
+ : QDialog(parent), m_template_changed(false), name(instance->name()), ui(new Ui::ExportToModListDialog)
+{
+ ui->setupUi(this);
+ enableCustom(false);
+
+ MinecraftInstance* mcInstance = dynamic_cast<MinecraftInstance*>(instance.get());
+ if (mcInstance) {
+ mcInstance->loaderModList()->update();
+ connect(mcInstance->loaderModList().get(), &ModFolderModel::updateFinished, this, [this, mcInstance]() {
+ m_allMods = mcInstance->loaderModList()->allMods();
+ triggerImp();
+ });
+ }
+
+ connect(ui->formatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ExportToModListDialog::formatChanged);
+ connect(ui->authorsCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger);
+ connect(ui->versionCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger);
+ connect(ui->urlCheckBox, &QCheckBox::stateChanged, this, &ExportToModListDialog::trigger);
+ connect(ui->authorsButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Authors); });
+ connect(ui->versionButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Version); });
+ connect(ui->urlButton, &QPushButton::clicked, this, [this](bool) { addExtra(ExportToModList::Url); });
+ connect(ui->templateText, &QTextEdit::textChanged, this, [this] {
+ if (ui->templateText->toPlainText() != exampleLines[format])
+ ui->formatComboBox->setCurrentIndex(5);
+ else
+ triggerImp();
+ });
+ connect(ui->copyButton, &QPushButton::clicked, this, [this](bool) {
+ this->ui->finalText->selectAll();
+ this->ui->finalText->copy();
+ });
+}
+
+ExportToModListDialog::~ExportToModListDialog()
+{
+ delete ui;
+}
+
+void ExportToModListDialog::formatChanged(int index)
+{
+ switch (index) {
+ case 0: {
+ enableCustom(false);
+ ui->resultText->show();
+ format = ExportToModList::HTML;
+ break;
+ }
+ case 1: {
+ enableCustom(false);
+ ui->resultText->show();
+ format = ExportToModList::MARKDOWN;
+ break;
+ }
+ case 2: {
+ enableCustom(false);
+ ui->resultText->hide();
+ format = ExportToModList::PLAINTXT;
+ break;
+ }
+ case 3: {
+ enableCustom(false);
+ ui->resultText->hide();
+ format = ExportToModList::JSON;
+ break;
+ }
+ case 4: {
+ enableCustom(false);
+ ui->resultText->hide();
+ format = ExportToModList::CSV;
+ break;
+ }
+ case 5: {
+ m_template_changed = true;
+ enableCustom(true);
+ ui->resultText->hide();
+ format = ExportToModList::CUSTOM;
+ break;
+ }
+ }
+ triggerImp();
+}
+
+void ExportToModListDialog::triggerImp()
+{
+ if (format == ExportToModList::CUSTOM) {
+ ui->finalText->setPlainText(ExportToModList::exportToModList(m_allMods, ui->templateText->toPlainText()));
+ return;
+ }
+ auto opt = 0;
+ if (ui->authorsCheckBox->isChecked())
+ opt |= ExportToModList::Authors;
+ if (ui->versionCheckBox->isChecked())
+ opt |= ExportToModList::Version;
+ if (ui->urlCheckBox->isChecked())
+ opt |= ExportToModList::Url;
+ auto txt = ExportToModList::exportToModList(m_allMods, format, static_cast<ExportToModList::OptionalData>(opt));
+ ui->finalText->setPlainText(txt);
+ switch (format) {
+ case ExportToModList::CUSTOM:
+ return;
+ case ExportToModList::HTML:
+ ui->resultText->setHtml(txt);
+ break;
+ case ExportToModList::MARKDOWN:
+ ui->resultText->setHtml(markdownToHTML(txt));
+ break;
+ case ExportToModList::PLAINTXT:
+ break;
+ case ExportToModList::JSON:
+ break;
+ case ExportToModList::CSV:
+ break;
+ }
+ auto exampleLine = exampleLines[format];
+ if (!m_template_changed && ui->templateText->toPlainText() != exampleLine)
+ ui->templateText->setPlainText(exampleLine);
+}
+
+void ExportToModListDialog::done(int result)
+{
+ if (result == Accepted) {
+ const QString filename = FS::RemoveInvalidFilenameChars(name);
+ const QString output =
+ QFileDialog::getSaveFileName(this, tr("Export %1").arg(name), FS::PathCombine(QDir::homePath(), filename + extension()),
+ "File (*.txt *.html *.md *.json *.csv)", nullptr);
+
+ if (output.isEmpty())
+ return;
+ FS::write(output, ui->finalText->toPlainText().toUtf8());
+ }
+
+ QDialog::done(result);
+}
+
+QString ExportToModListDialog::extension()
+{
+ switch (format) {
+ case ExportToModList::HTML:
+ return ".html";
+ case ExportToModList::MARKDOWN:
+ return ".md";
+ case ExportToModList::PLAINTXT:
+ return ".txt";
+ case ExportToModList::CUSTOM:
+ return ".txt";
+ case ExportToModList::JSON:
+ return ".json";
+ case ExportToModList::CSV:
+ return ".csv";
+ }
+ return ".txt";
+}
+
+void ExportToModListDialog::addExtra(ExportToModList::OptionalData option)
+{
+ if (format != ExportToModList::CUSTOM)
+ return;
+ switch (option) {
+ case ExportToModList::Authors:
+ ui->templateText->insertPlainText("{authors}");
+ break;
+ case ExportToModList::Url:
+ ui->templateText->insertPlainText("{url}");
+ break;
+ case ExportToModList::Version:
+ ui->templateText->insertPlainText("{version}");
+ break;
+ }
+}
+void ExportToModListDialog::enableCustom(bool enabled)
+{
+ ui->authorsCheckBox->setHidden(enabled);
+ ui->versionCheckBox->setHidden(enabled);
+ ui->urlCheckBox->setHidden(enabled);
+
+ ui->authorsButton->setHidden(!enabled);
+ ui->versionButton->setHidden(!enabled);
+ ui->urlButton->setHidden(!enabled);
+}
diff --git a/launcher/ui/dialogs/ExportToModListDialog.h b/launcher/ui/dialogs/ExportToModListDialog.h
new file mode 100644
index 00000000..9886ae5a
--- /dev/null
+++ b/launcher/ui/dialogs/ExportToModListDialog.h
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <QDialog>
+#include <QList>
+#include "BaseInstance.h"
+#include "minecraft/mod/Mod.h"
+#include "modplatform/helpers/ExportToModList.h"
+
+namespace Ui {
+class ExportToModListDialog;
+}
+
+class ExportToModListDialog : public QDialog {
+ Q_OBJECT
+
+ public:
+ explicit ExportToModListDialog(InstancePtr instance, QWidget* parent = nullptr);
+ ~ExportToModListDialog();
+
+ void done(int result) override;
+
+ protected slots:
+ void formatChanged(int index);
+ void triggerImp();
+ void trigger(int) { triggerImp(); };
+ void addExtra(ExportToModList::OptionalData option);
+
+ private:
+ QString extension();
+ void enableCustom(bool enabled);
+ QList<Mod*> m_allMods;
+ bool m_template_changed;
+ QString name;
+ ExportToModList::Formats format = ExportToModList::Formats::HTML;
+ Ui::ExportToModListDialog* ui;
+ static const QHash<ExportToModList::Formats, QString> exampleLines;
+};
diff --git a/launcher/ui/dialogs/ExportToModListDialog.ui b/launcher/ui/dialogs/ExportToModListDialog.ui
new file mode 100644
index 00000000..25eb4342
--- /dev/null
+++ b/launcher/ui/dialogs/ExportToModListDialog.ui
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ExportToModListDialog</class>
+ <widget class="QDialog" name="ExportToModListDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>650</width>
+ <height>446</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Export Pack to ModList</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0">
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>Settings</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QComboBox" name="formatComboBox">
+ <item>
+ <property name="text">
+ <string>HTML</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Markdown</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Plaintext</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>JSON</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CSV</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Custom</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QGroupBox" name="templateGroup">
+ <property name="title">
+ <string>Template</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QTextEdit" name="templateText"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QGroupBox" name="optionsGroup">
+ <property name="title">
+ <string>Optional Info</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QCheckBox" name="versionCheckBox">
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="authorsCheckBox">
+ <property name="text">
+ <string>Authors</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="urlCheckBox">
+ <property name="text">
+ <string>URL</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="versionButton">
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="authorsButton">
+ <property name="text">
+ <string>Authors</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="urlButton">
+ <property name="text">
+ <string>URL</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="text">
+ <string>Format</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="title">
+ <string>Result</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPlainTextEdit" name="finalText">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>143</height>
+ </size>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="resultText">
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="warningLabel">
+ <property name="text">
+ <string>This depends on the mods' metadata. To ensure it is available, run an update on the instance. Installing the updates isn't necessary.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="copyButton">
+ <property name="text">
+ <string>Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ExportToModListDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>334</x>
+ <y>435</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>324</x>
+ <y>206</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ExportToModListDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>324</x>
+ <y>390</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>324</x>
+ <y>206</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
index 4f59f560..b17eced3 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
@@ -43,6 +43,8 @@
#include "ui/pages/modplatform/flame/FlameResourcePages.h"
#include "ui/pages/modplatform/modrinth/ModrinthResourcePages.h"
+#include "modplatform/flame/FlameAPI.h"
+#include "modplatform/modrinth/ModrinthAPI.h"
#include "ui/widgets/PageContainer.h"
namespace ResourceDownload {
@@ -281,8 +283,11 @@ QList<BasePage*> ModDownloadDialog::getPages()
{
QList<BasePage*> pages;
- pages.append(ModrinthModPage::create(this, *m_instance));
- if (APPLICATION->capabilities() & Application::SupportsFlame)
+ auto loaders = static_cast<MinecraftInstance*>(m_instance)->getPackProfile()->getModLoaders().value();
+
+ if (ModrinthAPI::validateModLoaders(loaders))
+ pages.append(ModrinthModPage::create(this, *m_instance));
+ if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders))
pages.append(FlameModPage::create(this, *m_instance));
m_selectedPage = dynamic_cast<ModPage*>(pages[0]);
diff --git a/launcher/ui/pages/instance/ManagedPackPage.cpp b/launcher/ui/pages/instance/ManagedPackPage.cpp
index d89c5bfc..0fc0c986 100644
--- a/launcher/ui/pages/instance/ManagedPackPage.cpp
+++ b/launcher/ui/pages/instance/ManagedPackPage.cpp
@@ -69,7 +69,6 @@ class NoBigComboBoxStyle : public QProxyStyle {
private:
NoBigComboBoxStyle(QStyle* style) : QProxyStyle(style) {}
-
};
ManagedPackPage* ManagedPackPage::createPage(BaseInstance* inst, QString type, QWidget* parent)
@@ -91,13 +90,13 @@ ManagedPackPage::ManagedPackPage(BaseInstance* inst, InstanceWindow* instance_wi
// NOTE: GTK2 themes crash with the proxy style.
// This seems like an upstream bug, so there's not much else that can be done.
- if (!QStyleFactory::keys().contains("gtk2")){
+ if (!QStyleFactory::keys().contains("gtk2")) {
auto comboStyle = NoBigComboBoxStyle::getInstance(ui->versionsComboBox->style());
ui->versionsComboBox->setStyle(comboStyle);
}
ui->reloadButton->setVisible(false);
- connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool){
+ connect(ui->reloadButton, &QPushButton::clicked, this, [this](bool) {
ui->reloadButton->setVisible(false);
m_loaded = false;
@@ -226,7 +225,8 @@ void ModrinthManagedPackPage::parseManagedPack()
QString id = m_inst->getManagedPackID();
- m_fetch_job->addNetAction(Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
+ m_fetch_job->addNetAction(
+ Net::Download::makeByteArray(QString("%1/project/%2/version").arg(BuildConfig.MODRINTH_PROD_URL, id), response));
QObject::connect(m_fetch_job.get(), &NetJob::succeeded, this, [this, response, id] {
QJsonParseError parse_error{};
@@ -267,7 +267,6 @@ void ModrinthManagedPackPage::parseManagedPack()
if (version.version == m_inst->getManagedPackVersionName())
name = tr("%1 (Current)").arg(name);
-
ui->versionsComboBox->addItem(name, QVariant(version.id));
}
@@ -291,6 +290,10 @@ QString ModrinthManagedPackPage::url() const
void ModrinthManagedPackPage::suggestVersion()
{
auto index = ui->versionsComboBox->currentIndex();
+ if (m_pack.versions.length() == 0) {
+ setFailState();
+ return;
+ }
auto version = m_pack.versions.at(index);
ui->changelogTextBrowser->setHtml(markdownToHTML(version.changelog.toUtf8()));
@@ -301,6 +304,10 @@ void ModrinthManagedPackPage::suggestVersion()
void ModrinthManagedPackPage::update()
{
auto index = ui->versionsComboBox->currentIndex();
+ if (m_pack.versions.length() == 0) {
+ setFailState();
+ return;
+ }
auto version = m_pack.versions.at(index);
QMap<QString, QString> extra_info;
@@ -429,6 +436,10 @@ QString FlameManagedPackPage::url() const
void FlameManagedPackPage::suggestVersion()
{
auto index = ui->versionsComboBox->currentIndex();
+ if (m_pack.versions.length() == 0) {
+ setFailState();
+ return;
+ }
auto version = m_pack.versions.at(index);
ui->changelogTextBrowser->setHtml(m_api.getModFileChangelog(m_inst->getManagedPackID().toInt(), version.fileId));
@@ -439,6 +450,10 @@ void FlameManagedPackPage::suggestVersion()
void FlameManagedPackPage::update()
{
auto index = ui->versionsComboBox->currentIndex();
+ if (m_pack.versions.length() == 0) {
+ setFailState();
+ return;
+ }
auto version = m_pack.versions.at(index);
QMap<QString, QString> extra_info;
diff --git a/launcher/ui/pages/modplatform/ResourcePage.cpp b/launcher/ui/pages/modplatform/ResourcePage.cpp
index aab2ee89..48afbd90 100644
--- a/launcher/ui/pages/modplatform/ResourcePage.cpp
+++ b/launcher/ui/pages/modplatform/ResourcePage.cpp
@@ -104,6 +104,7 @@ void ResourcePage::openedImpl()
updateSelectionButton();
triggerSearch();
+ m_ui->searchEdit->setFocus();
}
auto ResourcePage::eventFilter(QObject* watched, QEvent* event) -> bool
diff --git a/launcher/ui/widgets/LanguageSelectionWidget.cpp b/launcher/ui/widgets/LanguageSelectionWidget.cpp
index 256b09da..37d05347 100644
--- a/launcher/ui/widgets/LanguageSelectionWidget.cpp
+++ b/launcher/ui/widgets/LanguageSelectionWidget.cpp
@@ -1,16 +1,16 @@
#include "LanguageSelectionWidget.h"
-#include <QVBoxLayout>
-#include <QTreeView>
+#include <QCheckBox>
#include <QHeaderView>
#include <QLabel>
+#include <QTreeView>
+#include <QVBoxLayout>
#include "Application.h"
#include "BuildConfig.h"
-#include "translations/TranslationsModel.h"
#include "settings/Setting.h"
+#include "translations/TranslationsModel.h"
-LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) :
- QWidget(parent)
+LanguageSelectionWidget::LanguageSelectionWidget(QWidget* parent) : QWidget(parent)
{
verticalLayout = new QVBoxLayout(this);
verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
@@ -31,6 +31,13 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) :
helpUsLabel->setWordWrap(true);
verticalLayout->addWidget(helpUsLabel);
+ formatCheckbox = new QCheckBox(this);
+ formatCheckbox->setObjectName(QStringLiteral("formatCheckbox"));
+ formatCheckbox->setCheckState(APPLICATION->settings()->get("UseSystemLocale").toBool() ? Qt::Checked : Qt::Unchecked);
+ connect(formatCheckbox, &QCheckBox::stateChanged,
+ [this]() { APPLICATION->translations()->setUseSystemLocale(formatCheckbox->isChecked()); });
+ verticalLayout->addWidget(formatCheckbox);
+
auto translations = APPLICATION->translations();
auto index = translations->selectedIndex();
languageView->setModel(translations.get());
@@ -38,7 +45,7 @@ LanguageSelectionWidget::LanguageSelectionWidget(QWidget *parent) :
languageView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
languageView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageSelectionWidget::languageRowChanged);
- verticalLayout->setContentsMargins(0,0,0,0);
+ verticalLayout->setContentsMargins(0, 0, 0, 0);
auto language_setting = APPLICATION->settings()->getSetting("Language");
connect(language_setting.get(), &Setting::SettingChanged, this, &LanguageSelectionWidget::languageSettingChanged);
@@ -53,15 +60,14 @@ QString LanguageSelectionWidget::getSelectedLanguageKey() const
void LanguageSelectionWidget::retranslate()
{
QString text = tr("Don't see your language or the quality is poor?<br/><a href=\"%1\">Help us with translations!</a>")
- .arg(BuildConfig.TRANSLATIONS_URL);
+ .arg(BuildConfig.TRANSLATIONS_URL);
helpUsLabel->setText(text);
-
+ formatCheckbox->setText(tr("Use system locales"));
}
void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, const QModelIndex& previous)
{
- if (current == previous)
- {
+ if (current == previous) {
return;
}
auto translations = APPLICATION->translations();
@@ -70,7 +76,7 @@ void LanguageSelectionWidget::languageRowChanged(const QModelIndex& current, con
translations->updateLanguage(key);
}
-void LanguageSelectionWidget::languageSettingChanged(const Setting &, const QVariant)
+void LanguageSelectionWidget::languageSettingChanged(const Setting&, const QVariant)
{
auto translations = APPLICATION->translations();
auto index = translations->selectedIndex();
diff --git a/launcher/ui/widgets/LanguageSelectionWidget.h b/launcher/ui/widgets/LanguageSelectionWidget.h
index 4a88924c..5e86a288 100644
--- a/launcher/ui/widgets/LanguageSelectionWidget.h
+++ b/launcher/ui/widgets/LanguageSelectionWidget.h
@@ -21,23 +21,24 @@ class QVBoxLayout;
class QTreeView;
class QLabel;
class Setting;
+class QCheckBox;
-class LanguageSelectionWidget: public QWidget
-{
+class LanguageSelectionWidget : public QWidget {
Q_OBJECT
-public:
- explicit LanguageSelectionWidget(QWidget *parent = 0);
- virtual ~LanguageSelectionWidget() { };
+ public:
+ explicit LanguageSelectionWidget(QWidget* parent = 0);
+ virtual ~LanguageSelectionWidget(){};
QString getSelectedLanguageKey() const;
void retranslate();
-protected slots:
- void languageRowChanged(const QModelIndex &current, const QModelIndex &previous);
- void languageSettingChanged(const Setting &, const QVariant);
+ protected slots:
+ void languageRowChanged(const QModelIndex& current, const QModelIndex& previous);
+ void languageSettingChanged(const Setting&, const QVariant);
-private:
- QVBoxLayout *verticalLayout = nullptr;
- QTreeView *languageView = nullptr;
- QLabel *helpUsLabel = nullptr;
+ private:
+ QVBoxLayout* verticalLayout = nullptr;
+ QTreeView* languageView = nullptr;
+ QLabel* helpUsLabel = nullptr;
+ QCheckBox* formatCheckbox = nullptr;
};