diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 8f8ee3f5a8..d5dbdae50f 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -32,6 +32,7 @@ is64bit = sys.maxsize > (1 << 32) isworker = 'CALIBRE_WORKER' in os.environ or 'CALIBRE_SIMPLE_WORKER' in os.environ if isworker: os.environ.pop('CALIBRE_FORCE_ANSI', None) +FAKE_PROTOCOL, FAKE_HOST = 'https', 'calibre-internal.invalid' try: preferred_encoding = locale.getpreferredencoding() diff --git a/src/calibre/gui2/tweak_book/live_css.py b/src/calibre/gui2/tweak_book/live_css.py index 9ca671999e..487585900a 100644 --- a/src/calibre/gui2/tweak_book/live_css.py +++ b/src/calibre/gui2/tweak_book/live_css.py @@ -11,10 +11,10 @@ import json from PyQt5.Qt import ( QWidget, QTimer, QStackedLayout, QLabel, QScrollArea, QVBoxLayout, QPainter, Qt, QPalette, QRect, QSize, QSizePolicy, pyqtSignal, - QColor, QMenu, QApplication, QIcon) + QColor, QMenu, QApplication, QIcon, QUrl) -from calibre.constants import iswindows -from calibre.gui2.tweak_book import editors, actions, current_container, tprefs +from calibre.constants import FAKE_HOST, FAKE_PROTOCOL +from calibre.gui2.tweak_book import editors, actions, tprefs from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color from calibre.gui2.tweak_book.editor.text import default_font_family from css_selectors import parse, SelectorError @@ -518,12 +518,11 @@ class LiveCSS(QWidget): rule['properties'] = properties href = rule['href'] - if hasattr(href, 'startswith') and href.startswith('file://'): - href = href[len('file://'):] - if iswindows and href.startswith('/'): - href = href[1:] - if href: - rule['href'] = current_container().abspath_to_name(href, root=self.preview.current_root) + if hasattr(href, 'startswith') and href.startswith('%s://%s' % (FAKE_PROTOCOL, FAKE_HOST)): + qurl = QUrl(href) + name = qurl.path()[1:] + if name: + rule['href'] = name @property def current_name(self): @@ -568,4 +567,3 @@ class LiveCSS(QWidget): editor.goto_css_rule(data['rule_address']) elif data['type'] == 'elem': editor.goto_css_rule(data['rule_address'], sourceline_address=data['sourceline_address']) - diff --git a/src/calibre/gui2/tweak_book/preview.py b/src/calibre/gui2/tweak_book/preview.py index 595fb800fd..c5e144ba37 100644 --- a/src/calibre/gui2/tweak_book/preview.py +++ b/src/calibre/gui2/tweak_book/preview.py @@ -17,15 +17,14 @@ from urlparse import urlparse from PyQt5.Qt import ( QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon, - QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar, + QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QToolBar, pyqtSlot, pyqtSignal) from PyQt5.QtWebKitWidgets import QWebView, QWebInspector, QWebPage from calibre import prints -from calibre.constants import iswindows +from calibre.constants import FAKE_PROTOCOL, FAKE_HOST from calibre.ebooks.oeb.polish.parsing import parse from calibre.ebooks.oeb.base import serialize, OEB_DOCS -from calibre.ptempfile import PersistentTemporaryDirectory from calibre.gui2 import error_dialog, open_url, NO_URL_FORMATTING from calibre.gui2.tweak_book import current_container, editors, tprefs, actions, TOP from calibre.gui2.viewer.documentview import apply_settings @@ -169,6 +168,12 @@ class NetworkReply(QNetworkReply): data = data.encode('utf-8') mime_type += '; charset=utf-8' self.__data = data + mime_type = { + # Prevent warning in console about mimetype of fonts + 'application/vnd.ms-opentype':'application/x-font-ttf', + 'application/x-font-truetype':'application/x-font-ttf', + 'application/font-sfnt': 'application/x-font-ttf', + }.get(mime_type, mime_type) self.setHeader(QNetworkRequest.ContentTypeHeader, mime_type) self.setHeader(QNetworkRequest.ContentLengthHeader, len(self.__data)) QTimer.singleShot(0, self.finalize_reply) @@ -220,25 +225,11 @@ class NetworkAccessManager(QNetworkAccessManager): 'Custom') } - def __init__(self, *args): - QNetworkAccessManager.__init__(self, *args) - self.current_root = None - self.cache = QNetworkDiskCache(self) - self.setCache(self.cache) - self.cache.setCacheDirectory(PersistentTemporaryDirectory(prefix='disk_cache_')) - self.cache.setMaximumCacheSize(0) - def createRequest(self, operation, request, data): - url = unicode(request.url().toString(NO_URL_FORMATTING)) - if operation == self.GetOperation and url.startswith('file://'): - path = url[7:] - if iswindows and path.startswith('/'): - path = path[1:] + qurl = request.url() + if operation == self.GetOperation and qurl.host() == FAKE_HOST: + name = qurl.path()[1:] c = current_container() - try: - name = c.abspath_to_name(path, root=self.current_root) - except ValueError: # Happens on windows with absolute paths on different drives - name = None if c.has_name(name): try: return NetworkReply(self, request, c.mime_map.get(name, 'application/octet-stream'), name) @@ -295,15 +286,6 @@ class WebPage(QWebPage): self.mainFrame().javaScriptWindowObjectCleared.connect(self.init_javascript) self.init_javascript() - @dynamic_property - def current_root(self): - def fget(self): - return self.networkAccessManager().current_root - - def fset(self, val): - self.networkAccessManager().current_root = val - return property(fget=fget, fset=fset) - def javaScriptConsoleMessage(self, msg, lineno, source_id): prints('preview js:%s:%s:'%(unicode(source_id), lineno), unicode(msg)) @@ -416,11 +398,6 @@ class WebView(QWebView): only, it is not intended to simulate an actual ebook reader. Some aspects of your ebook will not work, such as page breaks and page margins. ''')) - self.page().current_root = None - - def setUrl(self, qurl): - self.page().current_root = current_container().root - return QWebView.setUrl(self, qurl) def inspect(self): self.inspector.parent().show() @@ -559,13 +536,19 @@ class Preview(QWidget): error_dialog(self, _('Failed to launch worker'), _( 'Failed to launch the worker process used for rendering the preview'), det_msg=tb, show=True) + def name_to_qurl(self, name=None): + name = name or self.current_name + qurl = QUrl() + qurl.setScheme(FAKE_PROTOCOL), qurl.setAuthority(FAKE_HOST), qurl.setPath('/' + name) + return qurl + def show(self, name): if name != self.current_name: self.refresh_timer.stop() self.current_name = name self.report_worker_launch_error() parse_worker.add_request(name) - self.view.setUrl(QUrl.fromLocalFile(current_container().name_to_abspath(name))) + self.view.setUrl(self.name_to_qurl()) return True def refresh(self): @@ -576,7 +559,7 @@ class Preview(QWidget): self.report_worker_launch_error() parse_worker.add_request(self.current_name) # Tell webkit to reload all html and associated resources - current_url = QUrl.fromLocalFile(current_container().name_to_abspath(self.current_name)) + current_url = self.name_to_qurl() self.refresh_starting.emit() if current_url != self.view.url(): # The container was changed @@ -589,10 +572,6 @@ class Preview(QWidget): self.view.clear() self.current_name = None - @property - def current_root(self): - return self.view.page().current_root - @property def is_visible(self): return actions['preview-dock'].isChecked()