mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Restore reference mode from the 3.x viewer
This commit is contained in:
parent
d6262bbb90
commit
e1d9a25f81
@ -29,6 +29,7 @@ from read_book.paged_mode import (
|
|||||||
scroll_by_page as paged_scroll_by_page, scroll_to_elem,
|
scroll_by_page as paged_scroll_by_page, scroll_to_elem,
|
||||||
scroll_to_fraction as paged_scroll_to_fraction, snap_to_selection
|
scroll_to_fraction as paged_scroll_to_fraction, snap_to_selection
|
||||||
)
|
)
|
||||||
|
from read_book.referencing import end_reference_mode, start_reference_mode
|
||||||
from read_book.resources import finalize_resources, unserialize_html
|
from read_book.resources import finalize_resources, unserialize_html
|
||||||
from read_book.settings import (
|
from read_book.settings import (
|
||||||
apply_colors, apply_font_size, apply_settings, apply_stylesheet, opts,
|
apply_colors, apply_font_size, apply_settings, apply_stylesheet, opts,
|
||||||
@ -80,6 +81,7 @@ class IframeBoss:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
window.navigator.epubReadingSystem = EPUBReadingSystem()
|
window.navigator.epubReadingSystem = EPUBReadingSystem()
|
||||||
self.last_cfi = None
|
self.last_cfi = None
|
||||||
|
self.reference_mode_enabled = False
|
||||||
self.replace_history_on_next_cfi_update = True
|
self.replace_history_on_next_cfi_update = True
|
||||||
self.blob_url_map = {}
|
self.blob_url_map = {}
|
||||||
self.content_ready = False
|
self.content_ready = False
|
||||||
@ -100,6 +102,7 @@ class IframeBoss:
|
|||||||
'window_size': self.received_window_size,
|
'window_size': self.received_window_size,
|
||||||
'get_current_cfi': self.get_current_cfi,
|
'get_current_cfi': self.get_current_cfi,
|
||||||
'set_forward_keypresses': self.set_forward_keypresses,
|
'set_forward_keypresses': self.set_forward_keypresses,
|
||||||
|
'set_reference_mode': self.set_reference_mode,
|
||||||
}
|
}
|
||||||
self.comm = IframeClient(handlers)
|
self.comm = IframeClient(handlers)
|
||||||
self.last_window_ypos = 0
|
self.last_window_ypos = 0
|
||||||
@ -155,6 +158,7 @@ class IframeBoss:
|
|||||||
self.content_ready = False
|
self.content_ready = False
|
||||||
self.replace_history_on_next_cfi_update = True
|
self.replace_history_on_next_cfi_update = True
|
||||||
self.book = current_book.book = data.book
|
self.book = current_book.book = data.book
|
||||||
|
self.reference_mode_enabled = data.reference_mode_enabled
|
||||||
self.is_titlepage = data.is_titlepage
|
self.is_titlepage = data.is_titlepage
|
||||||
spine = self.book.manifest.spine
|
spine = self.book.manifest.spine
|
||||||
index = spine.indexOf(data.name)
|
index = spine.indexOf(data.name)
|
||||||
@ -178,7 +182,13 @@ class IframeBoss:
|
|||||||
self.anchor_funcs = paged_anchor_funcs
|
self.anchor_funcs = paged_anchor_funcs
|
||||||
update_settings(data.settings)
|
update_settings(data.settings)
|
||||||
self.keyboard_shortcut_map = create_shortcut_map(data.settings.keyboard_shortcuts)
|
self.keyboard_shortcut_map = create_shortcut_map(data.settings.keyboard_shortcuts)
|
||||||
set_current_spine_item({'name':data.name, 'is_first':index is 0, 'is_last':index is spine.length - 1, 'initial_position':data.initial_position})
|
set_current_spine_item({
|
||||||
|
'name':data.name,
|
||||||
|
'is_first':index is 0,
|
||||||
|
'is_last':index is spine.length - 1,
|
||||||
|
'index': index,
|
||||||
|
'initial_position':data.initial_position
|
||||||
|
})
|
||||||
self.last_cfi = None
|
self.last_cfi = None
|
||||||
for name in self.blob_url_map:
|
for name in self.blob_url_map:
|
||||||
window.URL.revokeObjectURL(self.blob_url_map[name])
|
window.URL.revokeObjectURL(self.blob_url_map[name])
|
||||||
@ -239,6 +249,8 @@ class IframeBoss:
|
|||||||
if self.is_titlepage and not opts.cover_preserve_aspect_ratio:
|
if self.is_titlepage and not opts.cover_preserve_aspect_ratio:
|
||||||
document.body.classList.add('cover-fill')
|
document.body.classList.add('cover-fill')
|
||||||
document.body.classList.add(f'calibre-viewer-{layout_style()}')
|
document.body.classList.add(f'calibre-viewer-{layout_style()}')
|
||||||
|
if self.reference_mode_enabled:
|
||||||
|
start_reference_mode()
|
||||||
self.last_window_width, self.last_window_height = scroll_viewport.width(), scroll_viewport.height()
|
self.last_window_width, self.last_window_height = scroll_viewport.width(), scroll_viewport.height()
|
||||||
apply_settings()
|
apply_settings()
|
||||||
fix_fullscreen_svg_images()
|
fix_fullscreen_svg_images()
|
||||||
@ -269,8 +281,7 @@ class IframeBoss:
|
|||||||
self.find(ipos.search_data, True)
|
self.find(ipos.search_data, True)
|
||||||
spine = self.book.manifest.spine
|
spine = self.book.manifest.spine
|
||||||
files = self.book.manifest.files
|
files = self.book.manifest.files
|
||||||
current_name = current_spine_item().name
|
spine_index = csi.index
|
||||||
spine_index = spine.indexOf(current_name)
|
|
||||||
self.length_before = 0
|
self.length_before = 0
|
||||||
if spine_index > -1:
|
if spine_index > -1:
|
||||||
for i in range(spine_index):
|
for i in range(spine_index):
|
||||||
@ -297,9 +308,7 @@ class IframeBoss:
|
|||||||
cfi = current_cfi()
|
cfi = current_cfi()
|
||||||
selected_text = window.getSelection().toString()
|
selected_text = window.getSelection().toString()
|
||||||
if cfi:
|
if cfi:
|
||||||
spine = self.book.manifest.spine
|
index = current_spine_item().index
|
||||||
current_name = current_spine_item().name
|
|
||||||
index = spine.indexOf(current_name)
|
|
||||||
if index > -1:
|
if index > -1:
|
||||||
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
||||||
self.send_message(
|
self.send_message(
|
||||||
@ -312,9 +321,7 @@ class IframeBoss:
|
|||||||
def update_cfi(self):
|
def update_cfi(self):
|
||||||
cfi = current_cfi()
|
cfi = current_cfi()
|
||||||
if cfi:
|
if cfi:
|
||||||
spine = self.book.manifest.spine
|
index = current_spine_item().index
|
||||||
current_name = current_spine_item().name
|
|
||||||
index = spine.indexOf(current_name)
|
|
||||||
if index > -1:
|
if index > -1:
|
||||||
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
cfi = 'epubcfi(/{}{})'.format(2*(index+1), cfi)
|
||||||
pf = self.calculate_progress_frac()
|
pf = self.calculate_progress_frac()
|
||||||
@ -472,6 +479,16 @@ class IframeBoss:
|
|||||||
else:
|
else:
|
||||||
self.send_message('find_in_spine', text=data.text, backwards=data.backwards, searched_in_spine=data.searched_in_spine)
|
self.send_message('find_in_spine', text=data.text, backwards=data.backwards, searched_in_spine=data.searched_in_spine)
|
||||||
|
|
||||||
|
def reference_item_changed(self, ref_num_or_none):
|
||||||
|
self.send_message('reference_item_changed', refnum=ref_num_or_none, index=current_spine_item().index)
|
||||||
|
|
||||||
|
def set_reference_mode(self, data):
|
||||||
|
self.reference_mode_enabled = data.enabled
|
||||||
|
if data.enabled:
|
||||||
|
start_reference_mode()
|
||||||
|
else:
|
||||||
|
end_reference_mode()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
main.boss = IframeBoss()
|
main.boss = IframeBoss()
|
||||||
|
35
src/pyj/read_book/referencing.pyj
Normal file
35
src/pyj/read_book/referencing.pyj
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
# noqa: eol-semicolon
|
||||||
|
from __python__ import bound_methods, hash_literals
|
||||||
|
|
||||||
|
from read_book.globals import get_boss
|
||||||
|
|
||||||
|
|
||||||
|
def on_mouse_over(ev):
|
||||||
|
p = this
|
||||||
|
if p.dataset.calibreRefNum:
|
||||||
|
refnum = int(p.dataset.calibreRefNum)
|
||||||
|
get_boss().reference_item_changed(refnum)
|
||||||
|
|
||||||
|
|
||||||
|
def on_mouse_out(ev):
|
||||||
|
get_boss().reference_item_changed(None)
|
||||||
|
|
||||||
|
|
||||||
|
def start_reference_mode():
|
||||||
|
i = 0
|
||||||
|
for p in document.getElementsByTagName('p'):
|
||||||
|
i += 1
|
||||||
|
if not p.dataset.calibreRefNum:
|
||||||
|
p.dataset.calibreRefNum = i + ''
|
||||||
|
p.addEventListener('mouseover', on_mouse_over, {'passive': True})
|
||||||
|
p.addEventListener('mouseout', on_mouse_out, {'passive': True})
|
||||||
|
|
||||||
|
|
||||||
|
def end_reference_mode():
|
||||||
|
for p in document.getElementsByTagName('p'):
|
||||||
|
if p.dataset.calibreRefNum:
|
||||||
|
p.removeEventListener('mouseover', on_mouse_over, {'passive': True})
|
||||||
|
p.removeEventListener('mouseout', on_mouse_out, {'passive': True})
|
||||||
|
v'delete p.dataset.calibreRefNum'
|
@ -228,6 +228,12 @@ def shortcuts_definition():
|
|||||||
_('Toggle between Paged mode and Flow mode for text layout')
|
_('Toggle between Paged mode and Flow mode for text layout')
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'toggle_reference_mode': desc(
|
||||||
|
'Ctrl+x',
|
||||||
|
'ui',
|
||||||
|
_('Toggle the Reference mode')
|
||||||
|
),
|
||||||
|
|
||||||
'reload_book': desc(
|
'reload_book': desc(
|
||||||
v"['F5', 'Ctrl+r']",
|
v"['F5', 'Ctrl+r']",
|
||||||
'ui',
|
'ui',
|
||||||
|
@ -147,6 +147,7 @@ class View:
|
|||||||
|
|
||||||
def __init__(self, container):
|
def __init__(self, container):
|
||||||
self.timers = Timers()
|
self.timers = Timers()
|
||||||
|
self.reference_mode_enabled = False
|
||||||
self.loaded_resources = {}
|
self.loaded_resources = {}
|
||||||
self.current_progress_frac = self.current_file_progress_frac = 0
|
self.current_progress_frac = self.current_file_progress_frac = 0
|
||||||
self.current_toc_node = self.current_toc_toplevel_node = None
|
self.current_toc_node = self.current_toc_toplevel_node = None
|
||||||
@ -190,8 +191,13 @@ class View:
|
|||||||
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; overflow: auto; display:none', id='book-overlay'), # main overlay
|
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; overflow: auto; display:none', id='book-overlay'), # main overlay
|
||||||
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='controls-help-overlay'), # controls help overlay
|
E.div(style='position: absolute; top:0; left:0; width: 100%; height: 100%; display:none', id='controls-help-overlay'), # controls help overlay
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
)
|
E.div(
|
||||||
|
style=f'color: {get_color("window-foreground")}; background: {get_color("window-background")};' +
|
||||||
|
'position: absolute; display: none; left: 0; top: 0; padding: 0.5ex; border: solid 2px; z-index: 3000',
|
||||||
|
id='reference-mode-overlay'
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
handlers = {
|
handlers = {
|
||||||
'ready': self.on_iframe_ready,
|
'ready': self.on_iframe_ready,
|
||||||
@ -216,6 +222,7 @@ class View:
|
|||||||
'selectionchange': self.on_selection_change,
|
'selectionchange': self.on_selection_change,
|
||||||
'handle_shortcut': self.on_handle_shortcut,
|
'handle_shortcut': self.on_handle_shortcut,
|
||||||
'handle_keypress': self.on_handle_keypress,
|
'handle_keypress': self.on_handle_keypress,
|
||||||
|
'reference_item_changed': self.on_reference_item_changed,
|
||||||
}
|
}
|
||||||
entry_point = None if runtime.is_standalone_viewer else 'read_book.iframe'
|
entry_point = None if runtime.is_standalone_viewer else 'read_book.iframe'
|
||||||
if runtime.is_standalone_viewer:
|
if runtime.is_standalone_viewer:
|
||||||
@ -236,6 +243,10 @@ class View:
|
|||||||
def iframe(self):
|
def iframe(self):
|
||||||
return self.iframe_wrapper.iframe
|
return self.iframe_wrapper.iframe
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reference_mode_overlay(self):
|
||||||
|
return document.getElementById('reference-mode-overlay')
|
||||||
|
|
||||||
def on_lookup_word(self, data):
|
def on_lookup_word(self, data):
|
||||||
if runtime.is_standalone_viewer:
|
if runtime.is_standalone_viewer:
|
||||||
ui_operations.selection_changed(data.word)
|
ui_operations.selection_changed(data.word)
|
||||||
@ -366,6 +377,8 @@ class View:
|
|||||||
self.bump_font_size({'increase': False})
|
self.bump_font_size({'increase': False})
|
||||||
elif data.name is 'toggle_full_screen':
|
elif data.name is 'toggle_full_screen':
|
||||||
ui_operations.toggle_full_screen()
|
ui_operations.toggle_full_screen()
|
||||||
|
elif data.name is 'toggle_reference_mode':
|
||||||
|
self.toggle_reference_mode()
|
||||||
elif data.name is 'reload_book':
|
elif data.name is 'reload_book':
|
||||||
ui_operations.reload_book()
|
ui_operations.reload_book()
|
||||||
elif data.name is 'search_for_selection':
|
elif data.name is 'search_for_selection':
|
||||||
@ -456,6 +469,7 @@ class View:
|
|||||||
self.overlay.hide()
|
self.overlay.hide()
|
||||||
self.search_overlay.hide()
|
self.search_overlay.hide()
|
||||||
self.content_popup_overlay.hide()
|
self.content_popup_overlay.hide()
|
||||||
|
self.reference_mode_overlay.style.display = 'none'
|
||||||
self.focus_iframe()
|
self.focus_iframe()
|
||||||
|
|
||||||
def focus_iframe(self):
|
def focus_iframe(self):
|
||||||
@ -932,7 +946,7 @@ class View:
|
|||||||
self.iframe_wrapper.send_unencrypted_message('display',
|
self.iframe_wrapper.send_unencrypted_message('display',
|
||||||
resource_data=resource_data, book=self.book, name=self.currently_showing.name,
|
resource_data=resource_data, book=self.book, name=self.currently_showing.name,
|
||||||
initial_position=self.currently_showing.initial_position,
|
initial_position=self.currently_showing.initial_position,
|
||||||
settings=self.currently_showing.settings,
|
settings=self.currently_showing.settings, reference_mode_enabled=self.reference_mode_enabled,
|
||||||
is_titlepage=self.currently_showing.name is self.book.manifest.title_page_name,
|
is_titlepage=self.currently_showing.name is self.book.manifest.title_page_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -941,6 +955,7 @@ class View:
|
|||||||
self.hide_loading()
|
self.hide_loading()
|
||||||
self.set_progress_frac(data.progress_frac, data.file_progress_frac)
|
self.set_progress_frac(data.progress_frac, data.file_progress_frac)
|
||||||
self.update_header_footer()
|
self.update_header_footer()
|
||||||
|
self.on_reference_item_changed()
|
||||||
window.scrollTo(0, 0) # ensure window is at 0 on mobile where the navbar causes issues
|
window.scrollTo(0, 0) # ensure window is at 0 on mobile where the navbar causes issues
|
||||||
if self.book_load_started:
|
if self.book_load_started:
|
||||||
self.book_load_started = False
|
self.book_load_started = False
|
||||||
@ -958,3 +973,17 @@ class View:
|
|||||||
def update_color_scheme(self):
|
def update_color_scheme(self):
|
||||||
cs = self.get_color_scheme(True)
|
cs = self.get_color_scheme(True)
|
||||||
self.iframe_wrapper.send_message('change_color_scheme', color_scheme=cs)
|
self.iframe_wrapper.send_message('change_color_scheme', color_scheme=cs)
|
||||||
|
|
||||||
|
def toggle_reference_mode(self):
|
||||||
|
self.reference_mode_enabled = not self.reference_mode_enabled
|
||||||
|
self.iframe_wrapper.send_message('set_reference_mode', enabled=self.reference_mode_enabled)
|
||||||
|
|
||||||
|
def on_reference_item_changed(self, data):
|
||||||
|
data = data or {'refnum': None, 'index': None}
|
||||||
|
refnum, index = data.refnum, data.index
|
||||||
|
div = self.reference_mode_overlay
|
||||||
|
if refnum is None:
|
||||||
|
div.style.display = 'none'
|
||||||
|
else:
|
||||||
|
div.style.display = 'block'
|
||||||
|
div.textContent = f'{index}.{refnum}'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user