15 # define ICON_PREFIX ":/icons/mac/"
17 # define ICON_PREFIX ":/icons/"
20 BookView::BookView(QWidget *parent):
21 QWebView(parent), contentIndex(-1), mBook(0), restore(true),
22 positionAfterLoad(0), loaded(false), contentsHeight(0), decorated(false)
24 Trace t("BookView::BookView");
25 settings()->setAttribute(QWebSettings::AutoLoadImages, true);
26 settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
27 settings()->setAttribute(QWebSettings::JavaEnabled, false);
28 settings()->setAttribute(QWebSettings::PluginsEnabled, false);
29 settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
30 settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, false);
31 settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, false);
32 settings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, false);
33 settings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, false);
34 settings()->setAttribute(QWebSettings::LocalStorageEnabled, false);
35 settings()->setAttribute(QWebSettings::ZoomTextOnly, true);
36 settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls,
38 settings()->setDefaultTextEncoding("utf-8");
39 page()->setContentEditable(false);
41 #if defined(Q_WS_MAEMO_5)
42 // Suppress unwanted text selections on Maemo
43 installEventFilter(this);
45 QWebFrame *frame = page()->mainFrame();
46 #if defined(Q_WS_MAEMO_5)
47 frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
49 frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
51 bookmarkImage = QImage(":/icons/bookmark.png");
53 connect(this, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
54 connect(frame, SIGNAL(javaScriptWindowObjectCleared()),
55 this, SLOT(addJavaScriptObjects()));
56 connect(frame, SIGNAL(contentsSizeChanged(const QSize &)),
57 this, SLOT(onContentsSizeChanged(const QSize &)));
58 connect(Settings::instance(), SIGNAL(valueChanged(const QString &)),
59 this, SLOT(onSettingsChanged(const QString &)));
60 Settings *s = Settings::instance();
61 s->setValue("zoom", s->value("zoom", 160));
62 s->setValue("font", s->value("font",
63 #if defined(Q_WS_MAEMO_5) || defined(Q_WS_X11)
65 #elif defined(Q_WS_MAC)
71 s->setValue("scheme", s->value("scheme", "default"));
79 Trace t("BookView::~BookView");
83 void BookView::loadContent(int index)
85 Trace t("BookView::loadContent");
89 if ((index < 0) || (index >= mBook->toc.size())) {
93 QString contentFile(mBook->content[mBook->toc[index]].href);
94 if (mBook->toc[index] == "error") {
100 emit chapterLoadStart(index);
101 load(QUrl(contentFile));
103 contentIndex = index;
106 void BookView::setBook(Book *book)
108 Trace t("BookView::setBook");
115 goToBookmark(book->lastBookmark());
119 setHtml(tr("No book"));
124 Book *BookView::book()
129 void BookView::goPrevious()
131 Trace t("BookView::goPrevious");
132 loadContent(contentIndex - 1);
135 void BookView::goNext()
137 Trace t("BookView::goNext");
138 loadContent(contentIndex + 1);
141 void BookView::setLastBookmark()
143 Trace t("BookView::saveLastBookmark");
145 int height = contentsHeight; // page()->mainFrame()->contentsSize().height();
146 int pos = page()->mainFrame()->scrollPosition().y();
147 t.trace(QString("At %1 (%2%, height %3)").
148 arg(pos).arg((qreal)pos / (qreal)height * 100).arg(height));
149 mBook->setLastBookmark(contentIndex, (qreal)pos / (qreal)height);
153 void BookView::goToBookmark(const Book::Bookmark &bookmark)
155 Trace t("BookView::goToBookmark");
158 positionAfterLoad = bookmark.pos;
159 if (bookmark.chapter != contentIndex) {
160 loadContent(bookmark.chapter);
162 onLoadFinished(true);
167 void BookView::onLoadFinished(bool ok)
169 Trace t("BookView::onLoadFinished");
176 onSettingsChanged("scheme");
177 emit chapterLoadEnd(contentIndex);
180 void BookView::onSettingsChanged(const QString &key)
182 Trace t("BookView::onSettingsChanged " + key);
184 setZoomFactor(Settings::instance()->value(key).toFloat() / 100.);
186 else if (key == "font") {
187 QString face = Settings::instance()->value("font").toString();
188 settings()->setFontFamily(QWebSettings::StandardFont, face);
190 else if (key == "scheme") {
191 QWebFrame *frame = page()->mainFrame();
192 QString scheme = Settings::instance()->value("scheme").toString();
193 if ((scheme != "day") && (scheme != "night") && (scheme != "sand") &&
194 (scheme != "default")) {
197 QFile script(":/styles/" + scheme + ".js");
198 script.open(QFile::ReadOnly);
199 QString scriptText = script.readAll();
201 QVariant ret = frame->evaluateJavaScript(scriptText);
205 void BookView::paintEvent(QPaintEvent *e)
207 QWebView::paintEvent(e);
208 if (!mBook || !loaded) {
213 QPoint scrollPos = page()->mainFrame()->scrollPosition();
214 QPixmap bookmarkPixmap = QPixmap::fromImage(bookmarkImage);
215 QPainter painter(this);
216 foreach (Book::Bookmark b, mBook->bookmarks()) {
217 if (b.chapter != contentIndex) {
220 int height = contentsHeight; // page()->mainFrame()->contentsSize().height();
221 int bookmarkPos = (qreal)height * (qreal)b.pos;
222 painter.drawPixmap(2, bookmarkPos - scrollPos.y(), bookmarkPixmap);
226 void BookView::mousePressEvent(QMouseEvent *e)
228 QWebView::mousePressEvent(e);
230 QWebFrame *frame = page()->mainFrame();
231 if (frame->scrollBarGeometry(Qt::Vertical).contains(e->pos())) {
235 #endif // Q_WS_MAEMO_5
239 void BookView::addBookmark()
241 Trace t("BookView::addBookmark");
242 int y = page()->mainFrame()->scrollPosition().y();
243 int height = page()->mainFrame()->contentsSize().height();
244 t.trace(QString().setNum((qreal)y / (qreal)height));
245 mBook->addBookmark(contentIndex, (qreal)y / (qreal)height);
249 void BookView::addNavigationBar()
251 Trace t("BookView::addNavigationBar");
257 "<a href=\"javascript:bv.goPrevious();\">"
258 "<img width=\"95\" height=\"95\" style=\"float:left;clear:none;\" "
264 "<a href=\"javascript:bv.goNext();\">"
265 "<img width=\"95\" height=\"95\" style=\"float:right;clear:none;\" "
270 if (contentIndex == 0) {
273 if (contentIndex >= mBook->toc.size() - 1) {
277 QWebFrame *frame = page()->currentFrame();
278 QString headerScript = "document.body.innerHTML = '" +
279 naviPrev + naviNext + "<br />" + "' + document.body.innerHTML;";
280 QString trailerScript = "document.body.innerHTML += '<br /><br />" +
281 naviPrev + naviNext + "';";
283 frame->evaluateJavaScript(headerScript);
284 frame->evaluateJavaScript(trailerScript);
288 QString BookView::tmpPath()
290 return QDir::tempPath() + "/dorian";
293 void BookView::extractIcons()
295 QFile next(ICON_PREFIX + QString("/next.png"));
296 QFile prev(ICON_PREFIX + QString("/previous.png"));
298 QDir().mkpath(tmpPath());
299 next.copy(tmpPath() + "/next.png");
300 prev.copy(tmpPath() + "/previous.png");
303 void BookView::removeIcons()
305 QFile(ICON_PREFIX + QString("/next.png")).remove();
306 QFile(ICON_PREFIX + QString("/previous.png")).remove();
307 QDir().rmpath(tmpPath());
310 bool BookView::eventFilter(QObject *, QEvent *e)
312 if (e->type() != QEvent::Paint && e->type() != QEvent::MouseMove) {
313 Trace::debug(QString("BookView::eventFilter %1").
314 arg(Trace::event(e->type())));
317 case QEvent::MouseButtonPress:
318 emit suppressedMouseButtonPress();
321 case QEvent::MouseButtonRelease:
322 mousePressed = false;
324 case QEvent::MouseMove:
329 case QEvent::MouseButtonDblClick:
337 void BookView::addJavaScriptObjects()
339 page()->mainFrame()->addToJavaScriptWindowObject("bv", this);
342 void BookView::onContentsSizeChanged(const QSize &size)
344 Trace t("BookView::onContentsSizeChanged");
345 t.trace(QString("To %1").arg(size.height()));
346 contentsHeight = size.height();
352 QWebPage *webPage = page();
353 QWebFrame *mainFrame = webPage->mainFrame();
354 int height = contentsHeight;
355 int scrollPos = (qreal)height * positionAfterLoad;
356 mainFrame->setScrollPosition(QPoint(0, scrollPos));
357 t.trace(QString("Restoring positon to %1 (%2%, height %3)").
358 arg(scrollPos).arg(positionAfterLoad * 100).arg(height));
359 foreach (QString key, mainFrame->metaData().keys()) {
360 QString value = mainFrame->metaData().value(key);
361 t.trace(key + ": " + value);