diff options
Diffstat (limited to 'launcher/ui')
23 files changed, 447 insertions, 118 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index d58f158e..299401f5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -252,6 +252,9 @@ public: TranslatedAction actionViewInstanceFolder; TranslatedAction actionViewCentralModsFolder; + QMenu * editMenu = nullptr; + TranslatedAction actionUndoTrashInstance; + QMenu * helpMenu = nullptr; TranslatedToolButton helpMenuButton; TranslatedAction actionReportBug; @@ -335,6 +338,14 @@ public: actionSettings->setShortcut(QKeySequence::Preferences); all_actions.append(&actionSettings); + actionUndoTrashInstance = TranslatedAction(MainWindow); + connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), MainWindow, SLOT(undoTrashInstance())); + actionUndoTrashInstance->setObjectName(QStringLiteral("actionUndoTrashInstance")); + actionUndoTrashInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Undo Last Instance Deletion")); + actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); + actionUndoTrashInstance->setShortcut(QKeySequence("Ctrl+Z")); + all_actions.append(&actionUndoTrashInstance); + if (!BuildConfig.BUG_TRACKER_URL.isEmpty()) { actionReportBug = TranslatedAction(MainWindow); actionReportBug->setObjectName(QStringLiteral("actionReportBug")); @@ -508,6 +519,9 @@ public: fileMenu->addSeparator(); fileMenu->addAction(actionSettings); + editMenu = menuBar->addMenu(tr("&Edit")); + editMenu->addAction(actionUndoTrashInstance); + viewMenu = menuBar->addMenu(tr("&View")); viewMenu->setSeparatorsCollapsible(false); viewMenu->addAction(actionCAT); @@ -732,9 +746,10 @@ public: actionDeleteInstance = TranslatedAction(MainWindow); actionDeleteInstance->setObjectName(QStringLiteral("actionDeleteInstance")); - actionDeleteInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Dele&te Instance...")); + actionDeleteInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Dele&te Instance")); actionDeleteInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Delete the selected instance.")); actionDeleteInstance->setShortcuts({QKeySequence(tr("Backspace")), QKeySequence::Delete}); + actionDeleteInstance->setAutoRepeat(false); all_actions.append(&actionDeleteInstance); actionCopyInstance = TranslatedAction(MainWindow); @@ -1150,6 +1165,11 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos) connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(deleteGroup())); actions.append(actionDeleteGroup); } + + QAction *actionUndoTrashInstance = new QAction("Undo last trash instance", this); + connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), SLOT(undoTrashInstance())); + actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); + actions.append(actionUndoTrashInstance); } QMenu myMenu; myMenu.addActions(actions); @@ -1445,6 +1465,7 @@ void MainWindow::updateNewsLabel() { newsLabel->setText(tr("Loading news...")); newsLabel->setEnabled(false); + ui->actionMoreNews->setVisible(false); } else { @@ -1453,11 +1474,13 @@ void MainWindow::updateNewsLabel() { newsLabel->setText(entries[0]->title); newsLabel->setEnabled(true); + ui->actionMoreNews->setVisible(true); } else { newsLabel->setText(tr("No news available.")); newsLabel->setEnabled(false); + ui->actionMoreNews->setVisible(false); } } } @@ -1832,6 +1855,11 @@ void MainWindow::deleteGroup() } } +void MainWindow::undoTrashInstance() +{ + APPLICATION->instances()->undoTrashInstance(); +} + void MainWindow::on_actionViewInstanceFolder_triggered() { QString str = APPLICATION->settings()->get("InstanceDir").toString(); @@ -1957,7 +1985,12 @@ void MainWindow::on_actionDeleteInstance_triggered() { return; } + auto id = m_selectedInstance->id(); + if (APPLICATION->instances()->trashInstance(id)) { + return; + } + auto response = CustomMessageBox::selectable( this, tr("CAREFUL!"), diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index d7930b5a..dde3d02c 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -145,6 +145,7 @@ private slots: void on_actionDeleteInstance_triggered(); void deleteGroup(); + void undoTrashInstance(); void on_actionExportInstance_triggered(); diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp index c5367d5b..743c34f1 100644 --- a/launcher/ui/dialogs/AboutDialog.cpp +++ b/launcher/ui/dialogs/AboutDialog.cpp @@ -147,10 +147,15 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia else ui->platformLabel->setVisible(false); - if (BuildConfig.VERSION_BUILD >= 0) - ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD)); + if (!BuildConfig.GIT_COMMIT.isEmpty()) + ui->commitLabel->setText(tr("Commit: %1").arg(BuildConfig.GIT_COMMIT)); else - ui->buildNumLabel->setVisible(false); + ui->commitLabel->setVisible(false); + + if (!BuildConfig.BUILD_DATE.isEmpty()) + ui->buildDateLabel->setText(tr("Build date: %1").arg(BuildConfig.BUILD_DATE)); + else + ui->buildDateLabel->setVisible(false); if (!BuildConfig.VERSION_CHANNEL.isEmpty()) ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL); diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui index 6323992b..6eaa0c4e 100644 --- a/launcher/ui/dialogs/AboutDialog.ui +++ b/launcher/ui/dialogs/AboutDialog.ui @@ -184,12 +184,28 @@ </widget> </item> <item> - <widget class="QLabel" name="buildNumLabel"> + <widget class="QLabel" name="buildDateLabel"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> </property> <property name="text"> - <string>Build Number:</string> + <string>Build Date:</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="commitLabel"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>Commit:</string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp new file mode 100644 index 00000000..fe87b517 --- /dev/null +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -0,0 +1,28 @@ +#include "BlockedModsDialog.h" +#include "ui_BlockedModsDialog.h" +#include <QPushButton> +#include <QDialogButtonBox> +#include <QDesktopServices> + + +BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls) : + QDialog(parent), ui(new Ui::BlockedModsDialog), urls(urls) { + ui->setupUi(this); + + auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); + connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); + + this->setWindowTitle(title); + ui->label->setText(text); + ui->textBrowser->setText(body); +} + +BlockedModsDialog::~BlockedModsDialog() { + delete ui; +} + +void BlockedModsDialog::openAll() { + for(auto &url : urls) { + QDesktopServices::openUrl(url); + } +} diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h new file mode 100644 index 00000000..5f5bd61b --- /dev/null +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -0,0 +1,22 @@ +#pragma once + +#include <QDialog> + + +QT_BEGIN_NAMESPACE +namespace Ui { class BlockedModsDialog; } +QT_END_NAMESPACE + +class BlockedModsDialog : public QDialog { +Q_OBJECT + +public: + BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls); + + ~BlockedModsDialog() override; + +private: + Ui::BlockedModsDialog *ui; + const QList<QUrl> &urls; + void openAll(); +}; diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui new file mode 100644 index 00000000..f4ae95b6 --- /dev/null +++ b/launcher/ui/dialogs/BlockedModsDialog.ui @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>BlockedModsDialog</class> + <widget class="QDialog" name="BlockedModsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>455</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true">BlockedModsDialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textFormat"> + <enum>Qt::RichText</enum> + </property> + </widget> + </item> + <item row="2" column="0"> + <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> + <item row="1" column="0"> + <widget class="QTextBrowser" name="textBrowser"> + <property name="acceptRichText"> + <bool>true</bool> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>BlockedModsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>199</x> + <y>425</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>227</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>BlockedModsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>199</x> + <y>425</y> + </hint> + <hint type="destinationlabel"> + <x>199</x> + <y>227</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/launcher/ui/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp index 194315a7..30394b72 100644 --- a/launcher/ui/dialogs/LoginDialog.cpp +++ b/launcher/ui/dialogs/LoginDialog.cpp @@ -115,5 +115,5 @@ MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg) { return dlg.m_account; } - return 0; + return nullptr; } diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index b11b6980..be49babb 100644 --- a/launcher/ui/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp @@ -169,5 +169,5 @@ MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg) { return dlg.m_account; } - return 0; + return nullptr; } diff --git a/launcher/ui/dialogs/OfflineLoginDialog.cpp b/launcher/ui/dialogs/OfflineLoginDialog.cpp index 4f3d8be4..a69537ab 100644 --- a/launcher/ui/dialogs/OfflineLoginDialog.cpp +++ b/launcher/ui/dialogs/OfflineLoginDialog.cpp @@ -103,5 +103,5 @@ MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget *parent, QString msg) { return dlg.m_account; } - return 0; + return nullptr; } diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp index a79bc837..3c7f53d3 100644 --- a/launcher/ui/dialogs/ProgressDialog.cpp +++ b/launcher/ui/dialogs/ProgressDialog.cpp @@ -43,8 +43,8 @@ void ProgressDialog::setSkipButton(bool present, QString label) void ProgressDialog::on_skipButton_clicked(bool checked) { Q_UNUSED(checked); - task->abort(); - QDialog::reject(); + if (task->abort()) + QDialog::reject(); } ProgressDialog::~ProgressDialog() diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index d06f412b..39fbe3e2 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -32,13 +32,13 @@ class SortProxy : public QSortFilterProxyModel { const auto& mod = model->at(source_row); - if (mod.name().contains(filterRegularExpression())) + if (filterRegularExpression().match(mod.name()).hasMatch()) return true; - if (mod.description().contains(filterRegularExpression())) + if (filterRegularExpression().match(mod.description()).hasMatch()) return true; for (auto& author : mod.authors()) { - if (author.contains(filterRegularExpression())) { + if (filterRegularExpression().match(author).hasMatch()) { return true; } } @@ -101,7 +101,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared { ui->setupUi(this); - runningStateChanged(m_instance && m_instance->isRunning()); + ExternalResourcesPage::runningStateChanged(m_instance && m_instance->isRunning()); ui->actionsToolbar->insertSpacer(ui->actionViewConfigs); @@ -182,7 +182,7 @@ void ExternalResourcesPage::retranslate() void ExternalResourcesPage::filterTextChanged(const QString& newContents) { m_viewFilter = newContents; - m_filterModel->setFilterFixedString(m_viewFilter); + m_filterModel->setFilterRegularExpression(m_viewFilter); } void ExternalResourcesPage::runningStateChanged(bool running) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.h b/launcher/ui/pages/instance/ExternalResourcesPage.h index 41237139..ff294678 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.h +++ b/launcher/ui/pages/instance/ExternalResourcesPage.h @@ -46,7 +46,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage { protected slots: void itemActivated(const QModelIndex& index); void filterTextChanged(const QString& newContents); - void runningStateChanged(bool running); + virtual void runningStateChanged(bool running); virtual void addItem(); virtual void removeItem(); diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 14e1f1e5..45678db1 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -84,49 +84,44 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods); - connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, - [this] { ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); }); + auto check_allow_update = [this] { + return (!m_instance || !m_instance->isRunning()) && + (ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); + }; - connect(mods.get(), &ModFolderModel::rowsInserted, this, - [this] { ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); }); - - connect(mods.get(), &ModFolderModel::updateFinished, this, [this, mods] { - ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); + connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { + ui->actionUpdateItem->setEnabled(check_allow_update()); + }); + + connect(mods.get(), &ModFolderModel::rowsInserted, this, [this, check_allow_update] { + ui->actionUpdateItem->setEnabled(check_allow_update()); + }); + + connect(mods.get(), &ModFolderModel::rowsRemoved, this, [this, check_allow_update] { + ui->actionUpdateItem->setEnabled(check_allow_update()); + }); + + connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update, mods] { + ui->actionUpdateItem->setEnabled(check_allow_update()); // Prevent a weird crash when trying to open the mods page twice in a session o.O disconnect(mods.get(), &ModFolderModel::updateFinished, this, 0); }); + + ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning()); } } -CoreModFolderPage::CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent) - : ModFolderPage(inst, mods, parent) -{} - -bool ModFolderPage::shouldDisplay() const +void ModFolderPage::runningStateChanged(bool running) { - return true; + ExternalResourcesPage::runningStateChanged(running); + ui->actionDownloadItem->setEnabled(!running); + ui->actionUpdateItem->setEnabled(!running); } -bool CoreModFolderPage::shouldDisplay() const +bool ModFolderPage::shouldDisplay() const { - if (ModFolderPage::shouldDisplay()) { - auto inst = dynamic_cast<MinecraftInstance*>(m_instance); - if (!inst) - return true; - - auto version = inst->getPackProfile(); - - if (!version) - return true; - if (!version->getComponent("net.minecraftforge")) - return false; - if (!version->getComponent("net.minecraft")) - return false; - if (version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate) - return true; - } - return false; + return true; } void ModFolderPage::installMods() @@ -232,3 +227,28 @@ void ModFolderPage::updateMods() m_model->update(); } } + +CoreModFolderPage::CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent) + : ModFolderPage(inst, mods, parent) +{} + +bool CoreModFolderPage::shouldDisplay() const +{ + if (ModFolderPage::shouldDisplay()) { + auto inst = dynamic_cast<MinecraftInstance*>(m_instance); + if (!inst) + return true; + + auto version = inst->getPackProfile(); + + if (!version) + return true; + if (!version->getComponent("net.minecraftforge")) + return false; + if (!version->getComponent("net.minecraft")) + return false; + if (version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate) + return true; + } + return false; +} diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 0a7fc9fa..7e305951 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -53,6 +53,7 @@ class ModFolderPage : public ExternalResourcesPage { virtual QString helpPage() const override { return "Loader-mods"; } virtual bool shouldDisplay() const override; + void runningStateChanged(bool running) override; private slots: void installMods(); @@ -63,5 +64,11 @@ class CoreModFolderPage : public ModFolderPage { public: explicit CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent = 0); virtual ~CoreModFolderPage() = default; - virtual bool shouldDisplay() const; + + virtual QString displayName() const override { return tr("Core mods"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("coremods"); } + virtual QString id() const override { return "coremods"; } + virtual QString helpPage() const override { return "Core-mods"; } + + virtual bool shouldDisplay() const override; }; diff --git a/launcher/ui/pages/instance/WorldListPage.cpp b/launcher/ui/pages/instance/WorldListPage.cpp index 647b04a7..85cc01ff 100644 --- a/launcher/ui/pages/instance/WorldListPage.cpp +++ b/launcher/ui/pages/instance/WorldListPage.cpp @@ -211,7 +211,7 @@ void WorldListPage::on_actionDatapacks_triggered() return; } - if(!worldSafetyNagQuestion()) + if(!worldSafetyNagQuestion(tr("Open World Datapacks Folder"))) return; auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString(); @@ -269,7 +269,7 @@ void WorldListPage::on_actionMCEdit_triggered() return; } - if(!worldSafetyNagQuestion()) + if(!worldSafetyNagQuestion(tr("Open World in MCEdit"))) return; auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString(); @@ -373,11 +373,11 @@ bool WorldListPage::isWorldSafe(QModelIndex) return !m_inst->isRunning(); } -bool WorldListPage::worldSafetyNagQuestion() +bool WorldListPage::worldSafetyNagQuestion(const QString &actionType) { if(!isWorldSafe(getSelectedWorld())) { - auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?")); + auto result = QMessageBox::question(this, actionType, tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?")); if(result == QMessageBox::No) { return false; @@ -395,7 +395,7 @@ void WorldListPage::on_actionCopy_triggered() return; } - if(!worldSafetyNagQuestion()) + if(!worldSafetyNagQuestion(tr("Copy World"))) return; auto worldVariant = m_worlds->data(index, WorldList::ObjectRole); @@ -417,7 +417,7 @@ void WorldListPage::on_actionRename_triggered() return; } - if(!worldSafetyNagQuestion()) + if(!worldSafetyNagQuestion(tr("Rename World"))) return; auto worldVariant = m_worlds->data(index, WorldList::ObjectRole); diff --git a/launcher/ui/pages/instance/WorldListPage.h b/launcher/ui/pages/instance/WorldListPage.h index 17e36a08..1dc9e53e 100644 --- a/launcher/ui/pages/instance/WorldListPage.h +++ b/launcher/ui/pages/instance/WorldListPage.h @@ -93,7 +93,7 @@ protected: private: QModelIndex getSelectedWorld(); bool isWorldSafe(QModelIndex index); - bool worldSafetyNagQuestion(); + bool worldSafetyNagQuestion(const QString &actionType); void mceditError(); private: diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp index 8de5211c..7901b90b 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp @@ -37,13 +37,12 @@ #include "AtlPage.h" #include "ui_AtlPage.h" -#include "modplatform/atlauncher/ATLPackInstallTask.h" +#include "BuildConfig.h" #include "AtlOptionalModDialog.h" +#include "AtlUserInteractionSupportImpl.h" +#include "modplatform/atlauncher/ATLPackInstallTask.h" #include "ui/dialogs/NewInstanceDialog.h" -#include "ui/dialogs/VersionSelectDialog.h" - -#include <BuildConfig.h> #include <QMessageBox> @@ -117,7 +116,9 @@ void AtlPage::suggestCurrent() return; } - dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ATLauncher::PackInstallTask(this, selected.name, selectedVersion)); + auto uiSupport = new AtlUserInteractionSupportImpl(this); + dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ATLauncher::PackInstallTask(uiSupport, selected.name, selectedVersion)); + auto editedLogoName = selected.safeName; auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(selected.safeName.toLower()); listModel->getLogo(selected.safeName, url, [this, editedLogoName](QString logo) @@ -172,51 +173,3 @@ void AtlPage::onVersionSelectionChanged(QString data) selectedVersion = data; suggestCurrent(); } - -QVector<QString> AtlPage::chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) -{ - AtlOptionalModDialog optionalModDialog(this, version, mods); - optionalModDialog.exec(); - return optionalModDialog.getResult(); -} - -QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { - VersionSelectDialog vselect(vlist.get(), "Choose Version", APPLICATION->activeWindow(), false); - if (minecraftVersion != Q_NULLPTR) { - vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); - vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); - } - else { - vselect.setEmptyString(tr("No versions are currently available")); - } - vselect.setEmptyErrorString(tr("Couldn't load or download the version lists!")); - - // select recommended build - for (int i = 0; i < vlist->versions().size(); i++) { - auto version = vlist->versions().at(i); - auto reqs = version->requires(); - - // filter by minecraft version, if the loader depends on a certain version. - if (minecraftVersion != Q_NULLPTR) { - auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) { - return req.uid == "net.minecraft"; - }); - if (iter == reqs.end()) continue; - if (iter->equalsVersion != minecraftVersion) continue; - } - - // first recommended build we find, we use. - if (version->isRecommended()) { - vselect.setCurrentVersion(version->descriptor()); - break; - } - } - - vselect.exec(); - return vselect.selectedVersion()->descriptor(); -} - -void AtlPage::displayMessage(QString message) -{ - QMessageBox::information(this, tr("Installing"), message); -} diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h index aa6d5da1..1b3b15c1 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h +++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h @@ -52,7 +52,7 @@ namespace Ui class NewInstanceDialog; -class AtlPage : public QWidget, public BasePage, public ATLauncher::UserInteractionSupport +class AtlPage : public QWidget, public BasePage { Q_OBJECT @@ -83,10 +83,6 @@ public: private: void suggestCurrent(); - QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; - QVector<QString> chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) override; - void displayMessage(QString message) override; - private slots: void triggerSearch(); diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp new file mode 100644 index 00000000..03196685 --- /dev/null +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> + * + * 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/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org> + * + * 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 <QMessageBox> +#include "AtlUserInteractionSupportImpl.h" + +#include "AtlOptionalModDialog.h" +#include "ui/dialogs/VersionSelectDialog.h" + +AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget *parent) : m_parent(parent) +{ +} + +QVector<QString> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) +{ + AtlOptionalModDialog optionalModDialog(m_parent, version, mods); + optionalModDialog.exec(); + return optionalModDialog.getResult(); +} + +QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) +{ + VersionSelectDialog vselect(vlist.get(), "Choose Version", m_parent, false); + if (minecraftVersion != nullptr) { + vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); + vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); + } + else { + vselect.setEmptyString(tr("No versions are currently available")); + } + vselect.setEmptyErrorString(tr("Couldn't load or download the version lists!")); + + // select recommended build + for (int i = 0; i < vlist->versions().size(); i++) { + auto version = vlist->versions().at(i); + auto reqs = version->requires(); + + // filter by minecraft version, if the loader depends on a certain version. + if (minecraftVersion != nullptr) { + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require& req) { + return req.uid == "net.minecraft"; + }); + if (iter == reqs.end()) + continue; + if (iter->equalsVersion != minecraftVersion) + continue; + } + + // first recommended build we find, we use. + if (version->isRecommended()) { + vselect.setCurrentVersion(version->descriptor()); + break; + } + } + + vselect.exec(); + return vselect.selectedVersion()->descriptor(); +} + +void AtlUserInteractionSupportImpl::displayMessage(QString message) +{ + QMessageBox::information(m_parent, tr("Installing"), message); +} diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h new file mode 100644 index 00000000..aa22fc73 --- /dev/null +++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * PolyMC - Minecraft Launcher + * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> + * + * 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/>. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org> + * + * 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 <QObject> + +#include "modplatform/atlauncher/ATLPackInstallTask.h" + +class AtlUserInteractionSupportImpl : public QObject, public ATLauncher::UserInteractionSupport { + Q_OBJECT + +public: + AtlUserInteractionSupportImpl(QWidget* parent); + +private: + QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; + QVector<QString> chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) override; + void displayMessage(QString message) override; + +private: + QWidget* m_parent; + +}; diff --git a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp index 8a93bc2e..504d7f7b 100644 --- a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp +++ b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield <jmansfield@cadixdev.org> + * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> * * 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 @@ -126,7 +127,7 @@ void FtbPage::suggestCurrent() return; } - dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ModpacksCH::PackInstallTask(selected, selectedVersion)); + dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ModpacksCH::PackInstallTask(selected, selectedVersion, this)); for(auto art : selected.art) { if(art.type == "square") { QString editedLogoName; diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.ui b/launcher/ui/pages/modplatform/legacy_ftb/Page.ui index f4231d8d..ad08dc25 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/Page.ui +++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.ui @@ -35,7 +35,11 @@ </widget> </item> <item row="0" column="1"> - <widget class="QTextBrowser" name="publicPackDescription"/> + <widget class="QTextBrowser" name="publicPackDescription"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> </item> </layout> </widget> @@ -45,7 +49,11 @@ </attribute> <layout class="QGridLayout" name="gridLayout_3"> <item row="0" column="1"> - <widget class="QTextBrowser" name="thirdPartyPackDescription"/> + <widget class="QTextBrowser" name="thirdPartyPackDescription"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> </item> <item row="0" column="0"> <widget class="QTreeView" name="thirdPartyPackList"> @@ -95,7 +103,11 @@ </widget> </item> <item row="0" column="1" rowspan="3"> - <widget class="QTextBrowser" name="privatePackDescription"/> + <widget class="QTextBrowser" name="privatePackDescription"> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> </item> </layout> </widget> |