From 0d3ccfada557d912f4c307d61e4e388c871385ab Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Mon, 20 Apr 2026 12:29:29 -0700 Subject: [PATCH 1/2] ARCodeWidget: Add Enable/Disable All button --- Source/Core/DolphinQt/Config/ARCodeWidget.cpp | 47 ++++++++++++++++++- Source/Core/DolphinQt/Config/ARCodeWidget.h | 5 ++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp index f2cc8b0e59..e4b55c3729 100644 --- a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp @@ -4,6 +4,7 @@ #include "DolphinQt/Config/ARCodeWidget.h" #include +#include #include #include @@ -72,6 +73,7 @@ void ARCodeWidget::CreateWidgets() m_code_add = new NonDefaultQPushButton(tr("&Add New Code...")); m_code_edit = new NonDefaultQPushButton(tr("&Edit Code...")); m_code_remove = new NonDefaultQPushButton(tr("&Remove Code")); + m_code_toggle_all = new NonDefaultQPushButton(tr("Disable All")); m_cheat_code_editor = new CheatCodeEditor(this); @@ -82,6 +84,7 @@ void ARCodeWidget::CreateWidgets() button_layout->addWidget(m_code_add); button_layout->addWidget(m_code_edit); button_layout->addWidget(m_code_remove); + button_layout->addWidget(m_code_toggle_all); auto* const layout = new QVBoxLayout{this}; @@ -113,6 +116,7 @@ void ARCodeWidget::ConnectWidgets() connect(m_code_add, &QPushButton::clicked, this, &ARCodeWidget::OnCodeAddClicked); connect(m_code_edit, &QPushButton::clicked, this, &ARCodeWidget::OnCodeEditClicked); connect(m_code_remove, &QPushButton::clicked, this, &ARCodeWidget::OnCodeRemoveClicked); + connect(m_code_toggle_all, &QPushButton::clicked, this, &ARCodeWidget::OnCodeToggleAllClicked); } void ARCodeWidget::OnItemChanged(QListWidgetItem* item) @@ -122,7 +126,7 @@ void ARCodeWidget::OnItemChanged(QListWidgetItem* item) if (!m_restart_required) ActionReplay::ApplyCodes(m_ar_codes, m_game_id, m_game_revision); - UpdateList(); + UpdateToggleButton(); SaveCodes(); } @@ -157,6 +161,21 @@ void ARCodeWidget::SortDisabledCodesFirst() SaveCodes(); } +bool ARCodeWidget::IsEveryCodeEnabled() +{ + return std::ranges::all_of(m_ar_codes, &ActionReplay::ARCode::enabled); +} + +void ARCodeWidget::UpdateToggleButton() +{ + if (IsEveryCodeEnabled()) + m_code_toggle_all->setText(tr("Disable All")); + else + m_code_toggle_all->setText(tr("Enable All")); + + m_code_toggle_all->setDisabled(m_ar_codes.empty()); +} + void ARCodeWidget::OnListReordered() { // Reorder codes based on the indices of table item @@ -229,6 +248,7 @@ void ARCodeWidget::UpdateList() } m_code_list->setDragDropMode(QAbstractItemView::InternalMove); + UpdateToggleButton(); } void ARCodeWidget::LoadCodes() @@ -341,3 +361,28 @@ void ARCodeWidget::OnCodeRemoveClicked() m_code_remove->setEnabled(false); } + +void ARCodeWidget::OnCodeToggleAllClicked() +{ + const bool new_state = !IsEveryCodeEnabled(); + const Qt::CheckState new_check_state = + new_state ? Qt::CheckState::Checked : Qt::CheckState::Unchecked; + + { + // Without this blocker, the call to setCheckState below would end up loading and saving the ini + // file once per code. + QSignalBlocker blocker(m_code_list); + + for (int i = 0; i < m_ar_codes.size(); ++i) + { + m_ar_codes[i].enabled = new_state; + m_code_list->item(i)->setCheckState(new_check_state); + } + } + + if (!m_restart_required) + ActionReplay::ApplyCodes(m_ar_codes, m_game_id, m_game_revision); + + UpdateList(); + SaveCodes(); +} diff --git a/Source/Core/DolphinQt/Config/ARCodeWidget.h b/Source/Core/DolphinQt/Config/ARCodeWidget.h index 94fb8ebbe5..b3be4b9053 100644 --- a/Source/Core/DolphinQt/Config/ARCodeWidget.h +++ b/Source/Core/DolphinQt/Config/ARCodeWidget.h @@ -54,13 +54,17 @@ private: void SortAlphabetically(); void SortEnabledCodesFirst(); void SortDisabledCodesFirst(); + void UpdateToggleButton(); void OnCodeAddClicked(); void OnCodeEditClicked(); void OnCodeRemoveClicked(); + void OnCodeToggleAllClicked(); void OnListReordered(); + bool IsEveryCodeEnabled(); + std::string m_game_id; u16 m_game_revision; @@ -72,6 +76,7 @@ private: QPushButton* m_code_add; QPushButton* m_code_edit; QPushButton* m_code_remove; + QPushButton* m_code_toggle_all; CheatCodeEditor* m_cheat_code_editor; From 39240edc2a9f3e5791f33e9acfd7e5a3f96c6fa6 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Mon, 20 Apr 2026 13:11:00 -0700 Subject: [PATCH 2/2] GeckoCodeWidget: Add Enable/Disable All button --- .../Core/DolphinQt/Config/GeckoCodeWidget.cpp | 46 +++++++++++++++++++ .../Core/DolphinQt/Config/GeckoCodeWidget.h | 5 ++ 2 files changed, 51 insertions(+) diff --git a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp index 74a3f58950..3d4e799f49 100644 --- a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp @@ -4,6 +4,7 @@ #include "DolphinQt/Config/GeckoCodeWidget.h" #include +#include #include #include @@ -108,6 +109,7 @@ void GeckoCodeWidget::CreateWidgets() m_edit_code = new NonDefaultQPushButton(tr("&Edit Code...")); m_remove_code = new NonDefaultQPushButton(tr("&Remove Code")); m_download_codes = new NonDefaultQPushButton(tr("Download Codes")); + m_toggle_all_codes = new NonDefaultQPushButton(tr("Disable All")); m_cheat_code_editor = new CheatCodeEditor(this); @@ -145,6 +147,7 @@ void GeckoCodeWidget::CreateWidgets() btn_layout->addWidget(m_edit_code); btn_layout->addWidget(m_remove_code); btn_layout->addWidget(m_download_codes); + btn_layout->addWidget(m_toggle_all_codes); layout->addLayout(btn_layout); } @@ -163,6 +166,7 @@ void GeckoCodeWidget::ConnectWidgets() connect(m_remove_code, &QPushButton::clicked, this, &GeckoCodeWidget::RemoveCode); connect(m_edit_code, &QPushButton::clicked, this, &GeckoCodeWidget::EditCode); connect(m_download_codes, &QPushButton::clicked, this, &GeckoCodeWidget::DownloadCodes); + connect(m_toggle_all_codes, &QPushButton::clicked, this, &GeckoCodeWidget::ToggleAllCodes); connect(m_warning, &CheatWarningWidget::OpenCheatEnableSettings, this, &GeckoCodeWidget::OpenGeneralSettings); #ifdef USE_RETRO_ACHIEVEMENTS @@ -212,6 +216,7 @@ void GeckoCodeWidget::OnItemChanged(QListWidgetItem* item) if (!m_restart_required) Gecko::SetActiveCodes(m_gecko_codes, m_game_id, m_game_revision); + UpdateToggleButton(); SaveCodes(); } @@ -336,6 +341,21 @@ void GeckoCodeWidget::SortDisabledCodesFirst() SaveCodes(); } +bool GeckoCodeWidget::IsEveryCodeEnabled() +{ + return std::ranges::all_of(m_gecko_codes, &Gecko::GeckoCode::enabled); +} + +void GeckoCodeWidget::UpdateToggleButton() +{ + if (IsEveryCodeEnabled()) + m_toggle_all_codes->setText(tr("Disable All")); + else + m_toggle_all_codes->setText(tr("Enable All")); + + m_toggle_all_codes->setDisabled(m_gecko_codes.empty()); +} + void GeckoCodeWidget::OnListReordered() { // Reorder codes based on the indices of table item @@ -391,6 +411,7 @@ void GeckoCodeWidget::UpdateList() } m_code_list->setDragDropMode(QAbstractItemView::InternalMove); + UpdateToggleButton(); } void GeckoCodeWidget::DownloadCodes() @@ -438,3 +459,28 @@ void GeckoCodeWidget::DownloadCodes() tr("Downloaded %1 codes. (added %2)") .arg(QString::number(codes.size()), QString::number(added_count))); } + +void GeckoCodeWidget::ToggleAllCodes() +{ + const bool new_state = !IsEveryCodeEnabled(); + const Qt::CheckState new_check_state = + new_state ? Qt::CheckState::Checked : Qt::CheckState::Unchecked; + + { + // Without this blocker, the call to setCheckState below would end up loading and saving the ini + // file once per code. + QSignalBlocker blocker(m_code_list); + + for (int i = 0; i < m_gecko_codes.size(); ++i) + { + m_gecko_codes[i].enabled = new_state; + m_code_list->item(i)->setCheckState(new_check_state); + } + } + + if (!m_restart_required) + Gecko::SetActiveCodes(m_gecko_codes, m_game_id, m_game_revision); + + UpdateList(); + SaveCodes(); +} diff --git a/Source/Core/DolphinQt/Config/GeckoCodeWidget.h b/Source/Core/DolphinQt/Config/GeckoCodeWidget.h index a490a9f3db..0ab51b8aa3 100644 --- a/Source/Core/DolphinQt/Config/GeckoCodeWidget.h +++ b/Source/Core/DolphinQt/Config/GeckoCodeWidget.h @@ -55,11 +55,15 @@ private: void EditCode(); void RemoveCode(); void DownloadCodes(); + void ToggleAllCodes(); void LoadCodes(); void SaveCodes(); void SortAlphabetically(); void SortEnabledCodesFirst(); void SortDisabledCodesFirst(); + void UpdateToggleButton(); + + bool IsEveryCodeEnabled(); std::string m_game_id; std::string m_gametdb_id; @@ -78,6 +82,7 @@ private: QPushButton* m_edit_code; QPushButton* m_remove_code; QPushButton* m_download_codes; + QPushButton* m_toggle_all_codes; CheatCodeEditor* m_cheat_code_editor; std::vector m_gecko_codes; bool m_restart_required;