Speech history added, bound to fenrir+control+h.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("opens speech history")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].open_history()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("closes speech history")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].close_history()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("copies current speech history item to the clipboard")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].copy_current_to_clipboard()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("speaks current speech history item")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].present_current()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("selects the next speech history item")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].next_entry()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class command:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def get_description(self):
|
||||
return _("selects the previous speech history item")
|
||||
|
||||
def run(self):
|
||||
self.env["runtime"]["SpeechHistoryManager"].prev_entry()
|
||||
|
||||
def set_callback(self, callback):
|
||||
pass
|
||||
@@ -103,6 +103,10 @@ class FenrirManager:
|
||||
self.environment["runtime"][
|
||||
"InputManager"
|
||||
].clear_event_buffer()
|
||||
if self.environment["runtime"]["SpeechHistoryManager"].is_active():
|
||||
self.environment["runtime"][
|
||||
"InputManager"
|
||||
].clear_event_buffer()
|
||||
|
||||
self.detect_shortcut_command()
|
||||
|
||||
@@ -159,6 +163,14 @@ class FenrirManager:
|
||||
current_command, "vmenu-navigation"
|
||||
)
|
||||
return
|
||||
elif self.environment["runtime"]["SpeechHistoryManager"].is_active():
|
||||
if self.environment["runtime"]["CommandManager"].command_exists(
|
||||
current_command, "speech-history"
|
||||
):
|
||||
self.environment["runtime"]["CommandManager"].execute_command(
|
||||
current_command, "speech-history"
|
||||
)
|
||||
return
|
||||
|
||||
# default
|
||||
self.environment["runtime"]["CommandManager"].execute_command(
|
||||
@@ -298,12 +310,18 @@ class FenrirManager:
|
||||
if self.command != "":
|
||||
self.singleKeyCommand = True
|
||||
elif (
|
||||
self.environment["runtime"]["DiffReviewManager"].is_active()
|
||||
(
|
||||
self.environment["runtime"]["DiffReviewManager"].is_active()
|
||||
or self.environment["runtime"][
|
||||
"SpeechHistoryManager"
|
||||
].is_active()
|
||||
)
|
||||
and self.command != ""
|
||||
):
|
||||
# Diff mode uses non-Fenrir modified bindings (Shift/Ctrl).
|
||||
# Modal modes use non-Fenrir modified bindings.
|
||||
# Promote resolved shortcuts to executable commands so
|
||||
# combinations like Shift+H and Ctrl+Right are dispatched.
|
||||
# combinations like Shift+H, Ctrl+Right, and plain arrows
|
||||
# are dispatched.
|
||||
self.singleKeyCommand = True
|
||||
|
||||
if not (self.singleKeyCommand or self.modifierInput):
|
||||
|
||||
@@ -20,6 +20,7 @@ general_data = {
|
||||
"ScreenManager",
|
||||
"InputManager",
|
||||
"OutputManager",
|
||||
"SpeechHistoryManager",
|
||||
"HelpManager",
|
||||
"MemoryManager",
|
||||
"EventManager",
|
||||
@@ -48,5 +49,6 @@ general_data = {
|
||||
"onSwitchApplicationProfile",
|
||||
"help",
|
||||
"vmenu-navigation",
|
||||
"speech-history",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -75,6 +75,14 @@ class OutputManager:
|
||||
return
|
||||
if (len(text) > 1) and (text.strip(string.whitespace) == ""):
|
||||
return
|
||||
if self.env["runtime"]["SettingsManager"].get_setting_as_bool(
|
||||
"speech", "enabled"
|
||||
):
|
||||
speech_history_manager = self.env["runtime"].get(
|
||||
"SpeechHistoryManager"
|
||||
)
|
||||
if speech_history_manager:
|
||||
speech_history_manager.add_text(text)
|
||||
is_capital = self._should_announce_capital(text, announce_capital)
|
||||
use_pitch_for_capital = False
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ runtime_data = {
|
||||
"CommandManager": None,
|
||||
"ScreenManager": None,
|
||||
"OutputManager": None,
|
||||
"SpeechHistoryManager": None,
|
||||
"DebugManager": None,
|
||||
"SettingsManager": None,
|
||||
"FenrirManager": None,
|
||||
|
||||
@@ -32,6 +32,7 @@ settings_data = {
|
||||
"hardware_baud_rate": 9600,
|
||||
"auto_read_incoming": True,
|
||||
"read_numbers_as_digits": False,
|
||||
"history_size": 50,
|
||||
"rapid_update_threshold": 5,
|
||||
"rapid_update_window": 0.3,
|
||||
"batch_flush_interval": 0.5,
|
||||
|
||||
@@ -29,6 +29,7 @@ from fenrirscreenreader.core import readAllManager
|
||||
from fenrirscreenreader.core import remoteManager
|
||||
from fenrirscreenreader.core import sayAllManager
|
||||
from fenrirscreenreader.core import screenManager
|
||||
from fenrirscreenreader.core import speechHistoryManager
|
||||
from fenrirscreenreader.core import tableManager
|
||||
from fenrirscreenreader.core import textManager
|
||||
from fenrirscreenreader.core import vmenuManager
|
||||
@@ -738,6 +739,11 @@ class SettingsManager:
|
||||
environment["runtime"]["OutputManager"] = outputManager.OutputManager()
|
||||
environment["runtime"]["OutputManager"].initialize(environment)
|
||||
|
||||
environment["runtime"][
|
||||
"SpeechHistoryManager"
|
||||
] = speechHistoryManager.SpeechHistoryManager()
|
||||
environment["runtime"]["SpeechHistoryManager"].initialize(environment)
|
||||
|
||||
environment["runtime"]["InputManager"] = inputManager.InputManager()
|
||||
environment["runtime"]["InputManager"].initialize(environment)
|
||||
self.load_keyboard_layout(environment)
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Fenrir TTY screen reader
|
||||
# By Chrys, Storm Dragon, and contributors.
|
||||
|
||||
from fenrirscreenreader.core.i18n import _
|
||||
|
||||
|
||||
class SpeechHistoryManager:
|
||||
def __init__(self):
|
||||
self.env = None
|
||||
self.history = []
|
||||
self.curr_index = -1
|
||||
self.active = False
|
||||
self.bindings_backup = None
|
||||
self.raw_bindings_backup = None
|
||||
|
||||
def initialize(self, environment):
|
||||
self.env = environment
|
||||
|
||||
def shutdown(self):
|
||||
self.set_active(False)
|
||||
|
||||
def is_active(self):
|
||||
return self.active
|
||||
|
||||
def add_text(self, text):
|
||||
if self.active:
|
||||
return False
|
||||
if not isinstance(text, str):
|
||||
return False
|
||||
if text == "":
|
||||
return False
|
||||
text_key = self._get_history_key(text)
|
||||
if text_key == "":
|
||||
return False
|
||||
if text_key in [self._get_history_key(item) for item in self.history]:
|
||||
return False
|
||||
history_size = self._get_history_size()
|
||||
if history_size <= 0:
|
||||
return False
|
||||
self.history.insert(0, text)
|
||||
del self.history[history_size:]
|
||||
if self.curr_index >= len(self.history):
|
||||
self.curr_index = len(self.history) - 1
|
||||
return True
|
||||
|
||||
def open_history(self):
|
||||
if not self.history:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("speech history empty"), interrupt=True
|
||||
)
|
||||
return False
|
||||
self.curr_index = -1
|
||||
self.set_active(True)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Speech history"), interrupt=True
|
||||
)
|
||||
return True
|
||||
|
||||
def close_history(self, announce=True):
|
||||
if announce:
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("speech history closed"), interrupt=True
|
||||
)
|
||||
self.set_active(False)
|
||||
|
||||
def next_entry(self):
|
||||
if not self._has_history():
|
||||
return
|
||||
if self.curr_index == -1:
|
||||
self.curr_index = 0
|
||||
self.present_current()
|
||||
return
|
||||
if self.curr_index <= 0:
|
||||
self.curr_index = 0
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("First speech history item"), interrupt=True
|
||||
)
|
||||
self.present_current(interrupt=False)
|
||||
return
|
||||
self.curr_index -= 1
|
||||
self.present_current()
|
||||
|
||||
def prev_entry(self):
|
||||
if not self._has_history():
|
||||
return
|
||||
if self.curr_index == -1:
|
||||
self.curr_index = 0
|
||||
self.present_current()
|
||||
return
|
||||
if self.curr_index >= len(self.history) - 1:
|
||||
self.curr_index = len(self.history) - 1
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("Last speech history item"), interrupt=True
|
||||
)
|
||||
self.present_current(interrupt=False)
|
||||
return
|
||||
self.curr_index += 1
|
||||
self.present_current()
|
||||
|
||||
def present_current(self, interrupt=True):
|
||||
if not self._has_history():
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("speech history empty"), interrupt=True
|
||||
)
|
||||
return
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
self.history[self.curr_index], interrupt=interrupt
|
||||
)
|
||||
|
||||
def copy_current_to_clipboard(self):
|
||||
if not self._has_history():
|
||||
self.close_history()
|
||||
return
|
||||
text = self.history[self.curr_index]
|
||||
self.env["runtime"]["MemoryManager"].add_value_to_first_index(
|
||||
"clipboardHistory", text
|
||||
)
|
||||
self.env["runtime"]["OutputManager"].present_text(
|
||||
_("copied to clipboard"),
|
||||
sound_icon="CopyToClipboard",
|
||||
interrupt=True,
|
||||
)
|
||||
self.set_active(False)
|
||||
|
||||
def set_active(self, active):
|
||||
if active == self.active:
|
||||
return
|
||||
self.active = active
|
||||
if self.active:
|
||||
self._install_bindings()
|
||||
else:
|
||||
self._restore_bindings()
|
||||
|
||||
def _has_history(self):
|
||||
if not self.history:
|
||||
self.curr_index = -1
|
||||
return False
|
||||
if self.curr_index >= len(self.history):
|
||||
self.curr_index = len(self.history) - 1
|
||||
return True
|
||||
|
||||
def _get_history_size(self):
|
||||
try:
|
||||
return self.env["runtime"]["SettingsManager"].get_setting_as_int(
|
||||
"speech", "history_size"
|
||||
)
|
||||
except Exception:
|
||||
return 50
|
||||
|
||||
def _get_history_key(self, text):
|
||||
return " ".join(text.split())
|
||||
|
||||
def _install_bindings(self):
|
||||
self.bindings_backup = self.env["bindings"].copy()
|
||||
self.raw_bindings_backup = self.env["rawBindings"].copy()
|
||||
self.env["bindings"] = {
|
||||
str([1, ["KEY_UP"]]): "SPEECH_HISTORY_PREV",
|
||||
str([1, ["KEY_DOWN"]]): "SPEECH_HISTORY_NEXT",
|
||||
str([1, ["KEY_SPACE"]]): "SPEECH_HISTORY_CURRENT",
|
||||
str([1, ["KEY_ENTER"]]): "SPEECH_HISTORY_COPY",
|
||||
str([1, ["KEY_KPENTER"]]): "SPEECH_HISTORY_COPY",
|
||||
str([1, ["KEY_ESC"]]): "SPEECH_HISTORY_CLOSE",
|
||||
}
|
||||
self.env["rawBindings"] = {
|
||||
str([1, ["KEY_UP"]]): [1, ["KEY_UP"]],
|
||||
str([1, ["KEY_DOWN"]]): [1, ["KEY_DOWN"]],
|
||||
str([1, ["KEY_SPACE"]]): [1, ["KEY_SPACE"]],
|
||||
str([1, ["KEY_ENTER"]]): [1, ["KEY_ENTER"]],
|
||||
str([1, ["KEY_KPENTER"]]): [1, ["KEY_KPENTER"]],
|
||||
str([1, ["KEY_ESC"]]): [1, ["KEY_ESC"]],
|
||||
}
|
||||
|
||||
def _restore_bindings(self):
|
||||
if self.bindings_backup is not None:
|
||||
self.env["bindings"] = self.bindings_backup
|
||||
if self.raw_bindings_backup is not None:
|
||||
self.env["rawBindings"] = self.raw_bindings_backup
|
||||
self.bindings_backup = None
|
||||
self.raw_bindings_backup = None
|
||||
Reference in New Issue
Block a user