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 "GameController.h"
10
11#include <QClipboard>
12
13extern "C" {
14#include "gba/cheats.h"
15}
16
17using namespace QGBA;
18
19CheatsView::CheatsView(GameController* controller, QWidget* parent)
20 : QWidget(parent)
21 , m_controller(controller)
22 , m_model(controller->cheatDevice())
23{
24 m_ui.setupUi(this);
25
26 m_ui.cheatList->installEventFilter(this);
27 m_ui.cheatList->setModel(&m_model);
28
29 connect(m_ui.load, SIGNAL(clicked()), this, SLOT(load()));
30 connect(m_ui.save, SIGNAL(clicked()), this, SLOT(save()));
31 connect(m_ui.addSet, SIGNAL(clicked()), this, SLOT(addSet()));
32 connect(m_ui.remove, SIGNAL(clicked()), this, SLOT(removeSet()));
33 connect(controller, SIGNAL(gameStopped(GBAThread*)), &m_model, SLOT(invalidated()));
34 connect(controller, SIGNAL(stateLoaded(GBAThread*)), &m_model, SLOT(invalidated()));
35
36 connect(m_ui.add, &QPushButton::clicked, [this]() {
37 enterCheat(GBACheatAddLine);
38 });
39
40 connect(m_ui.addGSA, &QPushButton::clicked, [this]() {
41 enterCheat(GBACheatAddGameSharkLine);
42 });
43
44 connect(m_ui.addPAR, &QPushButton::clicked, [this]() {
45 enterCheat(GBACheatAddProActionReplayLine);
46 });
47
48 connect(m_ui.addCB, &QPushButton::clicked, [this]() {
49 enterCheat(GBACheatAddCodeBreakerLine);
50 });
51}
52
53bool CheatsView::eventFilter(QObject* object, QEvent* event) {
54 if (object != m_ui.cheatList) {
55 return false;
56 }
57 if (event->type() != QEvent::KeyPress) {
58 return false;
59 }
60 if (static_cast<QKeyEvent*>(event) == QKeySequence::Copy) {
61 QApplication::clipboard()->setText(m_model.toString(m_ui.cheatList->selectionModel()->selectedIndexes()));
62 return true;
63 }
64 return false;
65}
66
67void CheatsView::load() {
68 QString filename = GBAApp::app()->getOpenFileName(this, tr("Select cheats file"));
69 if (!filename.isEmpty()) {
70 m_model.loadFile(filename);
71 }
72}
73
74void CheatsView::save() {
75 QString filename = GBAApp::app()->getSaveFileName(this, tr("Select cheats file"));
76 if (!filename.isEmpty()) {
77 m_model.saveFile(filename);
78 }
79}
80
81void CheatsView::addSet() {
82 GBACheatSet* set = new GBACheatSet;
83 GBACheatSetInit(set, nullptr);
84 m_controller->threadInterrupt();
85 m_model.addSet(set);
86 m_controller->threadContinue();
87}
88
89void CheatsView::removeSet() {
90 GBACheatSet* set;
91 QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
92 if (selection.count() < 1) {
93 return;
94 }
95 m_controller->threadInterrupt();
96 for (const QModelIndex& index : selection) {
97 m_model.removeAt(selection[0]);
98 }
99 m_controller->threadContinue();
100}
101
102void CheatsView::enterCheat(std::function<bool(GBACheatSet*, const char*)> callback) {
103 GBACheatSet* set = nullptr;
104 QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
105 QModelIndex index;
106 if (selection.count() == 0) {
107 set = new GBACheatSet;
108 GBACheatSetInit(set, nullptr);
109 } else if (selection.count() == 1) {
110 index = selection[0];
111 set = m_model.itemAt(index);
112 }
113
114 if (!set) {
115 return;
116 }
117 m_controller->threadInterrupt();
118 if (selection.count() == 0) {
119 m_model.addSet(set);
120 index = m_model.index(m_model.rowCount() - 1, 0, QModelIndex());
121 m_ui.cheatList->selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
122 }
123 QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts);
124 for (const QString& string : cheats) {
125 m_model.beginAppendRow(index);
126 callback(set, string.toUtf8().constData());
127 m_model.endAppendRow();
128 }
129 m_controller->threadContinue();
130 m_ui.codeEntry->clear();
131}