src/platform/qt/CheatsModel.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 "CheatsModel.h"
7
8#include <QFont>
9
10extern "C" {
11#include "gba/cheats.h"
12#include "util/vfs.h"
13}
14
15using namespace QGBA;
16
17CheatsModel::CheatsModel(GBACheatDevice* device, QObject* parent)
18 : QAbstractItemModel(parent)
19 , m_device(device)
20{
21}
22
23QVariant CheatsModel::data(const QModelIndex& index, int role) const {
24 if (!index.isValid()) {
25 return QVariant();
26 }
27
28 if (index.parent().isValid()) {
29 int row = index.row();
30 GBACheatSet* cheats = static_cast<GBACheatSet*>(index.internalPointer());
31 const char* line = *StringListGetPointer(&cheats->lines, row);
32 switch (role) {
33 case Qt::DisplayRole:
34 return line;
35 case Qt::FontRole:
36 return QFont("Courier New", 13);
37 default:
38 return QVariant();
39 }
40 }
41
42 int row = index.row();
43 const GBACheatSet* cheats = *GBACheatSetsGetPointer(&m_device->cheats, index.row());
44 switch (role) {
45 case Qt::DisplayRole:
46 case Qt::EditRole:
47 return cheats->name ? cheats->name : tr("(untitled)");
48 case Qt::CheckStateRole:
49 return cheats->enabled ? Qt::Checked : Qt::Unchecked;
50 default:
51 return QVariant();
52 }
53}
54
55bool CheatsModel::setData(const QModelIndex& index, const QVariant& value, int role) {
56 if (!index.isValid() || index.parent().isValid()) {
57 return false;
58 }
59
60 int row = index.row();
61 GBACheatSet* cheats = *GBACheatSetsGetPointer(&m_device->cheats, index.row());
62 switch (role) {
63 case Qt::DisplayRole:
64 case Qt::EditRole:
65 if (cheats->name) {
66 free(cheats->name);
67 cheats->name = nullptr;
68 }
69 cheats->name = strdup(value.toString().toLocal8Bit().constData());
70 emit dataChanged(index, index);
71 return true;
72 case Qt::CheckStateRole:
73 cheats->enabled = value == Qt::Checked;
74 emit dataChanged(index, index);
75 return true;
76 default:
77 return false;
78 }
79}
80
81QModelIndex CheatsModel::index(int row, int column, const QModelIndex& parent) const {
82 if (parent.isValid()) {
83 return createIndex(row, column, *GBACheatSetsGetPointer(&m_device->cheats, parent.row()));
84 } else {
85 return createIndex(row, column, nullptr);
86 }
87}
88
89QModelIndex CheatsModel::parent(const QModelIndex& index) const {
90 if (!index.isValid()) {
91 return QModelIndex();
92 }
93 const GBACheatSet* cheats = static_cast<const GBACheatSet*>(index.internalPointer());
94 if (!cheats) {
95 return QModelIndex();
96 }
97 for (size_t i = 0; i < GBACheatSetsSize(&m_device->cheats); ++i) {
98 if (cheats == *GBACheatSetsGetPointer(&m_device->cheats, i)) {
99 return createIndex(i, 0, nullptr);
100 }
101 }
102 return QModelIndex();
103}
104
105Qt::ItemFlags CheatsModel::flags(const QModelIndex &index) const {
106 if (!index.isValid()) {
107 return 0;
108 }
109
110 if (index.parent().isValid()) {
111 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
112 }
113
114 return Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
115}
116
117int CheatsModel::columnCount(const QModelIndex& parent) const {
118 return 1;
119}
120
121int CheatsModel::rowCount(const QModelIndex& parent) const {
122 if (parent.isValid()) {
123 if (parent.internalPointer()) {
124 return 0;
125 }
126 const GBACheatSet* set = *GBACheatSetsGetPointer(&m_device->cheats, parent.row());
127 return StringListSize(&set->lines);
128 }
129 return GBACheatSetsSize(&m_device->cheats);
130}
131
132GBACheatSet* CheatsModel::itemAt(const QModelIndex& index) {
133 if (!index.isValid()) {
134 return nullptr;
135 }
136 if (index.parent().isValid()) {
137 return static_cast<GBACheatSet*>(index.internalPointer());
138 }
139 return *GBACheatSetsGetPointer(&m_device->cheats, index.row());
140}
141
142void CheatsModel::removeAt(const QModelIndex& index) {
143 if (!index.isValid() || index.parent().isValid()) {
144 return;
145 }
146 int row = index.row();
147 GBACheatSet* set = *GBACheatSetsGetPointer(&m_device->cheats, index.row());
148 beginRemoveRows(QModelIndex(), row, row);
149 GBACheatRemoveSet(m_device, set);
150 GBACheatSetDeinit(set);
151 delete set;
152 endInsertRows();
153
154}
155
156void CheatsModel::beginAppendRow(const QModelIndex& index) {
157 if (index.parent().isValid()) {
158 beginInsertRows(index.parent(), rowCount(index.parent()), rowCount(index.parent()));
159 return;
160 }
161 beginInsertRows(index, rowCount(index), rowCount(index));
162}
163
164void CheatsModel::endAppendRow() {
165 endInsertRows();
166}
167
168void CheatsModel::loadFile(const QString& path) {
169 VFile* vf = VFileOpen(path.toLocal8Bit().constData(), O_RDONLY);
170 if (!vf) {
171 return;
172 }
173 beginResetModel();
174 GBACheatParseFile(m_device, vf);
175 endResetModel();
176 vf->close(vf);
177}
178
179void CheatsModel::addSet(GBACheatSet* set) {
180 beginInsertRows(QModelIndex(), GBACheatSetsSize(&m_device->cheats), GBACheatSetsSize(&m_device->cheats));
181 GBACheatAddSet(m_device, set);
182 endInsertRows();
183}
184
185void CheatsModel::invalidated() {
186 beginResetModel();
187 endResetModel();
188}