d792f6934a4037a1e98c2a968b9594e6f8871fc0
[emufront] / src / models / filepathmodel.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
22 #include "filepathmodel.h"
23 #include "emufrontfile.h"
24 #include "emufrontexception.h"
25 #include <QtSql>
26
27 FilePathModel::FilePathModel(QObject *parent) :
28     EmuFrontQueryModel(parent)
29 {
30     refresh();
31 }
32
33 void FilePathModel::refresh()
34 {
35     setQuery(constructSelect());
36     setHeaderData(FilePath_Id, Qt::Horizontal, tr("Id"));
37     setHeaderData(FilePath_Name, Qt::Horizontal, tr("Name"));
38     setHeaderData(FilePath_LastScanned, Qt::Horizontal, tr("Last scanned"));
39     setHeaderData(FilePath_SetupId, Qt::Horizontal, tr("Set up id"));
40     setHeaderData(FilePath_SetupName, Qt::Horizontal, tr("Set up"));
41 }
42
43 QString FilePathModel::constructSelect(QString where) const
44 {
45     return QString("SELECT "
46                    "filepath.id AS FilePathId, "
47                    "filepath.name AS Name, "
48                    "datetime(filepath.lastscanned, 'unixepoch') AS LastScanned, "
49                    "setup.id AS SetupId, "
50                    "platform.name || ' ' || mediatype.name AS SetupName, "
51                    "filepath.filetypeid "
52                    "FROM filepath "
53                    "INNER JOIN setup ON filepath.setupid=setup.id  "
54                    "INNER JOIN platform ON setup.platformid=platform.id "
55                    "INNER JOIN mediatype ON setup.mediatypeid=mediatype.id "
56                    "%1 "
57                    "ORDER BY SetupName").arg(where);
58 }
59
60 Qt::ItemFlags FilePathModel::flags(const QModelIndex &index) const
61 {
62     Qt::ItemFlags flags = QSqlQueryModel::flags(index);
63     int col = index.column();
64     if (col == FilePath_SetupId ||
65         col == FilePath_Name) {
66         flags |= Qt::ItemIsEditable;
67     }
68     return flags;
69 }
70
71 bool FilePathModel::setData(const QModelIndex &index, const QVariant &value, int role)
72 {
73     int col = index.column();
74     if (col != FilePath_SetupId &&
75         col != FilePath_Name) {
76         return false;
77     }
78
79     QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), FilePath_Id);
80
81     int id = data(primaryKeyIndex).toInt();
82     clear();
83
84     bool ok;
85     switch(index.column()) {
86     case FilePath_SetupId:
87         ok = setSetup(id, value.toInt());
88         break;
89     case FilePath_Name:
90         ok = setFilePath(id, value.toString());
91         break;
92     default:
93         qDebug() << "File path model, this shouldn't be happening!";
94     }
95     refresh();
96     return ok;
97 }
98
99 bool FilePathModel::insertRows(int row, int count, const QModelIndex &parent)
100 {
101     if (parent.isValid())
102         return false; // This is a flat model
103     if (rowCount() < row)
104         row = rowCount() + 1;
105     int supId = -1;
106     QSqlQuery q;
107     q.exec(QString("SELECT setup.id, "
108            // The following is to get the correct order:
109            "platform.name || ' ' || mediatype.name AS SetupName "
110            "FROM setup "
111            "INNER JOIN platform ON setup.platformid=platform.id "
112            "INNER JOIN mediatype ON setup.mediatypeid=mediatype.id "
113            "ORDER BY SetupName "
114            "LIMIT 1"));
115     if (q.first()) {
116         supId = q.value(0).toInt();
117         qDebug() << "Got id " << supId << " for default setup.";
118     }
119     else {
120         throw EmuFrontException(tr("No setups yet available for file path configuration!"));
121     }
122     q.prepare(QString("INSERT INTO filepath "
123         "(id, name, filetypeid, setupid, lastscanned) "
124         "VALUES (NULL, '', :filetype, :setupid, :lastscanned )"));
125     beginInsertRows(QModelIndex(), row, row + count - 1);
126     for(int i = 0; i < count; ++i) {
127         q.bindValue(":filetype", EmuFrontFile::FileType_MediaImageContainer);
128         q.bindValue(":setupid", supId);
129         q.bindValue(":lastscanned", 0);
130         if (!q.exec()) {
131             throw EmuFrontException(tr("Failed creating new filepath row: %1").
132                                     arg(q.lastError().text()));
133         }
134     }
135     endInsertRows();
136     refresh();
137     return true;
138 }
139
140 bool FilePathModel::removeRows(int row, int count, const QModelIndex &parent)
141 {
142     if (parent.isValid()) {
143         return false; // This is a flat model
144     }
145     if (rowCount() < row + count - 1)
146         return false;
147
148     QSqlQuery q;
149     q.prepare(QString("DELETE FROM filepath WHERE id=:id"));
150     QModelIndex primaryIndex;
151     int id = -1;
152     beginRemoveRows(QModelIndex(), row, row + count - 1);
153     for(int i = 0; i < count; ++i) {
154         primaryIndex = QSqlQueryModel::index(row + i, FilePath_Id);
155         id = data(primaryIndex).toInt();
156         qDebug() << "Removing data item with id " << id;
157         q.bindValue(":id", id);
158         q.exec();
159     }
160     endRemoveRows();
161     refresh();
162     return true;
163 }
164
165 bool FilePathModel::setSetup(int id, int setupId)
166 {
167     QSqlQuery q;
168     q.prepare(QString("UPDATE filepath SET setupid = :setupid WHERE id = :id"));
169     q.bindValue(":setupid", setupId);
170     q.bindValue(":id", id);
171     return q.exec();
172 }
173
174 bool FilePathModel::setFilePath(int id, QString filePath)
175 {
176     QSqlQuery q;
177     q.prepare(QString("UPDATE filepath SET name = :name WHERE id = :id"));
178     q.bindValue(":name", filePath);
179     q.bindValue(":id", id);
180     return q.exec();
181 }