diff options
Diffstat (limited to 'launcher/ui/dialogs')
-rw-r--r-- | launcher/ui/dialogs/ExportToModListDialog.cpp | 223 | ||||
-rw-r--r-- | launcher/ui/dialogs/ExportToModListDialog.h | 55 | ||||
-rw-r--r-- | launcher/ui/dialogs/ExportToModListDialog.ui | 240 |
3 files changed, 518 insertions, 0 deletions
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> |