mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -04:00
Start work on simple read aloud button for selection popup bar
This commit is contained in:
parent
6f34100ca7
commit
24b2e5f07f
1
imgsrc/srv/bullhorn.svg
Normal file
1
imgsrc/srv/bullhorn.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1664 640q53 0 90.5 37.5t37.5 90.5-37.5 90.5-90.5 37.5v384q0 52-38 90t-90 38q-417-347-812-380-58 19-91 66t-31 100.5 40 92.5q-20 33-23 65.5t6 58 33.5 55 48 50 61.5 50.5q-29 58-111.5 83t-168.5 11.5-132-55.5q-7-23-29.5-87.5t-32-94.5-23-89-15-101 3.5-98.5 22-110.5h-122q-66 0-113-47t-47-113v-192q0-66 47-113t113-47h480q435 0 896-384 52 0 90 38t38 90v384zm-128 604v-954q-394 302-768 343v270q377 42 768 341z"/></svg>
|
After Width: | Height: | Size: 510 B |
10
src/calibre/gui2/tts/errors.py
Normal file
10
src/calibre/gui2/tts/errors.py
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
class TTSSystemUnavailable(Exception):
|
||||
def __init__(self, message, details):
|
||||
Exception.__init__(self, message)
|
||||
self.short_msg = message
|
||||
self.details = details
|
14
src/calibre/gui2/tts/implementation.py
Normal file
14
src/calibre/gui2/tts/implementation.py
Normal file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from calibre.constants import iswindows, ismacos
|
||||
|
||||
if iswindows:
|
||||
pass
|
||||
elif ismacos:
|
||||
pass
|
||||
else:
|
||||
from .linux import speak_simple_text
|
||||
|
||||
speak_simple_text
|
30
src/calibre/gui2/tts/linux.py
Normal file
30
src/calibre/gui2/tts/linux.py
Normal file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import atexit
|
||||
from .errors import TTSSystemUnavailable
|
||||
|
||||
|
||||
def get_client():
|
||||
client = getattr(get_client, 'ans', None)
|
||||
if client is not None:
|
||||
return client
|
||||
from speechd.client import SSIPClient, SpawnError
|
||||
try:
|
||||
client = get_client.ans = SSIPClient('calibre')
|
||||
except SpawnError as err:
|
||||
raise TTSSystemUnavailable(_('Could not find speech-dispatcher on your system. Please install it.'), str(err))
|
||||
atexit.register(client.close)
|
||||
return client
|
||||
|
||||
|
||||
def speak_simple_text(text):
|
||||
client = get_client()
|
||||
from speechd.client import SSIPCommunicationError
|
||||
try:
|
||||
client.speak(text)
|
||||
except SSIPCommunicationError:
|
||||
get_client.ans = None
|
||||
client = get_client()
|
||||
client.speak(text)
|
@ -268,6 +268,7 @@ class ViewerBridge(Bridge):
|
||||
close_prep_finished = from_js(object)
|
||||
highlights_changed = from_js(object)
|
||||
open_url = from_js(object)
|
||||
speak_simple_text = from_js(object)
|
||||
|
||||
create_view = to_js()
|
||||
start_book_load = to_js()
|
||||
@ -514,6 +515,7 @@ class WebView(RestartingWebEngineView):
|
||||
self.bridge.close_prep_finished.connect(self.close_prep_finished)
|
||||
self.bridge.highlights_changed.connect(self.highlights_changed)
|
||||
self.bridge.open_url.connect(safe_open_url)
|
||||
self.bridge.speak_simple_text.connect(self.speak_simple_text)
|
||||
self.bridge.export_shortcut_map.connect(self.set_shortcut_map)
|
||||
self.shortcut_map = {}
|
||||
self.bridge.report_cfi.connect(self.call_callback)
|
||||
@ -527,6 +529,10 @@ class WebView(RestartingWebEngineView):
|
||||
self.inspector = Inspector(parent.inspector_dock.toggleViewAction(), self)
|
||||
parent.inspector_dock.setWidget(self.inspector)
|
||||
|
||||
def speak_simple_text(self, text):
|
||||
from calibre.gui2.tts.implementation import speak_simple_text
|
||||
speak_simple_text(text)
|
||||
|
||||
def set_shortcut_map(self, smap):
|
||||
self.shortcut_map = smap
|
||||
self.shortcuts_changed.emit(smap)
|
||||
|
@ -192,6 +192,7 @@ def all_actions():
|
||||
'search_net': a('global-search', _('Search for selection on the net'), 'internet_search'),
|
||||
'remove_highlight': a('trash', _('Remove this highlight'), 'remove_highlight', True),
|
||||
'clear': a('close', _('Clear selection'), 'clear_selection'),
|
||||
'speak': a('bullhorn', _('Speak aloud'), 'speak_aloud'),
|
||||
}
|
||||
qh = all_actions.ans.quick_highlight
|
||||
qh.icon_function = quick_highlight_icon.bind(None, qh.icon, qh.text)
|
||||
@ -950,6 +951,11 @@ class SelectionBar:
|
||||
self.view.on_handle_shortcut({'name': 'clear_selection'})
|
||||
self.hide()
|
||||
|
||||
def speak_aloud(self):
|
||||
text = self.view.currently_showing.selection.text
|
||||
if text:
|
||||
ui_operations.speak_simple_text(text)
|
||||
|
||||
def create_highlight(self):
|
||||
cs = self.view.currently_showing.selection
|
||||
hs = self.current_highlight_style
|
||||
|
@ -398,6 +398,8 @@ if window is window.top:
|
||||
ui_operations.annots_changed = def(amap):
|
||||
if amap.highlight:
|
||||
to_python.highlights_changed(amap.highlight)
|
||||
ui_operations.speak_simple_text = def(text):
|
||||
to_python.speak_simple_text(text)
|
||||
|
||||
document.body.appendChild(E.div(id='view'))
|
||||
window.onerror = onerror
|
||||
|
Loading…
x
Reference in New Issue
Block a user