From 2a66dfead081a92db8d26fb564d3da1afba68a0a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 23 Dec 2020 19:16:06 +0530 Subject: [PATCH] Edit book: A new option to show a configurable number lines above the current line when syncing the position of the preview panel to the current position in the code editor (under Preview settings in the Editor preferences). Fixes #1908929 [Enhancement request for seeing code changes in file previewer.](https://bugs.launchpad.net/calibre/+bug/1908929) --- src/calibre/gui2/tweak_book/__init__.py | 1 + src/calibre/gui2/tweak_book/preferences.py | 5 ++++ src/calibre/gui2/tweak_book/preview.py | 2 +- src/pyj/editor.pyj | 31 +++++++++++++++++----- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/calibre/gui2/tweak_book/__init__.py b/src/calibre/gui2/tweak_book/__init__.py index f9ebd3217b..7f365ba5ed 100644 --- a/src/calibre/gui2/tweak_book/__init__.py +++ b/src/calibre/gui2/tweak_book/__init__.py @@ -38,6 +38,7 @@ d['preview_standard_font_family'] = 'serif' d['preview_base_font_size'] = 18 d['preview_mono_font_size'] = 14 d['preview_minimum_font_size'] = 8 +d['preview_sync_context'] = 0 d['preview_background'] = 'auto' d['preview_foreground'] = 'auto' d['preview_link_color'] = 'auto' diff --git a/src/calibre/gui2/tweak_book/preferences.py b/src/calibre/gui2/tweak_book/preferences.py index 39e0d2a128..82042a597c 100644 --- a/src/calibre/gui2/tweak_book/preferences.py +++ b/src/calibre/gui2/tweak_book/preferences.py @@ -381,6 +381,11 @@ class PreviewSettings(BasicSettings): # {{{ w = self('preview_minimum_font_size') w.setMinimum(4), w.setMaximum(100), w.setSuffix(' px') l.addRow(_('Mi&nimum font size:'), w) + w = self('preview_sync_context') + w.setMinimum(0), w.setMaximum(10), w.setSuffix(' ' + _('lines')) + w.setToolTip('

' + _( + 'Number of lines that are shown above the current line when syncing the text shown in the preview panel to the cursor position in the code view')) + l.addRow(_('Visible lines above s&ync point:'), w) l.addRow(_('Background color:'), self.color_override('preview_background')) l.addRow(_('Foreground color:'), self.color_override('preview_foreground')) l.addRow(_('Link color:'), self.color_override('preview_link_color')) diff --git a/src/calibre/gui2/tweak_book/preview.py b/src/calibre/gui2/tweak_book/preview.py index fae4d4b9fa..acd9692222 100644 --- a/src/calibre/gui2/tweak_book/preview.py +++ b/src/calibre/gui2/tweak_book/preview.py @@ -341,7 +341,7 @@ class WebPage(QWebEnginePage): if lnum is None: return tags = [x.lower() for x in tags] - self.bridge.go_to_sourceline_address.emit(lnum, tags) + self.bridge.go_to_sourceline_address.emit(lnum, tags, tprefs['preview_sync_context']) def split_mode(self, enabled): if self.bridge.ready: diff --git a/src/pyj/editor.pyj b/src/pyj/editor.pyj index 2070cdcb0d..a03d886752 100644 --- a/src/pyj/editor.pyj +++ b/src/pyj/editor.pyj @@ -40,34 +40,53 @@ def find_containing_block(elem): elem = elem.parentNode return elem -def scroll_to_node(node): + +def line_height(): + ans = line_height.ans + if not ans: + ds = window.getComputedStyle(document.body) + try: + # will fail if line-height = "normal" + lh = float(ds.lineHeight) + except: + try: + lh = 1.2 * float(ds.fontSize) + except: + lh = 15 + ans = line_height.ans = max(5, lh) + return ans + + +def scroll_to_node(node, sync_context): if node is document.body: window.scrollTo(0, 0) else: node.scrollIntoView() + if sync_context: + window.scrollBy(0, -sync_context * line_height()) state = {'blocks_found': False, 'in_split_mode': False} -def go_to_line(lnum): +def go_to_line(lnum, sync_context): for node in document.querySelectorAll(f'[data-lnum="{lnum}"]'): if is_hidden(node): continue - scroll_to_node(node) + scroll_to_node(node, sync_context) break @from_python -def go_to_sourceline_address(sourceline, tags): +def go_to_sourceline_address(sourceline, tags, sync_context): nodes = document.querySelectorAll(f'[data-lnum="{sourceline}"]') for index in range(nodes.length): node = nodes[index] if index >= tags.length or node.tagName.toLowerCase() is not tags[index]: break if index == tags.length - 1 and not is_hidden(node): - return scroll_to_node(node) - go_to_line(sourceline) + return scroll_to_node(node, sync_context) + go_to_line(sourceline, sync_context) def line_numbers(): found_body = False