|
|
|
@@ -39,6 +39,8 @@ from . import input_event
|
|
|
|
|
from . import keybindings
|
|
|
|
|
from . import messages
|
|
|
|
|
from . import cthulhu_state
|
|
|
|
|
from . import script_manager
|
|
|
|
|
from . import speechserver
|
|
|
|
|
from . import settings
|
|
|
|
|
from . import settings_manager
|
|
|
|
|
from . import speech
|
|
|
|
@@ -49,6 +51,17 @@ class SpeechAndVerbosityManager:
|
|
|
|
|
"""Configures speech and verbosity settings."""
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
self._speech_settings_order = [
|
|
|
|
|
"rate",
|
|
|
|
|
"pitch",
|
|
|
|
|
"volume",
|
|
|
|
|
"module",
|
|
|
|
|
"voice",
|
|
|
|
|
]
|
|
|
|
|
self._current_speech_setting_index = 0
|
|
|
|
|
self._rate_step = 1
|
|
|
|
|
self._pitch_step = 0.1
|
|
|
|
|
self._volume_step = 0.1
|
|
|
|
|
self._handlers = self._setup_handlers()
|
|
|
|
|
self._bindings = self._setup_bindings()
|
|
|
|
|
|
|
|
|
@@ -149,6 +162,31 @@ class SpeechAndVerbosityManager:
|
|
|
|
|
self.increase_volume,
|
|
|
|
|
cmdnames.INCREASE_SPEECH_VOLUME)
|
|
|
|
|
|
|
|
|
|
handlers["selectPreviousSpeechSettingHandler"] = \
|
|
|
|
|
input_event.InputEventHandler(
|
|
|
|
|
self.select_previous_speech_setting,
|
|
|
|
|
cmdnames.SPEECH_SETTING_PREVIOUS)
|
|
|
|
|
|
|
|
|
|
handlers["selectNextSpeechSettingHandler"] = \
|
|
|
|
|
input_event.InputEventHandler(
|
|
|
|
|
self.select_next_speech_setting,
|
|
|
|
|
cmdnames.SPEECH_SETTING_NEXT)
|
|
|
|
|
|
|
|
|
|
handlers["decreaseCurrentSpeechSettingHandler"] = \
|
|
|
|
|
input_event.InputEventHandler(
|
|
|
|
|
self.decrease_current_speech_setting,
|
|
|
|
|
cmdnames.SPEECH_SETTING_DECREASE)
|
|
|
|
|
|
|
|
|
|
handlers["increaseCurrentSpeechSettingHandler"] = \
|
|
|
|
|
input_event.InputEventHandler(
|
|
|
|
|
self.increase_current_speech_setting,
|
|
|
|
|
cmdnames.SPEECH_SETTING_INCREASE)
|
|
|
|
|
|
|
|
|
|
handlers["saveSpeechSettingsHandler"] = \
|
|
|
|
|
input_event.InputEventHandler(
|
|
|
|
|
self.save_speech_settings,
|
|
|
|
|
cmdnames.SPEECH_SETTINGS_SAVE)
|
|
|
|
|
|
|
|
|
|
return handlers
|
|
|
|
|
|
|
|
|
|
def _setup_bindings(self):
|
|
|
|
@@ -233,6 +271,41 @@ class SpeechAndVerbosityManager:
|
|
|
|
|
keybindings.NO_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("increaseSpeechVolumeHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"Left",
|
|
|
|
|
keybindings.defaultModifierMask,
|
|
|
|
|
keybindings.CTHULHU_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("selectPreviousSpeechSettingHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"Right",
|
|
|
|
|
keybindings.defaultModifierMask,
|
|
|
|
|
keybindings.CTHULHU_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("selectNextSpeechSettingHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"Down",
|
|
|
|
|
keybindings.defaultModifierMask,
|
|
|
|
|
keybindings.CTHULHU_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("decreaseCurrentSpeechSettingHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"Up",
|
|
|
|
|
keybindings.defaultModifierMask,
|
|
|
|
|
keybindings.CTHULHU_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("increaseCurrentSpeechSettingHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"s",
|
|
|
|
|
keybindings.defaultModifierMask,
|
|
|
|
|
keybindings.CTHULHU_CTRL_MODIFIER_MASK | keybindings.SHIFT_MODIFIER_MASK,
|
|
|
|
|
self._handlers.get("saveSpeechSettingsHandler")))
|
|
|
|
|
|
|
|
|
|
bindings.add(
|
|
|
|
|
keybindings.KeyBinding(
|
|
|
|
|
"",
|
|
|
|
@@ -266,6 +339,380 @@ class SpeechAndVerbosityManager:
|
|
|
|
|
def _get_server(self):
|
|
|
|
|
return speech.getSpeechServer()
|
|
|
|
|
|
|
|
|
|
def _format_number(self, value):
|
|
|
|
|
if isinstance(value, float):
|
|
|
|
|
if value.is_integer():
|
|
|
|
|
return str(int(value))
|
|
|
|
|
return f"{value:.1f}".rstrip("0").rstrip(".")
|
|
|
|
|
return str(value)
|
|
|
|
|
|
|
|
|
|
def _present_message(self, script, message):
|
|
|
|
|
if script:
|
|
|
|
|
script.presentMessage(message)
|
|
|
|
|
else:
|
|
|
|
|
speech.speak(message)
|
|
|
|
|
|
|
|
|
|
def _get_default_voice(self):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = settings.voices.get(settings.DEFAULT_VOICE)
|
|
|
|
|
if default_voice is None:
|
|
|
|
|
default_voice = acss.ACSS({})
|
|
|
|
|
settings.voices[settings.DEFAULT_VOICE] = default_voice
|
|
|
|
|
return default_voice
|
|
|
|
|
|
|
|
|
|
def _set_default_voice_family(self, family):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
if family is None:
|
|
|
|
|
default_voice.pop(acss.ACSS.FAMILY, None)
|
|
|
|
|
else:
|
|
|
|
|
default_voice[acss.ACSS.FAMILY] = dict(family)
|
|
|
|
|
default_voice['established'] = True
|
|
|
|
|
|
|
|
|
|
def _get_current_speech_setting(self):
|
|
|
|
|
return self._speech_settings_order[self._current_speech_setting_index]
|
|
|
|
|
|
|
|
|
|
def _get_rate_value(self):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
return int(default_voice.get(acss.ACSS.RATE, 50))
|
|
|
|
|
|
|
|
|
|
def _set_rate_value(self, value):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
default_voice[acss.ACSS.RATE] = int(value)
|
|
|
|
|
default_voice['established'] = True
|
|
|
|
|
|
|
|
|
|
def _get_pitch_value(self):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
return float(default_voice.get(acss.ACSS.AVERAGE_PITCH, 5.0))
|
|
|
|
|
|
|
|
|
|
def _set_pitch_value(self, value):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
default_voice[acss.ACSS.AVERAGE_PITCH] = float(value)
|
|
|
|
|
default_voice['established'] = True
|
|
|
|
|
|
|
|
|
|
def _get_volume_value(self):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
return float(default_voice.get(acss.ACSS.GAIN, 10.0))
|
|
|
|
|
|
|
|
|
|
def _set_volume_value(self, value):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
default_voice[acss.ACSS.GAIN] = float(value)
|
|
|
|
|
default_voice['established'] = True
|
|
|
|
|
|
|
|
|
|
def _get_current_voice_name(self, server=None):
|
|
|
|
|
from . import acss
|
|
|
|
|
default_voice = self._get_default_voice()
|
|
|
|
|
family = default_voice.get(acss.ACSS.FAMILY, {}) or {}
|
|
|
|
|
name = family.get(speechserver.VoiceFamily.NAME)
|
|
|
|
|
if name:
|
|
|
|
|
return name
|
|
|
|
|
if server:
|
|
|
|
|
voices = self._get_available_voices(server)
|
|
|
|
|
if voices:
|
|
|
|
|
return voices[0].get(speechserver.VoiceFamily.NAME)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def _get_available_modules(self, server):
|
|
|
|
|
if server is None or not hasattr(server, 'list_output_modules'):
|
|
|
|
|
return []
|
|
|
|
|
try:
|
|
|
|
|
modules = list(server.list_output_modules() or [])
|
|
|
|
|
except Exception as e:
|
|
|
|
|
debug.printMessage(debug.LEVEL_WARNING, f"Error getting output modules: {e}", True)
|
|
|
|
|
return []
|
|
|
|
|
return modules
|
|
|
|
|
|
|
|
|
|
def _get_available_voices(self, server):
|
|
|
|
|
if server is None or not hasattr(server, 'getVoiceFamilies'):
|
|
|
|
|
return []
|
|
|
|
|
try:
|
|
|
|
|
voices = server.getVoiceFamilies() or []
|
|
|
|
|
except Exception as e:
|
|
|
|
|
debug.printMessage(debug.LEVEL_WARNING, f"Error getting voices: {e}", True)
|
|
|
|
|
return []
|
|
|
|
|
filtered = []
|
|
|
|
|
for voice in voices:
|
|
|
|
|
if voice.get(speechserver.VoiceFamily.NAME):
|
|
|
|
|
filtered.append(voice)
|
|
|
|
|
if not filtered:
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
if not self._should_filter_voices_by_locale(server):
|
|
|
|
|
return filtered
|
|
|
|
|
|
|
|
|
|
language, dialect = self._get_system_language_and_dialect()
|
|
|
|
|
if not language:
|
|
|
|
|
return filtered
|
|
|
|
|
|
|
|
|
|
language_filtered = []
|
|
|
|
|
for voice in filtered:
|
|
|
|
|
voice_lang = (voice.get(speechserver.VoiceFamily.LANG) or "").lower()
|
|
|
|
|
voice_dialect = (voice.get(speechserver.VoiceFamily.DIALECT) or "").lower()
|
|
|
|
|
if voice_lang != language:
|
|
|
|
|
continue
|
|
|
|
|
if dialect and voice_dialect and voice_dialect != dialect:
|
|
|
|
|
continue
|
|
|
|
|
language_filtered.append(voice)
|
|
|
|
|
|
|
|
|
|
if language_filtered:
|
|
|
|
|
msg = (
|
|
|
|
|
"SPEECH AND VERBOSITY MANAGER: "
|
|
|
|
|
f"Filtered voices to locale {language}"
|
|
|
|
|
f"{('-' + dialect) if dialect else ''}: "
|
|
|
|
|
f"{len(language_filtered)} of {len(filtered)}"
|
|
|
|
|
)
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
return language_filtered
|
|
|
|
|
|
|
|
|
|
msg = (
|
|
|
|
|
"SPEECH AND VERBOSITY MANAGER: "
|
|
|
|
|
f"No voices for locale {language}"
|
|
|
|
|
f"{('-' + dialect) if dialect else ''}; using all voices."
|
|
|
|
|
)
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
return filtered
|
|
|
|
|
|
|
|
|
|
def _should_filter_voices_by_locale(self, server):
|
|
|
|
|
if server is None or not hasattr(server, "getOutputModule"):
|
|
|
|
|
return False
|
|
|
|
|
try:
|
|
|
|
|
module = (server.getOutputModule() or "").lower()
|
|
|
|
|
except Exception:
|
|
|
|
|
return False
|
|
|
|
|
return "espeak-ng" in module
|
|
|
|
|
|
|
|
|
|
def _get_system_language_and_dialect(self):
|
|
|
|
|
import locale
|
|
|
|
|
locale_value = None
|
|
|
|
|
try:
|
|
|
|
|
locale_value = locale.getlocale(locale.LC_MESSAGES)[0]
|
|
|
|
|
except Exception:
|
|
|
|
|
locale_value = None
|
|
|
|
|
if not locale_value:
|
|
|
|
|
try:
|
|
|
|
|
locale_value = locale.getdefaultlocale()[0]
|
|
|
|
|
except Exception:
|
|
|
|
|
locale_value = None
|
|
|
|
|
|
|
|
|
|
if not locale_value:
|
|
|
|
|
return "", ""
|
|
|
|
|
|
|
|
|
|
if "_" in locale_value:
|
|
|
|
|
language, dialect = locale_value.split("_", 1)
|
|
|
|
|
elif "-" in locale_value:
|
|
|
|
|
language, dialect = locale_value.split("-", 1)
|
|
|
|
|
else:
|
|
|
|
|
language, dialect = locale_value, ""
|
|
|
|
|
|
|
|
|
|
return language.lower(), dialect.lower()
|
|
|
|
|
|
|
|
|
|
def _announce_current_speech_setting(self, script=None):
|
|
|
|
|
setting = self._get_current_speech_setting()
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO,
|
|
|
|
|
f"SPEECH AND VERBOSITY MANAGER: Current setting {setting}",
|
|
|
|
|
True)
|
|
|
|
|
if setting == "rate":
|
|
|
|
|
value = self._get_rate_value()
|
|
|
|
|
message = messages.SPEECH_RATE_VALUE % value
|
|
|
|
|
elif setting == "pitch":
|
|
|
|
|
value = self._format_number(self._get_pitch_value())
|
|
|
|
|
message = messages.SPEECH_PITCH_VALUE % value
|
|
|
|
|
elif setting == "volume":
|
|
|
|
|
value = self._format_number(self._get_volume_value())
|
|
|
|
|
message = messages.SPEECH_VOLUME_VALUE % value
|
|
|
|
|
elif setting == "module":
|
|
|
|
|
server = self._get_server()
|
|
|
|
|
if server is None or not hasattr(server, 'getOutputModule'):
|
|
|
|
|
message = messages.SPEECH_MODULES_UNAVAILABLE
|
|
|
|
|
else:
|
|
|
|
|
module = server.getOutputModule() or ""
|
|
|
|
|
if module:
|
|
|
|
|
message = messages.SPEECH_MODULE_VALUE % module
|
|
|
|
|
else:
|
|
|
|
|
message = messages.SPEECH_MODULES_UNAVAILABLE
|
|
|
|
|
elif setting == "voice":
|
|
|
|
|
server = self._get_server()
|
|
|
|
|
voices = self._get_available_voices(server)
|
|
|
|
|
if not voices:
|
|
|
|
|
message = messages.SPEECH_VOICES_UNAVAILABLE
|
|
|
|
|
else:
|
|
|
|
|
name = self._get_current_voice_name(server)
|
|
|
|
|
message = messages.SPEECH_VOICE_VALUE % name
|
|
|
|
|
else:
|
|
|
|
|
message = ""
|
|
|
|
|
|
|
|
|
|
if message:
|
|
|
|
|
self._present_message(script, message)
|
|
|
|
|
|
|
|
|
|
@dbus_service.command
|
|
|
|
|
def select_previous_speech_setting(self, script=None, event=None):
|
|
|
|
|
if self._current_speech_setting_index > 0:
|
|
|
|
|
self._current_speech_setting_index -= 1
|
|
|
|
|
self._announce_current_speech_setting(script)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@dbus_service.command
|
|
|
|
|
def select_next_speech_setting(self, script=None, event=None):
|
|
|
|
|
if self._current_speech_setting_index < len(self._speech_settings_order) - 1:
|
|
|
|
|
self._current_speech_setting_index += 1
|
|
|
|
|
self._announce_current_speech_setting(script)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@dbus_service.command
|
|
|
|
|
def decrease_current_speech_setting(self, script=None, event=None):
|
|
|
|
|
return self._adjust_current_speech_setting(script, decrease=True)
|
|
|
|
|
|
|
|
|
|
@dbus_service.command
|
|
|
|
|
def increase_current_speech_setting(self, script=None, event=None):
|
|
|
|
|
return self._adjust_current_speech_setting(script, decrease=False)
|
|
|
|
|
|
|
|
|
|
def _adjust_current_speech_setting(self, script, decrease=False):
|
|
|
|
|
setting = self._get_current_speech_setting()
|
|
|
|
|
if setting == "rate":
|
|
|
|
|
return self._adjust_rate(script, decrease)
|
|
|
|
|
if setting == "pitch":
|
|
|
|
|
return self._adjust_pitch(script, decrease)
|
|
|
|
|
if setting == "volume":
|
|
|
|
|
return self._adjust_volume(script, decrease)
|
|
|
|
|
if setting == "module":
|
|
|
|
|
return self._adjust_module(script, decrease)
|
|
|
|
|
if setting == "voice":
|
|
|
|
|
return self._adjust_voice(script, decrease)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _adjust_rate(self, script, decrease):
|
|
|
|
|
delta = -self._rate_step if decrease else self._rate_step
|
|
|
|
|
value = self._get_rate_value() + delta
|
|
|
|
|
value = max(0, min(100, value))
|
|
|
|
|
self._set_rate_value(value)
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Rate set to {value}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
self._announce_current_speech_setting(script)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _adjust_pitch(self, script, decrease):
|
|
|
|
|
delta = -self._pitch_step if decrease else self._pitch_step
|
|
|
|
|
value = round(self._get_pitch_value() + delta, 1)
|
|
|
|
|
value = max(0.0, min(10.0, value))
|
|
|
|
|
self._set_pitch_value(value)
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Pitch set to {value}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
self._announce_current_speech_setting(script)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _adjust_volume(self, script, decrease):
|
|
|
|
|
delta = -self._volume_step if decrease else self._volume_step
|
|
|
|
|
value = round(self._get_volume_value() + delta, 1)
|
|
|
|
|
value = max(0.0, min(10.0, value))
|
|
|
|
|
self._set_volume_value(value)
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Volume set to {value}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
self._announce_current_speech_setting(script)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _adjust_module(self, script, decrease):
|
|
|
|
|
server = self._get_server()
|
|
|
|
|
if server is None:
|
|
|
|
|
msg = "SPEECH AND VERBOSITY MANAGER: Cannot get speech server."
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
modules = self._get_available_modules(server)
|
|
|
|
|
if not modules:
|
|
|
|
|
self._present_message(script, messages.SPEECH_MODULES_UNAVAILABLE)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
current = server.getOutputModule() if hasattr(server, 'getOutputModule') else ""
|
|
|
|
|
try:
|
|
|
|
|
index = modules.index(current)
|
|
|
|
|
except ValueError:
|
|
|
|
|
index = 0
|
|
|
|
|
|
|
|
|
|
delta = -1 if decrease else 1
|
|
|
|
|
new_index = max(0, min(len(modules) - 1, index + delta))
|
|
|
|
|
new_module = modules[new_index]
|
|
|
|
|
|
|
|
|
|
if new_module != current:
|
|
|
|
|
try:
|
|
|
|
|
server.setOutputModule(new_module)
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Output module set to {new_module}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
debug.printMessage(debug.LEVEL_WARNING, f"Error setting output module: {e}", True)
|
|
|
|
|
return True
|
|
|
|
|
settings.speechServerInfo = [new_module, new_module]
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: speechServerInfo set to {settings.speechServerInfo}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
|
|
|
|
|
voices = self._get_available_voices(server)
|
|
|
|
|
if voices:
|
|
|
|
|
self._set_default_voice_family(voices[0])
|
|
|
|
|
else:
|
|
|
|
|
self._set_default_voice_family({})
|
|
|
|
|
|
|
|
|
|
self._present_message(script, messages.SPEECH_MODULE_VALUE % new_module)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def _adjust_voice(self, script, decrease):
|
|
|
|
|
server = self._get_server()
|
|
|
|
|
voices = self._get_available_voices(server)
|
|
|
|
|
if not voices:
|
|
|
|
|
self._present_message(script, messages.SPEECH_VOICES_UNAVAILABLE)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
current_name = self._get_current_voice_name(server)
|
|
|
|
|
index = 0
|
|
|
|
|
for idx, voice in enumerate(voices):
|
|
|
|
|
if voice.get(speechserver.VoiceFamily.NAME) == current_name:
|
|
|
|
|
index = idx
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
delta = -1 if decrease else 1
|
|
|
|
|
new_index = max(0, min(len(voices) - 1, index + delta))
|
|
|
|
|
new_voice = voices[new_index]
|
|
|
|
|
self._set_default_voice_family(new_voice)
|
|
|
|
|
name = new_voice.get(speechserver.VoiceFamily.NAME, "")
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Voice set to {name}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
self._present_message(script, messages.SPEECH_VOICE_VALUE % name)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
@dbus_service.command
|
|
|
|
|
def save_speech_settings(self, script=None, event=None):
|
|
|
|
|
try:
|
|
|
|
|
server = self._get_server()
|
|
|
|
|
if server and hasattr(server, "getOutputModule"):
|
|
|
|
|
module = server.getOutputModule() or ""
|
|
|
|
|
if module:
|
|
|
|
|
settings.speechServerInfo = [module, module]
|
|
|
|
|
msg = f"SPEECH AND VERBOSITY MANAGER: Saving speechServerInfo {settings.speechServerInfo}"
|
|
|
|
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
|
|
|
|
|
|
|
|
|
general = {}
|
|
|
|
|
for key in settings.userCustomizableSettings:
|
|
|
|
|
general[key] = getattr(settings, key)
|
|
|
|
|
|
|
|
|
|
current_profile = _settings_manager.profile
|
|
|
|
|
pronunciations = _settings_manager.getPronunciations(current_profile)
|
|
|
|
|
keybindings = _settings_manager.getKeybindings(current_profile)
|
|
|
|
|
|
|
|
|
|
default_script = script_manager.get_manager().get_default_script()
|
|
|
|
|
_settings_manager.saveSettings(default_script,
|
|
|
|
|
general,
|
|
|
|
|
pronunciations,
|
|
|
|
|
keybindings)
|
|
|
|
|
self._present_message(script, messages.SPEECH_SETTINGS_SAVED)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
debug.printMessage(debug.LEVEL_WARNING, f"Error saving speech settings: {e}", True)
|
|
|
|
|
self._present_message(script, messages.SPEECH_SETTINGS_SAVE_FAILED)
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
# ========================================================================
|
|
|
|
|
# D-Bus Speech Server Controls
|
|
|
|
|
# ========================================================================
|
|
|
|
|