mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-08-11 09:13:57 -04:00
E-book viewer: Make bookmark positioning (and remembering last read location) more robust. Fixes #4812 (E-book viewer not correctly remembering reading position on reopen)
This commit is contained in:
parent
80ad1fa467
commit
cf5ca45531
@ -20,37 +20,8 @@ function selector(elem) {
|
|||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
function find_closest_enclosing_block(top) {
|
function calculate_bookmark(y, node) {
|
||||||
var START = top-1000;
|
var elem = $(node);
|
||||||
var STOP = top;
|
|
||||||
var matches = [];
|
|
||||||
var elem, temp;
|
|
||||||
var width = 1000;
|
|
||||||
|
|
||||||
for (y = START; y < STOP; y += 20) {
|
|
||||||
for ( x = 0; x < width; x += 20) {
|
|
||||||
elem = document.elementFromPoint(x, y);
|
|
||||||
try {
|
|
||||||
elem = $(elem);
|
|
||||||
temp = elem.offset().top
|
|
||||||
matches.push(elem);
|
|
||||||
if (Math.abs(temp - START) < 25) { y = STOP; break}
|
|
||||||
} catch(error) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var miny = Math.abs(matches[0].offset().top - START), min_elem = matches[0];
|
|
||||||
|
|
||||||
for (i = 1; i < matches.length; i++) {
|
|
||||||
elem = matches[i];
|
|
||||||
temp = Math.abs(elem.offset().top - START);
|
|
||||||
if ( temp < miny ) { miny = temp; min_elem = elem; }
|
|
||||||
}
|
|
||||||
return min_elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculate_bookmark(y) {
|
|
||||||
var elem = find_closest_enclosing_block(y);
|
|
||||||
var sel = selector(elem);
|
var sel = selector(elem);
|
||||||
var ratio = (y - elem.offset().top)/elem.height();
|
var ratio = (y - elem.offset().top)/elem.height();
|
||||||
if (ratio > 1) { ratio = 1; }
|
if (ratio > 1) { ratio = 1; }
|
||||||
|
@ -5,7 +5,7 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
'''
|
'''
|
||||||
import os, math, re, glob
|
import os, math, re, glob, sys
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
from PyQt4.Qt import QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \
|
from PyQt4.Qt import QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \
|
||||||
QPainter, QPalette, QBrush, QFontDatabase, QDialog, \
|
QPainter, QPalette, QBrush, QFontDatabase, QDialog, \
|
||||||
@ -295,8 +295,50 @@ class Document(QWebPage):
|
|||||||
if r > 0:
|
if r > 0:
|
||||||
self.javascript('document.body.style.paddingBottom = "%dpx"'%r)
|
self.javascript('document.body.style.paddingBottom = "%dpx"'%r)
|
||||||
|
|
||||||
|
def element_ypos(self, elem):
|
||||||
|
ans, ok = elem.evaluateJavaScript('$(this).offset().top').toInt()
|
||||||
|
if not ok:
|
||||||
|
raise ValueError('No ypos found')
|
||||||
|
return ans
|
||||||
|
|
||||||
|
def elem_outer_xml(self, elem):
|
||||||
|
return unicode(elem.toOuterXml())
|
||||||
|
|
||||||
|
def find_bookmark_element(self):
|
||||||
|
mf = self.mainFrame()
|
||||||
|
doc_pos = self.ypos
|
||||||
|
min_delta, min_elem = sys.maxint, None
|
||||||
|
for y in range(10, -500, -10):
|
||||||
|
for x in range(-50, 500, 10):
|
||||||
|
pos = QPoint(x, y)
|
||||||
|
result = mf.hitTestContent(pos)
|
||||||
|
if result.isNull(): continue
|
||||||
|
elem = result.enclosingBlockElement()
|
||||||
|
if elem.isNull(): continue
|
||||||
|
try:
|
||||||
|
ypos = self.element_ypos(elem)
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
delta = abs(ypos - doc_pos)
|
||||||
|
if delta < 25:
|
||||||
|
return elem
|
||||||
|
if delta < min_delta:
|
||||||
|
min_elem, min_delta = elem, delta
|
||||||
|
return min_elem
|
||||||
|
|
||||||
|
|
||||||
def bookmark(self):
|
def bookmark(self):
|
||||||
return self.javascript('calculate_bookmark(%d)'%(self.ypos+25), 'string')
|
elem = self.find_bookmark_element()
|
||||||
|
|
||||||
|
if elem is None or self.element_ypos(elem) < 100:
|
||||||
|
print elem, self.element_ypos(elem)
|
||||||
|
bm = 'body|%f'%(float(self.ypos)/(self.height*0.7))
|
||||||
|
else:
|
||||||
|
bm = unicode(elem.evaluateJavaScript(
|
||||||
|
'calculate_bookmark(%d, this)'%self.ypos).toString())
|
||||||
|
if not bm:
|
||||||
|
bm = 'body|%f'%(float(self.ypos)/(self.height*0.7))
|
||||||
|
return bm
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def at_bottom(self):
|
def at_bottom(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user