From 35750ebada9dffdd63176e91ae8198bd6383c967 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 19 Nov 2025 22:50:24 +0200 Subject: [PATCH] update toggle message box Signed-off-by: Trial97 --- launcher/minecraft/mod/ModFolderModel.cpp | 82 +++--- launcher/ui/pages/instance/ModFolderPage.cpp | 2 +- launcher/ui/widgets/InfoFrame.cpp | 110 +++----- launcher/ui/widgets/InfoFrame.h | 4 +- launcher/ui/widgets/InfoFrame.ui | 258 +++++++------------ 5 files changed, 189 insertions(+), 267 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 2bcbf1fcb..2c15f30f4 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -278,6 +278,9 @@ void ModFolderModel::onParseFinished() auto modsList = allMods(); auto mods = QSet(modsList.begin(), modsList.end()); + m_requires.clear(); + m_requiredBy.clear(); + auto findByProjectID = [mods](QVariant modId, ModPlatform::ResourceProvider provider) -> Mod* { auto found = std::find_if(mods.begin(), mods.end(), [modId, provider](Mod* m) { return m->metadata() && m->metadata()->provider == provider && m->metadata()->project_id == modId; @@ -314,9 +317,10 @@ void ModFolderModel::onParseFinished() } } -QSet collectMods(QSet mods, QHash> relation, std::set& seen) +QSet collectMods(QSet mods, QHash> relation, std::set& seen, bool shouldBeEnabled) { QSet affectedList = {}; + QSet needToCheck = {}; for (auto mod : mods) { auto id = mod->mod_id(); if (seen.count(id) == 0) { @@ -326,14 +330,17 @@ QSet collectMods(QSet mods, QHash> relation, std if (findById(mods, affectedId) == nullptr && seen.count(affectedId) == 0) { seen.insert(affectedId); - affectedList << affected; + if (shouldBeEnabled != affected->enabled()) { + affectedList << affected; + } + needToCheck << affected; } } } } // collect the affected mods until all of them are included in the list - if (!affectedList.isEmpty()) { - affectedList += collectMods(affectedList, relation, seen); + if (!needToCheck.isEmpty()) { + affectedList += collectMods(needToCheck, relation, seen, shouldBeEnabled); } return affectedList; } @@ -350,24 +357,21 @@ QModelIndexList ModFolderModel::getAffectedMods(const QModelIndexList& indexes, switch (action) { case EnableAction::ENABLE: { - affectedMods = collectMods(affectedMods, m_requires, seen); + affectedMods = collectMods(affectedMods, m_requires, seen, true); break; } case EnableAction::DISABLE: { - affectedMods = collectMods(affectedMods, m_requiredBy, seen); + affectedMods = collectMods(affectedMods, m_requiredBy, seen, false); break; } case EnableAction::TOGGLE: { return {}; // this function should not be called with TOGGLE } } - bool shouldBeEnabled = action == EnableAction::ENABLE; for (auto affected : affectedMods) { auto affectedId = affected->mod_id(); - if (shouldBeEnabled != affected->enabled()) { - auto row = m_resources_index[affected->internal_id()]; - affectedList << index(row, 0); - } + auto row = m_resources_index[affected->internal_id()]; + affectedList << index(row, 0); } return affectedList; } @@ -377,7 +381,6 @@ bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAc if (indexes.isEmpty()) return {}; - QModelIndexList affectedList = {}; auto indexedModsList = selectedMods(indexes); auto indexedMods = QSet(indexedModsList.begin(), indexedModsList.end()); @@ -406,31 +409,50 @@ bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAc } } - auto requiredToEnable = collectMods(toEnable, m_requires, seen); - auto requiredToDisable = collectMods(toDisable, m_requiredBy, seen); + auto requiredToEnable = collectMods(toEnable, m_requires, seen, true); + auto requiredToDisable = collectMods(toDisable, m_requiredBy, seen, false); toDisable.removeIf([toEnable](Mod* m) { return toEnable.contains(m); }); - auto toList = [this](QSet mods, bool shouldBeEnabled) { + auto toList = [this](QSet mods) { QModelIndexList list; for (auto mod : mods) { - if (shouldBeEnabled != mod->enabled()) { - auto row = m_resources_index[mod->internal_id()]; - list << index(row, 0); - } + auto row = m_resources_index[mod->internal_id()]; + list << index(row, 0); } return list; }; if (requiredToEnable.size() > 0 || requiredToDisable.size() > 0) { - auto box = CustomMessageBox::selectable( - nullptr, tr("Confirm toggle"), - tr("Toggling this mod(s) will cause changes to other mods.\n") + - (requiredToEnable.size() > 0 ? tr("%1 mod(s) will be enabled\n").arg(requiredToEnable.size()) : "") + - (requiredToDisable.size() > 0 ? tr("%1 mod(s) will be disabled\n").arg(requiredToDisable.size()) : "") + - tr("Do you want to automatically apply these related changes?\nIgnoring them may break the game."), - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::No); - auto b = box->button(QMessageBox::No); - b->setText(tr("No, just toggle selected")); + QString title; + QString message; + QString noButton; + QString yesButton; + if (requiredToEnable.size() > 0 && requiredToDisable.size() > 0) { + title = tr("Confirm toggle"); + message = tr("Toggling this mod(s) will cause changes to other mods.\n") + + tr("%n mod(s) will be enabled\n").arg(requiredToEnable.size()) + + tr("%n mod(s) will be disabled\n").arg(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 additional mod(s)\n").arg(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 additional mod(s)\n").arg(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(); if (response == QMessageBox::Yes) { @@ -441,8 +463,8 @@ bool ModFolderModel::setResourceEnabled(const QModelIndexList& indexes, EnableAc } } - auto disableStatus = ResourceFolderModel::setResourceEnabled(toList(toDisable, false), EnableAction::DISABLE); - auto enableStatus = ResourceFolderModel::setResourceEnabled(toList(toEnable, true), EnableAction::ENABLE); + auto disableStatus = ResourceFolderModel::setResourceEnabled(toList(toDisable), EnableAction::DISABLE); + auto enableStatus = ResourceFolderModel::setResourceEnabled(toList(toEnable), EnableAction::ENABLE); return disableStatus && enableStatus; } diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index dbfabdec3..8ea2b7be8 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -122,7 +122,7 @@ void ModFolderPage::updateFrame(const QModelIndex& current, [[maybe_unused]] con auto sourceCurrent = m_filterModel->mapToSource(current); int row = sourceCurrent.row(); const Mod& mod = m_model->at(row); - ui->frame->updateWithMod(mod, m_model->requiresList(mod.mod_id()), m_model->requiredByList(mod.mod_id())); + ui->frame->updateWithMod(mod); } void ModFolderPage::removeItems(const QItemSelection& selection) diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp index cab2889ac..2363b6592 100644 --- a/launcher/ui/widgets/InfoFrame.cpp +++ b/launcher/ui/widgets/InfoFrame.cpp @@ -54,34 +54,28 @@ void setupLinkToolTip(QLabel* label) }); } -InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), m_ui(new Ui::InfoFrame) +InfoFrame::InfoFrame(QWidget* parent) : QFrame(parent), ui(new Ui::InfoFrame) { - m_ui->setupUi(this); - m_ui->descriptionLabel->setHidden(true); - m_ui->nameLabel->setHidden(true); - m_ui->licenseLabel->setHidden(true); - m_ui->issueTrackerLabel->setHidden(true); + ui->setupUi(this); + ui->descriptionLabel->setHidden(true); + ui->nameLabel->setHidden(true); + ui->licenseLabel->setHidden(true); + ui->issueTrackerLabel->setHidden(true); - setupLinkToolTip(m_ui->iconLabel); - setupLinkToolTip(m_ui->descriptionLabel); - setupLinkToolTip(m_ui->nameLabel); - setupLinkToolTip(m_ui->licenseLabel); - setupLinkToolTip(m_ui->issueTrackerLabel); + setupLinkToolTip(ui->iconLabel); + setupLinkToolTip(ui->descriptionLabel); + setupLinkToolTip(ui->nameLabel); + setupLinkToolTip(ui->licenseLabel); + setupLinkToolTip(ui->issueTrackerLabel); updateHiddenState(); - connect(m_ui->moreInfoBtn, &QPushButton::clicked, this, [this]() { - auto nextIndex = (m_ui->infoStacked->currentIndex() + 1) % 2; - m_ui->infoStacked->setCurrentIndex(nextIndex); - m_ui->moreInfoBtn->setText(nextIndex == 0 ? ">" : "<"); - }); - m_ui->moreInfoBtn->hide(); } InfoFrame::~InfoFrame() { - delete m_ui; + delete ui; } -void InfoFrame::updateWithMod(Mod const& m, QStringList requiresList, QStringList requiredByList) +void InfoFrame::updateWithMod(Mod const& m) { if (m.type() == ResourceType::FOLDER) { clear(); @@ -147,26 +141,6 @@ void InfoFrame::updateWithMod(Mod const& m, QStringList requiresList, QStringLis issueTracker += "" + m.issueTracker() + ""; } setIssueTracker(issueTracker); - if (requiredByList.isEmpty()) { - m_ui->requiredGB->hide(); - } else { - m_ui->requiredGB->show(); - m_ui->requiredView->clear(); - m_ui->requiredView->addItems(requiredByList); - } - - if (requiresList.isEmpty()) { - m_ui->requiresGB->hide(); - } else { - m_ui->requiresGB->show(); - m_ui->requiresView->clear(); - m_ui->requiresView->addItems(requiresList); - } - if (requiresList.isEmpty() && requiredByList.isEmpty()) { - m_ui->infoStacked->setCurrentIndex(0); - m_ui->moreInfoBtn->setText(">"); - } - m_ui->moreInfoBtn->setHidden(requiresList.isEmpty() && requiredByList.isEmpty()); } void InfoFrame::updateWithResource(const Resource& resource) @@ -253,8 +227,7 @@ void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack) setImage(resource_pack.image({ 64, 64 })); } -void InfoFrame::updateWithDataPack(DataPack& data_pack) -{ +void InfoFrame::updateWithDataPack(DataPack& data_pack) { setName(renderColorCodes(data_pack.name())); setDescription(renderColorCodes(data_pack.description())); setImage(data_pack.image({ 64, 64 })); @@ -281,13 +254,12 @@ void InfoFrame::clear() setImage(); setLicense(); setIssueTracker(); - m_ui->moreInfoBtn->hide(); } void InfoFrame::updateHiddenState() { - if (m_ui->descriptionLabel->isHidden() && m_ui->nameLabel->isHidden() && m_ui->licenseLabel->isHidden() && - m_ui->issueTrackerLabel->isHidden()) { + if (ui->descriptionLabel->isHidden() && ui->nameLabel->isHidden() && ui->licenseLabel->isHidden() && + ui->issueTrackerLabel->isHidden()) { setHidden(true); } else { setHidden(false); @@ -297,10 +269,10 @@ void InfoFrame::updateHiddenState() void InfoFrame::setName(QString text) { if (text.isEmpty()) { - m_ui->nameLabel->setHidden(true); + ui->nameLabel->setHidden(true); } else { - m_ui->nameLabel->setText(text); - m_ui->nameLabel->setHidden(false); + ui->nameLabel->setText(text); + ui->nameLabel->setHidden(false); } updateHiddenState(); } @@ -308,14 +280,14 @@ void InfoFrame::setName(QString text) void InfoFrame::setDescription(QString text) { if (text.isEmpty()) { - m_ui->descriptionLabel->setHidden(true); + ui->descriptionLabel->setHidden(true); updateHiddenState(); return; } else { - m_ui->descriptionLabel->setHidden(false); + ui->descriptionLabel->setHidden(false); updateHiddenState(); } - m_ui->descriptionLabel->setToolTip(""); + ui->descriptionLabel->setToolTip(""); QString intermediatetext = text.trimmed(); bool prev(false); QChar rem('\n'); @@ -337,8 +309,8 @@ void InfoFrame::setDescription(QString text) doc.setHtml(text); if (doc.characterCount() > maxCharacterElide) { - m_ui->descriptionLabel->setOpenExternalLinks(false); - m_ui->descriptionLabel->setTextFormat(Qt::TextFormat::RichText); // This allows injecting HTML here. + ui->descriptionLabel->setOpenExternalLinks(false); + ui->descriptionLabel->setTextFormat(Qt::TextFormat::RichText); // This allows injecting HTML here. m_description = text; // move the cursor to the character elide, doesn't see html @@ -351,25 +323,25 @@ void InfoFrame::setDescription(QString text) cursor.insertHtml("..."); labeltext.append(doc.toHtml()); - connect(m_ui->descriptionLabel, &QLabel::linkActivated, this, &InfoFrame::descriptionEllipsisHandler); + connect(ui->descriptionLabel, &QLabel::linkActivated, this, &InfoFrame::descriptionEllipsisHandler); } else { - m_ui->descriptionLabel->setTextFormat(Qt::TextFormat::AutoText); + ui->descriptionLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } - m_ui->descriptionLabel->setText(labeltext); + ui->descriptionLabel->setText(labeltext); } void InfoFrame::setLicense(QString text) { if (text.isEmpty()) { - m_ui->licenseLabel->setHidden(true); + ui->licenseLabel->setHidden(true); updateHiddenState(); return; } else { - m_ui->licenseLabel->setHidden(false); + ui->licenseLabel->setHidden(false); updateHiddenState(); } - m_ui->licenseLabel->setToolTip(""); + ui->licenseLabel->setToolTip(""); QString intermediatetext = text.trimmed(); bool prev(false); QChar rem('\n'); @@ -385,26 +357,26 @@ void InfoFrame::setLicense(QString text) QString labeltext; labeltext.reserve(300); if (finaltext.length() > 290) { - m_ui->licenseLabel->setOpenExternalLinks(false); - m_ui->licenseLabel->setTextFormat(Qt::TextFormat::RichText); + ui->licenseLabel->setOpenExternalLinks(false); + ui->licenseLabel->setTextFormat(Qt::TextFormat::RichText); m_license = text; // This allows injecting HTML here. labeltext.append("" + finaltext.left(287) + "..."); - connect(m_ui->licenseLabel, &QLabel::linkActivated, this, &InfoFrame::licenseEllipsisHandler); + connect(ui->licenseLabel, &QLabel::linkActivated, this, &InfoFrame::licenseEllipsisHandler); } else { - m_ui->licenseLabel->setTextFormat(Qt::TextFormat::AutoText); + ui->licenseLabel->setTextFormat(Qt::TextFormat::AutoText); labeltext.append(finaltext); } - m_ui->licenseLabel->setText(labeltext); + ui->licenseLabel->setText(labeltext); } void InfoFrame::setIssueTracker(QString text) { if (text.isEmpty()) { - m_ui->issueTrackerLabel->setHidden(true); + ui->issueTrackerLabel->setHidden(true); } else { - m_ui->issueTrackerLabel->setText(text); - m_ui->issueTrackerLabel->setHidden(false); + ui->issueTrackerLabel->setText(text); + ui->issueTrackerLabel->setHidden(false); } updateHiddenState(); } @@ -412,10 +384,10 @@ void InfoFrame::setIssueTracker(QString text) void InfoFrame::setImage(QPixmap img) { if (img.isNull()) { - m_ui->iconLabel->setHidden(true); + ui->iconLabel->setHidden(true); } else { - m_ui->iconLabel->setHidden(false); - m_ui->iconLabel->setPixmap(img); + ui->iconLabel->setHidden(false); + ui->iconLabel->setPixmap(img); } } diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h index 9cec3d2f2..20c54e2e5 100644 --- a/launcher/ui/widgets/InfoFrame.h +++ b/launcher/ui/widgets/InfoFrame.h @@ -61,7 +61,7 @@ class InfoFrame : public QFrame { void clear(); - void updateWithMod(Mod const& m, QStringList requiresList = {}, QStringList requiredByList = {}); + void updateWithMod(Mod const& m); void updateWithResource(Resource const& resource); void updateWithResourcePack(ResourcePack& rp); void updateWithDataPack(DataPack& rp); @@ -78,7 +78,7 @@ class InfoFrame : public QFrame { void updateHiddenState(); private: - Ui::InfoFrame* m_ui; + Ui::InfoFrame* ui; QString m_description; QString m_license; class QMessageBox* m_current_box = nullptr; diff --git a/launcher/ui/widgets/InfoFrame.ui b/launcher/ui/widgets/InfoFrame.ui index 3e044f06f..c4d8c83d3 100644 --- a/launcher/ui/widgets/InfoFrame.ui +++ b/launcher/ui/widgets/InfoFrame.ui @@ -7,7 +7,7 @@ 0 0 527 - 130 + 113 @@ -19,7 +19,7 @@ 16777215 - 130 + 120 @@ -35,169 +35,6 @@ 0 - - - - > - - - - - - - - - - - - - - - - - Qt::RichText - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - Qt::RichText - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - Qt::RichText - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - Qt::RichText - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - true - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - - - - Requires - - - - - - true - - - QListView::Adjust - - - 10 - - - QListView::IconMode - - - - - - - - - - Required by - - - - - - true - - - QListView::Static - - - QListView::Adjust - - - 10 - - - QListView::IconMode - - - - - - - - - - @@ -223,6 +60,97 @@ + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + true + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + +