mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 02:34:06 -04:00
CS FTS: Implement opening viewer to search result
This commit is contained in:
parent
ad6252ac41
commit
d63f0ff0d1
@ -11,7 +11,7 @@ from book_list.router import back, push_state, open_book_url
|
|||||||
from book_list.top_bar import create_top_bar
|
from book_list.top_bar import create_top_bar
|
||||||
from book_list.ui import set_panel_handler
|
from book_list.ui import set_panel_handler
|
||||||
from book_list.views import create_image
|
from book_list.views import create_image
|
||||||
from book_list.library_data import current_library_id
|
from book_list.library_data import current_library_id, download_url
|
||||||
from complete import create_search_bar
|
from complete import create_search_bar
|
||||||
from dom import add_extra_css, clear, set_css
|
from dom import add_extra_css, clear, set_css
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
@ -184,9 +184,12 @@ def open_format(book_id, fmt):
|
|||||||
text = s.text
|
text = s.text
|
||||||
break
|
break
|
||||||
url = open_book_url(book_id, fmt)
|
url = open_book_url(book_id, fmt)
|
||||||
window.open(url, '_blank')
|
if fmt is 'PDF':
|
||||||
|
url = download_url(book_id, fmt, 'inline')
|
||||||
|
w = window.open(url, '_blank')
|
||||||
if text:
|
if text:
|
||||||
pass
|
text = str.strip(text, '…').replaceAll('\x1c', '').replaceAll('\x1e', '')
|
||||||
|
w.read_book_initial_open_search_text = {'text': text, 'query': current_fts_query.query}
|
||||||
|
|
||||||
|
|
||||||
def book_result_tile_clicked(ev):
|
def book_result_tile_clicked(ev):
|
||||||
|
@ -20,6 +20,21 @@ from widgets import create_button, create_spinner
|
|||||||
from worker import start_worker
|
from worker import start_worker
|
||||||
|
|
||||||
|
|
||||||
|
def parse_error_msg(msg):
|
||||||
|
details = msg.msg
|
||||||
|
emsg = _('Unknown error')
|
||||||
|
if msg.code is GET_SPINE_FAILED:
|
||||||
|
emsg = _('Loading text from the book failed.')
|
||||||
|
elif msg.code is CONNECT_FAILED:
|
||||||
|
emsg = _('Connecting to database storing the local copy of the book failed in the worker thread.')
|
||||||
|
elif msg.code is UNHANDLED_ERROR:
|
||||||
|
emsg = _('There was an unhandled error while searching.')
|
||||||
|
elif msg.code is DB_ERROR:
|
||||||
|
emsg = msg.error.msg
|
||||||
|
details = msg.error.details
|
||||||
|
return emsg, details
|
||||||
|
|
||||||
|
|
||||||
def get_toc_data(book):
|
def get_toc_data(book):
|
||||||
spine = book.manifest.spine
|
spine = book.manifest.spine
|
||||||
spine_toc_map = {name: v'[]' for name in spine}
|
spine_toc_map = {name: v'[]' for name in spine}
|
||||||
@ -68,6 +83,7 @@ class SearchOverlay:
|
|||||||
c.style.userSelect = 'none'
|
c.style.userSelect = 'none'
|
||||||
c.addEventListener('keydown', self.onkeydown)
|
c.addEventListener('keydown', self.onkeydown)
|
||||||
c.addEventListener('keyup', self.onkeyup)
|
c.addEventListener('keyup', self.onkeyup)
|
||||||
|
self.result_handler = None
|
||||||
|
|
||||||
create_top_bar(c, title=_('Search in book'), action=self.hide, icon='close')
|
create_top_bar(c, title=_('Search in book'), action=self.hide, icon='close')
|
||||||
|
|
||||||
@ -176,6 +192,37 @@ class SearchOverlay:
|
|||||||
self.clear_caches()
|
self.clear_caches()
|
||||||
return self._worker
|
return self._worker
|
||||||
|
|
||||||
|
def do_initial_search(self, text, query):
|
||||||
|
q = {'mode': 'contains', 'case_sensitive': True, 'text': text, 'only_first_match': True}
|
||||||
|
self.request_counter += 1
|
||||||
|
self.initial_search_result_counter = 0
|
||||||
|
self.initial_search_human_readable_query = query
|
||||||
|
self.search_in_flight.id = self.request_counter
|
||||||
|
self.result_handler = self.handle_initial_search_result
|
||||||
|
self.worker.postMessage({
|
||||||
|
'type': 'search', 'current_name': '', 'id': self.request_counter, 'query': q
|
||||||
|
})
|
||||||
|
|
||||||
|
def handle_initial_search_result(self, msg):
|
||||||
|
if msg.type is 'error':
|
||||||
|
emsg, details = parse_error_msg(msg)
|
||||||
|
error_dialog(_('Could not search'), emsg, details)
|
||||||
|
self.result_handler = None
|
||||||
|
self.initial_search_result_counter = 0
|
||||||
|
elif msg.id is self.search_in_flight.id:
|
||||||
|
if msg.type is 'search_complete':
|
||||||
|
self.search_in_flight.id = None
|
||||||
|
self.result_handler = None
|
||||||
|
if self.initial_search_result_counter is 0:
|
||||||
|
self.view.hide_loading()
|
||||||
|
window.alert(_('The full text search query {} was not found in the book, try a manual search.').format(self.initial_search_human_readable_query))
|
||||||
|
self.initial_search_result_counter = 0
|
||||||
|
elif msg.type is 'search_result':
|
||||||
|
self.initial_search_result_counter += 1
|
||||||
|
if self.initial_search_result_counter is 1:
|
||||||
|
self.view.discover_search_result(msg.result)
|
||||||
|
self.view.hide_loading()
|
||||||
|
|
||||||
def queue_search(self, query, book, current_name):
|
def queue_search(self, query, book, current_name):
|
||||||
self.request_counter += 1
|
self.request_counter += 1
|
||||||
self.original_position = self.view.currently_showing.bookpos
|
self.original_position = self.view.currently_showing.bookpos
|
||||||
@ -197,18 +244,10 @@ class SearchOverlay:
|
|||||||
|
|
||||||
def on_worker_message(self, evt):
|
def on_worker_message(self, evt):
|
||||||
msg = evt.data
|
msg = evt.data
|
||||||
|
if self.result_handler:
|
||||||
|
return self.result_handler(msg)
|
||||||
if msg.type is 'error':
|
if msg.type is 'error':
|
||||||
details = msg.msg
|
emsg, details = parse_error_msg(msg)
|
||||||
emsg = _('Unknown error')
|
|
||||||
if msg.code is GET_SPINE_FAILED:
|
|
||||||
emsg = _('Loading text from the book failed.')
|
|
||||||
elif msg.code is CONNECT_FAILED:
|
|
||||||
emsg = _('Connecting to database storing the local copy of the book failed in the worker thread.')
|
|
||||||
elif msg.code is UNHANDLED_ERROR:
|
|
||||||
emsg = _('There was an unhandled error while searching.')
|
|
||||||
elif msg.code is DB_ERROR:
|
|
||||||
emsg = msg.error.msg
|
|
||||||
details = msg.error.details
|
|
||||||
error_dialog(_('Could not search'), emsg, details)
|
error_dialog(_('Could not search'), emsg, details)
|
||||||
elif msg.id is self.search_in_flight.id:
|
elif msg.id is self.search_in_flight.id:
|
||||||
if msg.type is 'search_complete':
|
if msg.type is 'search_complete':
|
||||||
@ -273,11 +312,6 @@ class SearchOverlay:
|
|||||||
entry.appendChild(E.span(result.after + '…'))
|
entry.appendChild(E.span(result.after + '…'))
|
||||||
ul.appendChild(entry)
|
ul.appendChild(entry)
|
||||||
|
|
||||||
def make_query_programmatically(self, text, mode, case_sensitive):
|
|
||||||
self.current_query = {'text': text, 'mode': mode, 'case_sensitive': case_sensitive}
|
|
||||||
self.show()
|
|
||||||
self.run_search()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_result_container(self):
|
def current_result_container(self):
|
||||||
return self.container.querySelector('.current')
|
return self.container.querySelector('.current')
|
||||||
|
@ -178,11 +178,16 @@ def search_in_text_of(name):
|
|||||||
}
|
}
|
||||||
result.toc_nodes = toc_nodes_for_search_result(result)
|
result.toc_nodes = toc_nodes_for_search_result(result)
|
||||||
self.postMessage({'type': 'search_result', 'id': wc.current_query_id, 'result': result})
|
self.postMessage({'type': 'search_result', 'id': wc.current_query_id, 'result': result})
|
||||||
|
if wc.current_query.query.only_first_match:
|
||||||
|
break
|
||||||
match_counts[q] += 1
|
match_counts[q] += 1
|
||||||
|
|
||||||
|
|
||||||
def queue_next_spine_item(spine_idx, allow_current_name):
|
def queue_next_spine_item(spine_idx, allow_current_name):
|
||||||
name = wc.current_book.spine[spine_idx]
|
name = wc.current_book.spine[spine_idx]
|
||||||
|
if wc.current_query.query.only_first_match and wc.result_num > 0:
|
||||||
|
send_search_complete()
|
||||||
|
return
|
||||||
if not name or (not allow_current_name and name is wc.current_query.current_name):
|
if not name or (not allow_current_name and name is wc.current_query.current_name):
|
||||||
send_search_complete()
|
send_search_complete()
|
||||||
return
|
return
|
||||||
|
@ -856,6 +856,12 @@ class View:
|
|||||||
self.show_loading_callback_timer = setTimeout(self.show_loading_message.bind(None, msg), 200)
|
self.show_loading_callback_timer = setTimeout(self.show_loading_message.bind(None, msg), 200)
|
||||||
|
|
||||||
def hide_loading(self):
|
def hide_loading(self):
|
||||||
|
if window.read_book_initial_open_search_text:
|
||||||
|
q = window.read_book_initial_open_search_text
|
||||||
|
v'delete window.read_book_initial_open_search_text'
|
||||||
|
self.search_overlay.do_initial_search(q.text, q.query)
|
||||||
|
self.show_loading_message(_('Searching for: {}').format(q.query))
|
||||||
|
return
|
||||||
if self.show_loading_callback_timer is not None:
|
if self.show_loading_callback_timer is not None:
|
||||||
clearTimeout(self.show_loading_callback_timer)
|
clearTimeout(self.show_loading_callback_timer)
|
||||||
self.show_loading_callback_timer = None
|
self.show_loading_callback_timer = None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user