5 #if defined(Q_OS_SYMBIAN)
6 # include "mediakeysobserver.h"
7 # include "flickcharm.h"
16 #include "progressdialog.h"
19 BookView::BookView(QWidget *parent): QWebView(parent), contentIndex(-1), mBook(0),
20 restorePositionAfterLoad(false), positionAfterLoad(0), loaded(false),
21 contentsHeight(0), grabbingVolumeKeys(false)
25 // Set up web view defaults
26 settings()->setAttribute(QWebSettings::AutoLoadImages, true);
27 settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
28 settings()->setAttribute(QWebSettings::JavaEnabled, false);
29 settings()->setAttribute(QWebSettings::PluginsEnabled, false);
30 settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
31 settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, false);
32 settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, false);
33 settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled,
35 settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled,
37 settings()->setAttribute(QWebSettings::LocalStorageEnabled, false);
38 settings()->setAttribute(QWebSettings::ZoomTextOnly, true);
39 settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,
41 settings()->setDefaultTextEncoding("utf-8");
42 page()->setContentEditable(false);
43 QWebFrame *frame = page()->mainFrame();
44 #if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN)
45 frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
47 frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
48 connect(this, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
49 connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
50 this, SLOT(addJavaScriptObjects()));
51 connect(frame, SIGNAL(contentsSizeChanged(const QSize &)),
52 this, SLOT(onContentsSizeChanged(const QSize &)));
54 // Suppress unwanted text selections on Maemo and Symbian
55 #if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN)
56 installEventFilter(this);
59 // Pre-load bookmark icon
60 bookmarkImage = QImage(":/icons/bookmark.png");
62 // Handle settings changes, force handling initial settings
63 Settings *s = Settings::instance();
64 connect(s, SIGNAL(valueChanged(const QString &)),
65 this, SLOT(onSettingsChanged(const QString &)));
66 s->setValue("zoom", s->value("zoom", 160));
67 s->setValue("font", s->value("font", Platform::defaultFont()));
68 s->setValue("scheme", s->value("scheme", "default"));
69 s->setValue("usevolumekeys", s->value("usevolumekeys", false));
72 // Enable kinetic scrolling
73 #if defined(Q_WS_MAEMO_5)
75 scroller = property("kineticScroller").value<QAbstractKineticScroller *>();
76 #elif defined(Q_OS_SYMBIAN)
78 charm = new FlickCharm(this);
79 charm->activateOn(this);
82 // Observe media keys on Symbian
84 MediaKeysObserver *observer = MediaKeysObserver::instance();
85 connect(observer, SIGNAL(mediaKeyPressed(MediaKeysObserver::MediaKeys)),
86 this, SLOT(onMediaKeysPressed(MediaKeysObserver::MediaKeys)));
90 void BookView::loadContent(int index)
97 if ((index < 0) || (index >= mBook->parts.size())) {
101 QString contentFile(mBook->content[mBook->parts[index]].href);
102 if (mBook->parts[index] == "error") {
103 setHtml(contentFile);
106 emit partLoadStart(index);
107 QUrl u = QUrl::fromLocalFile(QDir(mBook->rootPath()).
108 absoluteFilePath(contentFile));
109 qDebug() << "Loading" << u;
112 contentIndex = index;
115 void BookView::setBook(Book *book)
119 // Save position in current book
122 // Open new book, restore last position
128 restoreLastBookmark();
132 setHtml(tr("Failed to open book"));
137 setHtml(tr("No book"));
142 Book *BookView::book()
147 void BookView::goPrevious()
150 if (mBook && (contentIndex > 0)) {
151 mBook->setLastBookmark(contentIndex - 1, 0);
152 loadContent(contentIndex - 1);
156 void BookView::goNext()
159 if (mBook && (contentIndex < (mBook->parts.size() - 1))) {
160 mBook->setLastBookmark(contentIndex + 1, 0);
161 loadContent(contentIndex + 1);
165 void BookView::setLastBookmark()
169 int height = contentsHeight;
170 int pos = page()->mainFrame()->scrollPosition().y();
171 qDebug() << QString("At %1 (%2%, height %3)").
172 arg(pos).arg((qreal)pos / (qreal)height * 100).arg(height);
173 mBook->setLastBookmark(contentIndex, (qreal)pos / (qreal)height);
177 void BookView::restoreLastBookmark()
181 goToBookmark(mBook->lastBookmark());
185 void BookView::goToBookmark(const Book::Bookmark &bookmark)
189 if (bookmark.part != contentIndex) {
190 qDebug () << "Loading new part" << bookmark.part;
191 mBook->setLastBookmark(bookmark.part, bookmark.pos);
192 restorePositionAfterLoad = true;
193 positionAfterLoad = bookmark.pos;
194 loadContent(bookmark.part);
196 goToPosition(bookmark.pos);
201 void BookView::goToPart(int part, const QString &fragment)
205 if (part != contentIndex) {
206 qDebug() << "Loading new part" << part;
207 restoreFragmentAfterLoad = true;
208 fragmentAfterLoad = fragment;
211 goToFragment(fragment);
217 void BookView::goToFragment(const QString &fragment)
220 if (!fragment.isEmpty()) {
221 QVariant ret = page()->mainFrame()->evaluateJavaScript(
222 QString("window.location='") + fragment + "'");
228 void BookView::onLoadFinished(bool ok)
232 qDebug() << "Not OK";
236 onSettingsChanged("scheme");
237 onSettingsChanged("zoom");
238 onSettingsChanged("font");
239 emit partLoadEnd(contentIndex);
243 void BookView::onSettingsChanged(const QString &key)
246 qDebug() << key << Settings::instance()->value(key);
249 setZoomFactor(Settings::instance()->value(key).toFloat() / 100.);
251 else if (key == "font") {
252 QString face = Settings::instance()->value(key).toString();
253 settings()->setFontFamily(QWebSettings::StandardFont, face);
255 else if (key == "scheme") {
256 QWebFrame *frame = page()->mainFrame();
257 QString scheme = Settings::instance()->value("scheme").toString();
258 if ((scheme != "day") && (scheme != "night") && (scheme != "sand") &&
259 (scheme != "default")) {
262 QFile script(":/styles/" + scheme + ".js");
263 script.open(QFile::ReadOnly);
264 QString scriptText = script.readAll();
266 QVariant ret = frame->evaluateJavaScript(scriptText);
268 else if (key == "usevolumekeys") {
269 grabVolumeKeys(Settings::instance()->value(key).toBool());
273 void BookView::paintEvent(QPaintEvent *e)
275 QWebView::paintEvent(e);
276 if (!mBook || !loaded) {
281 QPoint scrollPos = page()->mainFrame()->scrollPosition();
282 QPixmap bookmarkPixmap = QPixmap::fromImage(bookmarkImage);
283 QPainter painter(this);
284 foreach (Book::Bookmark b, mBook->bookmarks()) {
285 if (b.part != contentIndex) {
288 int height = contentsHeight;
289 int bookmarkPos = (int)((qreal)height * (qreal)b.pos);
290 painter.drawPixmap(2, bookmarkPos - scrollPos.y(), bookmarkPixmap);
294 void BookView::mousePressEvent(QMouseEvent *e)
296 QWebView::mousePressEvent(e);
297 #if defined(Q_WS_MAEMO_5)
298 // Start monitoring kinetic scroll
299 if (scrollerMonitor) {
300 killTimer(scrollerMonitor);
304 scrollerMonitor = startTimer(500);
307 // Handle mouse presses on the scroll bar
308 QWebFrame *frame = page()->mainFrame();
309 if (frame->scrollBarGeometry(Qt::Vertical).contains(e->pos())) {
313 #endif // Q_WS_MAEMO_5
317 void BookView::wheelEvent(QWheelEvent *e)
319 QWebView::wheelEvent(e);
323 void BookView::addBookmark(const QString ¬e)
329 int y = page()->mainFrame()->scrollPosition().y();
330 int height = page()->mainFrame()->contentsSize().height();
331 qDebug() << ((qreal)y / (qreal)height);
332 mBook->addBookmark(contentIndex, (qreal)y / (qreal)height, note);
336 QString BookView::tmpPath()
338 return QDir::tempPath() + "/dorian";
341 bool BookView::eventFilter(QObject *o, QEvent *e)
344 if (e->type() != QEvent::Paint && e->type() != QEvent::MouseMove) {
345 if (e->type() == QEvent::Resize) {
346 qDebug() << "BookView::eventFilter QEvent::Resize to"
347 << page()->mainFrame()->contentsSize().height();
348 } else if (e->type() == QEvent::Timer) {
349 qDebug() << "BookView::eventFilter" << "QEvent::Timer"
350 << ((QTimerEvent *)e)->timerId();
352 qDebug() << "BookView::eventFilter" << Trace::event(e->type());
357 // Work around Qt bug that sometimes selects web view contents during swipe
359 case QEvent::MouseButtonPress:
360 emit suppressedMouseButtonPress();
363 case QEvent::MouseButtonRelease:
365 mousePressed = false;
367 case QEvent::MouseMove:
372 case QEvent::MouseButtonDblClick:
378 return QObject::eventFilter(o, e);
381 void BookView::addJavaScriptObjects()
383 page()->mainFrame()->addToJavaScriptWindowObject("bv", this);
386 void BookView::onContentsSizeChanged(const QSize &size)
389 contentsHeight = size.height();
390 if (restoreFragmentAfterLoad) {
391 qDebug() << "Restorint to fragment" << fragmentAfterLoad;
392 goToFragment(fragmentAfterLoad);
393 } else if (restorePositionAfterLoad) {
394 qDebug() << "Restoring to position";
395 goToPosition(positionAfterLoad);
397 restorePositionAfterLoad = false;
398 restoreFragmentAfterLoad = false;
403 void BookView::leaveEvent(QEvent *e)
406 // Save current position, to be restored later
408 QWebView::leaveEvent(e);
411 void BookView::enterEvent(QEvent *e)
414 // Restore position saved at Leave event. This seems to be required,
415 // after temporarily switching from portrait to landscape and back
416 restoreLastBookmark();
417 QWebView::enterEvent(e);
420 #endif // Q_WS_MAEMO_5
422 void BookView::goToPosition(qreal position)
424 int scrollPos = (int)((qreal)contentsHeight * position);
425 page()->mainFrame()->setScrollPosition(QPoint(0, scrollPos));
427 qDebug() << "BookView::goToPosition: To" << scrollPos << "("
428 << (position * 100) << "%, height" << contentsHeight << ")";
431 void BookView::showProgress()
434 qreal pos = (qreal)(page()->mainFrame()->scrollPosition().y()) /
435 (qreal)contentsHeight;
436 emit progress(mBook->getProgress(contentIndex, pos));
440 void BookView::timerEvent(QTimerEvent *e)
442 #if defined(Q_WS_MAEMO_5)
443 if (e->timerId() == scrollerMonitor) {
445 ((scroller->state() == QAbstractKineticScroller::AutoScrolling) ||
446 (scroller->state() == QAbstractKineticScroller::Pushing))) {
449 killTimer(scrollerMonitor);
450 scrollerMonitor = -1;
454 QWebView::timerEvent(e);
457 void BookView::goPreviousPage()
459 QWebFrame *frame = page()->mainFrame();
460 int pos = frame->scrollPosition().y();
461 frame->scroll(0, -height());
462 if (pos == frame->scrollPosition().y()) {
463 if (contentIndex > 0) {
464 Book::Bookmark bookmark(contentIndex - 1, 1.0);
465 mBook->setLastBookmark(contentIndex - 1, 1.0);
466 goToBookmark(bookmark);
473 void BookView::goNextPage()
476 QWebFrame *frame = page()->mainFrame();
477 int pos = frame->scrollPosition().y();
478 frame->scroll(0, height());
479 if (pos == frame->scrollPosition().y()) {
487 void BookView::grabVolumeKeys(bool grab)
490 grabbingVolumeKeys = grab;
495 void BookView::onMediaKeysPressed(MediaKeysObserver::MediaKeys key)
498 qDebug() << "Key" << (int)key;
499 if (grabbingVolumeKeys) {
500 if (key == MediaKeysObserver::EVolIncKey) {
501 qDebug() << "Volume up";
503 } else if (key == MediaKeysObserver::EVolDecKey){
504 qDebug() << "Volume down";
510 #endif // Q_OS_SYMBIAN