diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index b1f2657614..690babc4cd 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -388,6 +388,7 @@ class Boss(QObject): def shutdown(self): self.save_state() self.save_manager.shutdown() + self.gui.preview.parse_worker.shutdown() self.save_manager.wait(0.1) def save_state(self): diff --git a/src/calibre/gui2/tweak_book/preview.py b/src/calibre/gui2/tweak_book/preview.py new file mode 100644 index 0000000000..55e70082b2 --- /dev/null +++ b/src/calibre/gui2/tweak_book/preview.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8 +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2013, Kovid Goyal ' + +from threading import Thread +from Queue import Queue, Empty + +from PyQt4.Qt import (QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager) +from PyQt4.QtWebKit import QWebView + +from calibre.gui2.viewer.documentview import apply_settings +from calibre.gui2.viewer.config import config +from calibre.utils.ipc.simple_worker import offload_worker + +shutdown = object() + +class ParseWorker(Thread): + + daemon = True + + def __init__(self): + Thread.__init__(self) + self.worker = offload_worker(priority='low') + self.requests = Queue() + self.request_count = 0 + self.start() + + def run(self): + try: + # Connect to the worker and send a dummy job to initialize it + self.worker(None, None, (), {}) + except: + import traceback + traceback.print_exc() + return + + while True: + x = self.requests.get() + requests = [x] + while True: + try: + requests.append(self.requests.get_nowait()) + except Empty: + break + if shutdown in requests: + self.worker.shutdown() + break + request = sorted(requests, reverse=True)[0] + del requests + request + + def shutdown(self): + self.requests.put(shutdown) + +class NetworkAccessManager(QNetworkAccessManager): + + OPERATION_NAMES = {getattr(QNetworkAccessManager, '%sOperation'%x) : + x.upper() for x in ('Head', 'Get', 'Put', 'Post', 'Delete', + 'Custom') + } + + def createRequest(self, operation, request, data): + url = unicode(request.url().toString()) + print (url) + return QNetworkAccessManager.createRequest(self, operation, request, + data) + +class WebView(QWebView): + + def __init__(self, parent=None): + QWebView.__init__(self, parent) + w = QApplication.instance().desktop().availableGeometry(self).width() + self._size_hint = QSize(int(w/3), int(w/2)) + settings = self.page().settings() + apply_settings(settings, config().parse()) + settings.setMaximumPagesInCache(0) + self.setHtml('

') + self.nam = NetworkAccessManager(self) + self.page().setNetworkAccessManager(self.nam) + + def sizeHint(self): + return self._size_hint + +class Preview(QWidget): + + def __init__(self, parent=None): + QWidget.__init__(self, parent) + self.l = l = QVBoxLayout() + self.setLayout(l) + l.setContentsMargins(0, 0, 0, 0) + self.parse_worker = ParseWorker() + self.view = WebView(self) + l.addWidget(self.view) + diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index 1ba72fdd46..46d223e61a 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -17,6 +17,7 @@ from calibre.gui2.tweak_book.file_list import FileListWidget from calibre.gui2.tweak_book.job import BlockingJob from calibre.gui2.tweak_book.boss import Boss from calibre.gui2.tweak_book.keyboard import KeyboardManager +from calibre.gui2.tweak_book.preview import Preview class Central(QStackedWidget): ' The central widget, hosts the editors ' @@ -190,6 +191,13 @@ class Main(MainWindow): d.setWidget(self.file_list) self.addDockWidget(Qt.LeftDockWidgetArea, d) + self.preview_dock = d = QDockWidget(_('&Book preview'), self) + d.setObjectName('file_list_dock') # Needed for saveState + d.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) + self.preview = Preview(d) + d.setWidget(self.preview) + self.addDockWidget(Qt.RightDockWidgetArea, d) + def resizeEvent(self, ev): self.blocking_job.resize(ev.size()) return super(Main, self).resizeEvent(ev) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 2b49983970..6424ae741b 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -30,6 +30,18 @@ from calibre.ebooks.oeb.display.webview import load_html from calibre.constants import isxp, iswindows # }}} +def apply_settings(settings, opts): + settings.setFontSize(QWebSettings.DefaultFontSize, opts.default_font_size) + settings.setFontSize(QWebSettings.DefaultFixedFontSize, opts.mono_font_size) + settings.setFontSize(QWebSettings.MinimumLogicalFontSize, opts.minimum_font_size) + settings.setFontSize(QWebSettings.MinimumFontSize, opts.minimum_font_size) + settings.setFontFamily(QWebSettings.StandardFont, {'serif':opts.serif_family, 'sans':opts.sans_family, 'mono':opts.mono_family}[opts.standard_font]) + settings.setFontFamily(QWebSettings.SerifFont, opts.serif_family) + settings.setFontFamily(QWebSettings.SansSerifFont, opts.sans_family) + settings.setFontFamily(QWebSettings.FixedFont, opts.mono_family) + settings.setAttribute(QWebSettings.ZoomTextOnly, True) + + class Document(QWebPage): # {{{ page_turn = pyqtSignal(object) @@ -38,15 +50,7 @@ class Document(QWebPage): # {{{ def set_font_settings(self, opts): settings = self.settings() - settings.setFontSize(QWebSettings.DefaultFontSize, opts.default_font_size) - settings.setFontSize(QWebSettings.DefaultFixedFontSize, opts.mono_font_size) - settings.setFontSize(QWebSettings.MinimumLogicalFontSize, opts.minimum_font_size) - settings.setFontSize(QWebSettings.MinimumFontSize, opts.minimum_font_size) - settings.setFontFamily(QWebSettings.StandardFont, {'serif':opts.serif_family, 'sans':opts.sans_family, 'mono':opts.mono_family}[opts.standard_font]) - settings.setFontFamily(QWebSettings.SerifFont, opts.serif_family) - settings.setFontFamily(QWebSettings.SansSerifFont, opts.sans_family) - settings.setFontFamily(QWebSettings.FixedFont, opts.mono_family) - settings.setAttribute(QWebSettings.ZoomTextOnly, True) + apply_settings(settings, opts) def do_config(self, parent=None): d = ConfigDialog(self.shortcuts, parent) diff --git a/src/calibre/utils/ipc/simple_worker.py b/src/calibre/utils/ipc/simple_worker.py index b5458d5b30..28a059283a 100644 --- a/src/calibre/utils/ipc/simple_worker.py +++ b/src/calibre/utils/ipc/simple_worker.py @@ -206,7 +206,7 @@ def fork_job(mod_name, func_name, args=(), kwargs={}, timeout=300, # seconds def offload_worker(env={}, priority='normal', cwd=None): listener, w = create_worker(env=env, priority=priority, cwd=cwd, func='offload') - return OffloadWorker(listener) + return OffloadWorker(listener, w) def compile_code(src): import re, io