mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Viewer: Allow using search expressions for --open-at
This commit is contained in:
parent
2843ec81e1
commit
30fe553c28
@ -131,7 +131,10 @@ View an e-book.
|
||||
'the string "something". The form toc-href:something will match the '
|
||||
'href (internal link destination) of toc nodes. The matching is exact. '
|
||||
'If you want to match a substring, use the form toc-href-contains:something. '
|
||||
'The form ref:something will use Reference mode references.'))
|
||||
'The form ref:something will use Reference mode references. The form search:something will'
|
||||
' search for something after opening the book. The form regex:something will search'
|
||||
' for the regular expression something after opening the book.'
|
||||
))
|
||||
a('--continue', default=False, action='store_true', dest='continue_reading',
|
||||
help=_('Continue reading the last opened book'))
|
||||
|
||||
@ -197,7 +200,7 @@ def main(args=sys.argv):
|
||||
oat = opts.open_at
|
||||
if oat and not (
|
||||
oat.startswith('toc:') or oat.startswith('toc-href:') or oat.startswith('toc-href-contains:') or
|
||||
oat.startswith('epubcfi(/') or is_float(oat) or oat.startswith('ref:')):
|
||||
oat.startswith('epubcfi(/') or is_float(oat) or oat.startswith('ref:') or oat.startswith('search:') or oat.startswith('regex:')):
|
||||
raise SystemExit(f'Not a valid --open-at value: {opts.open_at}')
|
||||
|
||||
if get_session_pref('singleinstance', False):
|
||||
|
@ -319,9 +319,10 @@ def search_in_name(name, search_query, ctx_size=75):
|
||||
yield match.span()
|
||||
else:
|
||||
spans = []
|
||||
a = lambda s, l: spans.append((s, s + l))
|
||||
primary_collator_without_punctuation().find_all(search_query.text, raw, a, search_query.mode == 'word')
|
||||
miter = lambda: spans
|
||||
if raw:
|
||||
a = lambda s, l: spans.append((s, s + l))
|
||||
primary_collator_without_punctuation().find_all(search_query.text, raw, a, search_query.mode == 'word')
|
||||
|
||||
for (start, end) in miter():
|
||||
before = raw[max(0, start-ctx_size):start]
|
||||
@ -454,9 +455,16 @@ class SearchInput(QWidget): # {{{
|
||||
def find_previous(self):
|
||||
self.emit_search(backwards=True)
|
||||
|
||||
def focus_input(self, text=None):
|
||||
def focus_input(self, text=None, search_type=None, case_sensitive=None):
|
||||
if text and hasattr(text, 'rstrip'):
|
||||
self.search_box.setText(text)
|
||||
if search_type is not None:
|
||||
idx = self.query_type.findData(search_type)
|
||||
if idx < 0:
|
||||
idx = self.query_type.findData('normal')
|
||||
self.query_type.setCurrentIndex(idx)
|
||||
if case_sensitive is not None:
|
||||
self.case_sensitive.setChecked(bool(case_sensitive))
|
||||
self.search_box.setFocus(Qt.FocusReason.OtherFocusReason)
|
||||
le = self.search_box.lineEdit()
|
||||
le.end(False)
|
||||
@ -668,8 +676,8 @@ class SearchPanel(QWidget): # {{{
|
||||
def update_hidden_message(self):
|
||||
self.hidden_message.setVisible(self.results.current_result_is_hidden)
|
||||
|
||||
def focus_input(self, text=None):
|
||||
self.search_input.focus_input(text)
|
||||
def focus_input(self, text=None, search_type=None, case_sensitive=None):
|
||||
self.search_input.focus_input(text, search_type, case_sensitive)
|
||||
|
||||
def search_cleared(self):
|
||||
self.results.clear_all_results()
|
||||
|
@ -99,6 +99,7 @@ class EbookViewer(MainWindow):
|
||||
t.setSingleShot(True), t.setInterval(3000), t.setTimerType(Qt.TimerType.VeryCoarseTimer)
|
||||
connect_lambda(t.timeout, self, lambda self: self.save_annotations(in_book_file=False))
|
||||
self.pending_open_at = open_at
|
||||
self.pending_search = None
|
||||
self.base_window_title = _('E-book viewer')
|
||||
self.setDockOptions(QMainWindow.DockOption.AnimatedDocks | QMainWindow.DockOption.AllowTabbedDocks | QMainWindow.DockOption.AllowNestedDocks)
|
||||
self.setWindowTitle(self.base_window_title)
|
||||
@ -195,6 +196,7 @@ class EbookViewer(MainWindow):
|
||||
self.web_view.highlights_changed.connect(self.highlights_changed)
|
||||
self.web_view.update_reading_rates.connect(self.update_reading_rates)
|
||||
self.web_view.edit_book.connect(self.edit_book)
|
||||
self.web_view.content_file_changed.connect(self.content_file_changed)
|
||||
self.actions_toolbar.initialize(self.web_view, self.search_dock.toggleViewAction())
|
||||
at.update_action_state(False)
|
||||
self.setCentralWidget(self.web_view)
|
||||
@ -310,11 +312,11 @@ class EbookViewer(MainWindow):
|
||||
if not is_visible:
|
||||
self.toc.scroll_to_current_toc_node()
|
||||
|
||||
def show_search(self, text, trigger=False):
|
||||
def show_search(self, text, trigger=False, search_type=None, case_sensitive=None):
|
||||
self.search_dock.setVisible(True)
|
||||
self.search_dock.activateWindow()
|
||||
self.search_dock.raise_()
|
||||
self.search_widget.focus_input(text)
|
||||
self.search_widget.focus_input(text, search_type, case_sensitive)
|
||||
if trigger:
|
||||
self.search_widget.trigger()
|
||||
|
||||
@ -425,6 +427,11 @@ class EbookViewer(MainWindow):
|
||||
self.loading_overlay.hide()
|
||||
self.actions_toolbar.update_action_state(True)
|
||||
|
||||
def content_file_changed(self, fname):
|
||||
if self.pending_search:
|
||||
search, self.pending_search = self.pending_search, None
|
||||
self.show_search(text=search['query'], trigger=True, search_type=search['type'], case_sensitive=search['case_sensitive'])
|
||||
|
||||
def show_error(self, title, msg, details):
|
||||
self.loading_overlay.hide()
|
||||
error_dialog(self, title, msg, det_msg=details or None, show=True)
|
||||
@ -526,6 +533,7 @@ class EbookViewer(MainWindow):
|
||||
if self.shutting_down:
|
||||
return
|
||||
open_at, self.pending_open_at = self.pending_open_at, None
|
||||
self.pending_search = None
|
||||
self.web_view.clear_caches()
|
||||
if not ok:
|
||||
self.actions_toolbar.update_action_state(False)
|
||||
@ -577,6 +585,12 @@ class EbookViewer(MainWindow):
|
||||
initial_position = {'type': 'cfi', 'data': open_at}
|
||||
elif open_at.startswith('ref:'):
|
||||
initial_position = {'type': 'ref', 'data': open_at[len('ref:'):]}
|
||||
elif open_at.startswith('search:'):
|
||||
self.pending_search = {'type': 'normal', 'query': open_at[len('search:'):], 'case_sensitive': False}
|
||||
initial_position = {'type': 'bookpos', 'data': 0}
|
||||
elif open_at.startswith('regex:'):
|
||||
self.pending_search = {'type': 'regex', 'query': open_at[len('regex:'):], 'case_sensitive': True}
|
||||
initial_position = {'type': 'bookpos', 'data': 0}
|
||||
elif is_float(open_at):
|
||||
initial_position = {'type': 'bookpos', 'data': float(open_at)}
|
||||
highlights = self.current_book_data['annotations_map']['highlight']
|
||||
|
@ -462,6 +462,7 @@ class WebView(RestartingWebEngineView):
|
||||
paged_mode_changed = pyqtSignal()
|
||||
standalone_misc_settings_changed = pyqtSignal(object)
|
||||
view_created = pyqtSignal(object)
|
||||
content_file_changed = pyqtSignal(str)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
self._host_widget = None
|
||||
@ -623,6 +624,7 @@ class WebView(RestartingWebEngineView):
|
||||
|
||||
def on_content_file_changed(self, data):
|
||||
self.current_content_file = data
|
||||
self.content_file_changed.emit(self.current_content_file)
|
||||
|
||||
def start_book_load(self, initial_position=None, highlights=None, current_book_data=None, reading_rates=None):
|
||||
key = (set_book_path.path,)
|
||||
|
Loading…
x
Reference in New Issue
Block a user