all repos — mgba @ 4827daf5a6e30ed9b147b814e7ca165dab395a4f

mGBA Game Boy Advance Emulator

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 mPLATFORM_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 mPLATFORM_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	QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
133	if (selection.count() < 1) {
134		return;
135	}
136	CoreController::Interrupter interrupter(m_controller);
137	for (const QModelIndex& index : selection) {
138		m_model.removeAt(selection[0]);
139	}
140}
141
142void CheatsView::enterCheat(int codeType) {
143	mCheatSet* set = nullptr;
144	QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();
145	QModelIndex index;
146	if (selection.count() == 0) {
147		set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr);
148	} else if (selection.count() == 1) {
149		index = selection[0];
150		set = m_model.itemAt(index);
151	}
152
153	if (!set) {
154		return;
155	}
156	CoreController::Interrupter interrupter(m_controller);
157	if (selection.count() == 0) {
158		m_model.addSet(set);
159		index = m_model.index(m_model.rowCount() - 1, 0, QModelIndex());
160		m_ui.cheatList->selectionModel()->select(index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
161	}
162	QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts);
163	for (const QString& string : cheats) {
164		m_model.beginAppendRow(index);
165		mCheatAddLine(set, string.toUtf8().constData(), codeType);
166		m_model.endAppendRow();
167	}
168	if (set->refresh) {
169		set->refresh(set, m_controller->cheatDevice());
170	}
171	m_ui.codeEntry->clear();
172}