mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Do not use the pyqtProperty technique to pass data between JS and Qt as it fails with newer versions of QtWebKit
This commit is contained in:
parent
56915f8bf5
commit
650ce8aebc
Binary file not shown.
@ -163,8 +163,8 @@ class CalibreExtract
|
|||||||
cnode = inline_styles(node)
|
cnode = inline_styles(node)
|
||||||
return cnode.outerHTML
|
return cnode.outerHTML
|
||||||
|
|
||||||
is_footnote_link: (a, prefix) ->
|
is_footnote_link: (a, prefix, linked_to_anchors) ->
|
||||||
return is_footnote_link(a, a.href, py_bridge.value, prefix)
|
return is_footnote_link(a, a.href, linked_to_anchors, prefix)
|
||||||
|
|
||||||
show_footnote: (target, known_targets) ->
|
show_footnote: (target, known_targets) ->
|
||||||
if not target
|
if not target
|
||||||
|
@ -13,7 +13,7 @@ from math import floor
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QObject, QPainter, Qt, QSize, QTimer, pyqtProperty, QEventLoop, QPixmap, QRect, pyqtSlot)
|
QObject, QPainter, Qt, QSize, QTimer, QEventLoop, QPixmap, QRect, pyqtSlot)
|
||||||
from PyQt5.QtWebKit import QWebSettings
|
from PyQt5.QtWebKit import QWebSettings
|
||||||
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
from PyQt5.QtWebKitWidgets import QWebView, QWebPage
|
||||||
|
|
||||||
@ -127,16 +127,6 @@ def draw_image_page(page_rect, painter, p, preserve_aspect_ratio=True):
|
|||||||
|
|
||||||
class PDFWriter(QObject):
|
class PDFWriter(QObject):
|
||||||
|
|
||||||
def _pass_json_value_getter(self):
|
|
||||||
val = json.dumps(self.bridge_value)
|
|
||||||
return val
|
|
||||||
|
|
||||||
def _pass_json_value_setter(self, value):
|
|
||||||
self.bridge_value = json.loads(unicode(value))
|
|
||||||
|
|
||||||
_pass_json_value = pyqtProperty(str, fget=_pass_json_value_getter,
|
|
||||||
fset=_pass_json_value_setter)
|
|
||||||
|
|
||||||
@pyqtSlot(result=unicode)
|
@pyqtSlot(result=unicode)
|
||||||
def title(self):
|
def title(self):
|
||||||
return self.doc_title
|
return self.doc_title
|
||||||
@ -361,33 +351,32 @@ class PDFWriter(QObject):
|
|||||||
evaljs(self.paged_js)
|
evaljs(self.paged_js)
|
||||||
self.load_mathjax()
|
self.load_mathjax()
|
||||||
|
|
||||||
evaljs('''
|
amap = evaljs('''
|
||||||
Object.defineProperty(py_bridge, 'value', {
|
|
||||||
get : function() { return JSON.parse(this._pass_json_value); },
|
|
||||||
set : function(val) { this._pass_json_value = JSON.stringify(val); }
|
|
||||||
});
|
|
||||||
|
|
||||||
document.body.style.backgroundColor = "white";
|
document.body.style.backgroundColor = "white";
|
||||||
paged_display.set_geometry(1, %d, %d, %d);
|
paged_display.set_geometry(1, %d, %d, %d);
|
||||||
paged_display.layout();
|
paged_display.layout();
|
||||||
paged_display.fit_images();
|
paged_display.fit_images();
|
||||||
py_bridge.value = book_indexing.all_links_and_anchors();
|
ret = book_indexing.all_links_and_anchors();
|
||||||
window.scrollTo(0, 0); // This is needed as getting anchor positions could have caused the viewport to scroll
|
window.scrollTo(0, 0); // This is needed as getting anchor positions could have caused the viewport to scroll
|
||||||
|
ret;
|
||||||
'''%(self.margin_top, 0, self.margin_bottom))
|
'''%(self.margin_top, 0, self.margin_bottom))
|
||||||
|
|
||||||
amap = self.bridge_value
|
|
||||||
if not isinstance(amap, dict):
|
if not isinstance(amap, dict):
|
||||||
amap = {'links':[], 'anchors':{}} # Some javascript error occurred
|
amap = {'links':[], 'anchors':{}} # Some javascript error occurred
|
||||||
|
for val in amap['anchors'].itervalues():
|
||||||
|
if isinstance(val, dict) and 'column' in val:
|
||||||
|
val['column'] = int(val['column'])
|
||||||
|
for href, val in amap['links']:
|
||||||
|
if isinstance(val, dict) and 'column' in val:
|
||||||
|
val['column'] = int(val['column'])
|
||||||
sections = self.get_sections(amap['anchors'])
|
sections = self.get_sections(amap['anchors'])
|
||||||
tl_sections = self.get_sections(amap['anchors'], True)
|
tl_sections = self.get_sections(amap['anchors'], True)
|
||||||
col = 0
|
col = 0
|
||||||
|
|
||||||
if self.header:
|
if self.header:
|
||||||
self.bridge_value = self.header
|
evaljs('paged_display.header_template = ' + json.dumps(self.header))
|
||||||
evaljs('paged_display.header_template = py_bridge.value')
|
|
||||||
if self.footer:
|
if self.footer:
|
||||||
self.bridge_value = self.footer
|
evaljs('paged_display.footer_template = ' + json.dumps(self.footer))
|
||||||
evaljs('paged_display.footer_template = py_bridge.value')
|
|
||||||
if self.header or self.footer:
|
if self.header or self.footer:
|
||||||
evaljs('paged_display.create_header_footer("%s");'%self.hf_uuid)
|
evaljs('paged_display.create_header_footer("%s");'%self.hf_uuid)
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ class Page(QWebPage): # {{{
|
|||||||
secure_web_page(self.settings())
|
secure_web_page(self.settings())
|
||||||
self.js = None
|
self.js = None
|
||||||
self.evaljs = self.mainFrame().evaluateJavaScript
|
self.evaljs = self.mainFrame().evaluateJavaScript
|
||||||
self.bridge_value = None
|
|
||||||
nam = self.networkAccessManager()
|
nam = self.networkAccessManager()
|
||||||
nam.setNetworkAccessible(nam.NotAccessible)
|
nam.setNetworkAccessible(nam.NotAccessible)
|
||||||
self.setLinkDelegationPolicy(self.DelegateAllLinks)
|
self.setLinkDelegationPolicy(self.DelegateAllLinks)
|
||||||
|
@ -10,7 +10,7 @@ from functools import partial
|
|||||||
from future_builtins import map
|
from future_builtins import map
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QSize, QSizePolicy, QUrl, Qt, pyqtProperty, QPainter, QPalette, QBrush,
|
QSize, QSizePolicy, QUrl, Qt, QPainter, QPalette, QBrush,
|
||||||
QDialog, QColor, QPoint, QImage, QRegion, QIcon, QAction, QMenu,
|
QDialog, QColor, QPoint, QImage, QRegion, QIcon, QAction, QMenu,
|
||||||
pyqtSignal, QApplication, pyqtSlot, QKeySequence, QMimeData)
|
pyqtSignal, QApplication, pyqtSlot, QKeySequence, QMimeData)
|
||||||
from PyQt5.QtWebKitWidgets import QWebPage, QWebView
|
from PyQt5.QtWebKitWidgets import QWebPage, QWebView
|
||||||
@ -89,10 +89,6 @@ class Document(QWebPage): # {{{
|
|||||||
self.setNetworkAccessManager(self.nam)
|
self.setNetworkAccessManager(self.nam)
|
||||||
self.setObjectName("py_bridge")
|
self.setObjectName("py_bridge")
|
||||||
self.in_paged_mode = False
|
self.in_paged_mode = False
|
||||||
# Use this to pass arbitrary JSON encodable objects between python and
|
|
||||||
# javascript. In python get/set the value as: self.bridge_value. In
|
|
||||||
# javascript, get/set the value as: py_bridge.value
|
|
||||||
self.bridge_value = None
|
|
||||||
self.first_load = True
|
self.first_load = True
|
||||||
self.jump_to_cfi_listeners = set()
|
self.jump_to_cfi_listeners = set()
|
||||||
|
|
||||||
@ -197,12 +193,6 @@ class Document(QWebPage): # {{{
|
|||||||
|
|
||||||
def add_window_objects(self):
|
def add_window_objects(self):
|
||||||
self.mainFrame().addToJavaScriptWindowObject("py_bridge", self)
|
self.mainFrame().addToJavaScriptWindowObject("py_bridge", self)
|
||||||
self.javascript('''
|
|
||||||
Object.defineProperty(py_bridge, 'value', {
|
|
||||||
get : function() { return JSON.parse(this._pass_json_value); },
|
|
||||||
set : function(val) { this._pass_json_value = JSON.stringify(val); }
|
|
||||||
});
|
|
||||||
''')
|
|
||||||
self.loaded_javascript = False
|
self.loaded_javascript = False
|
||||||
|
|
||||||
def load_javascript_libraries(self):
|
def load_javascript_libraries(self):
|
||||||
@ -238,16 +228,6 @@ class Document(QWebPage): # {{{
|
|||||||
def page_turn_requested(self, backwards):
|
def page_turn_requested(self, backwards):
|
||||||
self.page_turn.emit(bool(backwards))
|
self.page_turn.emit(bool(backwards))
|
||||||
|
|
||||||
def _pass_json_value_getter(self):
|
|
||||||
val = json.dumps(self.bridge_value)
|
|
||||||
return val
|
|
||||||
|
|
||||||
def _pass_json_value_setter(self, value):
|
|
||||||
self.bridge_value = json.loads(unicode(value))
|
|
||||||
|
|
||||||
_pass_json_value = pyqtProperty(str, fget=_pass_json_value_getter,
|
|
||||||
fset=_pass_json_value_setter)
|
|
||||||
|
|
||||||
def after_load(self, last_loaded_path=None):
|
def after_load(self, last_loaded_path=None):
|
||||||
self.javascript('window.paged_display.read_document_margins()')
|
self.javascript('window.paged_display.read_document_margins()')
|
||||||
self.set_bottom_padding(0)
|
self.set_bottom_padding(0)
|
||||||
@ -267,19 +247,15 @@ class Document(QWebPage): # {{{
|
|||||||
self.first_load = False
|
self.first_load = False
|
||||||
|
|
||||||
def colors(self):
|
def colors(self):
|
||||||
self.javascript('''
|
ans = self.javascript('''
|
||||||
bs = getComputedStyle(document.body);
|
bs = getComputedStyle(document.body);
|
||||||
py_bridge.value = [bs.backgroundColor, bs.color]
|
[bs.backgroundColor, bs.color]
|
||||||
''')
|
''')
|
||||||
ans = self.bridge_value
|
return ans if isinstance(ans, list) else ['white', 'black']
|
||||||
return (ans if isinstance(ans, list) else ['white', 'black'])
|
|
||||||
|
|
||||||
def read_anchor_positions(self, use_cache=True):
|
def read_anchor_positions(self, use_cache=True):
|
||||||
self.bridge_value = tuple(self.index_anchors)
|
self.anchor_positions = self.javascript('book_indexing.anchor_positions(%s, %s);' % (
|
||||||
self.javascript(u'''
|
json.dumps(tuple(self.index_anchors)), 'true' if use_cache else 'false'))
|
||||||
py_bridge.value = book_indexing.anchor_positions(py_bridge.value, %s);
|
|
||||||
'''%('true' if use_cache else 'false'))
|
|
||||||
self.anchor_positions = self.bridge_value
|
|
||||||
if not isinstance(self.anchor_positions, dict):
|
if not isinstance(self.anchor_positions, dict):
|
||||||
# Some weird javascript error happened
|
# Some weird javascript error happened
|
||||||
self.anchor_positions = {}
|
self.anchor_positions = {}
|
||||||
@ -323,8 +299,8 @@ class Document(QWebPage): # {{{
|
|||||||
def column_boundaries(self):
|
def column_boundaries(self):
|
||||||
if not self.loaded_javascript:
|
if not self.loaded_javascript:
|
||||||
return (0, 1)
|
return (0, 1)
|
||||||
self.javascript(u'py_bridge.value = paged_display.column_boundaries()')
|
ans = self.javascript(u'paged_display.column_boundaries()')
|
||||||
return tuple(self.bridge_value)
|
return tuple(int(x) for x in ans)
|
||||||
|
|
||||||
def after_resize(self):
|
def after_resize(self):
|
||||||
if self.in_paged_mode:
|
if self.in_paged_mode:
|
||||||
|
@ -137,8 +137,7 @@ class Footnotes(object):
|
|||||||
linked_to_anchors = {}
|
linked_to_anchors = {}
|
||||||
else:
|
else:
|
||||||
linked_to_anchors = {anchor:0 for path, anchor in dest_path.verified_links if path == current_path}
|
linked_to_anchors = {anchor:0 for path, anchor in dest_path.verified_links if path == current_path}
|
||||||
self.view.document.bridge_value = linked_to_anchors
|
if a.evaluateJavaScript('calibre_extract.is_footnote_link(this, "%s://%s", %s)' % (FAKE_PROTOCOL, FAKE_HOST, json.dumps(linked_to_anchors))):
|
||||||
if a.evaluateJavaScript('calibre_extract.is_footnote_link(this, "%s://%s")' % (FAKE_PROTOCOL, FAKE_HOST)):
|
|
||||||
if dest_path not in self.known_footnote_targets:
|
if dest_path not in self.known_footnote_targets:
|
||||||
self.known_footnote_targets[dest_path] = s = set()
|
self.known_footnote_targets[dest_path] = s = set()
|
||||||
for item in self.view.manager.iterator.spine:
|
for item in self.view.manager.iterator.spine:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user