From a0f787aa1b72f52dd436f72c339ac8be81557c4a Mon Sep 17 00:00:00 2001 From: spycrab Date: Wed, 24 Jan 2018 13:35:13 +0100 Subject: [PATCH 1/3] Qt: Turn ARCodeEditor into general purpose CheatCodeEditor --- Source/Core/DolphinQt2/CMakeLists.txt | 2 +- .../Core/DolphinQt2/Config/ARCodeEditor.cpp | 170 ---------- Source/Core/DolphinQt2/Config/ARCodeEditor.h | 29 -- .../DolphinQt2/Config/CheatCodeEditor.cpp | 298 ++++++++++++++++++ .../Core/DolphinQt2/Config/CheatCodeEditor.h | 50 +++ Source/Core/DolphinQt2/DolphinQt2.vcxproj | 6 +- 6 files changed, 352 insertions(+), 203 deletions(-) delete mode 100644 Source/Core/DolphinQt2/Config/ARCodeEditor.cpp delete mode 100644 Source/Core/DolphinQt2/Config/ARCodeEditor.h create mode 100644 Source/Core/DolphinQt2/Config/CheatCodeEditor.cpp create mode 100644 Source/Core/DolphinQt2/Config/CheatCodeEditor.h diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt index 4faeaa94ab..9295ea8c65 100644 --- a/Source/Core/DolphinQt2/CMakeLists.txt +++ b/Source/Core/DolphinQt2/CMakeLists.txt @@ -32,7 +32,7 @@ set(SRCS Translation.cpp WiiUpdate.cpp WiiUpdate.h - Config/ARCodeEditor.cpp + Config/CheatCodeEditor.cpp Config/ARCodeWidget.cpp Config/CheatWarningWidget.cpp Config/ControllersWindow.cpp diff --git a/Source/Core/DolphinQt2/Config/ARCodeEditor.cpp b/Source/Core/DolphinQt2/Config/ARCodeEditor.cpp deleted file mode 100644 index 147974ff99..0000000000 --- a/Source/Core/DolphinQt2/Config/ARCodeEditor.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2018 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "DolphinQt2/Config/ARCodeEditor.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Core/ARDecrypt.h" - -ARCodeEditor::ARCodeEditor(ActionReplay::ARCode& ar) : m_code(ar) -{ - CreateWidgets(); - ConnectWidgets(); - - m_name_edit->setText(QString::fromStdString(ar.name)); - - QString s; - - for (ActionReplay::AREntry& e : ar.ops) - { - s += QStringLiteral("%1 %2\n") - .arg(e.cmd_addr, 8, 16, QLatin1Char('0')) - .arg(e.value, 8, 16, QLatin1Char('0')); - } - - m_code_edit->setText(s); -} - -void ARCodeEditor::CreateWidgets() -{ - m_name_edit = new QLineEdit; - m_code_edit = new QTextEdit; - m_button_box = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Save); - - QGridLayout* grid_layout = new QGridLayout; - - grid_layout->addWidget(new QLabel(tr("Name:")), 0, 0); - grid_layout->addWidget(m_name_edit, 0, 1); - grid_layout->addWidget(new QLabel(tr("Code:")), 1, 0); - grid_layout->addWidget(m_code_edit, 1, 1); - grid_layout->addWidget(m_button_box, 2, 1); - - QFont monospace(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); - - m_code_edit->setFont(monospace); - - setLayout(grid_layout); -} - -void ARCodeEditor::ConnectWidgets() -{ - connect(m_button_box, &QDialogButtonBox::accepted, this, &ARCodeEditor::accept); - connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); -} - -void ARCodeEditor::accept() -{ - std::vector entries; - std::vector encrypted_lines; - - QStringList lines = m_code_edit->toPlainText().split(QStringLiteral("\n")); - - for (int i = 0; i < lines.size(); i++) - { - QString line = lines[i]; - - if (line.isEmpty()) - continue; - - QStringList values = line.split(QStringLiteral(" ")); - - bool good = true; - - u32 addr = 0; - u32 value = 0; - - if (values.size() == 2) - { - addr = values[0].toUInt(&good, 16); - - if (good) - value = values[1].toUInt(&good, 16); - - if (good) - entries.push_back(ActionReplay::AREntry(addr, value)); - } - else - { - QStringList blocks = line.split(QStringLiteral("-")); - - if (blocks.size() == 3 && blocks[0].size() == 4 && blocks[1].size() == 4 && - blocks[2].size() == 4) - { - encrypted_lines.emplace_back(blocks[0].toStdString() + blocks[1].toStdString() + - blocks[2].toStdString()); - } - else - { - good = false; - } - } - - if (!good) - { - auto result = QMessageBox::warning( - this, tr("Parsing Error"), - tr("Unable to parse line %1 of the entered AR code as a valid " - "encrypted or decrypted code. Make sure you typed it correctly.\n\n" - "Would you like to ignore this line and continue parsing?") - .arg(i + 1), - QMessageBox::Ok | QMessageBox::Abort); - - if (result == QMessageBox::Abort) - return; - } - } - - if (!encrypted_lines.empty()) - { - if (!entries.empty()) - { - auto result = QMessageBox::warning( - this, tr("Invalid Mixed Code"), - tr("This Action Replay code contains both encrypted and unencrypted lines; " - "you should check that you have entered it correctly.\n\n" - "Do you want to discard all unencrypted lines?"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); - - // YES = Discard the unencrypted lines then decrypt the encrypted ones instead. - // NO = Discard the encrypted lines, keep the unencrypted ones - // CANCEL = Stop and let the user go back to editing - switch (result) - { - case QMessageBox::Yes: - entries.clear(); - break; - case QMessageBox::No: - encrypted_lines.clear(); - break; - case QMessageBox::Cancel: - return; - default: - break; - } - } - ActionReplay::DecryptARCode(encrypted_lines, &entries); - } - - if (entries.empty()) - { - QMessageBox::critical(this, tr("Error"), - tr("The resulting decrypted AR code doesn't contain any lines.")); - return; - } - - m_code.name = m_name_edit->text().toStdString(); - m_code.ops = std::move(entries); - m_code.active = true; - m_code.user_defined = true; - - QDialog::accept(); -} diff --git a/Source/Core/DolphinQt2/Config/ARCodeEditor.h b/Source/Core/DolphinQt2/Config/ARCodeEditor.h deleted file mode 100644 index bc8e2faf48..0000000000 --- a/Source/Core/DolphinQt2/Config/ARCodeEditor.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include "Core/ActionReplay.h" - -#include - -class QDialogButtonBox; -class QLineEdit; -class QTextEdit; - -class ARCodeEditor : public QDialog -{ -public: - explicit ARCodeEditor(ActionReplay::ARCode& ar); - -private: - void CreateWidgets(); - void ConnectWidgets(); - - void accept() override; - - QLineEdit* m_name_edit; - QTextEdit* m_code_edit; - QDialogButtonBox* m_button_box; - - ActionReplay::ARCode& m_code; -}; diff --git a/Source/Core/DolphinQt2/Config/CheatCodeEditor.cpp b/Source/Core/DolphinQt2/Config/CheatCodeEditor.cpp new file mode 100644 index 0000000000..8a91817cbe --- /dev/null +++ b/Source/Core/DolphinQt2/Config/CheatCodeEditor.cpp @@ -0,0 +1,298 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinQt2/Config/CheatCodeEditor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Core/ARDecrypt.h" +#include "Core/ActionReplay.h" +#include "Core/GeckoCodeConfig.h" + +CheatCodeEditor::CheatCodeEditor() +{ + CreateWidgets(); + ConnectWidgets(); +} + +void CheatCodeEditor::SetARCode(ActionReplay::ARCode* code) +{ + m_name_edit->setText(QString::fromStdString(code->name)); + + QString s; + + for (ActionReplay::AREntry& e : code->ops) + { + s += QStringLiteral("%1 %2\n") + .arg(e.cmd_addr, 8, 16, QLatin1Char('0')) + .arg(e.value, 8, 16, QLatin1Char('0')); + } + + m_code_edit->setText(s); + + m_creator_label->setHidden(true); + m_creator_edit->setHidden(true); + m_notes_label->setHidden(true); + m_notes_edit->setHidden(true); + + m_ar_code = code; + m_gecko_code = nullptr; +} + +void CheatCodeEditor::SetGeckoCode(Gecko::GeckoCode* code) +{ + m_name_edit->setText(QString::fromStdString(code->name)); + m_creator_edit->setText(QString::fromStdString(code->creator)); + + QString code_string; + + for (const auto& c : code->codes) + code_string += QStringLiteral("%1 %2\n") + .arg(c.address, 8, 16, QLatin1Char('0')) + .arg(c.data, 8, 16, QLatin1Char('0')); + + m_code_edit->setText(code_string); + + QString notes_string; + for (const auto& line : code->notes) + notes_string += QStringLiteral("%1\n").arg(QString::fromStdString(line)); + + m_notes_edit->setText(notes_string); + + m_creator_label->setHidden(false); + m_creator_edit->setHidden(false); + m_notes_label->setHidden(false); + m_notes_edit->setHidden(false); + + m_gecko_code = code; + m_ar_code = nullptr; +} + +void CheatCodeEditor::CreateWidgets() +{ + m_name_edit = new QLineEdit; + m_creator_edit = new QLineEdit; + m_notes_edit = new QTextEdit; + m_code_edit = new QTextEdit; + m_button_box = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Save); + + m_creator_label = new QLabel(tr("Creator:")); + m_notes_label = new QLabel(tr("Notes:")); + + QGridLayout* grid_layout = new QGridLayout; + + grid_layout->addWidget(new QLabel(tr("Name:")), 0, 0); + grid_layout->addWidget(m_name_edit, 0, 1); + grid_layout->addWidget(m_creator_label, 1, 0); + grid_layout->addWidget(m_creator_edit, 1, 1); + grid_layout->addWidget(m_notes_label, 2, 0); + grid_layout->addWidget(m_notes_edit, 2, 1); + grid_layout->addWidget(new QLabel(tr("Code:")), 3, 0); + grid_layout->addWidget(m_code_edit, 3, 1); + grid_layout->addWidget(m_button_box, 4, 1); + + QFont monospace(QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); + + m_code_edit->setFont(monospace); + + setLayout(grid_layout); +} + +void CheatCodeEditor::ConnectWidgets() +{ + connect(m_button_box, &QDialogButtonBox::accepted, this, &CheatCodeEditor::accept); + connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); +} + +bool CheatCodeEditor::AcceptAR() +{ + std::vector entries; + std::vector encrypted_lines; + + QStringList lines = m_code_edit->toPlainText().split(QStringLiteral("\n")); + + for (int i = 0; i < lines.size(); i++) + { + QString line = lines[i]; + + if (line.isEmpty()) + continue; + + QStringList values = line.split(QStringLiteral(" ")); + + bool good = true; + + u32 addr = 0; + u32 value = 0; + + if (values.size() == 2) + { + addr = values[0].toUInt(&good, 16); + + if (good) + value = values[1].toUInt(&good, 16); + + if (good) + entries.push_back(ActionReplay::AREntry(addr, value)); + } + else + { + QStringList blocks = line.split(QStringLiteral("-")); + + if (blocks.size() == 3 && blocks[0].size() == 4 && blocks[1].size() == 4 && + blocks[2].size() == 4) + { + encrypted_lines.emplace_back(blocks[0].toStdString() + blocks[1].toStdString() + + blocks[2].toStdString()); + } + else + { + good = false; + } + } + + if (!good) + { + auto result = QMessageBox::warning( + this, tr("Parsing Error"), + tr("Unable to parse line %1 of the entered AR code as a valid " + "encrypted or decrypted code. Make sure you typed it correctly.\n\n" + "Would you like to ignore this line and continue parsing?") + .arg(i + 1), + QMessageBox::Ok | QMessageBox::Abort); + + if (result == QMessageBox::Abort) + return false; + } + } + + if (!encrypted_lines.empty()) + { + if (!entries.empty()) + { + auto result = QMessageBox::warning( + this, tr("Invalid Mixed Code"), + tr("This Action Replay code contains both encrypted and unencrypted lines; " + "you should check that you have entered it correctly.\n\n" + "Do you want to discard all unencrypted lines?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + + // YES = Discard the unencrypted lines then decrypt the encrypted ones instead. + // NO = Discard the encrypted lines, keep the unencrypted ones + // CANCEL = Stop and let the user go back to editing + switch (result) + { + case QMessageBox::Yes: + entries.clear(); + break; + case QMessageBox::No: + encrypted_lines.clear(); + break; + case QMessageBox::Cancel: + return false; + default: + break; + } + } + ActionReplay::DecryptARCode(encrypted_lines, &entries); + } + + if (entries.empty()) + { + QMessageBox::critical(this, tr("Error"), + tr("The resulting decrypted AR code doesn't contain any lines.")); + return false; + } + + m_ar_code->name = m_name_edit->text().toStdString(); + m_ar_code->ops = std::move(entries); + m_ar_code->user_defined = true; + + return true; +} + +bool CheatCodeEditor::AcceptGecko() +{ + std::vector entries; + + QStringList lines = m_code_edit->toPlainText().split(QStringLiteral("\n")); + + for (int i = 0; i < lines.size(); i++) + { + QString line = lines[i]; + + if (line.isEmpty()) + continue; + + QStringList values = line.split(QStringLiteral(" ")); + + bool good = true; + + u32 addr = 0; + u32 value = 0; + + addr = values[0].toUInt(&good, 16); + + if (good) + value = values[1].toUInt(&good, 16); + + if (!good) + { + auto result = + QMessageBox::warning(this, tr("Parsing Error"), + tr("Unable to parse line %1 of the entered Gecko code as a valid " + "code. Make sure you typed it correctly.\n\n" + "Would you like to ignore this line and continue parsing?") + .arg(i + 1), + QMessageBox::Ok | QMessageBox::Abort); + + if (result == QMessageBox::Abort) + return false; + } + else + { + Gecko::GeckoCode::Code c; + c.address = addr; + c.data = value; + c.original_line = line.toStdString(); + + entries.push_back(c); + } + } + + if (entries.empty()) + { + QMessageBox::critical(this, tr("Error"), + tr("The resulting decrypted AR code doesn't contain any lines.")); + return true; + } + + m_gecko_code->name = m_name_edit->text().toStdString(); + m_gecko_code->creator = m_creator_edit->text().toStdString(); + m_gecko_code->codes = std::move(entries); + m_gecko_code->user_defined = true; + + std::vector note_lines; + for (QString line : m_notes_edit->toPlainText().split(QStringLiteral("\n"))) + note_lines.push_back(line.toStdString()); + + m_gecko_code->notes = std::move(note_lines); + + return true; +} + +void CheatCodeEditor::accept() +{ + bool success = m_gecko_code != nullptr ? AcceptGecko() : AcceptAR(); + + if (success) + QDialog::accept(); +} diff --git a/Source/Core/DolphinQt2/Config/CheatCodeEditor.h b/Source/Core/DolphinQt2/Config/CheatCodeEditor.h new file mode 100644 index 0000000000..e3057e10cc --- /dev/null +++ b/Source/Core/DolphinQt2/Config/CheatCodeEditor.h @@ -0,0 +1,50 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +class QDialogButtonBox; +class QLabel; +class QLineEdit; +class QTextEdit; + +namespace ActionReplay +{ +class ARCode; +} + +namespace Gecko +{ +class GeckoCode; +} + +class CheatCodeEditor : public QDialog +{ +public: + explicit CheatCodeEditor(); + + void SetARCode(ActionReplay::ARCode* code); + void SetGeckoCode(Gecko::GeckoCode* code); + +private: + void CreateWidgets(); + void ConnectWidgets(); + + bool AcceptAR(); + bool AcceptGecko(); + + void accept() override; + + QLabel* m_creator_label; + QLabel* m_notes_label; + + QLineEdit* m_name_edit; + QLineEdit* m_creator_edit; + QTextEdit* m_notes_edit; + QTextEdit* m_code_edit; + QDialogButtonBox* m_button_box; + + ActionReplay::ARCode* m_ar_code = nullptr; + Gecko::GeckoCode* m_gecko_code = nullptr; +}; diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj index 778f81b7cf..86b08a7f71 100644 --- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj +++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj @@ -60,7 +60,7 @@ - + @@ -118,7 +118,7 @@ - + @@ -174,7 +174,7 @@ - + From d9d75c27f0892d25de03a10fa0314fa2e87b9f1d Mon Sep 17 00:00:00 2001 From: spycrab Date: Wed, 24 Jan 2018 13:35:44 +0100 Subject: [PATCH 2/3] Qt/ARCodeWidget: Use CheatCodeEditor --- .../Core/DolphinQt2/Config/ARCodeWidget.cpp | 19 ++++++++++++------- .../Core/DolphinQt2/Config/CheatCodeEditor.h | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Source/Core/DolphinQt2/Config/ARCodeWidget.cpp b/Source/Core/DolphinQt2/Config/ARCodeWidget.cpp index e47cee4dc5..372ef5caf5 100644 --- a/Source/Core/DolphinQt2/Config/ARCodeWidget.cpp +++ b/Source/Core/DolphinQt2/Config/ARCodeWidget.cpp @@ -14,7 +14,7 @@ #include "Common/IniFile.h" #include "Core/ActionReplay.h" #include "Core/ConfigManager.h" -#include "DolphinQt2/Config/ARCodeEditor.h" +#include "DolphinQt2/Config/CheatCodeEditor.h" #include "DolphinQt2/Config/CheatWarningWidget.h" #include "DolphinQt2/GameList/GameFile.h" @@ -122,15 +122,19 @@ void ARCodeWidget::SaveCodes() void ARCodeWidget::OnCodeAddPressed() { ActionReplay::ARCode ar; + ar.active = true; - ARCodeEditor ed(ar); + CheatCodeEditor ed; - ed.exec(); + ed.SetARCode(&ar); - m_ar_codes.push_back(std::move(ar)); + if (ed.exec()) + { + m_ar_codes.push_back(std::move(ar)); - UpdateList(); - SaveCodes(); + UpdateList(); + SaveCodes(); + } } void ARCodeWidget::OnCodeEditPressed() @@ -148,8 +152,9 @@ void ARCodeWidget::OnCodeEditPressed() ActionReplay::ARCode ar = current_ar; - ARCodeEditor ed(user_defined ? current_ar : ar); + CheatCodeEditor ed; + ed.SetARCode(user_defined ? ¤t_ar : &ar); ed.exec(); if (!user_defined) diff --git a/Source/Core/DolphinQt2/Config/CheatCodeEditor.h b/Source/Core/DolphinQt2/Config/CheatCodeEditor.h index e3057e10cc..beb0862590 100644 --- a/Source/Core/DolphinQt2/Config/CheatCodeEditor.h +++ b/Source/Core/DolphinQt2/Config/CheatCodeEditor.h @@ -11,7 +11,7 @@ class QTextEdit; namespace ActionReplay { -class ARCode; +struct ARCode; } namespace Gecko From ee90893bfe959611aea31a364d674e5842155822 Mon Sep 17 00:00:00 2001 From: spycrab Date: Wed, 24 Jan 2018 13:36:16 +0100 Subject: [PATCH 3/3] Qt/GeckoCodeWidget: Option to add/remove gecko codes from UI --- .../DolphinQt2/Config/GeckoCodeWidget.cpp | 73 ++++++++++++++++++- .../Core/DolphinQt2/Config/GeckoCodeWidget.h | 7 ++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt2/Config/GeckoCodeWidget.cpp b/Source/Core/DolphinQt2/Config/GeckoCodeWidget.cpp index 0b04439e92..92f2c03af2 100644 --- a/Source/Core/DolphinQt2/Config/GeckoCodeWidget.cpp +++ b/Source/Core/DolphinQt2/Config/GeckoCodeWidget.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include "Common/IniFile.h" #include "Core/ConfigManager.h" #include "Core/GeckoCodeConfig.h" +#include "DolphinQt2/Config/CheatCodeEditor.h" #include "DolphinQt2/Config/CheatWarningWidget.h" #include "DolphinQt2/GameList/GameFile.h" @@ -59,9 +61,14 @@ void GeckoCodeWidget::CreateWidgets() m_code_view->setReadOnly(true); m_code_view->setFixedHeight(line_height * 10); + m_add_code = new QPushButton(tr("&Add New Code...")); + m_edit_code = new QPushButton(tr("&Edit Code...")); + m_remove_code = new QPushButton(tr("&Remove Code")); m_download_codes = new QPushButton(tr("Download Codes (WiiRD Database)")); + m_download_codes->setEnabled(!m_game_id.empty()); - m_download_codes->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_edit_code->setEnabled(false); + m_remove_code->setEnabled(false); auto* layout = new QVBoxLayout; @@ -85,7 +92,15 @@ void GeckoCodeWidget::CreateWidgets() layout->addLayout(info_layout); layout->addWidget(m_code_description); layout->addWidget(m_code_view); - layout->addWidget(m_download_codes, 0, Qt::AlignRight); + + QHBoxLayout* btn_layout = new QHBoxLayout; + + btn_layout->addWidget(m_add_code); + btn_layout->addWidget(m_edit_code); + btn_layout->addWidget(m_remove_code); + btn_layout->addWidget(m_download_codes); + + layout->addLayout(btn_layout); setLayout(layout); } @@ -96,6 +111,8 @@ void GeckoCodeWidget::ConnectWidgets() &GeckoCodeWidget::OnSelectionChanged); connect(m_code_list, &QListWidget::itemChanged, this, &GeckoCodeWidget::OnItemChanged); + connect(m_add_code, &QPushButton::pressed, this, &GeckoCodeWidget::AddCode); + connect(m_edit_code, &QPushButton::pressed, this, &GeckoCodeWidget::EditCode); connect(m_download_codes, &QPushButton::pressed, this, &GeckoCodeWidget::DownloadCodes); connect(m_warning, &CheatWarningWidget::OpenCheatEnableSettings, this, @@ -106,6 +123,9 @@ void GeckoCodeWidget::OnSelectionChanged() { auto items = m_code_list->selectedItems(); + m_edit_code->setEnabled(!items.empty()); + m_remove_code->setEnabled(!items.empty()); + if (items.empty()) return; @@ -136,6 +156,55 @@ void GeckoCodeWidget::OnItemChanged(QListWidgetItem* item) SaveCodes(); } +void GeckoCodeWidget::AddCode() +{ + Gecko::GeckoCode code; + code.enabled = true; + + CheatCodeEditor ed; + ed.SetGeckoCode(&code); + + if (ed.exec()) + { + m_gecko_codes.push_back(std::move(code)); + SaveCodes(); + UpdateList(); + } +} + +void GeckoCodeWidget::EditCode() +{ + const auto* item = m_code_list->currentItem(); + + if (item == nullptr) + return; + + int row = m_code_list->row(item); + + CheatCodeEditor ed; + + ed.SetGeckoCode(&m_gecko_codes[row]); + + if (ed.exec()) + { + SaveCodes(); + UpdateList(); + } +} + +void GeckoCodeWidget::RemoveCode() +{ + const auto* item = m_code_list->currentItem(); + + if (item == nullptr) + return; + + m_gecko_codes.erase(m_gecko_codes.begin() + m_code_list->row(item)); + + UpdateList(); + SaveCodes(); +} + void GeckoCodeWidget::SaveCodes() { IniFile game_ini_local; diff --git a/Source/Core/DolphinQt2/Config/GeckoCodeWidget.h b/Source/Core/DolphinQt2/Config/GeckoCodeWidget.h index 877090b367..20bd24cb43 100644 --- a/Source/Core/DolphinQt2/Config/GeckoCodeWidget.h +++ b/Source/Core/DolphinQt2/Config/GeckoCodeWidget.h @@ -32,10 +32,14 @@ signals: private: void OnSelectionChanged(); void OnItemChanged(QListWidgetItem* item); + void OnDelete(); void CreateWidgets(); void ConnectWidgets(); void UpdateList(); + void AddCode(); + void EditCode(); + void RemoveCode(); void DownloadCodes(); void SaveCodes(); @@ -49,6 +53,9 @@ private: QLabel* m_creator_label; QTextEdit* m_code_description; QTextEdit* m_code_view; + QPushButton* m_add_code; + QPushButton* m_edit_code; + QPushButton* m_remove_code; QPushButton* m_download_codes; std::vector m_gecko_codes; };