diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 3ae3776fc..99e323a11 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1158,6 +1158,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/InstallLoaderDialog.h ui/dialogs/ChooseOfflineNameDialog.cpp ui/dialogs/ChooseOfflineNameDialog.h + ui/dialogs/ModToggleConfirmDialog.cpp + ui/dialogs/ModToggleConfirmDialog.h ui/dialogs/skins/SkinManageDialog.cpp ui/dialogs/skins/SkinManageDialog.h @@ -1331,6 +1333,7 @@ qt_wrap_ui(LAUNCHER_UI ui/dialogs/ChooseProviderDialog.ui ui/dialogs/skins/SkinManageDialog.ui ui/dialogs/ChooseOfflineNameDialog.ui + ui/dialogs/ModToggleConfirmDialog.ui ) qt_wrap_ui(PRISM_UPDATE_UI diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 43eba87d7..dc7166009 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -57,7 +57,7 @@ #include "minecraft/mod/ResourceFolderModel.h" #include "minecraft/mod/tasks/LocalModParseTask.h" #include "modplatform/ModIndex.h" -#include "ui/dialogs/CustomMessageBox.h" +#include "ui/dialogs/ModToggleConfirmDialog.h" ModFolderModel::ModFolderModel(const QDir& dir, BaseInstance* instance, bool is_indexed, bool create_dir, QObject* parent) : ResourceFolderModel(QDir(dir), instance, is_indexed, create_dir, parent) @@ -420,42 +420,13 @@ bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAc }; if (requiredToEnable.size() > 0 || requiredToDisable.size() > 0) { - QString title; - QString message; - QString noButton; - QString yesButton; - if (requiredToEnable.size() > 0 && requiredToDisable.size() > 0) { - title = tr("Confirm toggle"); - message = tr("Toggling these mod(s) will cause changes to other mods.\n") + - tr("%n mod(s) will be enabled\n", "", requiredToEnable.size()) + - tr("%n mod(s) will be disabled\n", "", requiredToDisable.size()) + - tr("Do you want to automatically apply these related changes?\nIgnoring them may break the game."); - noButton = tr("Only Toggle Selected"); - yesButton = tr("Toggle Required Mods"); - } else if (requiredToEnable.size() > 0) { - title = tr("Confirm enable"); - message = tr("The enabled mod(s) require %n mod(s).\n", "", requiredToEnable.size()) + - tr("Would you like to enable them as well?\nIgnoring them may break the game."); - noButton = tr("Only Enable Selected"); - yesButton = tr("Enable Required"); - } else { - title = tr("Confirm disable"); - message = tr("The disabled mod(s) are required by %n mod(s).\n", "", requiredToDisable.size()) + - tr("Would you like to disable them as well?\nIgnoring them may break the game."); - noButton = tr("Only Disable Selected"); - yesButton = tr("Disable Required"); - } - - auto box = CustomMessageBox::selectable(nullptr, title, message, QMessageBox::Warning, - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::No); - box->button(QMessageBox::No)->setText(noButton); - box->button(QMessageBox::Yes)->setText(yesButton); - auto response = box->exec(); + auto dialog = ModToggleConfirmDialog(nullptr, requiredToEnable, requiredToDisable); + auto response = dialog.exec(); if (response == QMessageBox::Yes) { toEnable |= requiredToEnable; toDisable |= requiredToDisable; - } else if (response == QMessageBox::Cancel) { + } else if ((response == QMessageBox::Cancel) || (response == QDialog::Rejected)) { return false; } } diff --git a/launcher/ui/dialogs/ModToggleConfirmDialog.cpp b/launcher/ui/dialogs/ModToggleConfirmDialog.cpp new file mode 100644 index 000000000..af4766272 --- /dev/null +++ b/launcher/ui/dialogs/ModToggleConfirmDialog.cpp @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include + +#include "ModToggleConfirmDialog.h" +#include "ui_ModToggleConfirmDialog.h" +#include "minecraft/mod/ModFolderModel.h" +// ToDo: remove these dirty hacks and change translation files +#include "ui/dialogs/CopyInstanceDialog.h" + +/** + * Dirty hack to use ModFolderModel context for translation + */ +static inline QString translate(const char *s, const char *c = nullptr, int n = -1) +{ + return ModFolderModel::staticMetaObject.tr(s, c, n).trimmed(); +} + +/** + * Even more dirty hack, because ModFolderModel doesn't have translation for "Cancel" button + */ +static inline QString translate_cancel(const char *s, const char *c = nullptr, int n = -1) +{ + return CopyInstanceDialog::staticMetaObject.tr(s, c, n); +} + +static QString formatMod(Mod* mod) +{ + return QString("- %1 (%2)").arg(mod->name(), mod->version()); +} + +ModToggleConfirmDialog::ModToggleConfirmDialog(QWidget* parent, QSet toEnable, QSet toDisable) + : QDialog(parent), ui(new Ui::ModToggleConfirmDialog) +{ + ui->setupUi(this); + resize(minimumSizeHint()); + + if (toEnable.size() > 0 && toDisable.size() > 0) { + setWindowTitle(translate("Confirm toggle")); + + ui->introLabel->setText(translate("Toggling these mod(s) will cause changes to other mods.\n")); + ui->toEnableLabel->setText(translate("%n mod(s) will be enabled\n", "", toEnable.size())); + ui->toDisableLabel->setText(translate("%n mod(s) will be disabled\n", "", toDisable.size())); + ui->questionLabel->setText(translate("Do you want to automatically apply these related changes?\nIgnoring them may break the game.")); + + ui->confirmButton->setText(translate("Toggle Required Mods")); + ui->rejectButton->setText(translate("Only Toggle Selected")); + } else if (toEnable.size() > 0) { + setWindowTitle(translate("Confirm enable")); + + ui->toEnableLabel->setText(translate("The enabled mod(s) require %n mod(s).\n", "", toEnable.size())); + ui->questionLabel->setText(translate("Would you like to enable them as well?\nIgnoring them may break the game.")); + + ui->confirmButton->setText(translate("Enable Required")); + ui->rejectButton->setText(translate("Only Enable Selected")); + } else { + setWindowTitle(translate("Confirm disable")); + + ui->toDisableLabel->setText(translate("The disabled mod(s) are required by %n mod(s).\n", "", toDisable.size())); + ui->questionLabel->setText(translate("Would you like to disable them as well?\nIgnoring them may break the game.")); + + ui->confirmButton->setText(translate("Disable Required")); + ui->rejectButton->setText(translate("Only Disable Selected")); + } + + ui->cancelButton->setText(translate_cancel("Cancel")); + + ui->confirmButton->setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton)); + ui->rejectButton->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton)); + ui->cancelButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton)); + + if (toEnable.size() > 0 || toDisable.size() > 0) + { + ui->introLabel->setVisible(false); + } + + if (toEnable.isEmpty()) + { + ui->toEnableLabel->setVisible(false); + ui->toEnableList->setVisible(false); + } + + for (auto mod : toEnable) + { + ui->toEnableList->addItem(formatMod(mod)); + } + + if (toDisable.isEmpty()) + { + ui->toDisableLabel->setVisible(false); + ui->toDisableList->setVisible(false); + } + + for (auto mod : toDisable) + { + ui->toDisableList->addItem(formatMod(mod)); + } + + connect(ui->confirmButton, &QPushButton::clicked, this, &ModToggleConfirmDialog::onAcceptButtonClicked); + connect(ui->rejectButton, &QPushButton::clicked, this, &ModToggleConfirmDialog::onRejectButtonClicked); + connect(ui->cancelButton, &QPushButton::clicked, this, &ModToggleConfirmDialog::onCancelButtonClicked); +} + +ModToggleConfirmDialog::~ModToggleConfirmDialog() +{ + delete ui; +} + +void ModToggleConfirmDialog::onAcceptButtonClicked() +{ + done(QMessageBox::Yes); +} + +void ModToggleConfirmDialog::onRejectButtonClicked() +{ + done(QMessageBox::No); +} + +void ModToggleConfirmDialog::onCancelButtonClicked() +{ + done(QMessageBox::Cancel); +} diff --git a/launcher/ui/dialogs/ModToggleConfirmDialog.h b/launcher/ui/dialogs/ModToggleConfirmDialog.h new file mode 100644 index 000000000..c36529851 --- /dev/null +++ b/launcher/ui/dialogs/ModToggleConfirmDialog.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#include "minecraft/mod/Mod.h" + +namespace Ui { +class ModToggleConfirmDialog; +} + +/** + * Custom MessageBox for displaying affected mods by other mods toggle. + */ +class ModToggleConfirmDialog : public QDialog { + Q_OBJECT + + public: + ModToggleConfirmDialog(QWidget* parent, QSet toEnable, QSet toDisable); + ~ModToggleConfirmDialog(); + + private slots: + void onAcceptButtonClicked(); + void onRejectButtonClicked(); + void onCancelButtonClicked(); + + private: + Ui::ModToggleConfirmDialog* ui; +}; diff --git a/launcher/ui/dialogs/ModToggleConfirmDialog.ui b/launcher/ui/dialogs/ModToggleConfirmDialog.ui new file mode 100644 index 000000000..6b8962e79 --- /dev/null +++ b/launcher/ui/dialogs/ModToggleConfirmDialog.ui @@ -0,0 +1,265 @@ + + + ModToggleConfirmDialog + + + + 0 + 0 + 494 + 416 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Confirm toggle + + + + + + + + + + 0 + 0 + + + + Toggling these mod(s) will cause changes to other mods. + + + Qt::TextFormat::PlainText + + + true + + + + + + + + 0 + 0 + + + + %n mod(s) will be enabled + + + Qt::TextFormat::PlainText + + + true + + + + + + + + 0 + 0 + + + + QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents + + + QAbstractItemView::EditTrigger::NoEditTriggers + + + false + + + QAbstractItemView::DragDropMode::NoDragDrop + + + Qt::DropAction::IgnoreAction + + + true + + + QAbstractItemView::SelectionMode::NoSelection + + + QAbstractItemView::ScrollMode::ScrollPerPixel + + + QAbstractItemView::ScrollMode::ScrollPerPixel + + + QListView::Movement::Free + + + QListView::ResizeMode::Adjust + + + Qt::DropAction::IgnoreAction + + + + + + + + 0 + 0 + + + + %n mod(s) will be disabled + + + Qt::TextFormat::PlainText + + + true + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents + + + true + + + QAbstractItemView::EditTrigger::NoEditTriggers + + + false + + + QAbstractItemView::DragDropMode::NoDragDrop + + + Qt::DropAction::IgnoreAction + + + true + + + QAbstractItemView::SelectionMode::NoSelection + + + QAbstractItemView::ScrollMode::ScrollPerPixel + + + QAbstractItemView::ScrollMode::ScrollPerPixel + + + QListView::Movement::Free + + + QListView::ResizeMode::Adjust + + + Qt::DropAction::IgnoreAction + + + + + + + Qt::Orientation::Vertical + + + + 20 + 16 + + + + + + + + + 0 + 0 + + + + Do you want to automatically apply these related changes? +Ignoring them may break the game. + + + Qt::TextFormat::PlainText + + + true + + + + + + + + + Toggle Required Mods + + + + + + + Only Toggle Selected + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + + + +