mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
Edit Book: Fix a regression in the previous release that broke the Live CSS tool
This commit is contained in:
parent
344864a807
commit
a2c02acfe0
@ -32,6 +32,7 @@ is64bit = sys.maxsize > (1 << 32)
|
|||||||
isworker = 'CALIBRE_WORKER' in os.environ or 'CALIBRE_SIMPLE_WORKER' in os.environ
|
isworker = 'CALIBRE_WORKER' in os.environ or 'CALIBRE_SIMPLE_WORKER' in os.environ
|
||||||
if isworker:
|
if isworker:
|
||||||
os.environ.pop('CALIBRE_FORCE_ANSI', None)
|
os.environ.pop('CALIBRE_FORCE_ANSI', None)
|
||||||
|
FAKE_PROTOCOL, FAKE_HOST = 'https', 'calibre-internal.invalid'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
preferred_encoding = locale.getpreferredencoding()
|
preferred_encoding = locale.getpreferredencoding()
|
||||||
|
@ -11,10 +11,10 @@ import json
|
|||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QWidget, QTimer, QStackedLayout, QLabel, QScrollArea, QVBoxLayout,
|
QWidget, QTimer, QStackedLayout, QLabel, QScrollArea, QVBoxLayout,
|
||||||
QPainter, Qt, QPalette, QRect, QSize, QSizePolicy, pyqtSignal,
|
QPainter, Qt, QPalette, QRect, QSize, QSizePolicy, pyqtSignal,
|
||||||
QColor, QMenu, QApplication, QIcon)
|
QColor, QMenu, QApplication, QIcon, QUrl)
|
||||||
|
|
||||||
from calibre.constants import iswindows
|
from calibre.constants import FAKE_HOST, FAKE_PROTOCOL
|
||||||
from calibre.gui2.tweak_book import editors, actions, current_container, tprefs
|
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.themes import get_theme, theme_color
|
||||||
from calibre.gui2.tweak_book.editor.text import default_font_family
|
from calibre.gui2.tweak_book.editor.text import default_font_family
|
||||||
from css_selectors import parse, SelectorError
|
from css_selectors import parse, SelectorError
|
||||||
@ -518,12 +518,11 @@ class LiveCSS(QWidget):
|
|||||||
rule['properties'] = properties
|
rule['properties'] = properties
|
||||||
|
|
||||||
href = rule['href']
|
href = rule['href']
|
||||||
if hasattr(href, 'startswith') and href.startswith('file://'):
|
if hasattr(href, 'startswith') and href.startswith('%s://%s' % (FAKE_PROTOCOL, FAKE_HOST)):
|
||||||
href = href[len('file://'):]
|
qurl = QUrl(href)
|
||||||
if iswindows and href.startswith('/'):
|
name = qurl.path()[1:]
|
||||||
href = href[1:]
|
if name:
|
||||||
if href:
|
rule['href'] = name
|
||||||
rule['href'] = current_container().abspath_to_name(href, root=self.preview.current_root)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_name(self):
|
def current_name(self):
|
||||||
@ -568,4 +567,3 @@ class LiveCSS(QWidget):
|
|||||||
editor.goto_css_rule(data['rule_address'])
|
editor.goto_css_rule(data['rule_address'])
|
||||||
elif data['type'] == 'elem':
|
elif data['type'] == 'elem':
|
||||||
editor.goto_css_rule(data['rule_address'], sourceline_address=data['sourceline_address'])
|
editor.goto_css_rule(data['rule_address'], sourceline_address=data['sourceline_address'])
|
||||||
|
|
||||||
|
@ -17,15 +17,14 @@ from urlparse import urlparse
|
|||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
|
QWidget, QVBoxLayout, QApplication, QSize, QNetworkAccessManager, QMenu, QIcon,
|
||||||
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QNetworkDiskCache, QToolBar,
|
QNetworkReply, QTimer, QNetworkRequest, QUrl, Qt, QToolBar,
|
||||||
pyqtSlot, pyqtSignal)
|
pyqtSlot, pyqtSignal)
|
||||||
from PyQt5.QtWebKitWidgets import QWebView, QWebInspector, QWebPage
|
from PyQt5.QtWebKitWidgets import QWebView, QWebInspector, QWebPage
|
||||||
|
|
||||||
from calibre import prints
|
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.polish.parsing import parse
|
||||||
from calibre.ebooks.oeb.base import serialize, OEB_DOCS
|
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 import error_dialog, open_url, NO_URL_FORMATTING
|
||||||
from calibre.gui2.tweak_book import current_container, editors, tprefs, actions, TOP
|
from calibre.gui2.tweak_book import current_container, editors, tprefs, actions, TOP
|
||||||
from calibre.gui2.viewer.documentview import apply_settings
|
from calibre.gui2.viewer.documentview import apply_settings
|
||||||
@ -169,6 +168,12 @@ class NetworkReply(QNetworkReply):
|
|||||||
data = data.encode('utf-8')
|
data = data.encode('utf-8')
|
||||||
mime_type += '; charset=utf-8'
|
mime_type += '; charset=utf-8'
|
||||||
self.__data = data
|
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.ContentTypeHeader, mime_type)
|
||||||
self.setHeader(QNetworkRequest.ContentLengthHeader, len(self.__data))
|
self.setHeader(QNetworkRequest.ContentLengthHeader, len(self.__data))
|
||||||
QTimer.singleShot(0, self.finalize_reply)
|
QTimer.singleShot(0, self.finalize_reply)
|
||||||
@ -220,25 +225,11 @@ class NetworkAccessManager(QNetworkAccessManager):
|
|||||||
'Custom')
|
'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):
|
def createRequest(self, operation, request, data):
|
||||||
url = unicode(request.url().toString(NO_URL_FORMATTING))
|
qurl = request.url()
|
||||||
if operation == self.GetOperation and url.startswith('file://'):
|
if operation == self.GetOperation and qurl.host() == FAKE_HOST:
|
||||||
path = url[7:]
|
name = qurl.path()[1:]
|
||||||
if iswindows and path.startswith('/'):
|
|
||||||
path = path[1:]
|
|
||||||
c = current_container()
|
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):
|
if c.has_name(name):
|
||||||
try:
|
try:
|
||||||
return NetworkReply(self, request, c.mime_map.get(name, 'application/octet-stream'), name)
|
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.mainFrame().javaScriptWindowObjectCleared.connect(self.init_javascript)
|
||||||
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):
|
def javaScriptConsoleMessage(self, msg, lineno, source_id):
|
||||||
prints('preview js:%s:%s:'%(unicode(source_id), lineno), unicode(msg))
|
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
|
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.
|
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):
|
def inspect(self):
|
||||||
self.inspector.parent().show()
|
self.inspector.parent().show()
|
||||||
@ -559,13 +536,19 @@ class Preview(QWidget):
|
|||||||
error_dialog(self, _('Failed to launch worker'), _(
|
error_dialog(self, _('Failed to launch worker'), _(
|
||||||
'Failed to launch the worker process used for rendering the preview'), det_msg=tb, show=True)
|
'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):
|
def show(self, name):
|
||||||
if name != self.current_name:
|
if name != self.current_name:
|
||||||
self.refresh_timer.stop()
|
self.refresh_timer.stop()
|
||||||
self.current_name = name
|
self.current_name = name
|
||||||
self.report_worker_launch_error()
|
self.report_worker_launch_error()
|
||||||
parse_worker.add_request(name)
|
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
|
return True
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
@ -576,7 +559,7 @@ class Preview(QWidget):
|
|||||||
self.report_worker_launch_error()
|
self.report_worker_launch_error()
|
||||||
parse_worker.add_request(self.current_name)
|
parse_worker.add_request(self.current_name)
|
||||||
# Tell webkit to reload all html and associated resources
|
# 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()
|
self.refresh_starting.emit()
|
||||||
if current_url != self.view.url():
|
if current_url != self.view.url():
|
||||||
# The container was changed
|
# The container was changed
|
||||||
@ -589,10 +572,6 @@ class Preview(QWidget):
|
|||||||
self.view.clear()
|
self.view.clear()
|
||||||
self.current_name = None
|
self.current_name = None
|
||||||
|
|
||||||
@property
|
|
||||||
def current_root(self):
|
|
||||||
return self.view.page().current_root
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_visible(self):
|
def is_visible(self):
|
||||||
return actions['preview-dock'].isChecked()
|
return actions['preview-dock'].isChecked()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user