X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=model%2Fbook.cpp;h=d2098165497f2bc8183792b2dc67794f41fd6022;hb=b855b46f739479ca0d6dd15b73a4c56a8d8a2d2c;hp=8fc6f69298e2e6c05a5ad1cc58f0828bad99e42e;hpb=9013e91f2a2af2219a639156389e4e356ec36701;p=dorian diff --git a/model/book.cpp b/model/book.cpp index 8fc6f69..d209816 100644 --- a/model/book.cpp +++ b/model/book.cpp @@ -1,12 +1,5 @@ -#include -#include -#include -#include #include // Qt::escape is currently defined here... -#include -#include -#include -#include +#include #include "book.h" #include "opshandler.h" @@ -16,40 +9,40 @@ #include "containerhandler.h" #include "ncxhandler.h" #include "trace.h" +#include "bookdb.h" const int COVER_WIDTH = 53; const int COVER_HEIGHT = 59; +const int COVER_MAX = 512 * 1024; -static QImage makeCover(const QString &path) -{ - return QImage(path).scaled(COVER_WIDTH, COVER_HEIGHT, - Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation). - scaled(COVER_WIDTH, COVER_HEIGHT, Qt::KeepAspectRatio); -} - -Book::Book(const QString &p, QObject *parent): QObject(parent) +Book::Book(const QString &p, QObject *parent): QObject(parent), loaded(false) { mPath = ""; if (p.size()) { QFileInfo info(p); mPath = info.absoluteFilePath(); title = info.baseName(); - cover = makeCover(":/icons/book.png"); mTempFile.open(); } } -QString Book::path() const +Book::~Book() +{ + close(); +} + +QString Book::path() { return mPath; } bool Book::open() { - Trace t("Book::open"); + TRACE; qDebug() << path(); close(); clear(); + load(); if (path().isEmpty()) { title = "No book"; return false; @@ -67,10 +60,11 @@ bool Book::open() void Book::peek() { - Trace t("Book::peek"); + TRACE; qDebug() << path(); close(); clear(); + load(); if (path().isEmpty()) { title = "No book"; return; @@ -87,7 +81,7 @@ void Book::peek() void Book::close() { - Trace t("Book::close"); + TRACE; content.clear(); parts.clear(); QDir::setCurrent(QDir::rootPath()); @@ -103,11 +97,12 @@ QString Book::tmpDir() const bool Book::extract(const QStringList &excludedExtensions) { - Trace t("Book::extract"); + TRACE; bool ret = false; QString tmp = tmpDir(); qDebug() << "Extracting" << mPath << "to" << tmp; + load(); QDir::setCurrent(QDir::rootPath()); if (!clearDir(tmp)) { qCritical() << "Book::extract: Failed to remove" << tmp; @@ -149,7 +144,9 @@ bool Book::extract(const QStringList &excludedExtensions) bool Book::parse() { - Trace t("Book::parse"); + TRACE; + + load(); // Parse OPS file bool ret = false; @@ -275,109 +272,105 @@ void Book::clear() void Book::load() { - Trace t("Book::load"); + if (loaded) { + return; + } + + TRACE; + loaded = true; qDebug() << "path" << path(); - QSettings settings; - QString key = "book/" + path() + "/"; - qDebug() << "key" << key; - // Load book info - title = settings.value(key + "title").toString(); + QVariantHash data = BookDb::instance()->load(path()); + title = data["title"].toString(); qDebug() << title; - creators = settings.value(key + "creators").toStringList(); - date = settings.value(key + "date").toString(); - publisher = settings.value(key + "publisher").toString(); - datePublished = settings.value(key + "datepublished").toString(); - subject = settings.value(key + "subject").toString(); - source = settings.value(key + "source").toString(); - rights = settings.value(key + "rights").toString(); - mLastBookmark.part = settings.value(key + "lastpart").toInt(); - mLastBookmark.pos = settings.value(key + "lastpos").toReal(); - cover = settings.value(key + "cover").value().scaled(COVER_WIDTH, - COVER_HEIGHT, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + creators = data["creators"].toStringList(); + date = data["date"].toString(); + publisher = data["publisher"].toString(); + datePublished = data["datepublished"].toString(); + subject = data["subject"].toString(); + source = data["source"].toString(); + rights = data["rights"].toString(); + mLastBookmark.part = data["lastpart"].toInt(); + mLastBookmark.pos = data["lastpos"].toReal(); + cover = data["cover"].value(); if (cover.isNull()) { cover = makeCover(":/icons/book.png"); } - - // Load bookmarks - int size = settings.value(key + "bookmarks").toInt(); + int size = data["bookmarks"].toInt(); for (int i = 0; i < size; i++) { - int part = settings.value(key + "bookmark" + QString::number(i) + - "/part").toInt(); - qreal pos = settings.value(key + "bookmark" + QString::number(i) + - "/pos").toReal(); - qDebug() << QString("Bookmark %1 at part %2, %3"). - arg(i).arg(part).arg(pos); - mBookmarks.append(Bookmark(part, pos)); + int part = data[QString("bookmark%1part").arg(i)].toInt(); + qreal pos = data[QString("bookmark%1pos").arg(i)].toReal(); + QString note = data[QString("bookmark%1note").arg(i)].toString(); + mBookmarks.append(Bookmark(part, pos, note)); } } void Book::save() { - Trace t("Book::save"); - QSettings settings; - QString key = "book/" + path() + "/"; - qDebug() << "key" << key; - - // Save book info - settings.setValue(key + "title", title); - qDebug() << "title" << title; - settings.setValue(key + "creators", creators); - settings.setValue(key + "date", date); - settings.setValue(key + "publisher", publisher); - settings.setValue(key + "datepublished", datePublished); - settings.setValue(key + "subject", subject); - settings.setValue(key + "source", source); - settings.setValue(key + "rights", rights); - settings.setValue(key + "lastpart", mLastBookmark.part); - settings.setValue(key + "lastpos", mLastBookmark.pos); - settings.setValue(key + "cover", cover); - - // Save bookmarks - settings.setValue(key + "bookmarks", mBookmarks.size()); + TRACE; + + load(); + QVariantHash data; + data["title"] = title; + data["creators"] = creators; + data["date"] = date; + data["publisher"] = publisher; + data["datepublished"] = datePublished; + data["subject"] = subject; + data["source"] = source; + data["rights"] = rights; + data["lastpart"] = mLastBookmark.part; + data["lastpos"] = mLastBookmark.pos; + data["cover"] = cover; + data["bookmarks"] = mBookmarks.size(); for (int i = 0; i < mBookmarks.size(); i++) { - qDebug() << QString("Bookmark %1 at %2, %3"). - arg(i).arg(mBookmarks[i].part).arg(mBookmarks[i].pos); - settings.setValue(key + "bookmark" + QString::number(i) + "/part", - mBookmarks[i].part); - settings.setValue(key + "bookmark" + QString::number(i) + "/pos", - mBookmarks[i].pos); + data[QString("bookmark%1part").arg(i)] = mBookmarks[i].part; + data[QString("bookmark%1pos").arg(i)] = mBookmarks[i].pos; + data[QString("bookmark%1note").arg(i)] = mBookmarks[i].note; } + BookDb::instance()->save(path(), data); } void Book::setLastBookmark(int part, qreal position) { + TRACE; + load(); mLastBookmark.part = part; mLastBookmark.pos = position; save(); } -Book::Bookmark Book::lastBookmark() const +Book::Bookmark Book::lastBookmark() { + load(); return Book::Bookmark(mLastBookmark); } -void Book::addBookmark(int part, qreal position) +void Book::addBookmark(int part, qreal position, const QString ¬e) { - mBookmarks.append(Bookmark(part, position)); + load(); + mBookmarks.append(Bookmark(part, position, note)); qSort(mBookmarks.begin(), mBookmarks.end()); save(); } void Book::deleteBookmark(int index) { + load(); mBookmarks.removeAt(index); save(); } -QList Book::bookmarks() const +QList Book::bookmarks() { + load(); return mBookmarks; } QString Book::opsPath() { - Trace t("Book::opsPath"); + TRACE; + load(); QString ret; QFile container(tmpDir() + "/META-INF/container.xml"); @@ -399,34 +392,41 @@ QString Book::opsPath() return ret; } -QString Book::rootPath() const +QString Book::rootPath() { + load(); return mRootPath; } -QString Book::name() const +QString Book::name() { + load(); if (title.size()) { QString ret = title; if (creators.length()) { - ret += "\nBy " + creators[0]; - for (int i = 1; i < creators.length(); i++) { - ret += ", " + creators[i]; - } + ret += "\nBy " + creators.join(", "); } return ret; - } else { - return path(); } + return path(); } -QString Book::shortName() const +QString Book::shortName() { + load(); return (title.isEmpty())? QFileInfo(path()).baseName(): title; } +QImage Book::coverImage() +{ + load(); + return cover; +} + int Book::chapterFromPart(int index) { + TRACE; + load(); int ret = -1; QString partId = parts[index]; @@ -435,34 +435,37 @@ int Book::chapterFromPart(int index) for (int i = 0; i < chapters.size(); i++) { QString id = chapters[i]; QString href = content[id].href; - QString baseRef(href); - QUrl url(QString("file://") + href); - if (url.hasFragment()) { - QString fragment = url.fragment(); - baseRef.chop(fragment.length() + 1); + int hashPos = href.indexOf("#"); + if (hashPos != -1) { + href = href.left(hashPos); } - if (baseRef == partHref) { + if (href == partHref) { ret = i; // Don't break, keep looking } } + qDebug() << "Part" << index << partId << partHref << ":" << ret; return ret; } -int Book::partFromChapter(int index) +int Book::partFromChapter(int index, QString &fragment) { - Trace t("Book::partFromChapter"); + TRACE; + load(); + fragment.clear(); QString id = chapters[index]; QString href = content[id].href; int hashPos = href.indexOf("#"); if (hashPos != -1) { + fragment = href.mid(hashPos); href = href.left(hashPos); } qDebug() << "Chapter" << index; qDebug() << " id" << id; qDebug() << " href" << href; + qDebug() << " fragment" << fragment; for (int i = 0; i < parts.size(); i++) { QString partId = parts[i]; @@ -479,6 +482,7 @@ int Book::partFromChapter(int index) qreal Book::getProgress(int part, qreal position) { + load(); Q_ASSERT(part < parts.size()); QString key; qreal partSize = 0; @@ -494,6 +498,87 @@ qreal Book::getProgress(int part, qreal position) bool Book::extractMetaData() { QStringList excludedExtensions; - excludedExtensions << ".html" << ".xhtml" << ".xht" << ".htm"; + excludedExtensions << ".html" << ".xhtml" << ".xht" << ".htm" << ".gif" + << ".css" << "*.ttf" << "mimetype"; return extract(excludedExtensions); } + +void Book::upgrade() +{ + TRACE; + + // Load book from old database (QSettings) + QSettings settings; + QString key = "book/" + path() + "/"; + title = settings.value(key + "title").toString(); + qDebug() << title; + creators = settings.value(key + "creators").toStringList(); + date = settings.value(key + "date").toString(); + publisher = settings.value(key + "publisher").toString(); + datePublished = settings.value(key + "datepublished").toString(); + subject = settings.value(key + "subject").toString(); + source = settings.value(key + "source").toString(); + rights = settings.value(key + "rights").toString(); + mLastBookmark.part = settings.value(key + "lastpart").toInt(); + mLastBookmark.pos = settings.value(key + "lastpos").toReal(); + cover = settings.value(key + "cover").value(); + if (cover.isNull()) { + cover = makeCover(":/icons/book.png"); + } else { + cover = makeCover(QPixmap::fromImage(cover)); + } + int size = settings.value(key + "bookmarks").toInt(); + for (int i = 0; i < size; i++) { + int part = settings.value(key + "bookmark" + QString::number(i) + + "/part").toInt(); + qreal pos = settings.value(key + "bookmark" + QString::number(i) + + "/pos").toReal(); + qDebug() << QString("Bookmark %1 at part %2, %3"). + arg(i).arg(part).arg(pos); + mBookmarks.append(Bookmark(part, pos)); + } + + // Remove QSettings + settings.remove("book/" + path()); + + // Save book to new database + save(); +} + +void Book::remove() +{ + TRACE; + close(); + BookDb::instance()->remove(path()); +} + +QImage Book::makeCover(const QString &fileName) +{ + TRACE; + qDebug() << fileName; + QFileInfo info(fileName); + if (info.isReadable() && (info.size() < COVER_MAX)) { + return makeCover(QPixmap(fileName)); + } + return makeCover(QPixmap(":/icons/book.png")); +} + +QImage Book::makeCover(const QPixmap &pixmap) +{ + TRACE; + QPixmap src = pixmap.scaled(COVER_WIDTH, COVER_HEIGHT, + Qt::KeepAspectRatio, Qt::SmoothTransformation); + QPixmap transparent(COVER_WIDTH, COVER_HEIGHT); + transparent.fill(Qt::transparent); + + QPainter p; + p.begin(&transparent); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap((COVER_WIDTH - src.width()) / 2, + (COVER_HEIGHT - src.height()) / 2, src); + p.end(); + + return transparent.toImage(); +} + +