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