X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=bookview.cpp;h=840f8783e3f1037c3a52141c030a43ed5b753a33;hb=29dab253ded4ee3f92e95b54209ccb21f1e86004;hp=ce2de0dfd82dccc8ec2e85fc262e359fdcd9a2c6;hpb=77e2fb13d4293405ea15e33b061dd915a56469d2;p=dorian diff --git a/bookview.cpp b/bookview.cpp index ce2de0d..840f878 100644 --- a/bookview.cpp +++ b/bookview.cpp @@ -5,11 +5,16 @@ #include #include +#ifdef Q_WS_MAEMO_5 +# include +#endif + #include "book.h" #include "bookview.h" #include "library.h" #include "settings.h" #include "trace.h" +#include "progress.h" #ifdef Q_WS_MAC # define ICON_PREFIX ":/icons/mac/" @@ -18,16 +23,26 @@ #endif BookView::BookView(QWidget *parent): - QWebView(parent), contentIndex(-1), mBook(0), restore(true), - positionAfterLoad(0), loaded(false) + QWebView(parent), contentIndex(-1), mBook(0), + restorePositionAfterLoad(false), positionAfterLoad(0), loaded(false), + contentsHeight(0), scrollerMonitor(-1) { Trace t("BookView::BookView"); settings()->setAttribute(QWebSettings::AutoLoadImages, true); settings()->setAttribute(QWebSettings::JavascriptEnabled, true); + settings()->setAttribute(QWebSettings::JavaEnabled, false); settings()->setAttribute(QWebSettings::PluginsEnabled, false); + settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); + settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, false); + settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, false); + settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, false); + settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, + false); + settings()->setAttribute(QWebSettings::LocalStorageEnabled, false); settings()->setAttribute(QWebSettings::ZoomTextOnly, true); settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, false); + settings()->setDefaultTextEncoding("utf-8"); page()->setContentEditable(false); #if defined(Q_WS_MAEMO_5) @@ -43,6 +58,10 @@ BookView::BookView(QWidget *parent): bookmarkImage = QImage(":/icons/bookmark.png"); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool))); + connect(frame, SIGNAL(javaScriptWindowObjectCleared()), + this, SLOT(addJavaScriptObjects())); + connect(frame, SIGNAL(contentsSizeChanged(const QSize &)), + this, SLOT(onContentsSizeChanged(const QSize &))); connect(Settings::instance(), SIGNAL(valueChanged(const QString &)), this, SLOT(onSettingsChanged(const QString &))); Settings *s = Settings::instance(); @@ -59,13 +78,14 @@ BookView::BookView(QWidget *parent): s->setValue("scheme", s->value("scheme", "default")); setBook(0); - extractIcons(); +#ifdef Q_WS_MAEMO_5 + scroller = property("kineticScroller").value(); +#endif } BookView::~BookView() { Trace t("BookView::~BookView"); - removeIcons(); } void BookView::loadContent(int index) @@ -74,17 +94,17 @@ void BookView::loadContent(int index) if (!mBook) { return; } - if ((index < 0) || (index >= mBook->toc.size())) { + if ((index < 0) || (index >= mBook->parts.size())) { return; } - QString contentFile(mBook->content[mBook->toc[index]].href); - if (mBook->toc[index] == "error") { + QString contentFile(mBook->content[mBook->parts[index]].href); + if (mBook->parts[index] == "error") { setHtml(contentFile); } else { loaded = false; - emit chapterLoadStart(index); + emit partLoadStart(index); load(QUrl(contentFile)); } contentIndex = index; @@ -93,13 +113,22 @@ void BookView::loadContent(int index) void BookView::setBook(Book *book) { Trace t("BookView::setBook"); + + // Save position in current book setLastBookmark(); + + // Open new book, restore last position if (book != mBook) { mBook = book; if (book) { contentIndex = -1; - book->open(); - goToBookmark(book->lastBookmark()); + if (book->open()) { + restoreLastBookmark(); + } else { + mBook = 0; + contentIndex = 0; + setHtml(tr("Failed to open book")); + } } else { contentIndex = 0; @@ -116,56 +145,68 @@ Book *BookView::book() void BookView::goPrevious() { Trace t("BookView::goPrevious"); - loadContent(contentIndex - 1); + if (mBook && (contentIndex > 0)) { + mBook->setLastBookmark(contentIndex - 1, 0); + loadContent(contentIndex - 1); + } } void BookView::goNext() { Trace t("BookView::goNext"); - loadContent(contentIndex + 1); + if (mBook && (contentIndex < (mBook->parts.size() - 1))) { + mBook->setLastBookmark(contentIndex + 1, 0); + loadContent(contentIndex + 1); + } } void BookView::setLastBookmark() { - Trace t("BookView::saveLastBookmark"); + Trace t("BookView::setLastBookmark"); if (mBook) { - int height = page()->mainFrame()->contentsSize().height(); + int height = contentsHeight; int pos = page()->mainFrame()->scrollPosition().y(); + qDebug() << QString("At %1 (%2%, height %3)"). + arg(pos).arg((qreal)pos / (qreal)height * 100).arg(height); mBook->setLastBookmark(contentIndex, (qreal)pos / (qreal)height); } } +void BookView::restoreLastBookmark() +{ + Trace t("BookView::restoreLastBookmark"); + if (mBook) { + goToBookmark(mBook->lastBookmark()); + } +} + void BookView::goToBookmark(const Book::Bookmark &bookmark) { Trace t("BookView::goToBookmark"); if (mBook) { - restore = true; - positionAfterLoad = bookmark.pos; - if (bookmark.chapter != contentIndex) { - loadContent(bookmark.chapter); + if (bookmark.part != contentIndex) { + qDebug () << "Loading new part" << bookmark.part; + mBook->setLastBookmark(bookmark.part, bookmark.pos); + restorePositionAfterLoad = true; + positionAfterLoad = bookmark.pos; + loadContent(bookmark.part); } else { - onLoadFinished(true); + goToPosition(bookmark.pos); } } } void BookView::onLoadFinished(bool ok) { - Trace t(QString("BookView::onLoadFinished: %1").arg(ok)); - loaded = true; - if (ok) { - addNavigationBar(); + Trace t("BookView::onLoadFinished"); + if (!ok) { + qDebug() << "Not OK"; + return; } + loaded = true; onSettingsChanged("scheme"); - emit chapterLoadEnd(contentIndex); - if (restore) { - restore = false; - if (ok && mBook) { - int height = page()->mainFrame()->contentsSize().height(); - int scrollPos = (qreal)height * positionAfterLoad; - page()->mainFrame()->setScrollPosition(QPoint(0, scrollPos)); - } - } + emit partLoadEnd(contentIndex); + showProgress(); } void BookView::onSettingsChanged(const QString &key) @@ -205,10 +246,10 @@ void BookView::paintEvent(QPaintEvent *e) QPixmap bookmarkPixmap = QPixmap::fromImage(bookmarkImage); QPainter painter(this); foreach (Book::Bookmark b, mBook->bookmarks()) { - if (b.chapter != contentIndex) { + if (b.part != contentIndex) { continue; } - int height = page()->mainFrame()->contentsSize().height(); + int height = contentsHeight; int bookmarkPos = (qreal)height * (qreal)b.pos; painter.drawPixmap(2, bookmarkPos - scrollPos.y(), bookmarkPixmap); } @@ -217,7 +258,13 @@ void BookView::paintEvent(QPaintEvent *e) void BookView::mousePressEvent(QMouseEvent *e) { QWebView::mousePressEvent(e); -#ifndef Q_WS_MAEMO_5 +#ifdef Q_WS_MAEMO_5 + // Start monitoring kinetic scroll + if (scroller) { + scrollerMonitor = startTimer(250); + } +#else + // Handle mouse presses on the scroll bar QWebFrame *frame = page()->mainFrame(); if (frame->scrollBarGeometry(Qt::Vertical).contains(e->pos())) { e->accept(); @@ -227,53 +274,23 @@ void BookView::mousePressEvent(QMouseEvent *e) e->ignore(); } -void BookView::addBookmark() +void BookView::wheelEvent(QWheelEvent *e) { - Trace t("BookView::addBookmark"); - int y = page()->mainFrame()->scrollPosition().y(); - int height = page()->mainFrame()->contentsSize().height(); - t.trace(QString().setNum((qreal)y / (qreal)height)); - mBook->addBookmark(contentIndex, (qreal)y / (qreal)height); - repaint(); + QWebView::wheelEvent(e); + showProgress(); } -void BookView::addNavigationBar() +void BookView::addBookmark() { - Trace t("BookView::addNavigationBar"); + Trace t("BookView::addBookmark"); if (!mBook) { return; } - - QString naviPrev = - "" - "" - ""; - QString naviNext = - "" - "" - ""; - if (contentIndex == 0) { - naviPrev = ""; - } - if (contentIndex >= mBook->toc.size() - 1) { - naviNext = ""; - } - - QWebFrame *frame = page()->currentFrame(); - frame->addToJavaScriptWindowObject("bv", this); - QString headerScript = "document.body.innerHTML = '" + - naviPrev + naviNext + "
" + "' + document.body.innerHTML;"; - QString trailerScript = "document.body.innerHTML += '

" + - naviPrev + naviNext + "';"; - - frame->evaluateJavaScript(headerScript); - frame->evaluateJavaScript(trailerScript); + int y = page()->mainFrame()->scrollPosition().y(); + int height = page()->mainFrame()->contentsSize().height(); + qDebug() << ((qreal)y / (qreal)height); + mBook->addBookmark(contentIndex, (qreal)y / (qreal)height); + update(); } QString BookView::tmpPath() @@ -281,30 +298,25 @@ QString BookView::tmpPath() return QDir::tempPath() + "/dorian"; } -void BookView::extractIcons() +bool BookView::eventFilter(QObject *o, QEvent *e) { - QFile next(ICON_PREFIX + QString("/next.png")); - QFile prev(ICON_PREFIX + QString("/previous.png")); - - QDir().mkpath(tmpPath()); - next.copy(tmpPath() + "/next.png"); - prev.copy(tmpPath() + "/previous.png"); -} - -void BookView::removeIcons() -{ - QFile(ICON_PREFIX + QString("/next.png")).remove(); - QFile(ICON_PREFIX + QString("/previous.png")).remove(); - QDir().rmpath(tmpPath()); -} + if (e->type() != QEvent::Paint && e->type() != QEvent::MouseMove) { + if (e->type() == QEvent::Resize) { + qDebug() << "BookView::eventFilter QEvent::Resize to" + << page()->mainFrame()->contentsSize().height(); + } else { + qDebug() << "BookView::eventFilter" << Trace::event(e->type()); + } + } -bool BookView::eventFilter(QObject *, QEvent *e) { + // Work around Qt bug that sometimes selects web view contents during swipe switch (e->type()) { case QEvent::MouseButtonPress: emit suppressedMouseButtonPress(); mousePressed = true; break; case QEvent::MouseButtonRelease: + showProgress(); mousePressed = false; break; case QEvent::MouseMove: @@ -317,5 +329,118 @@ bool BookView::eventFilter(QObject *, QEvent *e) { default: break; } - return false; + + return QObject::eventFilter(o, e); +} + +void BookView::addJavaScriptObjects() +{ + page()->mainFrame()->addToJavaScriptWindowObject("bv", this); +} + +void BookView::onContentsSizeChanged(const QSize &size) +{ + contentsHeight = size.height(); + if (restorePositionAfterLoad) { + qDebug() << "BookView::onContentSizeChanged: Time to restore"; + restorePositionAfterLoad = false; + goToPosition(positionAfterLoad); + } +} + +void BookView::leaveEvent(QEvent *e) +{ + Trace t("BookView::leaveEvent"); + // Save current position, to be restored later + setLastBookmark(); + QWebView::leaveEvent(e); +} + +void BookView::enterEvent(QEvent *e) +{ + Trace t("BookView::enterEvent"); + // Restore position saved at Leave event. This seems to be required, + // after temporarily switching from portrait to landscape and back + restoreLastBookmark(); + QWebView::enterEvent(e); +} + +void BookView::goToPosition(qreal position) +{ + int scrollPos = (qreal)contentsHeight * position; + page()->mainFrame()->setScrollPosition(QPoint(0, scrollPos)); + // FIXME: update(); + qDebug() << "BookView::goToPosition: To" << scrollPos << "(" + << (position * 100) << "%, height" << contentsHeight << ")"; +} + +void BookView::showProgress() +{ + if (mBook) { + qreal pos = (qreal)(page()->mainFrame()->scrollPosition().y()) / + (qreal)contentsHeight; + emit progress(mBook->getProgress(contentIndex, pos)); + } +} + +void BookView::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == scrollerMonitor) { +#ifdef Q_WS_MAEMO_5 + if (scroller && + ((scroller->state() == QAbstractKineticScroller::AutoScrolling) || + (scroller->state() == QAbstractKineticScroller::Pushing))) { + showProgress(); + } else { + killTimer(scrollerMonitor); + } +#endif // Q_WS_MAEMO_5 + } +} + +void BookView::keyPressEvent(QKeyEvent* event) +{ + switch (event->key()) { + case Qt::Key_F7: + goNextPage(); + event->accept(); + break; + case Qt::Key_F8: + goPreviousPage(); + event->accept(); + break; + default: + ; + } + QWebView::keyPressEvent(event); +} + +void BookView::goPreviousPage() +{ + QWebFrame *frame = page()->mainFrame(); + int pos = frame->scrollPosition().y(); + frame->scroll(0, -height()); + if (pos == frame->scrollPosition().y()) { + if (contentIndex > 0) { + Book::Bookmark bookmark(contentIndex - 1, 1.0); + mBook->setLastBookmark(contentIndex - 1, 1.0); + goToBookmark(bookmark); + } + } else { + showProgress(); + } +} + +void BookView::goNextPage() +{ + Trace t("BookView::goNextPage"); + QWebFrame *frame = page()->mainFrame(); + int pos = frame->scrollPosition().y(); + frame->scroll(0, height()); + if (pos == frame->scrollPosition().y()) { + goNext(); + } else { + setLastBookmark(); + showProgress(); + } }