From 3fa649358b4b283d6c77fc92598c163e44212a03 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 22 Mar 2012 13:12:51 +0530 Subject: [PATCH] E-book viewer: Try to preserve page position when the window is resized --- src/calibre/gui2/viewer/documentview.py | 27 ++++-------------- src/calibre/gui2/viewer/main.py | 38 ++++++++++++++++--------- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/src/calibre/gui2/viewer/documentview.py b/src/calibre/gui2/viewer/documentview.py index 7999458004..3dee673150 100644 --- a/src/calibre/gui2/viewer/documentview.py +++ b/src/calibre/gui2/viewer/documentview.py @@ -8,7 +8,7 @@ import os, math, re, glob, sys, zipfile from base64 import b64encode from functools import partial -from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QTimer, +from PyQt4.Qt import (QSize, QSizePolicy, QUrl, SIGNAL, Qt, QPainter, QPalette, QBrush, QFontDatabase, QDialog, QColor, QPoint, QImage, QRegion, QVariant, QIcon, QFont, pyqtSignature, QAction, QByteArray, QMenu, @@ -184,12 +184,10 @@ class Document(QWebPage): # {{{ self.misc_config() self.after_load() - def __init__(self, shortcuts, parent=None, resize_callback=lambda: None, - debug_javascript=False): + def __init__(self, shortcuts, parent=None, debug_javascript=False): QWebPage.__init__(self, parent) self.setObjectName("py_bridge") self.debug_javascript = debug_javascript - self.resize_callback = resize_callback self.current_language = None self.loaded_javascript = False self.js_loader = JavaScriptLoader( @@ -259,12 +257,6 @@ class Document(QWebPage): # {{{ if self.loaded_javascript: return self.loaded_javascript = True - self.javascript( - ''' - window.onresize = function(event) { - window.py_bridge.window_resized(); - } - ''') self.loaded_lang = self.js_loader(self.mainFrame().evaluateJavaScript, self.current_language, self.hyphenate_default_lang) @@ -310,10 +302,6 @@ class Document(QWebPage): # {{{ def debug(self, msg): prints(msg) - @pyqtSignature('') - def window_resized(self): - self.resize_callback() - def reference_mode(self, enable): self.javascript(('enter' if enable else 'leave')+'_reference_mode()') @@ -444,7 +432,7 @@ class Document(QWebPage): # {{{ def scroll_fraction(self): def fget(self): try: - return float(self.ypos)/(self.height-self.window_height) + return abs(float(self.ypos)/(self.height-self.window_height)) except ZeroDivisionError: return 0. def fset(self, val): @@ -516,7 +504,6 @@ class DocumentView(QWebView): # {{{ self.initial_pos = 0.0 self.to_bottom = False self.document = Document(self.shortcuts, parent=self, - resize_callback=self.viewport_resized, debug_javascript=debug_javascript) self.setPage(self.document) self.manager = None @@ -1035,13 +1022,9 @@ class DocumentView(QWebView): # {{{ return handled def resizeEvent(self, event): - ret = QWebView.resizeEvent(self, event) - QTimer.singleShot(10, self.initialize_scrollbar) - return ret - - def viewport_resized(self): if self.manager is not None: - self.manager.viewport_resized(self.scroll_fraction) + self.manager.viewport_resize_started(event) + return QWebView.resizeEvent(self, event) def event(self, ev): if ev.type() == ev.Gesture: diff --git a/src/calibre/gui2/viewer/main.py b/src/calibre/gui2/viewer/main.py index 8ff496dfea..413916fb81 100644 --- a/src/calibre/gui2/viewer/main.py +++ b/src/calibre/gui2/viewer/main.py @@ -224,6 +224,10 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.toc.setVisible(False) self.action_quit = QAction(self) self.addAction(self.action_quit) + self.view_resized_timer = QTimer(self) + self.view_resized_timer.timeout.connect(self.viewport_resize_finished) + self.view_resized_timer.setSingleShot(True) + self.resize_in_progress = False qs = [Qt.CTRL+Qt.Key_Q] if isosx: qs += [Qt.CTRL+Qt.Key_W] @@ -301,8 +305,6 @@ class EbookViewer(MainWindow, Ui_EbookViewer): _('Press Esc to quit')), self) self.full_screen_label.setVisible(False) - self.window_mode_toggle_timer = QTimer(self) - self.window_mode_toggle_timer.timeout.connect(self.handle_window_mode_toggle) self.full_screen_label.setStyleSheet(''' QLabel { text-align: center; @@ -693,20 +695,28 @@ class EbookViewer(MainWindow, Ui_EbookViewer): self.open_progress_indicator(_('Laying out %s')%self.current_title) self.view.load_path(path, pos=pos) - def viewport_resized(self, frac): + def viewport_resize_started(self, event): + if not self.resize_in_progress: + # First resize, so save the current page position + self.resize_in_progress = True + if not self.window_mode_changed: + # The special handling for window mode changed will already + # have saved page position, so only save it if this is not a + # mode change + self.view.document.page_position.save() + + if self.resize_in_progress: + self.view_resized_timer.start(75) + + def viewport_resize_finished(self): + # There hasn't been a resize event for some time + # restore the current page position. + self.resize_in_progress = False if self.window_mode_changed: - # Soak up extra window resize events - self.window_mode_toggle_timer.start(15) - return - new_page = self.pos.value() - if self.current_page is not None: - try: - frac = float(new_page-self.current_page.start_page)/(self.current_page.pages-1) - except ZeroDivisionError: - frac = 0 - self.view.scroll_to(frac, notify=False) + # This resize is part of a window mode change, special case it + self.handle_window_mode_toggle() else: - self.set_page_number(frac) + self.view.document.page_position.restore() def close_progress_indicator(self): self.pi.stop()