Don't show progress on MouseButtonRelease on Symbian.
[dorian] / model / library.cpp
1 #include "library.h"
2 #include "book.h"
3 #include "trace.h"
4 #include "bookdb.h"
5
6 static const char *DORIAN_VERSION =
7 #include "pkg/version.txt"
8 ;
9
10 static Library *theInstance = 0;
11
12 Library::Library(QObject *parent): QAbstractListModel(parent)
13 {
14 }
15
16 Library::~Library()
17 {
18     clear();
19 }
20
21 Library *Library::instance()
22 {
23     if (!theInstance) {
24         theInstance = new Library();
25     }
26     return theInstance;
27 }
28
29 int Library::rowCount(const QModelIndex &parent) const
30 {
31     if (parent.isValid()) {
32         return 0;
33     } else {
34         return mBooks.size();
35     }
36 }
37
38 QVariant Library::data(const QModelIndex &index, int role) const
39 {
40     QVariant ret;
41     if (!index.isValid()) {
42         return ret;
43     }
44
45     switch (role) {
46     case Qt::DisplayRole:
47         ret = mBooks[index.row()]->name();
48         break;
49     case Qt::DecorationRole:
50         ret.setValue(mBooks[index.row()]->coverImage());
51         break;
52     default:
53         ;
54     }
55
56     return ret;
57 }
58
59 Book *Library::book(const QModelIndex &index)
60 {
61     if (index.isValid()) {
62         if ((index.row() >= 0) && (index.row() < mBooks.size())) {
63             return mBooks[index.row()];
64         } else {
65             qCritical() << "Library::book: Bad index" << index.row();
66         }
67     }
68     return 0;
69 }
70
71 void Library::close()
72 {
73     delete theInstance;
74     theInstance = 0;
75 }
76
77 void Library::load()
78 {
79     TRACE;
80
81     clear();
82     QStringList books = BookDb::instance()->books();
83     emit beginLoad(books.size());
84
85     foreach(QString path, books) {
86         emit loading(path);
87         Book *book = new Book(path);
88         connect(book, SIGNAL(opened(const QString &)),
89                 this, SLOT(onBookOpened(const QString &)));
90         // book->load();
91         mBooks.append(book);
92     }
93
94     QSettings settings;
95     QString currentPath = settings.value("lib/nowreading").toString();
96     mNowReading = find(currentPath);
97     emit endLoad();
98 }
99
100 void Library::save()
101 {
102     TRACE;
103     QSettings settings;
104     Book *currentBook = book(mNowReading);
105     settings.setValue("lib/nowreading",
106                       currentBook? currentBook->path(): QString());
107 }
108
109 bool Library::add(const QString &path)
110 {
111     TRACE;
112     if (path == "") {
113         qCritical() << "Library::add: Empty path";
114         return false;
115     }
116     if (find(path).isValid()) {
117         qDebug() << "Book already exists in library";
118         return false;
119     }
120     int size = mBooks.size();
121     beginInsertRows(QModelIndex(), size, size);
122     Book *book = new Book(path);
123     book->peek();
124     book->dateAdded = QDateTime::currentDateTime().toUTC();
125     mBooks.append(book);
126     save();
127     endInsertRows();
128     return true;
129 }
130
131 void Library::remove(const QModelIndex &index)
132 {
133     TRACE;
134     Book *toRemove = book(index);
135     if (!toRemove) {
136         return;
137     }
138     if (index == mNowReading) {
139         mNowReading = QModelIndex();
140         emit nowReadingChanged();
141     }
142     toRemove->remove();
143     int row = index.row();
144     beginRemoveRows(QModelIndex(), row, row);
145     mBooks.removeAt(row);
146     save();
147     endRemoveRows();
148     delete toRemove;
149 }
150
151 void Library::remove(const QString &path)
152 {
153     TRACE;
154     remove(find(path));
155 }
156
157 QModelIndex Library::nowReading() const
158 {
159     return mNowReading;
160 }
161
162 void Library::setNowReading(const QModelIndex &index)
163 {
164     mNowReading = index;
165     save();
166     emit nowReadingChanged();
167 }
168
169 void Library::clear()
170 {
171     TRACE;
172     for (int i = 0; i < mBooks.size(); i++) {
173         delete mBooks[i];
174     }
175     mBooks.clear();
176     mNowReading = QModelIndex();
177 }
178
179 QModelIndex Library::find(QString path) const
180 {
181     TRACE;
182     if (path != "") {
183         QString absolutePath = QFileInfo(path).absoluteFilePath();
184         for (int i = 0; i < mBooks.size(); i++) {
185             if (absolutePath == mBooks[i]->path()) {
186                 return index(i);
187             }
188         }
189     }
190     return QModelIndex();
191 }
192
193 QModelIndex Library::find(const Book *book) const
194 {
195     TRACE;
196     if (book) {
197         for (int i = 0; i < mBooks.size(); i++) {
198             if (book == mBooks[i]) {
199                 return index(i);
200             }
201         }
202     }
203     return QModelIndex();
204 }
205
206 void Library::onBookOpened(const QString &path)
207 {
208     TRACE;
209     QModelIndex index = find(path);
210     if (index.isValid()) {
211         emit dataChanged(index, index);
212     }
213 }
214
215 QStringList Library::bookPaths()
216 {
217     QStringList ret;
218     foreach (Book *book, mBooks) {
219         ret.append(book->path());
220     }
221     return ret;
222 }
223
224 void Library::upgrade()
225 {
226     TRACE;
227     QSettings settings;
228     QString oldVersion = settings.value("lib/version").toString();
229     if (oldVersion.isEmpty()) {
230         int size = settings.value("lib/size").toInt();
231         emit beginUpgrade(size);
232         for (int i = 0; i < size; i++) {
233             QString key = "lib/book" + QString::number(i);
234             QString path = settings.value(key).toString();
235             emit upgrading(path);
236             Book *book = new Book(path);
237             book->upgrade();
238         }
239     } else {
240         emit beginUpgrade(0);
241     }
242     settings.setValue("lib/version", QString(DORIAN_VERSION));
243     emit endUpgrade();
244 }