all repos — mgba @ a9620df0b8fbe74d48a6f459592049291a93948e

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