Changeset View
Changeset View
Standalone View
Standalone View
src/qtquick/BookListModel.cpp
Show All 21 Lines | |||||
22 | #include "BookListModel.h" | 22 | #include "BookListModel.h" | ||
23 | 23 | | |||
24 | #include "BookDatabase.h" | 24 | #include "BookDatabase.h" | ||
25 | #include "CategoryEntriesModel.h" | 25 | #include "CategoryEntriesModel.h" | ||
26 | #include "ArchiveBookModel.h" | 26 | #include "ArchiveBookModel.h" | ||
27 | 27 | | |||
28 | #include "AcbfAuthor.h" | 28 | #include "AcbfAuthor.h" | ||
29 | #include "AcbfSequence.h" | 29 | #include "AcbfSequence.h" | ||
30 | #include "AcbfBookinfo.h" | ||||
30 | 31 | | |||
31 | #include <kio/deletejob.h> | 32 | #include <kio/deletejob.h> | ||
33 | #include <KFileMetaData/UserMetaData> | ||||
32 | 34 | | |||
33 | #include <QCoreApplication> | 35 | #include <QCoreApplication> | ||
34 | #include <QDir> | 36 | #include <QDir> | ||
35 | #include <QDebug> | 37 | #include <QDebug> | ||
36 | #include <QMimeDatabase> | 38 | #include <QMimeDatabase> | ||
37 | #include <QTimer> | 39 | #include <QTimer> | ||
38 | #include <QUrl> | 40 | #include <QUrl> | ||
39 | 41 | | |||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Line(s) | 102 | { | |||
104 | emit q->folderCategoryModel(); | 106 | emit q->folderCategoryModel(); | ||
105 | } | 107 | } | ||
106 | } | 108 | } | ||
107 | 109 | | |||
108 | void addEntry(BookListModel* q, BookEntry* entry) { | 110 | void addEntry(BookListModel* q, BookEntry* entry) { | ||
109 | entries.append(entry); | 111 | entries.append(entry); | ||
110 | q->append(entry); | 112 | q->append(entry); | ||
111 | titleCategoryModel->addCategoryEntry(entry->title.left(1).toUpper(), entry); | 113 | titleCategoryModel->addCategoryEntry(entry->title.left(1).toUpper(), entry); | ||
112 | authorCategoryModel->addCategoryEntry(entry->author, entry); | 114 | for (int i=0; i<entry->author.size(); i++) { | ||
113 | seriesCategoryModel->addCategoryEntry(entry->series, entry); | 115 | authorCategoryModel->addCategoryEntry(entry->author.at(i), entry); | ||
116 | } | ||||
117 | for (int i=0; i<entry->series.size(); i++) { | ||||
118 | seriesCategoryModel->addCategoryEntry(entry->series.at(i), entry); | ||||
119 | } | ||||
114 | newlyAddedCategoryModel->append(entry, CreatedRole); | 120 | newlyAddedCategoryModel->append(entry, CreatedRole); | ||
115 | QUrl url(entry->filename.left(entry->filename.lastIndexOf("/"))); | 121 | QUrl url(entry->filename.left(entry->filename.lastIndexOf("/"))); | ||
116 | folderCategoryModel->addCategoryEntry(url.path().mid(1), entry); | 122 | folderCategoryModel->addCategoryEntry(url.path().mid(1), entry); | ||
117 | folderCategoryModel->append(entry); | 123 | folderCategoryModel->append(entry); | ||
118 | } | 124 | } | ||
119 | 125 | | |||
120 | void loadCache(BookListModel* q) { | 126 | void loadCache(BookListModel* q) { | ||
121 | QList<BookEntry*> entries = db->loadEntries(); | 127 | QList<BookEntry*> entries = db->loadEntries(); | ||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | 187 | { | |||
187 | { | 193 | { | ||
188 | QVariant filePath = d->contentModel->data(d->contentModel->index(first, 0, index), role); | 194 | QVariant filePath = d->contentModel->data(d->contentModel->index(first, 0, index), role); | ||
189 | BookEntry* entry = new BookEntry(); | 195 | BookEntry* entry = new BookEntry(); | ||
190 | entry->filename = filePath.toUrl().toLocalFile(); | 196 | entry->filename = filePath.toUrl().toLocalFile(); | ||
191 | QStringList splitName = entry->filename.split("/"); | 197 | QStringList splitName = entry->filename.split("/"); | ||
192 | if (!splitName.isEmpty()) | 198 | if (!splitName.isEmpty()) | ||
193 | entry->filetitle = splitName.takeLast(); | 199 | entry->filetitle = splitName.takeLast(); | ||
194 | if(!splitName.isEmpty()) | 200 | if(!splitName.isEmpty()) | ||
195 | entry->series = splitName.takeLast(); // hahahaheuristics (dumb assumptions about filesystems, go!) | 201 | entry->series = QStringList(splitName.takeLast()); // hahahaheuristics (dumb assumptions about filesystems, go!) | ||
196 | // just in case we end up without a title... using complete basename here, | 202 | // just in case we end up without a title... using complete basename here, | ||
197 | // as we would rather have "book one. part two" and the odd "book one - part two.tar" | 203 | // as we would rather have "book one. part two" and the odd "book one - part two.tar" | ||
198 | QFileInfo fileinfo(entry->filename); | 204 | QFileInfo fileinfo(entry->filename); | ||
199 | entry->title = fileinfo.completeBaseName(); | 205 | entry->title = fileinfo.completeBaseName(); | ||
200 | 206 | | |||
201 | if(entry->filename.toLower().endsWith("cbr")) { | 207 | if(entry->filename.toLower().endsWith("cbr")) { | ||
202 | entry->thumbnail = QString("image://comiccover/").append(entry->filename); | 208 | entry->thumbnail = QString("image://comiccover/").append(entry->filename); | ||
203 | } | 209 | } | ||
204 | #ifdef USE_PERUSE_PDFTHUMBNAILER | 210 | #ifdef USE_PERUSE_PDFTHUMBNAILER | ||
205 | else if(entry->filename.toLower().endsWith("pdf")) { | 211 | else if(entry->filename.toLower().endsWith("pdf")) { | ||
206 | entry->thumbnail = QString("image://pdfcover/").append(entry->filename); | 212 | entry->thumbnail = QString("image://pdfcover/").append(entry->filename); | ||
207 | } | 213 | } | ||
208 | #endif | 214 | #endif | ||
209 | else { | 215 | else { | ||
210 | entry->thumbnail = QString("image://preview/").append(entry->filename); | 216 | entry->thumbnail = QString("image://preview/").append(entry->filename); | ||
211 | } | 217 | } | ||
212 | 218 | | |||
219 | KFileMetaData::UserMetaData data(entry->filename); | ||||
220 | entry->rating = data.rating(); | ||||
221 | entry->comment = data.userComment(); | ||||
222 | entry->tags = data.tags(); | ||||
223 | | ||||
213 | QVariantHash metadata = d->contentModel->data(d->contentModel->index(first, 0, index), Qt::UserRole + 2).toHash(); | 224 | QVariantHash metadata = d->contentModel->data(d->contentModel->index(first, 0, index), Qt::UserRole + 2).toHash(); | ||
214 | QVariantHash::const_iterator it = metadata.constBegin(); | 225 | QVariantHash::const_iterator it = metadata.constBegin(); | ||
215 | for (; it != metadata.constEnd(); it++) { | 226 | for (; it != metadata.constEnd(); it++) { | ||
216 | if(it.key() == QLatin1String("author")) | 227 | if(it.key() == QLatin1String("author")) | ||
217 | { entry->author = it.value().toString().trimmed(); } | 228 | { entry->author = it.value().toStringList(); } | ||
218 | else if(it.key() == QLatin1String("title")) | 229 | else if(it.key() == QLatin1String("title")) | ||
219 | { entry->title = it.value().toString().trimmed(); } | 230 | { entry->title = it.value().toString().trimmed(); } | ||
220 | else if(it.key() == QLatin1String("publisher")) | 231 | else if(it.key() == QLatin1String("publisher")) | ||
221 | { entry->publisher = it.value().toString().trimmed(); } | 232 | { entry->publisher = it.value().toString().trimmed(); } | ||
222 | else if(it.key() == QLatin1String("created")) | 233 | else if(it.key() == QLatin1String("created")) | ||
223 | { entry->created = it.value().toDateTime(); } | 234 | { entry->created = it.value().toDateTime(); } | ||
224 | else if(it.key() == QLatin1String("currentPage")) | 235 | else if(it.key() == QLatin1String("currentPage")) | ||
225 | { entry->currentPage = it.value().toInt(); } | 236 | { entry->currentPage = it.value().toInt(); } | ||
226 | else if(it.key() == QLatin1String("totalPages")) | 237 | else if(it.key() == QLatin1String("totalPages")) | ||
227 | { entry->totalPages = it.value().toInt(); } | 238 | { entry->totalPages = it.value().toInt(); } | ||
239 | else if(it.key() == QLatin1String("comments")) | ||||
240 | { entry->comment = it.value().toString();} | ||||
241 | else if(it.key() == QLatin1Literal("tags")) | ||||
242 | { entry->tags = it.value().toStringList();} | ||||
243 | else if(it.key() == QLatin1String("rating")) | ||||
244 | { entry->rating = it.value().toInt();} | ||||
228 | } | 245 | } | ||
229 | // ACBF information is always preferred for CBRs, so let's just use that if it's there | 246 | // ACBF information is always preferred for CBRs, so let's just use that if it's there | ||
230 | QMimeDatabase db; | 247 | QMimeDatabase db; | ||
231 | QString mimetype = db.mimeTypeForFile(entry->filename).name(); | 248 | QString mimetype = db.mimeTypeForFile(entry->filename).name(); | ||
232 | if(mimetype == "application/x-cbz" || mimetype == "application/x-cbr" || mimetype == "application/vnd.comicbook+zip" || mimetype == "application/vnd.comicbook+rar") { | 249 | if(mimetype == "application/x-cbz" || mimetype == "application/x-cbr" || mimetype == "application/vnd.comicbook+zip" || mimetype == "application/vnd.comicbook+rar") { | ||
233 | ArchiveBookModel* bookModel = new ArchiveBookModel(this); | 250 | ArchiveBookModel* bookModel = new ArchiveBookModel(this); | ||
234 | bookModel->setFilename(entry->filename); | 251 | bookModel->setFilename(entry->filename); | ||
235 | 252 | | |||
236 | AdvancedComicBookFormat::Document* acbfDocument = qobject_cast<AdvancedComicBookFormat::Document*>(bookModel->acbfData()); | 253 | AdvancedComicBookFormat::Document* acbfDocument = qobject_cast<AdvancedComicBookFormat::Document*>(bookModel->acbfData()); | ||
237 | if(acbfDocument) { | 254 | if(acbfDocument) { | ||
238 | for(AdvancedComicBookFormat::Sequence* sequence : acbfDocument->metaData()->bookInfo()->sequence()) { | 255 | for(AdvancedComicBookFormat::Sequence* sequence : acbfDocument->metaData()->bookInfo()->sequence()) { | ||
239 | entry->series = sequence->title(); | 256 | entry->series.append(sequence->title()); | ||
240 | break; | 257 | } | ||
258 | for(AdvancedComicBookFormat::Author* author : acbfDocument->metaData()->bookInfo()->author()) { | ||||
259 | entry->author.append(author->displayName()); | ||||
260 | } | ||||
261 | entry->description = acbfDocument->metaData()->bookInfo()->annotation(""); | ||||
241 | } | 262 | } | ||
263 | | ||||
264 | if (entry->author.isEmpty()) { | ||||
265 | entry->author.append(bookModel->author()); | ||||
242 | } | 266 | } | ||
243 | // TODO extend the model to support multiple authors per book, ditto series/sequences | | |||
244 | entry->author = bookModel->author(); | | |||
245 | entry->title = bookModel->title(); | 267 | entry->title = bookModel->title(); | ||
246 | entry->publisher = bookModel->publisher(); | 268 | entry->publisher = bookModel->publisher(); | ||
247 | entry->totalPages = bookModel->pageCount(); | 269 | entry->totalPages = bookModel->pageCount(); | ||
248 | bookModel->deleteLater(); | 270 | bookModel->deleteLater(); | ||
249 | } | 271 | } | ||
250 | 272 | | |||
251 | d->addEntry(this, entry); | 273 | d->addEntry(this, entry); | ||
252 | d->db->addEntry(entry); | 274 | d->db->addEntry(entry); | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 328 | { | |||
307 | if(property == "totalPages") | 329 | if(property == "totalPages") | ||
308 | { | 330 | { | ||
309 | entry->totalPages = value.toInt(); | 331 | entry->totalPages = value.toInt(); | ||
310 | } | 332 | } | ||
311 | else if(property == "currentPage") | 333 | else if(property == "currentPage") | ||
312 | { | 334 | { | ||
313 | entry->currentPage = value.toInt(); | 335 | entry->currentPage = value.toInt(); | ||
314 | } | 336 | } | ||
337 | else if(property == "rating") | ||||
338 | { | ||||
339 | entry->rating = value.toInt(); | ||||
340 | } | ||||
341 | else if(property == "tags") | ||||
342 | { | ||||
343 | entry->tags = value.split(","); | ||||
344 | } | ||||
345 | else if(property == "comment") { | ||||
346 | entry->comment = value; | ||||
347 | } | ||||
315 | emit entryDataUpdated(entry); | 348 | emit entryDataUpdated(entry); | ||
316 | break; | 349 | break; | ||
317 | } | 350 | } | ||
318 | } | 351 | } | ||
319 | } | 352 | } | ||
320 | 353 | | |||
321 | void BookListModel::removeBook(QString fileName, bool deleteFile) | 354 | void BookListModel::removeBook(QString fileName, bool deleteFile) | ||
322 | { | 355 | { | ||
Show All 24 Lines |