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