a1aebc41521c0064b8279b12aa9e16df861e6cdb
[emufront] / src / models / setupmodel.cpp
1 // EmuFront
2 // Copyright 2010 Mikko Keinänen
3 //
4 // This file is part of EmuFront.
5 //
6 //
7 // EmuFront is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as published by
9 // the Free Software Foundation and appearing in the file gpl.txt included in the
10 // packaging of this file.
11 //
12 // EmuFront is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
19
20 #include "setupmodel.h"
21 #include "emufrontexception.h"
22 #include <QtSql>
23
24 const QString SetupModel::FILE_TYPE_EXTENSION_SEPARATOR = QString("|");
25
26 SetupModel::SetupModel(QObject *parent) :
27     EmuFrontQueryModel(parent)
28 {
29     refresh();
30 }
31
32 void SetupModel::refresh()
33 {
34     setQuery(constructSelect());
35     setHeaderData(Setup_Id, Qt::Horizontal, tr("Id"));
36     setHeaderData(Setup_PlatformId, Qt::Horizontal, tr("Platform id"));
37     setHeaderData(Setup_MediaTypeId, Qt::Horizontal, tr("Media type id"));
38     setHeaderData(Setup_FileTypeExtensions, Qt::Horizontal, tr("File types"));
39     setHeaderData(Setup_Name, Qt::Horizontal, tr("Name"));
40 }
41
42 QString SetupModel::constructSelect(QString where) const
43 {
44     return QString(
45         "SELECT setup.id AS SetupId, "
46         "setup.platformid AS PlatformId, "
47         "setup.mediatypeid AS MediaTypeId, "
48         "setup.filetypeextensions AS SupportedFileTypeExtensions, "
49         "platform.name || ' ' || mediatype.name AS SetupName "
50         "FROM setup "
51         "INNER JOIN platform ON setup.platformid=platform.id "
52         "INNER JOIN mediatype ON setup.mediatypeid=mediatype.id %1 "
53         "ORDER BY SetupName"
54         ).arg(where);
55 }
56
57 Qt::ItemFlags SetupModel::flags(const QModelIndex &index) const
58 {
59     Qt::ItemFlags flags = QSqlQueryModel::flags(index);
60     int col = index.column();
61     if (col == Setup_PlatformId ||
62         col == Setup_MediaTypeId ||
63         col == Setup_FileTypeExtensions) {
64         flags |= Qt::ItemIsEditable;
65     }
66     return flags;
67 }
68
69 bool SetupModel::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
70 {
71     int col = index.column();
72     if(col != Setup_PlatformId &&
73         col != Setup_MediaTypeId &&
74         col != Setup_FileTypeExtensions)
75         return false;
76
77     QModelIndex primaryKeyIndex
78         = QSqlQueryModel::index(index.row(), Setup_Id);
79
80     int id = data(primaryKeyIndex).toInt();
81     clear();
82
83     bool ok;
84     switch(index.column()) {
85
86     case Setup_PlatformId:
87         ok = setPlatform(id, value.toInt());
88         break;
89
90     case Setup_MediaTypeId:
91         ok = setMediaType(id, value.toInt());
92         break;
93
94     case Setup_FileTypeExtensions:
95         ok = setSupportedExtensions(id, value.toString());
96         break;
97
98     default:
99         qDebug() << "Setup model, this shouldn't be happening!";
100     };
101     refresh();
102     return ok;
103 }
104
105 bool SetupModel::setPlatform(int id, int platformId)
106 {
107     QSqlQuery query;
108     query.prepare(QString("update setup set platformid = :platformid where id = :id"));
109     query.bindValue(":platformid", platformId);
110     query.bindValue(":id", id);
111     return query.exec();
112 }
113
114 bool SetupModel::setMediaType(int id, int mediaTypeId)
115 {
116     QSqlQuery query;
117     query.prepare(QString("update setup set mediatypeid = :mediatypeid where id = :id"));
118     query.bindValue(":mediatypeid", mediaTypeId);
119     query.bindValue(":id", id);
120     return query.exec();
121 }
122
123 bool SetupModel::setSupportedExtensions(int id, QString exts)
124 {
125     QSqlQuery query;
126     query.prepare(QString("update setup set filetypeextensions = :exts where id = :id"));
127     query.bindValue(":exts", exts);
128     query.bindValue(":id", id);
129     return query.exec();
130 }
131
132 bool SetupModel::insertRows(int row, int count, const QModelIndex &parent)
133 {
134     if (parent.isValid())
135         return false; // This is a flat model
136     if (rowCount() < row)
137         row = rowCount() + 1;
138     // we need a default value for platformid and mediatypeid and if none is yet
139     // available an error message must be shown!
140     int plfId = -1;
141     int mdtId = -1;
142     QSqlQuery q;
143     q.exec(QString("SELECT id FROM platform ORDER BY name LIMIT 1"));
144     if (q.first()){
145         plfId = q.value(0).toInt();
146         qDebug() << "Got id " << plfId << " for default platform.";
147     }
148     else {
149         throw EmuFrontException(tr("No platforms yet available for setup configuration!"));
150     }
151     q.exec(QString("SELECT id FROM mediatype ORDER BY name LIMIT 1"));
152     if (q.first()) {
153         mdtId = q.value(0).toInt();
154         qDebug() << "Got id " << mdtId << " for default media type.";
155     }
156     else {
157         throw EmuFrontException(tr("No media types yet available for setup configuration!"));
158     }
159     q.prepare(QString("INSERT INTO setup (id, platformid, mediatypeid, filetypeextensions) "
160         " VALUES (NULL, :plfid, :mdtid, '') "));
161     beginInsertRows(QModelIndex(), row, row + count - 1);
162     for (int i = 0; i < count; ++i) {
163         q.bindValue(":plfid", plfId);
164         q.bindValue(":mdtid", mdtId);
165         if (!q.exec()) {
166             throw EmuFrontException(tr("Failed creating new setup: %1").
167                 arg(q.lastError().text()));
168         }
169     }
170     endInsertRows();
171     refresh();
172     return true;
173 }
174
175 bool SetupModel::removeRows(int row, int count, const QModelIndex &parent)
176 {
177     if (parent.isValid()) {
178         return false; // This is a flat model
179     }
180     if (rowCount() < row + count - 1)
181         return false;
182
183     QSqlQuery q;
184     q.prepare(QString("DELETE FROM setup WHERE id=:id"));
185     QModelIndex primaryIndex;
186     int id = -1;
187     beginRemoveRows(QModelIndex(), row, row + count - 1);
188     for(int i = 0; i < count; ++i) {
189         primaryIndex = QSqlQueryModel::index(row + i, Setup_Id);
190         id = data(primaryIndex).toInt();
191         qDebug() << "Removing data item with id " << id;
192         q.bindValue(":id", id);
193         q.exec();
194     }
195     endRemoveRows();
196     refresh();
197     return true;
198 }
199