src/platform/qt/CheatsView.cpp (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "CheatsView.h"
7
8#include "GBAApp.h"
9#include "CoreController.h"
10
11#include <QClipboard>
12#include <QPushButton>
13
14#include <mgba/core/cheats.h>
15#ifdef M_CORE_GBA
16#include <mgba/internal/gba/cheats.h>
17#endif
18#ifdef M_CORE_GB
19#include <mgba/internal/gb/cheats.h>
20#endif
21
22using namespace QGBA;
23
24CheatsView::CheatsView(std::shared_ptr<CoreController> controller, QWidget* parent)
25 : QWidget(parent)
26 , m_controller(controller)
27 , m_model(controller->cheatDevice())
28{
29 m_ui.setupUi(this);
30
31 m_ui.cheatList->installEventFilter(this);
32 m_ui.cheatList->setModel(&m_model);
33
34 connect(m_ui.load, &QPushButton::clicked, this, &CheatsView::load);
35 connect(m_ui.save, &QPushButton::clicked, this, &CheatsView::save);
36 connect(m_ui.addSet, &QPushButton::clicked, this, &CheatsView::addSet);
37 connect(m_ui.remove, &QPushButton::clicked, this, &CheatsView::removeSet);
38 connect(controller.get(), &CoreController::stopping, this, &CheatsView::close);
39 connect(controller.get(), &CoreController::stateLoaded, &m_model, &CheatsModel::invalidated);
40
41 QPushButton* add;
42 switch (controller->platform()) {
43#ifdef M_CORE_GBA
44 case PLATFORM_GBA:
45 connect(m_ui.add, &QPushButton::clicked, [this]() {
46 enterCheat(GBA_CHEAT_AUTODETECT);
47 });
48
49 add = new QPushButton(tr("Add GameShark"));
50 m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
51 connect(add, &QPushButton::clicked, [this]() {
52 enterCheat(GBA_CHEAT_GAMESHARK);
53 });
54
55 add = new QPushButton(tr("Add Pro Action Replay"));
56 m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
57 connect(add, &QPushButton::clicked, [this]() {
58 enterCheat(GBA_CHEAT_PRO_ACTION_REPLAY);
59 });
60
61 add = new QPushButton(tr("Add CodeBreaker"));
62 m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
63 connect(add, &QPushButton::clicked, [this]() {
64 enterCheat(GBA_CHEAT_CODEBREAKER);
65 });
66 break;
67#endif
68#ifdef M_CORE_GB
69 case PLATFORM_GB:
70 connect(m_ui.add, &QPushButton::clicked, [this]() {
71 enterCheat(GB_CHEAT_AUTODETECT);
72 });
73
74 add = new QPushButton(tr("Add GameShark"));
75 m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
76 connect(add, &QPushButton::clicked, [this]() {
77 enterCheat(GB_CHEAT_GAMESHARK);
78 });
79
80 add = new QPushButton(tr("Add GameGenie"));
81 m_ui.gridLayout->addWidget(add, m_ui.gridLayout->rowCount(), 2, 1, 2);
82 connect(add, &QPushButton::clicked, [this]() {
83 enterCheat(GB_CHEAT_GAME_GENIE);
84 });
85 break;
86#endif
87 default:
88 break;
89 }
90
91 // Stretch the cheat list back into place
92 int index = m_ui.gridLayout->indexOf(m_ui.cheatList);
93 m_ui.gridLayout->takeAt(index);
94 m_ui.gridLayout->addWidget(m_ui.cheatList, 0, 0, -1, 1);
95}
96
97bool CheatsView::eventFilter(QObject* object, QEvent* event) {
98 if (object != m_ui.cheatList) {
99 return false;
100 }
101 if (event->type() != QEvent::KeyPress) {
102 return false;
103 }
104 if (static_cast<QKeyEvent*>(event) == QKeySequence::Copy) {
105 QApplication::clipboard()->setText(m_model.toString(m_ui.cheatList->selectionModel()->selectedIndexes()));
106 return true;
107 }
108 return false;
109}
110
111void CheatsView::load() {
112 QString filename = GBAApp::app()->getOpenFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats *.cht)")));
113 if (!filename.isEmpty()) {
114 m_model.loadFile(filename);
115 }
116}
117
118void CheatsView::save() {
119 QString filename = GBAApp::app()->getSaveFileName(this, tr("Select cheats file"), tr(("Cheats file (*.cheats)")));
120 if (!filename.isEmpty()) {
121 m_model.saveFile(filename);
122 }
123}
124
125void CheatsView::addSet() {
126 CoreController::Interrupter interrupter(m_controller);
127 mCheatSet* set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
128 m_model.addSet(set);
129}
130
131void CheatsView::removeSet() {
132 GBACheatSet* set;
133 QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
134 if (selection.count() < 1) {
135 return;
136 }
137 CoreController::Interrupter interrupter(m_controller);
138 for (const QModelIndex& index : selection) {
139 m_model.removeAt(selection[0]);
140 }
141}
142
143void CheatsView::enterCheat(int codeType) {
144 mCheatSet* set = nullptr;
145 QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
146 QModelIndex index;
147 if (selection.count() == 0) {
148 set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
149 } else if (selection.count() == 1) {
150 index = selection[0];
151 set = m_model.itemAt(index);
152 }
153
154 if (!set) {
155 return;
156 }
157 CoreController::Interrupter interrupter(m_controller);
158 if (selection.count() == 0) {
159 m_model.addSet(set);
160 index = m_model.index(m_model.rowCount() - 1, 0, QModelIndex());
161 m_ui.cheatList->selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
162 }
163 QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts);
164 for (const QString& string : cheats) {
165 m_model.beginAppendRow(index);
166 mCheatAddLine(set, string.toUtf8().constData(), codeType);
167 m_model.endAppendRow();
168 }
169 set->refresh(set, m_controller->cheatDevice());
170 m_ui.codeEntry->clear();
171}