From 0d3f9eb8a45225472c935610d4308b0720cad1c3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 4 Dec 2009 18:06:52 -0700 Subject: [PATCH 01/10] ... --- Changelog.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.yaml b/Changelog.yaml index f2eee7dbef..727c717bd6 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -4,7 +4,7 @@ # for important features/bug fixes. # Also, each release can have new and improved recipes. -- version: 0.6.25 +- version: 0.6.26 date: 2009-12-04 new features: From 7faf8b09a0b2537dfcf73b9d39df274cf2a3737f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 5 Dec 2009 08:28:22 -0700 Subject: [PATCH 02/10] FB2 Output: Support creation of TOC from

tags --- src/calibre/ebooks/fb2/fb2ml.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/calibre/ebooks/fb2/fb2ml.py b/src/calibre/ebooks/fb2/fb2ml.py index 41b93f6d6b..31b0d8f0a2 100644 --- a/src/calibre/ebooks/fb2/fb2ml.py +++ b/src/calibre/ebooks/fb2/fb2ml.py @@ -46,6 +46,10 @@ TAG_LINKS = [ 'a', ] +TAG_TITLE = [ + 'h1', +] + STYLES = [ ('font-weight', {'bold' : 'strong', 'bolder' : 'strong'}), ('font-style', {'italic' : 'emphasis'}), @@ -196,7 +200,6 @@ class FB2MLizer(object): return [u''] tag = barename(elem.tag) - tag_count = 0 if tag in TAG_IMAGES: if elem.attrib.get('src', None): @@ -218,7 +221,6 @@ class FB2MLizer(object): self.link_hrefs[href] = 'calibre_link-%s' % len(self.link_hrefs.keys()) href = self.link_hrefs[href] fb2_text.append('' % href) - tag_count += 1 tag_stack.append('a') # Anchor ids @@ -226,11 +228,20 @@ class FB2MLizer(object): if id_name: fb2_text.append(self.get_anchor(page, id_name)) + if tag in TAG_TITLE: + if 'p' in tag_stack: + ctag = [] + ctag.append(tag_stack.pop()) + while ctag[-1] != 'p': + ctag.append(tag_stack.pop()) + fb2_text += self.close_tags(ctag) + fb2_text.append('
<p>') + tag_stack.append('title') + tag_stack.append('p') + fb2_tag = TAG_MAP.get(tag, None) if fb2_tag: - if fb2_tag not in tag_stack: - tag_count += 1 - else: + if fb2_tag in tag_stack: tag_stack.reverse() tag_stack.remove(fb2_tag) tag_stack.reverse() @@ -242,7 +253,6 @@ class FB2MLizer(object): for s in STYLES: style_tag = s[1].get(style[s[0]], None) if style_tag: - tag_count += 1 fb2_text.append('<%s>' % style_tag) tag_stack.append(style_tag) @@ -260,7 +270,7 @@ class FB2MLizer(object): fb2_text += self.dump_text(item, stylizer, page, tag_stack) close_tag_list = [] - for i in range(0, tag_count): + for i in range(0, len(tag_stack)): close_tag_list.insert(0, tag_stack.pop()) fb2_text += self.close_tags(close_tag_list) From c98ed0db76079158a80464096a81398bdd3c41b8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 08:33:50 -0700 Subject: [PATCH 03/10] Finding calibre-parallel: If sys.executables_location is wrong (as might happen in distro packages) fallback to using PATH --- src/calibre/utils/ipc/launch.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/calibre/utils/ipc/launch.py b/src/calibre/utils/ipc/launch.py index dbabfe86b2..0de81ed644 100644 --- a/src/calibre/utils/ipc/launch.py +++ b/src/calibre/utils/ipc/launch.py @@ -54,9 +54,14 @@ class Worker(object): 'console.app', 'Contents') return os.path.join(contents, 'MacOS', self.osx_interpreter) - return os.path.join(getattr(sys, 'frozen_path'), 'calibre-parallel') \ - if isfrozen else \ - os.path.join(sys.executables_location, 'calibre-parallel') + if isfrozen: + return os.path.join(getattr(sys, 'frozen_path'), 'calibre-parallel') + + c = os.path.join(sys.executables_location, 'calibre-parallel') + if os.access(c, os.X_OK): + return c + return 'calibre-parallel' + @property def gui_executable(self): From db6f1e7d50fff518d1a207cf152586454f1c0df9 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 09:05:26 -0700 Subject: [PATCH 04/10] Fix #2152 (Typo in GUI) --- src/calibre/gui2/ui.py | 2 +- src/calibre/translations/calibre.pot | 72 +++++++++++++--------------- 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 5bb00f0bb5..a25d4b2718 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -870,7 +870,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI): from a book file. ''' num, ok = QInputDialog.getInt(self, _('How many empty books?'), - _('How many empty boks should be added?'), 1, 1, 100) + _('How many empty books should be added?'), 1, 1, 100) if ok: from calibre.ebooks.metadata import MetaInformation for x in xrange(num): diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index dbe83e5082..a5a742b8a4 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.6.26\n" -"POT-Creation-Date: 2009-12-04 13:21+MST\n" -"PO-Revision-Date: 2009-12-04 13:21+MST\n" +"POT-Creation-Date: 2009-12-05 09:03+MST\n" +"PO-Revision-Date: 2009-12-05 09:03+MST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -164,54 +164,50 @@ msgid "Character encoding for the input HTML files. Common choices include: cp12 msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:56 -msgid " Create a PMLZ archive containing the PML file and all images in the directory pmlname_img or images file containing all linked files. This plugin is run every time you add an PML file to the library. " +msgid "Create a PMLZ archive containing the PML file and all images in the directory pmlname_img or images. This plugin is run every time you add a PML file to the library." msgstr "" #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:87 -msgid "Character encoding for the input PML files. Should ways be: cp1252." -msgstr "" - -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:94 msgid "Extract cover from comic files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:115 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:127 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:137 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:147 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:158 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:168 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:178 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:188 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:198 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:208 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:219 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:230 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:242 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:263 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:274 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:284 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:294 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:108 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:120 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:130 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:140 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:151 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:161 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:171 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:181 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:191 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:201 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:212 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:223 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:235 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:256 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:267 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:277 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:287 msgid "Read metadata from %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:253 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:246 msgid "Read metadata from ebooks in RAR archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:305 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:298 msgid "Read metadata from ebooks in ZIP archives" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:316 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:326 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:336 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:358 -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:369 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:309 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:319 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:329 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:351 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:362 msgid "Set metadata in %s files" msgstr "" -#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:347 +#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:340 msgid "Set metadata from %s files" msgstr "" @@ -989,7 +985,7 @@ msgstr "" msgid "Normally, if the input file has no cover and you don't specify one, a default cover is generated with the title, authors, etc. This option disables the generation of this cover." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/fb2ml.py:126 +#: /home/kovid/work/calibre/src/calibre/ebooks/fb2/fb2ml.py:130 #: /home/kovid/work/calibre/src/calibre/ebooks/pml/pmlml.py:114 #: /home/kovid/work/calibre/src/calibre/ebooks/rb/rbml.py:101 #: /home/kovid/work/calibre/src/calibre/ebooks/txt/txtml.py:77 @@ -1449,19 +1445,19 @@ msgstr "" msgid "Download %s from %s" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:135 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:137 msgid "Downloads metadata from Google Books" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:151 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:153 msgid "Downloads metadata from isbndb.com" msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:179 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:181 msgid "To use isbndb.com you must sign up for a %sfree account%s and enter your access key below." msgstr "" -#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:187 +#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/fetch.py:189 msgid "Downloads social metadata from amazon.com" msgstr "" @@ -5268,7 +5264,7 @@ msgid "How many empty books?" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/ui.py:873 -msgid "How many empty boks should be added?" +msgid "How many empty books should be added?" msgstr "" #: /home/kovid/work/calibre/src/calibre/gui2/ui.py:917 From f58c59ca0aa4b4e975419350b78ee3356db7f5ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 09:50:44 -0700 Subject: [PATCH 05/10] News download: Remove onload attributes when removing javascript --- src/calibre/web/feeds/news.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/calibre/web/feeds/news.py b/src/calibre/web/feeds/news.py index 8a7f25158e..6ff0424162 100644 --- a/src/calibre/web/feeds/news.py +++ b/src/calibre/web/feeds/news.py @@ -572,6 +572,9 @@ class BasicNewsRecipe(Recipe): if self.remove_javascript: for script in list(soup.findAll('script')): script.extract() + for o in soup.findAll(onload=True): + del o['onload'] + for script in list(soup.findAll('noscript')): script.extract() for attr in self.remove_attributes: From 4f13ef6aaa0e458cb543a29f31626f5a201267b8 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 09:51:38 -0700 Subject: [PATCH 06/10] Remove various bad tags from Economist downloads. --- resources/recipes/economist.recipe | 3 ++- resources/recipes/economist_free.recipe | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/recipes/economist.recipe b/resources/recipes/economist.recipe index 75cb86863a..cadf2964ed 100644 --- a/resources/recipes/economist.recipe +++ b/resources/recipes/economist.recipe @@ -22,7 +22,8 @@ class Economist(BasicNewsRecipe): oldest_article = 7.0 cover_url = 'http://www.economist.com/images/covers/currentcovereu_large.jpg' - remove_tags = [dict(name=['script', 'noscript', 'title'])] + remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']), + dict(attrs={'class':['dblClkTrk']})] remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body') needs_subscription = True diff --git a/resources/recipes/economist_free.recipe b/resources/recipes/economist_free.recipe index effda489c9..f7c1b3816f 100644 --- a/resources/recipes/economist_free.recipe +++ b/resources/recipes/economist_free.recipe @@ -16,7 +16,8 @@ class Economist(BasicNewsRecipe): oldest_article = 6.5 cover_url = 'http://www.economist.com/images/covers/currentcovereu_large.jpg' - remove_tags = [dict(name=['script', 'noscript', 'title'])] + remove_tags = [dict(name=['script', 'noscript', 'title', 'iframe', 'cf_floatingcontent']), + dict(attrs={'class':['dblClkTrk']})] remove_tags_before = dict(name=lambda tag: tag.name=='title' and tag.parent.name=='body') def parse_index(self): From 004e7cfb68807c58996e3a3daa0e22a50f0b6a9e Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 10:50:19 -0700 Subject: [PATCH 07/10] E-book viewer: Properly handle <iframe> tags --- src/calibre/gui2/viewer/documentview.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 1cabe310a1..3f80f9c154 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en' ''' ''' import os, math, re, glob -from PyQt4.Qt import QWidget, QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \ +from PyQt4.Qt import QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, \ QPainter, QPalette, QBrush, QFontDatabase, QDialog, \ QColor, QPoint, QImage, QRegion, QVariant, \ QFont, QObject, QApplication, pyqtSignature @@ -343,6 +343,8 @@ class Document(QWebPage): def width(self): return self.mainFrame().contentsSize().width() # offsetWidth gives inaccurate results + def load_finished(self, ok): + self.javascript('$("body").css("padding-bottom: 0px")') class EntityDeclarationProcessor(object): @@ -361,7 +363,7 @@ class DocumentView(QWebView): DISABLED_BRUSH = QBrush(Qt.lightGray, Qt.Dense5Pattern) def __init__(self, *args): - QWidget.__init__(self, *args) + QWebView.__init__(self, *args) self.debug_javascript = False self.self_closing_pat = re.compile(r'<([a-z]+)\s+([^>]+)/>', re.IGNORECASE) @@ -374,8 +376,8 @@ class DocumentView(QWebView): self.manager = None self._reference_mode = False self._ignore_scrollbar_signals = False - self.connect(self.document, SIGNAL('loadStarted()'), self.load_started) - self.connect(self.document, SIGNAL('loadFinished(bool)'), self.load_finished) + self.loading_url = None + self.loadFinished.connect(self.load_finished) self.connect(self.document, SIGNAL('linkClicked(QUrl)'), self.link_clicked) self.connect(self.document, SIGNAL('linkHovered(QString,QString,QString)'), self.link_hovered) self.connect(self.document, SIGNAL('selectionChanged()'), self.selection_changed) @@ -473,13 +475,12 @@ class DocumentView(QWebView): html = EntityDeclarationProcessor(html).processed_html if 'xhtml' in mt: html = self.self_closing_pat.sub(self.self_closing_sub, html) - #self.setContent(QByteArray(html.encode(path.encoding)), mt, QUrl.fromLocalFile(path)) - self.setHtml(html, QUrl.fromLocalFile(path)) - self.turn_off_internal_scrollbars() - - def load_started(self): if self.manager is not None: self.manager.load_started() + self.loading_url = QUrl.fromLocalFile(path) + #self.setContent(QByteArray(html.encode(path.encoding)), mt, QUrl.fromLocalFile(path)) + self.setHtml(html, self.loading_url) + self.turn_off_internal_scrollbars() def initialize_scrollbar(self): if getattr(self, 'scrollbar', None) is not None: @@ -497,6 +498,11 @@ class DocumentView(QWebView): def load_finished(self, ok): + if self.loading_url is None: + # An <iframe> finished loading + return + self.loading_url = None + self.document.load_finished(ok) self._size_hint = self.document.mainFrame().contentsSize() scrolled = False if self.to_bottom: From d8ba028e1fa2774be12947d7336afbd00fbad344 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 10:56:34 -0700 Subject: [PATCH 08/10] Add command line completion for ebook-viewer --- src/calibre/linux.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/calibre/linux.py b/src/calibre/linux.py index daa974db3b..7af0fe1a5d 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -172,11 +172,12 @@ class PostInstall: from calibre.ebooks.metadata.cli import option_parser as metaop, filetypes as meta_filetypes from calibre.ebooks.lrf.lrfparser import option_parser as lrf2lrsop from calibre.gui2.lrf_renderer.main import option_parser as lrfviewerop + from calibre.gui2.viewer.main import option_parser as viewer_op from calibre.ebooks.metadata.fetch import option_parser as fem_op from calibre.gui2.main import option_parser as guiop from calibre.utils.smtp import option_parser as smtp_op any_formats = ['epub', 'htm', 'html', 'xhtml', 'xhtm', 'rar', 'zip', - 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi', 'fb2', 'odt'] + 'txt', 'lit', 'rtf', 'pdf', 'prc', 'mobi', 'fb2', 'odt', 'lrf'] bc = os.path.join(os.path.dirname(self.opts.staging_sharedir), 'bash-completion') if os.path.exists(bc): @@ -193,6 +194,7 @@ class PostInstall: f.write(opts_and_exts('lrf2lrs', lrf2lrsop, ['lrf'])) f.write(opts_and_exts('ebook-meta', metaop, list(meta_filetypes()))) f.write(opts_and_exts('lrfviewer', lrfviewerop, ['lrf'])) + f.write(opts_and_exts('ebook-viewer', viewer_op, any_formats)) f.write(opts_and_words('fetch-ebook-metadata', fem_op, [])) f.write(opts_and_words('calibre-smtp', smtp_op, [])) f.write(textwrap.dedent(''' From 6eb1036f422fb0c65cc381a3dcaa5cd3618361a4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 11:00:37 -0700 Subject: [PATCH 09/10] Economist free recipe: respect proxy settings --- resources/recipes/economist_free.recipe | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/recipes/economist_free.recipe b/resources/recipes/economist_free.recipe index f7c1b3816f..7c27764b8d 100644 --- a/resources/recipes/economist_free.recipe +++ b/resources/recipes/economist_free.recipe @@ -3,7 +3,6 @@ from calibre.utils.threadpool import ThreadPool, makeRequests import time from datetime import datetime from lxml import html -from urllib2 import urlopen class Economist(BasicNewsRecipe): @@ -45,10 +44,12 @@ class Economist(BasicNewsRecipe): return [(t, a) for t, a in self.feed_dict.items()] def process_eco_feed_article(self, args): + from calibre import browser i, url, title, description, author, published = args - ret = urlopen(url) + br = browser() + ret = br.open(url) raw = ret.read() - url = ret.geturl().replace('displaystory', 'PrinterFriendly').strip() + url = br.geturl().replace('displaystory', 'PrinterFriendly').strip() root = html.fromstring(raw) matches = root.xpath('//*[@class = "article-section"]') feedtitle = 'Miscellaneous' From 3b3a189b03511cd460ffa94dd57e665275b624c0 Mon Sep 17 00:00:00 2001 From: Kovid Goyal <kovid@kovidgoyal.net> Date: Sat, 5 Dec 2009 11:20:17 -0700 Subject: [PATCH 10/10] Fix #3328 (Scroll past page-break to maintain reading flow) --- src/calibre/gui2/viewer/documentview.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 3f80f9c154..348b1232ee 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -343,8 +343,9 @@ class Document(QWebPage): def width(self): return self.mainFrame().contentsSize().width() # offsetWidth gives inaccurate results - def load_finished(self, ok): - self.javascript('$("body").css("padding-bottom: 0px")') + def set_bottom_padding(self, amount): + self.javascript('$("body").css("padding-bottom", "%dpx")' % amount) + class EntityDeclarationProcessor(object): @@ -502,7 +503,7 @@ class DocumentView(QWebView): # An <iframe> finished loading return self.loading_url = None - self.document.load_finished(ok) + self.document.set_bottom_padding(0) self._size_hint = self.document.mainFrame().contentsSize() scrolled = False if self.to_bottom: @@ -573,9 +574,13 @@ class DocumentView(QWebView): if self.manager is not None: self.manager.next_document() else: + self.document.set_bottom_padding(0) opos = self.document.ypos lower_limit = opos + delta_y max_y = self.document.height - window_height + if max_y < lower_limit: + self.document.set_bottom_padding(lower_limit - max_y) + max_y = self.document.height - window_height lower_limit = min(max_y, lower_limit) if lower_limit > opos: self.document.scroll_to(self.document.xpos, lower_limit)