diff --git a/config/keyboard/laptop.conf b/config/keyboard/laptop.conf index a00978e7..95680c9f 100644 --- a/config/keyboard/laptop.conf +++ b/config/keyboard/laptop.conf @@ -76,12 +76,11 @@ KEY_FENRIR,KEY_F3=toggle_sound KEY_FENRIR,KEY_F4=toggle_speech KEY_FENRIR,KEY_ENTER=temp_disable_speech KEY_FENRIR,KEY_SHIFT,KEY_P=progress_bar_monitor -#KEY_FENRIR,KEY_SHIFT,KEY_ENTER=silence_until_prompt +KEY_FENRIR,KEY_SHIFT,KEY_ENTER=toggle_auto_read KEY_FENRIR,KEY_SHIFT,KEY_CTRL,KEY_P=toggle_punctuation_level KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_ENTER=toggle_output KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons -KEY_FENRIR,KEY_ENTER=toggle_auto_read KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time KEY_FENRIR,KEY_Y=toggle_highlight_tracking #=toggle_barrier diff --git a/src/fenrir b/src/fenrir index 8f91aba1..11f332fd 100755 --- a/src/fenrir +++ b/src/fenrir @@ -27,7 +27,7 @@ def create_argument_parser(): argumentParser.add_argument( '-v', '--version', action='version', - version=f'Fenrir screen reader version {fenrirVersion.version}-{fenrirVersion.codeName}', + version=f'Fenrir screen reader version {fenrirVersion.version}-{fenrirVersion.code_name}', help='Show version information and exit' ) argumentParser.add_argument( @@ -94,9 +94,18 @@ def validate_arguments(cliArgs): def run_fenrir(): """Main function that runs Fenrir""" - fenrirApp = fenrirManager.fenrirManager(cliArgs) - fenrirApp.proceed() - del fenrirApp + fenrirApp = fenrirManager.FenrirManager(cliArgs) + try: + fenrirApp.proceed() + finally: + del fenrirApp + # Clean up PID file if it exists + pidFile = "/run/fenrir.pid" + if os.path.exists(pidFile): + try: + os.remove(pidFile) + except Exception: + pass def main(): global cliArgs diff --git a/src/fenrirscreenreader/commands/command_template.py b/src/fenrirscreenreader/commands/command_template.py index 4063c950..10da3943 100644 --- a/src/fenrirscreenreader/commands/command_template.py +++ b/src/fenrirscreenreader/commands/command_template.py @@ -5,16 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): pass - def setCallback(self, callback): + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/00_init_commands.py b/src/fenrirscreenreader/commands/commands/00_init_commands.py index 6457a1cc..6ec89477 100644 --- a/src/fenrirscreenreader/commands/commands/00_init_commands.py +++ b/src/fenrirscreenreader/commands/commands/00_init_commands.py @@ -6,20 +6,31 @@ # this command is just to initialize stuff. -# like init index lists in memoryManager +# like init index lists in MemoryManager # it is not useful to execute it + +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment # clipboard - self.env['runtime']['memoryManager'].addIndexList('clipboardHistory', self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards')) + self.env['runtime']['MemoryManager'].add_index_list( + 'clipboardHistory', self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'numberOfClipboards')) + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): pass - def setCallback(self, callback): + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py b/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py index 4f62a3d0..5055d5af 100644 --- a/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py +++ b/src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py @@ -4,6 +4,8 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils import string initialized = False @@ -12,42 +14,59 @@ try: initialized = True except Exception as e: pass - + + class command(): def __init__(self): self.language = '' self.spellChecker = None + def initialize(self, environment): self.env = environment - self.updateSpellLanguage() + self.update_spell_language() + def shutdown(self): - pass - def getDescription(self): - return _('adds the current word to the exceptions dictionary') - def updateSpellLanguage(self): - self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) - self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') - + pass + + def get_description(self): + return _('adds the current word to the exceptions dictionary') + + def update_spell_language(self): + self.spellChecker = enchant.Dict( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage')) + self.language = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') + def run(self): if not initialized: - return - if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: + return + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') != self.language: try: - self.updateSpellLanguage() + self.update_spell_language() except Exception as e: - return - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() + return + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() # get the word - newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] - x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) - currWord = currWord.strip(string.whitespace + r'!"#$%&\()*+,-./:;<=Â?@[\\]^_{|}~') + new_content = self.env['screen']['new_content_text'].split('\n')[ + cursor_pos['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + cursor_pos['x'], 0, new_content) + curr_word = curr_word.strip( + string.whitespace + + r'!"#$%&\()*+,-./:;<=Â?@[\\]^_{|}~') - if currWord != '': - if self.spellChecker.is_added(currWord): - self.env['runtime']['outputManager'].presentText(_('{0} is already in dictionary').format(currWord,), soundIcon='Cancel', interrupt=True) + if curr_word != '': + if self.spellChecker.is_added(curr_word): + self.env['runtime']['OutputManager'].present_text( + _('{0} is already in dictionary').format( + curr_word,), sound_icon ='Cancel', interrupt=True) else: - self.spellChecker.add(currWord) - self.env['runtime']['outputManager'].presentText(_('{0} added to dictionary').format(currWord,), soundIcon='Accept', interrupt=True) + self.spellChecker.add(curr_word) + self.env['runtime']['OutputManager'].present_text( + _('{0} added to dictionary').format( + curr_word,), sound_icon ='Accept', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/adjustment_base.py b/src/fenrirscreenreader/commands/commands/adjustment_base.py index 575c0abd..1ac77df4 100644 --- a/src/fenrirscreenreader/commands/commands/adjustment_base.py +++ b/src/fenrirscreenreader/commands/commands/adjustment_base.py @@ -4,29 +4,33 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import math -class AdjustmentCommand(): + +class adjustment_command(): """Base class for speech and sound adjustment commands""" + def __init__(self, section, setting, direction, step=0.1): self.section = section # 'speech' or 'sound' self.setting = setting # 'rate', 'pitch', 'volume' self.direction = direction # 'inc' or 'dec' self.step = step - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): action = "Increase" if self.direction == 'inc' else "Decrease" if self.section == 'speech': return _(f'{action} the speech {self.setting}') else: return _(f'{action} the {self.section} {self.setting}') - + def run(self): if self.section == 'sound' and self.setting == 'volume': # Sound volume uses different method @@ -34,11 +38,12 @@ class AdjustmentCommand(): else: # Speech rate, pitch, volume use standard method self._adjust_speech_setting() - + def _adjust_speech_setting(self): """Adjust speech settings (rate, pitch, volume)""" - value = self.env['runtime']['settingsManager'].getSettingAsFloat(self.section, self.setting) - + value = self.env['runtime']['SettingsManager'].get_setting_as_float( + self.section, self.setting) + # Apply adjustment with rounding if self.direction == 'inc': value = round((math.ceil(10 * value) / 10) + self.step, 2) @@ -48,23 +53,28 @@ class AdjustmentCommand(): value = round((math.ceil(10 * value) / 10) - self.step, 2) if value < 0.0: value = 0.0 - + # Set the new value - self.env['runtime']['settingsManager'].setSetting(self.section, self.setting, str(value)) - + self.env['runtime']['SettingsManager'].set_setting( + self.section, self.setting, str(value)) + # Present feedback percentage = int(value * 100) if self.section == 'speech': - feedback = _("{0} percent speech {1}").format(percentage, self.setting) + feedback = _("{0} percent speech {1}").format( + percentage, self.setting) else: - feedback = _("{0} percent {1} {2}").format(percentage, self.section, self.setting) - - self.env['runtime']['outputManager'].presentText(feedback, soundIcon='', interrupt=True) - + feedback = _("{0} percent {1} {2}").format( + percentage, self.section, self.setting) + + self.env['runtime']['OutputManager'].present_text( + feedback, sound_icon ='', interrupt=True) + def _adjust_sound_volume(self): """Adjust sound volume using same logic as speech""" - value = self.env['runtime']['settingsManager'].getSettingAsFloat(self.section, self.setting) - + value = self.env['runtime']['SettingsManager'].get_setting_as_float( + self.section, self.setting) + # Sound volume uses same math as speech settings if self.direction == 'inc': value = round((math.ceil(10 * value) / 10) + self.step, 2) @@ -74,15 +84,17 @@ class AdjustmentCommand(): value = round((math.ceil(10 * value) / 10) - self.step, 2) if value < 0.0: value = 0.0 - + # Set the new value - self.env['runtime']['settingsManager'].setSetting(self.section, self.setting, str(value)) - + self.env['runtime']['SettingsManager'].set_setting( + self.section, self.setting, str(value)) + # Present feedback with appropriate sound icon percentage = int(value * 100) sound_icon = 'SoundOn' if self.direction == 'inc' else 'SoundOff' feedback = _("{0} percent sound volume").format(percentage) - self.env['runtime']['outputManager'].presentText(feedback, soundIcon=sound_icon, interrupt=True) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + feedback, sound_icon =sound_icon, interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/announce_fenrir_version.py b/src/fenrirscreenreader/commands/commands/announce_fenrir_version.py index 6adc18f7..8d3f4e19 100644 --- a/src/fenrirscreenreader/commands/commands/announce_fenrir_version.py +++ b/src/fenrirscreenreader/commands/commands/announce_fenrir_version.py @@ -4,23 +4,33 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader import fenrirVersion + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return _('Present the version of Fenrir currrrently in use.') - + + def get_description(self): + return _('Present the version of Fenrir currently in use.') + def run(self): try: - self.env['runtime']['outputManager'].presentText(f'Fenrir screen reader version {fenrirVersion.version}-{fenrirVersion.codeName}', interrupt=True) - except exception as e: - self.env['runtime']['outputManager'].presentText(_('Version information is unavailable.'), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + f'Fenrir screen reader version { + fenrirVersion.version}-{ + fenrirVersion.code_name}', interrupt=True) + except Exception as e: + self.env['runtime']['OutputManager'].present_text( + _('Version information is unavailable.'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/apply_tested_voice.py b/src/fenrirscreenreader/commands/commands/apply_tested_voice.py index 91cbc047..2834ab35 100644 --- a/src/fenrirscreenreader/commands/commands/apply_tested_voice.py +++ b/src/fenrirscreenreader/commands/commands/apply_tested_voice.py @@ -1,71 +1,82 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Apply the last tested voice from safe voice browser" - + def run(self): try: # Check if we have a tested voice - if ('commandBuffer' not in self.env or + if ('commandBuffer' not in self.env or 'lastTestedModule' not in self.env['commandBuffer'] or - 'lastTestedVoice' not in self.env['commandBuffer']): - self.env['runtime']['outputManager'].presentText("No voice has been tested yet", interrupt=True) - self.env['runtime']['outputManager'].presentText("Use voice browser first", interrupt=True) + 'lastTestedVoice' not in self.env['commandBuffer']): + self.env['runtime']['OutputManager'].present_text( + "No voice has been tested yet", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "Use voice browser first", interrupt=True) return - + module = self.env['commandBuffer']['lastTestedModule'] voice = self.env['commandBuffer']['lastTestedVoice'] - - self.env['runtime']['outputManager'].presentText(f"Applying {voice} from {module}", interrupt=True) - + + self.env['runtime']['OutputManager'].present_text( + f"Applying {voice} from {module}", interrupt=True) + # Apply to runtime settings only (temporary until saved) - settingsManager = self.env['runtime']['settingsManager'] - + SettingsManager = self.env['runtime']['SettingsManager'] + # Store old values for safety - oldDriver = settingsManager.getSetting('speech', 'driver') - oldModule = settingsManager.getSetting('speech', 'module') - oldVoice = settingsManager.getSetting('speech', 'voice') - + old_driver = SettingsManager.get_setting('speech', 'driver') + old_module = SettingsManager.get_setting('speech', 'module') + old_voice = SettingsManager.get_setting('speech', 'voice') + try: - # Apply new settings to runtime only (use setSetting to update settingArgDict) - settingsManager.setSetting('speech', 'driver', 'speechdDriver') - settingsManager.setSetting('speech', 'module', module) - settingsManager.setSetting('speech', 'voice', voice) - + # Apply new settings to runtime only (use set_setting to update + # settingArgDict) + SettingsManager.set_setting('speech', 'driver', 'speechdDriver') + SettingsManager.set_setting('speech', 'module', module) + SettingsManager.set_setting('speech', 'voice', voice) + # Apply to speech driver instance directly - if 'speechDriver' in self.env['runtime']: - speechDriver = self.env['runtime']['speechDriver'] - + if 'SpeechDriver' in self.env['runtime']: + SpeechDriver = self.env['runtime']['SpeechDriver'] + # Set the module and voice on the driver instance - speechDriver.setModule(module) - speechDriver.setVoice(voice) - - self.env['runtime']['outputManager'].presentText("Voice applied successfully!", interrupt=True) - self.env['runtime']['outputManager'].presentText("Use save settings to make permanent", interrupt=True) - self.env['runtime']['outputManager'].playSound('Accept') - + SpeechDriver.set_module(module) + SpeechDriver.set_voice(voice) + + self.env['runtime']['OutputManager'].present_text( + "Voice applied successfully!", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "Use save settings to make permanent", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Accept') + except Exception as e: # Revert on failure - settingsManager.setSetting('speech', 'driver', oldDriver) - settingsManager.setSetting('speech', 'module', oldModule) - settingsManager.setSetting('speech', 'voice', oldVoice) - - self.env['runtime']['outputManager'].presentText(f"Failed to apply voice, reverted: {str(e)}", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') - + SettingsManager.set_setting('speech', 'driver', old_driver) + SettingsManager.set_setting('speech', 'module', old_module) + SettingsManager.set_setting('speech', 'voice', old_voice) + + self.env['runtime']['OutputManager'].present_text( + f"Failed to apply voice, reverted: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Apply voice error: {str(e)}", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + f"Apply voice error: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/attribute_cursor.py b/src/fenrirscreenreader/commands/commands/attribute_cursor.py index ec8010e1..ddfba9ad 100644 --- a/src/fenrirscreenreader/commands/commands/attribute_cursor.py +++ b/src/fenrirscreenreader/commands/commands/attribute_cursor.py @@ -4,26 +4,38 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import screen_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return _('Reads attributes of current cursor position') + + def get_description(self): + return _('Reads attributes of current cursor position') + def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() try: - attributes = self.env['runtime']['attributeManager'].getAttributeByXY( cursorPos['x'], cursorPos['y']) + attributes = self.env['runtime']['AttributeManager'].get_attribute_by_xy( + cursor_pos['x'], cursor_pos['y']) except Exception as e: - print(e) - attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString') - attributeFormatString = self.env['runtime']['attributeManager'].formatAttributes(attributes, attributeFormatString) - - self.env['runtime']['outputManager'].presentText(attributeFormatString, soundIcon='', interrupt=True) - def setCallback(self, callback): + print(e) + attribute_format_string = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'attribute_format_string') + attribute_format_string = self.env['runtime']['AttributeManager'].format_attributes( + attributes, attribute_format_string) + + self.env['runtime']['OutputManager'].present_text( + attribute_format_string, sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/bookmark_1.py b/src/fenrirscreenreader/commands/commands/bookmark_1.py index 13e6f54a..85bf1d1e 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_1.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_1.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(1, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_10.py b/src/fenrirscreenreader/commands/commands/bookmark_10.py index 1ea9c79f..30e7c8db 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_10.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_10.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(10, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_2.py b/src/fenrirscreenreader/commands/commands/bookmark_2.py index 8e93d4e1..7afb55d2 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_2.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_2.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(2, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_3.py b/src/fenrirscreenreader/commands/commands/bookmark_3.py index 168224af..990521c2 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_3.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_3.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(3, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_4.py b/src/fenrirscreenreader/commands/commands/bookmark_4.py index 913c31e4..41326199 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_4.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_4.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(4, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_5.py b/src/fenrirscreenreader/commands/commands/bookmark_5.py index f5556fa7..09916f97 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_5.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_5.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(5, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_6.py b/src/fenrirscreenreader/commands/commands/bookmark_6.py index 729fe1f3..287b267c 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_6.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_6.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(6, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_7.py b/src/fenrirscreenreader/commands/commands/bookmark_7.py index 8387c77a..be3a06b8 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_7.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_7.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(7, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_8.py b/src/fenrirscreenreader/commands/commands/bookmark_8.py index f1e4c799..0f5ca2f6 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_8.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_8.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(8, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_9.py b/src/fenrirscreenreader/commands/commands/bookmark_9.py index 04da752b..fae812c7 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_9.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_9.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(9, 'read') diff --git a/src/fenrirscreenreader/commands/commands/bookmark_base.py b/src/fenrirscreenreader/commands/commands/bookmark_base.py index 4bb4930f..b9a77e6a 100644 --- a/src/fenrirscreenreader/commands/commands/bookmark_base.py +++ b/src/fenrirscreenreader/commands/commands/bookmark_base.py @@ -4,28 +4,31 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.utils import line_utils +from fenrirscreenreader.utils import mark_utils +from fenrirscreenreader.core.i18n import _ + import gettext _ = gettext.gettext -from fenrirscreenreader.utils import mark_utils -from fenrirscreenreader.utils import line_utils -class BookmarkCommand(): +class bookmark_command(): """Base class for bookmark operations - read, set, clear""" + def __init__(self, bookmark_id, action='read'): self.ID = str(bookmark_id) self.action = action - + def initialize(self, environment): self.env = environment # Always initialize bookmark structure - all commands need this if self.ID not in self.env['commandBuffer']['bookMarks']: self.env['commandBuffer']['bookMarks'][self.ID] = {} - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): if self.action == 'read': return _('read Bookmark {0}').format(self.ID) elif self.action == 'set': @@ -33,7 +36,7 @@ class BookmarkCommand(): elif self.action == 'clear': return _('remove Bookmark {0}').format(self.ID) return f'{self.action} Bookmark {self.ID}' - + def run(self): if self.action == 'read': self._read_bookmark() @@ -41,95 +44,117 @@ class BookmarkCommand(): self._set_bookmark() elif self.action == 'clear': self._clear_bookmark() - + def _read_bookmark(self): - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() + if not self.env['commandBuffer']['bookMarks'][self.ID]: - self.env['runtime']['outputManager'].presentText('Bookmark {0} not set'.format(self.ID), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + 'Bookmark {0} not set'.format(self.ID), interrupt=True) return - - if currApp not in self.env['commandBuffer']['bookMarks'][self.ID]: - self.env['runtime']['outputManager'].presentText('Bookmark for application {0} not set'.format(currApp), interrupt=True) + + if curr_app not in self.env['commandBuffer']['bookMarks'][self.ID]: + self.env['runtime']['OutputManager'].present_text( + 'Bookmark for application {0} not set'.format(curr_app), interrupt=True) return - - if not self.env['commandBuffer']['bookMarks'][self.ID][currApp].get('1'): - self.env['runtime']['outputManager'].presentText('Bookmark for application {0} not set'.format(currApp), interrupt=True) + + if not self.env['commandBuffer']['bookMarks'][self.ID][curr_app].get( + '1'): + self.env['runtime']['OutputManager'].present_text( + 'Bookmark for application {0} not set'.format(curr_app), interrupt=True) return # Get bookmarked text marked = '' - startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy() - - if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']: - endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy() - marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) + start_mark = self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['1'].copy( + ) + + if self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['2']: + end_mark = self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['2'].copy( + ) + marked = mark_utils.get_text_between_marks( + start_mark, end_mark, self.env['screen']['new_content_text']) else: - x, y, marked = line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText']) - + x, y, marked = line_utils.get_current_line( + start_mark['x'], start_mark['y'], self.env['screen']['new_content_text']) + if marked.isspace(): - self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _('blank'), sound_icon ='EmptyLine', interrupt=True) else: - self.env['runtime']['outputManager'].presentText(marked, interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + marked, interrupt=True) + def _set_bookmark(self): if not self.env['commandBuffer']['Marks']['1']: - self.env['runtime']['outputManager'].presentText(_("No mark found"), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("No mark found"), interrupt=True) return - - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {} - - self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'] = self.env['commandBuffer']['Marks']['1'].copy() - + + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() + self.env['commandBuffer']['bookMarks'][self.ID][curr_app] = {} + + self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['1'] = self.env['commandBuffer']['Marks']['1'].copy() + if self.env['commandBuffer']['Marks']['2']: - self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy() + self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['2'] = self.env['commandBuffer']['Marks']['2'].copy() else: - self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None - - self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True) - + self.env['commandBuffer']['bookMarks'][self.ID][curr_app]['2'] = None + + self.env['runtime']['OutputManager'].present_text( + _('Bookmark {0} set for application {1}').format( + self.ID, curr_app), interrupt=True) + # Clear marks after setting bookmark self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None - + def _clear_bookmark(self): - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - - if self.ID in self.env['commandBuffer']['bookMarks'] and currApp in self.env['commandBuffer']['bookMarks'][self.ID]: - del self.env['commandBuffer']['bookMarks'][self.ID][currApp] - self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True) + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() + + if self.ID in self.env['commandBuffer']['bookMarks'] and curr_app in self.env['commandBuffer']['bookMarks'][self.ID]: + del self.env['commandBuffer']['bookMarks'][self.ID][curr_app] + self.env['runtime']['OutputManager'].present_text( + _('Bookmark {0} removed for application {1}').format( + self.ID, curr_app), interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set for application {1}').format(self.ID, currApp), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('Bookmark {0} not set for application {1}').format( + self.ID, curr_app), interrupt=True) + + def set_callback(self, callback): pass # Factory function to create bookmark command instances + + def create_bookmark_commands(): """Create all bookmark command instances""" commands = {} - + # Create read bookmark commands (bookmark_1 through bookmark_10) for i in range(1, 11): - commands[f'bookmark_{i}'] = lambda i=i: BookmarkCommand(i, 'read') - + commands[f'bookmark_{i}'] = lambda i=i: bookmark_command(i, 'read') + # Create set bookmark commands (set_bookmark_1 through set_bookmark_10) for i in range(1, 11): - commands[f'set_bookmark_{i}'] = lambda i=i: BookmarkCommand(i, 'set') - - # Create clear bookmark commands (clear_bookmark_1 through clear_bookmark_10) + commands[f'set_bookmark_{i}'] = lambda i=i: bookmark_command(i, 'set') + + # Create clear bookmark commands (clear_bookmark_1 through + # clear_bookmark_10) for i in range(1, 11): - commands[f'clear_bookmark_{i}'] = lambda i=i: BookmarkCommand(i, 'clear') - + commands[f'clear_bookmark_{i}'] = lambda i=i: bookmark_command( + i, 'clear') + return commands # For backwards compatibility, provide individual command classes # This allows the existing command loading system to work unchanged + def _make_command_class(bookmark_id, action): """Create a command class for a specific bookmark and action""" - class command(BookmarkCommand): + class command(bookmark_command): def __init__(self): super().__init__(bookmark_id, action) return command @@ -137,14 +162,15 @@ def _make_command_class(bookmark_id, action): # Generate individual command classes for each bookmark operation # These will be used by the existing command loading system + # Read bookmarks (bookmark_1.py style) for i in range(1, 11): globals()[f'bookmark_{i}_command'] = _make_command_class(i, 'read') -# Set bookmarks (set_bookmark_1.py style) +# Set bookmarks (set_bookmark_1.py style) for i in range(1, 11): globals()[f'set_bookmark_{i}_command'] = _make_command_class(i, 'set') # Clear bookmarks (clear_bookmark_1.py style) for i in range(1, 11): - globals()[f'clear_bookmark_{i}_command'] = _make_command_class(i, 'clear') \ No newline at end of file + globals()[f'clear_bookmark_{i}_command'] = _make_command_class(i, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_1.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_1.py index 4bbd2977..6084acf2 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_1.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_1.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(1, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_10.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_10.py index 56642bec..a0413ce7 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_10.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_10.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(10, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_2.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_2.py index 11d4d4ac..cce212bb 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_2.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_2.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(2, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_3.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_3.py index 5b94bf72..1930aa0b 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_3.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_3.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(3, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_4.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_4.py index 6b970a83..6819c6e6 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_4.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_4.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(4, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_5.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_5.py index 2a6ad9c7..09adb82e 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_5.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_5.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(5, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_6.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_6.py index 15521a9d..a474ea8e 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_6.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_6.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(6, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_7.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_7.py index d318ab79..63362bf5 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_7.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_7.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(7, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_8.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_8.py index 867c337b..258d762e 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_8.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_8.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(8, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_bookmark_9.py b/src/fenrirscreenreader/commands/commands/clear_bookmark_9.py index b579d0cc..88ef6f49 100644 --- a/src/fenrirscreenreader/commands/commands/clear_bookmark_9.py +++ b/src/fenrirscreenreader/commands/commands/clear_bookmark_9.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(9, 'clear') diff --git a/src/fenrirscreenreader/commands/commands/clear_clipboard.py b/src/fenrirscreenreader/commands/commands/clear_clipboard.py index a8d6126f..60d475db 100644 --- a/src/fenrirscreenreader/commands/commands/clear_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/clear_clipboard.py @@ -5,19 +5,28 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('clears the currently selected clipboard') + pass + + def get_description(self): + return _('clears the currently selected clipboard') def run(self): - self.env['runtime']['memoryManager'].clearCurrentIndexList('clipboardHistory') - self.env['runtime']['outputManager'].presentText(_('clipboard cleared'), interrupt=True) - return - def setCallback(self, callback): + self.env['runtime']['MemoryManager'].clear_current_index_list( + 'clipboardHistory') + self.env['runtime']['OutputManager'].present_text( + _('clipboard cleared'), interrupt=True) + return + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/clear_window_application.py b/src/fenrirscreenreader/commands/commands/clear_window_application.py index 31e436eb..4ab4f2ab 100644 --- a/src/fenrirscreenreader/commands/commands/clear_window_application.py +++ b/src/fenrirscreenreader/commands/commands/clear_window_application.py @@ -5,22 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Turn off window mode for application') - - def run(self): - if self.env['runtime']['cursorManager'].clearWindowForApplication(): - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - self.env['runtime']['outputManager'].presentText(_('Window Mode off for application {0}').format(currApp,), interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("Not in window Mode"), interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('Turn off window mode for application') + + def run(self): + if self.env['runtime']['CursorManager'].clear_window_for_application(): + curr_app = self.env['runtime']['ApplicationManager'].get_current_application( + ) + self.env['runtime']['OutputManager'].present_text( + _('Window Mode off for application {0}').format( + curr_app,), interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("Not in window Mode"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py b/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py index f8b56722..d582a7dc 100644 --- a/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/copy_last_echo_to_clipboard.py @@ -4,24 +4,32 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('copies last presented text to the clipboard') - - def run(self): - lastEcho = self.env['runtime']['outputManager'].getLastEcho() - if lastEcho.rstrip() != "": - lastEcho = lastEcho.rstrip() - self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', lastEcho) - self.env['runtime']['outputManager'].presentText(lastEcho, soundIcon='CopyToClipboard', interrupt=True) - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('copies last presented text to the clipboard') + + def run(self): + last_echo = self.env['runtime']['OutputManager'].get_last_echo() + if last_echo.rstrip() != "": + last_echo = last_echo.rstrip() + self.env['runtime']['MemoryManager'].add_value_to_first_index( + 'clipboardHistory', last_echo) + self.env['runtime']['OutputManager'].present_text( + last_echo, sound_icon ='CopyToClipboard', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py b/src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py index 806aac3e..6dd5f648 100644 --- a/src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/copy_marked_to_clipboard.py @@ -2,72 +2,79 @@ # -*- coding: utf-8 -*- +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): - pass - - def getDescription(self): - return _('copies marked text to the currently selected clipboard') - - def getTextFromScreen(self, startMark, endMark): - screenContent = self.env['screen']['newContentText'] - screenLines = screenContent.split('\n') - - startY = min(startMark['y'], len(screenLines) - 1) - endY = min(endMark['y'], len(screenLines) - 1) - + pass + + def get_description(self): + return _('copies marked text to the currently selected clipboard') + + def get_text_from_screen(self, start_mark, end_mark): + screen_content = self.env['screen']['new_content_text'] + screen_lines = screen_content.split('\n') + + start_y = min(start_mark['y'], len(screen_lines) - 1) + end_y = min(end_mark['y'], len(screen_lines) - 1) + # If marks are on the same line - if startY == endY: - line = screenLines[startY] - startX = min(startMark['x'], len(line)) - endX = min(endMark['x'], len(line)) + 1 - return line[startX:endX] - + if start_y == end_y: + line = screen_lines[start_y] + start_x = min(start_mark['x'], len(line)) + end_x = min(end_mark['x'], len(line)) + 1 + return line[start_x:end_x] + # Handle multi-line selection result = [] - + # First line (from start mark to end of line) - firstLine = screenLines[startY] - startX = min(startMark['x'], len(firstLine)) - result.append(firstLine[startX:].rstrip()) - + first_line = screen_lines[start_y] + start_x = min(start_mark['x'], len(first_line)) + result.append(first_line[start_x:].rstrip()) + # Middle lines (complete lines) - for lineNum in range(startY + 1, endY): - result.append(screenLines[lineNum].rstrip()) - + for lineNum in range(start_y + 1, end_y): + result.append(screen_lines[lineNum].rstrip()) + # Last line (from start to end mark) - if endY > startY: - lastLine = screenLines[endY] - endX = min(endMark['x'], len(lastLine)) + 1 - result.append(lastLine[:endX].rstrip()) - + if end_y > start_y: + last_line = screen_lines[end_y] + end_x = min(end_mark['x'], len(last_line)) + 1 + result.append(last_line[:end_x].rstrip()) + return '\n'.join(result) - + def run(self): if not self.env['commandBuffer']['Marks']['1']: - self.env['runtime']['outputManager'].presentText(_("One or two marks are needed"), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("One or two marks are needed"), interrupt=True) return if not self.env['commandBuffer']['Marks']['2']: - self.env['runtime']['cursorManager'].setMark() - + self.env['runtime']['CursorManager'].set_mark() + # use the last first and the last setted mark as range - startMark = self.env['commandBuffer']['Marks']['1'].copy() - endMark = self.env['commandBuffer']['Marks']['2'].copy() - - # Replace mark_utils.getTextBetweenMarks with our new method - marked = self.getTextFromScreen(startMark, endMark) - - self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', marked) + start_mark = self.env['commandBuffer']['Marks']['1'].copy() + end_mark = self.env['commandBuffer']['Marks']['2'].copy() + + # Replace mark_utils.get_text_between_marks with our new method + marked = self.get_text_from_screen(start_mark, end_mark) + + self.env['runtime']['MemoryManager'].add_value_to_first_index( + 'clipboardHistory', marked) # reset marks - self.env['runtime']['cursorManager'].clearMarks() - self.env['runtime']['outputManager'].presentText(marked, soundIcon='CopyToClipboard', interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['CursorManager'].clear_marks() + self.env['runtime']['OutputManager'].present_text( + marked, sound_icon ='CopyToClipboard', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/curr_clipboard.py b/src/fenrirscreenreader/commands/commands/curr_clipboard.py index 0031f835..2a68c51c 100644 --- a/src/fenrirscreenreader/commands/commands/curr_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/curr_clipboard.py @@ -5,22 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('speaks the contents of the currently selected clipboard') + pass + + def get_description(self): + return _('speaks the contents of the currently selected clipboard') def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - self.env['runtime']['outputManager'].presentText(clipboard , interrupt=True) - - def setCallback(self, callback): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + self.env['runtime']['OutputManager'].present_text( + clipboard, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/curr_screen.py b/src/fenrirscreenreader/commands/commands/curr_screen.py index de87910b..fa223ec1 100644 --- a/src/fenrirscreenreader/commands/commands/curr_screen.py +++ b/src/fenrirscreenreader/commands/commands/curr_screen.py @@ -5,21 +5,29 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('reads the contents of the current screen') + pass + + def get_description(self): + return _('reads the contents of the current screen') def run(self): - if self.env['screen']['newContentText'].isspace(): - self.env['runtime']['outputManager'].presentText(_("screen is empty"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'],interrupt=True) - - def setCallback(self, callback): + if self.env['screen']['new_content_text'].isspace(): + self.env['runtime']['OutputManager'].present_text( + _("screen is empty"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + self.env['screen']['new_content_text'], interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py b/src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py index 6269458a..b570e188 100644 --- a/src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py +++ b/src/fenrirscreenreader/commands/commands/curr_screen_after_cursor.py @@ -4,28 +4,37 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('reads from the cursor to the bottom of the screen') + pass + + def get_description(self): + return _('reads from the cursor to the bottom of the screen') def run(self): # Prefer review cursor over text cursor - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() - textAfterCursor = mark_utils.getTextAfterMark(cursorPos, self.env['screen']['newContentText']) + text_after_cursor = mark_utils.get_text_after_mark( + cursor_pos, self.env['screen']['new_content_text']) - if textAfterCursor.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) + if text_after_cursor.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) else: - self.env['runtime']['outputManager'].presentText(textAfterCursor, interrupt=True) + self.env['runtime']['OutputManager'].present_text( + text_after_cursor, interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py b/src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py index 7d0afbfc..de16fa4d 100644 --- a/src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py +++ b/src/fenrirscreenreader/commands/commands/curr_screen_before_cursor.py @@ -4,32 +4,40 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Reads from the top of the screen to the cursor position') + pass + + def get_description(self): + return _('Reads from the top of the screen to the cursor position') def run(self): # Prefer review cursor over text cursor if self.env['screen']['newCursorReview']: - cursorPos = self.env['screen']['newCursorReview'].copy() + cursor_pos = self.env['screen']['newCursorReview'].copy() else: - cursorPos = self.env['screen']['newCursor'].copy() + cursor_pos = self.env['screen']['new_cursor'].copy() - textBeforeCursor = mark_utils.getTextBeforeMark(cursorPos, self.env['screen']['newContentText']) + text_before_cursor = mark_utils.get_text_before_mark( + cursor_pos, self.env['screen']['new_content_text']) - if textBeforeCursor.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) + if text_before_cursor.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) else: - self.env['runtime']['outputManager'].presentText(textBeforeCursor, interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + text_before_cursor, interrupt=True) + + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py index a89ce3ee..960f3026 100644 --- a/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/commands/current_quick_menu_entry.py @@ -5,21 +5,30 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get current quick menu entry') + def run(self): menu = '' value = '' - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) - def setCallback(self, callback): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py index 6522e080..fc693ca5 100644 --- a/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/commands/current_quick_menu_value.py @@ -5,17 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get current quick menu value') - def run(self): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get current quick menu value') + + def run(self): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text(value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/cursor_column.py b/src/fenrirscreenreader/commands/commands/cursor_column.py index f6a9bb82..862464c6 100644 --- a/src/fenrirscreenreader/commands/commands/cursor_column.py +++ b/src/fenrirscreenreader/commands/commands/cursor_column.py @@ -5,20 +5,29 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return _('Column number for cursor') + + def get_description(self): + return _('Column number for cursor') + def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['outputManager'].presentText(str(cursorPos['x'] + 1) , interrupt=True) - self.env['runtime']['outputManager'].announceActiveCursor() - self.env['runtime']['outputManager'].presentText(' column number' , interrupt=False) - - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['OutputManager'].present_text( + str(cursor_pos['x'] + 1), interrupt=True) + self.env['runtime']['OutputManager'].announce_active_cursor() + self.env['runtime']['OutputManager'].present_text( + ' column number', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/cursor_lineno.py b/src/fenrirscreenreader/commands/commands/cursor_lineno.py index 938c1356..b921a531 100644 --- a/src/fenrirscreenreader/commands/commands/cursor_lineno.py +++ b/src/fenrirscreenreader/commands/commands/cursor_lineno.py @@ -5,20 +5,29 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return _('Line number for cursor') + + def get_description(self): + return _('Line number for cursor') + def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['outputManager'].presentText(str(cursorPos['y'] + 1), interrupt=True) - self.env['runtime']['outputManager'].announceActiveCursor() - self.env['runtime']['outputManager'].presentText(' line number' , interrupt=False) - - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['OutputManager'].present_text( + str(cursor_pos['y'] + 1), interrupt=True) + self.env['runtime']['OutputManager'].announce_active_cursor() + self.env['runtime']['OutputManager'].present_text( + ' line number', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/cursor_position.py b/src/fenrirscreenreader/commands/commands/cursor_position.py index c00cf38d..c0e5a59d 100644 --- a/src/fenrirscreenreader/commands/commands/cursor_position.py +++ b/src/fenrirscreenreader/commands/commands/cursor_position.py @@ -5,21 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('displays the position of the review cursor') + pass + + def get_description(self): + return _('displays the position of the review cursor') def run(self): # Prefer review cursor over text cursor - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() - self.env['runtime']['outputManager'].presentText(_("line {0}, column {1}, Terminal {2}").format(cursorPos['y']+1, cursorPos['x']+1, self.env['screen']['newTTY']), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("line {0}, column {1}, Terminal {2}").format( + cursor_pos['y'] + 1, + cursor_pos['x'] + 1, + self.env['screen']['newTTY']), + interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/cursor_read_line_to_cursor.py b/src/fenrirscreenreader/commands/commands/cursor_read_line_to_cursor.py index 80fd8d86..9c9961a2 100644 --- a/src/fenrirscreenreader/commands/commands/cursor_read_line_to_cursor.py +++ b/src/fenrirscreenreader/commands/commands/cursor_read_line_to_cursor.py @@ -4,29 +4,38 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('read line to cursor pos, use review cursor if you are in review mode, otherwhise use text cursor') - - def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - x, y, currLine = \ - line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) - - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(currLine[:cursorPos['x']], interrupt=True) - self.env['runtime']['outputManager'].announceActiveCursor() - def setCallback(self, callback): + def shutdown(self): pass + def get_description(self): + return _( + 'read line to cursor pos, use review cursor if you are in review mode, otherwhise use text cursor') + + def run(self): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + + x, y, curr_line = line_utils.get_current_line( + cursor_pos['x'], cursor_pos['y'], self.env['screen']['new_content_text']) + + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + curr_line[:cursor_pos['x']], interrupt=True) + self.env['runtime']['OutputManager'].announce_active_cursor() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py b/src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py index 5f8b32f6..fb124a37 100644 --- a/src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py +++ b/src/fenrirscreenreader/commands/commands/cursor_read_to_end_of_line.py @@ -4,29 +4,38 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('read to end of line, use review cursor if you are in review mode, otherwhise use text cursor') - - def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - x, y, currLine = \ - line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) - - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(currLine[cursorPos['x']:], interrupt=True) - self.env['runtime']['outputManager'].announceActiveCursor() - def setCallback(self, callback): + def shutdown(self): pass + def get_description(self): + return _( + 'read to end of line, use review cursor if you are in review mode, otherwhise use text cursor') + + def run(self): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + + x, y, curr_line = line_utils.get_current_line( + cursor_pos['x'], cursor_pos['y'], self.env['screen']['new_content_text']) + + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + curr_line[cursor_pos['x']:], interrupt=True) + self.env['runtime']['OutputManager'].announce_active_cursor() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/cycle_keyboard_layout.py b/src/fenrirscreenreader/commands/commands/cycle_keyboard_layout.py index 7f7f977b..49871b43 100644 --- a/src/fenrirscreenreader/commands/commands/cycle_keyboard_layout.py +++ b/src/fenrirscreenreader/commands/commands/cycle_keyboard_layout.py @@ -4,58 +4,67 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import debug import os + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('cycles between available keyboard layouts') - - def getAvailableLayouts(self): + + def get_available_layouts(self): """Get list of available keyboard layout files""" layouts = [] - + # Check standard locations for keyboard layouts - settingsRoot = '/etc/fenrirscreenreader/' - if not os.path.exists(settingsRoot): + settings_root = '/etc/fenrirscreenreader/' + if not os.path.exists(settings_root): # Fallback to source directory import fenrirscreenreader - fenrirPath = os.path.dirname(fenrirscreenreader.__file__) - settingsRoot = fenrirPath + '/../../config/' - - keyboardPath = settingsRoot + 'keyboard/' - - if os.path.exists(keyboardPath): - for file in os.listdir(keyboardPath): - if file.endswith('.conf') and not file.startswith('__') and not file.lower().startswith('pty'): + fenrir_path = os.path.dirname(fenrirscreenreader.__file__) + settings_root = fenrir_path + '/../../config/' + + keyboard_path = settings_root + 'keyboard/' + + if os.path.exists(keyboard_path): + for file in os.listdir(keyboard_path): + if file.endswith('.conf') and not file.startswith( + '__') and not file.lower().startswith('pty'): layout_name = file.replace('.conf', '') if layout_name not in layouts: layouts.append(layout_name) - + # Ensure we have at least basic layouts if not layouts: layouts = ['desktop', 'laptop'] else: layouts.sort() - + return layouts - + def run(self): - current_layout = self.env['runtime']['settingsManager'].getSetting('keyboard', 'keyboardLayout') - + current_layout = self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'keyboardLayout') + # Extract layout name from full path if needed if '/' in current_layout: - current_layout = os.path.basename(current_layout).replace('.conf', '') - + current_layout = os.path.basename( + current_layout).replace('.conf', '') + # Get available layouts - available_layouts = self.getAvailableLayouts() - + available_layouts = self.get_available_layouts() + # Find next layout in cycle try: current_index = available_layouts.index(current_layout) @@ -63,28 +72,29 @@ class command(): except ValueError: # If current layout not found, start from beginning next_index = 0 - + next_layout = available_layouts[next_index] - + # Update setting and reload shortcuts - self.env['runtime']['settingsManager'].setSetting('keyboard', 'keyboardLayout', next_layout) - + self.env['runtime']['SettingsManager'].set_setting( + 'keyboard', 'keyboardLayout', next_layout) + # Reload shortcuts with new layout try: - self.env['runtime']['inputManager'].reloadShortcuts() - self.env['runtime']['outputManager'].presentText( - _('Switched to {} keyboard layout').format(next_layout), + self.env['runtime']['InputManager'].reload_shortcuts() + self.env['runtime']['OutputManager'].present_text( + _('Switched to {} keyboard layout').format(next_layout), interrupt=True ) except Exception as e: - self.env['runtime']['debug'].writeDebugOut( - "Error reloading shortcuts: " + str(e), - debug.debugLevel.ERROR + self.env['runtime']['DebugManager'].write_debug_out( + "Error reloading shortcuts: " + str(e), + debug.DebugLevel.ERROR ) - self.env['runtime']['outputManager'].presentText( - _('Error switching keyboard layout'), + self.env['runtime']['OutputManager'].present_text( + _('Error switching keyboard layout'), interrupt=True ) - def setCallback(self, callback): - pass \ No newline at end of file + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/date.py b/src/fenrirscreenreader/commands/commands/date.py index 7a95ca1c..8e4ff2a1 100644 --- a/src/fenrirscreenreader/commands/commands/date.py +++ b/src/fenrirscreenreader/commands/commands/date.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the date') - + pass + + def get_description(self): + return _('presents the date') + def run(self): - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') # get the time formatted - dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) + date_string = datetime.datetime.strftime( + datetime.datetime.now(), date_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/dec_alsa_volume.py b/src/fenrirscreenreader/commands/commands/dec_alsa_volume.py index 59cf13fe..39be219d 100644 --- a/src/fenrirscreenreader/commands/commands/dec_alsa_volume.py +++ b/src/fenrirscreenreader/commands/commands/dec_alsa_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('alsa', 'volume', 'dec') diff --git a/src/fenrirscreenreader/commands/commands/dec_sound_volume.py b/src/fenrirscreenreader/commands/commands/dec_sound_volume.py index 4b36bf11..26d89beb 100644 --- a/src/fenrirscreenreader/commands/commands/dec_sound_volume.py +++ b/src/fenrirscreenreader/commands/commands/dec_sound_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('sound', 'volume', 'dec') diff --git a/src/fenrirscreenreader/commands/commands/dec_speech_pitch.py b/src/fenrirscreenreader/commands/commands/dec_speech_pitch.py index 02cf36e8..72715954 100644 --- a/src/fenrirscreenreader/commands/commands/dec_speech_pitch.py +++ b/src/fenrirscreenreader/commands/commands/dec_speech_pitch.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'pitch', 'dec') diff --git a/src/fenrirscreenreader/commands/commands/dec_speech_rate.py b/src/fenrirscreenreader/commands/commands/dec_speech_rate.py index 82b54982..6f3578d0 100644 --- a/src/fenrirscreenreader/commands/commands/dec_speech_rate.py +++ b/src/fenrirscreenreader/commands/commands/dec_speech_rate.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'rate', 'dec') diff --git a/src/fenrirscreenreader/commands/commands/dec_speech_volume.py b/src/fenrirscreenreader/commands/commands/dec_speech_volume.py index f3d48afc..32eec03d 100644 --- a/src/fenrirscreenreader/commands/commands/dec_speech_volume.py +++ b/src/fenrirscreenreader/commands/commands/dec_speech_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'volume', 'dec') diff --git a/src/fenrirscreenreader/commands/commands/exit_review.py b/src/fenrirscreenreader/commands/commands/exit_review.py index 86ddf87d..3ff1b751 100644 --- a/src/fenrirscreenreader/commands/commands/exit_review.py +++ b/src/fenrirscreenreader/commands/commands/exit_review.py @@ -5,23 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('exits review mode') - - def run(self): - if not self.env['runtime']['cursorManager'].isReviewMode(): - self.env['runtime']['outputManager'].presentText(_("Not in Review Mode"), interrupt=True) - return - self.env['runtime']['cursorManager'].clearReviewCursor() - self.env['runtime']['outputManager'].presentText(_("Exiting Review Mode"), interrupt=True) - - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('exits review mode') + + def run(self): + if not self.env['runtime']['CursorManager'].is_review_mode(): + self.env['runtime']['OutputManager'].present_text( + _("Not in Review Mode"), interrupt=True) + return + + self.env['runtime']['CursorManager'].clear_review_cursor() + self.env['runtime']['OutputManager'].present_text( + _("Exiting Review Mode"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py b/src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py index a818acd2..90223f60 100644 --- a/src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py +++ b/src/fenrirscreenreader/commands/commands/export_clipboard_to_file.py @@ -4,36 +4,55 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import debug import os + class command(): def __init__(self): pass - def initialize(self, environment, scriptPath=''): + + def initialize(self, environment, script_path=''): self.env = environment def shutdown(self): pass - def getDescription(self): + + def get_description(self): return _('export the current fenrir clipboard to a file') - def run(self): - clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath') - clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser']) - clipboardFile = open(clipboardFilePath,'w') + + def run(self): + clipboard_file_path = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'clipboardExportPath') + clipboard_file_path = clipboard_file_path.replace( + '$user', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$USER', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$User', self.env['general']['curr_user']) + clipboard_file = open(clipboard_file_path, 'w') try: - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - clipboardFile.write(clipboard) - clipboardFile.close() - os.chmod(clipboardFilePath, 0o644) - self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True) + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + clipboard_file.write(clipboard) + clipboard_file.close() + os.chmod(clipboard_file_path, 0o644) + self.env['runtime']['OutputManager'].present_text( + _('clipboard exported to file'), interrupt=True) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR) - - def setCallback(self, callback): + self.env['runtime']['DebugManager'].write_debug_out( + 'export_clipboard_to_file:run: Filepath:' + + clipboard_file + + ' trace:' + + str(e), + debug.DebugLevel.ERROR) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py b/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py index 6d460d5c..b10b0405 100644 --- a/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py +++ b/src/fenrirscreenreader/commands/commands/export_clipboard_to_x.py @@ -4,37 +4,48 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib import _thread import pyperclip + class command(): def __init__(self): pass - def initialize(self, environment, scriptPath=''): + + def initialize(self, environment, script_path=''): self.env = environment - self.scriptPath = scriptPath + self.script_path = script_path + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return _('Export current fenrir clipboard to X or GUI clipboard') - def run(self): - _thread.start_new_thread(self._threadRun , ()) - def _threadRun(self): + + def run(self): + _thread.start_new_thread(self._thread_run, ()) + + def _thread_run(self): try: # Check if clipboard is empty - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) return - + # Get current clipboard content - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + # Remember original display environment variable if it exists - originalDisplay = os.environ.get('DISPLAY', '') + original_display = os.environ.get('DISPLAY', '') success = False - + # Try different display options for i in range(10): display = f":{i}" @@ -42,29 +53,34 @@ class command(): # Set display environment variable os.environ['DISPLAY'] = display # Attempt to set clipboard content - importlib.reload(pyperclip) # Weird workaround for some distros + # Weird workaround for some distros + importlib.reload(pyperclip) pyperclip.copy(clipboard) - # If we get here without exception, we found a working display + # If we get here without exception, we found a working + # display success = True break except Exception: # Failed for this display, try next one continue - + # Restore original display setting - if originalDisplay: - os.environ['DISPLAY'] = originalDisplay + if original_display: + os.environ['DISPLAY'] = original_display else: os.environ.pop('DISPLAY', None) - + # Notify the user of the result if success: - self.env['runtime']['outputManager'].presentText(_('exported to the X session.'), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _('exported to the X session.'), interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('failed to export to X clipboard. No available display found.'), interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + _('failed to export to X clipboard. No available display found.'), interrupt=True) + except Exception as e: - self.env['runtime']['outputManager'].presentText(str(e), soundIcon='', interrupt=False) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + str(e), sound_icon ='', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/first_clipboard.py b/src/fenrirscreenreader/commands/commands/first_clipboard.py index c2bc287a..edb6307c 100644 --- a/src/fenrirscreenreader/commands/commands/first_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/first_clipboard.py @@ -5,23 +5,33 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('selects the first clipboard') - - def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - self.env['runtime']['memoryManager'].setFirstIndex('clipboardHistory') - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - self.env['runtime']['outputManager'].presentText(clipboard, interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('selects the first clipboard') + + def run(self): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + self.env['runtime']['MemoryManager'].set_first_index('clipboardHistory') + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + self.env['runtime']['OutputManager'].present_text( + clipboard, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/forward_keypress.py b/src/fenrirscreenreader/commands/commands/forward_keypress.py index 4c50bc61..253f1868 100644 --- a/src/fenrirscreenreader/commands/commands/forward_keypress.py +++ b/src/fenrirscreenreader/commands/commands/forward_keypress.py @@ -5,19 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('sends the following keypress to the terminal or application') - + pass + + def get_description(self): + return _('sends the following keypress to the terminal or application') + def run(self): self.env['input']['keyForeward'] = 3 - self.env['runtime']['outputManager'].presentText(_('Forward next keypress'), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _('Forward next keypress'), interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py b/src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py index 0446cb4b..72dceee0 100644 --- a/src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py +++ b/src/fenrirscreenreader/commands/commands/import_clipboard_from_file.py @@ -4,35 +4,48 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils import os + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('imports text from clipboard file to the clipboard') - - def run(self): - clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath') - clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser']) - if not os.path.exists(clipboardFilePath): - self.env['runtime']['outputManager'].presentText(_('File does not exist'), soundIcon='', interrupt=True) - return - clipboardFile = open(clipboardFilePath,'r') - imported = clipboardFile.read() - clipboardFile.close() - self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', imported) - - self.env['runtime']['outputManager'].presentText('Import to Clipboard', soundIcon='CopyToClipboard', interrupt=True) - self.env['runtime']['outputManager'].presentText(imported, soundIcon='', interrupt=False) - - - def setCallback(self, callback): + pass + + def get_description(self): + return _('imports text from clipboard file to the clipboard') + + def run(self): + clipboard_file_path = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'clipboardExportPath') + clipboard_file_path = clipboard_file_path.replace( + '$user', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$USER', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$User', self.env['general']['curr_user']) + if not os.path.exists(clipboard_file_path): + self.env['runtime']['OutputManager'].present_text( + _('File does not exist'), sound_icon ='', interrupt=True) + return + clipboard_file = open(clipboard_file_path, 'r') + imported = clipboard_file.read() + clipboard_file.close() + self.env['runtime']['MemoryManager'].add_value_to_first_index( + 'clipboardHistory', imported) + + self.env['runtime']['OutputManager'].present_text( + 'Import to Clipboard', sound_icon ='CopyToClipboard', interrupt=True) + self.env['runtime']['OutputManager'].present_text( + imported, sound_icon ='', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/import_clipboard_from_x.py b/src/fenrirscreenreader/commands/commands/import_clipboard_from_x.py index b5ea5222..5a9ad4bb 100644 --- a/src/fenrirscreenreader/commands/commands/import_clipboard_from_x.py +++ b/src/fenrirscreenreader/commands/commands/import_clipboard_from_x.py @@ -4,29 +4,37 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib import _thread import pyperclip import os + class command(): def __init__(self): pass - def initialize(self, environment, scriptPath=''): + + def initialize(self, environment, script_path=''): self.env = environment - self.scriptPath = scriptPath + self.script_path = script_path + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return _("imports the graphical clipboard to Fenrir's clipboard") - def run(self): - _thread.start_new_thread(self._threadRun , ()) - def _threadRun(self): + + def run(self): + _thread.start_new_thread(self._thread_run, ()) + + def _thread_run(self): try: # Remember original display environment variable if it exists - originalDisplay = os.environ.get('DISPLAY', '') - clipboardContent = None - + original_display = os.environ.get('DISPLAY', '') + clipboard_content = None + # Try different display options for i in range(10): display = f":{i}" @@ -34,30 +42,37 @@ class command(): # Set display environment variable os.environ['DISPLAY'] = display # Attempt to get clipboard content - importlib.reload(pyperclip) # Weird workaround for some distros - clipboardContent = pyperclip.paste() - # If we get here without exception, we found a working display - if clipboardContent: + # Weird workaround for some distros + importlib.reload(pyperclip) + clipboard_content = pyperclip.paste() + # If we get here without exception, we found a working + # display + if clipboard_content: break except Exception: # Failed for this display, try next one continue - + # Restore original display setting - if originalDisplay: - os.environ['DISPLAY'] = originalDisplay + if original_display: + os.environ['DISPLAY'] = original_display else: os.environ.pop('DISPLAY', None) - + # Process the clipboard content if we found any - if clipboardContent and isinstance(clipboardContent, str): - self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', clipboardContent) - self.env['runtime']['outputManager'].presentText('Import to Clipboard', soundIcon='CopyToClipboard', interrupt=True) - self.env['runtime']['outputManager'].presentText(clipboardContent, soundIcon='', interrupt=False) + if clipboard_content and isinstance(clipboard_content, str): + self.env['runtime']['MemoryManager'].add_value_to_first_index( + 'clipboardHistory', clipboard_content) + self.env['runtime']['OutputManager'].present_text( + 'Import to Clipboard', sound_icon ='CopyToClipboard', interrupt=True) + self.env['runtime']['OutputManager'].present_text( + clipboard_content, sound_icon ='', interrupt=False) else: - self.env['runtime']['outputManager'].presentText('No text found in clipboard or no accessible display', interrupt=True) + self.env['runtime']['OutputManager'].present_text( + 'No text found in clipboard or no accessible display', interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(str(e), soundIcon='', interrupt=False) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + str(e), sound_icon ='', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/inc_alsa_volume.py b/src/fenrirscreenreader/commands/commands/inc_alsa_volume.py index ba3f4086..fdf7d8ef 100644 --- a/src/fenrirscreenreader/commands/commands/inc_alsa_volume.py +++ b/src/fenrirscreenreader/commands/commands/inc_alsa_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('alsa', 'volume', 'inc') diff --git a/src/fenrirscreenreader/commands/commands/inc_sound_volume.py b/src/fenrirscreenreader/commands/commands/inc_sound_volume.py index 67bd8d55..73df4092 100644 --- a/src/fenrirscreenreader/commands/commands/inc_sound_volume.py +++ b/src/fenrirscreenreader/commands/commands/inc_sound_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('sound', 'volume', 'inc') diff --git a/src/fenrirscreenreader/commands/commands/inc_speech_pitch.py b/src/fenrirscreenreader/commands/commands/inc_speech_pitch.py index a4d9c09f..9d766041 100644 --- a/src/fenrirscreenreader/commands/commands/inc_speech_pitch.py +++ b/src/fenrirscreenreader/commands/commands/inc_speech_pitch.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'pitch', 'inc') diff --git a/src/fenrirscreenreader/commands/commands/inc_speech_rate.py b/src/fenrirscreenreader/commands/commands/inc_speech_rate.py index b91fd1cd..841bcffb 100644 --- a/src/fenrirscreenreader/commands/commands/inc_speech_rate.py +++ b/src/fenrirscreenreader/commands/commands/inc_speech_rate.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'rate', 'inc') diff --git a/src/fenrirscreenreader/commands/commands/inc_speech_volume.py b/src/fenrirscreenreader/commands/commands/inc_speech_volume.py index bb88059d..aaaef24b 100644 --- a/src/fenrirscreenreader/commands/commands/inc_speech_volume.py +++ b/src/fenrirscreenreader/commands/commands/inc_speech_volume.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'adjustment_base.py') _spec = importlib.util.spec_from_file_location("adjustment_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -AdjustmentCommand = _module.AdjustmentCommand +adjustment_command = _module.adjustment_command -class command(AdjustmentCommand): + +class command(adjustment_command): def __init__(self): super().__init__('speech', 'volume', 'inc') diff --git a/src/fenrirscreenreader/commands/commands/indent_curr_line.py b/src/fenrirscreenreader/commands/commands/indent_curr_line.py index 68c12760..663e5778 100644 --- a/src/fenrirscreenreader/commands/commands/indent_curr_line.py +++ b/src/fenrirscreenreader/commands/commands/indent_curr_line.py @@ -4,32 +4,40 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Presents the indentation level for the current line') + pass + + def get_description(self): + return _('Presents the indentation level for the current line') def run(self): # Prefer review cursor over text cursor if self.env['screen']['newCursorReview']: - cursorPos = self.env['screen']['newCursorReview'].copy() + cursor_pos = self.env['screen']['newCursorReview'].copy() else: - cursorPos = self.env['screen']['newCursor'].copy() - x, y, currLine = \ - line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) - - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("indent {0}").format(len(currLine) - len(currLine.lstrip())), interrupt=True) + cursor_pos = self.env['screen']['new_cursor'].copy() + x, y, curr_line = line_utils.get_current_line( + cursor_pos['x'], cursor_pos['y'], self.env['screen']['new_content_text']) - def setCallback(self, callback): + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text(_("indent {0}").format( + len(curr_line) - len(curr_line.lstrip())), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/last_clipboard.py b/src/fenrirscreenreader/commands/commands/last_clipboard.py index e09d7fe8..0821c52a 100644 --- a/src/fenrirscreenreader/commands/commands/last_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/last_clipboard.py @@ -5,23 +5,33 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('selects the last clipboard') - - def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - self.env['runtime']['memoryManager'].setLastIndex('clipboardHistory') - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - self.env['runtime']['outputManager'].presentText(clipboard, interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('selects the last clipboard') + + def run(self): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + self.env['runtime']['MemoryManager'].set_last_index('clipboardHistory') + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + self.env['runtime']['OutputManager'].present_text( + clipboard, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/marked_text.py b/src/fenrirscreenreader/commands/commands/marked_text.py index 3bf3f094..678e7a58 100644 --- a/src/fenrirscreenreader/commands/commands/marked_text.py +++ b/src/fenrirscreenreader/commands/commands/marked_text.py @@ -4,34 +4,45 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import mark_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Presents the currently selected text that will be copied to the clipboard') - + pass + + def get_description(self): + return _( + 'Presents the currently selected text that will be copied to the clipboard') + def run(self): - if not (self.env['commandBuffer']['Marks']['1'] and \ - self.env['commandBuffer']['Marks']['2']): - self.env['runtime']['outputManager'].presentText(_("please set begin and endmark"), interrupt=True) + if not (self.env['commandBuffer']['Marks']['1'] and + self.env['commandBuffer']['Marks']['2']): + self.env['runtime']['OutputManager'].present_text( + _("please set begin and endmark"), interrupt=True) return # use the last first and the last setted mark as range - startMark = self.env['commandBuffer']['Marks']['1'].copy() - endMark = self.env['commandBuffer']['Marks']['2'].copy() + start_mark = self.env['commandBuffer']['Marks']['1'].copy() + end_mark = self.env['commandBuffer']['Marks']['2'].copy() - marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText']) + marked = mark_utils.get_text_between_marks( + start_mark, end_mark, self.env['screen']['new_content_text']) if marked.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) else: - self.env['runtime']['outputManager'].presentText(marked, interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + marked, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/next_clipboard.py b/src/fenrirscreenreader/commands/commands/next_clipboard.py index 7364f62d..8257bcea 100644 --- a/src/fenrirscreenreader/commands/commands/next_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/next_clipboard.py @@ -5,31 +5,45 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('selects the next clipboard') - - def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - self.env['runtime']['memoryManager'].getNextIndex('clipboardHistory') - isFirst = self.env['runtime']['memoryManager'].isFirstIndex('clipboardHistory') - isLast = self.env['runtime']['memoryManager'].isLastIndex('clipboardHistory') - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - if isFirst: - self.env['runtime']['outputManager'].presentText(_('First clipboard '), interrupt=True) - if isLast: - self.env['runtime']['outputManager'].presentText(_('Last clipboard '), interrupt=True) - - speechInterrupt = not(isLast or isFirst) - self.env['runtime']['outputManager'].presentText(clipboard, interrupt = speechInterrupt) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('selects the next clipboard') + + def run(self): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + self.env['runtime']['MemoryManager'].get_next_index('clipboardHistory') + is_first = self.env['runtime']['MemoryManager'].is_first_index( + 'clipboardHistory') + is_last = self.env['runtime']['MemoryManager'].is_last_index( + 'clipboardHistory') + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + if is_first: + self.env['runtime']['OutputManager'].present_text( + _('First clipboard '), interrupt=True) + if is_last: + self.env['runtime']['OutputManager'].present_text( + _('Last clipboard '), interrupt=True) + + speech_interrupt = not (is_last or is_first) + self.env['runtime']['OutputManager'].present_text( + clipboard, interrupt=speech_interrupt) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py index 1d2a5fb1..c99fd2a7 100644 --- a/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/commands/next_quick_menu_entry.py @@ -5,24 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get next quick menu entry') + def run(self): menu = '' value = '' - if self.env['runtime']['quickMenuManager'].nextEntry(): - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + if self.env['runtime']['QuickMenuManager'].next_entry(): + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('Quick menu not available'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py index 78a0f9ad..11b4f312 100644 --- a/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/commands/next_quick_menu_value.py @@ -5,18 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get next quick menu value') - def run(self): - if self.env['runtime']['quickMenuManager'].nextValue(): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get next quick menu value') + + def run(self): + if self.env['runtime']['QuickMenuManager'].next_value(): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/paste_clipboard.py b/src/fenrirscreenreader/commands/commands/paste_clipboard.py index 565ffc25..9a5b28f9 100644 --- a/src/fenrirscreenreader/commands/commands/paste_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/paste_clipboard.py @@ -4,26 +4,38 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import time + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.env['runtime']['memoryManager'].addIndexList('clipboardHistory', self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards')) + self.env['runtime']['MemoryManager'].add_index_list( + 'clipboardHistory', self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'numberOfClipboards')) + def shutdown(self): - pass - def getDescription(self): - return _('pastes the text from the currently selected clipboard') - - def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - self.env['runtime']['outputManager'].presentText('paste clipboard', soundIcon='PasteClipboardOnScreen', interrupt=True) - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - self.env['runtime']['screenManager'].injectTextToScreen(clipboard) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('pastes the text from the currently selected clipboard') + + def run(self): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + self.env['runtime']['OutputManager'].present_text( + 'paste clipboard', sound_icon ='PasteClipboardOnScreen', interrupt=True) + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + self.env['runtime']['ScreenManager'].inject_text_to_screen(clipboard) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/present_first_line.py b/src/fenrirscreenreader/commands/commands/present_first_line.py index 3a901204..4bb2f3b1 100644 --- a/src/fenrirscreenreader/commands/commands/present_first_line.py +++ b/src/fenrirscreenreader/commands/commands/present_first_line.py @@ -4,26 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('present first line') - - def run(self): - x, y, firstLine = \ - line_utils.getCurrentLine(0, 0, self.env['screen']['newContentText']) - - if firstLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(firstLine, interrupt=True) - def setCallback(self, callback): pass + def get_description(self): + return _('present first line') + + def run(self): + x, y, first_line = line_utils.get_current_line( + 0, 0, self.env['screen']['new_content_text']) + + if first_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + first_line, interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/present_last_line.py b/src/fenrirscreenreader/commands/commands/present_last_line.py index 274eb721..0cccd403 100644 --- a/src/fenrirscreenreader/commands/commands/present_last_line.py +++ b/src/fenrirscreenreader/commands/commands/present_last_line.py @@ -4,26 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('current line') - - def run(self): - x, y, lastLine = \ - line_utils.getCurrentLine(0, self.env['screen']['lines'] -1, self.env['screen']['newContentText']) - if lastLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(lastLine, interrupt=True) - def setCallback(self, callback): + def shutdown(self): pass + def get_description(self): + return _('current line') + + def run(self): + x, y, last_line = line_utils.get_current_line( + 0, self.env['screen']['lines'] - 1, self.env['screen']['new_content_text']) + + if last_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + last_line, interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/prev_clipboard.py b/src/fenrirscreenreader/commands/commands/prev_clipboard.py index 95bca467..3f03f3ea 100644 --- a/src/fenrirscreenreader/commands/commands/prev_clipboard.py +++ b/src/fenrirscreenreader/commands/commands/prev_clipboard.py @@ -5,30 +5,44 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('selects the previous clipboard') + pass + + def get_description(self): + return _('selects the previous clipboard') def run(self): - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - self.env['runtime']['memoryManager'].setPrefIndex('clipboardHistory') - isFirst = self.env['runtime']['memoryManager'].isFirstIndex('clipboardHistory') - isLast = self.env['runtime']['memoryManager'].isLastIndex('clipboardHistory') - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') - if isFirst: - self.env['runtime']['outputManager'].presentText(_('First clipboard '), interrupt=True) - if isLast: - self.env['runtime']['outputManager'].presentText(_('Last clipboard '), interrupt=True) - speechInterrupt = not(isLast or isFirst) - self.env['runtime']['outputManager'].presentText(clipboard, interrupt = speechInterrupt) - - def setCallback(self, callback): + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + self.env['runtime']['MemoryManager'].set_pref_index('clipboardHistory') + is_first = self.env['runtime']['MemoryManager'].is_first_index( + 'clipboardHistory') + is_last = self.env['runtime']['MemoryManager'].is_last_index( + 'clipboardHistory') + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') + if is_first: + self.env['runtime']['OutputManager'].present_text( + _('First clipboard '), interrupt=True) + if is_last: + self.env['runtime']['OutputManager'].present_text( + _('Last clipboard '), interrupt=True) + speech_interrupt = not (is_last or is_first) + self.env['runtime']['OutputManager'].present_text( + clipboard, interrupt=speech_interrupt) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py b/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py index 87aef5df..160f0de2 100644 --- a/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/commands/prev_quick_menu_entry.py @@ -5,24 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get previous quick menu entry') + def run(self): menu = '' value = '' - if self.env['runtime']['quickMenuManager'].prevEntry(): - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + if self.env['runtime']['QuickMenuManager'].prev_entry(): + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('Quick menu not available'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py b/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py index bfa7e8cb..99b2dbfe 100644 --- a/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/commands/prev_quick_menu_value.py @@ -5,18 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get previous quick menu value') - def run(self): - if self.env['runtime']['quickMenuManager'].prevValue(): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get previous quick menu value') + + def run(self): + if self.env['runtime']['QuickMenuManager'].prev_value(): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/progress_bar_monitor.py b/src/fenrirscreenreader/commands/commands/progress_bar_monitor.py index d9583c24..35ba95f9 100644 --- a/src/fenrirscreenreader/commands/commands/progress_bar_monitor.py +++ b/src/fenrirscreenreader/commands/commands/progress_bar_monitor.py @@ -4,206 +4,232 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import re import time import threading + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment # Use commandBuffer like other commands if 'progressMonitoring' not in self.env['commandBuffer']: - # Check if progress monitoring should be enabled by default from settings + # Check if progress monitoring should be enabled by default from + # settings try: - defaultEnabled = self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'progressMonitoring') + default_enabled = self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'progressMonitoring') except Exception as e: # If setting doesn't exist, default to False - defaultEnabled = False - self.env['commandBuffer']['progressMonitoring'] = defaultEnabled + default_enabled = False + self.env['commandBuffer']['progressMonitoring'] = default_enabled self.env['commandBuffer']['lastProgressTime'] = 0 self.env['commandBuffer']['lastProgressValue'] = -1 - + def shutdown(self): - self.stopProgressMonitoring() - - def getDescription(self): + self.stop_progress_monitoring() + + def get_description(self): return _('Toggle progress bar monitoring with ascending tones') - + def run(self): # Check if commandBuffer exists if 'progressMonitoring' not in self.env['commandBuffer']: self.env['commandBuffer']['progressMonitoring'] = False self.env['commandBuffer']['lastProgressTime'] = 0 self.env['commandBuffer']['lastProgressValue'] = -1 - + if self.env['commandBuffer']['progressMonitoring']: - self.stopProgressMonitoring() - self.env['runtime']['outputManager'].presentText(_("Progress monitoring disabled"), interrupt=True) + self.stop_progress_monitoring() + self.env['runtime']['OutputManager'].present_text( + _("Progress monitoring disabled"), interrupt=True) else: - self.startProgressMonitoring() - self.env['runtime']['outputManager'].presentText(_("Progress monitoring enabled"), interrupt=True) - - def startProgressMonitoring(self): + self.start_progress_monitoring() + self.env['runtime']['OutputManager'].present_text( + _("Progress monitoring enabled"), interrupt=True) + + def start_progress_monitoring(self): self.env['commandBuffer']['progressMonitoring'] = True self.env['commandBuffer']['lastProgressTime'] = time.time() self.env['commandBuffer']['lastProgressValue'] = -1 # Don't control speech - let user decide with silence_until_prompt - - def stopProgressMonitoring(self): + + def stop_progress_monitoring(self): self.env['commandBuffer']['progressMonitoring'] = False # Don't control speech - progress monitor is beep-only - - def detectProgress(self, text): + + def detect_progress(self, text): if not self.env['commandBuffer']['progressMonitoring']: return - + # Skip progress detection if current screen looks like a prompt - if self.isCurrentLinePrompt(): + if self.is_current_line_prompt(): return - - currentTime = time.time() - + + current_time = time.time() + # Pattern 1: Percentage (50%, 25.5%, etc.) - percentMatch = re.search(r'(\d+(?:\.\d+)?)\s*%', text) - if percentMatch: - percentage = float(percentMatch.group(1)) + percent_match = re.search(r'(\d+(?:\.\d+)?)\s*%', text) + if percent_match: + percentage = float(percent_match.group(1)) if percentage != self.env['commandBuffer']['lastProgressValue']: - self.playProgressTone(percentage) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 2: Fraction (15/100, 3 of 10, etc.) - fractionMatch = re.search(r'(\d+)\s*(?:of|/)\s*(\d+)', text) - if fractionMatch: - current = int(fractionMatch.group(1)) - total = int(fractionMatch.group(2)) + fraction_match = re.search(r'(\d+)\s*(?:of|/)\s*(\d+)', text) + if fraction_match: + current = int(fraction_match.group(1)) + total = int(fraction_match.group(2)) if total > 0: percentage = (current / total) * 100 if percentage != self.env['commandBuffer']['lastProgressValue']: - self.playProgressTone(percentage) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 3: Progress bars ([#### ], [====> ], etc.) # Improved pattern to avoid matching IRC channels like [#channel] - barMatch = re.search(r'\[([#=\-\*]+)([\s\.]*)\]', text) - if barMatch: - filled = len(barMatch.group(1)) - unfilled = len(barMatch.group(2)) + bar_match = re.search(r'\[([#=\-\*]+)([\s\.]*)\]', text) + if bar_match: + filled = len(bar_match.group(1)) + unfilled = len(bar_match.group(2)) total = filled + unfilled - # Require at least 2 progress chars total and unfilled portion must be spaces/dots - if total >= 2 and (not barMatch.group(2) or re.match(r'^[\s\.]*$', barMatch.group(2))): + # Require at least 2 progress chars total and unfilled portion must + # be spaces/dots + if total >= 2 and ( + not bar_match.group(2) or re.match( + r'^[\s\.]*$', + bar_match.group(2))): percentage = (filled / total) * 100 if percentage != self.env['commandBuffer']['lastProgressValue']: - self.playProgressTone(percentage) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 4: Generic activity indicators (Loading..., Working..., etc.) - activityPattern = re.search(r'(loading|processing|working|installing|downloading|compiling|building).*\.{2,}', text, re.IGNORECASE) - if activityPattern: + activity_pattern = re.search( + r'(loading|processing|working|installing|downloading|compiling|building).*\.{2,}', + text, + re.IGNORECASE) + if activity_pattern: # Play a steady beep every 2 seconds for ongoing activity - if currentTime - self.env['commandBuffer']['lastProgressTime'] >= 2.0: - self.playActivityBeep() - self.env['commandBuffer']['lastProgressTime'] = currentTime - - def playProgressTone(self, percentage): + if current_time - \ + self.env['commandBuffer']['lastProgressTime'] >= 2.0: + self.play_activity_beep() + self.env['commandBuffer']['lastProgressTime'] = current_time + + def play_progress_tone(self, percentage): # Map 0-100% to 400-1200Hz frequency range frequency = 400 + (percentage * 8) frequency = max(400, min(1200, frequency)) # Clamp to safe range - self.env['runtime']['outputManager'].playFrequence(frequency, 0.15, interrupt=False) - - def playActivityBeep(self): + self.env['runtime']['OutputManager'].play_frequence( + frequency, 0.15, interrupt=False) + + def play_activity_beep(self): # Single tone for generic activity - self.env['runtime']['outputManager'].playFrequence(800, 0.1, interrupt=False) - - def isCurrentLinePrompt(self): + self.env['runtime']['OutputManager'].play_frequence( + 800, 0.1, interrupt=False) + + def is_current_line_prompt(self): """Check if the current line looks like a standalone prompt (not command with progress)""" import re - + try: # Get the current screen content - if not self.env['screen']['newContentText']: + if not self.env['screen']['new_content_text']: return False - - lines = self.env['screen']['newContentText'].split('\n') + + lines = self.env['screen']['new_content_text'].split('\n') if not lines: return False - - # Check the last line (most common) and current cursor line for prompt patterns - linesToCheck = [] - + + # Check the last line (most common) and current cursor line for + # prompt patterns + lines_to_check = [] + # Add last line (most common for prompts) if lines: - linesToCheck.append(lines[-1]) - + lines_to_check.append(lines[-1]) + # Add current cursor line if different from last line - if (self.env['screen']['newCursor']['y'] < len(lines) and - self.env['screen']['newCursor']['y'] != len(lines) - 1): - linesToCheck.append(lines[self.env['screen']['newCursor']['y']]) - + if (self.env['screen']['new_cursor']['y'] < len(lines) and + self.env['screen']['new_cursor']['y'] != len(lines) - 1): + lines_to_check.append( + lines[self.env['screen']['new_cursor']['y']]) + # Standalone prompt patterns (no commands mixed in) - standalonePromptPatterns = [ + standalone_prompt_patterns = [ r'^\s*\$\s*$', # Just $ (with whitespace) - r'^\s*#\s*$', # Just # (with whitespace) + r'^\s*#\s*$', # Just # (with whitespace) r'^\s*>\s*$', # Just > (with whitespace) r'^\[.*\]\s*[\\\$#>]\s*$', # [path]$ without commands r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', # bash-5.1$ without commands - + # Interactive prompt patterns (these ARE standalone) r'.*\?\s*\[[YyNn]/[YyNn]\]\s*$', # ? [Y/n] or ? [y/N] style r'.*\?\s*\[[Yy]es/[Nn]o\]\s*$', # ? [Yes/No] style - r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', # "continue? [Y/n]" style + # "continue? [Y/n]" style + r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', # pacman style prompts - + # Authentication prompts (these ARE standalone) r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', # [sudo] password r'^[Pp]assword\s*:\s*$', # Password: r'.*[Pp]assword\s*:\s*$', # general password prompts - + # Continuation prompts (these ARE standalone) r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', # Press any key r'^[Aa]re\s+you\s+sure\?\s*.*$', # Are you sure? ] - - for line in linesToCheck: + + for line in lines_to_check: line = line.strip() if not line: continue - + # Check if this line contains both a prompt AND other content (like commands) # If so, don't treat it as a standalone prompt - hasPromptMarker = bool(re.search(r'.*@.*[\\\$#>]', line) or re.search(r'^\[.*\]\s*[\\\$#>]', line)) - if hasPromptMarker: - # If line has prompt marker but also has significant content after it, + has_prompt_marker = bool( + re.search( + r'.*@.*[\\\$#>]', + line) or re.search( + r'^\[.*\]\s*[\\\$#>]', + line)) + if has_prompt_marker: + # If line has prompt marker but also has significant content after it, # it's a command line, not a standalone prompt - promptEnd = max( - line.rfind('$'), - line.rfind('#'), + prompt_end = max( + line.rfind('$'), + line.rfind('#'), line.rfind('>'), line.rfind('\\') ) - if promptEnd >= 0 and promptEnd < len(line) - 5: # More than just whitespace after prompt + if prompt_end >= 0 and prompt_end < len( + line) - 5: # More than just whitespace after prompt continue # This is a command line, not a standalone prompt - - for pattern in standalonePromptPatterns: + + for pattern in standalone_prompt_patterns: try: if re.search(pattern, line): return True except re.error: continue - + return False - + except Exception as e: # If anything fails, assume it's not a prompt to be safe return False - - def setCallback(self, callback): - pass \ No newline at end of file + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/quit_fenrir.py b/src/fenrirscreenreader/commands/commands/quit_fenrir.py index 0baf8449..af047e12 100644 --- a/src/fenrirscreenreader/commands/commands/quit_fenrir.py +++ b/src/fenrirscreenreader/commands/commands/quit_fenrir.py @@ -5,19 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('exits Fenrir') - - def run(self): - self.env['runtime']['eventManager'].stopMainEventLoop() - def setCallback(self, callback): + def shutdown(self): pass + def get_description(self): + return _('exits Fenrir') + + def run(self): + self.env['runtime']['EventManager'].stop_main_event_loop() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/remove_marks.py b/src/fenrirscreenreader/commands/commands/remove_marks.py index 17a62880..1cccc40c 100644 --- a/src/fenrirscreenreader/commands/commands/remove_marks.py +++ b/src/fenrirscreenreader/commands/commands/remove_marks.py @@ -5,19 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('Removes marks from selected text') - - def run(self): - self.env['runtime']['cursorManager'].clearMarks() - self.env['runtime']['outputManager'].presentText(_('Remove marks'), interrupt=True) - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('Removes marks from selected text') + + def run(self): + self.env['runtime']['CursorManager'].clear_marks() + self.env['runtime']['OutputManager'].present_text( + _('Remove marks'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py b/src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py index 55f01302..0bd4c041 100644 --- a/src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py +++ b/src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py @@ -4,6 +4,8 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils import string initialized = False @@ -12,43 +14,61 @@ try: initialized = True except Exception as e: pass - + + class command(): def __init__(self): self.language = '' self.spellChecker = None + def initialize(self, environment): self.env = environment - self.updateSpellLanguage() + self.update_spell_language() + def shutdown(self): pass - def getDescription(self): - return _('removes the current word from the exceptions dictionary') - def updateSpellLanguage(self): - self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) - self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') - + + def get_description(self): + return _('removes the current word from the exceptions dictionary') + + def update_spell_language(self): + self.spellChecker = enchant.Dict( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage')) + self.language = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') + def run(self): if not initialized: - self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) - return - if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: + self.env['runtime']['OutputManager'].present_text( + _('pyenchant is not installed'), interrupt=True) + return + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') != self.language: try: - self.updateSpellLanguage() + self.update_spell_language() except Exception as e: - return + return + + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - # get the word - newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] - x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) - currWord = currWord.strip(string.whitespace + r'!"#$%&()*+,-./:;<=Â?@[\\]^_{|}~') - if not currWord.isspace(): - if self.spellChecker.is_removed(currWord): - self.env['runtime']['outputManager'].presentText(_('{0} is not in the dictionary').format(currWord,), soundIcon='Cancel', interrupt=True) + new_content = self.env['screen']['new_content_text'].split('\n')[ + cursor_pos['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + cursor_pos['x'], 0, new_content) + curr_word = curr_word.strip( + string.whitespace + + r'!"#$%&()*+,-./:;<=Â?@[\\]^_{|}~') + if not curr_word.isspace(): + if self.spellChecker.is_removed(curr_word): + self.env['runtime']['OutputManager'].present_text( + _('{0} is not in the dictionary').format( + curr_word,), sound_icon ='Cancel', interrupt=True) else: - self.spellChecker.remove(currWord) - self.env['runtime']['outputManager'].presentText(_('{0} removed').format(currWord,), soundIcon='Accept', interrupt=True) - def setCallback(self, callback): + self.spellChecker.remove(curr_word) + self.env['runtime']['OutputManager'].present_text( + _('{0} removed').format(curr_word,), sound_icon ='Accept', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_bottom.py b/src/fenrirscreenreader/commands/commands/review_bottom.py index cc529e2b..66d9b55a 100644 --- a/src/fenrirscreenreader/commands/commands/review_bottom.py +++ b/src/fenrirscreenreader/commands/commands/review_bottom.py @@ -5,19 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('Move review to the bottom of the screen') def run(self): - self.env['screen']['newCursorReview'] = { 'x': 0, 'y':self.env['screen']['lines'] -1} - self.env['runtime']['outputManager'].presentText(_("Bottom"), interrupt=True, flush=False) + self.env['screen']['newCursorReview'] = { + 'x': 0, 'y': self.env['screen']['lines'] - 1} + self.env['runtime']['OutputManager'].present_text( + _("Bottom"), interrupt=True, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_curr_char.py b/src/fenrirscreenreader/commands/commands/review_curr_char.py index 6ce99926..62203cb9 100644 --- a/src/fenrirscreenreader/commands/commands/review_curr_char.py +++ b/src/fenrirscreenreader/commands/commands/review_curr_char.py @@ -4,32 +4,46 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('presents the current character.') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ - char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - char_utils.presentCharForReview(self.env, currChar, interrupt=True, announceCapital=True, flush=False) - # is has attribute it enabled? - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'): - cursorPos = self.env['screen']['newCursorReview'] - - if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos): - return - self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False) - - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('presents the current character.') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_char = char_utils.get_current_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + curr_char, + interrupt=True, + announce_capital=True, + flush=False) + # is has attribute it enabled? + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'): + cursor_pos = self.env['screen']['newCursorReview'] + + if not self.env['runtime']['AttributeManager'].has_attributes( + cursor_pos): + return + self.env['runtime']['OutputManager'].present_text( + 'has attribute', sound_icon ='HasAttributes', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py b/src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py index 120045fe..51e375a2 100644 --- a/src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_curr_char_phonetic.py @@ -4,29 +4,37 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('set review and phonetically presents the current character') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ - char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if currChar.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) - else: - currChar = char_utils.getPhonetic(currChar) - self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, announceCapital=True, flush=False) - - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('set review and phonetically presents the current character') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_char = char_utils.get_current_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if curr_char.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) + else: + curr_char = char_utils.get_phonetic(curr_char) + self.env['runtime']['OutputManager'].present_text( + curr_char, interrupt=True, announce_capital=True, flush=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_curr_line.py b/src/fenrirscreenreader/commands/commands/review_curr_line.py index 871cc0b7..647524f3 100644 --- a/src/fenrirscreenreader/commands/commands/review_curr_line.py +++ b/src/fenrirscreenreader/commands/commands/review_curr_line.py @@ -4,28 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('current line') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currLine = \ - line_utils.getCurrentLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) - else: - self.env['runtime']['outputManager'].presentText(currLine, interrupt=True, flush=False) - def setCallback(self, callback): + def shutdown(self): pass + def get_description(self): + return _('current line') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_line = line_utils.get_current_line( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True, flush=False) + else: + self.env['runtime']['OutputManager'].present_text( + curr_line, interrupt=True, flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/review_curr_word.py b/src/fenrirscreenreader/commands/commands/review_curr_word.py index 079eaae1..b5118d6b 100644 --- a/src/fenrirscreenreader/commands/commands/review_curr_word.py +++ b/src/fenrirscreenreader/commands/commands/review_curr_word.py @@ -4,33 +4,46 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('current word.') + pass + + def get_description(self): + return _('current word.') def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \ - word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if currWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if curr_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + curr_word, interrupt=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py b/src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py index d0158ef0..98b98bc1 100644 --- a/src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_curr_word_phonetic.py @@ -4,37 +4,50 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Phonetically spells the current word') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \ - word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if currWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) - else: - firstSequence = True - for c in currWord: - currChar = char_utils.getPhonetic(c) - self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) - firstSequence = False - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + pass + + def get_description(self): + return _('Phonetically spells the current word') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if curr_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) + else: + first_sequence = True + for c in curr_word: + curr_char = char_utils.get_phonetic(c) + self.env['runtime']['OutputManager'].present_text( + curr_char, interrupt=first_sequence, announce_capital=True, flush=False) + first_sequence = False + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_down.py b/src/fenrirscreenreader/commands/commands/review_down.py index 8797600a..5984fec9 100644 --- a/src/fenrirscreenreader/commands/commands/review_down.py +++ b/src/fenrirscreenreader/commands/commands/review_down.py @@ -4,25 +4,39 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Move review to the character below the current position') + pass + + def get_description(self): + return _('Move review to the character below the current position') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], downChar, endOfScreen = \ - char_utils.getDownChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - self.env['runtime']['outputManager'].presentText(downChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], downChar, end_of_screen = char_utils.get_down_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + self.env['runtime']['OutputManager'].present_text( + downChar, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_line_begin.py b/src/fenrirscreenreader/commands/commands/review_line_begin.py index 5d31a04a..5968dd40 100644 --- a/src/fenrirscreenreader/commands/commands/review_line_begin.py +++ b/src/fenrirscreenreader/commands/commands/review_line_begin.py @@ -4,29 +4,43 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('set review cursor to begin of current line and display the content') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['cursorManager'].setReviewCursorPosition(0 ,cursorPos['y']) - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ - char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if currChar.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['CursorManager'].set_review_cursor_position( + 0, cursor_pos['y']) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_char = char_utils.get_current_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if curr_char.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("beginning of line"), interrupt=False) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + curr_char, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + _("beginning of line"), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_line_end.py b/src/fenrirscreenreader/commands/commands/review_line_end.py index 5cf18dd2..22edc411 100644 --- a/src/fenrirscreenreader/commands/commands/review_line_end.py +++ b/src/fenrirscreenreader/commands/commands/review_line_end.py @@ -4,26 +4,39 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Move Review to the end of current line and display the content') + pass + + def get_description(self): + return _('Move Review to the end of current line and display the content') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y']) - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ - char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("end of line"), interrupt=False) - - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['CursorManager'].set_review_cursor_position( + self.env['screen']['columns'] - 1, cursor_pos['y']) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_char = char_utils.get_current_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + self.env['runtime']['OutputManager'].present_text( + curr_char, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + _("end of line"), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_line_first_char.py b/src/fenrirscreenreader/commands/commands/review_line_first_char.py index 84de0a72..2898a0ff 100644 --- a/src/fenrirscreenreader/commands/commands/review_line_first_char.py +++ b/src/fenrirscreenreader/commands/commands/review_line_first_char.py @@ -4,32 +4,46 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('Move Review to the first character on the line') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - x, y, currLine = \ - line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText']) - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("line is empty"), interrupt=True) - return - self.env['runtime']['cursorManager'].setReviewCursorPosition((len(currLine) - len(currLine.lstrip())), cursorPos['y']) - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \ - char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + x, y, curr_line = line_utils.get_current_line( + cursor_pos['x'], cursor_pos['y'], self.env['screen']['new_content_text']) + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("line is empty"), interrupt=True) + return + self.env['runtime']['CursorManager'].set_review_cursor_position( + (len(curr_line) - len(curr_line.lstrip())), cursor_pos['y']) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], curr_char = char_utils.get_current_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) - char_utils.presentCharForReview(self.env, currChar, interrupt=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("first character in line indent {0}").format(str(len(currLine) - len(currLine.lstrip()))), interrupt=False) - - def setCallback(self, callback): + char_utils.present_char_for_review( + self.env, + curr_char, + interrupt=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text(_("first character in line indent {0}").format( + str(len(curr_line) - len(curr_line.lstrip()))), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_line_last_char.py b/src/fenrirscreenreader/commands/commands/review_line_last_char.py index 82bcf101..7e9ef046 100644 --- a/src/fenrirscreenreader/commands/commands/review_line_last_char.py +++ b/src/fenrirscreenreader/commands/commands/review_line_last_char.py @@ -4,26 +4,39 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('Move Review to the last character on the line') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y']) + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['CursorManager'].set_review_cursor_position( + self.env['screen']['columns'] - 1, cursor_pos['y']) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \ - char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - char_utils.presentCharForReview(self.env, lastChar, interrupt=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("last character in line"), interrupt=False) - - def setCallback(self, callback): + char_utils.get_last_char_in_line(self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + lastChar, + interrupt=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + _("last character in line"), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_next_char.py b/src/fenrirscreenreader/commands/commands/review_next_char.py index 496e2f83..685efa28 100644 --- a/src/fenrirscreenreader/commands/commands/review_next_char.py +++ b/src/fenrirscreenreader/commands/commands/review_next_char.py @@ -4,36 +4,55 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('Moves review to the next character ') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \ - char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - char_utils.presentCharForReview(self.env, nextChar, interrupt=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - # is has attribute it enabled? - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'): - cursorPos = self.env['screen']['newCursorReview'] - - if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos): - return - self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False) - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('Moves review to the next character ') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], next_char, end_of_screen, line_break = char_utils.get_next_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + next_char, + interrupt=True, + announce_capital=True, + flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + # is has attribute it enabled? + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'): + cursor_pos = self.env['screen']['newCursorReview'] + + if not self.env['runtime']['AttributeManager'].has_attributes( + cursor_pos): + return + self.env['runtime']['OutputManager'].present_text( + 'has attribute', sound_icon ='HasAttributes', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py b/src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py index 2d3a1fb2..e9cb8277 100644 --- a/src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_next_char_phonetic.py @@ -4,31 +4,43 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('phonetically presents the next character and set review to it') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \ - char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - nextChar = char_utils.getPhonetic(nextChar) - self.env['runtime']['outputManager'].presentText(nextChar ,interrupt=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('phonetically presents the next character and set review to it') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], next_char, end_of_screen, line_break = char_utils.get_next_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + next_char = char_utils.get_phonetic(next_char) + self.env['runtime']['OutputManager'].present_text( + next_char, interrupt=True, announce_capital=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_next_line.py b/src/fenrirscreenreader/commands/commands/review_next_line.py index a2870d7f..10bc0a14 100644 --- a/src/fenrirscreenreader/commands/commands/review_next_line.py +++ b/src/fenrirscreenreader/commands/commands/review_next_line.py @@ -4,32 +4,43 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('moves review to the next line ') - + pass + + def get_description(self): + return _('moves review to the next line ') + def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: - self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() + self.env['screen']['newCursorReview'] = self.env['screen']['new_cursor'].copy() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextLine, end_of_screen = line_utils.get_next_line( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextLine, endOfScreen = \ - line_utils.getNextLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - if nextLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(nextLine, interrupt=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + nextLine, interrupt=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_next_word.py b/src/fenrirscreenreader/commands/commands/review_next_word.py index 488ddc44..17c9151b 100644 --- a/src/fenrirscreenreader/commands/commands/review_next_word.py +++ b/src/fenrirscreenreader/commands/commands/review_next_word.py @@ -4,35 +4,48 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('moves review to the next word ') - + pass + + def get_description(self): + return _('moves review to the next word ') + def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] - if self.env['screen']['newCursorReview'] == None: - self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() + if self.env['screen']['newCursorReview'] is None: + self.env['screen']['newCursorReview'] = self.env['screen']['new_cursor'].copy() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \ - word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if nextWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], next_word, end_of_screen, line_break = word_utils.get_next_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if next_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(nextWord, interrupt=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + next_word, interrupt=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py b/src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py index e15fb014..e32346f3 100644 --- a/src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_next_word_phonetic.py @@ -4,37 +4,50 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Phonetically spells the next word and moves review to it') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \ - word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if nextWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) - else: - firstSequence = True - for c in nextWord: - currChar = char_utils.getPhonetic(c) - self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) - firstSequence = False - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + pass + + def get_description(self): + return _('Phonetically spells the next word and moves review to it') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], next_word, end_of_screen, line_break = word_utils.get_next_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if next_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) + else: + first_sequence = True + for c in next_word: + curr_char = char_utils.get_phonetic(c) + self.env['runtime']['OutputManager'].present_text( + curr_char, interrupt=first_sequence, announce_capital=True, flush=False) + first_sequence = False + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_prev_char.py b/src/fenrirscreenreader/commands/commands/review_prev_char.py index 5c4587b8..2cc2ca79 100644 --- a/src/fenrirscreenreader/commands/commands/review_prev_char.py +++ b/src/fenrirscreenreader/commands/commands/review_prev_char.py @@ -4,39 +4,58 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('moves review to the previous character ') - + pass + + def get_description(self): + return _('moves review to the previous character ') + def run(self): self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: - self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() + self.env['screen']['newCursorReview'] = self.env['screen']['new_cursor'].copy() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \ - char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - char_utils.presentCharForReview(self.env, prevChar, interrupt=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - # is has attribute it enabled? - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'): - cursorPos = self.env['screen']['newCursorReview'] - - if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos): + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prev_char, end_of_screen, line_break = char_utils.get_prev_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + prev_char, + interrupt=True, + announce_capital=True, + flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + # is has attribute it enabled? + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'): + cursor_pos = self.env['screen']['newCursorReview'] + + if not self.env['runtime']['AttributeManager'].has_attributes( + cursor_pos): return - self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'has attribute', sound_icon ='HasAttributes', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py b/src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py index 8cf125f9..5958d224 100644 --- a/src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_prev_char_phonetic.py @@ -4,31 +4,43 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('phonetically presents the previous character and set review to it') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \ - char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - prevChar = char_utils.getPhonetic(prevChar) - self.env['runtime']['outputManager'].presentText(prevChar ,interrupt=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('phonetically presents the previous character and set review to it') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prev_char, end_of_screen, line_break = char_utils.get_prev_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + prev_char = char_utils.get_phonetic(prev_char) + self.env['runtime']['OutputManager'].present_text( + prev_char, interrupt=True, announce_capital=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_prev_line.py b/src/fenrirscreenreader/commands/commands/review_prev_line.py index 600fd171..f71bd993 100644 --- a/src/fenrirscreenreader/commands/commands/review_prev_line.py +++ b/src/fenrirscreenreader/commands/commands/review_prev_line.py @@ -4,31 +4,41 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('moves review to the previous line ') + pass + + def get_description(self): + return _('moves review to the previous line ') def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevLine, endOfScreen = \ - line_utils.getPrevLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if prevLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prev_line, end_of_screen = line_utils.get_prev_line( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if prev_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(prevLine, interrupt=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') + self.env['runtime']['OutputManager'].present_text( + prev_line, interrupt=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_prev_word.py b/src/fenrirscreenreader/commands/commands/review_prev_word.py index a785eb1d..e94d2ba0 100644 --- a/src/fenrirscreenreader/commands/commands/review_prev_word.py +++ b/src/fenrirscreenreader/commands/commands/review_prev_word.py @@ -4,33 +4,46 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('moves review focus to the previous word ') + pass + + def get_description(self): + return _('moves review focus to the previous word ') def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \ - word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if prevWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prev_word, end_of_screen, line_break = word_utils.get_prev_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if prev_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(prevWord, interrupt=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=False, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + prev_word, interrupt=True, flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=False, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py b/src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py index 96f27f80..ebdea968 100644 --- a/src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py +++ b/src/fenrirscreenreader/commands/commands/review_prev_word_phonetic.py @@ -4,37 +4,50 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Phonetically spells the previous word and moves review to it') - - def run(self): - self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \ - word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - if prevWord.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False) - else: - firstSequence = True - for c in prevWord: - currChar = char_utils.getPhonetic(c) - self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False) - firstSequence = False - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + pass + + def get_description(self): + return _('Phonetically spells the previous word and moves review to it') + + def run(self): + self.env['runtime']['CursorManager'].enter_review_mode_curr_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prev_word, end_of_screen, line_break = word_utils.get_prev_word( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + if prev_word.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), interrupt=True, flush=False) + else: + first_sequence = True + for c in prev_word: + curr_char = char_utils.get_phonetic(c) + self.env['runtime']['OutputManager'].present_text( + curr_char, interrupt=first_sequence, announce_capital=True, flush=False) + first_sequence = False + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_screen_first_char.py b/src/fenrirscreenreader/commands/commands/review_screen_first_char.py index 4bbc4554..349fba8f 100644 --- a/src/fenrirscreenreader/commands/commands/review_screen_first_char.py +++ b/src/fenrirscreenreader/commands/commands/review_screen_first_char.py @@ -4,26 +4,38 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('Move Review to the first character on the screen (left top)') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['cursorManager'].setReviewCursorPosition(0 ,0) + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['CursorManager'].set_review_cursor_position(0, 0) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \ - char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - char_utils.presentCharForReview(self.env, lastChar, interrupt=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("first character in screen"), interrupt=False) - - def setCallback(self, callback): + char_utils.get_last_char_in_line(self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + lastChar, + interrupt=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + _("first character in screen"), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_screen_last_char.py b/src/fenrirscreenreader/commands/commands/review_screen_last_char.py index afec3477..a1258493 100644 --- a/src/fenrirscreenreader/commands/commands/review_screen_last_char.py +++ b/src/fenrirscreenreader/commands/commands/review_screen_last_char.py @@ -4,26 +4,39 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('Move Review to the last character on the screen (right bottom)') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,self.env['screen']['lines']-1) + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['runtime']['CursorManager'].set_review_cursor_position( + self.env['screen']['columns'] - 1, self.env['screen']['lines'] - 1) self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \ - char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - - char_utils.presentCharForReview(self.env, lastChar, interrupt=True, announceCapital=True, flush=False) - self.env['runtime']['outputManager'].presentText(_("last character in screen"), interrupt=False) - - def setCallback(self, callback): + char_utils.get_last_char_in_line(self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + + char_utils.present_char_for_review( + self.env, + lastChar, + interrupt=True, + announce_capital=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + _("last character in screen"), interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_top.py b/src/fenrirscreenreader/commands/commands/review_top.py index b3778e92..a5e2e032 100644 --- a/src/fenrirscreenreader/commands/commands/review_top.py +++ b/src/fenrirscreenreader/commands/commands/review_top.py @@ -4,21 +4,28 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('move review to top of screen') + pass + + def get_description(self): + return _('move review to top of screen') def run(self): - self.env['screen']['newCursorReview'] = {'x':0,'y':0} - self.env['runtime']['outputManager'].presentText(_("Top"), interrupt=True, flush=False) + self.env['screen']['newCursorReview'] = {'x': 0, 'y': 0} + self.env['runtime']['OutputManager'].present_text( + _("Top"), interrupt=True, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/review_up.py b/src/fenrirscreenreader/commands/commands/review_up.py index 9788cb09..63145c68 100644 --- a/src/fenrirscreenreader/commands/commands/review_up.py +++ b/src/fenrirscreenreader/commands/commands/review_up.py @@ -4,28 +4,46 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Move review to the character in the line above the current position') + pass + + def get_description(self): + return _( + 'Move review to the character in the line above the current position') def run(self): - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], upChar, endOfScreen = \ - char_utils.getUpChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText']) - self.env['runtime']['outputManager'].presentText(upChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - if endOfScreen: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'): - self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen') - if lineBreak: - if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'): - self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine') - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], upChar, end_of_screen = char_utils.get_up_char( + self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['new_content_text']) + line_break = False + self.env['runtime']['OutputManager'].present_text( + upChar, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + if end_of_screen: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'end_of_screen'): + self.env['runtime']['OutputManager'].present_text( + _('end of screen'), interrupt=True, sound_icon ='EndOfScreen') + if line_break: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'line_break'): + self.env['runtime']['OutputManager'].present_text( + _('line break'), interrupt=False, sound_icon ='EndOfLine') + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/save_settings.py b/src/fenrirscreenreader/commands/commands/save_settings.py index 9f6ae177..bfce0276 100644 --- a/src/fenrirscreenreader/commands/commands/save_settings.py +++ b/src/fenrirscreenreader/commands/commands/save_settings.py @@ -4,20 +4,29 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import settingsManager + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return _('Saves your current Fenrir settings so they are the default.') + def run(self): - settingsFile = self.env['runtime']['settingsManager'].getSettingsFile() - self.env['runtime']['settingsManager'].saveSettings(settingsFile) - self.env['runtime']['outputManager'].presentText(_("Settings saved."), interrupt=True) - def setCallback(self, callback): + settings_file = self.env['runtime']['SettingsManager'].get_settings_file() + self.env['runtime']['SettingsManager'].save_settings(settings_file) + self.env['runtime']['OutputManager'].present_text( + _("Settings saved."), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_1.py b/src/fenrirscreenreader/commands/commands/set_bookmark_1.py index 333962b8..888331e3 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_1.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_1.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(1, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_10.py b/src/fenrirscreenreader/commands/commands/set_bookmark_10.py index 499c1d4f..fb4d3288 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_10.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_10.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(10, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_2.py b/src/fenrirscreenreader/commands/commands/set_bookmark_2.py index 826a093a..0b78549d 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_2.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_2.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(2, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_3.py b/src/fenrirscreenreader/commands/commands/set_bookmark_3.py index d87f444e..c9e5dfc4 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_3.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_3.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(3, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_4.py b/src/fenrirscreenreader/commands/commands/set_bookmark_4.py index fe2c1f83..fee7efe2 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_4.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_4.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(4, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_5.py b/src/fenrirscreenreader/commands/commands/set_bookmark_5.py index efa41d0d..e2f29134 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_5.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_5.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(5, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_6.py b/src/fenrirscreenreader/commands/commands/set_bookmark_6.py index e5998745..1584c176 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_6.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_6.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(6, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_7.py b/src/fenrirscreenreader/commands/commands/set_bookmark_7.py index f31fd689..86ad3ddb 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_7.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_7.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(7, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_8.py b/src/fenrirscreenreader/commands/commands/set_bookmark_8.py index dcdb9ce9..1f1cd1ad 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_8.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_8.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(8, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_bookmark_9.py b/src/fenrirscreenreader/commands/commands/set_bookmark_9.py index 30b67ed2..2996f53c 100644 --- a/src/fenrirscreenreader/commands/commands/set_bookmark_9.py +++ b/src/fenrirscreenreader/commands/commands/set_bookmark_9.py @@ -4,14 +4,17 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import importlib.util _base_path = os.path.join(os.path.dirname(__file__), 'bookmark_base.py') _spec = importlib.util.spec_from_file_location("bookmark_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -BookmarkCommand = _module.BookmarkCommand +bookmark_command = _module.bookmark_command -class command(BookmarkCommand): + +class command(bookmark_command): def __init__(self): super().__init__(9, 'set') diff --git a/src/fenrirscreenreader/commands/commands/set_mark.py b/src/fenrirscreenreader/commands/commands/set_mark.py index 2d22ae2a..675a59e1 100644 --- a/src/fenrirscreenreader/commands/commands/set_mark.py +++ b/src/fenrirscreenreader/commands/commands/set_mark.py @@ -5,25 +5,35 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('places marks to select text to copy to the clipboard') - + pass + + def get_description(self): + return _('places marks to select text to copy to the clipboard') + def run(self): - if not self.env['runtime']['cursorManager'].isReviewMode(): - self.env['runtime']['outputManager'].presentText(_('no review cursor'), interrupt=True) + if not self.env['runtime']['CursorManager'].is_review_mode(): + self.env['runtime']['OutputManager'].present_text( + _('no review cursor'), interrupt=True) return - currMark = self.env['runtime']['cursorManager'].setMark() - if currMark == 1: - self.env['runtime']['outputManager'].presentText(_('set mark'), soundIcon='PlaceStartMark', interrupt=True) - elif currMark == 2: - self.env['runtime']['outputManager'].presentText(_('set mark'),soundIcon='PlaceEndMark', interrupt=True) - def setCallback(self, callback): + curr_mark = self.env['runtime']['CursorManager'].set_mark() + if curr_mark == 1: + self.env['runtime']['OutputManager'].present_text( + _('set mark'), sound_icon ='PlaceStartMark', interrupt=True) + elif curr_mark == 2: + self.env['runtime']['OutputManager'].present_text( + _('set mark'), sound_icon ='PlaceEndMark', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/set_window_application.py b/src/fenrirscreenreader/commands/commands/set_window_application.py index bcc3f920..71f87338 100644 --- a/src/fenrirscreenreader/commands/commands/set_window_application.py +++ b/src/fenrirscreenreader/commands/commands/set_window_application.py @@ -5,23 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('set Window Mode, needs 2 marks ') - - def run(self): - if self.env['runtime']['cursorManager'].setWindowForApplication(): - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - self.env['runtime']['outputManager'].presentText(_('Window Mode on for application {0}').format(currApp), interrupt=True) - self.env['runtime']['cursorManager'].clearMarks() - else: - self.env['runtime']['outputManager'].presentText(_("Set window begin and end marks"), interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('set Window Mode, needs 2 marks ') + + def run(self): + if self.env['runtime']['CursorManager'].set_window_for_application(): + curr_app = self.env['runtime']['ApplicationManager'].get_current_application( + ) + self.env['runtime']['OutputManager'].present_text( + _('Window Mode on for application {0}').format(curr_app), interrupt=True) + self.env['runtime']['CursorManager'].clear_marks() + else: + self.env['runtime']['OutputManager'].present_text( + _("Set window begin and end marks"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/shut_up.py b/src/fenrirscreenreader/commands/commands/shut_up.py index 1a5aa4b2..931926d8 100644 --- a/src/fenrirscreenreader/commands/commands/shut_up.py +++ b/src/fenrirscreenreader/commands/commands/shut_up.py @@ -5,18 +5,28 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Interrupts the current presentation') - def run(self): - if len(self.env['input']['prevDeepestInput']) > len(self.env['input']['currInput']): - return - self.env['runtime']['outputManager'].interruptOutput() - def setCallback(self, callback): + pass + + def get_description(self): + return _('Interrupts the current presentation') + + def run(self): + if len( + self.env['input']['prevDeepestInput']) > len( + self.env['input']['currInput']): + return + self.env['runtime']['OutputManager'].interrupt_output() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/silence_until_prompt.py b/src/fenrirscreenreader/commands/commands/silence_until_prompt.py index cca33a3d..ba95d278 100644 --- a/src/fenrirscreenreader/commands/commands/silence_until_prompt.py +++ b/src/fenrirscreenreader/commands/commands/silence_until_prompt.py @@ -4,83 +4,102 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import debug import re + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment # Use commandBuffer like other commands if 'silenceUntilPrompt' not in self.env['commandBuffer']: self.env['commandBuffer']['silenceUntilPrompt'] = False - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return _('Toggle speech silence until shell prompt returns') - + def run(self): if self.env['commandBuffer']['silenceUntilPrompt']: - self.disableSilence() + self.disable_silence() else: - self.enableSilence() - - def enableSilence(self): + self.enable_silence() + + def enable_silence(self): self.env['commandBuffer']['silenceUntilPrompt'] = True - self.env['runtime']['outputManager'].presentText(_("Speech silenced until prompt returns"), soundIcon='SpeechOff', interrupt=True) - # Disable speech but don't use the normal temp disable that reactivates on keypress - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', 'False') - - def disableSilence(self): + self.env['runtime']['OutputManager'].present_text( + _("Speech silenced until prompt returns"), + sound_icon ='SpeechOff', + interrupt=True) + # Disable speech but don't use the normal temp disable that reactivates + # on keypress + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', 'False') + + def disable_silence(self): self.env['commandBuffer']['silenceUntilPrompt'] = False # Re-enable speech - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', 'True') - self.env['runtime']['outputManager'].presentText(_("Speech restored"), soundIcon='SpeechOn', interrupt=True) - - def checkForPrompt(self, text): + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', 'True') + self.env['runtime']['OutputManager'].present_text( + _("Speech restored"), sound_icon ='SpeechOn', interrupt=True) + + def check_for_prompt(self, text): """Check if the current line contains a shell prompt pattern""" if not self.env['commandBuffer']['silenceUntilPrompt']: return False - - # First check for exact matches from settings (with backward compatibility) + + # First check for exact matches from settings (with backward + # compatibility) try: - exactMatches = self.env['runtime']['settingsManager'].getSetting('prompt', 'exactMatches') - if exactMatches: - exactList = [match.strip() for match in exactMatches.split(',') if match.strip()] - for exactMatch in exactList: + exact_matches = self.env['runtime']['SettingsManager'].get_setting( + 'prompt', 'exact_matches') + if exact_matches: + exact_list = [match.strip() + for match in exact_matches.split(',') if match.strip()] + for exactMatch in exact_list: if text.strip() == exactMatch: - self.env['runtime']['debug'].writeDebugOut("Found exact prompt match: " + exactMatch, debug.debugLevel.INFO) - self.disableSilence() + self.env['runtime']['DebugManager'].write_debug_out( + "found exact prompt match: " + exactMatch, debug.DebugLevel.INFO) + self.disable_silence() return True except Exception as e: - # Prompt section doesn't exist in settings, skip custom exact matches + # Prompt section doesn't exist in settings, skip custom exact + # matches pass - + # Get custom patterns from settings (with backward compatibility) - promptPatterns = [] + prompt_patterns = [] try: - customPatterns = self.env['runtime']['settingsManager'].getSetting('prompt', 'customPatterns') + custom_patterns = self.env['runtime']['SettingsManager'].get_setting( + 'prompt', 'custom_patterns') # Add custom patterns from settings if they exist - if customPatterns: - customList = [pattern.strip() for pattern in customPatterns.split(',') if pattern.strip()] - promptPatterns.extend(customList) + if custom_patterns: + custom_list = [ + pattern.strip() for pattern in custom_patterns.split(',') if pattern.strip()] + prompt_patterns.extend(custom_list) except Exception as e: # Prompt section doesn't exist in settings, skip custom patterns pass - + # Add default shell prompt patterns - promptPatterns.extend([ + prompt_patterns.extend([ r'^\s*\$\s*$', # Just $ (with whitespace) - r'^\s*#\s*$', # Just # (with whitespace) + r'^\s*#\s*$', # Just # (with whitespace) r'^\s*>\s*$', # Just > (with whitespace) - r'.*@.*[\\\$#>]\s*$', # Contains @ and ends with prompt char (user@host style) + r'.*@.*[\\\$#>]\s*$', + # Contains @ and ends with prompt char (user@host style) r'^\[.*\]\s*[\\\$#>]\s*$', # [anything]$ style prompts - r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', # Simple shell names like bash-5.1$ - + # Simple shell names like bash-5.1$ + r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', + # Interactive prompt patterns # Package manager confirmation prompts r'.*\?\s*\[[YyNn]/[YyNn]\]\s*$', # ? [Y/n] or ? [y/N] style @@ -89,36 +108,43 @@ class command(): r'.*\?\s*\([Yy]es/[Nn]o\)\s*$', # ? (Yes/No) style r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', # "continue? [Y/n]" style r'.*ok\s*\[[YyNn]/[YyNn]\].*$', # "Is this ok [y/N]:" style - r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', # pacman ":: Proceed? [Y/n]" style - + # pacman ":: Proceed? [Y/n]" style + r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', + # Authentication prompts - r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', # [sudo] password for user: + # [sudo] password for user: + r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', r'^[Pp]assword\s*:\s*$', # Password: r'.*[Pp]assword\s*:\s*$', # general password prompts r".*'s\s*[Pp]assword\s*:\s*$", # user's password: r'^[Ee]nter\s+[Pp]assphrase.*:\s*$', # Enter passphrase: - r'^[Pp]lease\s+enter\s+[Pp]assphrase.*:\s*$', # Please enter passphrase: - + # Please enter passphrase: + r'^[Pp]lease\s+enter\s+[Pp]assphrase.*:\s*$', + # General confirmation and continuation prompts - r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', # Press any key to continue + # Press any key to continue + r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', r'^[Aa]re\s+you\s+sure\?\s*.*$', # Are you sure? r'^[Pp]lease\s+confirm.*$', # Please confirm r'.*confirm.*\([YyNn]/[YyNn]\).*$', # confirm (y/n) r'.*\([Yy]/[Nn]\)\s*$', # ends with (Y/n) or (y/N) ]) - - for pattern in promptPatterns: + + for pattern in prompt_patterns: try: if re.search(pattern, text.strip()): - self.env['runtime']['debug'].writeDebugOut("Found prompt pattern: " + pattern, debug.debugLevel.INFO) - self.disableSilence() + self.env['runtime']['DebugManager'].write_debug_out( + "found prompt pattern: " + pattern, debug.DebugLevel.INFO) + self.disable_silence() return True except re.error as e: # Invalid regex pattern, skip it and log the error - self.env['runtime']['debug'].writeDebugOut("Invalid prompt pattern: " + pattern + " Error: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Invalid prompt pattern: " + pattern + " Error: " + str(e), + debug.DebugLevel.ERROR) continue - + return False - - def setCallback(self, callback): - pass \ No newline at end of file + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/spell_check.py b/src/fenrirscreenreader/commands/commands/spell_check.py index 73f1fd03..9aaa9306 100644 --- a/src/fenrirscreenreader/commands/commands/spell_check.py +++ b/src/fenrirscreenreader/commands/commands/spell_check.py @@ -4,6 +4,8 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils initialized = False try: @@ -11,44 +13,59 @@ try: initialized = True except Exception as e: pass - + + class command(): def __init__(self): self.language = '' self.spellChecker = None + def initialize(self, environment): self.env = environment - self.updateSpellLanguage() + self.update_spell_language() + def shutdown(self): pass - def getDescription(self): - return _('checks the spelling of the current word') - def updateSpellLanguage(self): - if not initialized: - return - self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) - self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') - + + def get_description(self): + return _('checks the spelling of the current word') + + def update_spell_language(self): + if not initialized: + return + self.spellChecker = enchant.Dict( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage')) + self.language = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') + def run(self): if not initialized: - self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True) - return - if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: + self.env['runtime']['OutputManager'].present_text( + _('pyenchant is not installed'), interrupt=True) + return + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') != self.language: try: - self.updateSpellLanguage() + self.update_spell_language() except Exception as e: - return - - cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor() - - # get the word - newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] - x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent) + return - if not currWord.isspace(): - if not self.spellChecker.check(currWord): - self.env['runtime']['outputManager'].presentText(_('misspelled'),soundIcon='mispell', interrupt=True) - elif not ignore: - self.env['runtime']['outputManager'].presentText(_('correct'),soundIcon='', interrupt=True) - def setCallback(self, callback): + cursor_pos = self.env['runtime']['CursorManager'].get_review_or_text_cursor() + + # get the word + new_content = self.env['screen']['new_content_text'].split('\n')[ + cursor_pos['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + cursor_pos['x'], 0, new_content) + + if not curr_word.isspace(): + if not self.spellChecker.check(curr_word): + self.env['runtime']['OutputManager'].present_text( + _('misspelled'), sound_icon ='mispell', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _('correct'), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/subprocess.py b/src/fenrirscreenreader/commands/commands/subprocess.py index 052923a0..f38f3d46 100644 --- a/src/fenrirscreenreader/commands/commands/subprocess.py +++ b/src/fenrirscreenreader/commands/commands/subprocess.py @@ -4,46 +4,62 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -import subprocess, os +from fenrirscreenreader.core.i18n import _ + +import subprocess +import os from subprocess import Popen, PIPE import _thread + class command(): def __init__(self): pass - def initialize(self, environment, scriptPath=''): + + def initialize(self, environment, script_path=''): self.env = environment - self.scriptPath = scriptPath + self.script_path = script_path + def shutdown(self): pass - def getDescription(self): - return _('script: {0} fullpath: {1}').format(os.path.basename(self.scriptPath), self.scriptPath) - def run(self): - if not os.path.exists(self.scriptPath): - self.env['runtime']['outputManager'].presentText(_('Script file not found'), soundIcon='', interrupt=False) - return - if not os.path.isfile(self.scriptPath): - self.env['runtime']['outputManager'].presentText(_('Script source is not a valid file'), soundIcon='', interrupt=False) - return - if not os.access(self.scriptPath, os.X_OK): - self.env['runtime']['outputManager'].presentText(_('Script file is not executable'), soundIcon='', interrupt=False) - return - _thread.start_new_thread(self._threadRun , ()) - def _threadRun(self): + def get_description(self): + return _('script: {0} fullpath: {1}').format( + os.path.basename(self.script_path), self.script_path) + + def run(self): + if not os.path.exists(self.script_path): + self.env['runtime']['OutputManager'].present_text( + _('Script file not found'), sound_icon='', interrupt=False) + return + if not os.path.isfile(self.script_path): + self.env['runtime']['OutputManager'].present_text( + _('Script source is not a valid file'), sound_icon='', interrupt=False) + return + if not os.access(self.script_path, os.X_OK): + self.env['runtime']['OutputManager'].present_text( + _('Script file is not executable'), sound_icon='', interrupt=False) + return + _thread.start_new_thread(self._thread_run, ()) + + def _thread_run(self): try: - callstring = self.scriptPath + ' ' + self.env['general']['currUser'] - p = Popen(callstring , stdout=PIPE, stderr=PIPE, shell=True) + callstring = self.script_path + ' ' + \ + self.env['general']['curr_user'] + p = Popen(callstring, stdout=PIPE, stderr=PIPE, shell=True) stdout, stderr = p.communicate() stdout = stdout.decode('utf-8') stderr = stderr.decode('utf-8') - self.env['runtime']['outputManager'].interruptOutput() + self.env['runtime']['OutputManager'].interrupt_output() if stderr != '': - self.env['runtime']['outputManager'].presentText(str(stderr) , soundIcon='', interrupt=False) + self.env['runtime']['OutputManager'].present_text( + str(stderr), sound_icon='', interrupt=False) if stdout != '': - self.env['runtime']['outputManager'].presentText(str(stdout) , soundIcon='', interrupt=False) + self.env['runtime']['OutputManager'].present_text( + str(stdout), sound_icon='', interrupt=False) except Exception as e: - self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + str(e), sound_icon='', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/temp_disable_speech.py b/src/fenrirscreenreader/commands/commands/temp_disable_speech.py index 6af2e32d..94653246 100644 --- a/src/fenrirscreenreader/commands/commands/temp_disable_speech.py +++ b/src/fenrirscreenreader/commands/commands/temp_disable_speech.py @@ -5,18 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('disables speech until next keypress') - - def run(self): - self.env['runtime']['outputManager'].tempDisableSpeech() - - def setCallback(self, callback): + pass + + def get_description(self): + return _('disables speech until next keypress') + + def run(self): + self.env['runtime']['OutputManager'].temp_disable_speech() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/time.py b/src/fenrirscreenreader/commands/commands/time.py index 96b15b88..ee5f398d 100644 --- a/src/fenrirscreenreader/commands/commands/time.py +++ b/src/fenrirscreenreader/commands/commands/time.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the time') + pass + + def get_description(self): + return _('presents the time') def run(self): - timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat') + time_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'time_format') # get the time formatted - timeString = datetime.datetime.strftime(datetime.datetime.now(), timeFormat) + time_string = datetime.datetime.strftime( + datetime.datetime.now(), time_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(timeString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + time_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_auto_indent.py b/src/fenrirscreenreader/commands/commands/toggle_auto_indent.py index 7d32187c..04c46cb6 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_auto_indent.py +++ b/src/fenrirscreenreader/commands/commands/toggle_auto_indent.py @@ -4,22 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables automatic reading of indentation level changes') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('general', 'autoPresentIndent', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'): - self.env['runtime']['outputManager'].presentText(_("autoindent enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("autoindent disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables automatic reading of indentation level changes') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'general', 'autoPresentIndent', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoPresentIndent'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoPresentIndent'): + self.env['runtime']['OutputManager'].present_text( + _("autoindent enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("autoindent disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_auto_read.py b/src/fenrirscreenreader/commands/commands/toggle_auto_read.py index b62eda2e..042384ae 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_auto_read.py +++ b/src/fenrirscreenreader/commands/commands/toggle_auto_read.py @@ -4,22 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables automatic reading of new text as it appears') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('speech', 'autoReadIncoming', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'): - self.env['runtime']['outputManager'].presentText(_("autoread enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("autoread disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables automatic reading of new text as it appears') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'autoReadIncoming', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'autoReadIncoming'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'autoReadIncoming'): + self.env['runtime']['OutputManager'].present_text( + _("autoread enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("autoread disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py b/src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py index 622874fb..eea34bb7 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py +++ b/src/fenrirscreenreader/commands/commands/toggle_auto_spell_check.py @@ -5,22 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables automatic spell checking') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('general', 'autoSpellCheck', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'): - self.env['runtime']['outputManager'].presentText(_("auto spellcheck enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("auto spellcheck disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables automatic spell checking') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'general', 'autoSpellCheck', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoSpellCheck'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoSpellCheck'): + self.env['runtime']['OutputManager'].present_text( + _("auto spellcheck enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("auto spellcheck disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_auto_time.py b/src/fenrirscreenreader/commands/commands/toggle_auto_time.py index 01ce0f41..d87be58d 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_auto_time.py +++ b/src/fenrirscreenreader/commands/commands/toggle_auto_time.py @@ -4,22 +4,33 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('Enables or disables automatic reading of time after specified intervals') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('time', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'): - self.env['runtime']['outputManager'].presentText(_("Automatic time announcement enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("Automatic time announcement disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _( + 'Enables or disables automatic reading of time after specified intervals') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting('time', 'enabled', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool('time', 'enabled'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _("Automatic time announcement enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("Automatic time announcement disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_barrier.py b/src/fenrirscreenreader/commands/commands/toggle_barrier.py index c0f8720a..ceef6c97 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_barrier.py +++ b/src/fenrirscreenreader/commands/commands/toggle_barrier.py @@ -4,22 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables the barrier mode') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('barrier', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'): - self.env['runtime']['outputManager'].presentText(_("barrier mode enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("barrier mode disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables the barrier mode') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'barrier', 'enabled', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _("barrier mode enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("barrier mode disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_emoticons.py b/src/fenrirscreenreader/commands/commands/toggle_emoticons.py index 967976cf..a4223ca8 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_emoticons.py +++ b/src/fenrirscreenreader/commands/commands/toggle_emoticons.py @@ -4,22 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables announcement of emoticons instead of chars') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('general', 'emoticons', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'): - self.env['runtime']['outputManager'].presentText(_('emoticons enabled'), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_('emoticons disabled'), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables announcement of emoticons instead of chars') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'general', 'emoticons', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'emoticons'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'emoticons'): + self.env['runtime']['OutputManager'].present_text( + _('emoticons enabled'), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _('emoticons disabled'), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_has_attribute.py b/src/fenrirscreenreader/commands/commands/toggle_has_attribute.py index b9eb7ea3..04534e81 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_has_attribute.py +++ b/src/fenrirscreenreader/commands/commands/toggle_has_attribute.py @@ -4,22 +4,34 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables the announcement of attributes') - - def run(self): - self.env['runtime']['settingsManager'].setSetting('general', 'hasAttributes', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'): - self.env['runtime']['outputManager'].presentText(_("announcement of attributes enabled"), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_("announcement of attributes disabled"), soundIcon='', interrupt=True) - - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables the announcement of attributes') + + def run(self): + self.env['runtime']['SettingsManager'].set_setting( + 'general', 'hasattributes', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'): + self.env['runtime']['OutputManager'].present_text( + _("announcement of attributes enabled"), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _("announcement of attributes disabled"), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py b/src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py index e2782c4d..f0cc2701 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py +++ b/src/fenrirscreenreader/commands/commands/toggle_highlight_tracking.py @@ -4,25 +4,37 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('enables or disables tracking of highlighted text') - - def run(self): - currMode = self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') - self.env['runtime']['settingsManager'].setSetting('focus', 'highlight', str(not currMode)) - self.env['runtime']['settingsManager'].setSetting('focus', 'cursor', str(currMode)) - if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): - self.env['runtime']['outputManager'].presentText(_('highlight tracking'), soundIcon='', interrupt=True) - else: - self.env['runtime']['outputManager'].presentText(_('cursor tracking'), soundIcon='', interrupt=True) - - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('enables or disables tracking of highlighted text') + + def run(self): + curr_mode = self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'highlight') + + self.env['runtime']['SettingsManager'].set_setting( + 'focus', 'highlight', str(not curr_mode)) + self.env['runtime']['SettingsManager'].set_setting( + 'focus', 'cursor', str(curr_mode)) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'highlight'): + self.env['runtime']['OutputManager'].present_text( + _('highlight tracking'), sound_icon ='', interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _('cursor tracking'), sound_icon ='', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_output.py b/src/fenrirscreenreader/commands/commands/toggle_output.py index f932fcd2..bd5237a1 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_output.py +++ b/src/fenrirscreenreader/commands/commands/toggle_output.py @@ -5,26 +5,41 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('toggles all output settings') - - def run(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled') or \ - self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - self.env['runtime']['outputManager'].presentText(_('Fenrir muted'), soundIcon='Accept', interrupt=True) - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','False') - self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','False') - else: - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','True') - self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','True') - self.env['runtime']['outputManager'].presentText(_('Fenrir unmuted'), soundIcon='Cancel', interrupt=True) - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('toggles all output settings') + + def run(self): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', + 'enabled') or self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', + 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _('Fenrir muted'), sound_icon ='Accept', interrupt=True) + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', 'False') + self.env['runtime']['SettingsManager'].set_setting( + 'sound', 'enabled', 'False') + else: + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', 'True') + self.env['runtime']['SettingsManager'].set_setting( + 'sound', 'enabled', 'True') + self.env['runtime']['OutputManager'].present_text( + _('Fenrir unmuted'), sound_icon ='Cancel', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_punctuation_level.py b/src/fenrirscreenreader/commands/commands/toggle_punctuation_level.py index 7721e401..970696c9 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_punctuation_level.py +++ b/src/fenrirscreenreader/commands/commands/toggle_punctuation_level.py @@ -5,21 +5,30 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - + + def get_description(self): + return '' + def run(self): - if self.env['runtime']['punctuationManager'].cyclePunctuation(): - self.env['runtime']['outputManager'].presentText(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel'), interrupt=True, ignorePunctuation=True) + if self.env['runtime']['PunctuationManager'].cycle_punctuation(): + self.env['runtime']['OutputManager'].present_text( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'punctuationLevel'), interrupt=True, ignore_punctuation=True) else: - self.env['runtime']['outputManager'].presentText(_('No punctuation found.'), interrupt=True, ignorePunctuation=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('No punctuation found.'), interrupt=True, ignore_punctuation=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_sound.py b/src/fenrirscreenreader/commands/commands/toggle_sound.py index 41097d17..71eb1352 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_sound.py +++ b/src/fenrirscreenreader/commands/commands/toggle_sound.py @@ -4,22 +4,35 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables sound') + pass + + def get_description(self): + return _('enables or disables sound') def run(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - self.env['runtime']['outputManager'].presentText(_('sound disabled'), soundIcon='SoundOff', interrupt=True) - self.env['runtime']['settingsManager'].setSetting('sound', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - self.env['runtime']['outputManager'].presentText(_('sound enabled'), soundIcon='SoundOn', interrupt=True) - - def setCallback(self, callback): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _('sound disabled'), sound_icon ='SoundOff', interrupt=True) + self.env['runtime']['SettingsManager'].set_setting( + 'sound', 'enabled', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _('sound enabled'), sound_icon ='SoundOn', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_speech.py b/src/fenrirscreenreader/commands/commands/toggle_speech.py index c58e9d21..16aa98ae 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_speech.py +++ b/src/fenrirscreenreader/commands/commands/toggle_speech.py @@ -5,23 +5,36 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shutdown(self): - pass - def getDescription(self): - return _('enables or disables speech') - - def run(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): - self.env['runtime']['outputManager'].interruptOutput() - self.env['runtime']['outputManager'].presentText(_('speech disabled'), soundIcon='SpeechOff', interrupt=True) - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'))) - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): - self.env['runtime']['outputManager'].presentText(_('speech enabled'), soundIcon='SpeechOn', interrupt=True) - def setCallback(self, callback): + def shutdown(self): + pass + + def get_description(self): + return _('enables or disables speech') + + def run(self): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'): + self.env['runtime']['OutputManager'].interrupt_output() + self.env['runtime']['OutputManager'].present_text( + _('speech disabled'), sound_icon ='SpeechOff', interrupt=True) + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'))) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'): + self.env['runtime']['OutputManager'].present_text( + _('speech enabled'), sound_icon ='SpeechOn', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py b/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py index 9c98f4ba..e57be4ec 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py +++ b/src/fenrirscreenreader/commands/commands/toggle_tutorial_mode.py @@ -5,19 +5,30 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - self.env['runtime']['helpManager'].toggleTutorialMode() - return _('Exiting tutorial mode. To enter tutorial mode again press Fenrir+f1') - def run(self): - self.env['runtime']['helpManager'].toggleTutorialMode() - if self.env['runtime']['helpManager'].isTutorialMode(): - self.env['runtime']['outputManager'].presentText( _('Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1.'), interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + self.env['runtime']['HelpManager'].toggle_tutorial_mode() + return _( + 'Exiting tutorial mode. To enter tutorial mode again press Fenrir+f1') + + def run(self): + self.env['runtime']['HelpManager'].toggle_tutorial_mode() + if self.env['runtime']['HelpManager'].is_tutorial_mode(): + self.env['runtime']['OutputManager'].present_text( + _('Entering tutorial mode. In this mode commands are described but not executed. You can move through the list of commands with the up and down arrow keys. To Exit tutorial mode press Fenrir+f1.'), + interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py b/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py index 89cdf81d..6093efab 100644 --- a/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py +++ b/src/fenrirscreenreader/commands/commands/toggle_vmenu_mode.py @@ -5,21 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - self.env['runtime']['vmenuManager'].togglelVMenuMode() - return _('Entering or Leaving v menu mode.') - def run(self): - self.env['runtime']['vmenuManager'].togglelVMenuMode() - if self.env['runtime']['vmenuManager'].getActive(): - self.env['runtime']['outputManager'].presentText( _('Entering v menu.'), interrupt=True) - else: - self.env['runtime']['outputManager'].presentText( _('Leaving v menu.'), interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + self.env['runtime']['VmenuManager'].toggle_vmenu_mode() + return _('Entering or Leaving v menu mode.') + + def run(self): + self.env['runtime']['VmenuManager'].toggle_vmenu_mode() + if self.env['runtime']['VmenuManager'].get_active(): + self.env['runtime']['OutputManager'].present_text( + _('Entering v menu.'), interrupt=True) + else: + self.env['runtime']['OutputManager'].present_text( + _('Leaving v menu.'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser.py b/src/fenrirscreenreader/commands/commands/voice_browser.py index 64d7806f..fb387f8a 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser.py @@ -1,207 +1,226 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import subprocess import time + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment self.testMessage = "This is a voice test. The quick brown fox jumps over the lazy dog." self.modules = [] self.voices = [] - self.moduleIndex = 0 - self.voiceIndex = 0 + self.module_index = 0 + self.voice_index = 0 self.browserActive = False self.originalBindings = {} self.lastAnnounceTime = 0 - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Interactive voice browser with arrow key navigation" - + def run(self): if self.browserActive: - self.exitVoiceBrowser() + self.exit_voice_browser() return - - self.env['runtime']['outputManager'].presentText("Starting voice browser", interrupt=True) - + + self.env['runtime']['OutputManager'].present_text( + "Starting voice browser", interrupt=True) + # Load modules - self.modules = self.getSpeechdModules() + self.modules = self.get_speechd_modules() if not self.modules: - self.env['runtime']['outputManager'].presentText("No speech modules found", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') + self.env['runtime']['OutputManager'].present_text( + "No speech modules found", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') return - + # Set current module - currentModule = self.env['runtime']['settingsManager'].getSetting('speech', 'module') - if currentModule and currentModule in self.modules: - self.moduleIndex = self.modules.index(currentModule) - + current_module = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'module') + if current_module and current_module in self.modules: + self.module_index = self.modules.index(current_module) + # Load voices - self.loadVoicesForCurrentModule() - + self.load_voices_for_current_module() + # Set current voice - currentVoice = self.env['runtime']['settingsManager'].getSetting('speech', 'voice') - if currentVoice and currentVoice in self.voices: - self.voiceIndex = self.voices.index(currentVoice) - + current_voice = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'voice') + if current_voice and current_voice in self.voices: + self.voice_index = self.voices.index(current_voice) + # Enter browser mode - self.enterVoiceBrowser() - self.announceCurrentSelection() - - def enterVoiceBrowser(self): + self.enter_voice_browser() + self.announce_current_selection() + + def enter_voice_browser(self): """Enter voice browser mode with custom key bindings""" self.browserActive = True - + # Store original bindings self.originalBindings = self.env['bindings'].copy() - + # Override navigation keys for voice browsing # Use lambda to capture self and create bound methods self.env['bindings'][str([1, ['KEY_UP']])] = 'VOICE_BROWSER_PREV_VOICE' - self.env['bindings'][str([1, ['KEY_DOWN']])] = 'VOICE_BROWSER_NEXT_VOICE' - self.env['bindings'][str([1, ['KEY_LEFT']])] = 'VOICE_BROWSER_PREV_MODULE' - self.env['bindings'][str([1, ['KEY_RIGHT']])] = 'VOICE_BROWSER_NEXT_MODULE' + self.env['bindings'][str([1, ['KEY_DOWN']]) + ] = 'VOICE_BROWSER_NEXT_VOICE' + self.env['bindings'][str([1, ['KEY_LEFT']]) + ] = 'VOICE_BROWSER_PREV_MODULE' + self.env['bindings'][str([1, ['KEY_RIGHT']]) + ] = 'VOICE_BROWSER_NEXT_MODULE' self.env['bindings'][str([1, ['KEY_ENTER']])] = 'VOICE_BROWSER_TEST' self.env['bindings'][str([1, ['KEY_SPACE']])] = 'VOICE_BROWSER_APPLY' self.env['bindings'][str([1, ['KEY_ESC']])] = 'VOICE_BROWSER_EXIT' - + # Register browser commands - self.registerBrowserCommands() - - self.env['runtime']['outputManager'].presentText("Voice browser active", interrupt=True) - self.env['runtime']['outputManager'].presentText("Up/Down=voices, Left/Right=modules, Enter=test, Space=apply, Esc=exit", interrupt=True) - - def registerBrowserCommands(self): + self.register_browser_commands() + + self.env['runtime']['OutputManager'].present_text( + "Voice browser active", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "Up/Down=voices, Left/Right=modules, Enter=test, Space=apply, Esc=exit", + interrupt=True) + + def register_browser_commands(self): """Register voice browser commands with the command manager""" # Create command objects for voice browser actions - commandManager = self.env['runtime']['commandManager'] - + CommandManager = self.env['runtime']['CommandManager'] + # This is a hack - we'll store references to our methods in the environment # so the key handlers can call them if 'voiceBrowserInstance' not in self.env['runtime']: self.env['runtime']['voiceBrowserInstance'] = self - - def exitVoiceBrowser(self): + + def exit_voice_browser(self): """Exit voice browser and restore normal key bindings""" if not self.browserActive: return - + self.browserActive = False - + # Restore original bindings self.env['bindings'] = self.originalBindings - + # Clean up if 'voiceBrowserInstance' in self.env['runtime']: del self.env['runtime']['voiceBrowserInstance'] - - self.env['runtime']['outputManager'].presentText("Voice browser exited", interrupt=True) - - def loadVoicesForCurrentModule(self): + + self.env['runtime']['OutputManager'].present_text( + "Voice browser exited", interrupt=True) + + def load_voices_for_current_module(self): """Load voices for current module""" - if self.moduleIndex < len(self.modules): - module = self.modules[self.moduleIndex] - self.voices = self.getModuleVoices(module) - self.voiceIndex = 0 # Reset to first voice when changing modules - - def announceCurrentSelection(self): + if self.module_index < len(self.modules): + module = self.modules[self.module_index] + self.voices = self.get_module_voices(module) + self.voice_index = 0 # Reset to first voice when changing modules + + def announce_current_selection(self): """Announce current module and voice""" # Throttle announcements to avoid spam now = time.time() if now - self.lastAnnounceTime < 0.3: return self.lastAnnounceTime = now - - if not self.modules or self.moduleIndex >= len(self.modules): + + if not self.modules or self.module_index >= len(self.modules): return - - module = self.modules[self.moduleIndex] - if self.voices and self.voiceIndex < len(self.voices): - voice = self.voices[self.voiceIndex] - self.env['runtime']['outputManager'].presentText( - f"{module}: {voice} ({self.voiceIndex + 1}/{len(self.voices)})", interrupt=True + + module = self.modules[self.module_index] + if self.voices and self.voice_index < len(self.voices): + voice = self.voices[self.voice_index] + self.env['runtime']['OutputManager'].present_text( + f"{module}: {voice} ({self.voice_index + 1}/{len(self.voices)})", interrupt=True ) else: - self.env['runtime']['outputManager'].presentText(f"{module}: No voices", interrupt=True) - - def nextVoice(self): + self.env['runtime']['OutputManager'].present_text( + f"{module}: No voices", interrupt=True) + + def next_voice(self): """Move to next voice""" if not self.voices: return - self.voiceIndex = (self.voiceIndex + 1) % len(self.voices) - self.announceCurrentSelection() - - def prevVoice(self): + self.voice_index = (self.voice_index + 1) % len(self.voices) + self.announce_current_selection() + + def prev_voice(self): """Move to previous voice""" if not self.voices: return - self.voiceIndex = (self.voiceIndex - 1) % len(self.voices) - self.announceCurrentSelection() - - def nextModule(self): + self.voice_index = (self.voice_index - 1) % len(self.voices) + self.announce_current_selection() + + def next_module(self): """Move to next module""" - self.moduleIndex = (self.moduleIndex + 1) % len(self.modules) - self.loadVoicesForCurrentModule() - self.announceCurrentSelection() - - def prevModule(self): + self.module_index = (self.module_index + 1) % len(self.modules) + self.load_voices_for_current_module() + self.announce_current_selection() + + def prev_module(self): """Move to previous module""" - self.moduleIndex = (self.moduleIndex - 1) % len(self.modules) - self.loadVoicesForCurrentModule() - self.announceCurrentSelection() - - def testVoice(self): + self.module_index = (self.module_index - 1) % len(self.modules) + self.load_voices_for_current_module() + self.announce_current_selection() + + def test_voice(self): """Test current voice""" - if not self.voices or self.voiceIndex >= len(self.voices): - self.env['runtime']['outputManager'].presentText("No voice selected", interrupt=True) + if not self.voices or self.voice_index >= len(self.voices): + self.env['runtime']['OutputManager'].present_text( + "No voice selected", interrupt=True) return - - module = self.modules[self.moduleIndex] - voice = self.voices[self.voiceIndex] - - self.env['runtime']['outputManager'].presentText("Testing...", interrupt=True) - if self.previewVoice(module, voice): + + module = self.modules[self.module_index] + voice = self.voices[self.voice_index] + + self.env['runtime']['OutputManager'].present_text( + "Testing...", interrupt=True) + if self.preview_voice(module, voice): # Store for apply command self.env['commandBuffer']['lastTestedModule'] = module self.env['commandBuffer']['lastTestedVoice'] = voice - self.env['runtime']['outputManager'].playSound('Accept') + self.env['runtime']['OutputManager'].play_sound('Accept') else: - self.env['runtime']['outputManager'].playSound('Error') - - def applyVoice(self): + self.env['runtime']['OutputManager'].play_sound('Error') + + def apply_voice(self): """Apply current voice to Fenrir""" - if not self.voices or self.voiceIndex >= len(self.voices): + if not self.voices or self.voice_index >= len(self.voices): return - - module = self.modules[self.moduleIndex] - voice = self.voices[self.voiceIndex] - + + module = self.modules[self.module_index] + voice = self.voices[self.voice_index] + try: - settingsManager = self.env['runtime']['settingsManager'] - settingsManager.settings['speech']['driver'] = 'speechdDriver' - settingsManager.settings['speech']['module'] = module - settingsManager.settings['speech']['voice'] = voice - - if 'speechDriver' in self.env['runtime']: - speechDriver = self.env['runtime']['speechDriver'] - speechDriver.shutdown() - speechDriver.initialize(self.env) - - self.env['runtime']['outputManager'].presentText("Voice applied!", interrupt=True) - self.env['runtime']['outputManager'].playSound('Accept') - + SettingsManager = self.env['runtime']['SettingsManager'] + SettingsManager.settings['speech']['driver'] = 'speechdDriver' + SettingsManager.settings['speech']['module'] = module + SettingsManager.settings['speech']['voice'] = voice + + if 'SpeechDriver' in self.env['runtime']: + SpeechDriver = self.env['runtime']['SpeechDriver'] + SpeechDriver.shutdown() + SpeechDriver.initialize(self.env) + + self.env['runtime']['OutputManager'].present_text( + "Voice applied!", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Accept') + except Exception as e: - self.env['runtime']['outputManager'].presentText("Apply failed", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') - - def previewVoice(self, module, voice): + self.env['runtime']['OutputManager'].present_text( + "Apply failed", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') + + def preview_voice(self, module, voice): """Test voice with spd-say""" try: cmd = ['spd-say', '-o', module, '-y', voice, self.testMessage] @@ -209,22 +228,24 @@ class command(): return result.returncode == 0 except Exception: return False - - def getSpeechdModules(self): + + def get_speechd_modules(self): """Get available speech modules""" try: - result = subprocess.run(['spd-say', '-O'], capture_output=True, text=True, timeout=10) + result = subprocess.run( + ['spd-say', '-O'], capture_output=True, text=True, timeout=10) if result.returncode == 0: lines = result.stdout.strip().split('\n') return [line.strip() for line in lines[1:] if line.strip()] except Exception: pass return [] - - def getModuleVoices(self, module): + + def get_module_voices(self, module): """Get voices for module""" try: - result = subprocess.run(['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=10) + result = subprocess.run( + ['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=10) if result.returncode == 0: lines = result.stdout.strip().split('\n') voices = [] @@ -232,7 +253,7 @@ class command(): if not line.strip(): continue if module.lower() == 'espeak-ng': - voice = self.processEspeakVoice(line) + voice = self.process_espeak_voice(line) if voice: voices.append(voice) else: @@ -241,15 +262,15 @@ class command(): except Exception: pass return [] - - def processEspeakVoice(self, voiceLine): + + def process_espeak_voice(self, voiceLine): """Process espeak voice format""" parts = [p for p in voiceLine.split() if p] if len(parts) < 2: return None - langCode = parts[-2].lower() + lang_code = parts[-2].lower() variant = parts[-1].lower() - return f"{langCode}+{variant}" if variant and variant != 'none' else langCode - - def setCallback(self, callback): - pass \ No newline at end of file + return f"{lang_code}+{variant}" if variant and variant != 'none' else lang_code + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_apply.py b/src/fenrirscreenreader/commands/commands/voice_browser_apply.py index 1f0048d4..c4940ae4 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_apply.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_apply.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: apply current voice" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].applyVoice() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].apply_voice() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_exit.py b/src/fenrirscreenreader/commands/commands/voice_browser_exit.py index c8d5d17d..f351984f 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_exit.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_exit.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: exit browser mode" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].exitVoiceBrowser() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].exit_voice_browser() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_next_module.py b/src/fenrirscreenreader/commands/commands/voice_browser_next_module.py index a2dc1d01..44551589 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_next_module.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_next_module.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: next module" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].nextModule() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].next_module() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_next_voice.py b/src/fenrirscreenreader/commands/commands/voice_browser_next_voice.py index 5e56b42e..6fc8ca5c 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_next_voice.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_next_voice.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: next voice" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].nextVoice() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].next_voice() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_prev_module.py b/src/fenrirscreenreader/commands/commands/voice_browser_prev_module.py index b7add887..e8ab884f 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_prev_module.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_prev_module.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: previous module" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].prevModule() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].prev_module() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_prev_voice.py b/src/fenrirscreenreader/commands/commands/voice_browser_prev_voice.py index 24c858f5..4372c1ad 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_prev_voice.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_prev_voice.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: previous voice" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].prevVoice() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].prev_voice() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_safe.py b/src/fenrirscreenreader/commands/commands/voice_browser_safe.py index 2f59aaba..ccbb0386 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_safe.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_safe.py @@ -1,134 +1,153 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import subprocess import threading import time + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment self.testMessage = "Voice test: The quick brown fox jumps over the lazy dog." - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Safe voice browser - cycles through voices without hanging" - + def run(self): try: - self.env['runtime']['outputManager'].presentText("Starting safe voice browser", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Starting safe voice browser", interrupt=True) + # Get modules with timeout protection - modules = self.getSpeechdModulesWithTimeout() + modules = self.get_speechd_modules_with_timeout() if not modules: - self.env['runtime']['outputManager'].presentText("No speech modules found", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "No speech modules found", interrupt=True) return - + # Get current position from commandBuffer or start fresh - moduleIndex = self.env['commandBuffer'].get('safeBrowserModuleIndex', 0) - voiceIndex = self.env['commandBuffer'].get('safeBrowserVoiceIndex', 0) - + module_index = self.env['commandBuffer'].get( + 'safeBrowserModuleIndex', 0) + voice_index = self.env['commandBuffer'].get( + 'safeBrowserVoiceIndex', 0) + # Ensure valid module index - if moduleIndex >= len(modules): - moduleIndex = 0 - - currentModule = modules[moduleIndex] - self.env['runtime']['outputManager'].presentText(f"Loading voices for {currentModule}...", interrupt=True) - + if module_index >= len(modules): + module_index = 0 + + current_module = modules[module_index] + self.env['runtime']['OutputManager'].present_text( + f"Loading voices for {current_module}...", interrupt=True) + # Get voices with timeout protection - voices = self.getModuleVoicesWithTimeout(currentModule) + voices = self.get_module_voices_with_timeout(current_module) if not voices: - self.env['runtime']['outputManager'].presentText(f"No voices in {currentModule}, trying next module", interrupt=True) - moduleIndex = (moduleIndex + 1) % len(modules) - self.env['commandBuffer']['safeBrowserModuleIndex'] = moduleIndex + self.env['runtime']['OutputManager'].present_text( + f"No voices in {current_module}, trying next module", interrupt=True) + module_index = (module_index + 1) % len(modules) + self.env['commandBuffer']['safeBrowserModuleIndex'] = module_index self.env['commandBuffer']['safeBrowserVoiceIndex'] = 0 return - + # Ensure valid voice index - if voiceIndex >= len(voices): - voiceIndex = 0 - - currentVoice = voices[voiceIndex] - + if voice_index >= len(voices): + voice_index = 0 + + current_voice = voices[voice_index] + # Announce current selection - self.env['runtime']['outputManager'].presentText( - f"Module: {currentModule} ({moduleIndex + 1}/{len(modules)})", interrupt=True + self.env['runtime']['OutputManager'].present_text( + f"Module: {current_module} ({module_index + 1}/{len(modules)})", interrupt=True ) - self.env['runtime']['outputManager'].presentText( - f"Voice: {currentVoice} ({voiceIndex + 1}/{len(voices)})", interrupt=True + self.env['runtime']['OutputManager'].present_text( + f"Voice: {current_voice} ({voice_index + 1}/{len(voices)})", interrupt=True ) - + # Test voice in background thread to avoid blocking - self.env['runtime']['outputManager'].presentText("Testing voice...", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Testing voice...", interrupt=True) + # Use threading to prevent freezing - testThread = threading.Thread(target=self.testVoiceAsync, args=(currentModule, currentVoice)) - testThread.daemon = True - testThread.start() - + test_thread = threading.Thread( + target=self.test_voice_async, args=( + current_module, current_voice)) + test_thread.daemon = True + test_thread.start() + # Store tested voice for apply command - self.env['commandBuffer']['lastTestedModule'] = currentModule - self.env['commandBuffer']['lastTestedVoice'] = currentVoice - + self.env['commandBuffer']['lastTestedModule'] = current_module + self.env['commandBuffer']['lastTestedVoice'] = current_voice + # Advance to next voice for next run - voiceIndex += 1 - if voiceIndex >= len(voices): - voiceIndex = 0 - moduleIndex = (moduleIndex + 1) % len(modules) - + voice_index += 1 + if voice_index >= len(voices): + voice_index = 0 + module_index = (module_index + 1) % len(modules) + # Store position for next run - self.env['commandBuffer']['safeBrowserModuleIndex'] = moduleIndex - self.env['commandBuffer']['safeBrowserVoiceIndex'] = voiceIndex - + self.env['commandBuffer']['safeBrowserModuleIndex'] = module_index + self.env['commandBuffer']['safeBrowserVoiceIndex'] = voice_index + # Give instructions - self.env['runtime']['outputManager'].presentText("Run again for next voice, or use apply voice command", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Run again for next voice, or use apply voice command", interrupt=True) + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Voice browser error: {str(e)}", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') - - def testVoiceAsync(self, module, voice): + self.env['runtime']['OutputManager'].present_text( + f"Voice browser error: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') + + def test_voice_async(self, module, voice): """Test voice in background thread to avoid blocking""" try: # Run with strict timeout cmd = ['spd-say', '-o', module, '-y', voice, self.testMessage] result = subprocess.run(cmd, timeout=5, capture_output=True) - + # Schedule success sound for main thread if result.returncode == 0: - # We can't call outputManager from background thread safely + # We can't call OutputManager from background thread safely # So we'll just let the main thread handle feedback pass - + except subprocess.TimeoutExpired: # Voice test timed out - this is okay, don't crash pass except Exception: # Any other error - also okay, don't crash pass - - def getSpeechdModulesWithTimeout(self): + + def get_speechd_modules_with_timeout(self): """Get speech modules with timeout protection""" try: - result = subprocess.run(['spd-say', '-O'], capture_output=True, text=True, timeout=3) + result = subprocess.run( + ['spd-say', '-O'], capture_output=True, text=True, timeout=3) if result.returncode == 0: lines = result.stdout.strip().split('\n') modules = [line.strip() for line in lines[1:] if line.strip()] - return modules[:10] # Limit to first 10 modules to prevent overload + # Limit to first 10 modules to prevent overload + return modules[:10] except subprocess.TimeoutExpired: - self.env['runtime']['outputManager'].presentText("Module detection timed out", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "Module detection timed out", interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Module detection failed: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"Module detection failed: {str(e)}", interrupt=True) return [] - - def getModuleVoicesWithTimeout(self, module): + + def get_module_voices_with_timeout(self, module): """Get voices with timeout and limits""" try: - result = subprocess.run(['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=5) + result = subprocess.run( + ['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=5) if result.returncode == 0: lines = result.stdout.strip().split('\n') voices = [] @@ -136,35 +155,38 @@ class command(): if not line.strip(): continue if module.lower() == 'espeak-ng': - voice = self.processEspeakVoice(line) + voice = self.process_espeak_voice(line) if voice: voices.append(voice) else: voices.append(line.strip()) - + # Limit voice count to prevent memory issues if len(voices) > 1000: - self.env['runtime']['outputManager'].presentText(f"Found {len(voices)} voices, limiting to first 1000", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"found {len(voices)} voices, limiting to first 1000", interrupt=True) voices = voices[:1000] - + return voices except subprocess.TimeoutExpired: - self.env['runtime']['outputManager'].presentText(f"Voice detection for {module} timed out", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"Voice detection for {module} timed out", interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Voice detection failed: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"Voice detection failed: {str(e)}", interrupt=True) return [] - - def processEspeakVoice(self, voiceLine): + + def process_espeak_voice(self, voiceLine): """Process espeak voice format""" try: parts = [p for p in voiceLine.split() if p] if len(parts) < 2: return None - langCode = parts[-2].lower() + lang_code = parts[-2].lower() variant = parts[-1].lower() - return f"{langCode}+{variant}" if variant and variant != 'none' else langCode + return f"{lang_code}+{variant}" if variant and variant != 'none' else lang_code except Exception: return None - - def setCallback(self, callback): - pass \ No newline at end of file + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/commands/voice_browser_test.py b/src/fenrirscreenreader/commands/commands/voice_browser_test.py index 9c023de4..25fd0beb 100644 --- a/src/fenrirscreenreader/commands/commands/voice_browser_test.py +++ b/src/fenrirscreenreader/commands/commands/voice_browser_test.py @@ -1,21 +1,24 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Voice browser: test current voice" - + def run(self): if 'voiceBrowserInstance' in self.env['runtime']: - self.env['runtime']['voiceBrowserInstance'].testVoice() - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['voiceBrowserInstance'].test_voice() + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/help/curr_help.py b/src/fenrirscreenreader/commands/help/curr_help.py index 3586c63d..dbf734bd 100644 --- a/src/fenrirscreenreader/commands/help/curr_help.py +++ b/src/fenrirscreenreader/commands/help/curr_help.py @@ -4,17 +4,25 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get current help message') - def run(self): - text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get current help message') + + def run(self): + text = self.env['runtime']['HelpManager'].get_help_for_current_index() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/help/next_help.py b/src/fenrirscreenreader/commands/help/next_help.py index 3e4819b2..94e21295 100644 --- a/src/fenrirscreenreader/commands/help/next_help.py +++ b/src/fenrirscreenreader/commands/help/next_help.py @@ -4,18 +4,26 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get next help message') - def run(self): - self.env['runtime']['helpManager'].nextIndex() - text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get next help message') + + def run(self): + self.env['runtime']['HelpManager'].next_index() + text = self.env['runtime']['HelpManager'].get_help_for_current_index() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/help/prev_help.py b/src/fenrirscreenreader/commands/help/prev_help.py index 62ad1d98..c33e14ac 100644 --- a/src/fenrirscreenreader/commands/help/prev_help.py +++ b/src/fenrirscreenreader/commands/help/prev_help.py @@ -4,18 +4,26 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get prev help message') - def run(self): - self.env['runtime']['helpManager'].prevIndex() - text = self.env['runtime']['helpManager'].getHelpForCurrentIndex() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get prev help message') + + def run(self): + self.env['runtime']['HelpManager'].prev_index() + text = self.env['runtime']['HelpManager'].get_help_for_current_index() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onByteInput/10000-shut_up.py b/src/fenrirscreenreader/commands/onByteInput/10000-shut_up.py index ef808a0f..f8971eeb 100644 --- a/src/fenrirscreenreader/commands/onByteInput/10000-shut_up.py +++ b/src/fenrirscreenreader/commands/onByteInput/10000-shut_up.py @@ -5,32 +5,43 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - + + def get_description(self): + return '' + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'interruptOnKeyPress'): - return - if self.env['runtime']['inputManager'].noKeyPressed(): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'interruptOnKeyPress'): return - if self.env['runtime']['screenManager'].isScreenChange(): + if self.env['runtime']['InputManager'].no_key_pressed(): return - if len(self.env['input']['currInput']) <= len(self.env['input']['prevInput']): + if self.env['runtime']['ScreenManager'].is_screen_change(): + return + if len( + self.env['input']['currInput']) <= len( + self.env['input']['prevInput']): return # if the filter is set - if self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').strip() != '': - filterList = self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').split(',') + if self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'interruptOnKeyPressFilter').strip() != '': + filter_list = self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'interruptOnKeyPressFilter').split(',') for currInput in self.env['input']['currInput']: - if not currInput in filterList: - return - self.env['runtime']['outputManager'].interruptOutput() + if currInput not in filter_list: + return + self.env['runtime']['OutputManager'].interrupt_output() - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py b/src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py index 07fa7865..3bd28d11 100644 --- a/src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py +++ b/src/fenrirscreenreader/commands/onByteInput/15000-enable_temp_speech.py @@ -5,25 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('disables speech until next keypress') - + pass + + def get_description(self): + return _('disables speech until next keypress') + def run(self): if not self.env['commandBuffer']['enableSpeechOnKeypress']: return - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(self.env['commandBuffer']['enableSpeechOnKeypress'])) + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', str( + self.env['commandBuffer']['enableSpeechOnKeypress'])) self.env['commandBuffer']['enableSpeechOnKeypress'] = False # Also disable prompt watching since speech was manually re-enabled if 'silenceUntilPrompt' in self.env['commandBuffer']: self.env['commandBuffer']['silenceUntilPrompt'] = False - self.env['runtime']['outputManager'].presentText(_("speech enabled"), soundIcon='SpeechOn', interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("speech enabled"), sound_icon ='SpeechOn', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py b/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py index e940c6de..bd897e34 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py +++ b/src/fenrirscreenreader/commands/onCursorChange/15000-char_echo.py @@ -5,19 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No Description found' def run(self): - # enabled? - active = self.env['runtime']['settingsManager'].getSettingAsInt('keyboard', 'charEchoMode') + # enabled? + active = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'keyboard', 'charEchoMode') # 0 = off if active == 0: return @@ -25,29 +32,39 @@ class command(): if active == 2: if not self.env['input']['newCapsLock']: return - # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now) - xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']) - if xMove > 3: + # big changes are no char (but the value is bigger than one maybe the + # differ needs longer than you can type, so a little strange random + # buffer for now) + x_move = abs( + self.env['screen']['new_cursor']['x'] - + self.env['screen']['old_cursor']['x']) + if x_move > 3: return - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - if self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_TAB']]: - return - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: - if self.env['runtime']['byteManager'].getLastByteKey() in [b' ', b'\t']: - return - # detect deletion or chilling - if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']: + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + if self.env['runtime']['InputManager'].get_last_deepest_input() in [ + ['KEY_TAB']]: + return + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: + if self.env['runtime']['ByteManager'].get_last_byte_key() in [ + b' ', b'\t']: + return + # detect deletion or chilling + if self.env['screen']['new_cursor']['x'] <= self.env['screen']['old_cursor']['x']: return # is there any change? - if not self.env['runtime']['screenManager'].isDelta(): + if not self.env['runtime']['ScreenManager'].is_delta(): return # filter unneded space on word begin - currDelta = self.env['screen']['newDelta'] - if len(currDelta.strip()) != len(currDelta) and \ - currDelta.strip() != '': - currDelta = currDelta.strip() - self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) + curr_delta = self.env['screen']['new_delta'] + if len(curr_delta.strip()) != len(curr_delta) and \ + curr_delta.strip() != '': + curr_delta = curr_delta.strip() + self.env['runtime']['OutputManager'].present_text( + curr_delta, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py b/src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py index 6a05cdef..ace1e51d 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py +++ b/src/fenrirscreenreader/commands/onCursorChange/25000-word_echo_type.py @@ -4,54 +4,65 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils import string + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - # is it enabled? - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'): + # is it enabled? + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'wordEcho'): return # is naviation? - if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1: + if self.env['screen']['new_cursor']['x'] - \ + self.env['screen']['old_cursor']['x'] != 1: return # just when cursor move worddetection is needed - if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + if not self.env['runtime']['CursorManager'].is_cursor_horizontal_move(): return # for now no new line - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): return # currently writing - if self.env['runtime']['screenManager'].isDelta(): - return - - # get the word - newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] - x, y, currWord, endOfScreen, lineBreak = \ - word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) - - # is there a word? - if currWord == '': + if self.env['runtime']['ScreenManager'].is_delta(): return - # at the end of a word - if not newContent[self.env['screen']['newCursor']['x']].isspace(): + + # get the word + new_content = self.env['screen']['new_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['new_cursor']['x'], 0, new_content) + + # is there a word? + if curr_word == '': + return + # at the end of a word + if not new_content[self.env['screen']['new_cursor']['x']].isspace(): + return + # at the end of a word + if (x + + len(curr_word) != self.env['screen']['new_cursor']['x']) and (x + + len(curr_word) != self.env['screen']['new_cursor']['x'] - + 1): return - # at the end of a word - if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ - (x + len(currWord) != self.env['screen']['newCursor']['x']-1): - return - self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) + self.env['runtime']['OutputManager'].present_text( + curr_word, interrupt=True, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py b/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py index 61bccb1a..d79e33b2 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py +++ b/src/fenrirscreenreader/commands/onCursorChange/35000-spell_check.py @@ -4,8 +4,11 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils -import os, string +import os +import string initialized = False try: @@ -13,120 +16,160 @@ try: initialized = True except Exception as e: pass - + + class command(): def __init__(self): self.language = '' self.spellChecker = '' + def initialize(self, environment): self.env = environment - self.updateSpellLanguage() + self.update_spell_language() + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No Description found' - - def updateSpellLanguage(self): + + def update_spell_language(self): if not initialized: - return - self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')) - self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') + return + self.spellChecker = enchant.Dict( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage')) + self.language = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') def run(self): if not initialized: - return - if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'): return - if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language: + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoSpellCheck'): + return + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'spellCheckLanguage') != self.language: try: - self.updateSpellLanguage() + self.update_spell_language() except Exception as e: return # just when horizontal cursor move worddetection is needed - if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + if not self.env['runtime']['CursorManager'].is_cursor_horizontal_move(): return - + # for now no new line - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): return # more than a keyecho? - if len(self.env['screen']['newDelta']) > 1: - return - # deletion - if self.env['runtime']['screenManager'].isNegativeDelta(): - return - # first place could not be the end of a word - if self.env['screen']['newCursor']['x'] == 0: + if len(self.env['screen']['new_delta']) > 1: return - + # deletion + if self.env['runtime']['ScreenManager'].is_negative_delta(): + return + # first place could not be the end of a word + if self.env['screen']['new_cursor']['x'] == 0: + return + # get the word (just for speedup only look at current line - newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] - x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) + new_content = self.env['screen']['new_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['new_cursor']['x'], 0, new_content) # was this a typed word? - if self.env['runtime']['screenManager'].isDelta(): - if not(newContent[self.env['screen']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['oldCursor']['x']): + if self.env['runtime']['ScreenManager'].is_delta(): + if not (new_content[self.env['screen']['old_cursor']['x']] in string.whitespace + + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['old_cursor']['x']): return else: - currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~') + curr_word = curr_word.strip( + string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~') else: - # or just arrow arround? - if not newContent[self.env['screen']['newCursor']['x']].isspace(): + # or just arrow arround? + if not new_content[self.env['screen']['new_cursor']['x']].isspace(): + return + if (x + + len(curr_word) != self.env['screen']['new_cursor']['x']) and (x + + len(curr_word) != self.env['screen']['new_cursor']['x'] - + 1): return - if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ - (x + len(currWord) != self.env['screen']['newCursor']['x']-1): - return # just on end of word - if self.env['screen']['newCursor']['x'] > 0: - if not newContent[self.env['screen']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase: + if self.env['screen']['new_cursor']['x'] > 0: + if not new_content[self.env['screen']['old_cursor'] + ['x'] - 1].lower() in string.ascii_lowercase: return - + # ignore bash buildins - if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\ - 'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']: + if curr_word in [ + 'cd', + 'fg', + 'bg', + 'alias', + 'bind', + 'dir', + 'caller', + 'buildin', + 'command', + 'declare', + 'echo', + 'enable', + 'help', + 'let', + 'local', + 'logout', + 'mapfile', + 'printf', + 'read', + 'readarray', + 'source', + 'type', + 'typeset', + 'ulimit', + 'unalias']: return # ignore the application name - if currWord.upper() == 'FENRIR': - return - if currWord[0] =='-': + if curr_word.upper() == 'FENRIR': return - if currWord[0] == '/': + if curr_word[0] == '-': return - if currWord[0] == '#': + if curr_word[0] == '/': return - if currWord.startswith('./'): - return - if '@' in currWord and '.' in currWord: - return - if currWord[0] == '@': - return - if currWord.isnumeric(): - return - if currWord.isdecimal(): + if curr_word[0] == '#': return - if currWord.isspace(): + if curr_word.startswith('./'): return - + if '@' in curr_word and '.' in curr_word: + return + if curr_word[0] == '@': + return + if curr_word.isnumeric(): + return + if curr_word.isdecimal(): + return + if curr_word.isspace(): + return + try: - if os.path.exists("/bin/"+currWord): + if os.path.exists("/bin/" + curr_word): return except Exception as e: pass try: - if os.path.exists("/usr/bin/"+currWord): - return + if os.path.exists("/usr/bin/" + curr_word): + return except Exception as e: pass try: - if os.path.exists("/sbin/"+currWord): - return + if os.path.exists("/sbin/" + curr_word): + return except Exception as e: pass - if not self.spellChecker.check(currWord): - self.env['runtime']['outputManager'].presentText(_('misspelled'), soundIcon='mispell', interrupt=False, flush=False) + if not self.spellChecker.check(curr_word): + self.env['runtime']['OutputManager'].present_text( + _('misspelled'), sound_icon ='mispell', interrupt=False, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py b/src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py index 41feec75..425ff85b 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py +++ b/src/fenrirscreenreader/commands/onCursorChange/45000-char_delete_echo.py @@ -5,41 +5,53 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'charDeleteEcho'): return # detect typing or chilling - if self.env['screen']['newCursor']['x'] >= self.env['screen']['oldCursor']['x']: - return + if self.env['screen']['new_cursor']['x'] >= self.env['screen']['old_cursor']['x']: + return # More than just a deletion happend - if self.env['runtime']['screenManager'].isDelta(ignoreSpace=True): + if self.env['runtime']['ScreenManager'].is_delta(ignoreSpace=True): return # no deletion - if not self.env['runtime']['screenManager'].isNegativeDelta(): - return + if not self.env['runtime']['ScreenManager'].is_negative_delta(): + return # too much for a single backspace... # word begin produce a diff wiht len == 2 |a | others with 1 |a| if len(self.env['screen']['newNegativeDelta']) > 2: return - - currNegativeDelta = self.env['screen']['newNegativeDelta'] - if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \ - currNegativeDelta.strip() != '': - currNegativeDelta = currNegativeDelta.strip() - self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - def setCallback(self, callback): - pass + curr_negative_delta = self.env['screen']['newNegativeDelta'] + if len(curr_negative_delta.strip()) != len(curr_negative_delta) and \ + curr_negative_delta.strip() != '': + curr_negative_delta = curr_negative_delta.strip() + self.env['runtime']['OutputManager'].present_text( + curr_negative_delta, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py b/src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py index a6609ea5..e62bd65a 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py +++ b/src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py @@ -4,54 +4,72 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import char_utils from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - + + def get_description(self): + return '' + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'): - return - if self.env['runtime']['screenManager'].isScreenChange(): - return - # detect an change on the screen, we just want to cursor arround, so no change should appear - if self.env['runtime']['screenManager'].isDelta(): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'cursor'): return - if self.env['runtime']['screenManager'].isNegativeDelta(): + if self.env['runtime']['ScreenManager'].is_screen_change(): + return + # detect an change on the screen, we just want to cursor arround, so no + # change should appear + if self.env['runtime']['ScreenManager'].is_delta(): + return + if self.env['runtime']['ScreenManager'].is_negative_delta(): return # is a vertical change? - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): - return - # is it a horizontal change? - if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): return - - # echo word insteed of char - if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'): - if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) != 1: - # get the word - newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] - x, y, currWord, endOfScreen, lineBreak = \ - word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) - if self.env['screen']['newCursor']['x'] == x: - return - x, y, currChar = char_utils.getCurrentChar(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText']) - if currChar.isspace(): + # is it a horizontal change? + if not self.env['runtime']['CursorManager'].is_cursor_horizontal_move(): + return + + # echo word insteed of char + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'wordEcho'): + if abs(self.env['screen']['old_cursor']['x'] - + self.env['screen']['new_cursor']['x']) != 1: + # get the word + new_content = self.env['screen']['new_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['new_cursor']['x'], 0, new_content) + if self.env['screen']['new_cursor']['x'] == x: + return + x, y, curr_char = char_utils.get_current_char( + self.env['screen']['new_cursor']['x'], self.env['screen']['new_cursor']['y'], self.env['screen']['new_content_text']) + if curr_char.isspace(): # Only announce spaces during pure navigation (arrow keys) # Check if this is really navigation by looking at input history - if (self.env['runtime']['inputManager'].getShortcutType() in ['KEY'] and - self.env['runtime']['inputManager'].getLastDeepestInput()[0] in ['KEY_LEFT', 'KEY_RIGHT', 'KEY_UP', 'KEY_DOWN']): - char_utils.presentCharForReview(self.env, currChar, interrupt=True, announceCapital=True, flush=False) + if (self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY'] and self.env['runtime'][ + 'InputManager'].get_last_deepest_input()[0] in ['KEY_LEFT', 'KEY_RIGHT', 'KEY_UP', 'KEY_DOWN']): + char_utils.present_char_for_review( + self.env, curr_char, interrupt=True, announce_capital=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False) - def setCallback(self, callback): - pass + self.env['runtime']['OutputManager'].present_text( + curr_char, + interrupt=True, + ignore_punctuation=True, + announce_capital=True, + flush=False) + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py b/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py index b980c78e..d8996f4b 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py +++ b/src/fenrirscreenreader/commands/onCursorChange/55000-tab_completion.py @@ -5,44 +5,55 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No Description found' + def run(self): # try to detect the tab completion by cursor change - xMove = self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] - if xMove <= 0: + x_move = self.env['screen']['new_cursor']['x'] - \ + self.env['screen']['old_cursor']['x'] + if x_move <= 0: return - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_TAB']]): - if xMove < 5: - return - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + if not ( + self.env['runtime']['InputManager'].get_last_deepest_input() in [ + ['KEY_TAB']]): + if x_move < 5: + return + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: found = False - for currByte in self.env['runtime']['byteManager'].getLastByteKey(): + for currByte in self.env['runtime']['ByteManager'].get_last_byte_key( + ): if currByte == 9: found = True if not found: - if xMove < 5: - return + if x_move < 5: + return # is there any change? - if not self.env['runtime']['screenManager'].isDelta(): + if not self.env['runtime']['ScreenManager'].is_delta(): return - if not xMove == len(self.env['screen']['newDelta']): + if not x_move == len(self.env['screen']['new_delta']): return # filter unneded space on word begin - currDelta = self.env['screen']['newDelta'] - if len(currDelta.strip()) != len(currDelta) and \ - currDelta.strip() != '': - currDelta = currDelta.strip() - self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, announceCapital=True, flush=False) + curr_delta = self.env['screen']['new_delta'] + if len(curr_delta.strip()) != len(curr_delta) and \ + curr_delta.strip() != '': + curr_delta = curr_delta.strip() + self.env['runtime']['OutputManager'].present_text( + curr_delta, interrupt=True, announce_capital=True, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py b/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py index d108c1cd..3a23b24d 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py +++ b/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_navigation.py @@ -4,50 +4,58 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import word_utils import string + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - # is navigation? - if not abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) > 1: + # is navigation? + if not abs(self.env['screen']['old_cursor']['x'] - + self.env['screen']['new_cursor']['x']) > 1: return # just when cursor move worddetection is needed - if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + if not self.env['runtime']['CursorManager'].is_cursor_horizontal_move(): return # for now no new line - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): return # currently writing - if self.env['runtime']['screenManager'].isDelta(): - return - - # get the word - newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] - x, y, currWord, endOfScreen, lineBreak = \ - word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) - - # is there a word? - if currWord == '': + if self.env['runtime']['ScreenManager'].is_delta(): return - # at the start of a word - if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ - (self.env['screen']['newCursor']['x'] != x): - return + # get the word + new_content = self.env['screen']['new_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + x, y, curr_word, end_of_screen, line_break = word_utils.get_current_word( + self.env['screen']['new_cursor']['x'], 0, new_content) - self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) + # is there a word? + if curr_word == '': + return - def setCallback(self, callback): + # at the start of a word + if (x + len(curr_word) != self.env['screen']['new_cursor']['x']) and \ + (self.env['screen']['new_cursor']['x'] != x): + return + + self.env['runtime']['OutputManager'].present_text( + curr_word, interrupt=True, flush=False) + + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py b/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py index 057ffe27..53e67342 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py +++ b/src/fenrirscreenreader/commands/onCursorChange/65000-present_line_if_cursor_change_vertical.py @@ -4,58 +4,76 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): self.lastIdent = -1 + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - + + def get_description(self): + return '' + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'): - return - if self.env['runtime']['screenManager'].isScreenChange(): - self.lastIdent = 0 - return - # this leads to problems in vim -> status line change -> no announcement, so we do check the lengh as hack - if self.env['runtime']['screenManager'].isDelta(): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'cursor'): return - + if self.env['runtime']['ScreenManager'].is_screen_change(): + self.lastIdent = 0 + return + # this leads to problems in vim -> status line change -> no + # announcement, so we do check the lengh as hack + if self.env['runtime']['ScreenManager'].is_delta(): + return + # is a vertical change? - if not self.env['runtime']['cursorManager'].isCursorVerticalMove(): - return - - x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText']) - if currLine.isspace(): - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) + if not self.env['runtime']['CursorManager'].is_cursor_vertical_move(): + return + + x, y, curr_line = line_utils.get_current_line( + self.env['screen']['new_cursor']['x'], self.env['screen']['new_cursor']['y'], self.env['screen']['new_content_text']) + if curr_line.isspace(): + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True, flush=False) else: # ident - currIdent = len(currLine) - len(currLine.lstrip()) + curr_ident = len(curr_line) - len(curr_line.lstrip()) if self.lastIdent == -1: - self.lastIdent = currIdent - doInterrupt = True - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'): - if self.env['runtime']['settingsManager'].getSettingAsInt('general', 'autoPresentIndentMode') in [0,1]: - self.env['runtime']['outputManager'].playFrequence(currIdent * 50, 0.1, interrupt=doInterrupt) - if self.env['runtime']['settingsManager'].getSettingAsInt('general', 'autoPresentIndentMode') in [0,2]: - if self.lastIdent != currIdent: - self.env['runtime']['outputManager'].presentText(_('indented ') + str(currIdent) + ' ', interrupt=doInterrupt, flush=False) - doInterrupt = False + self.lastIdent = curr_ident + do_interrupt = True + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoPresentIndent'): + if self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'autoPresentIndentMode') in [0, 1]: + self.env['runtime']['OutputManager'].play_frequence( + curr_ident * 50, 0.1, interrupt=do_interrupt) + if self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'autoPresentIndentMode') in [0, 2]: + if self.lastIdent != curr_ident: + self.env['runtime']['OutputManager'].present_text( + _('indented ') + str(curr_ident) + ' ', interrupt=do_interrupt, flush=False) + do_interrupt = False # barrier - sayLine = currLine - if self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'): - isBarrier, barrierLine = self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y']) - if isBarrier: - sayLine = barrierLine + say_line = curr_line + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'): + is_barrier, barrierLine = self.env['runtime']['BarrierManager'].handle_line_barrier( + self.env['screen']['new_content_text'].split('\n'), self.env['screen']['new_cursor']['x'], self.env['screen']['new_cursor']['y']) + if is_barrier: + say_line = barrierLine # output - self.env['runtime']['outputManager'].presentText(sayLine, interrupt=doInterrupt, flush=False) - self.lastIdent = currIdent - def setCallback(self, callback): - pass + self.env['runtime']['OutputManager'].present_text( + say_line, interrupt=do_interrupt, flush=False) + self.lastIdent = curr_ident + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py b/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py index 49d9e50c..8b6cfa77 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py +++ b/src/fenrirscreenreader/commands/onCursorChange/68000-auto_identation_horizontal.py @@ -4,53 +4,67 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import line_utils from fenrirscreenreader.utils import word_utils + class command(): def __init__(self): self.lastIdent = -1 + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return '' - + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'cursor'): return - if self.env['runtime']['screenManager'].isScreenChange(): + if self.env['runtime']['ScreenManager'].is_screen_change(): self.lastIdent = 0 return # is a vertical change? - if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + if not self.env['runtime']['CursorManager'].is_cursor_horizontal_move(): return - x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText']) - currIdent = self.env['screen']['newCursor']['x'] + x, y, curr_line = line_utils.get_current_line( + self.env['screen']['new_cursor']['x'], self.env['screen']['new_cursor']['y'], self.env['screen']['new_content_text']) + curr_ident = self.env['screen']['new_cursor']['x'] - if not currLine.isspace(): + if not curr_line.isspace(): # ident - lastIdent, lastY, lastLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['oldContentText']) - if currLine.strip() != lastLine.strip(): + lastIdent, lastY, last_line = line_utils.get_current_line( + self.env['screen']['new_cursor']['x'], self.env['screen']['new_cursor']['y'], self.env['screen']['old_content_text']) + if curr_line.strip() != last_line.strip(): return - if len(currLine.lstrip()) == len(lastLine.lstrip()): + if len(curr_line.lstrip()) == len(last_line.lstrip()): return - currIdent = len(currLine) - len(currLine.lstrip()) + curr_ident = len(curr_line) - len(curr_line.lstrip()) if self.lastIdent == -1: - self.lastIdent = currIdent - if currIdent <= 0: + self.lastIdent = curr_ident + if curr_ident <= 0: return - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoPresentIndent'): - if self.env['runtime']['settingsManager'].getSettingAsInt('general', 'autoPresentIndentMode') in [0,1]: - self.env['runtime']['outputManager'].playFrequence(currIdent * 50, 0.1, interrupt=False) - if self.env['runtime']['settingsManager'].getSettingAsInt('general', 'autoPresentIndentMode') in [0,2]: - if self.lastIdent != currIdent: - self.env['runtime']['outputManager'].presentText(_('indented ') + str(currIdent) + ' ', interrupt=False, flush=False) - self.lastIdent = currIdent - def setCallback(self, callback): - pass + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'autoPresentIndent'): + if self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'autoPresentIndentMode') in [0, 1]: + self.env['runtime']['OutputManager'].play_frequence( + curr_ident * 50, 0.1, interrupt=False) + if self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'autoPresentIndentMode') in [0, 2]: + if self.lastIdent != curr_ident: + self.env['runtime']['OutputManager'].present_text( + _('indented ') + str(curr_ident) + ' ', interrupt=False, flush=False) + self.lastIdent = curr_ident + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py b/src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py index c7e9eed0..342c6488 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py +++ b/src/fenrirscreenreader/commands/onCursorChange/85000-has_attribute.py @@ -4,30 +4,41 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.utils import screen_utils + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return _('Reads attributes of current cursor position') - def run(self): - # is it enabled? - if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'hasAttributes'): - return - # is a vertical change? - if not (self.env['runtime']['cursorManager'].isCursorVerticalMove() or\ - self.env['runtime']['cursorManager'].isCursorHorizontalMove()): - return - cursorPos = self.env['screen']['newCursor'] - - if not self.env['runtime']['attributeManager'].hasAttributes(cursorPos): + def get_description(self): + return _('Reads attributes of current cursor position') + + def run(self): + # is it enabled? + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'hasattributes'): return - self.env['runtime']['outputManager'].presentText('has attribute', soundIcon='HasAttributes', interrupt=False) - def setCallback(self, callback): + # is a vertical change? + if not (self.env['runtime']['CursorManager'].is_cursor_vertical_move() or + self.env['runtime']['CursorManager'].is_cursor_horizontal_move()): + return + + cursor_pos = self.env['screen']['new_cursor'] + + if not self.env['runtime']['AttributeManager'].has_attributes( + cursor_pos): + return + self.env['runtime']['OutputManager'].present_text( + 'has attribute', sound_icon ='HasAttributes', interrupt=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py b/src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py index bde418da..b568b07f 100644 --- a/src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py +++ b/src/fenrirscreenreader/commands/onCursorChange/95000-exit_review_mode.py @@ -5,21 +5,28 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('exits review mode') - - def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnCursorChange'): - return - if self.env['runtime']['cursorManager'].isReviewMode(): - self.env['runtime']['cursorManager'].clearReviewCursor() - - def setCallback(self, callback): + pass + + def get_description(self): + return _('exits review mode') + + def run(self): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'leaveReviewOnCursorChange'): + return + if self.env['runtime']['CursorManager'].is_review_mode(): + self.env['runtime']['CursorManager'].clear_review_cursor() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onHeartBeat/2000-GetSessionInfo.py b/src/fenrirscreenreader/commands/onHeartBeat/2000-GetSessionInfo.py index c986b0d9..17ace9af 100755 --- a/src/fenrirscreenreader/commands/onHeartBeat/2000-GetSessionInfo.py +++ b/src/fenrirscreenreader/commands/onHeartBeat/2000-GetSessionInfo.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 + +from fenrirscreenreader.core.i18n import _ + import time # -*- coding: utf-8 -*- @@ -8,21 +11,25 @@ import time import time import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.lastTime = datetime.datetime.now() + self.last_time = datetime.datetime.now() self.lastDateString = '' - self.lastTimeString = '' + self.lastTimeString = '' + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - self.env['runtime']['screenDriver'].getSessionInformation() - def setCallback(self, callback): + self.env['runtime']['ScreenDriver'].get_session_information() + + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onHeartBeat/76000-time.py b/src/fenrirscreenreader/commands/onHeartBeat/76000-time.py index 59537a44..493122ea 100755 --- a/src/fenrirscreenreader/commands/onHeartBeat/76000-time.py +++ b/src/fenrirscreenreader/commands/onHeartBeat/76000-time.py @@ -4,81 +4,99 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import time import datetime + class command(): def __init__(self): pass def initialize(self, environment): self.env = environment - self.lastTime = datetime.datetime.now() + self.last_time = datetime.datetime.now() self.lastDateString = '' self.lastTimeString = '' def shutdown(self): pass - def getDescription(self): + def get_description(self): return 'No Description found' def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'enabled'): return - onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes') - delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec') + on_minutes = self.env['runtime']['SettingsManager'].get_setting( + 'time', 'on_minutes') + delay_sec = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'time', 'delay_sec') # no need - if onMinutes == '' and delaySec <= 0: + if on_minutes == '' and delay_sec <= 0: return - onMinutes = onMinutes.split(',') + on_minutes = on_minutes.split(',') now = datetime.datetime.now() - # ignore onMinutes if there is a delaySec - if delaySec > 0: - if int((now - self.lastTime).total_seconds()) < delaySec: + # ignore on_minutes if there is a delay_sec + if delay_sec > 0: + if int((now - self.last_time).total_seconds()) < delay_sec: return else: # should announce? - if not str(now.minute).zfill(2) in onMinutes: + if not str(now.minute).zfill(2) in on_minutes: return # already announced? - if now.hour == self.lastTime.hour: - if now.minute == self.lastTime.minute: + if now.hour == self.last_time.hour: + if now.minute == self.last_time.minute: return - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') - dateString = datetime.datetime.strftime(now, dateFormat) + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') + date_string = datetime.datetime.strftime(now, date_format) - presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \ - self.lastDateString != dateString - presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime') + present_date = self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'present_date') and self.lastDateString != date_string + present_time = self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'present_time') # no changed value to announce - if not (presentDate or presentTime): + if not (present_date or present_time): return - timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat') - timeString = datetime.datetime.strftime(now, timeFormat) + time_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'time_format') + time_string = datetime.datetime.strftime(now, time_format) - if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'interrupt'): - self.env['runtime']['outputManager'].interruptOutput() - if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'announce'): - self.env['runtime']['outputManager'].playSoundIcon('announce') + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'interrupt'): + self.env['runtime']['OutputManager'].interrupt_output() + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'time', 'announce'): + self.env['runtime']['OutputManager'].play_sound_icon('announce') - if presentTime: + if present_time: # present the time - self.env['runtime']['outputManager'].presentText(_("It's {0}").format(timeString.replace(':00', " O'clock ").lstrip('0')), soundIcon='', interrupt=False) + self.env['runtime']['OutputManager'].present_text( + _("It's {0}").format( + time_string.replace( + ':00', + " O'clock ").lstrip('0')), + sound_icon ='', + interrupt=False) # Check if it's 12:00 AM if now.hour == 0 and now.minute == 0: # present the date - self.env['runtime']['outputManager'].presentText(dateString, soundIcon='', interrupt=False) + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=False) - self.lastTime = datetime.datetime.now() - self.lastTimeString = timeString + self.last_time = datetime.datetime.now() + self.lastTimeString = time_string - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/10000-shut_up.py b/src/fenrirscreenreader/commands/onKeyInput/10000-shut_up.py index 71f0b1b1..cdc9a065 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/10000-shut_up.py +++ b/src/fenrirscreenreader/commands/onKeyInput/10000-shut_up.py @@ -4,32 +4,43 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - + + def get_description(self): + return '' + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'interruptOnKeyPress'): - return - if self.env['runtime']['inputManager'].noKeyPressed(): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'interruptOnKeyPress'): return - if self.env['runtime']['screenManager'].isScreenChange(): + if self.env['runtime']['InputManager'].no_key_pressed(): return - if len(self.env['input']['currInput']) <= len(self.env['input']['prevInput']): + if self.env['runtime']['ScreenManager'].is_screen_change(): + return + if len( + self.env['input']['currInput']) <= len( + self.env['input']['prevInput']): return # if the filter is set - if self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').strip() != '': - filterList = self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').split(',') + if self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'interruptOnKeyPressFilter').strip() != '': + filter_list = self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'interruptOnKeyPressFilter').split(',') for currInput in self.env['input']['currInput']: - if not currInput in filterList: - return - self.env['runtime']['outputManager'].interruptOutput() + if currInput not in filter_list: + return + self.env['runtime']['OutputManager'].interrupt_output() - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py b/src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py index 00a5d9a5..82de81f9 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py +++ b/src/fenrirscreenreader/commands/onKeyInput/15000-enable_temp_speech.py @@ -5,29 +5,38 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('disables speech until next keypress') - + pass + + def get_description(self): + return _('disables speech until next keypress') + def run(self): - if self.env['runtime']['inputManager'].noKeyPressed(): - return - if len(self.env['input']['prevInput']) >0: + if self.env['runtime']['InputManager'].no_key_pressed(): + return + if len(self.env['input']['prevInput']) > 0: return if not self.env['commandBuffer']['enableSpeechOnKeypress']: return - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(self.env['commandBuffer']['enableSpeechOnKeypress'])) + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', str( + self.env['commandBuffer']['enableSpeechOnKeypress'])) self.env['commandBuffer']['enableSpeechOnKeypress'] = False # Also disable prompt watching since speech was manually re-enabled if 'silenceUntilPrompt' in self.env['commandBuffer']: self.env['commandBuffer']['silenceUntilPrompt'] = False - self.env['runtime']['outputManager'].presentText(_("speech enabled"), soundIcon='SpeechOn', interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("speech enabled"), sound_icon ='SpeechOn', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py b/src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py index 6568b836..251516be 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py +++ b/src/fenrirscreenreader/commands/onKeyInput/80000-capslock.py @@ -5,22 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): if self.env['input']['oldCapsLock'] == self.env['input']['newCapsLock']: return if self.env['input']['newCapsLock']: - self.env['runtime']['outputManager'].presentText(_("Capslock on"), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("Capslock on"), interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_("Capslock off"), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("Capslock off"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py b/src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py index 752110ba..42f2ce54 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py +++ b/src/fenrirscreenreader/commands/onKeyInput/80300-scrolllock.py @@ -5,22 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): if self.env['input']['oldScrollLock'] == self.env['input']['newScrollLock']: return if self.env['input']['newScrollLock']: - self.env['runtime']['outputManager'].presentText(_("Scrolllock on"), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("Scrolllock on"), interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_("Scrolllock off"), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("Scrolllock off"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py b/src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py index 39b0fb92..3395dec7 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py +++ b/src/fenrirscreenreader/commands/onKeyInput/80500-numlock.py @@ -5,22 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): if self.env['input']['oldNumLock'] == self.env['input']['newNumLock']: return if self.env['input']['newNumLock']: - self.env['runtime']['outputManager'].presentText(_("Numlock on"), interrupt=True) + self.env['runtime']['OutputManager'].present_text( + _("Numlock on"), interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_("Numlock off"), interrupt=True) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _("Numlock off"), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py b/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py index a5df3c4c..e5391fb6 100644 --- a/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py +++ b/src/fenrirscreenreader/commands/onKeyInput/81000-key_echo.py @@ -5,18 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' - def run(self): - if self.env['runtime']['helpManager'].isTutorialMode(): - self.env['runtime']['inputManager'].keyEcho() - def setCallback(self, callback): + def get_description(self): + return 'No description found' + + def run(self): + if self.env['runtime']['HelpManager'].is_tutorial_mode(): + self.env['runtime']['InputManager'].key_echo() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py b/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py index cdcede66..0658d1f9 100755 --- a/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py +++ b/src/fenrirscreenreader/commands/onPlugInputDevice/50000-plugSound.py @@ -4,30 +4,40 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import time + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.lastTime = time.time() + self.last_time = time.time() + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No description found' + def run(self): - playSound = False - deviceList = self.env['runtime']['inputManager'].getLastDetectedDevices() + play_sound = False + device_list = self.env['runtime']['InputManager'].get_last_detected_devices( + ) try: - for deviceEntry in deviceList: - # dont play sounds for virtual devices - playSound = playSound or not deviceEntry['virtual'] + for deviceEntry in device_list: + # dont play sounds for virtual devices + play_sound = play_sound or not deviceEntry['virtual'] except Exception as e: - playSound = True - if playSound: - if time.time() - self.lastTime > 5: - self.env['runtime']['outputManager'].playSoundIcon(soundIcon = 'accept', interrupt=True) - lastTime = time.time() - def setCallback(self, callback): + play_sound = True + if play_sound: + if time.time() - self.last_time > 5: + self.env['runtime']['OutputManager'].play_sound_icon( + sound_icon ='accept', interrupt=True) + last_time = time.time() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenChanged/10000-shut_up.py b/src/fenrirscreenreader/commands/onScreenChanged/10000-shut_up.py index e1e18141..680c6bca 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/10000-shut_up.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/10000-shut_up.py @@ -4,18 +4,24 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return '' - - def run(self): - self.env['runtime']['outputManager'].interruptOutput() - def setCallback(self, callback): + def get_description(self): + return '' + + def run(self): + self.env['runtime']['OutputManager'].interrupt_output() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenChanged/20000-reset_last_cursor_attribute.py b/src/fenrirscreenreader/commands/onScreenChanged/20000-reset_last_cursor_attribute.py index 945bbe5c..265021c2 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/20000-reset_last_cursor_attribute.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/20000-reset_last_cursor_attribute.py @@ -5,18 +5,24 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - self.env['runtime']['attributeManager'].resetLastCursorAttribute() + self.env['runtime']['AttributeManager'].reset_last_cursor_attribute() - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenChanged/21000-reset_barrier_change.py b/src/fenrirscreenreader/commands/onScreenChanged/21000-reset_barrier_change.py index 2f4d51e4..4ef4d363 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/21000-reset_barrier_change.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/21000-reset_barrier_change.py @@ -5,18 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - self.env['runtime']['barrierManager'].resetBarrierChange() + self.env['runtime']['BarrierManager'].reset_barrier_change() - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenChanged/70000-barrier_detect.py b/src/fenrirscreenreader/commands/onScreenChanged/70000-barrier_detect.py index 02a23b70..e5d1d4d1 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/70000-barrier_detect.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/70000-barrier_detect.py @@ -5,22 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'): return - self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y']) + self.env['runtime']['BarrierManager'].handle_line_barrier( + self.env['screen']['new_content_text'].split('\n'), + self.env['screen']['new_cursor']['x'], + self.env['screen']['new_cursor']['y']) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onScreenChanged/80000-screen_change_announcement.py b/src/fenrirscreenreader/commands/onScreenChanged/80000-screen_change_announcement.py index cbd60d48..7a2aee89 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/80000-screen_change_announcement.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/80000-screen_change_announcement.py @@ -5,20 +5,31 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - self.env['runtime']['outputManager'].presentText(_("screen {0}").format(self.env['screen']['newTTY']),soundIcon='ChangeTTY', interrupt=True, flush=False) - self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'], interrupt=False, flush=False) + self.env['runtime']['OutputManager'].present_text( + _("screen {0}").format( + self.env['screen']['newTTY']), + sound_icon ='ChangeTTY', + interrupt=True, + flush=False) + self.env['runtime']['OutputManager'].present_text( + self.env['screen']['new_content_text'], interrupt=False, flush=False) - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onScreenChanged/85000-reset_marks.py b/src/fenrirscreenreader/commands/onScreenChanged/85000-reset_marks.py index 1cc55473..d35e1209 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/85000-reset_marks.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/85000-reset_marks.py @@ -5,19 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - self.env['runtime']['cursorManager'].clearMarks() + self.env['runtime']['CursorManager'].clear_marks() - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onScreenChanged/89000-leave_review_mode.py b/src/fenrirscreenreader/commands/onScreenChanged/89000-leave_review_mode.py index 505bbddf..74a95e2c 100644 --- a/src/fenrirscreenreader/commands/onScreenChanged/89000-leave_review_mode.py +++ b/src/fenrirscreenreader/commands/onScreenChanged/89000-leave_review_mode.py @@ -5,21 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' + + def get_description(self): + return 'No Description found' def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnScreenChange'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'review', 'leaveReviewOnScreenChange'): return - self.env['runtime']['cursorManager'].clearReviewCursor() + self.env['runtime']['CursorManager'].clear_review_cursor() - def setCallback(self, callback): + def set_callback(self, callback): pass - diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py b/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py index 5198ebd5..995f415a 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/56000-highlight_tracking.py @@ -4,19 +4,30 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enables or disables tracking of highlighted') - def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): - return - attributeDelta = self.env['runtime']['attributeManager'].getAttributeDelta() - self.env['runtime']['outputManager'].presentText(attributeDelta, soundIcon='', interrupt=True, flush=False) - def setCallback(self, callback): + pass + + def get_description(self): + return _('enables or disables tracking of highlighted') + + def run(self): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'highlight'): + return + attribute_delta = self.env['runtime']['AttributeManager'].get_attribute_delta( + ) + self.env['runtime']['OutputManager'].present_text( + attribute_delta, sound_icon ='', interrupt=True, flush=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py b/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py index fba8c870..cbb12837 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py @@ -5,68 +5,88 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return '' + def run(self): if self.env['screen']['newAttribDelta'] != '': - return - if self.env['runtime']['screenManager'].isScreenChange(): return - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): + if self.env['runtime']['ScreenManager'].is_screen_change(): return - if self.env['runtime']['attributeManager'].isAttributeChange(): + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): + return + if self.env['runtime']['AttributeManager'].is_attribute_change(): return # hack for pdmenu and maybe other dialog apps that place the cursor at last cell/row # this is not to be identified as history - if (self.env['screen']['newCursor']['x'] == self.env['runtime']['screenManager'].getColumns() - 1) and (self.env['screen']['newCursor']['y'] == self.env['runtime']['screenManager'].getRows() - 1): + if (self.env['screen']['new_cursor']['x'] == self.env['runtime']['ScreenManager'].get_columns( + ) - 1) and (self.env['screen']['new_cursor']['y'] == self.env['runtime']['ScreenManager'].get_rows() - 1): return - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_UP'],['KEY_DOWN']]): - return - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: - if not (self.env['runtime']['byteManager'].getLastByteKey() in [b'^[[A',b'^[[B']): - return + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + if not ( + self.env['runtime']['InputManager'].get_last_deepest_input() in [ + ['KEY_UP'], + ['KEY_DOWN']]): + return + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: + if not ( + self.env['runtime']['ByteManager'].get_last_byte_key() in [ + b'^[[A', + b'^[[B']): + return # Get the current cursor's line from both old and new content - prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']] - currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] - - is_blank = currLine.strip() == '' - - if prevLine == currLine: - if self.env['screen']['newDelta'] != '': + prev_line = self.env['screen']['old_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + curr_line = self.env['screen']['new_content_text'].split( + '\n')[self.env['screen']['new_cursor']['y']] + + is_blank = curr_line.strip() == '' + + if prev_line == curr_line: + if self.env['screen']['new_delta'] != '': return - - announce = currLine + + announce = curr_line if not is_blank: - currPrompt = currLine.find('$') - rootPrompt = currLine.find('#') - if currPrompt <= 0: - if rootPrompt > 0: - currPrompt = rootPrompt + curr_prompt = curr_line.find('$') + root_prompt = curr_line.find('#') + if curr_prompt <= 0: + if root_prompt > 0: + curr_prompt = root_prompt else: - announce = currLine - if currPrompt > 0: + announce = curr_line + if curr_prompt > 0: remove_digits = str.maketrans('0123456789', ' ') - if prevLine[:currPrompt].translate(remove_digits) == currLine[:currPrompt].translate(remove_digits): - announce = currLine[currPrompt+1:] + if prev_line[:curr_prompt].translate( + remove_digits) == curr_line[:curr_prompt].translate(remove_digits): + announce = curr_line[curr_prompt + 1:] else: - announce = currLine + announce = curr_line if is_blank: - self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False) + self.env['runtime']['OutputManager'].present_text( + _("blank"), sound_icon ='EmptyLine', interrupt=True, flush=False) else: - self.env['runtime']['outputManager'].presentText(announce, interrupt=True, flush=False) - + self.env['runtime']['OutputManager'].present_text( + announce, interrupt=True, flush=False) + self.env['commandsIgnore']['onScreenUpdate']['CHAR_DELETE_ECHO'] = True self.env['commandsIgnore']['onScreenUpdate']['CHAR_ECHO'] = True self.env['commandsIgnore']['onScreenUpdate']['INCOMING_IGNORE'] = True - def setCallback(self, callback): + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py index a10101b7..4880e87e 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/65000-progress_detector.py @@ -4,255 +4,308 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import debug + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return 'Detects progress patterns for progress bar monitoring' - + def run(self): # Only run if progress monitoring is enabled try: if 'progressMonitoring' in self.env['commandBuffer'] and self.env['commandBuffer']['progressMonitoring']: - # Check if current line is a prompt - if so, reset progress state - if self.isCurrentLinePrompt(): - self.resetProgressState() - # Only check new incoming text (newDelta), but filter out screen changes - elif self.env['screen']['newDelta'] and self.isRealProgressUpdate(): - self.detectProgress(self.env['screen']['newDelta']) + # Check if current line is a prompt - if so, reset progress + # state + if self.is_current_line_prompt(): + self.reset_progress_state() + # Only check new incoming text (new_delta), but filter out + # screen changes + elif self.env['screen']['new_delta'] and self.is_real_progress_update(): + self.detect_progress(self.env['screen']['new_delta']) except Exception as e: # Silently ignore errors to avoid disrupting normal operation pass - - def isRealProgressUpdate(self): + + def is_real_progress_update(self): """Check if this is a real progress update vs screen change/window switch""" # If the screen/application changed, it's not a progress update - if self.env['runtime']['screenManager'].isScreenChange(): + if self.env['runtime']['ScreenManager'].is_screen_change(): return False - - # If there was a large cursor movement, it's likely navigation, not progress - if self.env['runtime']['cursorManager'].isCursorVerticalMove(): - xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']) - yMove = abs(self.env['screen']['newCursor']['y'] - self.env['screen']['oldCursor']['y']) + + # If there was a large cursor movement, it's likely navigation, not + # progress + if self.env['runtime']['CursorManager'].is_cursor_vertical_move(): + x_move = abs( + self.env['screen']['new_cursor']['x'] - + self.env['screen']['old_cursor']['x']) + y_move = abs( + self.env['screen']['new_cursor']['y'] - + self.env['screen']['old_cursor']['y']) # Large movements suggest navigation, not progress output - if yMove > 2 or xMove > 20: + if y_move > 2 or x_move > 20: return False - - # Check if delta is too large (screen change) vs small incremental updates - deltaLength = len(self.env['screen']['newDelta']) - if deltaLength > 200: # Allow longer progress lines like Claude Code's status + + # Check if delta is too large (screen change) vs small incremental + # updates + delta_length = len(self.env['screen']['new_delta']) + if delta_length > 200: # Allow longer progress lines like Claude Code's status return False - - # Check if current line looks like a prompt - progress unlikely during prompts - if self.isCurrentLinePrompt(): + + # Check if current line looks like a prompt - progress unlikely during + # prompts + if self.is_current_line_prompt(): return False - + return True - - def resetProgressState(self): + + def reset_progress_state(self): """Reset progress state when a prompt is detected, allowing new progress operations to start fresh""" - self.env['runtime']['debug'].writeDebugOut("Resetting progress state due to prompt detection", debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "Resetting progress state due to prompt detection", + debug.DebugLevel.INFO) self.env['commandBuffer']['lastProgressValue'] = -1 self.env['commandBuffer']['lastProgressTime'] = 0 - - def detectProgress(self, text): + + def detect_progress(self, text): import re import time - - currentTime = time.time() - + + current_time = time.time() + # Debug: Print what we're checking - self.env['runtime']['debug'].writeDebugOut("Progress detector checking: '" + text + "'", debug.debugLevel.INFO) - - # Note: Auto-disable on 100% completion removed to respect user settings - + self.env['runtime']['DebugManager'].write_debug_out( + "Progress detector checking: '" + text + "'", debug.DebugLevel.INFO) + + # Note: Auto-disable on 100% completion removed to respect user + # settings + # Pattern 1: Percentage (50%, 25.5%, etc.) - # Filter out common non-progress percentages (weather, system stats, etc.) - percentMatch = re.search(r'(\d+(?:\.\d+)?)\s*%', text) - if percentMatch: - percentage = float(percentMatch.group(1)) + # Filter out common non-progress percentages (weather, system stats, + # etc.) + percent_match = re.search(r'(\d+(?:\.\d+)?)\s*%', text) + if percent_match: + percentage = float(percent_match.group(1)) # Only trigger on realistic progress percentages (0-100%) if 0 <= percentage <= 100: # Filter out weather/system stats that contain percentages - if not re.search(r'\b(?:humidity|cpu|memory|disk|usage|temp|weather|forecast)\b', text, re.IGNORECASE): - self.env['runtime']['debug'].writeDebugOut("Found percentage: " + str(percentage), debug.debugLevel.INFO) + if not re.search( + r'\b(?:humidity|cpu|memory|disk|usage|temp|weather|forecast)\b', + text, + re.IGNORECASE): + self.env['runtime']['DebugManager'].write_debug_out( + "found percentage: " + str(percentage), debug.DebugLevel.INFO) if percentage != self.env['commandBuffer']['lastProgressValue']: - self.env['runtime']['debug'].writeDebugOut("Playing tone for: " + str(percentage), debug.debugLevel.INFO) - self.playProgressTone(percentage) + self.env['runtime']['DebugManager'].write_debug_out( + "Playing tone for: " + str(percentage), debug.DebugLevel.INFO) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - - # Pattern 1b: Time/token activity (not percentage-based, so use single beep) - timeMatch = re.search(r'(\d+)s\s', text) - tokenMatch = re.search(r'(\d+)\s+tokens', text) + + # Pattern 1b: Time/token activity (not percentage-based, so use single + # beep) + time_match = re.search(r'(\d+)s\s', text) + token_match = re.search(r'(\d+)\s+tokens', text) # Pattern 1c: dd command output (bytes copied with transfer rate) - ddMatch = re.search(r'\d+\s+bytes.*copied.*\d+\s+s.*[kMGT]?B/s', text) + dd_match = re.search(r'\d+\s+bytes.*copied.*\d+\s+s.*[kMGT]?B/s', text) # Pattern 1d: Curl-style transfer data (bytes, speed indicators) - curlMatch = re.search(r'(\d+\s+\d+\s+\d+\s+\d+.*?(?:k|M|G)?.*?--:--:--|Speed)', text) - - if timeMatch or tokenMatch or ddMatch or curlMatch: - # For non-percentage progress, use a single activity beep every 2 seconds - if currentTime - self.env['commandBuffer']['lastProgressTime'] >= 2.0: - self.env['runtime']['debug'].writeDebugOut("Playing activity beep for transfer progress", debug.debugLevel.INFO) - self.playActivityBeep() - self.env['commandBuffer']['lastProgressTime'] = currentTime + curl_match = re.search( + r'(\d+\s+\d+\s+\d+\s+\d+.*?(?:k|M|G)?.*?--:--:--|Speed)', text) + + if time_match or token_match or dd_match or curl_match: + # For non-percentage progress, use a single activity beep every 2 + # seconds + if current_time - \ + self.env['commandBuffer']['lastProgressTime'] >= 2.0: + self.env['runtime']['DebugManager'].write_debug_out( + "Playing activity beep for transfer progress", debug.DebugLevel.INFO) + self.play_activity_beep() + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 2: Fraction (15/100, 3 of 10, etc.) - fractionMatch = re.search(r'(\d+)\s*(?:of|/)\s*(\d+)', text) - if fractionMatch: - current = int(fractionMatch.group(1)) - total = int(fractionMatch.group(2)) + fraction_match = re.search(r'(\d+)\s*(?:of|/)\s*(\d+)', text) + if fraction_match: + current = int(fraction_match.group(1)) + total = int(fraction_match.group(2)) if total > 0: percentage = (current / total) * 100 if percentage != self.env['commandBuffer']['lastProgressValue']: - self.playProgressTone(percentage) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 3: Progress bars ([#### ], [====> ], etc.) # Improved pattern to avoid matching IRC channels like [#channel] - barMatch = re.search(r'\[([#=\-\*]+)([\s\.]*)\]', text) - if barMatch: - filled = len(barMatch.group(1)) - unfilled = len(barMatch.group(2)) + bar_match = re.search(r'\[([#=\-\*]+)([\s\.]*)\]', text) + if bar_match: + filled = len(bar_match.group(1)) + unfilled = len(bar_match.group(2)) total = filled + unfilled - # Require at least 2 progress chars total and unfilled portion must be spaces/dots - if total >= 2 and (not barMatch.group(2) or re.match(r'^[\s\.]*$', barMatch.group(2))): + # Require at least 2 progress chars total and unfilled portion must + # be spaces/dots + if total >= 2 and ( + not bar_match.group(2) or re.match( + r'^[\s\.]*$', + bar_match.group(2))): percentage = (filled / total) * 100 if percentage != self.env['commandBuffer']['lastProgressValue']: - self.playProgressTone(percentage) + self.play_progress_tone(percentage) self.env['commandBuffer']['lastProgressValue'] = percentage - self.env['commandBuffer']['lastProgressTime'] = currentTime + self.env['commandBuffer']['lastProgressTime'] = current_time return - + # Pattern 4: Generic activity indicators (Loading..., Working..., etc.) - activityPattern = re.search(r'(loading|processing|working|installing|downloading|compiling|building).*\.{2,}', text, re.IGNORECASE) - if activityPattern: + activity_pattern = re.search( + r'(loading|processing|working|installing|downloading|compiling|building).*\.{2,}', + text, + re.IGNORECASE) + if activity_pattern: # Play a steady beep every 2 seconds for ongoing activity - if currentTime - self.env['commandBuffer']['lastProgressTime'] >= 2.0: - self.playActivityBeep() - self.env['commandBuffer']['lastProgressTime'] = currentTime - - def playProgressTone(self, percentage): - # Map 0-100% to 400-1200Hz frequency range + if current_time - \ + self.env['commandBuffer']['lastProgressTime'] >= 2.0: + self.play_activity_beep() + self.env['commandBuffer']['lastProgressTime'] = current_time + + def play_progress_tone(self, percentage): + # Map 0-100% to 400-1200Hz frequency range frequency = 400 + (percentage * 8) frequency = max(400, min(1200, frequency)) # Clamp to safe range - - # Use Sox directly for clean quiet tones like: play -qn synth .1 tri 400 gain -8 - self.playQuietTone(frequency, 0.1) - - def playActivityBeep(self): + + # Use Sox directly for clean quiet tones like: play -qn synth .1 tri + # 400 gain -8 + self.play_quiet_tone(frequency, 0.1) + + def play_activity_beep(self): # Single tone for generic activity - self.playQuietTone(800, 0.08) - - def playQuietTone(self, frequency, duration): + self.play_quiet_tone(800, 0.08) + + def play_quiet_tone(self, frequency, duration): """Play a quiet tone using Sox directly""" import subprocess import shlex - - # Build the Sox command: play -qn synth tri gain -8 + + # Build the Sox command: play -qn synth tri gain + # -8 command = f"play -qn synth {duration} tri {frequency} gain -8" - + try: # Only play if sound is enabled - if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - subprocess.Popen(shlex.split(command), stdin=None, stdout=None, stderr=None, shell=False) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'): + subprocess.Popen( + shlex.split(command), + stdin=None, + stdout=None, + stderr=None, + shell=False) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Sox tone error: " + str(e), debug.debugLevel.ERROR) - - def isCurrentLinePrompt(self): + self.env['runtime']['DebugManager'].write_debug_out( + "Sox tone error: " + str(e), debug.DebugLevel.ERROR) + + def is_current_line_prompt(self): """Check if the current line looks like a standalone prompt (not command with progress)""" import re - + try: # Get the current screen content - if not self.env['screen']['newContentText']: + if not self.env['screen']['new_content_text']: return False - - lines = self.env['screen']['newContentText'].split('\n') + + lines = self.env['screen']['new_content_text'].split('\n') if not lines: return False - - # Check the last line (most common) and current cursor line for prompt patterns - linesToCheck = [] - + + # Check the last line (most common) and current cursor line for + # prompt patterns + lines_to_check = [] + # Add last line (most common for prompts) if lines: - linesToCheck.append(lines[-1]) - + lines_to_check.append(lines[-1]) + # Add current cursor line if different from last line - if (self.env['screen']['newCursor']['y'] < len(lines) and - self.env['screen']['newCursor']['y'] != len(lines) - 1): - linesToCheck.append(lines[self.env['screen']['newCursor']['y']]) - + if (self.env['screen']['new_cursor']['y'] < len(lines) and + self.env['screen']['new_cursor']['y'] != len(lines) - 1): + lines_to_check.append( + lines[self.env['screen']['new_cursor']['y']]) + # Standalone prompt patterns (no commands mixed in) - standalonePromptPatterns = [ + standalone_prompt_patterns = [ r'^\s*\$\s*$', # Just $ (with whitespace) - r'^\s*#\s*$', # Just # (with whitespace) + r'^\s*#\s*$', # Just # (with whitespace) r'^\s*>\s*$', # Just > (with whitespace) r'^\[.*\]\s*[\\\$#>]\s*$', # [path]$ without commands r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', # bash-5.1$ without commands - + # Interactive prompt patterns (these ARE standalone) r'.*\?\s*\[[YyNn]/[YyNn]\]\s*$', # ? [Y/n] or ? [y/N] style r'.*\?\s*\[[Yy]es/[Nn]o\]\s*$', # ? [Yes/No] style - r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', # "continue? [Y/n]" style + # "continue? [Y/n]" style + r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', # pacman style prompts - + # Authentication prompts (these ARE standalone) r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', # [sudo] password r'^[Pp]assword\s*:\s*$', # Password: r'.*[Pp]assword\s*:\s*$', # general password prompts - + # Continuation prompts (these ARE standalone) r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', # Press any key r'^[Aa]re\s+you\s+sure\?\s*.*$', # Are you sure? ] - - for line in linesToCheck: + + for line in lines_to_check: line = line.strip() if not line: continue - + # Check if this line contains both a prompt AND other content (like commands) # If so, don't treat it as a standalone prompt - hasPromptMarker = bool(re.search(r'.*@.*[\\\$#>]', line) or re.search(r'^\[.*\]\s*[\\\$#>]', line)) - if hasPromptMarker: - # If line has prompt marker but also has significant content after it, + has_prompt_marker = bool( + re.search( + r'.*@.*[\\\$#>]', + line) or re.search( + r'^\[.*\]\s*[\\\$#>]', + line)) + if has_prompt_marker: + # If line has prompt marker but also has significant content after it, # it's a command line, not a standalone prompt - promptEnd = max( - line.rfind('$'), - line.rfind('#'), + prompt_end = max( + line.rfind('$'), + line.rfind('#'), line.rfind('>'), line.rfind('\\') ) - if promptEnd >= 0 and promptEnd < len(line) - 5: # More than just whitespace after prompt + if prompt_end >= 0 and prompt_end < len( + line) - 5: # More than just whitespace after prompt continue # This is a command line, not a standalone prompt - - for pattern in standalonePromptPatterns: + + for pattern in standalone_prompt_patterns: try: if re.search(pattern, line): return True except re.error: continue - + return False - + except Exception: # If anything fails, assume it's not a prompt to be safe return False - - def setCallback(self, callback): - pass \ No newline at end of file + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/66000-prompt_detector.py b/src/fenrirscreenreader/commands/onScreenUpdate/66000-prompt_detector.py index 28c981f9..b290baf0 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/66000-prompt_detector.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/66000-prompt_detector.py @@ -4,77 +4,94 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + from fenrirscreenreader.core import debug + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return 'Detects shell prompts for silence until prompt feature' - + def run(self): # Only run if silence until prompt is active try: if 'silenceUntilPrompt' in self.env['commandBuffer'] and self.env['commandBuffer']['silenceUntilPrompt']: # Check the current line for prompt patterns - if self.env['screen']['newContentText']: - lines = self.env['screen']['newContentText'].split('\n') - if lines and self.env['screen']['newCursor']['y'] < len(lines): - currentLine = lines[self.env['screen']['newCursor']['y']] - self.checkForPrompt(currentLine) + if self.env['screen']['new_content_text']: + lines = self.env['screen']['new_content_text'].split('\n') + if lines and self.env['screen']['new_cursor']['y'] < len( + lines): + current_line = lines[self.env['screen'] + ['new_cursor']['y']] + self.check_for_prompt(current_line) except Exception as e: # Silently ignore errors to avoid disrupting normal operation - self.env['runtime']['debug'].writeDebugOut('prompt_detector run: Error in prompt detection: ' + str(e), debug.debugLevel.ERROR) - - def checkForPrompt(self, text): + self.env['runtime']['DebugManager'].write_debug_out( + 'prompt_detector run: Error in prompt detection: ' + str(e), + debug.DebugLevel.ERROR) + + def check_for_prompt(self, text): """Check if the current line contains a shell prompt pattern""" import re - + # Debug: Print what we're checking - self.env['runtime']['debug'].writeDebugOut("Prompt detector checking: '" + text + "'", debug.debugLevel.INFO) - - # First check for exact matches from settings (with backward compatibility) + self.env['runtime']['DebugManager'].write_debug_out( + "Prompt detector checking: '" + text + "'", debug.DebugLevel.INFO) + + # First check for exact matches from settings (with backward + # compatibility) try: - exactMatches = self.env['runtime']['settingsManager'].getSetting('prompt', 'exactMatches') - if exactMatches: - exactList = [match.strip() for match in exactMatches.split(',') if match.strip()] - for exactMatch in exactList: + exact_matches = self.env['runtime']['SettingsManager'].get_setting( + 'prompt', 'exact_matches') + if exact_matches: + exact_list = [match.strip() + for match in exact_matches.split(',') if match.strip()] + for exactMatch in exact_list: if text.strip() == exactMatch: - self.env['runtime']['debug'].writeDebugOut("Found exact prompt match: " + exactMatch, debug.debugLevel.INFO) - self._restoreSpeech() + self.env['runtime']['DebugManager'].write_debug_out( + "found exact prompt match: " + exactMatch, debug.DebugLevel.INFO) + self._restore_speech() return True except Exception as e: - # Prompt section doesn't exist in settings, skip custom exact matches + # Prompt section doesn't exist in settings, skip custom exact + # matches pass - + # Get custom patterns from settings (with backward compatibility) - promptPatterns = [] + prompt_patterns = [] try: - customPatterns = self.env['runtime']['settingsManager'].getSetting('prompt', 'customPatterns') + custom_patterns = self.env['runtime']['SettingsManager'].get_setting( + 'prompt', 'custom_patterns') # Add custom patterns from settings if they exist - if customPatterns: - customList = [pattern.strip() for pattern in customPatterns.split(',') if pattern.strip()] - promptPatterns.extend(customList) + if custom_patterns: + custom_list = [ + pattern.strip() for pattern in custom_patterns.split(',') if pattern.strip()] + prompt_patterns.extend(custom_list) except Exception as e: # Prompt section doesn't exist in settings, skip custom patterns pass - + # Add default shell prompt patterns - promptPatterns.extend([ + prompt_patterns.extend([ r'^\s*\$\s*$', # Just $ (with whitespace) - r'^\s*#\s*$', # Just # (with whitespace) + r'^\s*#\s*$', # Just # (with whitespace) r'^\s*>\s*$', # Just > (with whitespace) - r'.*@.*[\\\$#>]\s*$', # Contains @ and ends with prompt char (user@host style) + r'.*@.*[\\\$#>]\s*$', + # Contains @ and ends with prompt char (user@host style) r'^\[.*\]\s*[\\\$#>]\s*$', # [anything]$ style prompts - r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', # Simple shell names like bash-5.1$ - + # Simple shell names like bash-5.1$ + r'^[a-zA-Z0-9._-]+[\\\$#>]\s*$', + # Interactive prompt patterns # Package manager confirmation prompts r'.*\?\s*\[[YyNn]/[YyNn]\]\s*$', # ? [Y/n] or ? [y/N] style @@ -83,47 +100,57 @@ class command(): r'.*\?\s*\([Yy]es/[Nn]o\)\s*$', # ? (Yes/No) style r'.*continue\?\s*\[[YyNn]/[YyNn]\].*$', # "continue? [Y/n]" style r'.*ok\s*\[[YyNn]/[YyNn]\].*$', # "Is this ok [y/N]:" style - r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', # pacman ":: Proceed? [Y/n]" style - + # pacman ":: Proceed? [Y/n]" style + r'^::.*\?\s*\[[YyNn]/[YyNn]\].*$', + # Authentication prompts - r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', # [sudo] password for user: + # [sudo] password for user: + r'^\[[Ss]udo\]\s*[Pp]assword\s*for\s+.*:\s*$', r'^[Pp]assword\s*:\s*$', # Password: r'.*[Pp]assword\s*:\s*$', # general password prompts r".*'s\s*[Pp]assword\s*:\s*$", # user's password: r'^[Ee]nter\s+[Pp]assphrase.*:\s*$', # Enter passphrase: - r'^[Pp]lease\s+enter\s+[Pp]assphrase.*:\s*$', # Please enter passphrase: - + # Please enter passphrase: + r'^[Pp]lease\s+enter\s+[Pp]assphrase.*:\s*$', + # General confirmation and continuation prompts - r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', # Press any key to continue + # Press any key to continue + r'^[Pp]ress\s+any\s+key\s+to\s+continue.*$', r'^[Aa]re\s+you\s+sure\?\s*.*$', # Are you sure? r'^[Pp]lease\s+confirm.*$', # Please confirm r'.*confirm.*\([YyNn]/[YyNn]\).*$', # confirm (y/n) r'.*\([Yy]/[Nn]\)\s*$', # ends with (Y/n) or (y/N) ]) - - for pattern in promptPatterns: + + for pattern in prompt_patterns: try: if re.search(pattern, text.strip()): - self.env['runtime']['debug'].writeDebugOut("Found prompt pattern: " + pattern, debug.debugLevel.INFO) - self._restoreSpeech() + self.env['runtime']['DebugManager'].write_debug_out( + "found prompt pattern: " + pattern, debug.DebugLevel.INFO) + self._restore_speech() return True except re.error as e: # Invalid regex pattern, skip it and log the error - self.env['runtime']['debug'].writeDebugOut("Invalid prompt pattern: " + pattern + " Error: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Invalid prompt pattern: " + pattern + " Error: " + str(e), + debug.DebugLevel.ERROR) continue - + return False - - def _restoreSpeech(self): + + def _restore_speech(self): """Helper method to restore speech when prompt is detected""" # Disable silence mode self.env['commandBuffer']['silenceUntilPrompt'] = False - # Also disable the keypress-based speech restoration since we're enabling it now + # Also disable the keypress-based speech restoration since we're + # enabling it now if 'enableSpeechOnKeypress' in self.env['commandBuffer']: self.env['commandBuffer']['enableSpeechOnKeypress'] = False # Re-enable speech - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', 'True') - self.env['runtime']['outputManager'].presentText(_("Speech restored"), soundIcon='SpeechOn', interrupt=True) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', 'True') + self.env['runtime']['OutputManager'].present_text( + _("Speech restored"), sound_icon ='SpeechOn', interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py index 40ad22e3..6593fe2b 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/70000-incoming.py @@ -5,34 +5,47 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No Description found' def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'autoReadIncoming'): return # is there something to read? - if not self.env['runtime']['screenManager'].isDelta(ignoreSpace=True): + if not self.env['runtime']['ScreenManager'].is_delta(ignoreSpace=True): return # this must be a keyecho or something - #if len(self.env['screen']['newDelta'].strip(' \n\t')) <= 1: - xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']) - yMove = abs(self.env['screen']['newCursor']['y'] - self.env['screen']['oldCursor']['y']) - - if (xMove >= 1) and xMove == len(self.env['screen']['newDelta']): - # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2: - if not '\n' in self.env['screen']['newDelta']: - return - #print(xMove, yMove, len(self.env['screen']['newDelta']), len(self.env['screen']['newNegativeDelta'])) - self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=False, flush=False) + # if len(self.env['screen']['new_delta'].strip(' \n\t')) <= 1: + x_move = abs( + self.env['screen']['new_cursor']['x'] - + self.env['screen']['old_cursor']['x']) + y_move = abs( + self.env['screen']['new_cursor']['y'] - + self.env['screen']['old_cursor']['y']) - def setCallback(self, callback): + if (x_move >= 1) and x_move == len(self.env['screen']['new_delta']): + # if len(self.env['screen']['new_delta'].strip(' \n\t0123456789')) + # <= 2: + if '\n' not in self.env['screen']['new_delta']: + return + # print(x_move, y_move, len(self.env['screen']['new_delta']), len(self.env['screen']['newNegativeDelta'])) + self.env['runtime']['OutputManager'].present_text( + self.env['screen']['new_delta'], interrupt=False, flush=False) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py b/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py index 23f2864b..8ba5ae35 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/75000-incoming_promote.py @@ -1,4 +1,7 @@ #!/usr/bin/env python3 + +from fenrirscreenreader.core.i18n import _ + import time # -*- coding: utf-8 -*- @@ -9,26 +12,41 @@ import time class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): + + def get_description(self): return 'No Description found' + def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('promote', 'enabled'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'promote', 'enabled'): return - if self.env['runtime']['settingsManager'].getSetting('promote', 'list').strip(" \t\n") == '': + if self.env['runtime']['SettingsManager'].get_setting( + 'promote', 'list').strip(" \t\n") == '': return - if int(time.time() - self.env['input']['lastInputTime']) < self.env['runtime']['settingsManager'].getSettingAsInt('promote', 'inactiveTimeoutSec'): + if int( + time.time() - + self.env['input']['lastInputTime']) < self.env['runtime']['SettingsManager'].get_setting_as_int( + 'promote', + 'inactiveTimeoutSec'): return - if len(self.env['runtime']['settingsManager'].getSetting('promote', 'list')) == 0: + if len( + self.env['runtime']['SettingsManager'].get_setting( + 'promote', + 'list')) == 0: return - for promote in self.env['runtime']['settingsManager'].getSetting('promote', 'list').split(','): - if promote in self.env['screen']['newDelta']: - self.env['runtime']['outputManager'].playSoundIcon('PromotedText') + for promote in self.env['runtime']['SettingsManager'].get_setting( + 'promote', 'list').split(','): + if promote in self.env['screen']['new_delta']: + self.env['runtime']['OutputManager'].play_sound_icon( + 'PromotedText') self.env['input']['lastInputTime'] = time.time() return - def setCallback(self, callback): - pass + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py b/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py index 3b516f8f..e26ed52a 100644 --- a/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py +++ b/src/fenrirscreenreader/commands/onScreenUpdate/80000-barrier_detect.py @@ -5,21 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No Description found' - def run(self): - if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier','enabled'): - return - if not self.env['runtime']['screenManager'].isDelta(ignoreSpace=True): - return - self.env['runtime']['barrierManager'].handleLineBarrier(self.env['screen']['newContentText'].split('\n'), self.env['screen']['newCursor']['x'],self.env['screen']['newCursor']['y']) - def setCallback(self, callback): - pass + def get_description(self): + return 'No Description found' + + def run(self): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'): + return + if not self.env['runtime']['ScreenManager'].is_delta(ignoreSpace=True): + return + self.env['runtime']['BarrierManager'].handle_line_barrier( + self.env['screen']['new_content_text'].split('\n'), + self.env['screen']['new_cursor']['x'], + self.env['screen']['new_cursor']['y']) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/onSwitchApplicationProfile/__init__.py b/src/fenrirscreenreader/commands/onSwitchApplicationProfile/__init__.py index 8b137891..e69de29b 100644 --- a/src/fenrirscreenreader/commands/onSwitchApplicationProfile/__init__.py +++ b/src/fenrirscreenreader/commands/onSwitchApplicationProfile/__init__.py @@ -1 +0,0 @@ - diff --git a/src/fenrirscreenreader/commands/onSwitchApplicationProfile/default.py b/src/fenrirscreenreader/commands/onSwitchApplicationProfile/default.py index 764a2292..9e1914d0 100644 --- a/src/fenrirscreenreader/commands/onSwitchApplicationProfile/default.py +++ b/src/fenrirscreenreader/commands/onSwitchApplicationProfile/default.py @@ -5,28 +5,35 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def load(self): return print('--------------') - print('default') - print('load new',self.env['screen']['newApplication']) + print('default') + print('load new', self.env['screen']['new_application']) print('--------------') - + def unload(self): return print('--------------') - print('default') - print('unload old',self.env['screen']['oldApplication']) + print('default') + print('unload old', self.env['screen']['oldApplication']) print('--------------') - - def setCallback(self, callback): + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py index a89ce3ee..960f3026 100644 --- a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_entry.py @@ -5,21 +5,30 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get current quick menu entry') + def run(self): menu = '' value = '' - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) - def setCallback(self, callback): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py index 6522e080..fc693ca5 100644 --- a/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/quickMenu/current_quick_menu_value.py @@ -5,17 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get current quick menu value') - def run(self): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get current quick menu value') + + def run(self): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text(value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py index 1d2a5fb1..c99fd2a7 100644 --- a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_entry.py @@ -5,24 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get next quick menu entry') + def run(self): menu = '' value = '' - if self.env['runtime']['quickMenuManager'].nextEntry(): - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + if self.env['runtime']['QuickMenuManager'].next_entry(): + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('Quick menu not available'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py index 78a0f9ad..11b4f312 100644 --- a/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/quickMenu/next_quick_menu_value.py @@ -5,18 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get next quick menu value') - def run(self): - if self.env['runtime']['quickMenuManager'].nextValue(): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get next quick menu value') + + def run(self): + if self.env['runtime']['QuickMenuManager'].next_value(): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py index 87aef5df..160f0de2 100644 --- a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py +++ b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_entry.py @@ -5,24 +5,34 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('get previous quick menu entry') + def run(self): menu = '' value = '' - if self.env['runtime']['quickMenuManager'].prevEntry(): - menu = self.env['runtime']['quickMenuManager'].getCurrentEntry() + if self.env['runtime']['QuickMenuManager'].prev_entry(): + menu = self.env['runtime']['QuickMenuManager'].get_current_entry() if menu != '': - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(menu + ' ' + value, interrupt=True) + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + menu + ' ' + value, interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('Quick menu not available'), interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + _('Quick menu not available'), interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py index bfa7e8cb..99b2dbfe 100644 --- a/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py +++ b/src/fenrirscreenreader/commands/quickMenu/prev_quick_menu_value.py @@ -5,18 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get previous quick menu value') - def run(self): - if self.env['runtime']['quickMenuManager'].prevValue(): - value = self.env['runtime']['quickMenuManager'].getCurrentValue() - self.env['runtime']['outputManager'].presentText(value, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get previous quick menu value') + + def run(self): + if self.env['runtime']['QuickMenuManager'].prev_value(): + value = self.env['runtime']['QuickMenuManager'].get_current_value() + self.env['runtime']['OutputManager'].present_text( + value, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/switchTrigger_template.py b/src/fenrirscreenreader/commands/switchTrigger_template.py index f8c837ff..0e0bf5ff 100644 --- a/src/fenrirscreenreader/commands/switchTrigger_template.py +++ b/src/fenrirscreenreader/commands/switchTrigger_template.py @@ -5,18 +5,27 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def unload(self): pass + def load(self): pass - def setCallback(self, callback): + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py index 41787ef8..069eca62 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/curr_vmenu_entry.py @@ -5,17 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get current v menu entry') - def run(self): - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get current v menu entry') + + def run(self): + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py index 56fcd4ff..cc63c686 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/dec_level_vmenu.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('leave v menu submenu') - def run(self): - self.env['runtime']['vmenuManager'].decLevel() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('leave v menu submenu') + + def run(self): + self.env['runtime']['VmenuManager'].dec_level() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py index 6ec99f52..9279ec99 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/exec_vmenu_entry.py @@ -5,16 +5,24 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('execute v menu entry') - def run(self): - self.env['runtime']['vmenuManager'].executeMenu() - def setCallback(self, callback): + pass + + def get_description(self): + return _('execute v menu entry') + + def run(self): + self.env['runtime']['VmenuManager'].execute_menu() + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py index f902dd00..94d0f6cc 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/inc_level_vmenu.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('enter v menu submenu') - def run(self): - self.env['runtime']['vmenuManager'].incLevel() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('enter v menu submenu') + + def run(self): + self.env['runtime']['VmenuManager'].inc_level() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py index 8aa5b011..449b63cf 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/next_vmenu_entry.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get next v menu entry') - def run(self): - self.env['runtime']['vmenuManager'].nextIndex() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get next v menu entry') + + def run(self): + self.env['runtime']['VmenuManager'].next_index() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/page_down_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/page_down_vmenu.py index 2e6e1550..d490a2a3 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/page_down_vmenu.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/page_down_vmenu.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('jump down 10% in v menu') + def run(self): - self.env['runtime']['vmenuManager'].pageDown() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['VmenuManager'].page_down() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/page_up_vmenu.py b/src/fenrirscreenreader/commands/vmenu-navigation/page_up_vmenu.py index c1c78ffa..0de37dce 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/page_up_vmenu.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/page_up_vmenu.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): + pass + + def get_description(self): return _('jump up 10% in v menu') + def run(self): - self.env['runtime']['vmenuManager'].pageUp() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['VmenuManager'].page_up() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py b/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py index 32ee67c1..ed0f21c2 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/prev_vmenu_entry.py @@ -5,18 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('get prev v menu entry') - def run(self): - self.env['runtime']['vmenuManager'].prevIndex() - text = self.env['runtime']['vmenuManager'].getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) - def setCallback(self, callback): + pass + + def get_description(self): + return _('get prev v menu entry') + + def run(self): + self.env['runtime']['VmenuManager'].prev_index() + text = self.env['runtime']['VmenuManager'].get_current_entry() + self.env['runtime']['OutputManager'].present_text(text, interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py index 7ef8987e..bfb73612 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_a.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('a') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py index 78575c33..530e00dc 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_b.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('b') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py index 3b2733ac..3d710545 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_c.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('c') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py index 08e46880..070aadca 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_d.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('d') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py index 6591af03..46e6659f 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_e.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('e') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py index 2ec56cad..693e2c1d 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_f.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('f') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py index 85efbb07..bb53ae0a 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_g.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('g') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py index 78751213..b44baccf 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_h.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('h') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py index 050ae6e1..dab222a8 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_i.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('i') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py index a6389c10..e76bd33c 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_j.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('j') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py index 121849d5..c1c07f7d 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_k.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('k') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py index a7c5e661..136ba02d 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_l.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('l') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py index 2c11eb16..acd475f2 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_m.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('m') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py index 06c6c944..86256ebc 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_n.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('n') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py index 5cf8ef4a..801c107b 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_o.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('o') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py index b32fd29f..04c48868 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_p.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('p') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py index 56844daa..4011606c 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_q.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('q') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py index 61e9536b..627ce9d8 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_r.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('r') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py index c0c9389b..1997378c 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_s.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('s') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py index 318d4275..d66c3690 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_t.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('t') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py index 66b2eb4a..9cf7e6fe 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_u.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('u') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py index 3ce4be06..f24b7d9f 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_v.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('v') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py index 0c4639f3..fd30ebd3 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_w.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('w') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py index 07b476ca..4625a4e0 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_x.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('x') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py index 81a2d4cf..7d12210f 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_y.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('y') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py b/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py index bd1ed83f..35c2e0e1 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/search_z.py @@ -4,13 +4,18 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import importlib.util import os -_spec = importlib.util.spec_from_file_location("vmenu_search_base", os.path.join(os.path.dirname(__file__), "vmenu_search_base.py")) +_spec = importlib.util.spec_from_file_location( + "vmenu_search_base", os.path.join( + os.path.dirname(__file__), "vmenu_search_base.py")) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -VMenuSearchCommand = _module.VMenuSearchCommand +vmenu_search_command = _module.vmenu_search_command -class command(VMenuSearchCommand): + +class command(vmenu_search_command): def __init__(self): super().__init__('z') diff --git a/src/fenrirscreenreader/commands/vmenu-navigation/vmenu_search_base.py b/src/fenrirscreenreader/commands/vmenu-navigation/vmenu_search_base.py index e3e8fafc..9e57906c 100644 --- a/src/fenrirscreenreader/commands/vmenu-navigation/vmenu_search_base.py +++ b/src/fenrirscreenreader/commands/vmenu-navigation/vmenu_search_base.py @@ -4,26 +4,33 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -class VMenuSearchCommand(): +from fenrirscreenreader.core.i18n import _ + + +class vmenu_search_command(): """Base class for VMenu search commands""" + def __init__(self, search_char): self.search_char = search_char.lower() - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return _('search for an menu entry') - + def run(self): - text = self.env['runtime']['vmenuManager'].searchEntry(self.search_char) + text = self.env['runtime']['VmenuManager'].search_entry( + self.search_char) if text != '': - self.env['runtime']['outputManager'].presentText(text, interrupt=True) + self.env['runtime']['OutputManager'].present_text( + text, interrupt=True) else: - self.env['runtime']['outputManager'].presentText(_('not found'), soundIcon='ErrorScreen', interrupt=True) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + _('not found'), sound_icon ='ErrorScreen', interrupt=True) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/__init__.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/__init__.py index 1c602751..a107eb8b 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/__init__.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/__init__.py @@ -1 +1 @@ -# Fenrir Configuration VMenu Profile \ No newline at end of file +# Fenrir Configuration VMenu Profile diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/config_base.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/config_base.py index 02f9d2bb..8254b407 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/config_base.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/config_base.py @@ -4,131 +4,143 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import os import shutil import tempfile import configparser from datetime import datetime -class ConfigCommand(): + +class config_command(): """Base class for configuration management commands""" - + def __init__(self): self.env = None - self.settingsFile = None + self.settings_file = None self.config = None - + def initialize(self, environment): self.env = environment - self.settingsFile = self.env['runtime']['settingsManager'].settingsFile - self.config = self.env['runtime']['settingsManager'].settings - + self.settings_file = self.env['runtime']['SettingsManager'].settings_file + self.config = self.env['runtime']['SettingsManager'].settings + def shutdown(self): pass - - def setCallback(self, callback): + + def set_callback(self, callback): pass - - def presentText(self, text, interrupt=True, flush=True): + + def present_text(self, text, interrupt=True, flush=True): """Present text to user with proper speech handling""" - self.env['runtime']['outputManager'].presentText(text, interrupt=interrupt, flush=flush) - - def playSound(self, soundName): + self.env['runtime']['OutputManager'].present_text( + text, interrupt=interrupt, flush=flush) + + def play_sound(self, soundName): """Play system sound""" - soundIcon = '' + sound_icon = '' if soundName == 'Accept': - soundIcon = 'Accept' + sound_icon = 'Accept' elif soundName == 'Error': - soundIcon = 'ErrorSound' + sound_icon = 'ErrorSound' elif soundName == 'Cancel': - soundIcon = 'Cancel' - - if soundIcon: - self.env['runtime']['outputManager'].presentText('', soundIcon=soundIcon, interrupt=False) - - def backupConfig(self, announce=True): + sound_icon = 'Cancel' + + if sound_icon: + self.env['runtime']['OutputManager'].present_text( + '', sound_icon =sound_icon, interrupt=False) + + def backup_config(self, announce=True): """Create backup of current configuration file""" try: - if not os.path.exists(self.settingsFile): + if not os.path.exists(self.settings_file): message = "Configuration file not found" if announce: - self.presentText(message) + self.present_text(message) return False, message - + # Create backup with timestamp timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") - backup_path = f"{self.settingsFile}.backup_{timestamp}" - - shutil.copy2(self.settingsFile, backup_path) - + backup_path = f"{self.settings_file}.backup_{timestamp}" + + shutil.copy2(self.settings_file, backup_path) + message = f"Configuration backed up to {backup_path}" if announce: - self.presentText("Configuration backup created successfully") + self.present_text("Configuration backup created successfully") return True, message - + except Exception as e: message = f"Failed to backup configuration: {str(e)}" if announce: - self.presentText(message) + self.present_text(message) return False, message - - def reloadConfig(self): + + def reload_config(self): """Reload configuration from file""" try: # Force settings manager to reload from file - self.env['runtime']['settingsManager'].loadSettings() - self.config = self.env['runtime']['settingsManager'].settings + self.env['runtime']['SettingsManager'].load_settings() + self.config = self.env['runtime']['SettingsManager'].settings return True - + except Exception as e: - self.presentText(f"Failed to reload configuration: {str(e)}") + self.present_text(f"Failed to reload configuration: {str(e)}") return False - - def findDefaultConfig(self): + + def find_default_config(self): """Find default configuration file path""" # Look for default config in multiple locations default_paths = [ '/etc/fenrir/settings/settings.conf.default', '/usr/share/fenrir/settings/settings.conf', - os.path.join(os.path.dirname(self.settingsFile), 'settings.conf.default'), - os.path.join(os.path.dirname(os.path.dirname(self.settingsFile)), 'settings', 'settings.conf.default') - ] - + os.path.join( + os.path.dirname( + self.settings_file), + 'settings.conf.default'), + os.path.join( + os.path.dirname( + os.path.dirname( + self.settings_file)), + 'settings', + 'settings.conf.default')] + for path in default_paths: if os.path.exists(path): return path - + return None - - def createBasicDefaults(self): + + def create_basic_defaults(self): """Create basic default configuration manually""" try: # Create a new config with basic defaults self.config = configparser.ConfigParser() - + # Add basic sections and settings self.config.add_section('speech') self.config.set('speech', 'driver', 'speechdDriver') self.config.set('speech', 'rate', '0.75') self.config.set('speech', 'pitch', '0.5') self.config.set('speech', 'volume', '1.0') - + self.config.add_section('sound') self.config.set('sound', 'driver', 'genericDriver') self.config.set('sound', 'volume', '0.7') - + self.config.add_section('keyboard') self.config.set('keyboard', 'driver', 'evdevDriver') self.config.set('keyboard', 'keyboardLayout', 'desktop') - + self.config.add_section('screen') self.config.set('screen', 'driver', 'vcsaDriver') - + self.config.add_section('general') - self.config.set('general', 'debugMode', 'Off') - + self.config.set('general', 'debug_mode', 'Off') + return True - + except Exception as e: - self.presentText(f"Failed to create basic defaults: {str(e)}") - return False \ No newline at end of file + self.present_text(f"Failed to create basic defaults: {str(e)}") + return False diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/set_punctuation_level.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/set_punctuation_level.py index 1f03fdee..5e3eef24 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/set_punctuation_level.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/set_punctuation_level.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,44 +10,45 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Set punctuation verbosity level" - + def run(self): - currentLevel = self.getSetting('general', 'punctuationLevel', 'some') - + current_level = self.get_setting('general', 'punctuationLevel', 'some') + # Present current level - levelDescriptions = { + level_descriptions = { 'none': 'None - no punctuation spoken', 'some': 'Some - basic punctuation only', 'most': 'Most - detailed punctuation', 'all': 'All - every punctuation mark' } - - currentDescription = levelDescriptions.get(currentLevel, 'Unknown') - self.presentText(f"Current punctuation level: {currentDescription}") - + + current_description = level_descriptions.get(current_level, 'Unknown') + self.present_text(f"Current punctuation level: {current_description}") + # Cycle through the four levels levels = ['none', 'some', 'most', 'all'] try: - currentIndex = levels.index(currentLevel) - nextIndex = (currentIndex + 1) % len(levels) - newLevel = levels[nextIndex] + current_index = levels.index(current_level) + next_index = (current_index + 1) % len(levels) + new_level = levels[next_index] except ValueError: - newLevel = 'some' # Default to some - - success = self.setSetting('general', 'punctuationLevel', newLevel) - + new_level = 'some' # Default to some + + success = self.set_setting('general', 'punctuationLevel', new_level) + if success: - newDescription = levelDescriptions[newLevel] - self.presentText(f"Punctuation level set to: {newDescription}") - self.playSound('Accept') + new_description = level_descriptions[new_level] + self.present_text(f"Punctuation level set to: {new_description}") + self.play_sound('Accept') else: - self.presentText("Failed to change punctuation level") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change punctuation level") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/toggle_debug.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/toggle_debug.py index 8a5e077a..f4504699 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/toggle_debug.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/general/toggle_debug.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,39 +10,41 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Toggle debug mode" - + def run(self): - currentLevel = self.getSetting('general', 'debugLevel', '0') - + current_level = self.get_setting('general', 'debug_level', '0') + # Present current debug level - if currentLevel == '0': - self.presentText("Current debug mode: disabled") - newLevel = '1' - stateText = "enabled" + if current_level == '0': + self.present_text("Current debug mode: disabled") + new_level = '1' + state_text = "enabled" else: - self.presentText(f"Current debug level: {currentLevel}") - newLevel = '0' - stateText = "disabled" - - success = self.setSetting('general', 'debugLevel', newLevel) - + self.present_text(f"Current debug level: {current_level}") + new_level = '0' + state_text = "disabled" + + success = self.set_setting('general', 'debug_level', new_level) + if success: - self.presentText(f"Debug mode {stateText}") - if newLevel != '0': - debugMode = self.getSetting('general', 'debugMode', 'File') - if debugMode == 'File': - self.presentText("Debug output will be written to log file") + self.present_text(f"Debug mode {state_text}") + if new_level != '0': + debug_mode = self.get_setting('general', 'debug_mode', 'File') + if debug_mode == 'File': + self.present_text( + "Debug output will be written to log file") else: - self.presentText("Debug output will be printed to console") - self.playSound('Accept') + self.present_text("Debug output will be printed to console") + self.play_sound('Accept') else: - self.presentText("Failed to change debug mode") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change debug mode") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/select_layout.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/select_layout.py index 49d3f7f4..c147039f 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/select_layout.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/select_layout.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,67 +10,74 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Select keyboard layout (desktop or laptop)" - + def run(self): - currentLayout = self.getSetting('keyboard', 'keyboardLayout', 'desktop') - + current_layout = self.get_setting( + 'keyboard', 'keyboardLayout', 'desktop') + # Present current layout - self.presentText(f"Current keyboard layout: {currentLayout}") - + self.present_text(f"Current keyboard layout: {current_layout}") + # Find available keyboard layouts - keyboardPath = '/etc/fenrirscreenreader/keyboard' - if not os.path.isdir(keyboardPath): + keyboard_path = '/etc/fenrirscreenreader/keyboard' + if not os.path.isdir(keyboard_path): # Development path - keyboardPath = os.path.join(os.path.dirname(self.settingsFile), '..', 'keyboard') - - availableLayouts = self.getAvailableLayouts(keyboardPath) - - if len(availableLayouts) > 1: + keyboard_path = os.path.join( + os.path.dirname( + self.settings_file), + '..', + 'keyboard') + + available_layouts = self.get_available_layouts(keyboard_path) + + if len(available_layouts) > 1: # Cycle through available layouts try: - currentIndex = availableLayouts.index(currentLayout) - nextIndex = (currentIndex + 1) % len(availableLayouts) - newLayout = availableLayouts[nextIndex] + current_index = available_layouts.index(current_layout) + next_index = (current_index + 1) % len(available_layouts) + new_layout = available_layouts[next_index] except ValueError: # Current layout not found, use first available - newLayout = availableLayouts[0] - - success = self.setSetting('keyboard', 'keyboardLayout', newLayout) - + new_layout = available_layouts[0] + + success = self.set_setting('keyboard', 'keyboardLayout', new_layout) + if success: - self.presentText(f"Keyboard layout changed to: {newLayout}") - self.presentText("Please restart Fenrir for this change to take effect.") - self.playSound('Accept') + self.present_text(f"Keyboard layout changed to: {new_layout}") + self.present_text( + "Please restart Fenrir for this change to take effect.") + self.play_sound('Accept') else: - self.presentText("Failed to change keyboard layout") - self.playSound('Error') + self.present_text("Failed to change keyboard layout") + self.play_sound('Error') else: - self.presentText("Only default keyboard layout is available") - self.playSound('Cancel') - - def getAvailableLayouts(self, keyboardPath): + self.present_text("Only default keyboard layout is available") + self.play_sound('Cancel') + + def get_available_layouts(self, keyboard_path): """Find available keyboard layout files""" layouts = [] - - if os.path.isdir(keyboardPath): + + if os.path.isdir(keyboard_path): try: - for file in os.listdir(keyboardPath): + for file in os.listdir(keyboard_path): if file.endswith('.conf') and not file.startswith('.'): - layoutName = file[:-5] # Remove .conf extension - layouts.append(layoutName) + layout_name = file[:-5] # Remove .conf extension + layouts.append(layout_name) except Exception: pass - + # Ensure we have at least the default layouts if not layouts: layouts = ['desktop', 'laptop'] - - return sorted(layouts) \ No newline at end of file + + return sorted(layouts) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/set_char_echo.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/set_char_echo.py index 523df8b5..250d0ac0 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/set_char_echo.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/set_char_echo.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,43 +10,44 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Set character echo mode" - + def run(self): - currentMode = self.getSetting('keyboard', 'charEchoMode', '1') - + current_mode = self.get_setting('keyboard', 'charEchoMode', '1') + # Present current mode - modeDescriptions = { + mode_descriptions = { '0': 'None - no character echo', '1': 'Always - echo all typed characters', '2': 'Caps Lock - echo only when caps lock is on' } - - currentDescription = modeDescriptions.get(currentMode, 'Unknown') - self.presentText(f"Current character echo mode: {currentDescription}") - + + current_description = mode_descriptions.get(current_mode, 'Unknown') + self.present_text(f"Current character echo mode: {current_description}") + # Cycle through the three modes modes = ['0', '1', '2'] try: - currentIndex = modes.index(currentMode) - nextIndex = (currentIndex + 1) % len(modes) - newMode = modes[nextIndex] + current_index = modes.index(current_mode) + next_index = (current_index + 1) % len(modes) + new_mode = modes[next_index] except ValueError: - newMode = '1' # Default to always - - success = self.setSetting('keyboard', 'charEchoMode', newMode) - + new_mode = '1' # Default to always + + success = self.set_setting('keyboard', 'charEchoMode', new_mode) + if success: - newDescription = modeDescriptions[newMode] - self.presentText(f"Character echo mode set to: {newDescription}") - self.playSound('Accept') + new_description = mode_descriptions[new_mode] + self.present_text(f"Character echo mode set to: {new_description}") + self.play_sound('Accept') else: - self.presentText("Failed to change character echo mode") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change character echo mode") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_grab_devices.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_grab_devices.py index fc10dd12..22c6736a 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_grab_devices.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_grab_devices.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,28 +10,32 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Toggle exclusive keyboard access" - + def run(self): - currentState = self.getBooleanSetting('keyboard', 'grabDevices', True) - newState = self.toggleBooleanSetting('keyboard', 'grabDevices') - - if newState != currentState: - stateText = "enabled" if newState else "disabled" - self.presentText(f"Exclusive keyboard access {stateText}") - if newState: - self.presentText("Fenrir will have exclusive control of keyboard input") + current_state = self.getBooleanSetting('keyboard', 'grabDevices', True) + new_state = self.toggleBooleanSetting('keyboard', 'grabDevices') + + if new_state != current_state: + state_text = "enabled" if new_state else "disabled" + self.present_text(f"Exclusive keyboard access {state_text}") + if new_state: + self.present_text( + "Fenrir will have exclusive control of keyboard input") else: - self.presentText("Fenrir will share keyboard input with other applications") - self.presentText("Please restart Fenrir for this change to take effect") - self.playSound('Accept') + self.present_text( + "Fenrir will share keyboard input with other applications") + self.present_text( + "Please restart Fenrir for this change to take effect") + self.play_sound('Accept') else: - self.presentText("Failed to change keyboard grab setting") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change keyboard grab setting") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_word_echo.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_word_echo.py index 14202636..de537806 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_word_echo.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/keyboard/toggle_word_echo.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,27 +10,29 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Toggle word echo when pressing space" - + def run(self): - currentState = self.getBooleanSetting('keyboard', 'wordEcho', False) - newState = self.toggleBooleanSetting('keyboard', 'wordEcho') - - if newState != currentState: - stateText = "enabled" if newState else "disabled" - self.presentText(f"Word echo {stateText}") - if newState: - self.presentText("Words will be spoken when you press space") + current_state = self.getBooleanSetting('keyboard', 'wordEcho', False) + new_state = self.toggleBooleanSetting('keyboard', 'wordEcho') + + if new_state != current_state: + state_text = "enabled" if new_state else "disabled" + self.present_text(f"Word echo {state_text}") + if new_state: + self.present_text("Words will be spoken when you press space") else: - self.presentText("Words will not be spoken when you press space") - self.playSound('Accept') + self.present_text( + "Words will not be spoken when you press space") + self.play_sound('Accept') else: - self.presentText("Failed to change word echo setting") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change word echo setting") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/backup_config.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/backup_config.py index 7aa588ba..89f8a702 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/backup_config.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/backup_config.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,22 +10,25 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Create backup of current configuration" - + def run(self): - self.presentText("Creating configuration backup...") - - success, message = self.backupConfig(announce=False) - + self.present_text("Creating configuration backup...") + + success, message = self.backup_config(announce=False) + if success: # Force the message to be queued and spoken - self.env['runtime']['outputManager'].presentText("Configuration backup created successfully", interrupt=False, flush=False) + self.env['runtime']['OutputManager'].present_text( + "Configuration backup created successfully", interrupt=False, flush=False) else: - self.env['runtime']['outputManager'].presentText("Failed to create configuration backup", interrupt=False, flush=False) \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + "Failed to create configuration backup", interrupt=False, flush=False) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reload_config.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reload_config.py index 7f0c3935..38c3c271 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reload_config.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reload_config.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,23 +10,24 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Reload configuration from file" - + def run(self): - self.presentText("Reloading configuration from file...") - - success = self.reloadConfig() - + self.present_text("Reloading configuration from file...") + + success = self.reload_config() + if success: - self.presentText("Configuration reloaded successfully") - self.playSound('Accept') + self.present_text("Configuration reloaded successfully") + self.play_sound('Accept') else: - self.presentText("Failed to reload configuration") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to reload configuration") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reset_defaults.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reset_defaults.py index 29388aa0..00c8cc12 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reset_defaults.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/reset_defaults.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util import shutil @@ -9,67 +11,91 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Reset configuration to default settings" - + def run(self): - self.presentText("WARNING: This will reset all settings to defaults") - self.presentText("Creating backup before reset...") - + self.present_text("WARNING: This will reset all settings to defaults") + self.present_text("Creating backup before reset...") + # Create backup first - backupSuccess, backupMessage = self.backupConfig(announce=False) + backupSuccess, backupMessage = self.backup_config(announce=False) if not backupSuccess: - self.presentText("Failed to create backup. Reset cancelled for safety.", interrupt=False) - self.playSound('Error') + self.present_text( + "Failed to create backup. Reset cancelled for safety.", + interrupt=False) + self.play_sound('Error') return - + # Find default configuration file - defaultConfigPath = self.findDefaultConfig() - - if defaultConfigPath and os.path.isfile(defaultConfigPath): + default_config_path = self.find_default_config() + + if default_config_path and os.path.isfile(default_config_path): try: # Copy default configuration over current - shutil.copy2(defaultConfigPath, self.settingsFile) - + shutil.copy2(default_config_path, self.settings_file) + # Reload the configuration - self.reloadConfig() - - self.presentText("Configuration reset to defaults successfully", interrupt=False, flush=False) - self.presentText("Please restart Fenrir for all changes to take effect", interrupt=False, flush=False) - + self.reload_config() + + self.present_text( + "Configuration reset to defaults successfully", + interrupt=False, + flush=False) + self.present_text( + "Please restart Fenrir for all changes to take effect", + interrupt=False, + flush=False) + except Exception as e: - self.presentText(f"Failed to reset configuration: {str(e)}", interrupt=False, flush=False) + self.present_text( + f"Failed to reset configuration: { + str(e)}", interrupt=False, flush=False) else: # Manually create basic default configuration - self.createBasicDefaults() - - def findDefaultConfig(self): + self.create_basic_defaults() + + def find_default_config(self): """Find the default configuration file""" - possiblePaths = [ + possible_paths = [ '/usr/share/fenrirscreenreader/config/settings/settings.conf', '/etc/fenrirscreenreader/settings/settings.conf.default', - os.path.join(os.path.dirname(self.settingsFile), 'settings.conf.default'), + os.path.join( + os.path.dirname( + self.settings_file), + 'settings.conf.default'), # Development path - os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..', '..', 'config', 'settings', 'settings.conf') + os.path.join( + os.path.dirname(__file__), + '..', + '..', + '..', + '..', + '..', + '..', + 'config', + 'settings', + 'settings.conf') ] - - for path in possiblePaths: + + for path in possible_paths: if os.path.isfile(path): return path - + return None - - def createBasicDefaults(self): + + def create_basic_defaults(self): """Create basic default configuration manually""" try: self.config.clear() - + # Basic speech defaults self.config['speech'] = { 'enabled': 'True', @@ -79,7 +105,7 @@ class command(ConfigCommand): 'volume': '1.0', 'autoReadIncoming': 'True' } - + # Basic sound defaults self.config['sound'] = { 'enabled': 'True', @@ -87,7 +113,7 @@ class command(ConfigCommand): 'theme': 'default', 'volume': '0.7' } - + # Basic keyboard defaults self.config['keyboard'] = { 'driver': 'evdevDriver', @@ -97,26 +123,34 @@ class command(ConfigCommand): 'wordEcho': 'False', 'charDeleteEcho': 'True' } - + # Basic screen defaults self.config['screen'] = { 'driver': 'vcsaDriver', 'encoding': 'auto' } - + # Basic general defaults self.config['general'] = { 'punctuationLevel': 'some', - 'debugLevel': '0', + 'debug_level': '0', 'numberOfClipboards': '50' } - + # Write the configuration - with open(self.settingsFile, 'w') as configfile: + with open(self.settings_file, 'w') as configfile: self.config.write(configfile) - - self.presentText("Basic default configuration created", interrupt=False, flush=False) - self.presentText("Please restart Fenrir for changes to take effect", interrupt=False, flush=False) - + + self.present_text( + "Basic default configuration created", + interrupt=False, + flush=False) + self.present_text( + "Please restart Fenrir for changes to take effect", + interrupt=False, + flush=False) + except Exception as e: - self.presentText(f"Failed to create default configuration: {str(e)}", interrupt=False, flush=False) \ No newline at end of file + self.present_text( + f"Failed to create default configuration: { + str(e)}", interrupt=False, flush=False) diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/revert_to_saved.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/revert_to_saved.py index 5629524a..5ba3924e 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/revert_to_saved.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/revert_to_saved.py @@ -1,50 +1,62 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Discard temporary changes and revert to saved settings" - + def run(self): - self.env['runtime']['outputManager'].presentText("Reverting to saved configuration...", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Reverting to saved configuration...", interrupt=True) + try: # Reload settings from file, discarding runtime changes - settingsManager = self.env['runtime']['settingsManager'] - settingsManager.loadSettings() - + SettingsManager = self.env['runtime']['SettingsManager'] + SettingsManager.load_settings() + # Reinitialize speech system with restored settings - if 'speechDriver' in self.env['runtime']: + if 'SpeechDriver' in self.env['runtime']: try: - speechDriver = self.env['runtime']['speechDriver'] - speechDriver.shutdown() - speechDriver.initialize(self.env) + SpeechDriver = self.env['runtime']['SpeechDriver'] + SpeechDriver.shutdown() + SpeechDriver.initialize(self.env) except Exception as e: - print(f'revert_to_saved speechDriver: Error reinitializing speech driver: {str(e)}') - - # Reinitialize sound system with restored settings - if 'soundDriver' in self.env['runtime']: + print( + f'revert_to_saved SpeechDriver: Error reinitializing speech driver: { + str(e)}') + + # Reinitialize sound system with restored settings + if 'sound_driver' in self.env['runtime']: try: - soundDriver = self.env['runtime']['soundDriver'] - soundDriver.shutdown() - soundDriver.initialize(self.env) + sound_driver = self.env['runtime']['sound_driver'] + sound_driver.shutdown() + sound_driver.initialize(self.env) except Exception as e: - print(f'revert_to_saved soundDriver: Error reinitializing sound driver: {str(e)}') - - self.env['runtime']['outputManager'].presentText("Successfully reverted to saved settings", interrupt=False, flush=False) - self.env['runtime']['outputManager'].presentText("All temporary changes have been discarded", interrupt=False, flush=False) - + print( + f'revert_to_saved sound_driver: Error reinitializing sound driver: { + str(e)}') + + self.env['runtime']['OutputManager'].present_text( + "Successfully reverted to saved settings", interrupt=False, flush=False) + self.env['runtime']['OutputManager'].present_text( + "All temporary changes have been discarded", interrupt=False, flush=False) + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Error reverting settings: {str(e)}", interrupt=False, flush=False) - self.env['runtime']['outputManager'].presentText("You may need to restart Fenrir", interrupt=False, flush=False) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + f"Error reverting settings: {str(e)}", interrupt=False, flush=False) + self.env['runtime']['OutputManager'].present_text( + "You may need to restart Fenrir", interrupt=False, flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_config.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_config.py index 85cb011b..56bce4e3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_config.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_config.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,29 +10,30 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Save current configuration to file" - + def run(self): - self.presentText("Saving current configuration...") - + self.present_text("Saving current configuration...") + try: # Force reload and save of current configuration - self.reloadConfig() - + self.reload_config() + # Write the configuration file - with open(self.settingsFile, 'w') as configfile: + with open(self.settings_file, 'w') as configfile: self.config.write(configfile) - - self.presentText("Configuration saved successfully") - self.playSound('Accept') - + + self.present_text("Configuration saved successfully") + self.play_sound('Accept') + except Exception as e: - self.presentText(f"Failed to save configuration: {str(e)}") - self.playSound('Error') \ No newline at end of file + self.present_text(f"Failed to save configuration: {str(e)}") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_session_settings.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_session_settings.py index 262c16fa..79a1d91b 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_session_settings.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/save_session_settings.py @@ -1,30 +1,38 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Save current session settings to configuration file" - + def run(self): - self.env['runtime']['outputManager'].presentText("Saving current session settings to configuration file...", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Saving current session settings to configuration file...", interrupt=True) + try: - # This calls the settings manager's save method which writes current runtime settings to file - self.env['runtime']['settingsManager'].saveSettings() - - self.env['runtime']['outputManager'].presentText("Session settings saved successfully!", interrupt=False, flush=False) - self.env['runtime']['outputManager'].presentText("All temporary changes are now permanent.", interrupt=False, flush=False) - + # This calls the settings manager's save method which writes + # current runtime settings to file + self.env['runtime']['SettingsManager'].save_settings() + + self.env['runtime']['OutputManager'].present_text( + "Session settings saved successfully!", interrupt=False, flush=False) + self.env['runtime']['OutputManager'].present_text( + "All temporary changes are now permanent.", interrupt=False, flush=False) + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Failed to save settings: {str(e)}", interrupt=False, flush=False) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + f"Failed to save settings: {str(e)}", interrupt=False, flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/show_unsaved_changes.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/show_unsaved_changes.py index 6af2aae5..6dfd8b07 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/show_unsaved_changes.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/management/show_unsaved_changes.py @@ -1,66 +1,82 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import configparser + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Show temporary changes not yet saved to file" - + def run(self): - self.env['runtime']['outputManager'].presentText("Checking for unsaved changes...", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Checking for unsaved changes...", interrupt=True) + try: # Read the current config file - settingsFile = self.env['runtime']['settingsManager'].settingsFile - fileConfig = configparser.ConfigParser(interpolation=None) - fileConfig.read(settingsFile) - + settings_file = self.env['runtime']['SettingsManager'].settings_file + file_config = configparser.ConfigParser(interpolation=None) + file_config.read(settings_file) + # Compare with runtime settings - runtimeSettings = self.env['runtime']['settingsManager'].settings - + runtime_settings = self.env['runtime']['SettingsManager'].settings + changes = [] - + # Check speech settings specifically - speechSections = ['speech', 'sound', 'keyboard', 'screen', 'general'] - - for section in speechSections: - if section in runtimeSettings and section in fileConfig: - for option in runtimeSettings[section]: - runtimeValue = runtimeSettings[section][option] + speech_sections = [ + 'speech', + 'sound', + 'keyboard', + 'screen', + 'general'] + + for section in speech_sections: + if section in runtime_settings and section in file_config: + for option in runtime_settings[section]: + runtime_value = runtime_settings[section][option] try: - fileValue = fileConfig[section][option] + file_value = file_config[section][option] except Exception as e: - fileValue = "" - - if runtimeValue != fileValue: - changes.append(f"{section}.{option}: {fileValue} → {runtimeValue}") - + file_value = "" + + if runtime_value != file_value: + changes.append( + f"{section}.{option}: {file_value} → {runtime_value}") + if changes: - self.env['runtime']['outputManager'].presentText(f"Found {len(changes)} unsaved changes:", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"found {len(changes)} unsaved changes:", interrupt=True) for change in changes[:5]: # Limit to first 5 changes - self.env['runtime']['outputManager'].presentText(change, interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + change, interrupt=True) + if len(changes) > 5: - self.env['runtime']['outputManager'].presentText(f"... and {len(changes) - 5} more changes", interrupt=True) - - self.env['runtime']['outputManager'].presentText("Use save command to make these changes permanent", interrupt=True) - self.env['runtime']['outputManager'].playSound('Accept') + self.env['runtime']['OutputManager'].present_text( + f"... and {len(changes) - 5} more changes", interrupt=True) + + self.env['runtime']['OutputManager'].present_text( + "Use save command to make these changes permanent", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Accept') else: - self.env['runtime']['outputManager'].presentText("No unsaved changes found", interrupt=True) - self.env['runtime']['outputManager'].playSound('Cancel') - + self.env['runtime']['OutputManager'].present_text( + "No unsaved changes found", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Cancel') + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Error checking for changes: {str(e)}", interrupt=True) - self.env['runtime']['outputManager'].playSound('Error') - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + f"Error checking for changes: {str(e)}", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Error') + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/select_driver.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/select_driver.py index 8b39be77..4cdc3b9e 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/select_driver.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/select_driver.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,45 +10,48 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Select screen driver" - + def run(self): - currentDriver = self.getSetting('screen', 'driver', 'vcsaDriver') - + current_driver = self.get_setting('screen', 'driver', 'vcsaDriver') + # Present current driver - driverDescriptions = { + driver_descriptions = { 'vcsaDriver': 'VCSA Driver - Linux TTY console access', 'ptyDriver': 'PTY Driver - terminal emulation', 'dummyDriver': 'Dummy Driver - for testing only', 'debugDriver': 'Debug Driver - development/debugging' } - - currentDescription = driverDescriptions.get(currentDriver, 'Unknown driver') - self.presentText(f"Current screen driver: {currentDescription}") - + + current_description = driver_descriptions.get( + current_driver, 'Unknown driver') + self.present_text(f"Current screen driver: {current_description}") + # Cycle through the available drivers drivers = ['vcsaDriver', 'ptyDriver', 'dummyDriver', 'debugDriver'] try: - currentIndex = drivers.index(currentDriver) - nextIndex = (currentIndex + 1) % len(drivers) - newDriver = drivers[nextIndex] + current_index = drivers.index(current_driver) + next_index = (current_index + 1) % len(drivers) + new_driver = drivers[next_index] except ValueError: - newDriver = 'vcsaDriver' # Default to VCSA - - success = self.setSetting('screen', 'driver', newDriver) - + new_driver = 'vcsaDriver' # Default to VCSA + + success = self.set_setting('screen', 'driver', new_driver) + if success: - newDescription = driverDescriptions[newDriver] - self.presentText(f"Screen driver changed to: {newDescription}") - self.presentText("Please restart Fenrir for this change to take effect.") - self.playSound('Accept') + new_description = driver_descriptions[new_driver] + self.present_text(f"Screen driver changed to: {new_description}") + self.present_text( + "Please restart Fenrir for this change to take effect.") + self.play_sound('Accept') else: - self.presentText("Failed to change screen driver") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change screen driver") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/set_encoding.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/set_encoding.py index e94c36ce..c0b2bee3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/set_encoding.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/screen/set_encoding.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,39 +10,41 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Set screen text encoding" - + def run(self): - currentEncoding = self.getSetting('screen', 'encoding', 'auto') - + current_encoding = self.get_setting('screen', 'encoding', 'auto') + # Present current encoding - self.presentText(f"Current screen encoding: {currentEncoding}") - + self.present_text(f"Current screen encoding: {current_encoding}") + # Cycle through available encodings encodings = ['auto', 'utf-8', 'cp1252', 'iso-8859-1'] try: - currentIndex = encodings.index(currentEncoding) - nextIndex = (currentIndex + 1) % len(encodings) - newEncoding = encodings[nextIndex] + current_index = encodings.index(current_encoding) + next_index = (current_index + 1) % len(encodings) + new_encoding = encodings[next_index] except ValueError: - newEncoding = 'auto' # Default to auto - - success = self.setSetting('screen', 'encoding', newEncoding) - + new_encoding = 'auto' # Default to auto + + success = self.set_setting('screen', 'encoding', new_encoding) + if success: - self.presentText(f"Screen encoding set to: {newEncoding}") - if newEncoding == 'auto': - self.presentText("Fenrir will automatically detect text encoding") + self.present_text(f"Screen encoding set to: {new_encoding}") + if new_encoding == 'auto': + self.present_text( + "Fenrir will automatically detect text encoding") else: - self.presentText(f"Fenrir will use {newEncoding} encoding") - self.playSound('Accept') + self.present_text(f"Fenrir will use {new_encoding} encoding") + self.play_sound('Accept') else: - self.presentText("Failed to change screen encoding") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change screen encoding") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/adjust_volume.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/adjust_volume.py index ee26d606..5f065cbc 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/adjust_volume.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/adjust_volume.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,36 +10,42 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Adjust sound volume" - + def run(self): - currentVolume = self.getFloatSetting('sound', 'volume', 0.7) - + current_volume = self.getFloatSetting('sound', 'volume', 0.7) + # Present current volume - volumePercent = int(currentVolume * 100) - self.presentText(f"Current sound volume: {volumePercent} percent") - + volume_percent = int(current_volume * 100) + self.present_text(f"Current sound volume: {volume_percent} percent") + # Adjust volume by 10% - newVolume = self.adjustFloatSetting('sound', 'volume', 0.1, 0.0, 1.0) - - if newVolume != currentVolume: - newPercent = int(newVolume * 100) - self.presentText(f"Sound volume set to {newPercent} percent", interrupt=False) - self.playSound('Accept') + new_volume = self.adjustFloatSetting('sound', 'volume', 0.1, 0.0, 1.0) + + if new_volume != current_volume: + new_percent = int(new_volume * 100) + self.present_text( + f"Sound volume set to {new_percent} percent", + interrupt=False) + self.play_sound('Accept') else: # If we hit the maximum, try decreasing instead - newVolume = self.adjustFloatSetting('sound', 'volume', -0.1, 0.0, 1.0) - if newVolume != currentVolume: - newPercent = int(newVolume * 100) - self.presentText(f"Sound volume set to {newPercent} percent", interrupt=False) - self.playSound('Accept') + new_volume = self.adjustFloatSetting( + 'sound', 'volume', -0.1, 0.0, 1.0) + if new_volume != current_volume: + new_percent = int(new_volume * 100) + self.present_text( + f"Sound volume set to {new_percent} percent", + interrupt=False) + self.play_sound('Accept') else: - self.presentText("Sound volume unchanged", interrupt=False) - self.playSound('Cancel') \ No newline at end of file + self.present_text("Sound volume unchanged", interrupt=False) + self.play_sound('Cancel') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_driver.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_driver.py index d524492b..81269896 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_driver.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_driver.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,35 +10,38 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Select sound driver (genericDriver or gstreamerDriver)" - + def run(self): - currentDriver = self.getSetting('sound', 'driver', 'genericDriver') - + current_driver = self.get_setting('sound', 'driver', 'genericDriver') + # Present current driver - self.presentText(f"Current sound driver: {currentDriver}") - + self.present_text(f"Current sound driver: {current_driver}") + # Toggle between the two available drivers - if currentDriver == 'genericDriver': - newDriver = 'gstreamerDriver' - driverDescription = "GStreamer Driver - advanced multimedia framework" + if current_driver == 'genericDriver': + new_driver = 'gstreamerDriver' + driver_description = "GStreamer Driver - advanced multimedia framework" else: - newDriver = 'genericDriver' - driverDescription = "Generic Driver - uses SOX for audio playback" - - success = self.setSetting('sound', 'driver', newDriver) - + new_driver = 'genericDriver' + driver_description = "Generic Driver - uses SOX for audio playback" + + success = self.set_setting('sound', 'driver', new_driver) + if success: - self.presentText(f"Sound driver changed to {newDriver}. {driverDescription}") - self.presentText("Please restart Fenrir for this change to take effect.") - self.playSound('Accept') + self.present_text( + f"Sound driver changed to {new_driver}. {driver_description}") + self.present_text( + "Please restart Fenrir for this change to take effect.") + self.play_sound('Accept') else: - self.presentText("Failed to change sound driver") - self.playSound('Error') \ No newline at end of file + self.present_text("Failed to change sound driver") + self.play_sound('Error') diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_theme.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_theme.py index 9203f0a5..65f2a170 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_theme.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/select_theme.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,77 +10,80 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Select sound theme" - + def run(self): - currentTheme = self.getSetting('sound', 'theme', 'default') - + current_theme = self.get_setting('sound', 'theme', 'default') + # Present current theme - self.presentText(f"Current sound theme: {currentTheme}") - + self.present_text(f"Current sound theme: {current_theme}") + # Look for available sound themes - soundPaths = [ + sound_paths = [ '/usr/share/sounds', '/usr/share/fenrirscreenreader/sounds', os.path.expanduser('~/.local/share/fenrirscreenreader/sounds') ] - - availableThemes = self.getAvailableThemes(soundPaths) - - if len(availableThemes) > 1: + + available_themes = self.get_available_themes(sound_paths) + + if len(available_themes) > 1: # For this implementation, cycle through available themes try: - currentIndex = availableThemes.index(currentTheme) - nextIndex = (currentIndex + 1) % len(availableThemes) - newTheme = availableThemes[nextIndex] + current_index = available_themes.index(current_theme) + next_index = (current_index + 1) % len(available_themes) + new_theme = available_themes[next_index] except ValueError: # Current theme not found in available themes, use first one - newTheme = availableThemes[0] - - success = self.setSetting('sound', 'theme', newTheme) - + new_theme = available_themes[0] + + success = self.set_setting('sound', 'theme', new_theme) + if success: - self.presentText(f"Sound theme changed to: {newTheme}") - self.playSound('Accept') + self.present_text(f"Sound theme changed to: {new_theme}") + self.play_sound('Accept') else: - self.presentText("Failed to change sound theme") - self.playSound('Error') + self.present_text("Failed to change sound theme") + self.play_sound('Error') else: - self.presentText("Only default sound theme is available") - self.playSound('Cancel') - - def getAvailableThemes(self, searchPaths): + self.present_text("Only default sound theme is available") + self.play_sound('Cancel') + + def get_available_themes(self, searchPaths): """Find available sound themes in the search paths""" themes = ['default'] # Always include default - + for path in searchPaths: if os.path.isdir(path): try: for item in os.listdir(path): - fullPath = os.path.join(path, item) - if os.path.isdir(fullPath) and item != 'default' and item not in themes: - # Check if it looks like a sound theme (contains sound files) - if self.isValidSoundTheme(fullPath): + full_path = os.path.join(path, item) + if os.path.isdir( + full_path) and item != 'default' and item not in themes: + # Check if it looks like a sound theme (contains + # sound files) + if self.is_valid_sound_theme(full_path): themes.append(item) except Exception: continue - + return themes - - def isValidSoundTheme(self, themePath): + + def is_valid_sound_theme(self, themePath): """Check if a directory contains sound files""" - soundExtensions = ['.wav', '.ogg', '.mp3', '.flac'] + sound_extensions = ['.wav', '.ogg', '.mp3', '.flac'] try: for file in os.listdir(themePath): - if any(file.lower().endswith(ext) for ext in soundExtensions): + if any(file.lower().endswith(ext) for ext in sound_extensions): return True except Exception: pass - return False \ No newline at end of file + return False diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/toggle_enabled.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/toggle_enabled.py index 892c2758..cd648e9f 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/toggle_enabled.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/sound/toggle_enabled.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + import os import importlib.util @@ -8,24 +10,25 @@ _base_path = os.path.join(os.path.dirname(__file__), '..', 'config_base.py') _spec = importlib.util.spec_from_file_location("config_base", _base_path) _module = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(_module) -ConfigCommand = _module.ConfigCommand +config_command = _module.config_command -class command(ConfigCommand): + +class command(config_command): def __init__(self): super().__init__() - - def getDescription(self): + + def get_description(self): return "Toggle sound output on or off" - + def run(self): - currentState = self.getBooleanSetting('sound', 'enabled', True) - newState = self.toggleBooleanSetting('sound', 'enabled') - - if newState != currentState: - stateText = "enabled" if newState else "disabled" - self.presentText(f"Sound {stateText}") + current_state = self.getBooleanSetting('sound', 'enabled', True) + new_state = self.toggleBooleanSetting('sound', 'enabled') + + if new_state != current_state: + state_text = "enabled" if new_state else "disabled" + self.present_text(f"Sound {state_text}") # Only play sound if we enabled sound - if newState: - self.playSound('Accept') + if new_state: + self.play_sound('Accept') else: - self.presentText("Failed to change sound setting") \ No newline at end of file + self.present_text("Failed to change sound setting") diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_pitch.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_pitch.py index d0993a42..6ed85581 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_pitch.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_pitch.py @@ -1,40 +1,48 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Adjust speech pitch (voice height)" - + def run(self): try: # Get current pitch - currentPitch = float(self.env['runtime']['settingsManager'].getSetting('speech', 'pitch')) + current_pitch = float( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'pitch')) except Exception as e: - currentPitch = 0.5 - + current_pitch = 0.5 + # Present current pitch - pitchPercent = int(currentPitch * 100) - self.env['runtime']['outputManager'].presentText(f"Current speech pitch: {pitchPercent} percent", interrupt=True) - + pitch_percent = int(current_pitch * 100) + self.env['runtime']['OutputManager'].present_text( + f"Current speech pitch: {pitch_percent} percent", interrupt=True) + # Increase by 10%, wrap around if at max - newPitch = currentPitch + 0.1 - if newPitch > 1.0: - newPitch = 0.1 # Wrap to minimum - + new_pitch = current_pitch + 0.1 + if new_pitch > 1.0: + new_pitch = 0.1 # Wrap to minimum + # Apply the new pitch - self.env['runtime']['settingsManager'].setSetting('speech', 'pitch', str(newPitch)) - - newPercent = int(newPitch * 100) - self.env['runtime']['outputManager'].presentText(f"Speech pitch set to {newPercent} percent", interrupt=True) - self.env['runtime']['outputManager'].playSound('Accept') - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'pitch', str(new_pitch)) + + new_percent = int(new_pitch * 100) + self.env['runtime']['OutputManager'].present_text( + f"Speech pitch set to {new_percent} percent", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Accept') + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_rate.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_rate.py index e27b1515..44c50714 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_rate.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_rate.py @@ -1,39 +1,47 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Adjust speech rate (speed)" - + def run(self): try: # Get current rate - currentRate = float(self.env['runtime']['settingsManager'].getSetting('speech', 'rate')) + current_rate = float( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'rate')) except Exception as e: - currentRate = 0.5 - + current_rate = 0.5 + # Present current rate - ratePercent = int(currentRate * 100) - self.env['runtime']['outputManager'].presentText(f"Current speech rate: {ratePercent} percent", interrupt=True) - + rate_percent = int(current_rate * 100) + self.env['runtime']['OutputManager'].present_text( + f"Current speech rate: {rate_percent} percent", interrupt=True) + # Increase by 10%, wrap around if at max - newRate = currentRate + 0.1 - if newRate > 1.0: - newRate = 0.1 # Wrap to minimum - + new_rate = current_rate + 0.1 + if new_rate > 1.0: + new_rate = 0.1 # Wrap to minimum + # Apply the new rate - self.env['runtime']['settingsManager'].setSetting('speech', 'rate', str(newRate)) - - newPercent = int(newRate * 100) - self.env['runtime']['outputManager'].presentText(f"Speech rate set to {newPercent} percent", interrupt=False, flush=False) - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'rate', str(new_rate)) + + new_percent = int(new_rate * 100) + self.env['runtime']['OutputManager'].present_text( + f"Speech rate set to {new_percent} percent", interrupt=False, flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_speech_rate.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_speech_rate.py index f9cd18de..3efd8b99 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_speech_rate.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_speech_rate.py @@ -1,49 +1,59 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Adjust speech rate (temporary - use save to make permanent)" - + def run(self): try: # Get current rate from runtime settings (may be temporary) - settingsManager = self.env['runtime']['settingsManager'] - currentRate = float(settingsManager.getSetting('speech', 'rate')) + SettingsManager = self.env['runtime']['SettingsManager'] + current_rate = float(SettingsManager.get_setting('speech', 'rate')) except Exception as e: - currentRate = 0.5 - + current_rate = 0.5 + # Present current rate - ratePercent = int(currentRate * 100) - self.env['runtime']['outputManager'].presentText(f"Current speech rate: {ratePercent} percent", interrupt=True) - + rate_percent = int(current_rate * 100) + self.env['runtime']['OutputManager'].present_text( + f"Current speech rate: {rate_percent} percent", interrupt=True) + # Increase by 10%, wrap around if at max - newRate = currentRate + 0.1 - if newRate > 1.0: - newRate = 0.1 # Wrap to minimum - + new_rate = current_rate + 0.1 + if new_rate > 1.0: + new_rate = 0.1 # Wrap to minimum + # Apply ONLY to runtime - this is temporary until saved - settingsManager = self.env['runtime']['settingsManager'] - settingsManager.settings['speech']['rate'] = str(newRate) - + SettingsManager = self.env['runtime']['SettingsManager'] + SettingsManager.settings['speech']['rate'] = str(new_rate) + # Apply to speech system immediately for this session - if 'speechDriver' in self.env['runtime']: + if 'SpeechDriver' in self.env['runtime']: try: - self.env['runtime']['speechDriver'].setRate(newRate) + self.env['runtime']['SpeechDriver'].set_rate(new_rate) except Exception as e: - print(f'adjust_speech_rate setRate: Error setting speech rate: {str(e)}') - - newPercent = int(newRate * 100) - self.env['runtime']['outputManager'].presentText(f"Speech rate temporarily set to {newPercent} percent", interrupt=False, flush=False) - self.env['runtime']['outputManager'].presentText("Use save command to make permanent", interrupt=False, flush=False) - - def setCallback(self, callback): - pass \ No newline at end of file + print( + f'adjust_speech_rate set_rate: Error setting speech rate: { + str(e)}') + + new_percent = int(new_rate * 100) + self.env['runtime']['OutputManager'].present_text( + f"Speech rate temporarily set to {new_percent} percent", + interrupt=False, + flush=False) + self.env['runtime']['OutputManager'].present_text( + "Use save command to make permanent", interrupt=False, flush=False) + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_volume.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_volume.py index 14accb4a..cd3ca596 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_volume.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/adjust_volume.py @@ -1,40 +1,48 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Adjust speech volume (loudness)" - + def run(self): try: # Get current volume - currentVolume = float(self.env['runtime']['settingsManager'].getSetting('speech', 'volume')) + current_volume = float( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'volume')) except Exception as e: - currentVolume = 1.0 - + current_volume = 1.0 + # Present current volume - volumePercent = int(currentVolume * 100) - self.env['runtime']['outputManager'].presentText(f"Current speech volume: {volumePercent} percent", interrupt=True) - + volume_percent = int(current_volume * 100) + self.env['runtime']['OutputManager'].present_text( + f"Current speech volume: {volume_percent} percent", interrupt=True) + # Increase by 10%, wrap around if at max - newVolume = currentVolume + 0.1 - if newVolume > 1.0: - newVolume = 0.1 # Wrap to minimum - + new_volume = current_volume + 0.1 + if new_volume > 1.0: + new_volume = 0.1 # Wrap to minimum + # Apply the new volume - self.env['runtime']['settingsManager'].setSetting('speech', 'volume', str(newVolume)) - - newPercent = int(newVolume * 100) - self.env['runtime']['outputManager'].presentText(f"Speech volume set to {newPercent} percent", interrupt=True) - self.env['runtime']['outputManager'].playSound('Accept') - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'volume', str(new_volume)) + + new_percent = int(new_volume * 100) + self.env['runtime']['OutputManager'].present_text( + f"Speech volume set to {new_percent} percent", interrupt=True) + self.env['runtime']['OutputManager'].play_sound('Accept') + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/show_current_settings.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/show_current_settings.py index 3d9c759d..5f91f310 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/show_current_settings.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/fenrir/speech/show_current_settings.py @@ -1,59 +1,80 @@ #!/usr/bin/env python3 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Show current speech settings" - + def run(self): # Get current speech settings - driver = self.env['runtime']['settingsManager'].getSetting('speech', 'driver') - module = self.env['runtime']['settingsManager'].getSetting('speech', 'module') - voice = self.env['runtime']['settingsManager'].getSetting('speech', 'voice') - rate = self.env['runtime']['settingsManager'].getSetting('speech', 'rate') - pitch = self.env['runtime']['settingsManager'].getSetting('speech', 'pitch') - volume = self.env['runtime']['settingsManager'].getSetting('speech', 'volume') - enabled = self.env['runtime']['settingsManager'].getSetting('speech', 'enabled') - - self.env['runtime']['outputManager'].presentText("Current speech settings:", interrupt=True) - + driver = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'driver') + module = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'module') + voice = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'voice') + rate = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'rate') + pitch = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'pitch') + volume = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'volume') + enabled = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'enabled') + + self.env['runtime']['OutputManager'].present_text( + "Current speech settings:", interrupt=True) + # Present all settings - self.env['runtime']['outputManager'].presentText(f"Speech enabled: {enabled}", interrupt=True) - self.env['runtime']['outputManager'].presentText(f"Driver: {driver}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Speech enabled: {enabled}", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + f"Driver: {driver}", interrupt=True) + if module: - self.env['runtime']['outputManager'].presentText(f"Module: {module}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Module: {module}", interrupt=True) + if voice: - self.env['runtime']['outputManager'].presentText(f"Voice: {voice}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Voice: {voice}", interrupt=True) + try: - ratePercent = int(float(rate) * 100) - self.env['runtime']['outputManager'].presentText(f"Rate: {ratePercent} percent", interrupt=True) + rate_percent = int(float(rate) * 100) + self.env['runtime']['OutputManager'].present_text( + f"Rate: {rate_percent} percent", interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Rate: {rate}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Rate: {rate}", interrupt=True) + try: - pitchPercent = int(float(pitch) * 100) - self.env['runtime']['outputManager'].presentText(f"Pitch: {pitchPercent} percent", interrupt=True) + pitch_percent = int(float(pitch) * 100) + self.env['runtime']['OutputManager'].present_text( + f"Pitch: {pitch_percent} percent", interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Pitch: {pitch}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Pitch: {pitch}", interrupt=True) + try: - volumePercent = int(float(volume) * 100) - self.env['runtime']['outputManager'].presentText(f"Volume: {volumePercent} percent", interrupt=True) + volume_percent = int(float(volume) * 100) + self.env['runtime']['OutputManager'].present_text( + f"Volume: {volume_percent} percent", interrupt=True) except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Volume: {volume}", interrupt=True) - - self.env['runtime']['outputManager'].playSound('Accept') - - def setCallback(self, callback): - pass \ No newline at end of file + self.env['runtime']['OutputManager'].present_text( + f"Volume: {volume}", interrupt=True) + + self.env['runtime']['OutputManager'].play_sound('Accept') + + def set_callback(self, callback): + pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py index 571f69c8..35ea7ce7 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/open.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py index d5d57e3c..dd71e6bc 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/file/save.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open save', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py index 08e1e27a..c5ffbfda 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/replace.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run replace macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py index 6862f01b..c66a25b3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/search.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run search macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py index 7a95ca1c..8e4ff2a1 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mc/search/test.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the date') - + pass + + def get_description(self): + return _('presents the date') + def run(self): - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') # get the time formatted - dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) + date_string = datetime.datetime.strftime( + datetime.datetime.now(), date_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py index 3329ab3e..5a705fcc 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/issue.py @@ -5,20 +5,26 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.keyMakro = [[1, 'KEY_LEFTCTRL'], [1, 'KEY_G'], [0.05,'sleep'] ,[0, 'KEY_G'], [0, 'KEY_LEFTCTRL']] + self.key_macro = [[1, 'KEY_LEFTCTRL'], [1, 'KEY_G'], [ + 0.05, 'sleep'], [0, 'KEY_G'], [0, 'KEY_LEFTCTRL']] + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['inputManager'].sendKeys(self.keyMakro) - def setCallback(self, callback): + self.env['runtime']['InputManager'].send_keys(self.key_macro) + + def set_callback(self, callback): pass - - - diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py index a7d9ceab..609776b8 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/open.py @@ -5,17 +5,33 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.macro = [[1,'KEY_LEFTSHIFT'],[1,'KEY_LEFTCTRL'],[1,'KEY_N'],[0.05,'SLEEP'],[0,'KEY_N'],[0,'KEY_LEFTCTRL'],[0,'KEY_LEFTSHIFT']] + self.macro = [ + [ + 1, 'KEY_LEFTSHIFT'], [ + 1, 'KEY_LEFTCTRL'], [ + 1, 'KEY_N'], [ + 0.05, 'SLEEP'], [ + 0, 'KEY_N'], [ + 0, 'KEY_LEFTCTRL'], [ + 0, 'KEY_LEFTSHIFT']] + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['inputManager'].sendKeys(self.macro) - def setCallback(self, callback): + self.env['runtime']['InputManager'].send_keys(self.macro) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py index d5d57e3c..dd71e6bc 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/file/save.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open save', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py index 08e1e27a..c5ffbfda 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/replace.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run replace macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py index 6862f01b..c66a25b3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/search.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run search macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py index 7a95ca1c..8e4ff2a1 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/mutt/search/test.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the date') - + pass + + def get_description(self): + return _('presents the date') + def run(self): - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') # get the time formatted - dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) + date_string = datetime.datetime.strftime( + datetime.datetime.now(), date_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py index f4e2bddb..a5eeda40 100755 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/Help/about_nano.py @@ -2,13 +2,16 @@ # -*- encoding: utf-8 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass def initialize(self, environment): self.env = environment - self.keyMakro = [[1, 'KEY_LEFTCTRL'], + self.key_macro = [[1, 'KEY_LEFTCTRL'], [1, 'KEY_G'], [0.05, 'SLEEP'], [0, 'KEY_G'], @@ -17,16 +20,16 @@ class command(): def shutdown(self): pass - def getDescription(self): + def get_description(self): return "Learn about the Nano text editor." def run(self): - self.env['runtime']['outputManager'].presentText( + self.env['runtime']['OutputManager'].present_text( "Okay, loading the information about Nano.", interrupt=True) - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - self.env['runtime']['inputManager'].sendKeys(self.keyMakro) - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: - self.env['runtime']['byteManager'].sendBytes(self.byteMakro) + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + self.env['runtime']['InputManager'].send_keys(self.key_macro) + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: + self.env['runtime']['ByteManager'].send_bytes(self.byteMakro) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py index 571f69c8..35ea7ce7 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/open.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py index 879f01b7..604ee4a0 100755 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/file/save.py @@ -2,13 +2,16 @@ # -*- encoding: utf-8 +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass def initialize(self, environment): self.env = environment - self.keyMakro = [[1, 'KEY_LEFTCTRL'], + self.key_macro = [[1, 'KEY_LEFTCTRL'], [1, 'KEY_S'], [0.05, 'SLEEP'], [0, 'KEY_S'], @@ -17,16 +20,16 @@ class command(): def shutdown(self): pass - def getDescription(self): + def get_description(self): return "Save your work." def run(self): - self.env['runtime']['outputManager'].presentText( + self.env['runtime']['OutputManager'].present_text( "Okay, you will now be asked to save your work.", interrupt=True) - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - self.env['runtime']['inputManager'].sendKeys(self.keyMakro) - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: - self.env['runtime']['byteManager'].sendBytes(self.byteMakro) + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + self.env['runtime']['InputManager'].send_keys(self.key_macro) + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: + self.env['runtime']['ByteManager'].send_bytes(self.byteMakro) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py index 08e1e27a..c5ffbfda 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/replace.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run replace macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py index 6862f01b..c66a25b3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/search.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run search macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py index 7a95ca1c..8e4ff2a1 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/nano/search/test.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the date') - + pass + + def get_description(self): + return _('presents the date') + def run(self): - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') # get the time formatted - dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) + date_string = datetime.datetime.strftime( + datetime.datetime.now(), date_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py index 571f69c8..35ea7ce7 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/open.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py index d5d57e3c..dd71e6bc 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/file/save.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run open save' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run open save', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py index 08e1e27a..c5ffbfda 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/replace.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run replace macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run replace macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py index 6862f01b..c66a25b3 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/search.py @@ -5,16 +5,25 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - self.env['runtime']['outputManager'].presentText('ok i run search macro' , interrupt=True) - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + 'ok i run search macro', interrupt=True) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py index 7a95ca1c..8e4ff2a1 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/KEY/vim/search/test.py @@ -4,26 +4,36 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + import datetime + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def getDescription(self): - return _('presents the date') - + pass + + def get_description(self): + return _('presents the date') + def run(self): - dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat') + date_format = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'date_format') # get the time formatted - dateString = datetime.datetime.strftime(datetime.datetime.now(), dateFormat) + date_string = datetime.datetime.strftime( + datetime.datetime.now(), date_format) - # present the time via speak and braile, there is no soundicon, interrupt the current speech - self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=True) + # present the time via speak and braile, there is no soundicon, + # interrupt the current speech + self.env['runtime']['OutputManager'].present_text( + date_string, sound_icon ='', interrupt=True) - def setCallback(self, callback): + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/commands/vmenu-profiles/template.py b/src/fenrirscreenreader/commands/vmenu-profiles/template.py index 922d5cc1..6b2ba8bb 100644 --- a/src/fenrirscreenreader/commands/vmenu-profiles/template.py +++ b/src/fenrirscreenreader/commands/vmenu-profiles/template.py @@ -5,24 +5,32 @@ # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.i18n import _ + + class command(): def __init__(self): pass + def initialize(self, environment): self.env = environment # examples: - # self.keyMakro = [[1,'KEY_LEFTCTRL'],[1,'KEY_O'],[0.05,'SLEEP'],[0,'KEY_O'],[0,'KEY_LEFTCTRL']] - # self.keyMakro = [[1,'KEY_LEFTSHIFT'],[1,'KEY_LEFTCTRL'],[1,'KEY_N'],[0.05,'SLEEP'],[0,'KEY_N'],[0,'KEY_LEFTCTRL'],[0,'KEY_LEFTSHIFT']] - self.keyMakro = [] + # self.key_macro = [[1,'KEY_LEFTCTRL'],[1,'KEY_O'],[0.05,'SLEEP'],[0,'KEY_O'],[0,'KEY_LEFTCTRL']] + # self.key_macro = [[1,'KEY_LEFTSHIFT'],[1,'KEY_LEFTCTRL'],[1,'KEY_N'],[0.05,'SLEEP'],[0,'KEY_N'],[0,'KEY_LEFTCTRL'],[0,'KEY_LEFTSHIFT']] + self.key_macro = [] self.byteMakro = [] + def shutdown(self): pass - def getDescription(self): - return 'No description found' + + def get_description(self): + return 'No description found' + def run(self): - if self.env['runtime']['inputManager'].getShortcutType() in ['KEY']: - self.env['runtime']['inputManager'].sendKeys(self.keyMakro) - elif self.env['runtime']['inputManager'].getShortcutType() in ['BYTE']: - self.env['runtime']['byteManager'].sendBytes(self.byteMakro) - def setCallback(self, callback): + if self.env['runtime']['InputManager'].get_shortcut_type() in ['KEY']: + self.env['runtime']['InputManager'].send_keys(self.key_macro) + elif self.env['runtime']['InputManager'].get_shortcut_type() in ['BYTE']: + self.env['runtime']['ByteManager'].send_bytes(self.byteMakro) + + def set_callback(self, callback): pass diff --git a/src/fenrirscreenreader/core/applicationManager.py b/src/fenrirscreenreader/core/applicationManager.py index b05fde9a..b6639fc6 100644 --- a/src/fenrirscreenreader/core/applicationManager.py +++ b/src/fenrirscreenreader/core/applicationManager.py @@ -6,26 +6,32 @@ from fenrirscreenreader.core import debug -class applicationManager(): + +class ApplicationManager(): def __init__(self): pass + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getCurrentApplication(self): - currApp = self.env['screen']['newApplication'].upper() - if not currApp: - currApp = 'DEFAULT' - if currApp == '': - currApp = 'DEFAULT' - return currApp - def getPrevApplication(self): - prevApp = self.env['screen']['oldApplication'].upper() - if not prevApp: - prevApp = 'DEFAULT' - if prevApp == '': - prevApp = 'DEFAULT' - return prevApp - def isApplicationChange(self): - return self.env['screen']['oldApplication'] != self.env['screen']['newApplication'] + + def get_current_application(self): + curr_app = self.env['screen']['new_application'].upper() + if not curr_app: + curr_app = 'DEFAULT' + if curr_app == '': + curr_app = 'DEFAULT' + return curr_app + + def get_prev_application(self): + prev_app = self.env['screen']['oldApplication'].upper() + if not prev_app: + prev_app = 'DEFAULT' + if prev_app == '': + prev_app = 'DEFAULT' + return prev_app + + def is_application_change(self): + return self.env['screen']['oldApplication'] != self.env['screen']['new_application'] diff --git a/src/fenrirscreenreader/core/attributeManager.py b/src/fenrirscreenreader/core/attributeManager.py index 43ced0d7..d4ad5ba9 100644 --- a/src/fenrirscreenreader/core/attributeManager.py +++ b/src/fenrirscreenreader/core/attributeManager.py @@ -5,64 +5,81 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ from collections import Counter -class attributeManager(): + +class AttributeManager(): def __init__(self): self.currAttributes = None self.prevAttributes = None self.currAttributeDelta = '' self.currAttributeCursor = None self.prefAttributeCursor = None - self.initDefaultAttributes() + self.init_default_attributes() self.prevLastCursorAttribute = None self.currLastCursorAttribute = None def initialize(self, environment): self.env = environment + def shutdown(self): pass - def setLastCursorAttribute(self, lastCursorAttribute): + + def set_last_cursor_attribute(self, lastCursorAttribute): self.prevLastCursorAttribute = self.currLastCursorAttribute self.currLastCursorAttribute = lastCursorAttribute - def resetLastCursorAttribute(self): + + def reset_last_cursor_attribute(self): self.prevLastCursorAttribute = None self.currLastCursorAttribute = None - def isLastCursorAttributeChange(self): - if self.prevLastCursorAttribute == None: + + def is_last_cursor_attribute_change(self): + if self.prevLastCursorAttribute is None: return False return self.prevLastCursorAttribute != self.currLastCursorAttribute - def getCurrAttributeCursor(self): + + def get_curr_attribute_cursor(self): return self.currAttributeCursor - def isAttributeCursorActive(self): - return self.currAttributeCursor != None - def isAttributeChange(self): - if not self.prevAttributes: + + def is_attribute_cursor_active(self): + return self.currAttributeCursor is not None + + def is_attribute_change(self): + if not self.prevAttributes: return False return self.currAttributes != self.prevAttributes - def resetAttributeAll(self): - self.resetAttributeDelta() - self.resetAttributeCursor() - def getAttributeDelta(self): + + def reset_attribute_all(self): + self.reset_attribute_delta() + self.reset_attribute_cursor() + + def get_attribute_delta(self): return self.currAttributeDelta - def resetAttributeDelta(self): + + def reset_attribute_delta(self): self.currAttributeDelta = '' - def setAttributeDelta(self, currAttributeDelta): + + def set_attribute_delta(self, currAttributeDelta): self.currAttributeDelta = currAttributeDelta - def resetAttributeCursor(self): + + def reset_attribute_cursor(self): self.currAttributeCursor = None self.prefAttributeCursor = None - def setAttributeCursor(self, currAttributeCursor): + + def set_attribute_cursor(self, currAttributeCursor): self.prefAttributeCursor = self.currAttributeCursor self.currAttributeCursor = currAttributeCursor.copy() - def resetAttributes(self, currAttributes): + + def reset_attributes(self, currAttributes): self.prevAttributes = None self.currAttributes = currAttributes - def setAttributes(self, currAttributes): + + def set_attributes(self, currAttributes): self.prevAttributes = self.currAttributes self.currAttributes = currAttributes.copy() - def getAttributeByXY(self, x, y): + def get_attribute_by_xy(self, x, y): if not self.currAttributes: return None if len(self.currAttributes) < y: @@ -75,50 +92,57 @@ class attributeManager(): try: return self.defaultAttributes[0] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('attributeManager getAttributeByXY: Error accessing default attributes: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'AttributeManager get_attribute_by_xy: Error accessing default attributes: ' + + str(e), + debug.DebugLevel.ERROR) return None - def appendDefaultAttributes(self, attribute): + + def append_default_attributes(self, attribute): if not attribute: return if len(attribute) != 10: return self.defaultAttributes.append(attribute) - def initDefaultAttributes(self): + + def init_default_attributes(self): self.defaultAttributes = [None] self.defaultAttributes.append([ - 'default', # fg - 'default', # bg - False, # bold - False, # italics - False, # underscore - False, # strikethrough - False, # reverse - False, # blink - 'default', # fontsize - 'default' # fontfamily - ]) #end attribute - def isDefaultAttribute(self,attribute): + 'default', # fg + 'default', # bg + False, # bold + False, # italics + False, # underscore + False, # strikethrough + False, # reverse + False, # blink + 'default', # fontsize + 'default' # fontfamily + ]) # end attribute + + def is_default_attribute(self, attribute): return attribute in self.defaultAttributes - def hasAttributes(self, cursor, update=True): + + def has_attributes(self, cursor, update=True): if not cursor: return False - cursorPos = cursor.copy() + cursor_pos = cursor.copy() try: - attribute = self.getAttributeByXY( cursorPos['x'], cursorPos['y']) + attribute = self.get_attribute_by_xy(cursor_pos['x'], cursor_pos['y']) if update: - self.setLastCursorAttribute(attribute) - if not self.isLastCursorAttributeChange(): + self.set_last_cursor_attribute(attribute) + if not self.is_last_cursor_attribute_change(): return False - if self.isDefaultAttribute(attribute): + if self.is_default_attribute(attribute): return False except Exception as e: return False return True - def formatAttributes(self, attribute, attributeFormatString = ''): + def format_attributes(self, attribute, attribute_format_string=''): # "black", # "red", # "green", @@ -139,11 +163,12 @@ class attributeManager(): # "blink" # "fontsieze" # "fontfamily" - if attributeFormatString == '': - attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString') - if not attributeFormatString: + if attribute_format_string == '': + attribute_format_string = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'attribute_format_string') + if not attribute_format_string: return '' - if attributeFormatString == '': + if attribute_format_string == '': return '' if not attribute: return '' @@ -152,154 +177,194 @@ class attributeManager(): # 0 FG color (name) try: - attributeFormatString = attributeFormatString.replace('fenrirFGColor', _(attribute[0])) + attribute_format_string = attribute_format_string.replace( + 'fenrirFGColor', _(attribute[0])) except Exception as e: - attributeFormatString = attributeFormatString.replace('fenrirFGColor', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirFGColor', '') # 1 BG color (name) try: - attributeFormatString = attributeFormatString.replace('fenrirBGColor', _(attribute[1])) + attribute_format_string = attribute_format_string.replace( + 'fenrirBGColor', _(attribute[1])) except Exception as e: - attributeFormatString = attributeFormatString.replace('fenrirBGColor', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirBGColor', '') # 2 bold (True/ False) try: if attribute[2]: - attributeFormatString = attributeFormatString.replace('fenrirBold', _('bold')) + attribute_format_string = attribute_format_string.replace( + 'fenrirBold', _('bold')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirBold', '') + attribute_format_string = attribute_format_string.replace('fenrirBold', '') # 3 italics (True/ False) try: if attribute[3]: - attributeFormatString = attributeFormatString.replace('fenrirItalics', _('italic')) + attribute_format_string = attribute_format_string.replace( + 'fenrirItalics', _('italic')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirItalics', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirItalics', '') # 4 underline (True/ False) try: if attribute[4]: - attributeFormatString = attributeFormatString.replace('fenrirUnderline', _('underline')) + attribute_format_string = attribute_format_string.replace( + 'fenrirUnderline', _('underline')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirUnderline', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirUnderline', '') # 5 strikethrough (True/ False) try: if attribute[5]: - attributeFormatString = attributeFormatString.replace('fenrirStrikethrough', _('strikethrough')) + attribute_format_string = attribute_format_string.replace( + 'fenrirStrikethrough', _('strikethrough')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirStrikethrough', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirStrikethrough', '') # 6 reverse (True/ False) try: if attribute[6]: - attributeFormatString = attributeFormatString.replace('fenrirReverse', _('reverse')) + attribute_format_string = attribute_format_string.replace( + 'fenrirReverse', _('reverse')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirReverse', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirReverse', '') # 7 blink (True/ False) try: if attribute[7]: - attributeFormatString = attributeFormatString.replace('fenrirBlink', _('blink')) + attribute_format_string = attribute_format_string.replace( + 'fenrirBlink', _('blink')) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirBlink', '') + attribute_format_string = attribute_format_string.replace( + 'fenrirBlink', '') # 8 font size (int/ string) try: try: - attributeFormatString = attributeFormatString.replace('fenrirFontSize', int(attribute[8])) + attribute_format_string = attribute_format_string.replace( + 'fenrirFontSize', int(attribute[8])) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('attributeManager formatAttributeToString: Error formatting font size as int: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'AttributeManager formatAttributeToString: Error formatting font size as int: ' + + str(e), + debug.DebugLevel.ERROR) try: - attributeFormatString = attributeFormatString.replace('fenrirFontSize', str(attribute[8])) + attribute_format_string = attribute_format_string.replace( + 'fenrirFontSize', str(attribute[8])) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('attributeManager formatAttributeToString: Error formatting font size as string: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'AttributeManager formatAttributeToString: Error formatting font size as string: ' + + str(e), + debug.DebugLevel.ERROR) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirFontSize', _('default')) + attribute_format_string = attribute_format_string.replace( + 'fenrirFontSize', _('default')) # 9 font family (string) try: - attributeFormatString = attributeFormatString.replace('fenrirFont', attribute[9]) + attribute_format_string = attribute_format_string.replace( + 'fenrirFont', attribute[9]) except Exception as e: pass - attributeFormatString = attributeFormatString.replace('fenrirFont', _('default')) + attribute_format_string = attribute_format_string.replace( + 'fenrirFont', _('default')) - return attributeFormatString - def trackHighlights(self): + return attribute_format_string + + def track_highlights(self): """ Detects text with changed attributes (highlighting) between screen updates. - + This is crucial for screen readers to announce when text becomes highlighted, selected, or changes visual emphasis (bold, reverse video, color changes, etc.) - + Returns: tuple: (highlighted_text, cursor_position) - highlighted_text: string of characters that gained highlighting - cursor_position: dict {'x': col, 'y': row} of first highlighted char """ result = '' - currCursor = None - + curr_cursor = None + # Early exit conditions - no attribute comparison possible - if self.prevAttributes == None: + if self.prevAttributes is None: # First screen load - no previous attributes to compare against - return result, currCursor + return result, curr_cursor if self.prevAttributes == self.currAttributes: # No attribute changes detected - return result, currCursor - if self.currAttributes == None: + return result, curr_cursor + if self.currAttributes is None: # Error condition - current attributes missing - return result, currCursor + return result, curr_cursor if len(self.currAttributes) == 0: # Special case for PTY environments with no text content - return result, currCursor - + return result, curr_cursor + # Get current screen text to correlate with attribute changes - text = self.env['runtime']['screenManager'].getScreenText() - textLines = text.split('\n') + text = self.env['runtime']['ScreenManager'].get_screen_text() + text_lines = text.split('\n') # Sanity check: text lines must match attribute array dimensions - if len(textLines) != len(self.currAttributes): - return result, currCursor - + if len(text_lines) != len(self.currAttributes): + return result, curr_cursor + # Compare attributes line by line, character by character for line in range(len(self.prevAttributes)): if self.prevAttributes[line] != self.currAttributes[line]: - # This line has attribute changes - examine each character position + # This line has attribute changes - examine each character + # position for column in range(len(self.prevAttributes[line])): if self.prevAttributes[line][column] == self.currAttributes[line][column]: # No change at this position continue - # Attribute changed at this position - check if it's worth announcing - if self.isUsefulForTracking(line, column, self.currAttributes, self.prevAttributes): - # First highlighted character becomes cursor position for navigation - if not currCursor: - currCursor = {'x': column, 'y': line} + # Attribute changed at this position - check if it's worth + # announcing + if self.is_useful_for_tracking( + line, column, self.currAttributes, self.prevAttributes): + # First highlighted character becomes cursor position + # for navigation + if not curr_cursor: + curr_cursor = {'x': column, 'y': line} # Accumulate highlighted characters - result += textLines[line][column] - # Add space between lines of highlighted text for speech clarity + result += text_lines[line][column] + # Add space between lines of highlighted text for speech + # clarity result += ' ' - return result, currCursor - def isUsefulForTracking(self, line, column, currAttributes, prevAttributes, attribute=1 , mode = 'zaxe'): + return result, curr_cursor + + def is_useful_for_tracking( + self, + line, + column, + currAttributes, + prevAttributes, + attribute=1, + mode='zaxe'): """ Determines if an attribute change at a specific position is worth announcing. - + This prevents announcing every minor attribute change and focuses on meaningful highlighting that indicates user selections, focus changes, or important emphasis. - + Args: line, column: Position of the attribute change currAttributes, prevAttributes: Current and previous attribute arrays attribute: Which attribute to examine (1=background color by default) mode: Detection algorithm ('zaxe', 'default', 'barrier') - + Returns: bool: True if this attribute change should be announced to user """ @@ -307,37 +372,37 @@ class attributeManager(): if len(currAttributes) <= 3: return False if line < 0: - return False + return False if line > len(currAttributes): return False - + useful = False - + if mode == 'default': # Simple mode: announce any non-default attribute - useful = not self.isDefaultAttribute(currAttributes[line][column]) - + useful = not self.is_default_attribute(currAttributes[line][column]) + elif (mode == 'zaxe') or (mode == ''): # Context-aware mode: only announce attributes that stand out from surroundings # This prevents announcing entire blocks of highlighted text character by character # by checking if the attribute differs from adjacent lines - + if line == 0: # Top line: compare against lines below - useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and \ - (currAttributes[line][column][attribute] != currAttributes[line + 2][column][attribute]) + useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and ( + currAttributes[line][column][attribute] != currAttributes[line + 2][column][attribute]) elif line >= len(prevAttributes): - # Bottom line: compare against lines above - useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and \ - (currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute]) + # Bottom line: compare against lines above + useful = (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) and ( + currAttributes[line][column][attribute] != currAttributes[line - 2][column][attribute]) else: # Middle lines: compare against both directions - useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and \ - (currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) - + useful = (currAttributes[line][column][attribute] != currAttributes[line + 1][column][attribute]) and ( + currAttributes[line][column][attribute] != currAttributes[line - 1][column][attribute]) + elif mode == 'barrier': - # Barrier mode: future enhancement for detecting screen boundaries/separators + # Barrier mode: future enhancement for detecting screen + # boundaries/separators useful = True return useful - diff --git a/src/fenrirscreenreader/core/barrierManager.py b/src/fenrirscreenreader/core/barrierManager.py index 6e8b4585..097789ca 100644 --- a/src/fenrirscreenreader/core/barrierManager.py +++ b/src/fenrirscreenreader/core/barrierManager.py @@ -5,75 +5,92 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -import re, string +import re +import string -class barrierManager(): + +class BarrierManager(): def __init__(self): self.currIsBarrier = False self.prefIsBarrier = False - def initialize(self, environment): - self.env = environment - def shutdown(self): - pass - def updateBarrierChange(self, isBarrier): - self.prefIsBarrier = self.currIsBarrier - self.currIsBarrier = isBarrier - def resetBarrierChange(self): + def initialize(self, environment): + self.env = environment + + def shutdown(self): + pass + + def update_barrier_change(self, is_barrier): + self.prefIsBarrier = self.currIsBarrier + self.currIsBarrier = is_barrier + + def reset_barrier_change(self): self.currIsBarrier = False self.prefIsBarrier = False - def isBarrierChange(self): + + def is_barrier_change(self): return self.currIsBarrier != self.prefIsBarrier - def handleLineBarrier(self, text, xCursor, yCursor, output=True, doInterrupt=True): - isBarrier = False + + def handle_line_barrier( + self, + text, + xCursor, + yCursor, + output=True, + do_interrupt=True): + is_barrier = False try: - isBarrier, sayLine = self.getBarrierText(text, xCursor, yCursor) + is_barrier, say_line = self.get_barrier_text(text, xCursor, yCursor) except Exception as e: return False, '' - self.updateBarrierChange(isBarrier) - if self.isBarrierChange(): - if output: - if isBarrier: - self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierStart', interrupt=doInterrupt) + self.update_barrier_change(is_barrier) + if self.is_barrier_change(): + if output: + if is_barrier: + self.env['runtime']['OutputManager'].play_sound_icon( + sound_icon ='BarrierStart', interrupt=do_interrupt) else: - self.env['runtime']['outputManager'].playSoundIcon(soundIcon='BarrierEnd', interrupt=doInterrupt) + self.env['runtime']['OutputManager'].play_sound_icon( + sound_icon ='BarrierEnd', interrupt=do_interrupt) - if not isBarrier: - sayLine = '' - return isBarrier, sayLine + if not is_barrier: + say_line = '' + return is_barrier, say_line - def getBarrierText(self, text, xCursor, yCursor): + def get_barrier_text(self, text, xCursor, yCursor): line = text[yCursor] - if not self.env['runtime']['settingsManager'].getSettingAsBool('barrier', 'enabled'): - return False, line - offset = xCursor + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'barrier', 'enabled'): + return False, line + offset = xCursor - leftBarriers = self.env['runtime']['settingsManager'].getSetting('barrier', 'leftBarriers') - rightBarriers = self.env['runtime']['settingsManager'].getSetting('barrier', 'rightBarriers') - # is the cursor at the begin or end of an entry: - #print(line[:offset + 1].count('│'),line[offset:].count('│')) + left_barriers = self.env['runtime']['SettingsManager'].get_setting( + 'barrier', 'left_barriers') + right_barriers = self.env['runtime']['SettingsManager'].get_setting( + 'barrier', 'right_barriers') + # is the cursor at the begin or end of an entry: + # print(line[:offset + 1].count('│'),line[offset:].count('│')) # start - for b in leftBarriers: + for b in left_barriers: if line[:offset + 1].count(b) > line[offset:].count(b): offset = xCursor - 1 start = line[:offset].rfind(b) if start != -1: - start += 1 + start += 1 break if start == -1: - return False, line + return False, line # end - for b in rightBarriers: + for b in right_barriers: end = line[start:].find(b) if end != -1: - end = start + end + end = start + end break if end == -1: - return False, line + return False, line if start == end: return False, line return True, line[start:end] - diff --git a/src/fenrirscreenreader/core/byteManager.py b/src/fenrirscreenreader/core/byteManager.py index 9d91158f..abca3768 100644 --- a/src/fenrirscreenreader/core/byteManager.py +++ b/src/fenrirscreenreader/core/byteManager.py @@ -5,149 +5,189 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType -import os, inspect, re, time -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) +from fenrirscreenreader.core.i18n import _ +from fenrirscreenreader.core.eventData import FenrirEventType +import os +import inspect +import re +import time +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) -class byteManager(): + +class ByteManager(): def __init__(self): - self.switchCtrlModeOnce = 0 + self.switchCtrlModeOnce = 0 self.controlMode = True self.repeat = 1 self.lastInputTime = time.time() self.lastByteKey = b'' + def initialize(self, environment): - self.env = environment + self.env = environment + def shutdown(self): pass - def unifyEscapeSeq(self, escapeSequence): - convertedEscapeSequence = escapeSequence - if convertedEscapeSequence[0] == 27: - convertedEscapeSequence = b'^[' + convertedEscapeSequence[1:] - if len(convertedEscapeSequence) > 1: - if convertedEscapeSequence[0] == 94 and convertedEscapeSequence[1] ==91: - convertedEscapeSequence = b'^[' + convertedEscapeSequence[2:] - return convertedEscapeSequence - def handleByteStream(self, eventData, sep = b'\x1b'): - buffer = eventData + + def unify_escape_seq(self, escapeSequence): + converted_escape_sequence = escapeSequence + if converted_escape_sequence[0] == 27: + converted_escape_sequence = b'^[' + converted_escape_sequence[1:] + if len(converted_escape_sequence) > 1: + if converted_escape_sequence[0] == 94 and converted_escape_sequence[1] == 91: + converted_escape_sequence = b'^[' + converted_escape_sequence[2:] + return converted_escape_sequence + + def handle_byte_stream(self, event_data, sep=b'\x1b'): + buffer = event_data # handle prefix - endIndex = buffer.find(sep) - if endIndex > 0: - currSequence = buffer[:endIndex] - buffer = buffer[endIndex:] - self.handleSingleByteSequence(currSequence) + end_index = buffer.find(sep) + if end_index > 0: + curr_sequence = buffer[:end_index] + buffer = buffer[end_index:] + self.handle_single_byte_sequence(curr_sequence) # special handlig for none found (performance) - elif endIndex == -1: - self.handleSingleByteSequence(buffer) + elif end_index == -1: + self.handle_single_byte_sequence(buffer) return # handle outstanding sequence while buffer != b'': - endIndex = buffer[len(sep):].find(sep) - if endIndex == -1: - currSequence = buffer + end_index = buffer[len(sep):].find(sep) + if end_index == -1: + curr_sequence = buffer buffer = b'' else: - currSequence = buffer[:endIndex + len(sep)] - buffer = buffer[endIndex + len(sep):] - self.handleSingleByteSequence(currSequence) - def handleByteInput(self, eventData): - if not eventData: + curr_sequence = buffer[:end_index + len(sep)] + buffer = buffer[end_index + len(sep):] + self.handle_single_byte_sequence(curr_sequence) + + def handle_byte_input(self, event_data): + if not event_data: return - if eventData == b'': + if event_data == b'': return try: - self.env['runtime']['debug'].writeDebugOut("handleByteInput " + eventData.decode('utf8') ,debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "handle_byte_input " + event_data.decode('utf8'), debug.DebugLevel.INFO) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('byteManager handleByteInput: Error decoding byte data: ' + str(e), debug.debugLevel.ERROR) - self.handleByteStream(eventData) - def handleSingleByteSequence(self, eventData): - convertedEscapeSequence = self.unifyEscapeSeq(eventData) + self.env['runtime']['DebugManager'].write_debug_out( + 'ByteManager handle_byte_input: Error decoding byte data: ' + str(e), + debug.DebugLevel.ERROR) + self.handle_byte_stream(event_data) + + def handle_single_byte_sequence(self, event_data): + converted_escape_sequence = self.unify_escape_seq(event_data) if self.switchCtrlModeOnce > 0: self.switchCtrlModeOnce -= 1 - isControlMode = False + is_control_mode = False if self.controlMode and not self.switchCtrlModeOnce == 1 or\ - not self.controlMode: - isControlMode = self.handleControlMode(eventData) + not self.controlMode: + is_control_mode = self.handle_control_mode(event_data) - isCommand = False + is_command = False if self.controlMode and not self.switchCtrlModeOnce == 1 or\ - not self.controlMode and self.switchCtrlModeOnce == 1: - if self.lastByteKey == convertedEscapeSequence: - if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): + not self.controlMode and self.switchCtrlModeOnce == 1: + if self.lastByteKey == converted_escape_sequence: + if time.time() - self.lastInputTime <= self.env['runtime']['SettingsManager'].get_setting_as_float( + 'keyboard', 'doubleTapTimeout'): self.repeat += 1 - shortcutData = b'' + shortcut_data = b'' for i in range(self.repeat): - shortcutData = shortcutData + convertedEscapeSequence - isCommand = self.detectByteCommand(shortcutData) + shortcut_data = shortcut_data + converted_escape_sequence + is_command = self.detect_byte_command(shortcut_data) # fall back to single stroke - do we want this? - if not isCommand: - isCommand = self.detectByteCommand(convertedEscapeSequence) + if not is_command: + is_command = self.detect_byte_command(converted_escape_sequence) self.repeat = 1 - if not (isCommand or isControlMode): - self.env['runtime']['screenManager'].injectTextToScreen(eventData) - if not isCommand: + if not (is_command or is_control_mode): + self.env['runtime']['ScreenManager'].inject_text_to_screen(event_data) + if not is_command: self.repeat = 1 - self.lastByteKey = convertedEscapeSequence + self.lastByteKey = converted_escape_sequence self.lastInputTime = time.time() - def getLastByteKey(self): + + def get_last_byte_key(self): return self.lastByteKey - def handleControlMode(self, escapeSequence): - convertedEscapeSequence = self.unifyEscapeSeq(escapeSequence) - if convertedEscapeSequence == b'^[R': + + def handle_control_mode(self, escapeSequence): + converted_escape_sequence = self.unify_escape_seq(escapeSequence) + if converted_escape_sequence == b'^[R': self.controlMode = not self.controlMode self.switchCtrlModeOnce = 0 if self.controlMode: - self.env['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Accept', interrupt=True, flush=True) + self.env['runtime']['OutputManager'].present_text( + _('Sticky Mode On'), sound_icon ='Accept', interrupt=True, flush=True) else: - self.env['runtime']['outputManager'].presentText(_('Sticky Mode On'), soundIcon='Cancel', interrupt=True, flush=True) - return True - if convertedEscapeSequence == b'^[:': - self.switchCtrlModeOnce = 2 - self.env['runtime']['outputManager'].presentText(_('bypass'), soundIcon='PTYBypass', interrupt=True, flush=True) + self.env['runtime']['OutputManager'].present_text( + _('Sticky Mode On'), sound_icon ='Cancel', interrupt=True, flush=True) return True - return False - def sendBytes(self, byteMacro): + if converted_escape_sequence == b'^[:': + self.switchCtrlModeOnce = 2 + self.env['runtime']['OutputManager'].present_text( + _('bypass'), sound_icon ='PTYBypass', interrupt=True, flush=True) + return True + return False + + def send_bytes(self, byteMacro): pass - def detectByteCommand(self, escapeSequence): - convertedEscapeSequence = self.unifyEscapeSeq(escapeSequence) - command = self.env['runtime']['inputManager'].getCommandForShortcut(convertedEscapeSequence) - if command != '': - self.env['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, command) + + def detect_byte_command(self, escapeSequence): + converted_escape_sequence = self.unify_escape_seq(escapeSequence) + command = self.env['runtime']['InputManager'].get_command_for_shortcut( + converted_escape_sequence) + if command != '': + self.env['runtime']['EventManager'].put_to_event_queue( + FenrirEventType.execute_command, command) command = '' return True - return False - def loadByteShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/pty.conf'): - kbConfig = open(kbConfigPath,"r") - while(True): - line = kbConfig.readline() + return False + + def load_byte_shortcuts( + self, + kb_config_path=fenrir_path + + '/../../config/keyboard/pty.conf'): + kb_config = open(kb_config_path, "r") + while (True): + line = kb_config.readline() if not line: break - line = line.replace('\n','') - if line.replace(" ","") == '': - continue - if line.replace(" ","").startswith("#"): + line = line.replace('\n', '') + if line.replace(" ", "") == '': + continue + if line.replace(" ", "").startswith("#"): continue if line.count("=") != 1: continue - Values = line.split('=') - cleanShortcut = bytes(Values[0],'UTF-8') + values = line.split('=') + clean_shortcut = bytes(values[0], 'UTF-8') repeat = 1 - if len(cleanShortcut) > 2: - if chr(cleanShortcut[1]) == ',': + if len(clean_shortcut) > 2: + if chr(clean_shortcut[1]) == ',': try: - repeat = int(chr(cleanShortcut[0])) - cleanShortcut = cleanShortcut[2:] + repeat = int(chr(clean_shortcut[0])) + clean_shortcut = clean_shortcut[2:] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('byteManager loadByteShortcuts: Error parsing repeat count: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'ByteManager load_byte_shortcuts: Error parsing repeat count: ' + str(e), + debug.DebugLevel.ERROR) repeat = 1 - cleanShortcut = cleanShortcut - shortcut = b'' + clean_shortcut = clean_shortcut + shortcut = b'' for i in range(repeat): - shortcut += cleanShortcut - commandName = Values[1].upper() - self.env['bindings'][shortcut] = commandName - self.env['runtime']['debug'].writeDebugOut("Byte Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True) - kbConfig.close() + shortcut += clean_shortcut + command_name = values[1].upper() + self.env['bindings'][shortcut] = command_name + self.env['runtime']['DebugManager'].write_debug_out( + "Byte Shortcut: " + + str(shortcut) + + ' command:' + + command_name, + debug.DebugLevel.INFO, + on_any_level=True) + kb_config.close() diff --git a/src/fenrirscreenreader/core/commandData.py b/src/fenrirscreenreader/core/commandData.py index 65ec426a..619a9afd 100644 --- a/src/fenrirscreenreader/core/commandData.py +++ b/src/fenrirscreenreader/core/commandData.py @@ -9,16 +9,16 @@ import time # used as shared memory between commands # use this in your own commands -commandBuffer = { -'enableSpeechOnKeypress': False, -'Marks':{'1':None, '2':None}, -'bookMarks':{}, -'windowArea':{}, +command_buffer = { + 'enableSpeechOnKeypress': False, + 'Marks': {'1': None, '2': None}, + 'bookMarks': {}, + 'windowArea': {}, } -# used by the commandManager -commandInfo = { -#'currCommand': '', -'lastCommandExecutionTime': time.time(), -'lastCommandRequestTime': time.time(), +# used by the command_manager +command_info = { + # 'curr_command': '', + 'lastCommandExecutionTime': time.time(), + 'lastCommandRequestTime': time.time(), } diff --git a/src/fenrirscreenreader/core/commandManager.py b/src/fenrirscreenreader/core/commandManager.py index c23af755..6716339e 100644 --- a/src/fenrirscreenreader/core/commandManager.py +++ b/src/fenrirscreenreader/core/commandManager.py @@ -4,167 +4,222 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -import glob, os, time, inspect -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) - -from fenrirscreenreader.core import debug from fenrirscreenreader.utils import module_utils +from fenrirscreenreader.core import debug +import glob +import os +import time +import inspect +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) -class commandManager(): + +class CommandManager(): def __init__(self): pass + def initialize(self, environment): self.env = environment # commands self.env['commands'] = {} - self.env['commandsIgnore'] = {} - for commandFolder in self.env['general']['commandFolderList']: - self.env['runtime']['commandManager'].loadCommands(commandFolder) - if self.env['runtime']['settingsManager'].getSetting('general', 'commandPath') != '': - self.env['runtime']['commandManager'].loadCommands(commandFolder, - self.env['runtime']['settingsManager'].getSetting('general', 'commandPath')) + self.env['commandsIgnore'] = {} + for command_folder in self.env['general']['commandFolderList']: + self.env['runtime']['CommandManager'].load_commands(command_folder) + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'command_path') != '': + self.env['runtime']['CommandManager'].load_commands( + command_folder, self.env['runtime']['SettingsManager'].get_setting( + 'general', 'command_path')) # scripts for scriptKey - self.env['runtime']['commandManager'].loadScriptCommands() + self.env['runtime']['CommandManager'].load_script_commands() def shutdown(self): - for commandFolder in self.env['general']['commandFolderList']: - self.env['runtime']['commandManager'].shutdownCommands(commandFolder) + for command_folder in self.env['general']['commandFolderList']: + self.env['runtime']['CommandManager'].shutdown_commands( + command_folder) - def loadFile(self, filepath = ''): + def load_file(self, filepath=''): if filepath == '': return None if not os.path.exists(filepath): - self.env['runtime']['debug'].writeDebugOut("loadFile: filepath not exists:" + filepath ,debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + "load_file: filepath not exists:" + filepath, debug.DebugLevel.WARNING) return None if os.path.isdir(filepath): - self.env['runtime']['debug'].writeDebugOut("loadFile: filepath is a directory:" + filepath ,debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "load_file: filepath is a directory:" + filepath, debug.DebugLevel.ERROR) return None if not os.access(filepath, os.R_OK): - self.env['runtime']['debug'].writeDebugOut("loadFile: filepath not readable:" + filepath ,debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "load_file: filepath not readable:" + filepath, debug.DebugLevel.ERROR) return None try: - fileName, fileExtension = os.path.splitext(filepath) - fileName = fileName.split('/')[-1] - if fileName.startswith('__'): + file_name, file_extension = os.path.splitext(filepath) + file_name = file_name.split('/')[-1] + if file_name.startswith('__'): return None - if fileExtension.lower() == '.py': - command_mod = module_utils.importModule(fileName, filepath) + if file_extension.lower() == '.py': + command_mod = module_utils.import_module(file_name, filepath) command = command_mod.command() command.initialize(self.env) - self.env['runtime']['debug'].writeDebugOut("loadFile: Load command:" + filepath ,debug.debugLevel.INFO, onAnyLevel=True) + self.env['runtime']['DebugManager'].write_debug_out( + "load_file: Load command:" + filepath, debug.DebugLevel.INFO, on_any_level=True) return command except Exception as e: - self.env['runtime']['debug'].writeDebugOut("loadFile: Loading command:" + filepath ,debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "load_file: Loading command:" + filepath, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) return None - def loadCommands(self, section='commands',commandPath=''): - if commandPath =='': - commandPath = fenrirPath+ "/commands/" - if not commandPath.endswith('/'): - commandPath += '/' - commandFolder = commandPath + section +"/" - if not os.path.exists(commandFolder): - self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING) - return - if not os.path.isdir(commandFolder): - self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR) + + def load_commands(self, section='commands', command_path=''): + if command_path == '': + command_path = fenrir_path + "/commands/" + if not command_path.endswith('/'): + command_path += '/' + command_folder = command_path + section + "/" + if not os.path.exists(command_folder): + self.env['runtime']['DebugManager'].write_debug_out( + "load_commands: command_folder not exists:" + command_folder, + debug.DebugLevel.WARNING) return - if not os.access(commandFolder, os.R_OK): - self.env['runtime']['debug'].writeDebugOut("loadCommands: commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR) + if not os.path.isdir(command_folder): + self.env['runtime']['DebugManager'].write_debug_out( + "load_commands: command_folder not a directory:" + + command_folder, + debug.DebugLevel.ERROR) + return + if not os.access(command_folder, os.R_OK): + self.env['runtime']['DebugManager'].write_debug_out( + "load_commands: command_folder not readable:" + command_folder, + debug.DebugLevel.ERROR) return self.env['commands'][section] = {} self.env['commandsIgnore'][section] = {} - commandList = glob.glob(commandFolder+'*') - for command in commandList: + command_list = glob.glob(command_folder + '*') + for command in command_list: try: - fileName, fileExtension = os.path.splitext(command) - fileName = fileName.split('/')[-1] - if fileName.startswith('__'): + file_name, file_extension = os.path.splitext(command) + file_name = file_name.split('/')[-1] + if file_name.startswith('__'): continue # Skip base classes that shouldn't be loaded as commands - if fileName.endswith('_base'): + if file_name.endswith('_base'): continue # Check if command already exists to prevent duplicate loading - if fileName.upper() in self.env['commands'][section] and self.env['commands'][section][fileName.upper()] is not None: + if file_name.upper( + ) in self.env['commands'][section] and self.env['commands'][section][file_name.upper()] is not None: continue - if fileExtension.lower() == '.py': - command_mod = module_utils.importModule(fileName, command) - self.env['commands'][section][fileName.upper()] = command_mod.command() - self.env['commandsIgnore'][section][fileName.upper()[fileName.upper().find('-')+1:]+'_IGNORE'] = False - self.env['commands'][section][fileName.upper()].initialize(self.env) - self.env['runtime']['debug'].writeDebugOut("loadCommands: Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True) + if file_extension.lower() == '.py': + command_mod = module_utils.import_module(file_name, command) + self.env['commands'][section][file_name.upper() + ] = command_mod.command() + self.env['commandsIgnore'][section][file_name.upper( + )[file_name.upper().find('-') + 1:] + '_IGNORE'] = False + self.env['commands'][section][file_name.upper() + ].initialize(self.env) + self.env['runtime']['DebugManager'].write_debug_out( + "load_commands: Load command:" + + section + + "." + + file_name.upper(), + debug.DebugLevel.INFO, + on_any_level=True) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("loadCommands: Loading command:" + command ,debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "load_commands: Loading command:" + command, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) continue - def loadScriptCommands(self, section='commands', scriptPath=''): - if scriptPath =='': - scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath') - if not scriptPath.endswith('/'): - scriptPath += '/' - if not os.path.exists(scriptPath): - if os.path.exists(fenrirPath +'/../../config/scripts/'): - scriptPath = fenrirPath +'/../../config/scripts/' + def load_script_commands(self, section='commands', script_path=''): + if script_path == '': + script_path = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'script_path') + if not script_path.endswith('/'): + script_path += '/' + if not os.path.exists(script_path): + if os.path.exists(fenrir_path + '/../../config/scripts/'): + script_path = fenrir_path + '/../../config/scripts/' else: - self.env['runtime']['debug'].writeDebugOut("scriptpath not exists:" + scriptPath ,debug.debugLevel.WARNING) - return - if not os.path.isdir(scriptPath): - self.env['runtime']['debug'].writeDebugOut("scriptpath not a directory:" + scriptPath ,debug.debugLevel.ERROR) - return - if not os.access(scriptPath, os.R_OK): - self.env['runtime']['debug'].writeDebugOut("scriptpath not readable:" + scriptPath ,debug.debugLevel.ERROR) - return - commandList = glob.glob(scriptPath+'*') - subCommand = fenrirPath + '/commands/commands/subprocess.py' - for command in commandList: + self.env['runtime']['DebugManager'].write_debug_out( + "scriptpath not exists:" + script_path, debug.DebugLevel.WARNING) + return + if not os.path.isdir(script_path): + self.env['runtime']['DebugManager'].write_debug_out( + "scriptpath not a directory:" + script_path, debug.DebugLevel.ERROR) + return + if not os.access(script_path, os.R_OK): + self.env['runtime']['DebugManager'].write_debug_out( + "scriptpath not readable:" + script_path, debug.DebugLevel.ERROR) + return + command_list = glob.glob(script_path + '*') + sub_command = fenrir_path + '/commands/commands/subprocess.py' + for command in command_list: invalid = False try: - fileName, fileExtension = os.path.splitext(command) - fileName = fileName.split('/')[-1] - if fileName.startswith('__'): + file_name, file_extension = os.path.splitext(command) + file_name = file_name.split('/')[-1] + if file_name.startswith('__'): continue - if fileName.upper() in self.env['commands'][section]: + if file_name.upper() in self.env['commands'][section]: continue - command_mod = module_utils.importModule(fileName ,subCommand) - self.env['commands'][section][fileName.upper()] = command_mod.command() - self.env['commands'][section][fileName.upper()].initialize(self.env,command) - self.env['runtime']['debug'].writeDebugOut("Load script:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True) - commSettings = fileName.upper().split('__-__') - if len(commSettings) == 1: - keys = commSettings[0] - elif len(commSettings) == 2: - keys = commSettings[1] - elif len(commSettings) > 2: + command_mod = module_utils.import_module(file_name, sub_command) + self.env['commands'][section][file_name.upper() + ] = command_mod.command() + self.env['commands'][section][file_name.upper()].initialize( + self.env, command) + self.env['runtime']['DebugManager'].write_debug_out( + "Load script:" + + section + + "." + + file_name.upper(), + debug.DebugLevel.INFO, + on_any_level=True) + comm_settings = file_name.upper().split('__-__') + if len(comm_settings) == 1: + keys = comm_settings[0] + elif len(comm_settings) == 2: + keys = comm_settings[1] + elif len(comm_settings) > 2: continue keys = keys.split('__+__') - shortcutKeys = [] + shortcut_keys = [] shortcut = [] for key in keys: - if not self.env['runtime']['inputManager'].isValidKey(key.upper()): - self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' script:' + fileName ,debug.debugLevel.WARNING) + if not self.env['runtime']['InputManager'].is_valid_key( + key.upper()): + self.env['runtime']['DebugManager'].write_debug_out( + "invalid key : " + key.upper() + ' script:' + file_name, debug.DebugLevel.WARNING) invalid = True break - shortcutKeys.append(key.upper()) + shortcut_keys.append(key.upper()) if invalid: continue - if not 'KEY_SCRIPT' in shortcutKeys: - shortcutKeys.append('KEY_SCRIPT') + if 'KEY_SCRIPT' not in shortcut_keys: + shortcut_keys.append('KEY_SCRIPT') shortcut.append(1) - shortcut.append(sorted(shortcutKeys)) - self.env['bindings'][str(shortcut)] = fileName.upper() + shortcut.append(sorted(shortcut_keys)) + self.env['bindings'][str(shortcut)] = file_name.upper() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Loading script:" + fileName ,debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Loading script:" + file_name, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) continue - def shutdownCommands(self, section): + def shutdown_commands(self, section): # Check if the section exists in the commands dictionary if section not in self.env['commands']: - self.env['runtime']['debug'].writeDebugOut("shutdownCommands: section not found:" + section, debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + "shutdown_commands: section not found:" + section, + debug.DebugLevel.WARNING) return for command in sorted(self.env['commands'][section]): @@ -172,117 +227,150 @@ class commandManager(): self.env['commands'][section][command].shutdown() del self.env['commands'][section][command] except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Shutdown command:" + section + "." + command, debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Shutdown command:" + section + "." + command, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) continue - def executeSwitchTrigger(self, trigger, unLoadScript, loadScript): - if self.env['runtime']['screenManager'].isIgnoredScreen(): + def execute_switch_trigger(self, trigger, unLoadScript, loadScript): + if self.env['runtime']['ScreenManager'].is_ignored_screen(): return - #unload - oldScript = unLoadScript - if self.commandExists(oldScript, trigger): + # unload + old_script = unLoadScript + if self.command_exists(old_script, trigger): try: - self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.unload:" + trigger + "." + oldScript ,debug.debugLevel.INFO) - self.env['commands'][trigger][oldScript].unload() + self.env['runtime']['DebugManager'].write_debug_out( + "Executing switchtrigger.unload:" + trigger + "." + old_script, + debug.DebugLevel.INFO) + self.env['commands'][trigger][old_script].unload() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + oldScript ,debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) - #load - newScript = loadScript - if self.commandExists(newScript, trigger): + self.env['runtime']['DebugManager'].write_debug_out( + "Executing trigger:" + trigger + "." + old_script, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) + # load + new_script = loadScript + if self.command_exists(new_script, trigger): try: - self.env['runtime']['debug'].writeDebugOut("Executing switchtrigger.load:" + trigger + "." + newScript ,debug.debugLevel.INFO) - self.env['commands'][trigger][newScript].load() + self.env['runtime']['DebugManager'].write_debug_out( + "Executing switchtrigger.load:" + trigger + "." + new_script, + debug.DebugLevel.INFO) + self.env['commands'][trigger][new_script].load() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + newScript ,debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Executing trigger:" + trigger + "." + new_script, debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) - def executeDefaultTrigger(self, trigger, force=False): + def execute_default_trigger(self, trigger, force=False): if not force: - if self.env['runtime']['screenManager'].isIgnoredScreen(): + if self.env['runtime']['ScreenManager'].is_ignored_screen(): return for command in sorted(self.env['commands'][trigger]): - if self.commandExists(command, trigger): + if self.command_exists(command, trigger): try: - if self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE']: - self.env['commandsIgnore'][trigger][command[command.find('-')+1:]+'_IGNORE'] = False - self.env['runtime']['debug'].writeDebugOut("Ignore trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO) + if self.env['commandsIgnore'][trigger][command[command.find( + '-') + 1:] + '_IGNORE']: + self.env['commandsIgnore'][trigger][command[command.find( + '-') + 1:] + '_IGNORE'] = False + self.env['runtime']['DebugManager'].write_debug_out( + "ignore trigger.command:" + trigger + "." + command, debug.DebugLevel.INFO) else: - self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "Executing trigger.command:" + trigger + "." + command, debug.DebugLevel.INFO) self.env['commands'][trigger][command].run() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command + str(e) ,debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Executing trigger:" + trigger + "." + command + str(e), debug.DebugLevel.ERROR) - def executeCommand(self, command, section = 'commands'): - if self.env['runtime']['screenManager'].isIgnoredScreen(): - return - if self.commandExists(command, section): + def execute_command(self, command, section='commands'): + if self.env['runtime']['ScreenManager'].is_ignored_screen(): + return + if self.command_exists(command, section): try: - if self.env['runtime']['helpManager'].isTutorialMode() and section != 'help': - self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO) - description = self.getCommandDescription(command, section) - self.env['runtime']['outputManager'].presentText(description, interrupt=False) + if self.env['runtime']['HelpManager'].is_tutorial_mode( + ) and section != 'help': + self.env['runtime']['DebugManager'].write_debug_out( + "Tutorial for command:" + section + "." + command, debug.DebugLevel.INFO) + description = self.get_command_description(command, section) + self.env['runtime']['OutputManager'].present_text( + description, interrupt=False) else: - self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO) - self.runCommand(command, section) + self.env['runtime']['DebugManager'].write_debug_out( + "Executing command:" + section + "." + command, debug.DebugLevel.INFO) + self.run_command(command, section) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Executing command:" + section + "." + command + ' ' + str(e), + debug.DebugLevel.ERROR) - - def runCommand(self, command, section = 'commands'): - if self.commandExists(command, section): + def run_command(self, command, section='commands'): + if self.command_exists(command, section): try: - self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command ,debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "run_command command:" + section + "." + command, debug.DebugLevel.INFO) self.env['commands'][section][command].run() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR) - self.env['commandInfo']['lastCommandExecutionTime'] = time.time() + self.env['runtime']['DebugManager'].write_debug_out( + "run_command command:" + section + "." + command + ' ' + str(e), + debug.DebugLevel.ERROR) + self.env['commandInfo']['lastCommandExecutionTime'] = time.time() - def getCommandDescription(self, command, section = 'commands'): - if self.commandExists(command, section): + def get_command_description(self, command, section='commands'): + if self.command_exists(command, section): try: - return self.env['commands'][section][command].getDescription() + return self.env['commands'][section][command].get_description() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR) - self.env['commandInfo']['lastCommandExecutionTime'] = time.time() + self.env['runtime']['DebugManager'].write_debug_out( + 'command_manager.get_command_description:' + str(e), debug.DebugLevel.ERROR) + self.env['commandInfo']['lastCommandExecutionTime'] = time.time() - def commandExists(self, command, section = 'commands'): + def command_exists(self, command, section='commands'): try: - return( command in self.env['commands'][section]) + return (command in self.env['commands'][section]) except Exception as e: return False - def getShortcutForCommand(self, command, formatKeys = False): + + def get_shortcut_for_command(self, command, formatKeys=False): shortcut = [] try: - rawShortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)] + raw_shortcut = list(self.env['bindings'].keys())[ + list(self.env['bindings'].values()).index(command)] # prefer numbers for multitap for k in ['2', '3', '4', '5', '6', '7', '8']: - if k in rawShortcut: - formattedKey = k + if k in raw_shortcut: + formatted_key = k if formatKeys: - formattedKey = formattedKey.lower() - formattedKey += ' times ' - shortcut.append(formattedKey) - rawShortcut.remove(k) + formatted_key = formatted_key.lower() + formatted_key += ' times ' + shortcut.append(formatted_key) + raw_shortcut.remove(k) # prefer metha keys - for k in ['KEY_FENRIR', 'KEY_SCRIPT', 'KEY_CTRL', 'KEY_SHIFT', 'KEY_ALT', 'KEY_META']: - if k in rawShortcut: - formattedKey = k + for k in [ + 'KEY_FENRIR', + 'KEY_SCRIPT', + 'KEY_CTRL', + 'KEY_SHIFT', + 'KEY_ALT', + 'KEY_META']: + if k in raw_shortcut: + formatted_key = k if formatKeys: - formattedKey = formattedKey.lower() - formattedKey = formattedKey.replace('key_kp', ' keypad ') - formattedKey = formattedKey.replace('key_', ' ') - shortcut.append(formattedKey) - rawShortcut.remove(k) + formatted_key = formatted_key.lower() + formatted_key = formatted_key.replace( + 'key_kp', ' keypad ') + formatted_key = formatted_key.replace('key_', ' ') + shortcut.append(formatted_key) + raw_shortcut.remove(k) # handle other keys - for k in rawShortcut: - formattedKey = k + for k in raw_shortcut: + formatted_key = k if formatKeys: - formattedKey = formattedKey.lower() - formattedKey = formattedKey.replace('key_kp', ' keypad ') - formattedKey = formattedKey.replace('key_', ' ') - shortcut.append(formattedKey) + formatted_key = formatted_key.lower() + formatted_key = formatted_key.replace('key_kp', ' keypad ') + formatted_key = formatted_key.replace('key_', ' ') + shortcut.append(formatted_key) except Exception as e: pass - return shortcut + return shortcut diff --git a/src/fenrirscreenreader/core/cursorManager.py b/src/fenrirscreenreader/core/cursorManager.py index 69f10073..fb640a57 100644 --- a/src/fenrirscreenreader/core/cursorManager.py +++ b/src/fenrirscreenreader/core/cursorManager.py @@ -6,12 +6,15 @@ from fenrirscreenreader.core import debug -class cursorManager(): + +class CursorManager(): def __init__(self): pass + def initialize(self, environment): self.env = environment - def shouldProcessNumpadCommands(self): + + def should_process_numpad_commands(self): """ Check if numpad commands should be processed based on numlock state Return True if numlock is OFF (commands should work) @@ -19,83 +22,99 @@ class cursorManager(): """ # Return False if numlock is ON return not self.env['input']['newNumLock'] + def shutdown(self): pass - def clearMarks(self): + + def clear_marks(self): self.env['commandBuffer']['Marks']['1'] = None self.env['commandBuffer']['Marks']['2'] = None - def isMarkSet(self): - return self.env['commandBuffer']['Marks']['1'] != None - def isSingleMark(self): - return self.env['commandBuffer']['Marks']['1'] != None and \ - self.env['commandBuffer']['Marks']['2'] == None - def isMultibleMark(self): - return self.env['commandBuffer']['Marks']['1'] != None and \ - self.env['commandBuffer']['Marks']['2'] != None - def setMark(self): - currCursor = None + + def is_mark_set(self): + return self.env['commandBuffer']['Marks']['1'] is not None + + def is_single_mark(self): + return self.env['commandBuffer']['Marks']['1'] is not None and \ + self.env['commandBuffer']['Marks']['2'] is None + + def is_multible_mark(self): + return self.env['commandBuffer']['Marks']['1'] is not None and \ + self.env['commandBuffer']['Marks']['2'] is not None + + def set_mark(self): + curr_cursor = None if self.env['screen']['newCursorReview']: - currCursor = self.env['screen']['newCursorReview'].copy() + curr_cursor = self.env['screen']['newCursorReview'].copy() else: - currCursor = self.env['screen']['newCursor'].copy() + curr_cursor = self.env['screen']['new_cursor'].copy() if not self.env['commandBuffer']['Marks']['1']: - self.env['commandBuffer']['Marks']['1'] = currCursor.copy() + self.env['commandBuffer']['Marks']['1'] = curr_cursor.copy() return 1 else: - self.env['commandBuffer']['Marks']['2'] = currCursor.copy() + self.env['commandBuffer']['Marks']['2'] = curr_cursor.copy() return 2 return 0 - def getReviewOrTextCursor(self): + + def get_review_or_text_cursor(self): if self.env['screen']['newCursorReview']: return self.env['screen']['newCursorReview'].copy() else: - return self.env['screen']['newCursor'].copy() - def clearReviewCursor(self): - if not self.isReviewMode(): + return self.env['screen']['new_cursor'].copy() + + def clear_review_cursor(self): + if not self.is_review_mode(): return self.env['screen']['oldCursorReview'] = None self.env['screen']['newCursorReview'] = None - def isCursorHorizontalMove(self): - return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x'] + def is_cursor_horizontal_move(self): + return self.env['screen']['new_cursor']['x'] != self.env['screen']['old_cursor']['x'] - def isCursorVerticalMove(self): - return self.env['screen']['newCursor']['y'] != self.env['screen']['oldCursor']['y'] + def is_cursor_vertical_move(self): + return self.env['screen']['new_cursor']['y'] != self.env['screen']['old_cursor']['y'] - def isReviewMode(self): - return self.env['screen']['newCursorReview'] != None + def is_review_mode(self): + return self.env['screen']['newCursorReview'] is not None - def enterReviewModeCurrTextCursor(self, overwrite=False): - if self.isReviewMode() and not overwrite: + def enter_review_mode_curr_text_cursor(self, overwrite=False): + if self.is_review_mode() and not overwrite: return self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] if not self.env['screen']['newCursorReview']: - self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy() - if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') and \ - self.env['runtime']['attributeManager'].isAttributeCursorActive(): - self.env['screen']['newCursorReview'] = self.env['runtime']['attributeManager'].getCurrAttributeCursor().copy() + self.env['screen']['newCursorReview'] = self.env['screen']['new_cursor'].copy() + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', + 'highlight') and self.env['runtime']['AttributeManager'].is_attribute_cursor_active(): + self.env['screen']['newCursorReview'] = self.env['runtime']['AttributeManager'].get_curr_attribute_cursor( + ).copy() - def setReviewCursorPosition(self, x, y): - if not self.isReviewMode(): - self.enterReviewModeCurrTextCursor() + def set_review_cursor_position(self, x, y): + if not self.is_review_mode(): + self.enter_review_mode_curr_text_cursor() self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview'] self.env['screen']['newCursorReview']['x'] = x self.env['screen']['newCursorReview']['y'] = y - def isApplicationWindowSet(self): + def is_application_window_set(self): try: - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - if self.env['commandBuffer']['windowArea'][currApp]['1'] != None: + curr_app = self.env['runtime']['ApplicationManager'].get_current_application( + ) + if curr_app in self.env['commandBuffer']['windowArea'] and \ + '1' in self.env['commandBuffer']['windowArea'][curr_app] and \ + self.env['commandBuffer']['windowArea'][curr_app]['1'] is not None: return True except Exception as e: - self.env['runtime']['debug'].writeDebugOut('cursorManager isApplicationWindowSet: Error checking window area: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'CursorManager is_application_window_set: Error checking window area: ' + str(e), + debug.DebugLevel.ERROR) return False - def setWindowForApplication(self, start = None, end = None): + + def set_window_for_application(self, start=None, end=None): x1 = 0 x2 = 0 y1 = 0 y2 = 0 - if start == None: + if start is None: if not self.env['commandBuffer']['Marks']['1']: return False else: @@ -104,32 +123,40 @@ class cursorManager(): else: x1 = start['x'] y1 = start['y'] - if end == None: + if end is None: if not self.env['commandBuffer']['Marks']['2']: return False else: - x1 = self.env['commandBuffer']['Marks']['2']['x'] - y1 = self.env['commandBuffer']['Marks']['2']['y'] + x2 = self.env['commandBuffer']['Marks']['2']['x'] + y2 = self.env['commandBuffer']['Marks']['2']['y'] else: - x1 = start['x'] - y1 = start['y'] + x2 = end['x'] + y2 = end['y'] - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - self.env['commandBuffer']['windowArea'][currApp] = {} + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() + self.env['commandBuffer']['windowArea'][curr_app] = {} if x1 * y1 <= \ - x2 * y2: - self.env['commandBuffer']['windowArea'][currApp]['1'] = {'x':x1, 'y':y1} - self.env['commandBuffer']['windowArea'][currApp]['2'] = {'x':x2, 'y':y2} + x2 * y2: + self.env['commandBuffer']['windowArea'][curr_app]['1'] = { + 'x': x1, 'y': y1} + self.env['commandBuffer']['windowArea'][curr_app]['2'] = { + 'x': x2, 'y': y2} else: - self.env['commandBuffer']['windowArea'][currApp]['1'] = {'x':x2, 'y':y2} - self.env['commandBuffer']['windowArea'][currApp]['2'] = {'x':x1, 'y':y1} - return True - def clearWindowForApplication(self): - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() + self.env['commandBuffer']['windowArea'][curr_app]['1'] = { + 'x': x2, 'y': y2} + self.env['commandBuffer']['windowArea'][curr_app]['2'] = { + 'x': x1, 'y': y1} + return True + + def clear_window_for_application(self): + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() try: - del self.env['commandBuffer']['windowArea'][currApp] + del self.env['commandBuffer']['windowArea'][curr_app] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('cursorManager clearWindowForApplication: Error clearing window area: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'CursorManager clear_window_for_application: Error clearing window area: ' + + str(e), + debug.DebugLevel.ERROR) return False - return True + return True diff --git a/src/fenrirscreenreader/core/debug.py b/src/fenrirscreenreader/core/debug.py index 7c7d0885..c9de68e0 100644 --- a/src/fenrirscreenreader/core/debug.py +++ b/src/fenrirscreenreader/core/debug.py @@ -2,12 +2,15 @@ from enum import Enum -class debugLevel(Enum): + +class DebugLevel(Enum): DEACTIVE = 0 ERROR = 1 WARNING = 2 INFO = 3 + def __int__(self): return self.value + def __str__(self): return self.name diff --git a/src/fenrirscreenreader/core/debugManager.py b/src/fenrirscreenreader/core/debugManager.py index 42d7d417..69a528f4 100644 --- a/src/fenrirscreenreader/core/debugManager.py +++ b/src/fenrirscreenreader/core/debugManager.py @@ -3,88 +3,104 @@ from fenrirscreenreader.core import debug from datetime import datetime -import pathlib, os +import pathlib +import os -class debugManager(): - def __init__(self, fileName = ''): + +class DebugManager(): + def __init__(self, file_name=''): self._file = None self._fileOpened = False - self._fileName = '/tmp/fenrir_' + str(os.getpid()) + '_' + str(datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S')) + '.log' - if fileName != '': - self._fileName = fileName + self._fileName = '/tmp/fenrir_' + \ + str(os.getpid()) + '_' + str(datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S')) + '.log' + if file_name != '': + self._fileName = file_name + def initialize(self, environment): self.env = environment + def shutdown(self): - self.closeDebugFile() + self.close_debug_file() + def __del__(self): try: self.shutdown() except Exception as e: # Cannot use debug manager to log its own shutdown errors - print(f'debugManager shutdown: Error during shutdown: {e}') + print(f'DebugManager shutdown: Error during shutdown: {e}') - def openDebugFile(self, fileName = ''): + def open_debug_file(self, file_name=''): self._fileOpened = False - if fileName != '': - self._fileName = fileName + if file_name != '': + self._fileName = file_name if self._fileName != '': directory = os.path.dirname(self._fileName) if not os.path.exists(directory): pathlib.Path(directory).mkdir(parents=True, exist_ok=True) try: - self._file = open(self._fileName,'a') + self._file = open(self._fileName, 'a') # Set readable permissions for all users (644) os.chmod(self._fileName, 0o644) self._fileOpened = True except Exception as e: print(e) - def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False): - mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode') + def write_debug_out( + self, + text, + level=debug.DebugLevel.DEACTIVE, + on_any_level=False): + + mode = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'debug_mode') if mode == '': - mode = 'FILE' + mode = 'FILE' mode = mode.upper().split(',') - fileMode = 'FILE' in mode - printMode = 'PRINT' in mode + file_mode = 'FILE' in mode + print_mode = 'PRINT' in mode - if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \ - not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) : + if ( + int(self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'debug_level')) < int(level)) and not ( + on_any_level and int(self.env['runtime']['SettingsManager'].get_setting_as_int( + 'general', 'debug_level')) > int(debug.DebugLevel.DEACTIVE)): if self._fileOpened: - self.closeDebugFile() + self.close_debug_file() return else: - if not self._fileOpened and fileMode: - self.openDebugFile() + if not self._fileOpened and file_mode: + self.open_debug_file() timestamp = str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')) - if onAnyLevel: - levelInfo = 'INFO ANY' - else: - levelInfo = str(level) - + if on_any_level: + level_info = 'INFO ANY' + else: + level_info = str(level) + # Changed order: text comes first, then level and timestamp - msg = text + ' - ' + levelInfo + ' ' + timestamp - - if printMode: + msg = text + ' - ' + level_info + ' ' + timestamp + + if print_mode: print(msg) - if fileMode: + if file_mode: try: - self._file.write(msg + '\n') + self._file.write(msg + '\n') except Exception as e: print(e) - def closeDebugFile(self): + + def close_debug_file(self): if not self._fileOpened: return False - if self._file != None: + if self._file is not None: try: self._file.close() except Exception as e: - print(e) + print(e) self._fileOpened = False return True - def getDebugFile(self): + def get_debug_file(self): return self._fileName - def setDebugFile(self, fileName): - self.closeDebugFile() - self._fileName = fileName + def set_debug_file(self, file_name): + self.close_debug_file() + self._fileName = file_name diff --git a/src/fenrirscreenreader/core/dynamicVoiceMenu.py b/src/fenrirscreenreader/core/dynamicVoiceMenu.py index 19610aa6..f1f4580b 100644 --- a/src/fenrirscreenreader/core/dynamicVoiceMenu.py +++ b/src/fenrirscreenreader/core/dynamicVoiceMenu.py @@ -4,231 +4,289 @@ import subprocess import importlib.util import os import time +from fenrirscreenreader.core import debug + class DynamicVoiceCommand: """Dynamic command class for voice selection""" + def __init__(self, module, voice, env): self.module = module self.voice = voice self.env = env self.testMessage = "This is a voice test. The quick brown fox jumps over the lazy dog." - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return f"Select voice: {self.voice}" - + def run(self): try: - self.env['runtime']['outputManager'].presentText(f"Testing voice {self.voice} from {self.module}. Please wait.", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Testing voice { + self.voice} from { + self.module}. Please wait.", + interrupt=True) + # Brief pause before testing to avoid speech overlap time.sleep(0.5) - + # Test voice - testResult, errorMsg = self.testVoice() + testResult, errorMsg = self.test_voice() if testResult: - self.env['runtime']['outputManager'].presentText("Voice test completed successfully. Navigate to Apply Tested Voice to use this voice.", interrupt=False, flush=False) - - # Store for confirmation (use same variables as apply_tested_voice.py) + self.env['runtime']['OutputManager'].present_text( + "Voice test completed successfully. Navigate to Apply Tested Voice to use this voice.", + interrupt=False, + flush=False) + + # Store for confirmation (use same variables as + # apply_tested_voice.py) self.env['commandBuffer']['lastTestedModule'] = self.module self.env['commandBuffer']['lastTestedVoice'] = self.voice self.env['commandBuffer']['pendingVoiceModule'] = self.module self.env['commandBuffer']['pendingVoiceVoice'] = self.voice self.env['commandBuffer']['voiceTestCompleted'] = True else: - self.env['runtime']['outputManager'].presentText(f"Voice test failed: {errorMsg}", interrupt=False, flush=False) - + self.env['runtime']['OutputManager'].present_text( + f"Voice test failed: {errorMsg}", interrupt=False, flush=False) + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Voice selection error: {str(e)}", interrupt=False, flush=False) - - def testVoice(self): + self.env['runtime']['OutputManager'].present_text( + f"Voice selection error: {str(e)}", interrupt=False, flush=False) + + def test_voice(self): """Test voice with spd-say""" try: - cmd = ['spd-say', '-C', '-w', '-o', self.module, '-y', self.voice, self.testMessage] - result = subprocess.run(cmd, timeout=8, capture_output=True, text=True) + cmd = [ + 'spd-say', + '-C', + '-w', + '-o', + self.module, + '-y', + self.voice, + self.testMessage] + result = subprocess.run( + cmd, timeout=8, capture_output=True, text=True) if result.returncode == 0: return True, "Voice test successful" else: - error_msg = result.stderr.strip() if result.stderr else f"Command failed with return code {result.returncode}" + error_msg = result.stderr.strip( + ) if result.stderr else f"Command failed with return code {result.returncode}" return False, error_msg except subprocess.TimeoutExpired: return False, "Voice test timed out" except Exception as e: return False, f"Error running voice test: {str(e)}" - - def setCallback(self, callback): + + def set_callback(self, callback): pass + class DynamicApplyVoiceCommand: """Command to apply the tested voice""" + def __init__(self, env): self.env = env - + def initialize(self, environment): self.env = environment - + def shutdown(self): pass - - def getDescription(self): + + def get_description(self): return "Apply tested voice to Fenrir" - + def run(self): try: if not self.env['commandBuffer'].get('voiceTestCompleted', False): - self.env['runtime']['outputManager'].presentText("No voice has been tested yet", interrupt=True) + self.env['runtime']['OutputManager'].present_text( + "No voice has been tested yet", interrupt=True) return - + module = self.env['commandBuffer']['pendingVoiceModule'] voice = self.env['commandBuffer']['pendingVoiceVoice'] - - self.env['runtime']['outputManager'].presentText(f"Applying {voice} from {module}", interrupt=True) - + + self.env['runtime']['OutputManager'].present_text( + f"Applying {voice} from {module}", interrupt=True) + # Debug: Show current settings - settingsManager = self.env['runtime']['settingsManager'] - currentModule = settingsManager.getSetting('speech', 'module') - currentVoice = settingsManager.getSetting('speech', 'voice') - self.env['runtime']['outputManager'].presentText(f"Current: {currentVoice} from {currentModule}", interrupt=False, flush=False) - + settings_manager = self.env['runtime']['SettingsManager'] + current_module = settings_manager.get_setting('speech', 'module') + current_voice = settings_manager.get_setting('speech', 'voice') + self.env['runtime']['OutputManager'].present_text( + f"Current: {current_voice} from {current_module}", interrupt=False, flush=False) + # Apply to runtime settings with fallback - settingsManager = self.env['runtime']['settingsManager'] - + settings_manager = self.env['runtime']['SettingsManager'] + # Store old values for safety - oldDriver = settingsManager.getSetting('speech', 'driver') - oldModule = settingsManager.getSetting('speech', 'module') - oldVoice = settingsManager.getSetting('speech', 'voice') - + old_driver = settings_manager.get_setting('speech', 'driver') + old_module = settings_manager.get_setting('speech', 'module') + old_voice = settings_manager.get_setting('speech', 'voice') + try: - # Apply new settings to runtime only (use setSetting to update settingArgDict) - settingsManager.setSetting('speech', 'driver', 'speechdDriver') - settingsManager.setSetting('speech', 'module', module) - settingsManager.setSetting('speech', 'voice', voice) - + # Apply new settings to runtime only (use set_setting to update + # settingArgDict) + settings_manager.set_setting('speech', 'driver', 'speechdDriver') + settings_manager.set_setting('speech', 'module', module) + settings_manager.set_setting('speech', 'voice', voice) + # Apply settings to speech driver directly - if 'speechDriver' in self.env['runtime']: - speechDriver = self.env['runtime']['speechDriver'] - + if 'SpeechDriver' in self.env['runtime']: + SpeechDriver = self.env['runtime']['SpeechDriver'] + # Get current module to see if we're changing modules - currentModule = settingsManager.getSetting('speech', 'module') - moduleChanging = (currentModule != module) - + current_module = settings_manager.get_setting( + 'speech', 'module') + module_changing = (current_module != module) + # Set module and voice on driver instance first - speechDriver.setModule(module) - speechDriver.setVoice(voice) - - if moduleChanging: - # Module change requires reinitializing the speech driver - self.env['runtime']['outputManager'].presentText(f"Switching from {currentModule} to {module} module", interrupt=True) - speechDriver.shutdown() - speechDriver.initialize(self.env) + SpeechDriver.set_module(module) + SpeechDriver.set_voice(voice) + + if module_changing: + # Module change requires reinitializing the speech + # driver + self.env['runtime']['OutputManager'].present_text( + f"Switching from {current_module} to {module} module", interrupt=True) + SpeechDriver.shutdown() + SpeechDriver.initialize(self.env) # Re-set after initialization - speechDriver.setModule(module) - speechDriver.setVoice(voice) - self.env['runtime']['outputManager'].presentText("Speech driver reinitialized", interrupt=True) - + SpeechDriver.set_module(module) + SpeechDriver.set_voice(voice) + self.env['runtime']['OutputManager'].present_text( + "Speech driver reinitialized", interrupt=True) + # Debug: verify what was actually set - self.env['runtime']['outputManager'].presentText(f"Speech driver now has module: {speechDriver.module}, voice: {speechDriver.voice}", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + f"Speech driver now has module: { + SpeechDriver.module}, voice: { + SpeechDriver.voice}", interrupt=True) + # Force application by speaking a test message - self.env['runtime']['outputManager'].presentText("Voice applied successfully! You should hear this in the new voice.", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Voice applied successfully! You should hear this in the new voice.", interrupt=True) + # Brief pause then more speech to test time.sleep(1) - self.env['runtime']['outputManager'].presentText("Use save settings to make permanent", interrupt=True) - + self.env['runtime']['OutputManager'].present_text( + "Use save settings to make permanent", interrupt=True) + # Clear pending state self.env['commandBuffer']['voiceTestCompleted'] = False - + # Exit vmenu after successful application - self.env['runtime']['vmenuManager'].setActive(False) - + self.env['runtime']['VmenuManager'].set_active(False) + except Exception as e: # Revert on failure - settingsManager.settings['speech']['driver'] = oldDriver - settingsManager.settings['speech']['module'] = oldModule - settingsManager.settings['speech']['voice'] = oldVoice - + settings_manager.settings['speech']['driver'] = old_driver + settings_manager.settings['speech']['module'] = old_module + settings_manager.settings['speech']['voice'] = old_voice + # Try to reinitialize with old settings - if 'speechDriver' in self.env['runtime']: + if 'SpeechDriver' in self.env['runtime']: try: - speechDriver = self.env['runtime']['speechDriver'] - speechDriver.shutdown() - speechDriver.initialize(self.env) + SpeechDriver = self.env['runtime']['SpeechDriver'] + SpeechDriver.shutdown() + SpeechDriver.initialize(self.env) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('dynamicVoiceMenu: Error reinitializing speech driver: ' + str(e), debug.debugLevel.ERROR) - - self.env['runtime']['outputManager'].presentText(f"Failed to apply voice, reverted: {str(e)}", interrupt=False, flush=False) - + self.env['runtime']['DebugManager'].write_debug_out( + 'dynamicVoiceMenu: Error reinitializing speech driver: ' + str(e), + debug.DebugLevel.ERROR) + + self.env['runtime']['OutputManager'].present_text( + f"Failed to apply voice, reverted: { + str(e)}", interrupt=False, flush=False) + except Exception as e: - self.env['runtime']['outputManager'].presentText(f"Apply voice error: {str(e)}", interrupt=False, flush=False) - - def setCallback(self, callback): + self.env['runtime']['OutputManager'].present_text( + f"Apply voice error: {str(e)}", interrupt=False, flush=False) + + def set_callback(self, callback): pass -def addDynamicVoiceMenus(vmenuManager): + +def add_dynamic_voice_menus(VmenuManager): """Add dynamic voice menus to vmenu system""" try: - env = vmenuManager.env - + env = VmenuManager.env + # Get speech modules - modules = getSpeechdModules() + modules = get_speechd_modules() if not modules: return - + # Create voice browser submenu - voiceBrowserMenu = {} - + voice_browser_menu = {} + # Add apply voice command - applyCommand = DynamicApplyVoiceCommand(env) - voiceBrowserMenu['Apply Tested Voice Action'] = applyCommand - + apply_command = DynamicApplyVoiceCommand(env) + voice_browser_menu['Apply Tested Voice Action'] = apply_command + # Add modules as submenus for module in modules[:8]: # Limit to 8 modules to keep menu manageable - moduleMenu = {} - + module_menu = {} + # Get voices for this module - voices = getModuleVoices(module) + voices = get_module_voices(module) if voices: - + # Add voice commands for voice in voices: - voiceCommand = DynamicVoiceCommand(module, voice, env) - moduleMenu[f"{voice} Action"] = voiceCommand + voice_command = DynamicVoiceCommand(module, voice, env) + module_menu[f"{voice} Action"] = voice_command else: - moduleMenu['No voices available Action'] = createInfoCommand(f"No voices found for {module}", env) - - voiceBrowserMenu[f"{module} Menu"] = moduleMenu - - # Add to main menu dict - vmenuManager.menuDict['Voice Browser Menu'] = voiceBrowserMenu - - except Exception as e: - print(f"Error creating dynamic voice menus: {e}") + module_menu['No voices available Action'] = create_info_command( + f"No voices found for {module}", env) -def createInfoCommand(message, env): + voice_browser_menu[f"{module} Menu"] = module_menu + + # Add to main menu dict + VmenuManager.menuDict['Voice Browser Menu'] = voice_browser_menu + + except Exception as e: + # Use debug manager instead of print for error logging + if 'DebugManager' in env['runtime']: + env['runtime']['DebugManager'].write_debug_out( + f"Error creating dynamic voice menus: {e}", + debug.DebugLevel.ERROR) + else: + print(f"Error creating dynamic voice menus: {e}") + + +def create_info_command(message, env): """Create a simple info command""" class InfoCommand: def __init__(self, message, env): self.message = message self.env = env + def initialize(self, environment): pass def shutdown(self): pass - def getDescription(self): return self.message - def run(self): - self.env['runtime']['outputManager'].presentText(self.message, interrupt=True) - def setCallback(self, callback): pass - + def get_description(self): return self.message + + def run(self): + self.env['runtime']['OutputManager'].present_text( + self.message, interrupt=True) + + def set_callback(self, callback): pass + return InfoCommand(message, env) -def getSpeechdModules(): + +def get_speechd_modules(): """Get available speech modules""" try: - result = subprocess.run(['spd-say', '-O'], capture_output=True, text=True, timeout=5) + result = subprocess.run( + ['spd-say', '-O'], capture_output=True, text=True, timeout=5) if result.returncode == 0: lines = result.stdout.strip().split('\n') return [line.strip() for line in lines[1:] if line.strip()] @@ -236,10 +294,12 @@ def getSpeechdModules(): pass return [] -def getModuleVoices(module): + +def get_module_voices(module): """Get voices for a module""" try: - result = subprocess.run(['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=8) + result = subprocess.run( + ['spd-say', '-o', module, '-L'], capture_output=True, text=True, timeout=8) if result.returncode == 0: lines = result.stdout.strip().split('\n') voices = [] @@ -247,7 +307,7 @@ def getModuleVoices(module): if not line.strip(): continue if module.lower() == 'espeak-ng': - voice = processEspeakVoice(line) + voice = process_espeak_voice(line) if voice: voices.append(voice) else: @@ -257,14 +317,15 @@ def getModuleVoices(module): pass return [] -def processEspeakVoice(voiceLine): + +def process_espeak_voice(voiceLine): """Process espeak voice format""" try: parts = [p for p in voiceLine.split() if p] if len(parts) < 2: return None - langCode = parts[-2].lower() + lang_code = parts[-2].lower() variant = parts[-1].lower() - return f"{langCode}+{variant}" if variant and variant != 'none' else langCode + return f"{lang_code}+{variant}" if variant and variant != 'none' else lang_code except Exception: - return None \ No newline at end of file + return None diff --git a/src/fenrirscreenreader/core/environment.py b/src/fenrirscreenreader/core/environment.py index 27f356d9..d06166af 100644 --- a/src/fenrirscreenreader/core/environment.py +++ b/src/fenrirscreenreader/core/environment.py @@ -5,26 +5,26 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.settingsData import settingsData -from fenrirscreenreader.core.runtimeData import runtimeData -from fenrirscreenreader.core.screenData import screenData -from fenrirscreenreader.core.outputData import outputData -from fenrirscreenreader.core.generalData import generalData +from fenrirscreenreader.core.settingsData import settings_data +from fenrirscreenreader.core.runtimeData import runtime_data +from fenrirscreenreader.core.screenData import screen_data +from fenrirscreenreader.core.outputData import output_data +from fenrirscreenreader.core.generalData import general_data from fenrirscreenreader.core import commandData -from fenrirscreenreader.core.inputData import inputData -from fenrirscreenreader.core.punctuationData import punctuationData +from fenrirscreenreader.core.inputData import input_data +from fenrirscreenreader.core.punctuationData import punctuation_data environment = { -'screen': screenData, -'runtime': runtimeData, -'general': generalData, -'settings': settingsData, -'commandInfo': commandData.commandInfo, -'commandBuffer': commandData.commandBuffer, -'input': inputData, -'punctuation': punctuationData, -'output': outputData, -'soundIcons': {}, -'bindings': {}, -'rawBindings': {}, + 'screen': screen_data, + 'runtime': runtime_data, + 'general': general_data, + 'settings': settings_data, + 'commandInfo': commandData.command_info, + 'commandBuffer': commandData.command_buffer, + 'input': input_data, + 'punctuation': punctuation_data, + 'output': output_data, + 'soundIcons': {}, + 'bindings': {}, + 'rawBindings': {}, } diff --git a/src/fenrirscreenreader/core/eventData.py b/src/fenrirscreenreader/core/eventData.py index 0dafeeca..bcfd9418 100644 --- a/src/fenrirscreenreader/core/eventData.py +++ b/src/fenrirscreenreader/core/eventData.py @@ -7,18 +7,21 @@ from fenrirscreenreader.core import debug from enum import Enum -class fenrirEventType(Enum): - Ignore = 0 - StopMainLoop = 1 - ScreenUpdate = 2 - KeyboardInput = 3 - PlugInputDevice = 4 - ScreenChanged = 5 - HeartBeat = 6 - ExecuteCommand = 7 - ByteInput = 8 - RemoteIncomming = 9 + +class FenrirEventType(Enum): + ignore = 0 + stop_main_loop = 1 + screen_update = 2 + keyboard_input = 3 + plug_input_device = 4 + screen_changed = 5 + heart_beat = 6 + execute_command = 7 + byte_input = 8 + remote_incomming = 9 + def __int__(self): return self.value + def __str__(self): return self.name diff --git a/src/fenrirscreenreader/core/eventManager.py b/src/fenrirscreenreader/core/eventManager.py index 94ae82cc..6c43c949 100644 --- a/src/fenrirscreenreader/core/eventManager.py +++ b/src/fenrirscreenreader/core/eventManager.py @@ -5,68 +5,79 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType +from fenrirscreenreader.core.eventData import FenrirEventType from queue import Empty import time from multiprocessing import Queue from multiprocessing.sharedctypes import Value from ctypes import c_bool -class eventManager(): + +class EventManager(): def __init__(self): - self.running = Value(c_bool, True) - self._eventQueue = Queue(maxsize=100) # Bounded queue to prevent memory exhaustion - self.cleanEventQueue() + self.running = Value(c_bool, True) + # Bounded queue to prevent memory exhaustion + self._eventQueue = Queue(maxsize=100) + self.clean_event_queue() + def initialize(self, environment): self.env = environment - def shutdown(self): - self.cleanEventQueue() - def proceedEventLoop(self): + def shutdown(self): + self.clean_event_queue() + + def proceed_event_loop(self): event = self._eventQueue.get() st = time.time() - self.eventDispatcher(event) - #print('NET loop ' + str(time.time() - st)) - def eventDispatcher(self, event): - self.env['runtime']['debug'].writeDebugOut('eventManager:eventDispatcher:start: event: ' + str(event['Type']),debug.debugLevel.INFO) + self.event_dispatcher(event) + # print('NET loop ' + str(time.time() - st)) + + def event_dispatcher(self, event): + self.env['runtime']['DebugManager'].write_debug_out( + 'EventManager:event_dispatcher:start: event: ' + str(event['Type']), debug.DebugLevel.INFO) if not event: return if not event['Type']: return - if event['Type'] == fenrirEventType.Ignore: + if event['Type'] == FenrirEventType.ignore: return - elif event['Type'] == fenrirEventType.StopMainLoop: - self.handleStopMainLoop(event) - elif event['Type'] == fenrirEventType.ScreenUpdate: - self.env['runtime']['fenrirManager'].handleScreenUpdate(event) - elif event['Type'] == fenrirEventType.KeyboardInput: - self.env['runtime']['fenrirManager'].handleInput(event) - elif event['Type'] == fenrirEventType.PlugInputDevice: - self.env['runtime']['fenrirManager'].handlePlugInputDevice(event) - elif event['Type'] == fenrirEventType.ScreenChanged: - self.env['runtime']['fenrirManager'].handleScreenChange(event) - elif event['Type'] == fenrirEventType.HeartBeat: - self.env['runtime']['fenrirManager'].handleHeartBeat(event) - elif event['Type'] == fenrirEventType.ExecuteCommand: - self.env['runtime']['fenrirManager'].handleExecuteCommand(event) - elif event['Type'] == fenrirEventType.ByteInput: - self.env['runtime']['fenrirManager'].handleByteInput(event) - elif event['Type'] == fenrirEventType.RemoteIncomming: - self.env['runtime']['fenrirManager'].handleRemoteIncomming(event) - def isMainEventLoopRunning(self): - return self.running.value == 1 - def startMainEventLoop(self): - self.running.value = 1 - while( self.isMainEventLoopRunning()): - self.proceedEventLoop() + elif event['Type'] == FenrirEventType.stop_main_loop: + self.handle_stop_main_loop(event) + elif event['Type'] == FenrirEventType.screen_update: + self.env['runtime']['FenrirManager'].handle_screen_update(event) + elif event['Type'] == FenrirEventType.keyboard_input: + self.env['runtime']['FenrirManager'].handle_input(event) + elif event['Type'] == FenrirEventType.plug_input_device: + self.env['runtime']['FenrirManager'].handle_plug_input_device(event) + elif event['Type'] == FenrirEventType.screen_changed: + self.env['runtime']['FenrirManager'].handle_screen_change(event) + elif event['Type'] == FenrirEventType.heart_beat: + self.env['runtime']['FenrirManager'].handle_heart_beat(event) + elif event['Type'] == FenrirEventType.execute_command: + self.env['runtime']['FenrirManager'].handle_execute_command(event) + elif event['Type'] == FenrirEventType.byte_input: + self.env['runtime']['FenrirManager'].handle_byte_input(event) + elif event['Type'] == FenrirEventType.remote_incomming: + self.env['runtime']['FenrirManager'].handle_remote_incomming(event) - def handleStopMainLoop(self, event): - self.running.value = 0 + def is_main_event_loop_running(self): + return self.running.value == 1 + + def start_main_event_loop(self): + self.running.value = 1 + while (self.is_main_event_loop_running()): + self.proceed_event_loop() + + def handle_stop_main_loop(self, event): + self.running.value = 0 time.sleep(0.1) - def stopMainEventLoop(self): - self._eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) - def cleanEventQueue(self): + + def stop_main_event_loop(self): + self._eventQueue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) + + def clean_event_queue(self): if self._eventQueue.empty(): return try: @@ -74,27 +85,36 @@ class eventManager(): self._eventQueue.get_nowait() except Empty: pass - def getEventQueue(self): + + def get_event_queue(self): return self._eventQueue - def getRunning(self): + + def get_running(self): return self.running - def getEventQueueSize(self): + + def get_event_queue_size(self): return self._eventQueue.qsize() - def putToEventQueue(self,event, data): - if not isinstance(event, fenrirEventType): + + def put_to_event_queue(self, event, data): + if not isinstance(event, FenrirEventType): return False - if event == fenrirEventType.Ignore: + if event == FenrirEventType.ignore: return False - # Use bounded queue - if full, this will block briefly or drop older events + # Use bounded queue - if full, this will block briefly or drop older + # events try: - self._eventQueue.put({"Type":event,"Data":data}, timeout=0.1) + self._eventQueue.put({"Type": event, "data": data}, timeout=0.1) except Exception as e: - # Queue full - drop oldest event and add new one for critical events - if event in [fenrirEventType.ScreenUpdate, fenrirEventType.KeyboardInput]: + # Queue full - drop oldest event and add new one for critical + # events + if event in [ + FenrirEventType.screen_update, + FenrirEventType.keyboard_input]: try: self._eventQueue.get_nowait() # Remove oldest - self._eventQueue.put({"Type":event,"Data":data}, timeout=0.1) - except: + self._eventQueue.put( + {"Type": event, "data": data}, timeout=0.1) + except BaseException: pass # If still can't add, drop the event # For non-critical events, just drop them if queue is full return True diff --git a/src/fenrirscreenreader/core/fenrirManager.py b/src/fenrirscreenreader/core/fenrirManager.py index 9f320a9c..c350106d 100644 --- a/src/fenrirscreenreader/core/fenrirManager.py +++ b/src/fenrirscreenreader/core/fenrirManager.py @@ -9,164 +9,199 @@ import time import os import sys -from fenrirscreenreader.core import i18n +from fenrirscreenreader.core.i18n import _ from fenrirscreenreader.core import settingsManager from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType +from fenrirscreenreader.core.eventData import FenrirEventType -class fenrirManager(): + +class FenrirManager(): def __init__(self, cliArgs): - self.isInitialized = False + self.is_initialized = False try: - self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self) + self.environment = settingsManager.SettingsManager().init_fenrir_config(cliArgs, self) if not self.environment: - raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable') + raise RuntimeError( + 'Cannot Initialize. Maybe the configfile is not available or not parseable') except RuntimeError: raise - self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True) - signal.signal(signal.SIGINT, self.captureSignal) - signal.signal(signal.SIGTERM, self.captureSignal) + self.environment['runtime']['OutputManager'].present_text( + _("Start Fenrir"), sound_icon ='ScreenReaderOn', interrupt=True) + signal.signal(signal.SIGINT, self.capture_signal) + signal.signal(signal.SIGTERM, self.capture_signal) - self.isInitialized = True + self.is_initialized = True self.modifierInput = False self.singleKeyCommand = False self.command = '' - self.setProcessName() + self.set_process_name() def proceed(self): - if not self.isInitialized: + if not self.is_initialized: return - self.environment['runtime']['eventManager'].startMainEventLoop() + self.environment['runtime']['EventManager'].start_main_event_loop() self.shutdown() - def handleInput(self, event): - self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event), debug.debugLevel.INFO) + def handle_input(self, event): + self.environment['runtime']['DebugManager'].write_debug_out( + 'DEBUG INPUT fenrirMan:' + str(event), debug.DebugLevel.INFO) - if not event['Data']: - event['Data'] = self.environment['runtime']['inputManager'].getInputEvent() + if not event['data']: + event['data'] = self.environment['runtime']['InputManager'].get_input_event() - if event['Data']: - event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName']) - self.environment['runtime']['inputManager'].handleInputEvent(event['Data']) + if event['data']: + event['data']['EventName'] = self.environment['runtime']['InputManager'].convert_event_name( + event['data']['EventName']) + self.environment['runtime']['InputManager'].handle_input_event( + event['data']) else: return - if self.environment['runtime']['inputManager'].noKeyPressed(): - self.environment['runtime']['inputManager'].clearLastDeepInput() + if self.environment['runtime']['InputManager'].no_key_pressed(): + self.environment['runtime']['InputManager'].clear_last_deep_input() - if self.environment['runtime']['screenManager'].isIgnoredScreen(): - self.environment['runtime']['inputManager'].writeEventBuffer() - else: - if self.environment['runtime']['helpManager'].isTutorialMode(): - self.environment['runtime']['inputManager'].clearEventBuffer() - self.environment['runtime']['inputManager'].keyEcho(event['Data']) + if self.environment['runtime']['ScreenManager'].is_ignored_screen(): + self.environment['runtime']['InputManager'].write_event_buffer() + else: + if self.environment['runtime']['HelpManager'].is_tutorial_mode(): + self.environment['runtime']['InputManager'].clear_event_buffer() + self.environment['runtime']['InputManager'].key_echo( + event['data']) - if self.environment['runtime']['vmenuManager'].getActive(): - self.environment['runtime']['inputManager'].clearEventBuffer() + if self.environment['runtime']['VmenuManager'].get_active(): + self.environment['runtime']['InputManager'].clear_event_buffer() - self.detectShortcutCommand() + self.detect_shortcut_command() if self.modifierInput: - self.environment['runtime']['inputManager'].clearEventBuffer() + self.environment['runtime']['InputManager'].clear_event_buffer() if self.singleKeyCommand: - if self.environment['runtime']['inputManager'].noKeyPressed(): - self.environment['runtime']['inputManager'].clearEventBuffer() + if self.environment['runtime']['InputManager'].no_key_pressed(): + self.environment['runtime']['InputManager'].clear_event_buffer() else: - self.environment['runtime']['inputManager'].writeEventBuffer() + self.environment['runtime']['InputManager'].write_event_buffer() - if self.environment['runtime']['inputManager'].noKeyPressed(): + if self.environment['runtime']['InputManager'].no_key_pressed(): self.modifierInput = False self.singleKeyCommand = False - self.environment['runtime']['inputManager'].writeEventBuffer() - self.environment['runtime']['inputManager'].handleDeviceGrab() + self.environment['runtime']['InputManager'].write_event_buffer() + self.environment['runtime']['InputManager'].handle_device_grab() if self.environment['input']['keyForeward'] > 0: self.environment['input']['keyForeward'] -= 1 - self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput') + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onKeyInput') - def handleByteInput(self, event): - if not event['Data'] or event['Data'] == b'': + def handle_byte_input(self, event): + if not event['data'] or event['data'] == b'': return - self.environment['runtime']['byteManager'].handleByteInput(event['Data']) - self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput') + self.environment['runtime']['ByteManager'].handle_byte_input( + event['data']) + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onByteInput') - def handleExecuteCommand(self, event): - if not event['Data'] or event['Data'] == '': + def handle_execute_command(self, event): + if not event['data'] or event['data'] == '': return - currentCommand = event['Data'] + current_command = event['data'] # special modes - if self.environment['runtime']['helpManager'].isTutorialMode(): - if self.environment['runtime']['commandManager'].commandExists(currentCommand, 'help'): - self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'help') + if self.environment['runtime']['HelpManager'].is_tutorial_mode(): + if self.environment['runtime']['CommandManager'].command_exists( + current_command, 'help'): + self.environment['runtime']['CommandManager'].execute_command( + current_command, 'help') return - elif self.environment['runtime']['vmenuManager'].getActive(): - if self.environment['runtime']['commandManager'].commandExists(currentCommand, 'vmenu-navigation'): - self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'vmenu-navigation') + elif self.environment['runtime']['VmenuManager'].get_active(): + if self.environment['runtime']['CommandManager'].command_exists( + current_command, 'vmenu-navigation'): + self.environment['runtime']['CommandManager'].execute_command( + current_command, 'vmenu-navigation') return # default - self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'commands') + self.environment['runtime']['CommandManager'].execute_command( + current_command, 'commands') - def handleRemoteIncomming(self, event): - if not event['Data']: + def handle_remote_incomming(self, event): + if not event['data']: return - self.environment['runtime']['remoteManager'].handleRemoteIncomming(event['Data']) + self.environment['runtime']['RemoteManager'].handle_remote_incomming( + event['data']) - def handleScreenChange(self, event): - self.environment['runtime']['screenManager'].handleScreenChange(event['Data']) - if self.environment['runtime']['vmenuManager'].getActive(): + def handle_screen_change(self, event): + self.environment['runtime']['ScreenManager'].handle_screen_change( + event['data']) + if self.environment['runtime']['VmenuManager'].get_active(): return - self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged') - self.environment['runtime']['screenDriver'].getCurrScreen() + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onScreenChanged') + self.environment['runtime']['ScreenDriver'].get_curr_screen() - def handleScreenUpdate(self, event): - self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data']) + def handle_screen_update(self, event): + self.environment['runtime']['ScreenManager'].handle_screen_update( + event['data']) - if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3: - self.environment['runtime']['inputManager'].clearLastDeepInput() + if time.time() - \ + self.environment['runtime']['InputManager'].get_last_input_time() >= 0.3: + self.environment['runtime']['InputManager'].clear_last_deep_input() - if (self.environment['runtime']['cursorManager'].isCursorVerticalMove() or - self.environment['runtime']['cursorManager'].isCursorHorizontalMove()): - self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange') + if (self.environment['runtime']['CursorManager'].is_cursor_vertical_move( + ) or self.environment['runtime']['CursorManager'].is_cursor_horizontal_move()): + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onCursorChange') - self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate') - self.environment['runtime']['inputManager'].clearLastDeepInput() + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onScreenUpdate') + self.environment['runtime']['InputManager'].clear_last_deep_input() - def handlePlugInputDevice(self, event): + def handle_plug_input_device(self, event): try: - self.environment['runtime']['inputManager'].setLastDetectedDevices(event['Data']) + self.environment['runtime']['InputManager'].set_last_detected_devices( + event['data']) except Exception as e: - self.environment['runtime']['debug'].writeDebugOut('handlePlugInputDevice: Error setting last detected devices: ' + str(e), debug.debugLevel.ERROR) - self.environment['runtime']['inputManager'].handlePlugInputDevice(event['Data']) - self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True) - self.environment['runtime']['inputManager'].setLastDetectedDevices(None) + self.environment['runtime']['DebugManager'].write_debug_out( + 'handle_plug_input_device: Error setting last detected devices: ' + str(e), + debug.DebugLevel.ERROR) + self.environment['runtime']['InputManager'].handle_plug_input_device( + event['data']) + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onPlugInputDevice', force=True) + self.environment['runtime']['InputManager'].set_last_detected_devices( + None) - def handleHeartBeat(self, event): - self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat', force=True) + def handle_heart_beat(self, event): + self.environment['runtime']['CommandManager'].execute_default_trigger( + 'onHeartBeat', force=True) - def detectShortcutCommand(self): + def detect_shortcut_command(self): if self.environment['input']['keyForeward'] > 0: return - if len(self.environment['input']['prevInput']) > len(self.environment['input']['currInput']): + if len(self.environment['input']['prevInput']) > len( + self.environment['input']['currInput']): return - if self.environment['runtime']['inputManager'].isKeyPress(): - self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier() + if self.environment['runtime']['InputManager'].is_key_press(): + self.modifierInput = self.environment['runtime']['InputManager'].curr_key_is_modifier( + ) else: - if not self.environment['runtime']['inputManager'].noKeyPressed(): + if not self.environment['runtime']['InputManager'].no_key_pressed(): if self.singleKeyCommand: - self.singleKeyCommand = len(self.environment['input']['currInput']) == 1 + self.singleKeyCommand = len( + self.environment['input']['currInput']) == 1 - if not(self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()): - currentShortcut = self.environment['runtime']['inputManager'].getCurrShortcut() - self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(currentShortcut) + if not ( + self.singleKeyCommand and self.environment['runtime']['InputManager'].no_key_pressed()): + current_shortcut = self.environment['runtime']['InputManager'].get_curr_shortcut( + ) + self.command = self.environment['runtime']['InputManager'].get_command_for_shortcut( + current_shortcut) if not self.modifierInput: - if self.environment['runtime']['inputManager'].isKeyPress(): + if self.environment['runtime']['InputManager'].is_key_press(): if self.command != '': self.singleKeyCommand = True @@ -176,14 +211,16 @@ class fenrirManager(): # fire event if self.command != '': if self.modifierInput: - self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) + self.environment['runtime']['EventManager'].put_to_event_queue( + FenrirEventType.execute_command, self.command) self.command = '' else: if self.singleKeyCommand: - self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) + self.environment['runtime']['EventManager'].put_to_event_queue( + FenrirEventType.execute_command, self.command) self.command = '' - def setProcessName(self, name='fenrir'): + def set_process_name(self, name='fenrir'): """Attempts to set the process name to 'fenrir'.""" try: from setproctitle import setproctitle @@ -196,29 +233,33 @@ class fenrirManager(): try: from ctypes import cdll, byref, create_string_buffer libc = cdll.LoadLibrary('libc.so.6') - stringBuffer = create_string_buffer(len(name) + 1) - stringBuffer.value = bytes(name, 'UTF-8') - libc.prctl(15, byref(stringBuffer), 0, 0, 0) + string_buffer = create_string_buffer(len(name) + 1) + string_buffer.value = bytes(name, 'UTF-8') + libc.prctl(15, byref(string_buffer), 0, 0, 0) return True except Exception as e: - self.environment['runtime']['debug'].writeDebugOut('setProcName: Error setting process name: ' + str(e), debug.debugLevel.ERROR) + self.environment['runtime']['DebugManager'].write_debug_out( + 'setProcName: Error setting process name: ' + str(e), debug.DebugLevel.ERROR) return False - def shutdownRequest(self): + def shutdown_request(self): try: - self.environment['runtime']['eventManager'].stopMainEventLoop() + self.environment['runtime']['EventManager'].stop_main_event_loop() except Exception as e: - self.environment['runtime']['debug'].writeDebugOut('shutdownRequest: Error stopping main event loop: ' + str(e), debug.debugLevel.ERROR) + self.environment['runtime']['DebugManager'].write_debug_out( + 'shutdown_request: Error stopping main event loop: ' + str(e), + debug.DebugLevel.ERROR) - def captureSignal(self, sigInit, frame): - self.shutdownRequest() + def capture_signal(self, sigInit, frame): + self.shutdown_request() def shutdown(self): - self.environment['runtime']['inputManager'].ungrabAllDevices() - self.environment['runtime']['eventManager'].stopMainEventLoop() - self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True) - self.environment['runtime']['eventManager'].cleanEventQueue() + self.environment['runtime']['InputManager'].ungrab_all_devices() + self.environment['runtime']['EventManager'].stop_main_event_loop() + self.environment['runtime']['OutputManager'].present_text( + _("Quit Fenrir"), sound_icon ='ScreenReaderOff', interrupt=True) + self.environment['runtime']['EventManager'].clean_event_queue() time.sleep(0.6) for currentManager in self.environment['general']['managerList']: diff --git a/src/fenrirscreenreader/core/generalData.py b/src/fenrirscreenreader/core/generalData.py index b7d75a3b..7ebf3c04 100644 --- a/src/fenrirscreenreader/core/generalData.py +++ b/src/fenrirscreenreader/core/generalData.py @@ -6,13 +6,46 @@ from fenrirscreenreader.core import debug -generalData = { -'args': None, -'tutorialMode': False, -'currUser':'', -'prevUser':'', -'managerList':[ 'attributeManager','punctuationManager', 'byteManager', 'cursorManager', 'applicationManager', 'commandManager' - , 'screenManager', 'inputManager','outputManager', 'helpManager', 'memoryManager', 'eventManager','processManager', 'debug'], -'commandFolderList':['commands','onKeyInput', 'onByteInput', 'onCursorChange', 'onScreenUpdate','onScreenChanged','onHeartBeat', 'onPlugInputDevice' - ,'onApplicationChange','onSwitchApplicationProfile','help','vmenu-navigation',], +general_data = { + 'args': None, + 'tutorialMode': False, + 'curr_user': '', + 'prev_user': '', + 'managerList': [ + 'AttributeManager', + 'PunctuationManager', + 'ByteManager', + 'CursorManager', + 'ApplicationManager', + 'CommandManager', + 'ScreenManager', + 'InputManager', + 'OutputManager', + 'HelpManager', + 'MemoryManager', + 'EventManager', + 'ProcessManager', + 'VmenuManager', + 'QuickMenuManager', + 'RemoteManager', + 'SettingsManager', + 'SayAllManager', + 'TableManager', + 'TextManager', + 'BarrierManager', + 'DebugManager'], + 'commandFolderList': [ + 'commands', + 'onKeyInput', + 'onByteInput', + 'onCursorChange', + 'onScreenUpdate', + 'onScreenChanged', + 'onHeartBeat', + 'onPlugInputDevice', + 'onApplicationChange', + 'onSwitchApplicationProfile', + 'help', + 'vmenu-navigation', + ], } diff --git a/src/fenrirscreenreader/core/helpManager.py b/src/fenrirscreenreader/core/helpManager.py index e28b5671..1afec0a5 100755 --- a/src/fenrirscreenreader/core/helpManager.py +++ b/src/fenrirscreenreader/core/helpManager.py @@ -5,106 +5,131 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ -class helpManager(): +class HelpManager(): def __init__(self): self.helpDict = {} self.tutorialListIndex = None + def initialize(self, environment): self.env = environment + def shutdown(self): - pass - def toggleTutorialMode(self): - self.setTutorialMode(not self.env['general']['tutorialMode']) - def setTutorialMode(self, newTutorialMode): - if self.env['runtime']['vmenuManager'].getActive(): + pass + + def toggle_tutorial_mode(self): + self.set_tutorial_mode(not self.env['general']['tutorialMode']) + + def set_tutorial_mode(self, newTutorialMode): + if self.env['runtime']['VmenuManager'].get_active(): return self.env['general']['tutorialMode'] = newTutorialMode if newTutorialMode: - self.createHelpDict() - self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_TUTORIAL_MODE' + self.create_help_dict() + self.env['bindings'][str([1, ['KEY_ESC']]) + ] = 'TOGGLE_TUTORIAL_MODE' self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_HELP' self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_HELP' self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP' else: try: - self.env['bindings'] = self.env['runtime']['settingsManager'].getBindingBackup() + self.env['bindings'] = self.env['runtime']['SettingsManager'].get_binding_backup( + ) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('helpManager setTutorialMode: Error restoring binding backup: ' + str(e), debug.debugLevel.ERROR) - def isTutorialMode(self): + self.env['runtime']['DebugManager'].write_debug_out( + 'HelpManager set_tutorial_mode: Error restoring binding backup: ' + str(e), + debug.DebugLevel.ERROR) + + def is_tutorial_mode(self): return self.env['general']['tutorialMode'] - def getFormattedShortcutForCommand(self, command): + + def get_formatted_shortcut_for_command(self, command): shortcut = [] - rawShortcut = [] + raw_shortcut = [] try: - rawShortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)] - rawShortcut = self.env['rawBindings'][rawShortcut] + raw_shortcut = list(self.env['bindings'].keys())[ + list(self.env['bindings'].values()).index(command)] + raw_shortcut = self.env['rawBindings'][raw_shortcut] # prefer numbers for multitap - if rawShortcut[0] in range(2, 9): - formattedKey = str(rawShortcut[0]) +' times ' - shortcut.append(formattedKey) + if raw_shortcut[0] in range(2, 9): + formatted_key = str(raw_shortcut[0]) + ' times ' + shortcut.append(formatted_key) # prefer metha keys - for k in ['KEY_FENRIR', 'KEY_SCRIPT', 'KEY_CTRL', 'KEY_SHIFT', 'KEY_ALT', 'KEY_META']: - if k in rawShortcut[1]: - formattedKey = k - formattedKey = formattedKey.lower() - formattedKey = formattedKey.replace('key_kp', ' keypad ') - formattedKey = formattedKey.replace('key_', ' ') - shortcut.append(formattedKey) - rawShortcut[1].remove(k) + for k in [ + 'KEY_FENRIR', + 'KEY_SCRIPT', + 'KEY_CTRL', + 'KEY_SHIFT', + 'KEY_ALT', + 'KEY_META']: + if k in raw_shortcut[1]: + formatted_key = k + formatted_key = formatted_key.lower() + formatted_key = formatted_key.replace('key_kp', ' keypad ') + formatted_key = formatted_key.replace('key_', ' ') + shortcut.append(formatted_key) + raw_shortcut[1].remove(k) # handle other keys - for k in rawShortcut[1]: - formattedKey = k - formattedKey = formattedKey.lower() - formattedKey = formattedKey.replace('key_kp', ' keypad ') - formattedKey = formattedKey.replace('key_', ' ') - shortcut.append(formattedKey) + for k in raw_shortcut[1]: + formatted_key = k + formatted_key = formatted_key.lower() + formatted_key = formatted_key.replace('key_kp', ' keypad ') + formatted_key = formatted_key.replace('key_', ' ') + shortcut.append(formatted_key) except Exception as e: return '' shortcut = str(shortcut) - shortcut = shortcut.replace('[','') - shortcut = shortcut.replace(']','') - shortcut = shortcut.replace("'",'') + shortcut = shortcut.replace('[', '') + shortcut = shortcut.replace(']', '') + shortcut = shortcut.replace("'", '') return shortcut - def getCommandHelpText(self, command, section = 'commands'): - commandName = command.lower() - commandName = commandName.split('__-__')[0] - commandName = commandName.replace('_',' ') - commandName = commandName.replace('_',' ') + def get_command_help_text(self, command, section='commands'): + command_name = command.lower() + command_name = command_name.split('__-__')[0] + command_name = command_name.replace('_', ' ') + command_name = command_name.replace('_', ' ') if command == 'TOGGLE_TUTORIAL_MODE': - commandDescription = _('toggles the tutorial mode') + command_description = _('toggles the tutorial mode') else: - commandDescription = self.env['runtime']['commandManager'].getCommandDescription(command, section = 'commands') - if commandDescription == '': - commandDescription = 'no Description available' - commandShortcut = self.getFormattedShortcutForCommand(command) - if commandShortcut == '': - commandShortcut = 'unbound' - helptext = commandName + ', Shortcut ' + commandShortcut + ', Description ' + commandDescription + command_description = self.env['runtime']['CommandManager'].get_command_description( + command, section='commands') + if command_description == '': + command_description = 'no Description available' + command_shortcut = self.get_formatted_shortcut_for_command(command) + if command_shortcut == '': + command_shortcut = 'unbound' + helptext = command_name + ', Shortcut ' + \ + command_shortcut + ', Description ' + command_description return helptext - def createHelpDict(self, section = 'commands'): + + def create_help_dict(self, section='commands'): self.helpDict = {} for command in sorted(self.env['commands'][section].keys()): - self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section) + self.helpDict[len(self.helpDict)] = self.get_command_help_text( + command, section) if len(self.helpDict) > 0: self.tutorialListIndex = 0 else: self.tutorialListIndex = None - def getHelpForCurrentIndex(self): - if self.tutorialListIndex == None: - return '' + + def get_help_for_current_index(self): + if self.tutorialListIndex is None: + return '' return self.helpDict[self.tutorialListIndex] - def nextIndex(self): - if self.tutorialListIndex == None: - return + + def next_index(self): + if self.tutorialListIndex is None: + return self.tutorialListIndex += 1 if self.tutorialListIndex >= len(self.helpDict): - self.tutorialListIndex = 0 - def prevIndex(self): - if self.tutorialListIndex == None: - return + self.tutorialListIndex = 0 + + def prev_index(self): + if self.tutorialListIndex is None: + return self.tutorialListIndex -= 1 if self.tutorialListIndex < 0: - self.tutorialListIndex = len(self.helpDict) - 1 + self.tutorialListIndex = len(self.helpDict) - 1 diff --git a/src/fenrirscreenreader/core/i18n.py b/src/fenrirscreenreader/core/i18n.py index 5493d371..d7636c12 100644 --- a/src/fenrirscreenreader/core/i18n.py +++ b/src/fenrirscreenreader/core/i18n.py @@ -6,6 +6,11 @@ import gettext import locale +import builtins -# the only function we really need to call here is gettext.install. Python3 has simplified this. +# the only function we really need to call here is gettext.install. +# Python3 has simplified this. gettext.install("fenrir") + +# Make _ available for import to satisfy static analysis tools +_ = builtins._ diff --git a/src/fenrirscreenreader/core/inputData.py b/src/fenrirscreenreader/core/inputData.py index e3bd87e4..4e8d3840 100644 --- a/src/fenrirscreenreader/core/inputData.py +++ b/src/fenrirscreenreader/core/inputData.py @@ -7,30 +7,594 @@ from fenrirscreenreader.core import debug import time -inputData = { -'currInput': [], -'prevDeepestInput': [], -'eventBuffer': [], -'shortcutRepeat': 0, -'fenrirKey': [], -'scriptKey': [], -'keyForeward': 0, -'lastInputTime':time.time(), -'oldNumLock': True, -'newNumLock':True, -'oldScrollLock': True, -'newScrollLock':True, -'oldCapsLock':False, -'newCapsLock':False +input_data = { + 'currInput': [], + 'prevDeepestInput': [], + 'eventBuffer': [], + 'shortcut_repeat': 0, + 'fenrirKey': [], + 'scriptKey': [], + 'keyForeward': 0, + 'lastInputTime': time.time(), + 'oldNumLock': True, + 'newNumLock': True, + 'oldScrollLock': True, + 'newScrollLock': True, + 'oldCapsLock': False, + 'newCapsLock': False } -inputEvent = { -'EventName': '', -'EventValue': '', -'EventSec': 0, -'EventUsec': 0, -'EventState': 0, +input_event = { + 'EventName': '', + 'EventValue': '', + 'EventSec': 0, + 'EventUsec': 0, + 'EventState': 0, } -keyNames = ['KEY_RESERVED', 'KEY_ESC', 'KEY_1', 'KEY_2', 'KEY_3', 'KEY_4', 'KEY_5', 'KEY_6', 'KEY_7', 'KEY_8', 'KEY_9', 'KEY_0', 'KEY_MINUS', 'KEY_EQUAL', 'KEY_BACKSPACE', 'KEY_TAB', 'KEY_Q', 'KEY_W', 'KEY_E', 'KEY_R', 'KEY_T', 'KEY_Y', 'KEY_U', 'KEY_I', 'KEY_O', 'KEY_P', 'KEY_LEFTBRACE', 'KEY_RIGHTBRACE', 'KEY_ENTER', 'KEY_LEFTCTRL', 'KEY_A', 'KEY_S', 'KEY_D', 'KEY_F', 'KEY_G', 'KEY_H', 'KEY_J', 'KEY_K', 'KEY_L', 'KEY_SEMICOLON', 'KEY_APOSTROPHE', 'KEY_GRAVE', 'KEY_LEFTSHIFT', 'KEY_BACKSLASH', 'KEY_Z', 'KEY_X', 'KEY_C', 'KEY_V', 'KEY_B', 'KEY_N', 'KEY_M', 'KEY_COMMA', 'KEY_DOT', 'KEY_SLASH', 'KEY_RIGHTSHIFT', 'KEY_KPASTERISK', 'KEY_LEFTALT', 'KEY_SPACE', 'KEY_CAPSLOCK', 'KEY_F1', 'KEY_F2', 'KEY_F3', 'KEY_F4', 'KEY_F5', 'KEY_F6', 'KEY_F7', 'KEY_F8', 'KEY_F9', 'KEY_F10', 'KEY_NUMLOCK', 'KEY_SCROLLLOCK', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9', 'KEY_KPMINUS', 'KEY_KP4', 'KEY_KP5', 'KEY_KP6', 'KEY_KPPLUS', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP0', 'KEY_KPDOT', 'KEY_ZENKAKUHANKAKU', 'KEY_102ND', 'KEY_F11', 'KEY_F12', 'KEY_RO', 'KEY_KATAKANA', 'KEY_HIRAGANA', 'KEY_HENKAN', 'KEY_KATAKANAHIRAGANA', 'KEY_MUHENKAN', 'KEY_KPJPCOMMA', 'KEY_KPENTER', 'KEY_RIGHTCTRL', 'KEY_KPSLASH', 'KEY_SYSRQ', 'KEY_RIGHTALT', 'KEY_LINEFEED', 'KEY_HOME', 'KEY_UP', 'KEY_PAGEUP', 'KEY_LEFT', 'KEY_RIGHT', 'KEY_END', 'KEY_DOWN', 'KEY_PAGEDOWN', 'KEY_INSERT', 'KEY_DELETE', 'KEY_MACRO', 'KEY_MIN_INTERESTING', 'KEY_MUTE', 'KEY_VOLUMEDOWN', 'KEY_VOLUMEUP', 'KEY_POWER', 'KEY_KPEQUAL', 'KEY_KPPLUSMINUS', 'KEY_PAUSE', 'KEY_SCALE', 'KEY_KPCOMMA', 'KEY_HANGEUL', 'KEY_HANGUEL', 'KEY_HANJA', 'KEY_YEN', 'KEY_LEFTMETA', 'KEY_RIGHTMETA', 'KEY_COMPOSE', 'KEY_STOP', 'KEY_AGAIN', 'KEY_PROPS', 'KEY_UNDO', 'KEY_FRONT', 'KEY_COPY', 'KEY_OPEN', 'KEY_PASTE', 'KEY_FIND', 'KEY_CUT', 'KEY_HELP', 'KEY_MENU', 'KEY_CALC', 'KEY_SETUP', 'KEY_SLEEP', 'KEY_WAKEUP', 'KEY_FILE', 'KEY_SENDFILE', 'KEY_DELETEFILE', 'KEY_XFER', 'KEY_PROG1', 'KEY_PROG2', 'KEY_WWW', 'KEY_MSDOS', 'KEY_COFFEE', 'KEY_SCREENLOCK', 'KEY_DIRECTION', 'KEY_ROTATE_DISPLAY', 'KEY_CYCLEWINDOWS', 'KEY_MAIL', 'KEY_BOOKMARKS', 'KEY_COMPUTER', 'KEY_BACK', 'KEY_FORWARD', 'KEY_CLOSECD', 'KEY_EJECTCD', 'KEY_EJECTCLOSECD', 'KEY_NEXTSONG', 'KEY_PLAYPAUSE', 'KEY_PREVIOUSSONG', 'KEY_STOPCD', 'KEY_RECORD', 'KEY_REWIND', 'KEY_PHONE', 'KEY_ISO', 'KEY_CONFIG', 'KEY_HOMEPAGE', 'KEY_REFRESH', 'KEY_EXIT', 'KEY_MOVE', 'KEY_EDIT', 'KEY_SCROLLUP', 'KEY_SCROLLDOWN', 'KEY_KPLEFTPAREN', 'KEY_KPRIGHTPAREN', 'KEY_NEW', 'KEY_REDO', 'KEY_F13', 'KEY_F14', 'KEY_F15', 'KEY_F16', 'KEY_F17', 'KEY_F18', 'KEY_F19', 'KEY_F20', 'KEY_F21', 'KEY_F22', 'KEY_F23', 'KEY_F24', 'KEY_PLAYCD', 'KEY_PAUSECD', 'KEY_PROG3', 'KEY_PROG4', 'KEY_DASHBOARD', 'KEY_SUSPEND', 'KEY_CLOSE', 'KEY_PLAY', 'KEY_FASTFORWARD', 'KEY_BASSBOOST', 'KEY_PRINT', 'KEY_HP', 'KEY_CAMERA', 'KEY_SOUND', 'KEY_QUESTION', 'KEY_EMAIL', 'KEY_CHAT', 'KEY_SEARCH', 'KEY_CONNECT', 'KEY_FINANCE', 'KEY_SPORT', 'KEY_SHOP', 'KEY_ALTERASE', 'KEY_CANCEL', 'KEY_BRIGHTNESSDOWN', 'KEY_BRIGHTNESSUP', 'KEY_MEDIA', 'KEY_SWITCHVIDEOMODE', 'KEY_KBDILLUMTOGGLE', 'KEY_KBDILLUMDOWN', 'KEY_KBDILLUMUP', 'KEY_SEND', 'KEY_REPLY', 'KEY_FORWARDMAIL', 'KEY_SAVE', 'KEY_DOCUMENTS', 'KEY_BATTERY', 'KEY_BLUETOOTH', 'KEY_WLAN', 'KEY_UWB', 'KEY_UNKNOWN', 'KEY_VIDEO_NEXT', 'KEY_VIDEO_PREV', 'KEY_BRIGHTNESS_CYCLE', 'KEY_BRIGHTNESS_AUTO', 'KEY_BRIGHTNESS_ZERO', 'KEY_DISPLAY_OFF', 'KEY_WIMAX', 'KEY_WWAN', 'KEY_RFKILL', 'KEY_MICMUTE', 'BTN_0', 'BTN_MISC', 'BTN_1', 'BTN_2', 'BTN_3', 'BTN_4', 'BTN_5', 'BTN_6', 'BTN_7', 'BTN_8', 'BTN_9', 'BTN_LEFT', 'BTN_MOUSE', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_SIDE', 'BTN_EXTRA', 'BTN_FORWARD', 'BTN_BACK', 'BTN_TASK', 'BTN_JOYSTICK', 'BTN_TRIGGER', 'BTN_THUMB', 'BTN_THUMB2', 'BTN_TOP', 'BTN_TOP2', 'BTN_PINKIE', 'BTN_BASE', 'BTN_BASE2', 'BTN_BASE3', 'BTN_BASE4', 'BTN_BASE5', 'BTN_BASE6', 'BTN_DEAD', 'BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH', 'BTN_B', 'BTN_EAST', 'BTN_C', 'BTN_NORTH', 'BTN_X', 'BTN_WEST', 'BTN_Y', 'BTN_Z', 'BTN_TL', 'BTN_TR', 'BTN_TL2', 'BTN_TR2', 'BTN_SELECT', 'BTN_START', 'BTN_MODE', 'BTN_THUMBL', 'BTN_THUMBR', 'BTN_DIGI', 'BTN_TOOL_PEN', 'BTN_TOOL_RUBBER', 'BTN_TOOL_BRUSH', 'BTN_TOOL_PENCIL', 'BTN_TOOL_AIRBRUSH', 'BTN_TOOL_FINGER', 'BTN_TOOL_MOUSE', 'BTN_TOOL_LENS', 'BTN_TOOL_QUINTTAP', 'BTN_TOUCH', 'BTN_STYLUS', 'BTN_STYLUS2', 'BTN_TOOL_DOUBLETAP', 'BTN_TOOL_TRIPLETAP', 'BTN_TOOL_QUADTAP', 'BTN_GEAR_DOWN', 'BTN_WHEEL', 'BTN_GEAR_UP', 'KEY_OK', 'KEY_SELECT', 'KEY_GOTO', 'KEY_CLEAR', 'KEY_POWER2', 'KEY_OPTION', 'KEY_INFO', 'KEY_TIME', 'KEY_VENDOR', 'KEY_ARCHIVE', 'KEY_PROGRAM', 'KEY_CHANNEL', 'KEY_FAVORITES', 'KEY_EPG', 'KEY_PVR', 'KEY_MHP', 'KEY_LANGUAGE', 'KEY_TITLE', 'KEY_SUBTITLE', 'KEY_ANGLE', 'KEY_ZOOM', 'KEY_MODE', 'KEY_KEYBOARD', 'KEY_SCREEN', 'KEY_PC', 'KEY_TV', 'KEY_TV2', 'KEY_VCR', 'KEY_VCR2', 'KEY_SAT', 'KEY_SAT2', 'KEY_CD', 'KEY_TAPE', 'KEY_RADIO', 'KEY_TUNER', 'KEY_PLAYER', 'KEY_TEXT', 'KEY_DVD', 'KEY_AUX', 'KEY_MP3', 'KEY_AUDIO', 'KEY_VIDEO', 'KEY_DIRECTORY', 'KEY_LIST', 'KEY_MEMO', 'KEY_CALENDAR', 'KEY_RED', 'KEY_GREEN', 'KEY_YELLOW', 'KEY_BLUE', 'KEY_CHANNELUP', 'KEY_CHANNELDOWN', 'KEY_FIRST', 'KEY_LAST', 'KEY_AB', 'KEY_NEXT', 'KEY_RESTART', 'KEY_SLOW', 'KEY_SHUFFLE', 'KEY_BREAK', 'KEY_PREVIOUS', 'KEY_DIGITS', 'KEY_TEEN', 'KEY_TWEN', 'KEY_VIDEOPHONE', 'KEY_GAMES', 'KEY_ZOOMIN', 'KEY_ZOOMOUT', 'KEY_ZOOMRESET', 'KEY_WORDPROCESSOR', 'KEY_EDITOR', 'KEY_SPREADSHEET', 'KEY_GRAPHICSEDITOR', 'KEY_PRESENTATION', 'KEY_DATABASE', 'KEY_NEWS', 'KEY_VOICEMAIL', 'KEY_ADDRESSBOOK', 'KEY_MESSENGER', 'KEY_BRIGHTNESS_TOGGLE', 'KEY_DISPLAYTOGGLE', 'KEY_SPELLCHECK', 'KEY_LOGOFF', 'KEY_DOLLAR', 'KEY_EURO', 'KEY_FRAMEBACK', 'KEY_FRAMEFORWARD', 'KEY_CONTEXT_MENU', 'KEY_MEDIA_REPEAT', 'KEY_10CHANNELSUP', 'KEY_10CHANNELSDOWN', 'KEY_IMAGES', 'KEY_DEL_EOL', 'KEY_DEL_EOS', 'KEY_INS_LINE', 'KEY_DEL_LINE', 'KEY_FN', 'KEY_FN_ESC', 'KEY_FN_F1', 'KEY_FN_F2', 'KEY_FN_F3', 'KEY_FN_F4', 'KEY_FN_F5', 'KEY_FN_F6', 'KEY_FN_F7', 'KEY_FN_F8', 'KEY_FN_F9', 'KEY_FN_F10', 'KEY_FN_F11', 'KEY_FN_F12', 'KEY_FN_1', 'KEY_FN_2', 'KEY_FN_D', 'KEY_FN_E', 'KEY_FN_F', 'KEY_FN_S', 'KEY_FN_B', 'KEY_BRL_DOT1', 'KEY_BRL_DOT2', 'KEY_BRL_DOT3', 'KEY_BRL_DOT4', 'KEY_BRL_DOT5', 'KEY_BRL_DOT6', 'KEY_BRL_DOT7', 'KEY_BRL_DOT8', 'KEY_BRL_DOT9', 'KEY_BRL_DOT10', 'KEY_NUMERIC_0', 'KEY_NUMERIC_1', 'KEY_NUMERIC_2', 'KEY_NUMERIC_3', 'KEY_NUMERIC_4', 'KEY_NUMERIC_5', 'KEY_NUMERIC_6', 'KEY_NUMERIC_7', 'KEY_NUMERIC_8', 'KEY_NUMERIC_9', 'KEY_NUMERIC_STAR', 'KEY_NUMERIC_POUND', 'KEY_NUMERIC_A', 'KEY_NUMERIC_B', 'KEY_NUMERIC_C', 'KEY_NUMERIC_D', 'KEY_CAMERA_FOCUS', 'KEY_WPS_BUTTON', 'KEY_TOUCHPAD_TOGGLE', 'KEY_TOUCHPAD_ON', 'KEY_TOUCHPAD_OFF', 'KEY_CAMERA_ZOOMIN', 'KEY_CAMERA_ZOOMOUT', 'KEY_CAMERA_UP', 'KEY_CAMERA_DOWN', 'KEY_CAMERA_LEFT', 'KEY_CAMERA_RIGHT', 'KEY_ATTENDANT_ON', 'KEY_ATTENDANT_OFF', 'KEY_ATTENDANT_TOGGLE', 'KEY_LIGHTS_TOGGLE', 'BTN_DPAD_UP', 'BTN_DPAD_DOWN', 'BTN_DPAD_LEFT', 'BTN_DPAD_RIGHT', 'KEY_ALS_TOGGLE', 'KEY_BUTTONCONFIG', 'KEY_TASKMANAGER', 'KEY_JOURNAL', 'KEY_CONTROLPANEL', 'KEY_APPSELECT', 'KEY_SCREENSAVER', 'KEY_VOICECOMMAND', 'KEY_BRIGHTNESS_MIN', 'KEY_BRIGHTNESS_MAX', 'KEY_KBDINPUTASSIST_PREV', 'KEY_KBDINPUTASSIST_NEXT', 'KEY_KBDINPUTASSIST_PREVGROUP', 'KEY_KBDINPUTASSIST_NEXTGROUP', 'KEY_KBDINPUTASSIST_ACCEPT', 'KEY_KBDINPUTASSIST_CANCEL', 'KEY_RIGHT_UP', 'KEY_RIGHT_DOWN', 'KEY_LEFT_UP', 'KEY_LEFT_DOWN', 'KEY_ROOT_MENU', 'KEY_MEDIA_TOP_MENU', 'KEY_NUMERIC_11', 'KEY_NUMERIC_12', 'KEY_AUDIO_DESC', 'KEY_3D_MODE', 'KEY_NEXT_FAVORITE', 'KEY_STOP_RECORD', 'KEY_PAUSE_RECORD', 'KEY_VOD', 'KEY_UNMUTE', 'KEY_DATA', 'KEY_FASTREVERSE', 'KEY_SLOWREVERSE', 'BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1', 'BTN_TRIGGER_HAPPY2', 'BTN_TRIGGER_HAPPY3', 'BTN_TRIGGER_HAPPY4', 'BTN_TRIGGER_HAPPY5', 'BTN_TRIGGER_HAPPY6', 'BTN_TRIGGER_HAPPY7', 'BTN_TRIGGER_HAPPY8', 'BTN_TRIGGER_HAPPY9', 'BTN_TRIGGER_HAPPY10', 'BTN_TRIGGER_HAPPY11', 'BTN_TRIGGER_HAPPY12', 'BTN_TRIGGER_HAPPY13', 'BTN_TRIGGER_HAPPY14', 'BTN_TRIGGER_HAPPY15', 'BTN_TRIGGER_HAPPY16', 'BTN_TRIGGER_HAPPY17', 'BTN_TRIGGER_HAPPY18', 'BTN_TRIGGER_HAPPY19', 'BTN_TRIGGER_HAPPY20', 'BTN_TRIGGER_HAPPY21', 'BTN_TRIGGER_HAPPY22', 'BTN_TRIGGER_HAPPY23', 'BTN_TRIGGER_HAPPY24', 'BTN_TRIGGER_HAPPY25', 'BTN_TRIGGER_HAPPY26', 'BTN_TRIGGER_HAPPY27', 'BTN_TRIGGER_HAPPY28', 'BTN_TRIGGER_HAPPY29', 'BTN_TRIGGER_HAPPY30', 'BTN_TRIGGER_HAPPY31', 'BTN_TRIGGER_HAPPY32', 'BTN_TRIGGER_HAPPY33', 'BTN_TRIGGER_HAPPY34', 'BTN_TRIGGER_HAPPY35', 'BTN_TRIGGER_HAPPY36', 'BTN_TRIGGER_HAPPY37', 'BTN_TRIGGER_HAPPY38', 'BTN_TRIGGER_HAPPY39', 'BTN_TRIGGER_HAPPY40', 'KEY_FENRIR', 'KEY_SCRIPT', 'KEY_ALT', 'KEY_CTRL', 'KEY_META', 'KEY_SHIFT'] - +key_names = [ + 'KEY_RESERVED', + 'KEY_ESC', + 'KEY_1', + 'KEY_2', + 'KEY_3', + 'KEY_4', + 'KEY_5', + 'KEY_6', + 'KEY_7', + 'KEY_8', + 'KEY_9', + 'KEY_0', + 'KEY_MINUS', + 'KEY_EQUAL', + 'KEY_BACKSPACE', + 'KEY_TAB', + 'KEY_Q', + 'KEY_W', + 'KEY_E', + 'KEY_R', + 'KEY_T', + 'KEY_Y', + 'KEY_U', + 'KEY_I', + 'KEY_O', + 'KEY_P', + 'KEY_LEFTBRACE', + 'KEY_RIGHTBRACE', + 'KEY_ENTER', + 'KEY_LEFTCTRL', + 'KEY_A', + 'KEY_S', + 'KEY_D', + 'KEY_F', + 'KEY_G', + 'KEY_H', + 'KEY_J', + 'KEY_K', + 'KEY_L', + 'KEY_SEMICOLON', + 'KEY_APOSTROPHE', + 'KEY_GRAVE', + 'KEY_LEFTSHIFT', + 'KEY_BACKSLASH', + 'KEY_Z', + 'KEY_X', + 'KEY_C', + 'KEY_V', + 'KEY_B', + 'KEY_N', + 'KEY_M', + 'KEY_COMMA', + 'KEY_DOT', + 'KEY_SLASH', + 'KEY_RIGHTSHIFT', + 'KEY_KPASTERISK', + 'KEY_LEFTALT', + 'KEY_SPACE', + 'KEY_CAPSLOCK', + 'KEY_F1', + 'KEY_F2', + 'KEY_F3', + 'KEY_F4', + 'KEY_F5', + 'KEY_F6', + 'KEY_F7', + 'KEY_F8', + 'KEY_F9', + 'KEY_F10', + 'KEY_NUMLOCK', + 'KEY_SCROLLLOCK', + 'KEY_KP7', + 'KEY_KP8', + 'KEY_KP9', + 'KEY_KPMINUS', + 'KEY_KP4', + 'KEY_KP5', + 'KEY_KP6', + 'KEY_KPPLUS', + 'KEY_KP1', + 'KEY_KP2', + 'KEY_KP3', + 'KEY_KP0', + 'KEY_KPDOT', + 'KEY_ZENKAKUHANKAKU', + 'KEY_102ND', + 'KEY_F11', + 'KEY_F12', + 'KEY_RO', + 'KEY_KATAKANA', + 'KEY_HIRAGANA', + 'KEY_HENKAN', + 'KEY_KATAKANAHIRAGANA', + 'KEY_MUHENKAN', + 'KEY_KPJPCOMMA', + 'KEY_KPENTER', + 'KEY_RIGHTCTRL', + 'KEY_KPSLASH', + 'KEY_SYSRQ', + 'KEY_RIGHTALT', + 'KEY_LINEFEED', + 'KEY_HOME', + 'KEY_UP', + 'KEY_PAGEUP', + 'KEY_LEFT', + 'KEY_RIGHT', + 'KEY_END', + 'KEY_DOWN', + 'KEY_PAGEDOWN', + 'KEY_INSERT', + 'KEY_DELETE', + 'KEY_MACRO', + 'KEY_MIN_INTERESTING', + 'KEY_MUTE', + 'KEY_VOLUMEDOWN', + 'KEY_VOLUMEUP', + 'KEY_POWER', + 'KEY_KPEQUAL', + 'KEY_KPPLUSMINUS', + 'KEY_PAUSE', + 'KEY_SCALE', + 'KEY_KPCOMMA', + 'KEY_HANGEUL', + 'KEY_HANGUEL', + 'KEY_HANJA', + 'KEY_YEN', + 'KEY_LEFTMETA', + 'KEY_RIGHTMETA', + 'KEY_COMPOSE', + 'KEY_STOP', + 'KEY_AGAIN', + 'KEY_PROPS', + 'KEY_UNDO', + 'KEY_FRONT', + 'KEY_COPY', + 'KEY_OPEN', + 'KEY_PASTE', + 'KEY_FIND', + 'KEY_CUT', + 'KEY_HELP', + 'KEY_MENU', + 'KEY_CALC', + 'KEY_SETUP', + 'KEY_SLEEP', + 'KEY_WAKEUP', + 'KEY_FILE', + 'KEY_SENDFILE', + 'KEY_DELETEFILE', + 'KEY_XFER', + 'KEY_PROG1', + 'KEY_PROG2', + 'KEY_WWW', + 'KEY_MSDOS', + 'KEY_COFFEE', + 'KEY_SCREENLOCK', + 'KEY_DIRECTION', + 'KEY_ROTATE_DISPLAY', + 'KEY_CYCLEWINDOWS', + 'KEY_MAIL', + 'KEY_BOOKMARKS', + 'KEY_COMPUTER', + 'KEY_BACK', + 'KEY_FORWARD', + 'KEY_CLOSECD', + 'KEY_EJECTCD', + 'KEY_EJECTCLOSECD', + 'KEY_NEXTSONG', + 'KEY_PLAYPAUSE', + 'KEY_PREVIOUSSONG', + 'KEY_STOPCD', + 'KEY_RECORD', + 'KEY_REWIND', + 'KEY_PHONE', + 'KEY_ISO', + 'KEY_CONFIG', + 'KEY_HOMEPAGE', + 'KEY_REFRESH', + 'KEY_EXIT', + 'KEY_MOVE', + 'KEY_EDIT', + 'KEY_SCROLLUP', + 'KEY_SCROLLDOWN', + 'KEY_KPLEFTPAREN', + 'KEY_KPRIGHTPAREN', + 'KEY_NEW', + 'KEY_REDO', + 'KEY_F13', + 'KEY_F14', + 'KEY_F15', + 'KEY_F16', + 'KEY_F17', + 'KEY_F18', + 'KEY_F19', + 'KEY_F20', + 'KEY_F21', + 'KEY_F22', + 'KEY_F23', + 'KEY_F24', + 'KEY_PLAYCD', + 'KEY_PAUSECD', + 'KEY_PROG3', + 'KEY_PROG4', + 'KEY_DASHBOARD', + 'KEY_SUSPEND', + 'KEY_CLOSE', + 'KEY_PLAY', + 'KEY_FASTFORWARD', + 'KEY_BASSBOOST', + 'KEY_PRINT', + 'KEY_HP', + 'KEY_CAMERA', + 'KEY_SOUND', + 'KEY_QUESTION', + 'KEY_EMAIL', + 'KEY_CHAT', + 'KEY_SEARCH', + 'KEY_CONNECT', + 'KEY_FINANCE', + 'KEY_SPORT', + 'KEY_SHOP', + 'KEY_ALTERASE', + 'KEY_CANCEL', + 'KEY_BRIGHTNESSDOWN', + 'KEY_BRIGHTNESSUP', + 'KEY_MEDIA', + 'KEY_SWITCHVIDEOMODE', + 'KEY_KBDILLUMTOGGLE', + 'KEY_KBDILLUMDOWN', + 'KEY_KBDILLUMUP', + 'KEY_SEND', + 'KEY_REPLY', + 'KEY_FORWARDMAIL', + 'KEY_SAVE', + 'KEY_DOCUMENTS', + 'KEY_BATTERY', + 'KEY_BLUETOOTH', + 'KEY_WLAN', + 'KEY_UWB', + 'KEY_UNKNOWN', + 'KEY_VIDEO_NEXT', + 'KEY_VIDEO_PREV', + 'KEY_BRIGHTNESS_CYCLE', + 'KEY_BRIGHTNESS_AUTO', + 'KEY_BRIGHTNESS_ZERO', + 'KEY_DISPLAY_OFF', + 'KEY_WIMAX', + 'KEY_WWAN', + 'KEY_RFKILL', + 'KEY_MICMUTE', + 'BTN_0', + 'BTN_MISC', + 'BTN_1', + 'BTN_2', + 'BTN_3', + 'BTN_4', + 'BTN_5', + 'BTN_6', + 'BTN_7', + 'BTN_8', + 'BTN_9', + 'BTN_LEFT', + 'BTN_MOUSE', + 'BTN_RIGHT', + 'BTN_MIDDLE', + 'BTN_SIDE', + 'BTN_EXTRA', + 'BTN_FORWARD', + 'BTN_BACK', + 'BTN_TASK', + 'BTN_JOYSTICK', + 'BTN_TRIGGER', + 'BTN_THUMB', + 'BTN_THUMB2', + 'BTN_TOP', + 'BTN_TOP2', + 'BTN_PINKIE', + 'BTN_BASE', + 'BTN_BASE2', + 'BTN_BASE3', + 'BTN_BASE4', + 'BTN_BASE5', + 'BTN_BASE6', + 'BTN_DEAD', + 'BTN_A', + 'BTN_GAMEPAD', + 'BTN_SOUTH', + 'BTN_B', + 'BTN_EAST', + 'BTN_C', + 'BTN_NORTH', + 'BTN_X', + 'BTN_WEST', + 'BTN_Y', + 'BTN_Z', + 'BTN_TL', + 'BTN_TR', + 'BTN_TL2', + 'BTN_TR2', + 'BTN_SELECT', + 'BTN_START', + 'BTN_MODE', + 'BTN_THUMBL', + 'BTN_THUMBR', + 'BTN_DIGI', + 'BTN_TOOL_PEN', + 'BTN_TOOL_RUBBER', + 'BTN_TOOL_BRUSH', + 'BTN_TOOL_PENCIL', + 'BTN_TOOL_AIRBRUSH', + 'BTN_TOOL_FINGER', + 'BTN_TOOL_MOUSE', + 'BTN_TOOL_LENS', + 'BTN_TOOL_QUINTTAP', + 'BTN_TOUCH', + 'BTN_STYLUS', + 'BTN_STYLUS2', + 'BTN_TOOL_DOUBLETAP', + 'BTN_TOOL_TRIPLETAP', + 'BTN_TOOL_QUADTAP', + 'BTN_GEAR_DOWN', + 'BTN_WHEEL', + 'BTN_GEAR_UP', + 'KEY_OK', + 'KEY_SELECT', + 'KEY_GOTO', + 'KEY_CLEAR', + 'KEY_POWER2', + 'KEY_OPTION', + 'KEY_INFO', + 'KEY_TIME', + 'KEY_VENDOR', + 'KEY_ARCHIVE', + 'KEY_PROGRAM', + 'KEY_CHANNEL', + 'KEY_FAVORITES', + 'KEY_EPG', + 'KEY_PVR', + 'KEY_MHP', + 'KEY_LANGUAGE', + 'KEY_TITLE', + 'KEY_SUBTITLE', + 'KEY_ANGLE', + 'KEY_ZOOM', + 'KEY_MODE', + 'KEY_KEYBOARD', + 'KEY_SCREEN', + 'KEY_PC', + 'KEY_TV', + 'KEY_TV2', + 'KEY_VCR', + 'KEY_VCR2', + 'KEY_SAT', + 'KEY_SAT2', + 'KEY_CD', + 'KEY_TAPE', + 'KEY_RADIO', + 'KEY_TUNER', + 'KEY_PLAYER', + 'KEY_TEXT', + 'KEY_DVD', + 'KEY_AUX', + 'KEY_MP3', + 'KEY_AUDIO', + 'KEY_VIDEO', + 'KEY_DIRECTORY', + 'KEY_LIST', + 'KEY_MEMO', + 'KEY_CALENDAR', + 'KEY_RED', + 'KEY_GREEN', + 'KEY_YELLOW', + 'KEY_BLUE', + 'KEY_CHANNELUP', + 'KEY_CHANNELDOWN', + 'KEY_FIRST', + 'KEY_LAST', + 'KEY_AB', + 'KEY_NEXT', + 'KEY_RESTART', + 'KEY_SLOW', + 'KEY_SHUFFLE', + 'KEY_BREAK', + 'KEY_PREVIOUS', + 'KEY_DIGITS', + 'KEY_TEEN', + 'KEY_TWEN', + 'KEY_VIDEOPHONE', + 'KEY_GAMES', + 'KEY_ZOOMIN', + 'KEY_ZOOMOUT', + 'KEY_ZOOMRESET', + 'KEY_WORDPROCESSOR', + 'KEY_EDITOR', + 'KEY_SPREADSHEET', + 'KEY_GRAPHICSEDITOR', + 'KEY_PRESENTATION', + 'KEY_DATABASE', + 'KEY_NEWS', + 'KEY_VOICEMAIL', + 'KEY_ADDRESSBOOK', + 'KEY_MESSENGER', + 'KEY_BRIGHTNESS_TOGGLE', + 'KEY_DISPLAYTOGGLE', + 'KEY_SPELLCHECK', + 'KEY_LOGOFF', + 'KEY_DOLLAR', + 'KEY_EURO', + 'KEY_FRAMEBACK', + 'KEY_FRAMEFORWARD', + 'KEY_CONTEXT_MENU', + 'KEY_MEDIA_REPEAT', + 'KEY_10CHANNELSUP', + 'KEY_10CHANNELSDOWN', + 'KEY_IMAGES', + 'KEY_DEL_EOL', + 'KEY_DEL_EOS', + 'KEY_INS_LINE', + 'KEY_DEL_LINE', + 'KEY_FN', + 'KEY_FN_ESC', + 'KEY_FN_F1', + 'KEY_FN_F2', + 'KEY_FN_F3', + 'KEY_FN_F4', + 'KEY_FN_F5', + 'KEY_FN_F6', + 'KEY_FN_F7', + 'KEY_FN_F8', + 'KEY_FN_F9', + 'KEY_FN_F10', + 'KEY_FN_F11', + 'KEY_FN_F12', + 'KEY_FN_1', + 'KEY_FN_2', + 'KEY_FN_D', + 'KEY_FN_E', + 'KEY_FN_F', + 'KEY_FN_S', + 'KEY_FN_B', + 'KEY_BRL_DOT1', + 'KEY_BRL_DOT2', + 'KEY_BRL_DOT3', + 'KEY_BRL_DOT4', + 'KEY_BRL_DOT5', + 'KEY_BRL_DOT6', + 'KEY_BRL_DOT7', + 'KEY_BRL_DOT8', + 'KEY_BRL_DOT9', + 'KEY_BRL_DOT10', + 'KEY_NUMERIC_0', + 'KEY_NUMERIC_1', + 'KEY_NUMERIC_2', + 'KEY_NUMERIC_3', + 'KEY_NUMERIC_4', + 'KEY_NUMERIC_5', + 'KEY_NUMERIC_6', + 'KEY_NUMERIC_7', + 'KEY_NUMERIC_8', + 'KEY_NUMERIC_9', + 'KEY_NUMERIC_STAR', + 'KEY_NUMERIC_POUND', + 'KEY_NUMERIC_A', + 'KEY_NUMERIC_B', + 'KEY_NUMERIC_C', + 'KEY_NUMERIC_D', + 'KEY_CAMERA_FOCUS', + 'KEY_WPS_BUTTON', + 'KEY_TOUCHPAD_TOGGLE', + 'KEY_TOUCHPAD_ON', + 'KEY_TOUCHPAD_OFF', + 'KEY_CAMERA_ZOOMIN', + 'KEY_CAMERA_ZOOMOUT', + 'KEY_CAMERA_UP', + 'KEY_CAMERA_DOWN', + 'KEY_CAMERA_LEFT', + 'KEY_CAMERA_RIGHT', + 'KEY_ATTENDANT_ON', + 'KEY_ATTENDANT_OFF', + 'KEY_ATTENDANT_TOGGLE', + 'KEY_LIGHTS_TOGGLE', + 'BTN_DPAD_UP', + 'BTN_DPAD_DOWN', + 'BTN_DPAD_LEFT', + 'BTN_DPAD_RIGHT', + 'KEY_ALS_TOGGLE', + 'KEY_BUTTONCONFIG', + 'KEY_TASKMANAGER', + 'KEY_JOURNAL', + 'KEY_CONTROLPANEL', + 'KEY_APPSELECT', + 'KEY_SCREENSAVER', + 'KEY_VOICECOMMAND', + 'KEY_BRIGHTNESS_MIN', + 'KEY_BRIGHTNESS_MAX', + 'KEY_KBDINPUTASSIST_PREV', + 'KEY_KBDINPUTASSIST_NEXT', + 'KEY_KBDINPUTASSIST_PREVGROUP', + 'KEY_KBDINPUTASSIST_NEXTGROUP', + 'KEY_KBDINPUTASSIST_ACCEPT', + 'KEY_KBDINPUTASSIST_CANCEL', + 'KEY_RIGHT_UP', + 'KEY_RIGHT_DOWN', + 'KEY_LEFT_UP', + 'KEY_LEFT_DOWN', + 'KEY_ROOT_MENU', + 'KEY_MEDIA_TOP_MENU', + 'KEY_NUMERIC_11', + 'KEY_NUMERIC_12', + 'KEY_AUDIO_DESC', + 'KEY_3D_MODE', + 'KEY_NEXT_FAVORITE', + 'KEY_STOP_RECORD', + 'KEY_PAUSE_RECORD', + 'KEY_VOD', + 'KEY_UNMUTE', + 'KEY_DATA', + 'KEY_FASTREVERSE', + 'KEY_SLOWREVERSE', + 'BTN_TRIGGER_HAPPY', + 'BTN_TRIGGER_HAPPY1', + 'BTN_TRIGGER_HAPPY2', + 'BTN_TRIGGER_HAPPY3', + 'BTN_TRIGGER_HAPPY4', + 'BTN_TRIGGER_HAPPY5', + 'BTN_TRIGGER_HAPPY6', + 'BTN_TRIGGER_HAPPY7', + 'BTN_TRIGGER_HAPPY8', + 'BTN_TRIGGER_HAPPY9', + 'BTN_TRIGGER_HAPPY10', + 'BTN_TRIGGER_HAPPY11', + 'BTN_TRIGGER_HAPPY12', + 'BTN_TRIGGER_HAPPY13', + 'BTN_TRIGGER_HAPPY14', + 'BTN_TRIGGER_HAPPY15', + 'BTN_TRIGGER_HAPPY16', + 'BTN_TRIGGER_HAPPY17', + 'BTN_TRIGGER_HAPPY18', + 'BTN_TRIGGER_HAPPY19', + 'BTN_TRIGGER_HAPPY20', + 'BTN_TRIGGER_HAPPY21', + 'BTN_TRIGGER_HAPPY22', + 'BTN_TRIGGER_HAPPY23', + 'BTN_TRIGGER_HAPPY24', + 'BTN_TRIGGER_HAPPY25', + 'BTN_TRIGGER_HAPPY26', + 'BTN_TRIGGER_HAPPY27', + 'BTN_TRIGGER_HAPPY28', + 'BTN_TRIGGER_HAPPY29', + 'BTN_TRIGGER_HAPPY30', + 'BTN_TRIGGER_HAPPY31', + 'BTN_TRIGGER_HAPPY32', + 'BTN_TRIGGER_HAPPY33', + 'BTN_TRIGGER_HAPPY34', + 'BTN_TRIGGER_HAPPY35', + 'BTN_TRIGGER_HAPPY36', + 'BTN_TRIGGER_HAPPY37', + 'BTN_TRIGGER_HAPPY38', + 'BTN_TRIGGER_HAPPY39', + 'BTN_TRIGGER_HAPPY40', + 'KEY_FENRIR', + 'KEY_SCRIPT', + 'KEY_ALT', + 'KEY_CTRL', + 'KEY_META', + 'KEY_SHIFT'] diff --git a/src/fenrirscreenreader/core/inputDriver.py b/src/fenrirscreenreader/core/inputDriver.py index 9f9c5460..99abf814 100644 --- a/src/fenrirscreenreader/core/inputDriver.py +++ b/src/fenrirscreenreader/core/inputDriver.py @@ -4,77 +4,93 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +import time from fenrirscreenreader.core import debug -class inputDriver(): + +class InputDriver(): def __init__(self): self._initialized = False + def initialize(self, environment): self.env = environment - self.env['runtime']['inputManager'].setShortcutType('KEY') - self._isInitialized = True + self.env['runtime']['InputManager'].set_shortcut_type('KEY') + self._is_initialized = True + def shutdown(self): if self._initialized: - self.removeAllDevices() - self._isInitialized = False - def getInputEvent(self): + self.remove_all_devices() + self._is_initialized = False + + def get_input_event(self): time.sleep(0.1) return None - def clearEventBuffer(self): + + def clear_event_buffer(self): if not self._initialized: return del self.env['input']['eventBuffer'][:] - def updateInputDevices(self, newDevices = None, init = False): + + def update_input_devices(self, new_devices=None, init=False): if not self._initialized: return - def getLedState(self, led = 0): + + def get_led_state(self, led=0): if not self._initialized: return False return False - def toggleLedState(self, led = 0): + + def toggle_led_state(self, led=0): if not self._initialized: return - def grabAllDevices(self): - if not self._initialized: - return True - return True - def ungrabAllDevices(self): + + def grab_all_devices(self): if not self._initialized: return True return True - def forceUngrab(self): + def ungrab_all_devices(self): + if not self._initialized: + return True + return True + + def force_ungrab(self): """Emergency method to release grabbed devices in case of failure""" if not self._initialized: return True try: # Try standard ungrab first - return self.ungrabAllDevices() + return self.ungrab_all_devices() except Exception as e: # Just log the failure and inform the user - if hasattr(self, 'env') and 'runtime' in self.env and 'debug' in self.env['runtime']: - self.env['runtime']['debug'].writeDebugOut( - f"Emergency device release failed: {str(e)}", - debug.debugLevel.ERROR + if hasattr( + self, + 'env') and 'runtime' in self.env and 'DebugManager' in self.env['runtime']: + self.env['runtime']['DebugManager'].write_debug_out( + f"Emergency device release failed: {str(e)}", + debug.DebugLevel.ERROR ) else: print(f"Emergency device release failed: {str(e)}") return False - def hasIDevices(self): + def has_i_devices(self): if not self._initialized: return False return True - def removeAllDevices(self): + + def remove_all_devices(self): if not self._initialized: return - def sendKey(self): + + def send_key(self): if not self._initialized: return + def __del__(self): if not self._initialized: return try: - self.removeAllDevices() + self.remove_all_devices() except Exception as e: - print(f'inputDriver __del__: Error removing devices: {str(e)}') + print(f'InputDriver __del__: Error removing devices: {str(e)}') diff --git a/src/fenrirscreenreader/core/inputManager.py b/src/fenrirscreenreader/core/inputManager.py index fef1e300..f32a8227 100644 --- a/src/fenrirscreenreader/core/inputManager.py +++ b/src/fenrirscreenreader/core/inputManager.py @@ -5,96 +5,127 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ from fenrirscreenreader.core import inputData -import os, inspect, time, traceback -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) +import os +import inspect +import time +import traceback +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) -class inputManager(): + +class InputManager(): def __init__(self): self.shortcutType = 'KEY' self.executeDeviceGrab = False self.lastDetectedDevices = None - def setShortcutType(self, shortcutType = 'KEY'): + + def set_shortcut_type(self, shortcutType='KEY'): if shortcutType in ['KEY', 'BYTE']: self.shortcutType = shortcutType - def getShortcutType(self): + + def get_shortcut_type(self): return self.shortcutType + def initialize(self, environment): self.env = environment - self.env['runtime']['settingsManager'].loadDriver(\ - self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver') - self.updateInputDevices() + self.env['runtime']['SettingsManager'].load_driver( + self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'driver'), 'InputDriver') + self.update_input_devices() # init LEDs with current state - self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState() + self.env['input']['newNumLock'] = self.env['runtime']['InputDriver'].get_led_state() self.env['input']['oldNumLock'] = self.env['input']['newNumLock'] - self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1) + self.env['input']['newCapsLock'] = self.env['runtime']['InputDriver'].get_led_state( + 1) self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] - self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2) + self.env['input']['newScrollLock'] = self.env['runtime']['InputDriver'].get_led_state( + 2) self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] self.lastDeepestInput = [] self.lastEvent = None - self.env['input']['shortcutRepeat'] = 1 + self.env['input']['shortcut_repeat'] = 1 self.lastInputTime = time.time() + def shutdown(self): - self.removeAllDevices() - self.env['runtime']['settingsManager'].shutdownDriver('inputDriver') - def getInputEvent(self): - event = None + self.remove_all_devices() + self.env['runtime']['SettingsManager'].shutdown_driver('InputDriver') + + def get_input_event(self): + event = None try: - event = self.env['runtime']['inputDriver'].getInputEvent() + event = self.env['runtime']['InputDriver'].get_input_event() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager getInputEvent: Error getting input event: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager get_input_event: Error getting input event: ' + str(e), + debug.DebugLevel.ERROR) return event - def setExecuteDeviceGrab(self, newExecuteDeviceGrab = True): + + def set_execute_device_grab(self, newExecuteDeviceGrab=True): self.executeDeviceGrab = newExecuteDeviceGrab - def handleDeviceGrab(self, force = False): + def handle_device_grab(self, force=False): if force: - self.setExecuteDeviceGrab() + self.set_execute_device_grab() if not self.executeDeviceGrab: return if self.env['input']['eventBuffer'] != []: return - if not self.noKeyPressed(): + if not self.no_key_pressed(): return - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): self.executeDeviceGrab = False return # Add maximum retries to prevent infinite loops - maxRetries = 5 - retryCount = 0 - grabTimeout = 3 # Timeout in seconds - startTime = time.time() + max_retries = 5 + retry_count = 0 + grab_timeout = 3 # Timeout in seconds + start_time = time.time() - if self.env['runtime']['screenManager'].getCurrScreenIgnored(): - while not self.ungrabAllDevices(): - retryCount += 1 - if retryCount >= maxRetries or (time.time() - startTime) > grabTimeout: - self.env['runtime']['debug'].writeDebugOut("Failed to ungrab devices after multiple attempts", debug.debugLevel.ERROR) - # Force a release of devices if possible through alternative means + if self.env['runtime']['ScreenManager'].get_curr_screen_ignored(): + while not self.ungrab_all_devices(): + retry_count += 1 + if retry_count >= max_retries or ( + time.time() - start_time) > grab_timeout: + self.env['runtime']['DebugManager'].write_debug_out( + "Failed to ungrab devices after multiple attempts", debug.DebugLevel.ERROR) + # Force a release of devices if possible through + # alternative means try: - self.env['runtime']['inputDriver'].forceUngrab() + self.env['runtime']['InputDriver'].force_ungrab() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager handleDeviceGrab: Error forcing ungrab: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager handle_device_grab: Error forcing ungrab: ' + str(e), + debug.DebugLevel.ERROR) break time.sleep(0.25) - self.env['runtime']['debug'].writeDebugOut(f"retry ungrabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + f"retry ungrab_all_devices {retry_count}/{max_retries}", debug.DebugLevel.WARNING) else: - while not self.grabAllDevices(): - retryCount += 1 - if retryCount >= maxRetries or (time.time() - startTime) > grabTimeout: - self.env['runtime']['debug'].writeDebugOut("Failed to grab devices after multiple attempts", debug.debugLevel.ERROR) - # Continue without grabbing input - limited functionality but not locked + while not self.grab_all_devices(): + retry_count += 1 + if retry_count >= max_retries or ( + time.time() - start_time) > grab_timeout: + self.env['runtime']['DebugManager'].write_debug_out( + "Failed to grab devices after multiple attempts", debug.DebugLevel.ERROR) + # Continue without grabbing input - limited functionality + # but not locked break time.sleep(0.25) - self.env['runtime']['debug'].writeDebugOut(f"retry grabAllDevices {retryCount}/{maxRetries}", debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + f"retry grab_all_devices {retry_count}/{max_retries}", debug.DebugLevel.WARNING) self.executeDeviceGrab = False - def sendKeys(self, keyMacro): + def send_keys(self, keyMacro): for e in keyMacro: key = '' value = 0 @@ -111,313 +142,398 @@ class inputManager(): if key.upper() == 'SLEEP': time.sleep(value) else: - self.env['runtime']['inputDriver'].sendKey(key, value) - def getLastEvent(self): + self.env['runtime']['InputDriver'].send_key(key, value) + + def get_last_event(self): return self.lastEvent - def handleInputEvent(self, eventData): - if not eventData: + + def handle_input_event(self, event_data): + if not event_data: return - self.lastEvent = eventData + self.lastEvent = event_data # a hang apears.. try to fix if self.env['input']['eventBuffer'] == []: if self.env['input']['currInput'] != []: self.env['input']['currInput'] = [] - self.env['input']['shortcutRepeat'] = 1 + self.env['input']['shortcut_repeat'] = 1 self.env['input']['prevInput'] = self.env['input']['currInput'].copy() - if eventData['EventState'] == 0: - if eventData['EventName'] in self.env['input']['currInput']: - self.env['input']['currInput'].remove(eventData['EventName']) + if event_data['EventState'] == 0: + if event_data['EventName'] in self.env['input']['currInput']: + self.env['input']['currInput'].remove(event_data['EventName']) if len(self.env['input']['currInput']) > 1: - self.env['input']['currInput'] = sorted(self.env['input']['currInput']) + self.env['input']['currInput'] = sorted( + self.env['input']['currInput']) elif len(self.env['input']['currInput']) == 0: - self.env['input']['shortcutRepeat'] = 1 + self.env['input']['shortcut_repeat'] = 1 self.lastInputTime = time.time() - elif eventData['EventState'] == 1: - if not eventData['EventName'] in self.env['input']['currInput']: - self.env['input']['currInput'].append(eventData['EventName']) + elif event_data['EventState'] == 1: + if not event_data['EventName'] in self.env['input']['currInput']: + self.env['input']['currInput'].append(event_data['EventName']) if len(self.env['input']['currInput']) > 1: - self.env['input']['currInput'] = sorted(self.env['input']['currInput']) - if len(self.lastDeepestInput) < len(self.env['input']['currInput']): - self.setLastDeepestInput( self.env['input']['currInput'].copy()) + self.env['input']['currInput'] = sorted( + self.env['input']['currInput']) + if len( + self.lastDeepestInput) < len( + self.env['input']['currInput']): + self.set_last_deepest_input( + self.env['input']['currInput'].copy()) elif self.lastDeepestInput == self.env['input']['currInput']: - if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'): - self.env['input']['shortcutRepeat'] += 1 + if time.time() - self.lastInputTime <= self.env['runtime']['SettingsManager'].get_setting_as_float( + 'keyboard', 'doubleTapTimeout'): + self.env['input']['shortcut_repeat'] += 1 else: - self.env['input']['shortcutRepeat'] = 1 - self.handleLedStates(eventData) + self.env['input']['shortcut_repeat'] = 1 + self.handle_led_states(event_data) self.lastInputTime = time.time() - elif eventData['EventState'] == 2: - self.lastInputTime = time.time() + elif event_data['EventState'] == 2: + self.lastInputTime = time.time() self.env['input']['oldNumLock'] = self.env['input']['newNumLock'] - self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState() - self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] - self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1) - self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] - self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2) - self.env['runtime']['debug'].writeDebugOut("currInput " + str(self.env['input']['currInput'] ) ,debug.debugLevel.INFO) - if self.noKeyPressed(): + self.env['input']['newNumLock'] = self.env['runtime']['InputDriver'].get_led_state() + self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock'] + self.env['input']['newCapsLock'] = self.env['runtime']['InputDriver'].get_led_state( + 1) + self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock'] + self.env['input']['newScrollLock'] = self.env['runtime']['InputDriver'].get_led_state( + 2) + self.env['runtime']['DebugManager'].write_debug_out( + "currInput " + str(self.env['input']['currInput']), debug.DebugLevel.INFO) + if self.no_key_pressed(): self.env['input']['prevInput'] = [] - def handleLedStates(self, mEvent): - if self.currKeyIsModifier(): + def handle_led_states(self, m_event): + if self.curr_key_is_modifier(): return try: - if mEvent['EventName'] == 'KEY_NUMLOCK': - self.env['runtime']['inputDriver'].toggleLedState() - elif mEvent['EventName'] == 'KEY_CAPSLOCK': - self.env['runtime']['inputDriver'].toggleLedState(1) - elif mEvent['EventName'] == 'KEY_SCROLLLOCK': - self.env['runtime']['inputDriver'].toggleLedState(2) + if m_event['EventName'] == 'KEY_NUMLOCK': + self.env['runtime']['InputDriver'].toggle_led_state() + elif m_event['EventName'] == 'KEY_CAPSLOCK': + self.env['runtime']['InputDriver'].toggle_led_state(1) + elif m_event['EventName'] == 'KEY_SCROLLLOCK': + self.env['runtime']['InputDriver'].toggle_led_state(2) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager handleLedStates: Error toggling LED state: ' + str(e), debug.debugLevel.ERROR) - def grabAllDevices(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager handle_led_states: Error toggling LED state: ' + str(e), + debug.DebugLevel.ERROR) + + def grab_all_devices(self): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): try: - return self.env['runtime']['inputDriver'].grabAllDevices() + return self.env['runtime']['InputDriver'].grab_all_devices() except Exception as e: return False return True - def ungrabAllDevices(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + + def ungrab_all_devices(self): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): try: - return self.env['runtime']['inputDriver'].ungrabAllDevices() + return self.env['runtime']['InputDriver'].ungrab_all_devices() except Exception as e: return False return True - def handlePlugInputDevice(self, eventData): - for deviceEntry in eventData: - self.updateInputDevices(deviceEntry['device']) - def updateInputDevices(self, newDevice = None): - try: - self.env['runtime']['inputDriver'].updateInputDevices(newDevice) - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager updateInputDevices: Error updating input devices: ' + str(e), debug.debugLevel.ERROR) - try: - if self.env['runtime']['screenManager']: - self.handleDeviceGrab(force = True) - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager updateInputDevices: Error handling device grab: ' + str(e), debug.debugLevel.ERROR) - def removeAllDevices(self): - try: - self.env['runtime']['inputDriver'].removeAllDevices() - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('inputManager removeAllDevices: Error removing devices: ' + str(e), debug.debugLevel.ERROR) - def convertEventName(self, eventName): - if not eventName: - return '' - if eventName == '': - return '' - eventName = eventName.upper() - if eventName == 'KEY_LEFTCTRL': - eventName = 'KEY_CTRL' - elif eventName == 'KEY_RIGHTCTRL': - eventName = 'KEY_CTRL' - elif eventName == 'KEY_LEFTSHIFT': - eventName = 'KEY_SHIFT' - elif eventName == 'KEY_RIGHTSHIFT': - eventName = 'KEY_SHIFT' - elif eventName == 'KEY_LEFTALT': - eventName = 'KEY_ALT' - elif eventName == 'KEY_RIGHTALT': - eventName = 'KEY_ALT' - elif eventName == 'KEY_LEFTMETA': - eventName = 'KEY_META' - elif eventName == 'KEY_RIGHTMETA': - eventName = 'KEY_META' - if self.isFenrirKey(eventName): - eventName = 'KEY_FENRIR' - if self.isScriptKey(eventName): - eventName = 'KEY_SCRIPT' - return eventName + def handle_plug_input_device(self, event_data): + for deviceEntry in event_data: + self.update_input_devices(deviceEntry['device']) - def clearEventBuffer(self): + def update_input_devices(self, newDevice=None): try: - self.env['runtime']['inputDriver'].clearEventBuffer() + self.env['runtime']['InputDriver'].update_input_devices(newDevice) + except Exception as e: + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager update_input_devices: Error updating input devices: ' + str(e), + debug.DebugLevel.ERROR) + try: + if self.env['runtime']['ScreenManager']: + self.handle_device_grab(force=True) + except Exception as e: + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager update_input_devices: Error handling device grab: ' + str(e), + debug.DebugLevel.ERROR) + + def remove_all_devices(self): + try: + self.env['runtime']['InputDriver'].remove_all_devices() + except Exception as e: + self.env['runtime']['DebugManager'].write_debug_out( + 'InputManager remove_all_devices: Error removing devices: ' + str(e), + debug.DebugLevel.ERROR) + + def convert_event_name(self, event_name): + if not event_name: + return '' + if event_name == '': + return '' + event_name = event_name.upper() + if event_name == 'KEY_LEFTCTRL': + event_name = 'KEY_CTRL' + elif event_name == 'KEY_RIGHTCTRL': + event_name = 'KEY_CTRL' + elif event_name == 'KEY_LEFTSHIFT': + event_name = 'KEY_SHIFT' + elif event_name == 'KEY_RIGHTSHIFT': + event_name = 'KEY_SHIFT' + elif event_name == 'KEY_LEFTALT': + event_name = 'KEY_ALT' + elif event_name == 'KEY_RIGHTALT': + event_name = 'KEY_ALT' + elif event_name == 'KEY_LEFTMETA': + event_name = 'KEY_META' + elif event_name == 'KEY_RIGHTMETA': + event_name = 'KEY_META' + if self.is_fenrir_key(event_name): + event_name = 'KEY_FENRIR' + if self.is_script_key(event_name): + event_name = 'KEY_SCRIPT' + return event_name + + def clear_event_buffer(self): + try: + self.env['runtime']['InputDriver'].clear_event_buffer() except Exception as e: pass - def setLastDeepestInput(self, currentDeepestInput): - self.lastDeepestInput = currentDeepestInput - def clearLastDeepInput(self): - self.lastDeepestInput = [] - def getLastInputTime(self): - return self.lastInputTime - def getLastDeepestInput(self): - return self.lastDeepestInput - def writeEventBuffer(self): - try: - if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): - self.env['runtime']['inputDriver'].writeEventBuffer() - self.clearEventBuffer() - except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Error while writeUInput",debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) - def noKeyPressed(self): + def set_last_deepest_input(self, currentDeepestInput): + self.lastDeepestInput = currentDeepestInput + + def clear_last_deep_input(self): + self.lastDeepestInput = [] + + def get_last_input_time(self): + return self.lastInputTime + + def get_last_deepest_input(self): + return self.lastDeepestInput + + def write_event_buffer(self): + try: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): + self.env['runtime']['InputDriver'].write_event_buffer() + self.clear_event_buffer() + except Exception as e: + self.env['runtime']['DebugManager'].write_debug_out( + "Error while write_u_input", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) + + def no_key_pressed(self): return self.env['input']['currInput'] == [] - def isKeyPress(self): - return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != []) - def getPrevDeepestShortcut(self): + + def is_key_press(self): + return ( + self.env['input']['prevInput'] == []) and ( + self.env['input']['currInput'] != []) + + def get_prev_deepest_shortcut(self): shortcut = [] - shortcut.append(self.env['input']['shortcutRepeat']) - shortcut.append(self.getLastDeepestInput()) + shortcut.append(self.env['input']['shortcut_repeat']) + shortcut.append(self.get_last_deepest_input()) return str(shortcut) - def getPrevShortcut(self): + def get_prev_shortcut(self): shortcut = [] - shortcut.append(self.env['input']['shortcutRepeat']) + shortcut.append(self.env['input']['shortcut_repeat']) shortcut.append(self.env['input']['prevInput']) return str(shortcut) - def getCurrShortcut(self, inputSequence = None): + def get_curr_shortcut(self, inputSequence=None): shortcut = [] - shortcut.append(self.env['input']['shortcutRepeat']) + shortcut.append(self.env['input']['shortcut_repeat']) - numpadKeys = ['KEY_KP0', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP4', - 'KEY_KP5', 'KEY_KP6', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9', - 'KEY_KPDOT', 'KEY_KPPLUS', 'KEY_KPMINUS', 'KEY_KPASTERISK', - 'KEY_KPSLASH', 'KEY_KPENTER', 'KEY_KPEQUAL'] + numpad_keys = [ + 'KEY_KP0', + 'KEY_KP1', + 'KEY_KP2', + 'KEY_KP3', + 'KEY_KP4', + 'KEY_KP5', + 'KEY_KP6', + 'KEY_KP7', + 'KEY_KP8', + 'KEY_KP9', + 'KEY_KPDOT', + 'KEY_KPPLUS', + 'KEY_KPMINUS', + 'KEY_KPASTERISK', + 'KEY_KPSLASH', + 'KEY_KPENTER', + 'KEY_KPEQUAL'] if inputSequence: # Check if any key in the sequence is a numpad key and numlock is ON - # If numlock is ON and any key in the sequence is a numpad key, return an empty shortcut - if not self.env['runtime']['cursorManager'].shouldProcessNumpadCommands(): + # If numlock is ON and any key in the sequence is a numpad key, + # return an empty shortcut + if not self.env['runtime']['CursorManager'].should_process_numpad_commands( + ): for key in inputSequence: - if key in numpadKeys: - # Return an empty/invalid shortcut that won't match any command + if key in numpad_keys: + # Return an empty/invalid shortcut that won't match any + # command return "[]" shortcut.append(inputSequence) else: # Same check for current input - if not self.env['runtime']['cursorManager'].shouldProcessNumpadCommands(): + if not self.env['runtime']['CursorManager'].should_process_numpad_commands( + ): for key in self.env['input']['currInput']: - if key in numpadKeys: - # Return an empty/invalid shortcut that won't match any command + if key in numpad_keys: + # Return an empty/invalid shortcut that won't match any + # command return "[]" shortcut.append(self.env['input']['currInput']) - if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']): - if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)): + if len( + self.env['input']['prevInput']) < len( + self.env['input']['currInput']): + if self.env['input']['shortcut_repeat'] > 1 and not self.shortcut_exists( + str(shortcut)): shortcut = [] - self.env['input']['shortcutRepeat'] = 1 - shortcut.append(self.env['input']['shortcutRepeat']) + self.env['input']['shortcut_repeat'] = 1 + shortcut.append(self.env['input']['shortcut_repeat']) shortcut.append(self.env['input']['currInput']) - self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut), debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "curr_shortcut " + str(shortcut), debug.DebugLevel.INFO) return str(shortcut) - def currKeyIsModifier(self): - if len(self.getLastDeepestInput()) != 1: + def curr_key_is_modifier(self): + if len(self.get_last_deepest_input()) != 1: return False - return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT') + return (self.env['input']['currInput'][0] == 'KEY_FENRIR') or ( + self.env['input']['currInput'][0] == 'KEY_SCRIPT') - def isFenrirKey(self, eventName): - return eventName in self.env['input']['fenrirKey'] + def is_fenrir_key(self, event_name): + return event_name in self.env['input']['fenrirKey'] - def isScriptKey(self, eventName): - return eventName in self.env['input']['scriptKey'] + def is_script_key(self, event_name): + return event_name in self.env['input']['scriptKey'] - def getCommandForShortcut(self, shortcut): - if not self.shortcutExists(shortcut): - return '' + def get_command_for_shortcut(self, shortcut): + if not self.shortcut_exists(shortcut): + return '' return self.env['bindings'][shortcut] - def keyEcho(self, eventData = None): - if not eventData: - eventData = self.getLastEvent() - if not eventData: - return - keyName = '' - if eventData['EventState'] == 1: - keyName = eventData['EventName'].lower() - if keyName.startswith('key_'): - keyName = keyName[4:] - self.env['runtime']['outputManager'].presentText(_(keyName), interrupt=True) - def shortcutExists(self, shortcut): - return(shortcut in self.env['bindings']) - def loadShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/desktop.conf'): - kbConfig = open(kbConfigPath,"r") - while(True): + def key_echo(self, event_data=None): + if not event_data: + event_data = self.get_last_event() + if not event_data: + return + key_name = '' + if event_data['EventState'] == 1: + key_name = event_data['EventName'].lower() + if key_name.startswith('key_'): + key_name = key_name[4:] + self.env['runtime']['OutputManager'].present_text( + _(key_name), interrupt=True) + + def shortcut_exists(self, shortcut): + return (shortcut in self.env['bindings']) + + def load_shortcuts(self, kb_config_path=fenrir_path + + '/../../config/keyboard/desktop.conf'): + kb_config = open(kb_config_path, "r") + while (True): invalid = False - line = kbConfig.readline() + line = kb_config.readline() if not line: break - line = line.replace('\n','') - if line.replace(" ","") == '': + line = line.replace('\n', '') + if line.replace(" ", "") == '': continue - if line.replace(" ","").startswith("#"): + if line.replace(" ", "").startswith("#"): continue if line.count("=") != 1: continue - sepLine = line.split('=') - commandName = sepLine[1].upper() - sepLine[0] = sepLine[0].replace(" ","") - sepLine[0] = sepLine[0].replace("'","") - sepLine[0] = sepLine[0].replace('"',"") - keys = sepLine[0].split(',') - shortcutKeys = [] - shortcutRepeat = 1 + sep_line = line.split('=') + command_name = sep_line[1].upper() + sep_line[0] = sep_line[0].replace(" ", "") + sep_line[0] = sep_line[0].replace("'", "") + sep_line[0] = sep_line[0].replace('"', "") + keys = sep_line[0].split(',') + shortcut_keys = [] + shortcut_repeat = 1 shortcut = [] for key in keys: try: - shortcutRepeat = int(key) + shortcut_repeat = int(key) except Exception as e: - if not self.isValidKey(key.upper()): - self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING) + if not self.is_valid_key(key.upper()): + self.env['runtime']['DebugManager'].write_debug_out( + "invalid key : " + key.upper() + ' command:' + command_name, + debug.DebugLevel.WARNING) invalid = True break - shortcutKeys.append(key.upper()) + shortcut_keys.append(key.upper()) if invalid: continue - shortcut.append(shortcutRepeat) - shortcut.append(sorted(shortcutKeys)) - if len(shortcutKeys) != 1 and not 'KEY_FENRIR' in shortcutKeys: - self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR) + shortcut.append(shortcut_repeat) + shortcut.append(sorted(shortcut_keys)) + if len(shortcut_keys) != 1 and 'KEY_FENRIR' not in shortcut_keys: + self.env['runtime']['DebugManager'].write_debug_out( + "invalid shortcut (missing KEY_FENRIR): " + + str(shortcut) + + ' command:' + + command_name, + debug.DebugLevel.ERROR) continue - self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True) - self.env['bindings'][str(shortcut)] = commandName + self.env['runtime']['DebugManager'].write_debug_out( + "Shortcut: " + + str(shortcut) + + ' command:' + + command_name, + debug.DebugLevel.INFO, + on_any_level=True) + self.env['bindings'][str(shortcut)] = command_name self.env['rawBindings'][str(shortcut)] = shortcut - kbConfig.close() - # fix bindings - self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE' - def isValidKey(self, key): - return key in inputData.keyNames - def setLastDetectedDevices(self, devices): - self.lastDetectedDevices =devices - def getLastDetectedDevices(self): + kb_config.close() + # fix bindings + self.env['bindings'][str( + [1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE' + + def is_valid_key(self, key): + return key in inputData.key_names + + def set_last_detected_devices(self, devices): + self.lastDetectedDevices = devices + + def get_last_detected_devices(self): return self.lastDetectedDevices - def reloadShortcuts(self): + + def reload_shortcuts(self): """Reload keyboard shortcuts from current layout setting""" # Clear existing bindings self.env['bindings'].clear() self.env['rawBindings'].clear() - + # Get current layout path - layout_setting = self.env['runtime']['settingsManager'].getSetting('keyboard', 'keyboardLayout') - + layout_setting = self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'keyboardLayout') + # Resolve full path if needed if not os.path.exists(layout_setting): - settingsRoot = '/etc/fenrirscreenreader/' - if not os.path.exists(settingsRoot): + settings_root = '/etc/fenrirscreenreader/' + if not os.path.exists(settings_root): import fenrirscreenreader - fenrirPath = os.path.dirname(fenrirscreenreader.__file__) - settingsRoot = fenrirPath + '/../../config/' - - layout_path = settingsRoot + 'keyboard/' + layout_setting + '.conf' + fenrir_path = os.path.dirname(fenrirscreenreader.__file__) + settings_root = fenrir_path + '/../../config/' + + layout_path = settings_root + 'keyboard/' + layout_setting + '.conf' if not os.path.exists(layout_path): # Fallback to default if layout not found - layout_path = settingsRoot + 'keyboard/desktop.conf' + layout_path = settings_root + 'keyboard/desktop.conf' else: layout_path = layout_setting - + # Reload shortcuts - self.loadShortcuts(layout_path) - - self.env['runtime']['debug'].writeDebugOut( - "Reloaded shortcuts from: " + layout_path, - debug.debugLevel.INFO, - onAnyLevel=True + self.load_shortcuts(layout_path) + + self.env['runtime']['DebugManager'].write_debug_out( + "Reloaded shortcuts from: " + layout_path, + debug.DebugLevel.INFO, + on_any_level=True ) diff --git a/src/fenrirscreenreader/core/memoryManager.py b/src/fenrirscreenreader/core/memoryManager.py index b6c21f5e..a53d74e7 100644 --- a/src/fenrirscreenreader/core/memoryManager.py +++ b/src/fenrirscreenreader/core/memoryManager.py @@ -7,120 +7,151 @@ import time from fenrirscreenreader.core import debug -class memoryManager(): + +class MemoryManager(): def __init__(self): self.listStorage = {} + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def listStorageValid(self,name, checkIndex = False): + + def list_storage_valid(self, name, checkIndex=False): try: if checkIndex: index = self.listStorage[name]['index'] if index == -1: - return self.listStorage[name]['list'] == [] - return self.listStorage[name]['list'][index] != None + return self.listStorage[name]['list'] == [] + return self.listStorage[name]['list'][index] is not None else: - return isinstance(self.listStorage[name]['list'],list) + return isinstance(self.listStorage[name]['list'], list) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("listStorageValid " + str(e),debug.debugLevel.ERROR) - return False - def addValueToFirstIndex(self, name, value): - if not self.listStorageValid(name): + self.env['runtime']['DebugManager'].write_debug_out( + "list_storage_valid " + str(e), debug.DebugLevel.ERROR) + return False + + def add_value_to_first_index(self, name, value): + if not self.list_storage_valid(name): return - if self.listStorage[name]['maxLength'] == None: + if self.listStorage[name]['maxLength'] is None: # Fallback: if maxLength is still None, apply default limit of 1000 - self.listStorage[name]['list'] = [value] + self.listStorage[name]['list'][:999] - else: - self.listStorage[name]['list'] = [value] + self.listStorage[name]['list'][:self.listStorage[name]['maxLength'] -1] + self.listStorage[name]['list'] = [value] + \ + self.listStorage[name]['list'][:999] + else: + self.listStorage[name]['list'] = [ + value] + self.listStorage[name]['list'][:self.listStorage[name]['maxLength'] - 1] self.listStorage[name]['index'] = 0 - def addIndexList(self, name, maxLength = 1000, currList = [], currIndex = -1): - if len(currList) != 0 and (currIndex == -1): - currIndex = 0 - self.listStorage[name] = {'list': currList, 'index': currIndex, 'maxLength': maxLength} - def isLastIndex(self, name): - if not self.listStorageValid(name): - return False - return self.listStorage[name]['index'] == len(self.listStorage[name]['list']) - 1 - def isFirstIndex(self, name): - if not self.listStorageValid(name): - return False - return self.listStorage[name]['index'] == 0 - def getNextIndex(self, name): - if not self.listStorageValid(name): - return False - if self.isIndexListEmpty(name): + + def add_index_list(self, name, maxLength=1000, currList=[], curr_index=-1): + if len(currList) != 0 and (curr_index == -1): + curr_index = 0 + self.listStorage[name] = { + 'list': currList, + 'index': curr_index, + 'maxLength': maxLength} + + def is_last_index(self, name): + if not self.list_storage_valid(name): + return False + return self.listStorage[name]['index'] == len( + self.listStorage[name]['list']) - 1 + + def is_first_index(self, name): + if not self.list_storage_valid(name): + return False + return self.listStorage[name]['index'] == 0 + + def get_next_index(self, name): + if not self.list_storage_valid(name): + return False + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 return False self.listStorage[name]['index'] += 1 - if self.listStorage[name]['index'] > len(self.listStorage[name]['list']) -1: + if self.listStorage[name]['index'] > len( + self.listStorage[name]['list']) - 1: self.listStorage[name]['index'] = 0 - return True - def setPrefIndex(self, name): - if not self.listStorageValid(name): - return False - if self.isIndexListEmpty(name): + return True + + def set_pref_index(self, name): + if not self.list_storage_valid(name): + return False + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 return False self.listStorage[name]['index'] -= 1 if self.listStorage[name]['index'] < 0: - self.listStorage[name]['index'] = len(self.listStorage[name]['list']) -1 + self.listStorage[name]['index'] = len( + self.listStorage[name]['list']) - 1 return True - def setFirstIndex(self, name): - if not self.listStorageValid(name): - return False - if self.isIndexListEmpty(name): + + def set_first_index(self, name): + if not self.list_storage_valid(name): + return False + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 return False self.listStorage[name]['index'] = 0 return True - def getIndexListLen(self, name): - if not self.listStorageValid(name): - return 0 - if self.isIndexListEmpty(name): + + def get_index_list_len(self, name): + if not self.list_storage_valid(name): + return 0 + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 - return 0 + return 0 return len(self.listStorage[name]) - def setLastIndex(self, name): - if not self.listStorageValid(name): - return False - if self.isIndexListEmpty(name): + + def set_last_index(self, name): + if not self.list_storage_valid(name): + return False + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 return False - self.listStorage[name]['index'] = len(self.listStorage[name]['list']) -1 - return True - def clearCurrentIndexList(self, name): - if not self.listStorageValid(name): - return False + self.listStorage[name]['index'] = len( + self.listStorage[name]['list']) - 1 + return True + + def clear_current_index_list(self, name): + if not self.list_storage_valid(name): + return False self.listStorage[name]['list'] = [] self.listStorage[name]['index'] = -1 - def getCurrentIndex(self,name): - if not self.listStorageValid(name): - return False - if self.isIndexListEmpty(name): + + def get_current_index(self, name): + if not self.list_storage_valid(name): + return False + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 - return False - try: - return self.listStorage[name]['index'] + return False + try: + return self.listStorage[name]['index'] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('memoryManager getCurrentIndex: Error accessing index for ' + name + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'MemoryManager get_current_index: Error accessing index for ' + name + ': ' + str(e), + debug.DebugLevel.ERROR) return -1 - def isIndexListEmpty(self, name): - if not self.listStorageValid(name): - return False + + def is_index_list_empty(self, name): + if not self.list_storage_valid(name): + return False return len(self.listStorage[name]['list']) == 0 - def getIndexListElement(self, name): - if not self.listStorageValid(name): - return None - if self.isIndexListEmpty(name): + + def get_index_list_element(self, name): + if not self.list_storage_valid(name): + return None + if self.is_index_list_empty(name): self.listStorage[name]['index'] = -1 - return None - currIndex = self.getCurrentIndex(name) - if currIndex == -1: return None - try: - return self.listStorage[name]['list'][currIndex] + curr_index = self.get_current_index(name) + if curr_index == -1: + return None + try: + return self.listStorage[name]['list'][curr_index] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('memoryManager getIndexListElement: Error accessing element for ' + name + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'MemoryManager get_index_list_element: Error accessing element for ' + name + ': ' + str(e), + debug.DebugLevel.ERROR) return None diff --git a/src/fenrirscreenreader/core/outputData.py b/src/fenrirscreenreader/core/outputData.py index ca1729f6..6411d3cd 100644 --- a/src/fenrirscreenreader/core/outputData.py +++ b/src/fenrirscreenreader/core/outputData.py @@ -7,9 +7,9 @@ import time from fenrirscreenreader.core import debug -outputData = { -'nextFlush': time.time(), -'messageText': '', -'messageOffset': None, -'cursorOffset': None, +output_data = { + 'nextFlush': time.time(), + 'messageText': '', + 'messageOffset': None, + 'cursorOffset': None, } diff --git a/src/fenrirscreenreader/core/outputManager.py b/src/fenrirscreenreader/core/outputManager.py index 87a9868c..a17735c6 100644 --- a/src/fenrirscreenreader/core/outputManager.py +++ b/src/fenrirscreenreader/core/outputManager.py @@ -5,203 +5,304 @@ # By Chrys, Storm Dragon, and contributors. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ from fenrirscreenreader.utils import line_utils -import string, time, re +import string +import time +import re -class outputManager(): + +class OutputManager(): def __init__(self): - self.lastEcho = '' + self.last_echo = '' def initialize(self, environment): self.env = environment - self.env['runtime']['settingsManager'].loadDriver( - self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver') - self.env['runtime']['settingsManager'].loadDriver( - self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver') + self.env['runtime']['SettingsManager'].load_driver( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'driver'), 'SpeechDriver') + self.env['runtime']['SettingsManager'].load_driver( + self.env['runtime']['SettingsManager'].get_setting( + 'sound', 'driver'), 'SoundDriver') def shutdown(self): - self.env['runtime']['settingsManager'].shutdownDriver('soundDriver') - self.env['runtime']['settingsManager'].shutdownDriver('speechDriver') + self.env['runtime']['SettingsManager'].shutdown_driver('SoundDriver') + self.env['runtime']['SettingsManager'].shutdown_driver('SpeechDriver') - def presentText(self, text, interrupt=True, soundIcon='', ignorePunctuation=False, announceCapital=False, flush=True): + def present_text( + self, + text, + interrupt=True, + sound_icon ='', + ignore_punctuation=False, + announce_capital=False, + flush=True): if text == '': return - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'readNumbersAsDigits') and len(text.strip()) > 1: + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'readNumbersAsDigits') and len(text.strip()) > 1: text = re.sub(r"(\d)", r"\1 ", text).rstrip() - self.env['runtime']['debug'].writeDebugOut("presentText:\nsoundIcon:'"+soundIcon+"'\nText:\n" + text, debug.debugLevel.INFO) - if self.playSoundIcon(soundIcon, interrupt): - self.env['runtime']['debug'].writeDebugOut("soundIcon found", debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "present_text:\nsoundIcon:'" + + sound_icon + + "'\nText:\n" + + text, + debug.DebugLevel.INFO) + if self.play_sound_icon(sound_icon, interrupt): + self.env['runtime']['DebugManager'].write_debug_out( + "sound_icon found", debug.DebugLevel.INFO) return if (len(text) > 1) and (text.strip(string.whitespace) == ''): return - toAnnounceCapital = announceCapital and text[0].isupper() - if toAnnounceCapital: - if self.playSoundIcon('capital', False): - toAnnounceCapital = False - self.lastEcho = text - self.speakText(text, interrupt, ignorePunctuation, toAnnounceCapital) + to_announce_capital = announce_capital and text[0].isupper() + if to_announce_capital: + if self.play_sound_icon('capital', False): + to_announce_capital = False + self.last_echo = text + self.speak_text(text, interrupt, ignore_punctuation, to_announce_capital) - def getLastEcho(self): - return self.lastEcho + def get_last_echo(self): + return self.last_echo - def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False): - if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): - self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText", debug.debugLevel.INFO) + def speak_text( + self, + text, + interrupt=True, + ignore_punctuation=False, + announce_capital=False): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'): + self.env['runtime']['DebugManager'].write_debug_out( + "Speech disabled in OutputManager.speak_text", debug.DebugLevel.INFO) return - if self.env['runtime']['speechDriver'] == None: - self.env['runtime']['debug'].writeDebugOut("No speechDriver in outputManager.speakText", debug.debugLevel.ERROR) + if self.env['runtime']['SpeechDriver'] is None: + self.env['runtime']['DebugManager'].write_debug_out( + "No SpeechDriver in OutputManager.speak_text", debug.DebugLevel.ERROR) return if interrupt: - self.interruptOutput() + self.interrupt_output() try: - self.env['runtime']['speechDriver'].setLanguage(self.env['runtime']['settingsManager'].getSetting('speech', 'language')) + self.env['runtime']['SpeechDriver'].set_language( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'language')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("setting speech language in outputManager.speakText", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "setting speech language in OutputManager.speak_text", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - self.env['runtime']['speechDriver'].setVoice(self.env['runtime']['settingsManager'].getSetting('speech', 'voice')) + self.env['runtime']['SpeechDriver'].set_voice( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'voice')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("Error while setting speech voice in outputManager.speakText", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "Error while setting speech voice in OutputManager.speak_text", + debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - if announceCapital: - self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'capitalPitch')) + if announce_capital: + self.env['runtime']['SpeechDriver'].set_pitch( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'speech', 'capitalPitch')) else: - self.env['runtime']['speechDriver'].setPitch(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch')) + self.env['runtime']['SpeechDriver'].set_pitch( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'speech', 'pitch')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("setting speech pitch in outputManager.speakText", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "setting speech pitch in OutputManager.speak_text", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - self.env['runtime']['speechDriver'].setRate(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate')) + self.env['runtime']['SpeechDriver'].set_rate( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'speech', 'rate')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("setting speech rate in outputManager.speakText", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "setting speech rate in OutputManager.speak_text", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - self.env['runtime']['speechDriver'].setModule(self.env['runtime']['settingsManager'].getSetting('speech', 'module')) + self.env['runtime']['SpeechDriver'].set_module( + self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'module')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("setting speech module in outputManager.speakText", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "setting speech module in OutputManager.speak_text", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - self.env['runtime']['speechDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume')) + self.env['runtime']['SpeechDriver'].set_volume( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'speech', 'volume')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("setting speech volume in outputManager.speakText ", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "setting speech volume in OutputManager.speak_text ", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) try: - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'newLinePause'): - cleanText = text.replace('\n', ' , ') + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'newLinePause'): + clean_text = text.replace('\n', ' , ') else: - cleanText = text.replace('\n', ' ') + clean_text = text.replace('\n', ' ') - cleanText = self.env['runtime']['textManager'].replaceHeadLines(cleanText) - cleanText = self.env['runtime']['punctuationManager'].proceedPunctuation(cleanText, ignorePunctuation) - cleanText = re.sub(' +$', ' ', cleanText) - self.env['runtime']['speechDriver'].speak(cleanText, True, ignorePunctuation) - self.env['runtime']['debug'].writeDebugOut("Speak: "+ cleanText, debug.debugLevel.INFO) + clean_text = self.env['runtime']['TextManager'].replace_head_lines( + clean_text) + clean_text = self.env['runtime']['PunctuationManager'].proceed_punctuation( + clean_text, ignore_punctuation) + clean_text = re.sub(' +$', ' ', clean_text) + self.env['runtime']['SpeechDriver'].speak( + clean_text, True, ignore_punctuation) + self.env['runtime']['DebugManager'].write_debug_out( + "Speak: " + clean_text, debug.DebugLevel.INFO) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ", debug.debugLevel.ERROR) - self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "\"speak\" in OutputManager.speak_text ", debug.DebugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) - def interruptOutput(self): + def interrupt_output(self): try: - self.env['runtime']['speechDriver'].cancel() - self.env['runtime']['debug'].writeDebugOut("Interrupt speech", debug.debugLevel.INFO) + self.env['runtime']['SpeechDriver'].cancel() + self.env['runtime']['DebugManager'].write_debug_out( + "Interrupt speech", debug.DebugLevel.INFO) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('outputManager interruptOutput: Error canceling speech: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'OutputManager interrupt_output: Error canceling speech: ' + str(e), + debug.DebugLevel.ERROR) - def playSoundIcon(self, soundIcon='', interrupt=True): - if soundIcon == '': + def play_sound_icon(self, sound_icon ='', interrupt=True): + if sound_icon == '': return False - soundIcon = soundIcon.upper() - if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.playSoundIcon", debug.debugLevel.INFO) - return False - - try: - e = self.env['soundIcons'][soundIcon] - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('outputManager playSoundIcon: SoundIcon does not exist ' + soundIcon + ': ' + str(e), debug.debugLevel.WARNING) - return False - - if self.env['runtime']['soundDriver'] == None: - self.env['runtime']['debug'].writeDebugOut("No soundDriver in outputManager.playSoundIcon: soundDriver not loaded", debug.debugLevel.ERROR) + sound_icon = sound_icon.upper() + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'): + self.env['runtime']['DebugManager'].write_debug_out( + "Sound disabled in OutputManager.play_sound_icon", debug.DebugLevel.INFO) return False try: - self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume')) + e = self.env['soundIcons'][sound_icon] except Exception as e: - self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::setVolume: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'OutputManager play_sound_icon: SoundIcon does not exist ' + sound_icon + ': ' + str(e), + debug.DebugLevel.WARNING) + return False + + if self.env['runtime']['SoundDriver'] is None: + self.env['runtime']['DebugManager'].write_debug_out( + "No SoundDriver in OutputManager.play_sound_icon: SoundDriver not loaded", + debug.DebugLevel.ERROR) + return False try: - self.env['runtime']['soundDriver'].playSoundFile(self.env['soundIcons'][soundIcon], interrupt) + self.env['runtime']['SoundDriver'].set_volume( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'sound', 'volume')) + except Exception as e: + self.env['runtime']['DebugManager'].write_debug_out( + "OutputManager.play_sound_icon::set_volume: " + str(e), debug.DebugLevel.ERROR) + + try: + self.env['runtime']['SoundDriver'].play_sound_file( + self.env['soundIcons'][sound_icon], interrupt) return True except Exception as e: - self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::playSoundFile: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "OutputManager.play_sound_icon::play_sound_file: " + str(e), + debug.DebugLevel.ERROR) return False return False - def playFrequence(self, frequence, duration, interrupt=True): - if not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'): - self.env['runtime']['debug'].writeDebugOut("Sound disabled in outputManager.playFrequence", debug.debugLevel.INFO) + def play_frequence(self, frequence, duration, interrupt=True): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'sound', 'enabled'): + self.env['runtime']['DebugManager'].write_debug_out( + "Sound disabled in OutputManager.play_frequence", debug.DebugLevel.INFO) return False if frequence < 1 or frequence > 20000: - self.env['runtime']['debug'].writeDebugOut("outputManager.playFrequence::Filefrequence is out of range:" + str(frequence), debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "OutputManager.play_frequence::Filefrequence is out of range:" + + str(frequence), + debug.DebugLevel.INFO) return False - if self.env['runtime']['soundDriver'] == None: - self.env['runtime']['debug'].writeDebugOut("No soundDriver in outputManager.playFrequence: soundDriver not loaded", debug.debugLevel.ERROR) + if self.env['runtime']['SoundDriver'] is None: + self.env['runtime']['DebugManager'].write_debug_out( + "No SoundDriver in OutputManager.play_frequence: SoundDriver not loaded", + debug.DebugLevel.ERROR) return False try: - self.env['runtime']['soundDriver'].setVolume(self.env['runtime']['settingsManager'].getSettingAsFloat('sound', 'volume')) + self.env['runtime']['SoundDriver'].set_volume( + self.env['runtime']['SettingsManager'].get_setting_as_float( + 'sound', 'volume')) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::setVolume: " + str(e), debug.debugLevel.ERROR) - adjustVolume = 0.0 + self.env['runtime']['DebugManager'].write_debug_out( + "OutputManager.play_sound_icon::set_volume: " + str(e), debug.DebugLevel.ERROR) + adjust_volume = 0.0 try: - adjustVolume = 1.0 - (frequence / 20000) + adjust_volume = 1.0 - (frequence / 20000) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('outputManager playFrequence: Error calculating adjust volume: ' + str(e), debug.debugLevel.ERROR) - if adjustVolume > 9.0: - adjustVolume = 9.0 + self.env['runtime']['DebugManager'].write_debug_out( + 'OutputManager play_frequence: Error calculating adjust volume: ' + str(e), + debug.DebugLevel.ERROR) + if adjust_volume > 9.0: + adjust_volume = 9.0 try: - self.env['runtime']['soundDriver'].playFrequence(frequence, duration, adjustVolume, interrupt) + self.env['runtime']['SoundDriver'].play_frequence( + frequence, duration, adjust_volume, interrupt) return True except Exception as e: - self.env['runtime']['debug'].writeDebugOut("outputManager.playSoundIcon::playSoundFile: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "OutputManager.play_sound_icon::play_sound_file: " + str(e), + debug.DebugLevel.ERROR) return False return False - def tempDisableSpeech(self): - if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'): - self.presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True) + def temp_disable_speech(self): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'): + self.present_text( + _("speech temporary disabled"), + sound_icon ='SpeechOff', + interrupt=True) self.env['commandBuffer']['enableSpeechOnKeypress'] = True # Also enable prompt watching for automatic speech restoration if 'silenceUntilPrompt' not in self.env['commandBuffer']: self.env['commandBuffer']['silenceUntilPrompt'] = False self.env['commandBuffer']['silenceUntilPrompt'] = True - self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'))) - self.interruptOutput() + self.env['runtime']['SettingsManager'].set_setting( + 'speech', 'enabled', str( + not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'speech', 'enabled'))) + self.interrupt_output() - def announceActiveCursor(self, interrupt_p=False): - if self.env['runtime']['cursorManager'].isReviewMode(): - self.presentText(' review cursor ', interrupt=interrupt_p) + def announce_active_cursor(self, interrupt_p=False): + if self.env['runtime']['CursorManager'].is_review_mode(): + self.present_text(' review cursor ', interrupt=interrupt_p) else: - self.presentText(' text cursor ', interrupt=interrupt_p) + self.present_text(' text cursor ', interrupt=interrupt_p) - def resetSpeechDriver(self): - """Reset speech driver to clean state - called by settingsManager""" - if 'speechDriver' in self.env['runtime'] and self.env['runtime']['speechDriver']: + def reset_SpeechDriver(self): + """Reset speech driver to clean state - called by settings_manager""" + if 'SpeechDriver' in self.env['runtime'] and self.env['runtime']['SpeechDriver']: try: - self.env['runtime']['speechDriver'].reset() - self.env['runtime']['debug'].writeDebugOut("Speech driver reset successfully", debug.debugLevel.INFO) + self.env['runtime']['SpeechDriver'].reset() + self.env['runtime']['DebugManager'].write_debug_out( + "Speech driver reset successfully", debug.DebugLevel.INFO) except Exception as e: - self.env['runtime']['debug'].writeDebugOut(f"resetSpeechDriver error: {e}", debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + f"reset_SpeechDriver error: {e}", debug.DebugLevel.ERROR) diff --git a/src/fenrirscreenreader/core/processManager.py b/src/fenrirscreenreader/core/processManager.py index c75eee78..6d3df919 100644 --- a/src/fenrirscreenreader/core/processManager.py +++ b/src/fenrirscreenreader/core/processManager.py @@ -5,90 +5,146 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType -import time, signal +from fenrirscreenreader.core.eventData import FenrirEventType +import time +import signal from threading import Thread from multiprocessing import Process -class processManager(): + +class ProcessManager(): def __init__(self): self._Processes = [] - self._Threads = [] - def initialize(self, environment): - self.env = environment - self.running = self.env['runtime']['eventManager'].getRunning() - self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True) - def shutdown(self): - self.terminateAllProcesses() + self._Threads = [] - def terminateAllProcesses(self): + def initialize(self, environment): + self.env = environment + self.running = self.env['runtime']['EventManager'].get_running() + self.add_simple_event_thread( + FenrirEventType.heart_beat, + self.heart_beat_timer, + multiprocess=True) + + def shutdown(self): + self.terminate_all_processes() + + def terminate_all_processes(self): for proc in self._Processes: - #try: + # try: # proc.terminate() - #except KeyboardInterrupt: + # except KeyboardInterrupt: # pass - #except: + # except: # pass proc.join(timeout=5.0) # Timeout to prevent hanging shutdown for t in self._Threads: t.join(timeout=5.0) # Timeout to prevent hanging shutdown - def heartBeatTimer(self, active): + + def heart_beat_timer(self, active): try: time.sleep(0.5) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('processManager heartBeatTimer: Error during sleep: ' + str(e), debug.debugLevel.ERROR) - return time.time() - def addCustomEventThread(self, function, pargs = None, multiprocess = False, runOnce = False): - eventQueue = self.env['runtime']['eventManager'].getEventQueue() - original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) - if multiprocess: - t = Process(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce)) - self._Processes.append(t) - else:# thread not implemented yet - t = Thread(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce)) - self._Threads.append(t) - t.start() - signal.signal(signal.SIGINT, original_sigint_handler) - def addSimpleEventThread(self, event, function, pargs = None, multiprocess = False, runOnce = False): - original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) + self.env['runtime']['DebugManager'].write_debug_out( + 'ProcessManager heart_beat_timer: Error during sleep: ' + str(e), + debug.DebugLevel.ERROR) + return time.time() + + def add_custom_event_thread( + self, + function, + pargs=None, + multiprocess=False, + run_once=False): + event_queue = self.env['runtime']['EventManager'].get_event_queue() + original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) if multiprocess: - t = Process(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce)) - self._Processes.append(t) - else: - t = Thread(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce)) - self._Threads.append(t) + t = Process( + target=self.custom_event_worker_thread, args=( + event_queue, function, pargs, run_once)) + self._Processes.append(t) + else: # thread not implemented yet + t = Thread( + target=self.custom_event_worker_thread, + args=( + event_queue, + function, + pargs, + run_once)) + self._Threads.append(t) t.start() - signal.signal(signal.SIGINT, original_sigint_handler) - def customEventWorkerThread(self, eventQueue, function, pargs = None, runOnce = False): - #if not isinstance(eventQueue, Queue): + signal.signal(signal.SIGINT, original_sigint_handler) + + def add_simple_event_thread( + self, + event, + function, + pargs=None, + multiprocess=False, + run_once=False): + original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) + if multiprocess: + t = Process( + target=self.simple_event_worker_thread, args=( + event, function, pargs, run_once)) + self._Processes.append(t) + else: + t = Thread( + target=self.simple_event_worker_thread, args=( + event, function, pargs, run_once)) + self._Threads.append(t) + t.start() + signal.signal(signal.SIGINT, original_sigint_handler) + + def custom_event_worker_thread( + self, + event_queue, + function, + pargs=None, + run_once=False): + # if not isinstance(event_queue, Queue): # return if not callable(function): return while self.running.value: try: if pargs: - function(self.running, eventQueue, pargs) + function(self.running, event_queue, pargs) else: - function(self.running, eventQueue) + function(self.running, event_queue) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('processManager:customEventWorkerThread:function('+str(function)+'):' + str(e),debug.debugLevel.ERROR) - if runOnce: + self.env['runtime']['DebugManager'].write_debug_out( + 'ProcessManager:custom_event_worker_thread:function(' + + str(function) + + '):' + + str(e), + debug.DebugLevel.ERROR) + if run_once: break - def simpleEventWorkerThread(self, event, function, pargs = None, runOnce = False): - if not isinstance(event, fenrirEventType): + def simple_event_worker_thread( + self, + event, + function, + pargs=None, + run_once=False): + if not isinstance(event, FenrirEventType): return if not callable(function): return while self.running.value: - Data = None + data = None try: if pargs: - Data = function(self.running, pargs) + data = function(self.running, pargs) else: - Data = function(self.running) + data = function(self.running) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('processManager:simpleEventWorkerThread:function('+str(function)+'):' + str(e),debug.debugLevel.ERROR) - self.env['runtime']['eventManager'].putToEventQueue(event, Data) - if runOnce: + self.env['runtime']['DebugManager'].write_debug_out( + 'ProcessManager:simple_event_worker_thread:function(' + + str(function) + + '):' + + str(e), + debug.DebugLevel.ERROR) + self.env['runtime']['EventManager'].put_to_event_queue(event, data) + if run_once: break diff --git a/src/fenrirscreenreader/core/punctuationData.py b/src/fenrirscreenreader/core/punctuationData.py index cb633fff..319a5896 100644 --- a/src/fenrirscreenreader/core/punctuationData.py +++ b/src/fenrirscreenreader/core/punctuationData.py @@ -8,15 +8,15 @@ from fenrirscreenreader.core import debug import string from collections import OrderedDict -punctuationData = { -'LEVELDICT':{ - 'none': '', - 'some': '#-$~+*-/\\@', - 'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;', - 'all': string.punctuation + ' §', - }, -'PUNCTDICT':{ - }, -'CUSTOMDICT':OrderedDict(), -'EMOTICONDICT':OrderedDict(), +punctuation_data = { + 'LEVELDICT': { + 'none': '', + 'some': '#-$~+*-/\\@', + 'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;', + 'all': string.punctuation + ' §', + }, + 'PUNCTDICT': { + }, + 'CUSTOMDICT': OrderedDict(), + 'EMOTICONDICT': OrderedDict(), } diff --git a/src/fenrirscreenreader/core/punctuationManager.py b/src/fenrirscreenreader/core/punctuationManager.py index 8f351ffe..3cb53fc4 100644 --- a/src/fenrirscreenreader/core/punctuationManager.py +++ b/src/fenrirscreenreader/core/punctuationManager.py @@ -6,120 +6,171 @@ import string from fenrirscreenreader.core import debug -import os, inspect, re -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) +import os +import inspect +import re +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) -class punctuationManager(): + +class PunctuationManager(): def __init__(self): pass + def initialize(self, environment): self.env = environment - self.allPunctNone = dict.fromkeys(map(ord, string.punctuation +"§ "), ' ') - # replace with None: + self.allPunctNone = dict.fromkeys( + map(ord, string.punctuation + "§ "), ' ') + # replace with None: # dot, comma, grave, apostrophe - #for char in [ord('`'),ord("'")]: + # for char in [ord('`'),ord("'")]: # self.allPunctNone[char] = None # dont restore the following (for announce correct pause) - for char in [ord("'"),ord('.'), ord(','), ord(';'), ord(':'), ord('?'), ord('!'), ord('-')]: + for char in [ + ord("'"), + ord('.'), + ord(','), + ord(';'), + ord(':'), + ord('?'), + ord('!'), + ord('-')]: self.allPunctNone[char] = chr(char) + def shutdown(self): pass - def removeUnused(self, text, currLevel = ''): + + def remove_unused(self, text, curr_level=''): # dont translate dot and comma because they create a pause - currAllPunctNone = self.allPunctNone.copy() - for char in currLevel: + curr_all_punct_none = self.allPunctNone.copy() + for char in curr_level: try: - del currAllPunctNone[ord(char)] + del curr_all_punct_none[ord(char)] except Exception as e: pass - return text.translate(currAllPunctNone) - def useCustomDict(self, text, customDict, seperator=''): - resultText = str(text) + return text.translate(curr_all_punct_none) + + def use_custom_dict(self, text, customDict, seperator=''): + result_text = str(text) if customDict: - for key,item in customDict.items(): + for key, item in customDict.items(): try: - regexLbl = 'REGEX;' - if key.upper().startswith(regexLbl) and (len(key) > len(regexLbl)): - resultText = re.sub(str(key[len(regexLbl):]), seperator + str(item) + seperator, resultText) + regex_lbl = 'REGEX;' + if key.upper().startswith(regex_lbl) and (len(key) > len(regex_lbl)): + result_text = re.sub( + str(key[len(regex_lbl):]), seperator + str(item) + seperator, result_text) else: - resultText = resultText.replace(str(key),seperator + str(item) + seperator) + result_text = result_text.replace( + str(key), seperator + str(item) + seperator) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("useCustomDict replace:'" + key + "' with '" + item +"' failed:" + str(e),debug.debugLevel.ERROR, onAnyLevel=False) - return resultText - def usePunctuationDict(self, text, punctuationDict, punctuation): - resultText = str(text) + self.env['runtime']['DebugManager'].write_debug_out( + "use_custom_dict replace:'" + + key + + "' with '" + + item + + "' failed:" + + str(e), + debug.DebugLevel.ERROR, + on_any_level=False) + return result_text + + def use_punctuation_dict(self, text, punctuationDict, punctuation): + result_text = str(text) if punctuationDict and punctuation and punctuation != '': if ' ' in punctuation: - resultText = resultText.replace(' ',' ' + punctuationDict[' '] + ' ') - for key,item in punctuationDict.items(): + result_text = result_text.replace( + ' ', ' ' + punctuationDict[' '] + ' ') + for key, item in punctuationDict.items(): if (punctuation != '' and key in punctuation) and key not in ' ': - if self.env['runtime']['settingsManager'].getSetting('general', 'respectPunctuationPause') and \ - len(key) == 1 and \ - key in "',.;:?!": - resultText = resultText.replace(str(key),' ' +str(item) + str(key) + ' ') + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'respectPunctuationPause') and len(key) == 1 and key in "',.;:?!": + result_text = result_text.replace( + str(key), ' ' + str(item) + str(key) + ' ') else: - resultText = resultText.replace(str(key),' ' +str(item) + ' ') - return resultText - def isPuctuation(self, char): - return char in self.env['punctuation']['PUNCTDICT'] - def proceedPunctuation(self, text, ignorePunctuation=False): - if ignorePunctuation: - return text - resultText = text - resultText = self.useCustomDict(resultText, self.env['punctuation']['CUSTOMDICT']) - if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'): - resultText = self.useCustomDict(resultText, self.env['punctuation']['EMOTICONDICT'], ' ') - currPunctLevel = '' - if self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower() in self.env['punctuation']['LEVELDICT']: - currPunctLevel = self.env['punctuation']['LEVELDICT'][self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()] - else: - currPunctLevel = string.punctuation +' §' - resultText = self.usePunctuationDict(resultText, self.env['punctuation']['PUNCTDICT'], currPunctLevel) - resultText = self.removeUnused(resultText, currPunctLevel) - return resultText + result_text = result_text.replace( + str(key), ' ' + str(item) + ' ') + return result_text - def cyclePunctuation(self): - punctList = list(self.env['punctuation']['LEVELDICT'].keys()) + def is_puctuation(self, char): + return char in self.env['punctuation']['PUNCTDICT'] + + def proceed_punctuation(self, text, ignore_punctuation=False): + if ignore_punctuation: + return text + result_text = text + result_text = self.use_custom_dict( + result_text, self.env['punctuation']['CUSTOMDICT']) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'general', 'emoticons'): + result_text = self.use_custom_dict( + result_text, self.env['punctuation']['EMOTICONDICT'], ' ') + curr_punct_level = '' + if self.env['runtime']['SettingsManager'].get_setting( + 'general', 'punctuationLevel').lower() in self.env['punctuation']['LEVELDICT']: + curr_punct_level = self.env['punctuation']['LEVELDICT'][self.env['runtime'][ + 'SettingsManager'].get_setting('general', 'punctuationLevel').lower()] + else: + curr_punct_level = string.punctuation + ' §' + result_text = self.use_punctuation_dict( + result_text, self.env['punctuation']['PUNCTDICT'], curr_punct_level) + result_text = self.remove_unused(result_text, curr_punct_level) + return result_text + + def cycle_punctuation(self): + punct_list = list(self.env['punctuation']['LEVELDICT'].keys()) try: - currIndex = punctList.index(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()) # curr punctuation + curr_index = punct_list.index( + self.env['runtime']['SettingsManager'].get_setting( + 'general', 'punctuationLevel').lower()) # curr punctuation except Exception as e: return False - currIndex += 1 - if currIndex >= len(punctList): - currIndex = 0 - currLevel = punctList[currIndex] - self.env['runtime']['settingsManager'].setSetting('general', 'punctuationLevel', currLevel.lower()) + curr_index += 1 + if curr_index >= len(punct_list): + curr_index = 0 + curr_level = punct_list[curr_index] + self.env['runtime']['SettingsManager'].set_setting( + 'general', 'punctuationLevel', curr_level.lower()) return True - def loadDicts(self, dictConfigPath=fenrirPath + '/../../config/punctuation/default.conf'): - dictConfig = open(dictConfigPath,"r") - currDictName = '' - while(True): - line = dictConfig.readline() + + def load_dicts(self, dictConfigPath=fenrir_path + + '/../../config/punctuation/default.conf'): + dict_config = open(dictConfigPath, "r") + curr_dict_name = '' + while (True): + line = dict_config.readline() if not line: break - line = line.replace('\n','') - if line.replace(" ","") == '': + line = line.replace('\n', '') + if line.replace(" ", "") == '': continue - if line.replace(" ","").startswith("#"): - if not line.replace(" ","").startswith("#:===:"): + if line.replace(" ", "").startswith("#"): + if not line.replace(" ", "").startswith("#:===:"): continue - if line.replace(" ","").upper().startswith("[") and \ - line.replace(" ","").upper().endswith("DICT]"): - currDictName = line[line.find('[') + 1 :line.upper().find('DICT]') + 4].upper() + if line.replace(" ", "").upper().startswith("[") and \ + line.replace(" ", "").upper().endswith("DICT]"): + curr_dict_name = line[line.find( + '[') + 1:line.upper().find('DICT]') + 4].upper() else: - if currDictName == '': + if curr_dict_name == '': continue - if not ":===:" in line: + if ":===:" not in line: continue - sepLine = line.split(':===:') - if len(sepLine) == 1: - sepLine.append('') - elif len(sepLine) < 1: + sep_line = line.split(':===:') + if len(sep_line) == 1: + sep_line.append('') + elif len(sep_line) < 1: continue - elif len(sepLine) > 2: - sepLine[1] = ':===:' - self.env['punctuation'][currDictName][sepLine[0]] = sepLine[1] - self.env['runtime']['debug'].writeDebugOut("Punctuation: " + currDictName + '.' + str(sepLine[0]) + ' :' + sepLine[1] ,debug.debugLevel.INFO, onAnyLevel=True) - dictConfig.close() + elif len(sep_line) > 2: + sep_line[1] = ':===:' + self.env['punctuation'][curr_dict_name][sep_line[0]] = sep_line[1] + self.env['runtime']['DebugManager'].write_debug_out( + "Punctuation: " + curr_dict_name + '.' + str( + sep_line[0]) + ' :' + sep_line[1], + debug.DebugLevel.INFO, + on_any_level=True) + dict_config.close() diff --git a/src/fenrirscreenreader/core/quickMenuManager.py b/src/fenrirscreenreader/core/quickMenuManager.py index da924d9c..d755de8a 100644 --- a/src/fenrirscreenreader/core/quickMenuManager.py +++ b/src/fenrirscreenreader/core/quickMenuManager.py @@ -5,20 +5,26 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.settingsData import settingsData +from fenrirscreenreader.core.i18n import _ +from fenrirscreenreader.core.settingsData import settings_data -class quickMenuManager(): + +class QuickMenuManager(): def __init__(self): self.position = 0 self.quickMenu = [] - self.settings = settingsData + self.settings = settings_data def initialize(self, environment): self.env = environment - self.loadMenu(self.env['runtime']['settingsManager'].getSetting('menu', 'quickMenu')) + self.load_menu( + self.env['runtime']['SettingsManager'].get_setting( + 'menu', 'quickMenu')) + def shutdown(self): pass - def loadMenu(self, menuString): + + def load_menu(self, menuString): self.position = 0 self.quickMenu = [] if menuString == '': @@ -31,106 +37,132 @@ class quickMenuManager(): try: t = self.settings[entry[0]][entry[1]] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('quickMenuManager loadMenu: Setting not found ' + str(entry) + ': ' + str(e), debug.debugLevel.ERROR) - print(entry[0],entry[1], 'not found') + self.env['runtime']['DebugManager'].write_debug_out( + 'QuickMenuManager load_menu: Setting not found ' + str(entry) + ': ' + str(e), + debug.DebugLevel.ERROR) + print(entry[0], entry[1], 'not found') continue self.quickMenu.append({'section': entry[0], 'setting': entry[1]}) - def nextEntry(self): + + def next_entry(self): if len(self.quickMenu) == 0: return False self.position += 1 if self.position >= len(self.quickMenu): self.position = 0 return True - def prevEntry(self): + + def prev_entry(self): if len(self.quickMenu) == 0: return False self.position -= 1 if self.position < 0: self.position = len(self.quickMenu) - 1 return True - def nextValue(self): + + def next_value(self): if len(self.quickMenu) == 0: return False section = self.quickMenu[self.position]['section'] setting = self.quickMenu[self.position]['setting'] - valueString = '' + value_string = '' try: - valueString = self.env['runtime']['settingsManager'].getSetting(section, setting) + value_string = self.env['runtime']['SettingsManager'].get_setting( + section, setting) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('quickMenuManager nextValue: Error getting setting value: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'QuickMenuManager next_value: Error getting setting value: ' + str(e), + debug.DebugLevel.ERROR) return False try: if isinstance(self.settings[section][setting], str): - value = str(valueString) + value = str(value_string) return False elif isinstance(self.settings[section][setting], bool): - if not valueString in ['True','False']: + if value_string not in ['True', 'False']: return False value = not value - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)) elif isinstance(self.settings[section][setting], int): - value = int(valueString) + value = int(value_string) value += 1 - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)) elif isinstance(self.settings[section][setting], float): - value = float(valueString) + value = float(value_string) value += 0.05 if value > 1.0: value = 1.0 - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)[:4]) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)[:4]) except Exception as e: return False return True - def prevValue(self): + + def prev_value(self): if len(self.quickMenu) == 0: return False section = self.quickMenu[self.position]['section'] setting = self.quickMenu[self.position]['setting'] - valueString = '' + value_string = '' try: - valueString = self.env['runtime']['settingsManager'].getSetting(section, setting) + value_string = self.env['runtime']['SettingsManager'].get_setting( + section, setting) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('quickMenuManager prevValue: Error getting setting value: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'QuickMenuManager prev_value: Error getting setting value: ' + str(e), + debug.DebugLevel.ERROR) return False try: if isinstance(self.settings[section][setting], str): - value = str(valueString) + value = str(value_string) return False elif isinstance(self.settings[section][setting], bool): - if not valueString in ['True','False']: + if value_string not in ['True', 'False']: return False value = not value - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)) elif isinstance(self.settings[section][setting], int): - value = int(valueString) + value = int(value_string) value -= 1 if value < 0: value = 0 - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)) elif isinstance(self.settings[section][setting], float): - value = float(valueString) + value = float(value_string) value -= 0.05 if value < 0.0: value = 0.0 - self.env['runtime']['settingsManager'].setSetting(section, setting, str(value)[:4]) + self.env['runtime']['SettingsManager'].set_setting( + section, setting, str(value)[:4]) except Exception as e: return False return True - def getCurrentEntry(self): + + def get_current_entry(self): if len(self.quickMenu) == 0: return '' try: - return _(self.quickMenu[self.position]['section']) + ' ' + _(self.quickMenu[self.position]['setting']) + return _(self.quickMenu[self.position]['section']) + \ + ' ' + _(self.quickMenu[self.position]['setting']) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('quickMenuManager getCurrentEntry: Error formatting entry: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'QuickMenuManager get_current_entry: Error formatting entry: ' + str(e), + debug.DebugLevel.ERROR) return _('setting invalid') - def getCurrentValue(self): + + def get_current_value(self): if len(self.quickMenu) == 0: return '' try: - return self.env['runtime']['settingsManager'].getSetting(self.quickMenu[self.position]['section'], self.quickMenu[self.position]['setting']) + return self.env['runtime']['SettingsManager'].get_setting( + self.quickMenu[self.position]['section'], self.quickMenu[self.position]['setting']) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('quickMenuManager getCurrentValue: Error getting setting value: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'QuickMenuManager get_current_value: Error getting setting value: ' + str(e), + debug.DebugLevel.ERROR) return _('setting value invalid') diff --git a/src/fenrirscreenreader/core/remoteDriver.py b/src/fenrirscreenreader/core/remoteDriver.py index 68a8e6e4..4e7c54d2 100644 --- a/src/fenrirscreenreader/core/remoteDriver.py +++ b/src/fenrirscreenreader/core/remoteDriver.py @@ -6,11 +6,14 @@ from fenrirscreenreader.core import debug -class remoteDriver(): + +class RemoteDriver(): def __init__(self): - self._isInitialized = False + self._is_initialized = False + def initialize(self, environment): self.env = environment - self._isInitialized = True + self._is_initialized = True + def shutdown(self): - self._isInitialized = False + self._is_initialized = False diff --git a/src/fenrirscreenreader/core/remoteManager.py b/src/fenrirscreenreader/core/remoteManager.py index af2850a2..ce0654ea 100644 --- a/src/fenrirscreenreader/core/remoteManager.py +++ b/src/fenrirscreenreader/core/remoteManager.py @@ -27,10 +27,13 @@ command interrupt from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType -import time, os +from fenrirscreenreader.core.i18n import _ +from fenrirscreenreader.core.eventData import FenrirEventType +import time +import os -class remoteManager(): + +class RemoteManager(): def __init__(self): # command controll self.commandConst = 'COMMAND ' @@ -50,253 +53,321 @@ class remoteManager(): self.saveAsSettingConst = 'SAVEAS ' self.saveSettingConst = 'SAVE' self.resetSettingConst = 'RESET' + def initialize(self, environment): self.env = environment - self.env['runtime']['settingsManager'].loadDriver(\ - self.env['runtime']['settingsManager'].getSetting('remote', 'driver'), 'remoteDriver') + self.env['runtime']['SettingsManager'].load_driver( + self.env['runtime']['SettingsManager'].get_setting( + 'remote', 'driver'), 'RemoteDriver') + def shutdown(self): - self.env['runtime']['settingsManager'].shutdownDriver('remoteDriver') + self.env['runtime']['SettingsManager'].shutdown_driver('RemoteDriver') - def handleSettingsChangeWithResponse(self, settingsText): - if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableSettingsRemote'): - return {"success": False, "message": "Settings remote control is disabled"} + def handle_settings_change_with_response(self, settings_text): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'remote', 'enableSettingsRemote'): + return { + "success": False, + "message": "Settings remote control is disabled"} - upperSettingsText = settingsText.upper() + upper_settings_text = settings_text.upper() try: # set setting - if upperSettingsText.startswith(self.setSettingConst): - parameterText = settingsText[len(self.setSettingConst):] - self.setSettings(parameterText) - return {"success": True, "message": f"Setting applied: {parameterText}"} + if upper_settings_text.startswith(self.setSettingConst): + parameter_text = settings_text[len(self.setSettingConst):] + self.set_settings(parameter_text) + return { + "success": True, + "message": f"Setting applied: {parameter_text}"} # save as setting - elif upperSettingsText.startswith(self.saveAsSettingConst): - parameterText = settingsText[len(self.saveAsSettingConst):] - self.saveSettings(parameterText) - return {"success": True, "message": f"Settings saved to: {parameterText}"} + elif upper_settings_text.startswith(self.saveAsSettingConst): + parameter_text = settings_text[len(self.saveAsSettingConst):] + self.save_settings(parameter_text) + return { + "success": True, + "message": f"Settings saved to: {parameter_text}"} # save setting - elif upperSettingsText == self.saveSettingConst: - self.saveSettings() + elif upper_settings_text == self.saveSettingConst: + self.save_settings() return {"success": True, "message": "Settings saved"} # reset setting - elif upperSettingsText == self.resetSettingConst: - self.resetSettings() - return {"success": True, "message": "Settings reset to defaults"} + elif upper_settings_text == self.resetSettingConst: + self.reset_settings() + return { + "success": True, + "message": "Settings reset to defaults"} else: - return {"success": False, "message": f"Unknown settings command: {settingsText}"} + return { + "success": False, + "message": f"Unknown settings command: {settings_text}"} except Exception as e: return {"success": False, "message": f"Settings error: {str(e)}"} - def handleSettingsChange(self, settingsText): - if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableSettingsRemote'): + def handle_settings_change(self, settings_text): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'remote', 'enableSettingsRemote'): return - upperSettingsText = settingsText.upper() + upper_settings_text = settings_text.upper() # set setting - if upperSettingsText.startswith(self.setSettingConst): - parameterText = settingsText[len(self.setSettingConst):] - self.setSettings(parameterText) + if upper_settings_text.startswith(self.setSettingConst): + parameter_text = settings_text[len(self.setSettingConst):] + self.set_settings(parameter_text) # save as setting - elif upperSettingsText.startswith(self.saveAsSettingConst): - parameterText = settingsText[len(self.saveAsSettingConst):] - self.saveSettings(parameterText) + elif upper_settings_text.startswith(self.saveAsSettingConst): + parameter_text = settings_text[len(self.saveAsSettingConst):] + self.save_settings(parameter_text) # save setting - elif upperSettingsText == self.saveSettingConst: - self.saveSettings() + elif upper_settings_text == self.saveSettingConst: + self.save_settings() # reset setting - elif upperSettingsText == self.resetSettingConst: - self.resetSettings() + elif upper_settings_text == self.resetSettingConst: + self.reset_settings() - def handleCommandExecutionWithResponse(self, commandText): - if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableCommandRemote'): - return {"success": False, "message": "Command remote control is disabled"} + def handle_command_execution_with_response(self, command_text): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'remote', 'enableCommandRemote'): + return { + "success": False, + "message": "Command remote control is disabled"} - upperCommandText = commandText.upper() + upper_command_text = command_text.upper() try: # say - if upperCommandText.startswith(self.sayConst): - parameterText = commandText[len(self.sayConst):] - self.say(parameterText) - return {"success": True, "message": f"Speaking: {parameterText[:50]}{'...' if len(parameterText) > 50 else ''}"} + if upper_command_text.startswith(self.sayConst): + parameter_text = command_text[len(self.sayConst):] + self.say(parameter_text) + return {"success": True, + "message": f"Speaking: {parameter_text[:50]}{'...' if len(parameter_text) > 50 else ''}"} # interrupt - elif upperCommandText == self.interruptConst: - self.interruptSpeech() + elif upper_command_text == self.interruptConst: + self.interrupt_speech() return {"success": True, "message": "Speech interrupted"} # temp disable speech - elif upperCommandText == self.tempDisableSpeechConst: - self.tempDisableSpeech() - return {"success": True, "message": "Speech temporarily disabled"} + elif upper_command_text == self.tempDisableSpeechConst: + self.temp_disable_speech() + return { + "success": True, + "message": "Speech temporarily disabled"} # set vmenu - elif upperCommandText.startswith(self.vmenuConst): - parameterText = commandText[len(self.vmenuConst):] - self.setVMenu(parameterText) - return {"success": True, "message": f"VMenu set to: {parameterText}"} + elif upper_command_text.startswith(self.vmenuConst): + parameter_text = command_text[len(self.vmenuConst):] + self.set_vmenu(parameter_text) + return { + "success": True, + "message": f"VMenu set to: {parameter_text}"} # reset vmenu - elif upperCommandText == self.resetVmenuConst: - self.resetVMenu() + elif upper_command_text == self.resetVmenuConst: + self.reset_vmenu() return {"success": True, "message": "VMenu reset"} # quit fenrir - elif upperCommandText == self.quitAppConst: - self.quitFenrir() + elif upper_command_text == self.quitAppConst: + self.quit_fenrir() return {"success": True, "message": "Fenrir shutting down"} # define window - elif upperCommandText.startswith(self.defineWindowConst): - parameterText = commandText[len(self.defineWindowConst):] - self.defineWindow(parameterText) - return {"success": True, "message": f"Window defined: {parameterText}"} + elif upper_command_text.startswith(self.defineWindowConst): + parameter_text = command_text[len(self.defineWindowConst):] + self.define_window(parameter_text) + return { + "success": True, + "message": f"Window defined: {parameter_text}"} # reset window - elif upperCommandText == self.resetWindowConst: - self.resetWindow() + elif upper_command_text == self.resetWindowConst: + self.reset_window() return {"success": True, "message": "Window reset"} # set clipboard - elif upperCommandText.startswith(self.setClipboardConst): - parameterText = commandText[len(self.setClipboardConst):] - self.setClipboard(parameterText) - return {"success": True, "message": f"Clipboard set: {parameterText[:50]}{'...' if len(parameterText) > 50 else ''}"} - elif upperCommandText.startswith(self.exportClipboardConst): - self.exportClipboard() - return {"success": True, "message": "Clipboard exported to file"} + elif upper_command_text.startswith(self.setClipboardConst): + parameter_text = command_text[len(self.setClipboardConst):] + self.set_clipboard(parameter_text) + return {"success": True, + "message": f"Clipboard set: {parameter_text[:50]}{'...' if len(parameter_text) > 50 else ''}"} + elif upper_command_text.startswith(self.exportClipboardConst): + self.export_clipboard() + return { + "success": True, + "message": "Clipboard exported to file"} else: - return {"success": False, "message": f"Unknown command: {commandText}"} + return { + "success": False, + "message": f"Unknown command: {command_text}"} except Exception as e: return {"success": False, "message": f"Command error: {str(e)}"} - def handleCommandExecution(self, commandText): - if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableCommandRemote'): + def handle_command_execution(self, command_text): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'remote', 'enableCommandRemote'): return - upperCommandText = commandText.upper() + upper_command_text = command_text.upper() # say - if upperCommandText.startswith(self.sayConst): - parameterText = commandText[len(self.sayConst):] - self.say(parameterText) + if upper_command_text.startswith(self.sayConst): + parameter_text = command_text[len(self.sayConst):] + self.say(parameter_text) # interrupt - elif upperCommandText == self.interruptConst: - self.interruptSpeech() + elif upper_command_text == self.interruptConst: + self.interrupt_speech() # temp disable speech - elif upperCommandText == self.tempDisableSpeechConst: - self.tempDisableSpeech() + elif upper_command_text == self.tempDisableSpeechConst: + self.temp_disable_speech() # set vmenu - elif upperCommandText.startswith(self.vmenuConst): - parameterText = commandText[len(self.vmenuConst):] - self.setVMenu(parameterText) + elif upper_command_text.startswith(self.vmenuConst): + parameter_text = command_text[len(self.vmenuConst):] + self.set_vmenu(parameter_text) # reset vmenu - elif upperCommandText == self.resetVmenuConst: - self.resetVMenu() + elif upper_command_text == self.resetVmenuConst: + self.reset_vmenu() # quit fenrir - elif upperCommandText == self.quitAppConst: - self.quitFenrir() + elif upper_command_text == self.quitAppConst: + self.quit_fenrir() # define window - elif upperCommandText.startswith(self.defineWindowConst): - parameterText = commandText[len(self.defineWindowConst):] - self.defineWindow(parameterText) + elif upper_command_text.startswith(self.defineWindowConst): + parameter_text = command_text[len(self.defineWindowConst):] + self.define_window(parameter_text) # reset window - elif upperCommandText == self.resetWindowConst: - self.resetWindow() + elif upper_command_text == self.resetWindowConst: + self.reset_window() # set clipboard - elif upperCommandText.startswith(self.setClipboardConst): - parameterText = commandText[len(self.setClipboardConst):] - self.setClipboard(parameterText) - elif upperCommandText.startswith(self.exportClipboardConst): - self.exportClipboard() - def tempDisableSpeech(self): - self.env['runtime']['outputManager'].tempDisableSpeech() - def setVMenu(self, vmenu = ''): - self.env['runtime']['vmenuManager'].setCurrMenu(vmenu) - def resetVMenu(self): - self.env['runtime']['vmenuManager'].setCurrMenu() - def setClipboard(self, text = ''): - self.env['runtime']['memoryManager'].addValueToFirstIndex('clipboardHistory', text) - def quitFenrir(self): - self.env['runtime']['eventManager'].stopMainEventLoop() - def defineWindow(self, windowText): + elif upper_command_text.startswith(self.setClipboardConst): + parameter_text = command_text[len(self.setClipboardConst):] + self.set_clipboard(parameter_text) + elif upper_command_text.startswith(self.exportClipboardConst): + self.export_clipboard() + + def temp_disable_speech(self): + self.env['runtime']['OutputManager'].temp_disable_speech() + + def set_vmenu(self, vmenu=''): + self.env['runtime']['VmenuManager'].set_curr_menu(vmenu) + + def reset_vmenu(self): + self.env['runtime']['VmenuManager'].set_curr_menu() + + def set_clipboard(self, text=''): + self.env['runtime']['MemoryManager'].add_value_to_first_index( + 'clipboardHistory', text) + + def quit_fenrir(self): + self.env['runtime']['EventManager'].stop_main_event_loop() + + def define_window(self, window_text): start = {} end = {} try: - windowList = windowText.split(' ') - if len(windowList) < 4: + window_list = window_text.split(' ') + if len(window_list) < 4: return - start['x'] = int(windowList[0]) - start['y'] = int(windowList[1]) - end['x'] = int(windowList[2]) - end['y'] = int(windowList[3]) + start['x'] = int(window_list[0]) + start['y'] = int(window_list[1]) + end['x'] = int(window_list[2]) + end['y'] = int(window_list[3]) - self.env['runtime']['cursorManager'].setWindowForApplication(start, end) + self.env['runtime']['CursorManager'].set_window_for_application( + start, end) except Exception as e: pass - def resetWindow(self): - self.env['runtime']['cursorManager'].clearWindowForApplication() + + def reset_window(self): + self.env['runtime']['CursorManager'].clear_window_for_application() + def say(self, text): if not text: return if text == '': return - self.env['runtime']['outputManager'].speakText(text) - def interruptSpeech(self): - self.env['runtime']['outputManager'].interruptOutput() - def exportClipboard(self): - clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath') - clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser']) - clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser']) - clipboardFile = open(clipboardFilePath,'w') + self.env['runtime']['OutputManager'].speak_text(text) + + def interrupt_speech(self): + self.env['runtime']['OutputManager'].interrupt_output() + + def export_clipboard(self): + clipboard_file_path = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'clipboardExportPath') + clipboard_file_path = clipboard_file_path.replace( + '$user', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$USER', self.env['general']['curr_user']) + clipboard_file_path = clipboard_file_path.replace( + '$User', self.env['general']['curr_user']) + clipboard_file = open(clipboard_file_path, 'w') try: - if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'): - self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True) - return - clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory') + if self.env['runtime']['MemoryManager'].is_index_list_empty( + 'clipboardHistory'): + self.env['runtime']['OutputManager'].present_text( + _('clipboard empty'), interrupt=True) + return + clipboard = self.env['runtime']['MemoryManager'].get_index_list_element( + 'clipboardHistory') # Fenrir will crash if the clipboard variable is type None if clipboard is not None: - clipboardFile.write(clipboard) + clipboard_file.write(clipboard) else: - clipboardFile.write('') - clipboardFile.close() - os.chmod(clipboardFilePath, 0o644) - self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True) + clipboard_file.write('') + clipboard_file.close() + os.chmod(clipboard_file_path, 0o644) + self.env['runtime']['OutputManager'].present_text( + _('clipboard exported to file'), interrupt=True) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'export_clipboard_to_file:run: Filepath:' + + clipboard_file + + ' trace:' + + str(e), + debug.DebugLevel.ERROR) - def saveSettings(self, settingConfigPath = None): - if not settingConfigPath: - settingConfigPath = self.env['runtime']['settingsManager'].getSettingsFile() - if settingConfigPath == '': + def save_settings(self, setting_config_path=None): + if not setting_config_path: + setting_config_path = self.env['runtime']['SettingsManager'].get_settings_file( + ) + if setting_config_path == '': return - self.env['runtime']['settingsManager'].saveSettings(settingConfigPath) - def resetSettings(self): - self.env['runtime']['settingsManager'].resetSettingArgDict() - def setSettings(self, settingsArgs): - self.env['runtime']['settingsManager'].parseSettingArgs(settingsArgs) - self.env['runtime']['screenManager'].updateScreenIgnored() - self.env['runtime']['inputManager'].handleDeviceGrab(force = True) - def handleRemoteIncommingWithResponse(self, eventData): - if not eventData: + self.env['runtime']['SettingsManager'].save_settings(setting_config_path) + + def reset_settings(self): + self.env['runtime']['SettingsManager'].reset_setting_arg_dict() + + def set_settings(self, settingsArgs): + self.env['runtime']['SettingsManager'].parse_setting_args(settingsArgs) + self.env['runtime']['ScreenManager'].update_screen_ignored() + self.env['runtime']['InputManager'].handle_device_grab(force=True) + + def handle_remote_incomming_with_response(self, event_data): + if not event_data: return {"success": False, "message": "No data received"} - - upperEventData = eventData.upper() - self.env['runtime']['debug'].writeDebugOut('remoteManager:handleRemoteIncommingWithResponse: event: ' + str(eventData),debug.debugLevel.INFO) + + upper_event_data = event_data.upper() + self.env['runtime']['DebugManager'].write_debug_out( + 'RemoteManager:handle_remote_incomming_with_response: event: ' + + str(event_data), + debug.DebugLevel.INFO) try: - if upperEventData.startswith(self.settingConst): - settingsText = eventData[len(self.settingConst):] - return self.handleSettingsChangeWithResponse(settingsText) - elif upperEventData.startswith(self.commandConst): - commandText = eventData[len(self.commandConst):] - return self.handleCommandExecutionWithResponse(commandText) + if upper_event_data.startswith(self.settingConst): + settings_text = event_data[len(self.settingConst):] + return self.handle_settings_change_with_response(settings_text) + elif upper_event_data.startswith(self.commandConst): + command_text = event_data[len(self.commandConst):] + return self.handle_command_execution_with_response(command_text) else: - return {"success": False, "message": "Unknown command format. Use 'COMMAND ...' or 'SETTING ...'"} + return { + "success": False, + "message": "Unknown command format. Use 'COMMAND ...' or 'SETTING ...'"} except Exception as e: return {"success": False, "message": f"Exception: {str(e)}"} - - def handleRemoteIncomming(self, eventData): - if not eventData: - return - upperEventData = eventData.upper() - self.env['runtime']['debug'].writeDebugOut('remoteManager:handleRemoteIncomming: event: ' + str(eventData),debug.debugLevel.INFO) - if upperEventData.startswith(self.settingConst): - settingsText = eventData[len(self.settingConst):] - self.handleSettingsChange(settingsText) - elif upperEventData.startswith(self.commandConst): - commandText = eventData[len(self.commandConst):] - self.handleCommandExecution(commandText) + def handle_remote_incomming(self, event_data): + if not event_data: + return + upper_event_data = event_data.upper() + self.env['runtime']['DebugManager'].write_debug_out( + 'RemoteManager:handle_remote_incomming: event: ' + + str(event_data), + debug.DebugLevel.INFO) + + if upper_event_data.startswith(self.settingConst): + settings_text = event_data[len(self.settingConst):] + self.handle_settings_change(settings_text) + elif upper_event_data.startswith(self.commandConst): + command_text = event_data[len(self.commandConst):] + self.handle_command_execution(command_text) diff --git a/src/fenrirscreenreader/core/runtimeData.py b/src/fenrirscreenreader/core/runtimeData.py index c2677f1d..9d2d26cb 100644 --- a/src/fenrirscreenreader/core/runtimeData.py +++ b/src/fenrirscreenreader/core/runtimeData.py @@ -6,15 +6,19 @@ from fenrirscreenreader.core import debug -runtimeData = { -'speechDriver': None, -'screenDriver': None, -'soundDriver': None, -'inputDriver': None, -'remoteDriver': None, -'inputManager': None, -'commandManager': None, -'screenManager': None, -'outputManager': None, -'debug':None, +runtime_data = { + 'SpeechDriver': None, + 'ScreenDriver': None, + 'SoundDriver': None, + 'InputDriver': None, + 'RemoteDriver': None, + 'InputManager': None, + 'CommandManager': None, + 'ScreenManager': None, + 'OutputManager': None, + 'DebugManager': None, + 'SettingsManager': None, + 'FenrirManager': None, + 'EventManager': None, + 'ProcessManager': None, } diff --git a/src/fenrirscreenreader/core/sayAllManager.py b/src/fenrirscreenreader/core/sayAllManager.py index 73865c50..95dc63d0 100644 --- a/src/fenrirscreenreader/core/sayAllManager.py +++ b/src/fenrirscreenreader/core/sayAllManager.py @@ -6,25 +6,35 @@ from fenrirscreenreader.core import debug -class sayAllManager(): + +class SayAllManager(): def __init__(self): self.isActive = False self.isActiveLock = None + def initialize(self, environment): - self.env = environment + self.env = environment + def shutdown(self): pass - def setIsActive(self, isActive): + + def set_is_active(self, isActive): pass + def start(self): pass - def isSayAllActive(self): + + def is_say_all_active(self): pass - def sayAllWorker(self): + + def say_all_worker(self): pass + def stop(self): pass + def finish(self): pass - def gotoNextPage(self): + + def goto_next_page(self): pass diff --git a/src/fenrirscreenreader/core/screenData.py b/src/fenrirscreenreader/core/screenData.py index d090f26b..86fef3ca 100644 --- a/src/fenrirscreenreader/core/screenData.py +++ b/src/fenrirscreenreader/core/screenData.py @@ -7,31 +7,31 @@ from fenrirscreenreader.core import debug import time -screenData = { -'columns': 0, -'lines': 0, -'oldDelta': '', -'oldAttribDelta': '', -'oldNegativeDelta': '', -'oldCursorReview':None, -'oldCursorAttrib':None, -'oldCursor':{'x':0,'y':0}, -'oldContentBytes': b'', -'oldContentText': '', -'oldContentAttrib': None, -'oldApplication': '', -'oldTTY':None, -'newDelta': '', -'newNegativeDelta': '', -'newAttribDelta': '', -'newCursorReview':None, -'newCursorAttrib':None, -'newCursor':{'x':0,'y':0}, -'newContentBytes': b'', -'newContentText': '', -'newContentAttrib': None, -'newTTY':'0', -'newApplication': '', -'lastScreenUpdate': time.time(), -'autoIgnoreScreens':[], +screen_data = { + 'columns': 0, + 'lines': 0, + 'oldDelta': '', + 'oldAttribDelta': '', + 'oldNegativeDelta': '', + 'oldCursorReview': None, + 'oldCursorAttrib': None, + 'old_cursor': {'x': 0, 'y': 0}, + 'oldContentBytes': b'', + 'old_content_text': '', + 'oldContentAttrib': None, + 'oldApplication': '', + 'oldTTY': None, + 'new_delta': '', + 'newNegativeDelta': '', + 'newAttribDelta': '', + 'newCursorReview': None, + 'newCursorAttrib': None, + 'new_cursor': {'x': 0, 'y': 0}, + 'newContentBytes': b'', + 'new_content_text': '', + 'newContentAttrib': None, + 'newTTY': '0', + 'new_application': '', + 'lastScreenUpdate': time.time(), + 'autoIgnoreScreens': [], } diff --git a/src/fenrirscreenreader/core/screenDriver.py b/src/fenrirscreenreader/core/screenDriver.py index df03b90a..71f3ee68 100644 --- a/src/fenrirscreenreader/core/screenDriver.py +++ b/src/fenrirscreenreader/core/screenDriver.py @@ -5,22 +5,54 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ -class screenDriver(): + +class ScreenDriver(): def __init__(self): - self._isInitialized = False - self.bgColorNames = {0: _('black'), 1: _('blue'), 2: _('green'), 3: _('cyan'), 4: _('red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('white')} - self.fgColorNames = {0: _('Black'), 1: _('Blue'), 2: _('Green'), 3: _('Cyan'), 4: _('Red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('Light gray'), 8: _('Dark gray'), 9: _('Light blue'), 10: ('Light green'), 11: _('Light cyan'), 12: _('Light red'), 13: _('Light magenta'), 14: _('Light yellow'), 15: _('White')} + self._is_initialized = False + self.bgColorNames = { + 0: _('black'), + 1: _('blue'), + 2: _('green'), + 3: _('cyan'), + 4: _('red'), + 5: _('Magenta'), + 6: _('brown/yellow'), + 7: _('white')} + self.fgColorNames = { + 0: _('Black'), + 1: _('Blue'), + 2: _('Green'), + 3: _('Cyan'), + 4: _('Red'), + 5: _('Magenta'), + 6: _('brown/yellow'), + 7: _('Light gray'), + 8: _('Dark gray'), + 9: _('Light blue'), + 10: ('Light green'), + 11: _('Light cyan'), + 12: _('Light red'), + 13: _('Light magenta'), + 14: _('Light yellow'), + 15: _('White')} + def initialize(self, environment): self.env = environment - self._isInitialized = True + self._is_initialized = True + def shutdown(self): - self._isInitialized = False - def getCurrScreen(self): + self._is_initialized = False + + def get_curr_screen(self): pass - def injectTextToScreen(self, text, screen = None): + + def inject_text_to_screen(self, text, screen=None): pass - def getCurrApplication(self): + + def get_curr_application(self): pass - def getSessionInformation(self): + + def get_session_information(self): pass diff --git a/src/fenrirscreenreader/core/screenManager.py b/src/fenrirscreenreader/core/screenManager.py index 92239325..d40d0f92 100644 --- a/src/fenrirscreenreader/core/screenManager.py +++ b/src/fenrirscreenreader/core/screenManager.py @@ -6,9 +6,13 @@ from fenrirscreenreader.core import debug from fenrirscreenreader.utils import screen_utils -import time, os, re, difflib +import time +import os +import re +import difflib -class screenManager(): + +class ScreenManager(): def __init__(self): self.differ = difflib.Differ() self.currScreenIgnored = False @@ -18,255 +22,337 @@ class screenManager(): self.colums = None self.rows = None # Compile regex once for better performance - self._space_normalize_regex = re.compile(' +') - def getRows(self): + self._space_normalize_regex = re.compile(' +') + + def get_rows(self): return self.rows - def getColumns(self): + + def get_columns(self): return self.colums + def initialize(self, environment): self.env = environment - self.env['runtime']['settingsManager'].loadDriver(\ - self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver') - self.getCurrScreen() - self.getCurrScreen() - self.getSessionInformation() - self.updateScreenIgnored() - self.updateScreenIgnored() - def resetScreenText(self, screenText): + self.env['runtime']['SettingsManager'].load_driver( + self.env['runtime']['SettingsManager'].get_setting( + 'screen', 'driver'), 'ScreenDriver') + self.get_curr_screen() + self.get_curr_screen() + self.get_session_information() + self.update_screen_ignored() + self.update_screen_ignored() + + def reset_screen_text(self, screen_text): self.prevScreenText = '' - self.currScreenText = screenText - def setScreenText(self, screenText): + self.currScreenText = screen_text + + def set_screen_text(self, screen_text): self.prevScreenText = self.currScreenText - self.currScreenText = screenText - def getScreenText(self): + self.currScreenText = screen_text + + def get_screen_text(self): return self.currScreenText - def getCurrScreen(self): + + def get_curr_screen(self): try: - self.env['runtime']['screenDriver'].getCurrScreen() + self.env['runtime']['ScreenDriver'].get_curr_screen() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('screenManager getCurrScreen: Error getting current screen: ' + str(e), debug.debugLevel.ERROR) - def getSessionInformation(self): + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenManager get_curr_screen: Error getting current screen: ' + str(e), + debug.DebugLevel.ERROR) + + def get_session_information(self): try: - self.env['runtime']['screenDriver'].getSessionInformation() + self.env['runtime']['ScreenDriver'].get_session_information() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('screenManager getSessionInformation: Error getting session info: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenManager get_session_information: Error getting session info: ' + str(e), + debug.DebugLevel.ERROR) + def shutdown(self): - self.env['runtime']['settingsManager'].shutdownDriver('screenDriver') - def isCurrScreenIgnoredChanged(self): - return self.getCurrScreenIgnored() != self.getPrevScreenIgnored() - def handleScreenChange(self, eventData): - self.getCurrScreen() - self.getSessionInformation() - self.updateScreenIgnored() - if self.isCurrScreenIgnoredChanged(): - self.env['runtime']['inputManager'].setExecuteDeviceGrab() - self.env['runtime']['inputManager'].handleDeviceGrab() - if not self.isIgnoredScreen(self.env['screen']['newTTY']): - self.update(eventData, 'onScreenChange') + self.env['runtime']['SettingsManager'].shutdown_driver('ScreenDriver') + + def is_curr_screen_ignored_changed(self): + return self.get_curr_screen_ignored() != self.get_prev_screen_ignored() + + def handle_screen_change(self, event_data): + self.get_curr_screen() + self.get_session_information() + self.update_screen_ignored() + if self.is_curr_screen_ignored_changed(): + self.env['runtime']['InputManager'].set_execute_device_grab() + self.env['runtime']['InputManager'].handle_device_grab() + if not self.is_ignored_screen(self.env['screen']['newTTY']): + self.update(event_data, 'onScreenChange') self.env['screen']['lastScreenUpdate'] = time.time() else: - self.env['runtime']['outputManager'].interruptOutput() - def handleScreenUpdate(self, eventData): - self.env['screen']['oldApplication'] = self.env['screen']['newApplication'] - self.updateScreenIgnored() - if self.isCurrScreenIgnoredChanged(): - self.env['runtime']['inputManager'].setExecuteDeviceGrab() - self.env['runtime']['inputManager'].handleDeviceGrab() - if not self.getCurrScreenIgnored(): - self.update(eventData, 'onScreenUpdate') + self.env['runtime']['OutputManager'].interrupt_output() + + def handle_screen_update(self, event_data): + self.env['screen']['oldApplication'] = self.env['screen']['new_application'] + self.update_screen_ignored() + if self.is_curr_screen_ignored_changed(): + self.env['runtime']['InputManager'].set_execute_device_grab() + self.env['runtime']['InputManager'].handle_device_grab() + if not self.get_curr_screen_ignored(): + self.update(event_data, 'onScreenUpdate') self.env['screen']['lastScreenUpdate'] = time.time() - elif self.isCurrScreenIgnoredChanged(): - self.env['runtime']['outputManager'].interruptOutput() - def getCurrScreenIgnored(self): + elif self.is_curr_screen_ignored_changed(): + self.env['runtime']['OutputManager'].interrupt_output() + + def get_curr_screen_ignored(self): return self.currScreenIgnored - def getPrevScreenIgnored(self): + + def get_prev_screen_ignored(self): return self.prevScreenIgnored - def updateScreenIgnored(self): + + def update_screen_ignored(self): self.prevScreenIgnored = self.currScreenIgnored - self.currScreenIgnored = self.isIgnoredScreen(self.env['screen']['newTTY']) - def update(self, eventData, trigger='onUpdate'): + self.currScreenIgnored = self.is_ignored_screen( + self.env['screen']['newTTY']) + + def update(self, event_data, trigger='onUpdate'): # set new "old" values self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes'] - self.env['screen']['oldContentText'] = self.env['screen']['newContentText'] - self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy() - self.env['screen']['oldDelta'] = self.env['screen']['newDelta'] + self.env['screen']['old_content_text'] = self.env['screen']['new_content_text'] + self.env['screen']['old_cursor'] = self.env['screen']['new_cursor'].copy() + self.env['screen']['oldDelta'] = self.env['screen']['new_delta'] self.env['screen']['oldNegativeDelta'] = self.env['screen']['newNegativeDelta'] - self.env['screen']['newContentBytes'] = eventData['bytes'] + self.env['screen']['newContentBytes'] = event_data['bytes'] # get metadata like cursor or screensize - self.env['screen']['lines'] = int( eventData['lines']) - self.env['screen']['columns'] = int( eventData['columns']) - self.colums = int( eventData['columns']) - self.rows = int( eventData['lines']) - self.env['screen']['newCursor']['x'] = int( eventData['textCursor']['x']) - self.env['screen']['newCursor']['y'] = int( eventData['textCursor']['y']) - self.env['screen']['newTTY'] = eventData['screen'] - self.env['screen']['newContentText'] = eventData['text'] + self.env['screen']['lines'] = int(event_data['lines']) + self.env['screen']['columns'] = int(event_data['columns']) + self.colums = int(event_data['columns']) + self.rows = int(event_data['lines']) + self.env['screen']['new_cursor']['x'] = int( + event_data['textCursor']['x']) + self.env['screen']['new_cursor']['y'] = int( + event_data['textCursor']['y']) + self.env['screen']['newTTY'] = event_data['screen'] + self.env['screen']['new_content_text'] = event_data['text'] # screen change - if self.isScreenChange(): + if self.is_screen_change(): self.env['screen']['oldContentBytes'] = b'' - self.resetScreenText(eventData['text']) - self.env['runtime']['attributeManager'].resetAttributes(eventData['attributes']) - self.env['runtime']['attributeManager'].resetAttributeCursor() - self.env['screen']['oldContentText'] = '' - self.env['screen']['oldCursor']['x'] = 0 - self.env['screen']['oldCursor']['y'] = 0 + self.reset_screen_text(event_data['text']) + self.env['runtime']['AttributeManager'].reset_attributes( + event_data['attributes']) + self.env['runtime']['AttributeManager'].reset_attribute_cursor() + self.env['screen']['old_content_text'] = '' + self.env['screen']['old_cursor']['x'] = 0 + self.env['screen']['old_cursor']['y'] = 0 self.env['screen']['oldDelta'] = '' self.env['screen']['oldNegativeDelta'] = '' else: - self.setScreenText(eventData['text']) - self.env['runtime']['attributeManager'].setAttributes(eventData['attributes']) + self.set_screen_text(event_data['text']) + self.env['runtime']['AttributeManager'].set_attributes( + event_data['attributes']) # initialize current deltas self.env['screen']['newNegativeDelta'] = '' - self.env['screen']['newDelta'] = '' - self.env['runtime']['attributeManager'].resetAttributeDelta() + self.env['screen']['new_delta'] = '' + self.env['runtime']['AttributeManager'].reset_attribute_delta() # Diff generation - critical for screen reader functionality # This code detects and categorizes screen content changes to provide appropriate # speech feedback (typing echo vs incoming text vs screen updates) - - # Track whether this appears to be typing (user input) vs other screen changes - typing = False - diffList = [] - if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']): + # Track whether this appears to be typing (user input) vs other screen + # changes + typing = False + diff_list = [] + + if (self.env['screen']['old_content_text'] != + self.env['screen']['new_content_text']): # Special case: Initial screen content (going from empty to populated) # This handles first screen load or TTY switch scenarios - if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '': + if self.env['screen']['new_content_text'] != '' and self.env['screen']['old_content_text'] == '': # Pre-process screen text for comparison - collapse multiple spaces to single space - # This normalization prevents spurious diffs from spacing inconsistencies - oldScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText'])) - newScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText'])) - if oldScreenText == '' and\ - newScreenText != '': - self.env['screen']['newDelta'] = newScreenText + # This normalization prevents spurious diffs from spacing + # inconsistencies + old_screen_text = self._space_normalize_regex.sub( + ' ', self.env['runtime']['ScreenManager'].get_window_area_in_text( + self.env['screen']['old_content_text'])) + new_screen_text = self._space_normalize_regex.sub( + ' ', self.env['runtime']['ScreenManager'].get_window_area_in_text( + self.env['screen']['new_content_text'])) + if old_screen_text == '' and\ + new_screen_text != '': + self.env['screen']['new_delta'] = new_screen_text else: # Calculate byte positions for the current cursor's line in the flat text buffer # Formula: (line_number * columns) + line_number accounts for newlines # Each line contributes 'columns' chars + 1 newline char - cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y'] - cursorLineEnd = cursorLineStart + self.env['screen']['columns'] - + cursor_line_start = self.env['screen']['new_cursor']['y'] * \ + self.env['screen']['columns'] + self.env['screen']['new_cursor']['y'] + cursor_line_end = cursor_line_start + self.env['screen']['columns'] + # TYPING DETECTION ALGORITHM # Determines if this screen change is likely user typing vs other content changes # All conditions must be met for typing detection: - if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) >= 1 and \ - self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \ - self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \ - self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]: + if abs(self.env['screen']['old_cursor']['x'] - self.env['screen']['new_cursor']['x']) >= 1 and \ + self.env['screen']['old_cursor']['y'] == self.env['screen']['new_cursor']['y'] and \ + self.env['screen']['new_content_text'][:cursor_line_start] == self.env['screen']['old_content_text'][:cursor_line_start] and \ + self.env['screen']['new_content_text'][cursor_line_end:] == self.env['screen']['old_content_text'][cursor_line_end:]: # Condition 1: Cursor moved horizontally by at least 1 position (typical of typing) # Condition 2: Cursor stayed on same line (typing doesn't usually change lines) # Condition 3: Content BEFORE cursor line is unchanged (text above typing area) # Condition 4: Content AFTER cursor line is unchanged (text below typing area) - # Together: only the current line changed, cursor moved horizontally = likely typing - - # Optimize diff calculation for typing by focusing on a small window around cursor - cursorLineStartOffset = cursorLineStart - cursorLineEndOffset = cursorLineEnd - + # Together: only the current line changed, cursor moved + # horizontally = likely typing + + # Optimize diff calculation for typing by focusing on a + # small window around cursor + cursor_line_start_offset = cursor_line_start + cursor_line_end_offset = cursor_line_end + # Limit analysis window to avoid processing entire long lines # +3 provides safety buffer beyond cursor position to catch edge cases - if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3: - cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3 - - # Extract just the relevant text sections for character-level diff - oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset] - newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset] - - # Character-level diff for typing detection (not line-level) - diff = self.differ.compare(oldScreenText, newScreenText) - diffList = list(diff) + if cursor_line_end > cursor_line_start + \ + self.env['screen']['new_cursor']['x'] + 3: + cursor_line_end_offset = cursor_line_start + \ + self.env['screen']['new_cursor']['x'] + 3 + + # Extract just the relevant text sections for + # character-level diff + old_screen_text = self.env['screen']['old_content_text'][cursor_line_start_offset:cursor_line_end_offset] + new_screen_text = self.env['screen']['new_content_text'][cursor_line_start_offset:cursor_line_end_offset] + + # Character-level diff for typing detection (not + # line-level) + diff = self.differ.compare(old_screen_text, new_screen_text) + diff_list = list(diff) typing = True - - # Validate typing assumption by checking if detected changes match cursor movement - tempNewDelta = ''.join(x[2:] for x in diffList if x[0] == '+') - if tempNewDelta.strip() != '': + + # Validate typing assumption by checking if detected + # changes match cursor movement + temp_new_delta = ''.join(x[2:] + for x in diff_list if x[0] == '+') + if temp_new_delta.strip() != '': # Compare diff result against expected typing pattern - # Expected: characters between old and new cursor positions - expectedTyping = ''.join(newScreenText[self.env['screen']['oldCursor']['x']:self.env['screen']['newCursor']['x']].rstrip()) - - # If diff doesn't match expected typing pattern, treat as general screen change - if tempNewDelta != expectedTyping: - # Fallback: treat entire current line as new content - diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n'] + # Expected: characters between old and new cursor + # positions + expected_typing = ''.join( + new_screen_text[self.env['screen']['old_cursor']['x']:self.env['screen']['new_cursor']['x']].rstrip()) + + # If diff doesn't match expected typing pattern, treat + # as general screen change + if temp_new_delta != expected_typing: + # Fallback: treat entire current line as new + # content + diff_list = [ + '+ ' + + self.env['screen']['new_content_text'].split('\n')[ + self.env['screen']['new_cursor']['y']] + + '\n'] typing = False else: # GENERAL SCREEN CHANGE DETECTION # Not typing - handle as line-by-line content change - # This catches: incoming messages, screen updates, application output, etc. - + # This catches: incoming messages, screen updates, + # application output, etc. + # Pre-process screen text for comparison - collapse multiple spaces to single space - # This normalization prevents spurious diffs from spacing inconsistencies - oldScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText'])) - newScreenText = self._space_normalize_regex.sub(' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText'])) - - diff = self.differ.compare(oldScreenText.split('\n'),\ - newScreenText.split('\n')) - diffList = list(diff) + # This normalization prevents spurious diffs from spacing + # inconsistencies + old_screen_text = self._space_normalize_regex.sub( + ' ', self.env['runtime']['ScreenManager'].get_window_area_in_text( + self.env['screen']['old_content_text'])) + new_screen_text = self._space_normalize_regex.sub( + ' ', self.env['runtime']['ScreenManager'].get_window_area_in_text( + self.env['screen']['new_content_text'])) + + diff = self.differ.compare(old_screen_text.split('\n'), + new_screen_text.split('\n')) + diff_list = list(diff) # Extract added and removed content from diff results - # Output format depends on whether this was detected as typing or general change + # Output format depends on whether this was detected as typing + # or general change if not typing: - # Line-based changes: join with newlines for proper speech cadence - self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+') + # Line-based changes: join with newlines for proper speech + # cadence + self.env['screen']['new_delta'] = '\n'.join( + x[2:] for x in diff_list if x[0] == '+') else: - # Character-based changes: no newlines for smooth typing echo - self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+') - - # Negative delta (removed content) - used for backspace/delete detection - self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-') + # Character-based changes: no newlines for smooth typing + # echo + self.env['screen']['new_delta'] = ''.join( + x[2:] for x in diff_list if x[0] == '+') + + # Negative delta (removed content) - used for backspace/delete + # detection + self.env['screen']['newNegativeDelta'] = ''.join( + x[2:] for x in diff_list if x[0] == '-') # track highlighted try: - if self.env['runtime']['attributeManager'].isAttributeChange(): - if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'): - attributeDelta, attributeCursor = self.env['runtime']['attributeManager'].trackHighlights() + if self.env['runtime']['AttributeManager'].is_attribute_change(): + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'focus', 'highlight'): + attribute_delta, attributeCursor = self.env['runtime']['AttributeManager'].track_highlights( + ) if attributeCursor: - self.env['runtime']['attributeManager'].setAttributeCursor(attributeCursor) - self.env['runtime']['attributeManager'].setAttributeDelta(attributeDelta) + self.env['runtime']['AttributeManager'].set_attribute_cursor( + attributeCursor) + self.env['runtime']['AttributeManager'].set_attribute_delta( + attribute_delta) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('screenManager:update:highlight: ' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenManager:update:highlight: ' + str(e), debug.DebugLevel.ERROR) - def isIgnoredScreen(self, screen = None): - if screen == None: + def is_ignored_screen(self, screen=None): + if screen is None: screen = self.env['screen']['newTTY'] # Check if force all screens flag is set if self.env['runtime'].get('force_all_screens', False): return False - ignoreScreens = [] - fixIgnoreScreens = self.env['runtime']['settingsManager'].getSetting('screen', 'ignoreScreen') - if fixIgnoreScreens != '': - ignoreScreens.extend(fixIgnoreScreens.split(',')) - if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectIgnoreScreen'): - ignoreScreens.extend(self.env['screen']['autoIgnoreScreens']) - self.env['runtime']['debug'].writeDebugOut('screenManager:isIgnoredScreen ignore:' + str(ignoreScreens) + ' current:'+ str(screen ), debug.debugLevel.INFO) - return (screen in ignoreScreens) - - def isScreenChange(self): + ignore_screens = [] + fix_ignore_screens = self.env['runtime']['SettingsManager'].get_setting( + 'screen', 'ignoreScreen') + if fix_ignore_screens != '': + ignore_screens.extend(fix_ignore_screens.split(',')) + if self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'screen', 'autodetectIgnoreScreen'): + ignore_screens.extend(self.env['screen']['autoIgnoreScreens']) + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenManager:is_ignored_screen ignore:' + + str(ignore_screens) + + ' current:' + + str(screen), + debug.DebugLevel.INFO) + return (screen in ignore_screens) + + def is_screen_change(self): if not self.env['screen']['oldTTY']: return False return self.env['screen']['newTTY'] != self.env['screen']['oldTTY'] - def isDelta(self, ignoreSpace=False): - newDelta = self.env['screen']['newDelta'] - if ignoreSpace: - newDelta = newDelta.strip() - return newDelta != '' - def isNegativeDelta(self): - return self.env['screen']['newNegativeDelta'] != '' - def getWindowAreaInText(self, text): - if not self.env['runtime']['cursorManager'].isApplicationWindowSet(): - return text - windowText = '' - windowList = text.split('\n') - currApp = self.env['runtime']['applicationManager'].getCurrentApplication() - windowList = windowList[self.env['commandBuffer']['windowArea'][currApp]['1']['y']:self.env['commandBuffer']['windowArea'][currApp]['2']['y'] + 1] - for line in windowList: - windowText += line[self.env['commandBuffer']['windowArea'][currApp]['1']['x']:self.env['commandBuffer']['windowArea'][currApp]['2']['x'] + 1] + '\n' - return windowText - def injectTextToScreen(self, text, screen = None): + def is_delta(self, ignoreSpace=False): + new_delta = self.env['screen']['new_delta'] + if ignoreSpace: + new_delta = new_delta.strip() + return new_delta != '' + + def is_negative_delta(self): + return self.env['screen']['newNegativeDelta'] != '' + + def get_window_area_in_text(self, text): + if not self.env['runtime']['CursorManager'].is_application_window_set(): + return text + window_text = '' + window_list = text.split('\n') + curr_app = self.env['runtime']['ApplicationManager'].get_current_application() + window_list = window_list[self.env['commandBuffer']['windowArea'][curr_app][ + '1']['y']:self.env['commandBuffer']['windowArea'][curr_app]['2']['y'] + 1] + for line in window_list: + window_text += line[self.env['commandBuffer']['windowArea'][curr_app]['1']['x'] + :self.env['commandBuffer']['windowArea'][curr_app]['2']['x'] + 1] + '\n' + return window_text + + def inject_text_to_screen(self, text, screen=None): try: - self.env['runtime']['screenDriver'].injectTextToScreen(text, screen) + self.env['runtime']['ScreenDriver'].inject_text_to_screen( + text, screen) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenManager:inject_text_to_screen ' + str(e), debug.DebugLevel.ERROR) diff --git a/src/fenrirscreenreader/core/settingsData.py b/src/fenrirscreenreader/core/settingsData.py index d5c681e8..7cbc8b3c 100644 --- a/src/fenrirscreenreader/core/settingsData.py +++ b/src/fenrirscreenreader/core/settingsData.py @@ -6,119 +6,119 @@ from fenrirscreenreader.core import debug -settingsData = { -'sound': { - 'enabled': True, - 'driver': 'genericDriver', - 'theme': 'default', - 'volume': 1.0, - 'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile', - 'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' -}, -'speech':{ - 'enabled': True, - 'driver': 'genericDriver', - 'serverPath': '', - 'rate': 0.75, - 'pitch': 0.5, - 'capitalPitch':0.8, - 'volume': 1.0, - 'module': '', - 'voice': 'en-us', - 'language': '', - 'autoReadIncoming': True, - 'readNumbersAsDigits': False, - 'genericSpeechCommand':'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"', - 'fenrirMinVolume':0, - 'fenrirMaxVolume':200, - 'fenrirMinPitch':0, - 'fenrirMaxPitch':99, - 'fenrirMinRate':80, - 'fenrirMaxRate':450, -}, -'screen':{ - 'driver': 'vcsaDriver', - 'encoding': 'auto', - 'screenUpdateDelay': 0.1, - 'ignoreScreen': '', - 'autodetectIgnoreScreen': False, -}, -'general':{ - 'debugLevel': debug.debugLevel.DEACTIVE, - 'debugMode': 'FILE', - 'debugFile': '', - 'punctuationProfile':'default', - 'punctuationLevel': 'some', - 'respectPunctuationPause':True, - 'newLinePause':True, - 'numberOfClipboards': 10, - 'emoticons': True, - 'fenrirKeys': 'KEY_KP0,KEY_META', - 'scriptKeys': 'KEY_COMPOSE', - 'timeFormat': '%I:%M%P', - 'dateFormat': '%A, %B %d, %Y', - 'autoSpellCheck': False, - 'spellCheckLanguage': 'en_US', - 'scriptPath': '/usr/share/fenrirscreenreader/scripts', - 'commandPath': '/usr/share/fenrirscreenreader/commands', - 'attributeFormatString': 'Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize', - 'autoPresentIndent': False, - 'autoPresentIndentMode': 1, - 'hasAttributes': True, - 'shell': '', -}, -'focus':{ - 'cursor': True, - 'highlight': False, -}, -'remote':{ - 'enabled': True, - 'driver': 'unixDriver', - 'port': 22447, - 'socketFile':'', - 'enableSettingsRemote': True, - 'enableCommandRemote': True, -}, -'barrier':{ - 'enabled': True, - 'leftBarriers': '│└┌─', - 'rightBarriers': '│┘┐─', -}, -'review':{ - 'lineBreak': True, - 'endOfScreen': True, - 'leaveReviewOnCursorChange': True, - 'leaveReviewOnScreenChange': True, -}, -'menu':{ - 'vmenuPath': '', - 'quickMenu': 'speech#rate;speech#pitch;speech#volume', -}, -'promote':{ - 'enabled': True, - 'inactiveTimeoutSec': 120, - 'list': '', -}, -'time':{ - 'enabled': False, - 'presentTime': True, - 'presentDate': True, - 'delaySec': 0, - 'onMinutes': '00,30', - 'announce': True, - 'interrupt': False, -}, -'keyboard':{ - 'driver': 'evdev', - 'device': 'all', - 'grabDevices': True, - 'ignoreShortcuts': False, - 'keyboardLayout': "desktop", - 'charEchoMode': 2, # while capslock - 'charDeleteEcho': True, - 'wordEcho': True, - 'interruptOnKeyPress': True, - 'interruptOnKeyPressFilter': '', - 'doubleTapTimeout': 0.2, -} +settings_data = { + 'sound': { + 'enabled': True, + 'driver': 'genericDriver', + 'theme': 'default', + 'volume': 1.0, + 'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile', + 'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' + }, + 'speech': { + 'enabled': True, + 'driver': 'genericDriver', + 'serverPath': '', + 'rate': 0.75, + 'pitch': 0.5, + 'capitalPitch': 0.8, + 'volume': 1.0, + 'module': '', + 'voice': 'en-us', + 'language': '', + 'autoReadIncoming': True, + 'readNumbersAsDigits': False, + 'genericSpeechCommand': 'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"', + 'fenrirMinVolume': 0, + 'fenrirMaxVolume': 200, + 'fenrirMinPitch': 0, + 'fenrirMaxPitch': 99, + 'fenrirMinRate': 80, + 'fenrirMaxRate': 450, + }, + 'screen': { + 'driver': 'vcsaDriver', + 'encoding': 'auto', + 'screenUpdateDelay': 0.1, + 'ignoreScreen': '', + 'autodetectIgnoreScreen': False, + }, + 'general': { + 'debug_level': debug.DebugLevel.DEACTIVE, + 'debug_mode': 'FILE', + 'debugFile': '', + 'punctuationProfile': 'default', + 'punctuationLevel': 'some', + 'respectPunctuationPause': True, + 'newLinePause': True, + 'numberOfClipboards': 10, + 'emoticons': True, + 'fenrirKeys': 'KEY_KP0,KEY_META', + 'scriptKeys': 'KEY_COMPOSE', + 'time_format': '%I:%M%P', + 'date_format': '%A, %B %d, %Y', + 'autoSpellCheck': False, + 'spellCheckLanguage': 'en_US', + 'script_path': '/usr/share/fenrirscreenreader/scripts', + 'command_path': '/usr/share/fenrirscreenreader/commands', + 'attribute_format_string': 'Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize', + 'autoPresentIndent': False, + 'autoPresentIndentMode': 1, + 'has_attributes': True, + 'shell': '', + }, + 'focus': { + 'cursor': True, + 'highlight': False, + }, + 'remote': { + 'enabled': True, + 'driver': 'unixDriver', + 'port': 22447, + 'socket_file': '', + 'enableSettingsRemote': True, + 'enableCommandRemote': True, + }, + 'barrier': { + 'enabled': True, + 'left_barriers': '│└┌─', + 'right_barriers': '│┘┐─', + }, + 'review': { + 'line_break': True, + 'end_of_screen': True, + 'leaveReviewOnCursorChange': True, + 'leaveReviewOnScreenChange': True, + }, + 'menu': { + 'vmenuPath': '', + 'quickMenu': 'speech#rate;speech#pitch;speech#volume', + }, + 'promote': { + 'enabled': True, + 'inactiveTimeoutSec': 120, + 'list': '', + }, + 'time': { + 'enabled': False, + 'present_time': True, + 'present_date': True, + 'delay_sec': 0, + 'on_minutes': '00,30', + 'announce': True, + 'interrupt': False, + }, + 'keyboard': { + 'driver': 'evdev', + 'device': 'all', + 'grabDevices': True, + 'ignoreShortcuts': False, + 'keyboardLayout': "desktop", + 'charEchoMode': 2, # while capslock + 'charDeleteEcho': True, + 'wordEcho': True, + 'interruptOnKeyPress': True, + 'interruptOnKeyPressFilter': '', + 'doubleTapTimeout': 0.2, + } } diff --git a/src/fenrirscreenreader/core/settingsManager.py b/src/fenrirscreenreader/core/settingsManager.py index 9ae333d0..ef422dee 100644 --- a/src/fenrirscreenreader/core/settingsManager.py +++ b/src/fenrirscreenreader/core/settingsManager.py @@ -4,123 +4,154 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -import os, inspect - -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) - -from configparser import ConfigParser -from fenrirscreenreader.core import debugManager -from fenrirscreenreader.core import memoryManager -from fenrirscreenreader.core import processManager -from fenrirscreenreader.core import eventManager -from fenrirscreenreader.core import inputManager -from fenrirscreenreader.core import outputManager -from fenrirscreenreader.core import commandManager -from fenrirscreenreader.core import screenManager -from fenrirscreenreader.core import punctuationManager -from fenrirscreenreader.core import cursorManager -from fenrirscreenreader.core import applicationManager -from fenrirscreenreader.core import helpManager -from fenrirscreenreader.core import vmenuManager -from fenrirscreenreader.core import textManager -from fenrirscreenreader.core import tableManager -from fenrirscreenreader.core import byteManager -from fenrirscreenreader.core import attributeManager -from fenrirscreenreader.core import barrierManager -from fenrirscreenreader.core import remoteManager -from fenrirscreenreader.core import sayAllManager -from fenrirscreenreader.core import quickMenuManager -from fenrirscreenreader.core import environment -from fenrirscreenreader.core.settingsData import settingsData -from fenrirscreenreader.core import debug +from fenrirscreenreader.core import environment from fenrirscreenreader.utils import module_utils +from fenrirscreenreader.core import debug +from fenrirscreenreader.core.settingsData import settings_data +from fenrirscreenreader.core import quickMenuManager +from fenrirscreenreader.core import sayAllManager +from fenrirscreenreader.core import remoteManager +from fenrirscreenreader.core import barrierManager +from fenrirscreenreader.core import attributeManager +from fenrirscreenreader.core import byteManager +from fenrirscreenreader.core import tableManager +from fenrirscreenreader.core import textManager +from fenrirscreenreader.core import vmenuManager +from fenrirscreenreader.core import helpManager +from fenrirscreenreader.core import applicationManager +from fenrirscreenreader.core import cursorManager +from fenrirscreenreader.core import punctuationManager +from fenrirscreenreader.core import screenManager +from fenrirscreenreader.core import commandManager +from fenrirscreenreader.core import outputManager +from fenrirscreenreader.core import inputManager +from fenrirscreenreader.core import eventManager +from fenrirscreenreader.core import processManager +from fenrirscreenreader.core import memoryManager +from fenrirscreenreader.core import debugManager +from configparser import ConfigParser +import os +import inspect -class settingsManager(): +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) + + +class SettingsManager(): def __init__(self): - self.settings = settingsData + self.settings = settings_data self.settingArgDict = {} self.bindingsBackup = None - self.settingsFile = '' + self.settings_file = '' + def initialize(self, environment): self.env = environment + def shutdown(self): pass - def getBindingBackup(self): + + def get_binding_backup(self): return self.bindingsBackup.copy() - def loadSoundIcons(self, soundIconPath): + + def load_sound_icons(self, soundIconPath, environment=None): + # Use passed environment or fall back to self.env + env = environment if environment is not None else self.env try: with open(soundIconPath + '/soundicons.conf', "r") as siConfig: - while(True): + while (True): line = siConfig.readline() if not line: break - line = line.replace('\n','') - if line.replace(" ","") == '': + line = line.replace('\n', '') + if line.replace(" ", "") == '': continue - if line.replace(" ","").startswith("#"): + if line.replace(" ", "").startswith("#"): continue if line.count("=") != 1: continue - Values = line.split('=') - soundIcon = Values[0].upper() - Values[1] = Values[1].replace("'","") - Values[1] = Values[1].replace('"',"") - soundIconFile = '' - if os.path.exists(Values[1]): - soundIconFile = Values[1] + values = line.split('=') + sound_icon = values[0].upper() + values[1] = values[1].replace("'", "") + values[1] = values[1].replace('"', "") + sound_icon_file = '' + if os.path.exists(values[1]): + sound_icon_file = values[1] else: if not soundIconPath.endswith("/"): soundIconPath += '/' - if os.path.exists(soundIconPath + Values[1]): - soundIconFile = soundIconPath + Values[1] - self.env['soundIcons'][soundIcon] = soundIconFile - self.env['runtime']['debug'].writeDebugOut("SoundIcon: " + soundIcon + '.' + soundIconFile, debug.debugLevel.INFO, onAnyLevel=True) + if os.path.exists(soundIconPath + values[1]): + sound_icon_file = soundIconPath + values[1] + env['soundIcons'][sound_icon] = sound_icon_file + env['runtime']['DebugManager'].write_debug_out( + "SoundIcon: " + sound_icon + '.' + sound_icon_file, + debug.DebugLevel.INFO, + on_any_level=True) except (IOError, OSError) as e: - self.env['runtime']['debug'].writeDebugOut('loadSoundIcons: failed to load sound icons from ' + soundIconPath + '. Error: ' + str(e), debug.debugLevel.ERROR) - def getSettingsFile(self): - return self.settingsFile - def setSettingsFile(self, settingsFile): - if not os.path.exists(settingsFile): + env['runtime']['DebugManager'].write_debug_out( + 'load_sound_icons: failed to load sound icons from ' + + soundIconPath + + '. Error: ' + + str(e), + debug.DebugLevel.ERROR) + + def get_settings_file(self): + return self.settings_file + + def set_settings_file(self, settings_file): + if not os.path.exists(settings_file): return - if not os.access(settingsFile, os.R_OK): - return - self.settingsFile = settingsFile - def loadSettings(self, settingConfigPath): - if not os.path.exists(settingConfigPath): + if not os.access(settings_file, os.R_OK): + return + self.settings_file = settings_file + + def load_settings(self, setting_config_path): + if not os.path.exists(setting_config_path): return False - if not os.access(settingConfigPath, os.R_OK): + if not os.access(setting_config_path, os.R_OK): return False self.env['settings'] = ConfigParser() try: - self.env['settings'].read(settingConfigPath) + self.env['settings'].read(setting_config_path) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('settingsManager loadSettings: Error reading config file: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'settings_manager load_settings: Error reading config file: ' + str(e), + debug.DebugLevel.ERROR) return False - self.setSettingsFile(settingConfigPath) + self.set_settings_file(setting_config_path) return True - def saveSettings(self, settingConfigPath): + + def save_settings(self, setting_config_path): # set opt dict here # save file try: - #print('file: ',settingConfigPath) + # print('file: ',setting_config_path) for section, settings in self.settingArgDict.items(): for setting, value in settings.items(): - #print(section, setting, value) + # print(section, setting, value) self.env['settings'].set(section, setting, value) - #print('full',self.env['settings']) + # print('full',self.env['settings']) - configFile = open(settingConfigPath, 'w') - self.env['settings'].write(configFile) - configFile.close() - os.chmod(settingConfigPath, 0o644) + config_file = open(setting_config_path, 'w') + self.env['settings'].write(config_file) + config_file.close() + os.chmod(setting_config_path, 0o644) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('saveSettings: save settingsfile:' + settingConfigPath + 'failed. Error:' + str(e), debug.debugLevel.ERROR) - def setSetting(self, section, setting, value): - self.setOptionArgDict(section, setting, value) - #self.env['settings'].set(section, setting, value) + self.env['runtime']['DebugManager'].write_debug_out( + 'save_settings: save settingsfile:' + + setting_config_path + + 'failed. Error:' + + str(e), + debug.DebugLevel.ERROR) - def getSetting(self, section, setting): + def set_setting(self, section, setting, value): + self.set_option_arg_dict(section, setting, value) + # self.env['settings'].set(section, setting, value) + + def get_setting(self, section, setting): value = '' try: value = self.settingArgDict[section][setting] @@ -133,7 +164,7 @@ class settingsManager(): value = str(self.settings[section][setting]) return value - def getSettingAsInt(self, section, setting): + def get_setting_as_int(self, section, setting): value = 0 try: value = int(self.settingArgDict[section][setting]) @@ -146,7 +177,7 @@ class settingsManager(): value = self.settings[section][setting] return value - def getSettingAsFloat(self, section, setting): + def get_setting_as_float(self, section, setting): value = 0.0 try: value = float(self.settingArgDict[section][setting]) @@ -159,10 +190,11 @@ class settingsManager(): value = self.settings[section][setting] return value - def getSettingAsBool(self, section, setting): + def get_setting_as_bool(self, section, setting): value = False try: - value = self.settingArgDict[section][setting].upper() in ['1','YES','JA','TRUE'] + value = self.settingArgDict[section][setting].upper() in [ + '1', 'YES', 'JA', 'TRUE'] return value except Exception as e: pass @@ -172,53 +204,78 @@ class settingsManager(): value = self.settings[section][setting] return value - def loadDriver(self, driverName, driverType): + def load_driver(self, driverName, driverType): + # Map runtime keys to actual directory names + driver_dir_map = { + 'InputDriver': 'inputDriver', + 'ScreenDriver': 'screenDriver', + 'SpeechDriver': 'speechDriver', + 'SoundDriver': 'soundDriver', + 'RemoteDriver': 'remoteDriver' + } + driver_dir = driver_dir_map.get(driverType, driverType) + try: if self.env['runtime'][driverType] is not None: self.env['runtime'][driverType].shutdown(self.env) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('settingsManager loadDriver: Error shutting down driver: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'settings_manager load_driver: Error shutting down driver: ' + str(e), + debug.DebugLevel.ERROR) try: - driver_mod = module_utils.importModule(driverName, - fenrirPath + "/" + driverType + '/' + driverName + '.py') + driver_mod = module_utils.import_module( + driverName, fenrir_path + "/" + driver_dir + '/' + driverName + '.py') self.env['runtime'][driverType] = driver_mod.driver() self.env['runtime'][driverType].initialize(self.env) - self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") OK",debug.debugLevel.INFO, onAnyLevel=True) + self.env['runtime']['DebugManager'].write_debug_out( + 'Loading Driver ' + driverType + ' (' + driverName + ") OK", + debug.DebugLevel.INFO, + on_any_level=True) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") FAILED:"+ str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'Loading Driver ' + driverType + ' (' + driverName + ") FAILED:" + str(e), + debug.DebugLevel.ERROR) try: - driver_mod = module_utils.importModule(driverName, - fenrirPath + "/" + driverType + '/dummyDriver.py') + driver_mod = module_utils.import_module( + driverName, fenrir_path + "/" + driver_dir + '/dummyDriver.py') self.env['runtime'][driverType] = driver_mod.driver() self.env['runtime'][driverType].initialize(self.env) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('(fallback) Loading Driver ' + driverType + ' (dummyDriver) FAILED:'+ str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + '(fallback) Loading Driver ' + + driverType + + ' (dummyDriver) FAILED:' + + str(e), + debug.DebugLevel.ERROR) - def shutdownDriver(self, driverType): + def shutdown_driver(self, driverType): try: self.env['runtime'][driverType].shutdown() except Exception as e: pass del self.env['runtime'][driverType] - def setFenrirKeys(self, keys): + def set_fenrir_keys(self, keys): keys = keys.upper() - keyList = keys.split(',') - for key in keyList: - if not key in self.env['input']['fenrirKey']: + key_list = keys.split(',') + for key in key_list: + if key not in self.env['input']['fenrirKey']: self.env['input']['fenrirKey'].append(key) - def setScriptKeys(self, keys): + + def set_script_keys(self, keys): keys = keys.upper() - keyList = keys.split(',') - for key in keyList: - if not key in self.env['input']['scriptKey']: + key_list = keys.split(',') + for key in key_list: + if key not in self.env['input']['scriptKey']: self.env['input']['scriptKey'].append(key) - def resetSettingArgDict(self): + + def reset_setting_arg_dict(self): self.settingArgDict = {} - self.env['runtime']['outputManager'].resetSpeechDriver() - def setOptionArgDict(self, section, setting, value): - #section = section.lower() - #setting = setting.lower() + self.env['runtime']['OutputManager'].reset_SpeechDriver() + + def set_option_arg_dict(self, section, setting, value): + # section = section.lower() + # setting = setting.lower() try: e = self.settingArgDict[section] except KeyError: @@ -226,279 +283,431 @@ class settingsManager(): try: t = self.settings[section][setting] except Exception as e: - print(section,setting, 'not found') + print(section, setting, 'not found') return try: + v = value # Initialize v with the original value if isinstance(self.settings[section][setting], str): v = str(value) elif isinstance(self.settings[section][setting], bool): - if not value in ['True','False']: - raise ValueError('could not convert string to bool: '+ value) + if value not in ['True', 'False']: + raise ValueError( + 'could not convert string to bool: ' + value) v = value == 'True' elif isinstance(self.settings[section][setting], int): v = int(value) elif isinstance(self.settings[section][setting], float): v = float(value) - + # Content validation for critical settings - self._validateSettingValue(section, setting, v) - + self._validate_setting_value(section, setting, v) + self.settingArgDict[section][setting] = str(value) except Exception as e: - print('settingsManager:setOptionArgDict:Datatype missmatch: '+ section + '#' + setting + '=' + value + ' Error:' + str(e)) - #self.env['runtime']['debug'].writeDebugOut('settingsManager:setOptionArgDict:Datatype missmatch: '+ section + '#' + setting + '=' + value + ' Error:' + str(e), debug.debugLevel.ERROR) + print('settings_manager:set_option_arg_dict:Datatype missmatch: ' + + section + '#' + setting + '=' + str(value) + ' Error:' + str(e)) + # self.env['runtime']['DebugManager'].write_debug_out('settings_manager:set_option_arg_dict:Datatype + # missmatch: '+ section + '#' + setting + '=' + value + ' Error:' + # + str(e), debug.DebugLevel.ERROR) return - - def _validateSettingValue(self, section, setting, value): + + def _validate_setting_value(self, section, setting, value): """Validate setting values for critical screen reader functionality. Only validates settings that could cause crashes or accessibility issues. Invalid values raise ValueError which is caught by the calling method.""" - + # Speech settings validation - critical for accessibility if section == 'speech': if setting == 'rate': if not (0.0 <= value <= 3.0): - raise ValueError(f'Speech rate must be between 0.0 and 3.0, got {value}') + raise ValueError( + f'Speech rate must be between 0.0 and 3.0, got {value}') elif setting == 'pitch': if not (0.0 <= value <= 2.0): - raise ValueError(f'Speech pitch must be between 0.0 and 2.0, got {value}') + raise ValueError( + f'Speech pitch must be between 0.0 and 2.0, got {value}') elif setting == 'volume': if not (0.0 <= value <= 1.5): - raise ValueError(f'Speech volume must be between 0.0 and 1.5, got {value}') + raise ValueError( + f'Speech volume must be between 0.0 and 1.5, got {value}') elif setting == 'driver': - valid_drivers = ['speechdDriver', 'genericDriver', 'dummyDriver'] + valid_drivers = [ + 'speechdDriver', + 'genericDriver', + 'dummyDriver'] if value not in valid_drivers: - raise ValueError(f'Invalid speech driver: {value}. Valid options: {valid_drivers}') - + raise ValueError( + f'Invalid speech driver: {value}. Valid options: {valid_drivers}') + # Sound settings validation elif section == 'sound': if setting == 'volume': if not (0.0 <= value <= 1.5): - raise ValueError(f'Sound volume must be between 0.0 and 1.5, got {value}') + raise ValueError( + f'Sound volume must be between 0.0 and 1.5, got {value}') elif setting == 'driver': - valid_drivers = ['genericDriver', 'gstreamerDriver', 'dummyDriver'] + valid_drivers = [ + 'genericDriver', + 'gstreamerDriver', + 'dummyDriver'] if value not in valid_drivers: - raise ValueError(f'Invalid sound driver: {value}. Valid options: {valid_drivers}') - + raise ValueError( + f'Invalid sound driver: {value}. Valid options: {valid_drivers}') + # Screen settings validation elif section == 'screen': if setting == 'driver': - valid_drivers = ['vcsaDriver', 'ptyDriver', 'dummyDriver'] + valid_drivers = ['vcsaDriver', 'ptyDriver', 'dummyDriver'] if value not in valid_drivers: - raise ValueError(f'Invalid screen driver: {value}. Valid options: {valid_drivers}') - + raise ValueError( + f'Invalid screen driver: {value}. Valid options: {valid_drivers}') + # Input settings validation elif section == 'keyboard': if setting == 'driver': - valid_drivers = ['evdevDriver', 'ptyDriver', 'atspiDriver', 'dummyDriver'] + valid_drivers = [ + 'evdevDriver', + 'ptyDriver', + 'atspiDriver', + 'dummyDriver'] if value not in valid_drivers: - raise ValueError(f'Invalid input driver: {value}. Valid options: {valid_drivers}') - - # General settings validation - elif section == 'general': - if setting == 'debugLevel': - if not (0 <= value <= 3): - raise ValueError(f'Debug level must be between 0 and 3, got {value}') + raise ValueError( + f'Invalid input driver: {value}. Valid options: {valid_drivers}') - def parseSettingArgs(self, settingArgs): + # General settings validation + elif section == 'general': + if setting == 'debug_level': + if not (0 <= value <= 3): + raise ValueError( + f'Debug level must be between 0 and 3, got {value}') + + def parse_setting_args(self, settingArgs): + if settingArgs is None: + return for optionElem in settingArgs.split(';'): - settingValList = [] - sectionOptionList = [] + setting_val_list = [] + section_option_list = [] section = '' option = '' value = '' - settingValList = optionElem.split('=',1) - if len(settingValList) != 2: + setting_val_list = optionElem.split('=', 1) + if len(setting_val_list) != 2: continue - if '#' in settingValList[0]: - sectionOptionList = settingValList[0].split('#', 1) - elif '.' in settingValList[0]: - sectionOptionList = settingValList[0].split('.', 1) - elif ',' in settingValList[0]: - sectionOptionList = settingValList[0].split(',', 1) - elif '!' in settingValList[0]: - sectionOptionList = settingValList[0].split('!', 1) + if '#' in setting_val_list[0]: + section_option_list = setting_val_list[0].split('#', 1) + elif '.' in setting_val_list[0]: + section_option_list = setting_val_list[0].split('.', 1) + elif ',' in setting_val_list[0]: + section_option_list = setting_val_list[0].split(',', 1) + elif '!' in setting_val_list[0]: + section_option_list = setting_val_list[0].split('!', 1) else: continue - if len(sectionOptionList) != 2: + if len(section_option_list) != 2: continue - section = str(sectionOptionList[0]) - option = str(sectionOptionList[1]) - value = str(settingValList[1]) - self.setOptionArgDict(section, option, value) + section = str(section_option_list[0]) + option = str(section_option_list[1]) + value = str(setting_val_list[1]) + self.set_option_arg_dict(section, option, value) - def initFenrirConfig(self, cliArgs, fenrirManager = None, environment = environment.environment): - settingsRoot = '/etc/fenrirscreenreader/' - settingsFile = cliArgs.setting - soundRoot = '/usr/share/sounds/fenrirscreenreader/' + def init_fenrir_config( + self, + cliArgs, + fenrir_manager=None, + environment=environment.environment): + settings_root = '/etc/fenrirscreenreader/' + settings_file = cliArgs.setting + sound_root = '/usr/share/sounds/fenrirscreenreader/' # get fenrir settings root - if not os.path.exists(settingsRoot): - if os.path.exists(fenrirPath +'/../../config/'): - settingsRoot = fenrirPath +'/../../config/' + if not os.path.exists(settings_root): + if os.path.exists(fenrir_path + '/../../config/'): + settings_root = fenrir_path + '/../../config/' else: return None # get settings file - if not os.path.exists(settingsFile): - if os.path.exists(settingsRoot + '/settings/settings.conf'): - settingsFile = settingsRoot + '/settings/settings.conf' + if settings_file is None or not os.path.exists(settings_file): + if os.path.exists(settings_root + '/settings/settings.conf'): + settings_file = settings_root + '/settings/settings.conf' else: return None # get sound themes root - if not os.path.exists(soundRoot): - if os.path.exists(fenrirPath + '/../../config/sound/'): - soundRoot = fenrirPath + '/../../config/sound/' + if not os.path.exists(sound_root): + if os.path.exists(fenrir_path + '/../../config/sound/'): + sound_root = fenrir_path + '/../../config/sound/' - environment['runtime']['settingsManager'] = self - environment['runtime']['settingsManager'].initialize(environment) + environment['runtime']['SettingsManager'] = self + environment['runtime']['SettingsManager'].initialize(environment) - validConfig = environment['runtime']['settingsManager'].loadSettings(settingsFile) - if not validConfig: + valid_config = environment['runtime']['SettingsManager'].load_settings( + settings_file) + if not valid_config: return None if cliArgs.options != '': - self.parseSettingArgs(cliArgs.options) + self.parse_setting_args(cliArgs.options) if cliArgs.debug: - self.setSetting('general', 'debugLevel', 3) + self.set_setting('general', 'debug_level', 3) if cliArgs.print: - self.setSetting('general', 'debugLevel', 3) - self.setSetting('general', 'debugMode', 'PRINT') + self.set_setting('general', 'debug_level', 3) + self.set_setting('general', 'debug_mode', 'PRINT') if cliArgs.emulated_pty: - self.setSetting('screen', 'driver', 'ptyDriver') - self.setSetting('keyboard', 'driver', 'ptyDriver') + self.set_setting('screen', 'driver', 'ptyDriver') + self.set_setting('keyboard', 'driver', 'ptyDriver') # TODO needs cleanup use dict - #self.setOptionArgDict('keyboard', 'keyboardLayout', 'pty') - self.setSetting('keyboard', 'keyboardLayout', 'pty') + # self.set_option_arg_dict('keyboard', 'keyboardLayout', 'pty') + self.set_setting('keyboard', 'keyboardLayout', 'pty') if cliArgs.emulated_evdev: - self.setSetting('screen', 'driver', 'ptyDriver') - self.setSetting('keyboard', 'driver', 'evdevDriver') + self.set_setting('screen', 'driver', 'ptyDriver') + self.set_setting('keyboard', 'driver', 'evdevDriver') - self.setFenrirKeys(self.getSetting('general','fenrirKeys')) - self.setScriptKeys(self.getSetting('general','scriptKeys')) + self.set_fenrir_keys(self.get_setting('general', 'fenrirKeys')) + self.set_script_keys(self.get_setting('general', 'scriptKeys')) + + environment['runtime']['DebugManager'] = debugManager.DebugManager( + self.env['runtime']['SettingsManager'].get_setting('general', 'debugFile')) + environment['runtime']['DebugManager'].initialize(environment) - environment['runtime']['debug'] = debugManager.debugManager(self.env['runtime']['settingsManager'].getSetting('general','debugFile')) - environment['runtime']['debug'].initialize(environment) - if cliArgs.force_all_screens: environment['runtime']['force_all_screens'] = True - + if cliArgs.ignore_screen: - currentIgnoreScreen = self.getSetting('screen', 'ignoreScreen') - if currentIgnoreScreen: - ignoreScreens = currentIgnoreScreen.split(',') + cliArgs.ignore_screen + current_ignore_screen = self.get_setting('screen', 'ignoreScreen') + if current_ignore_screen: + ignore_screens = current_ignore_screen.split( + ',') + cliArgs.ignore_screen else: - ignoreScreens = cliArgs.ignore_screen - self.setSetting('screen', 'ignoreScreen', ','.join(ignoreScreens)) + ignore_screens = cliArgs.ignore_screen + self.set_setting('screen', 'ignoreScreen', ','.join(ignore_screens)) - if not os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'): - if os.path.exists(soundRoot + self.getSetting('sound','theme')): - self.setSetting('sound', 'theme', soundRoot + self.getSetting('sound','theme')) - if os.path.exists(self.getSetting('sound','theme') + '/soundicons.conf'): - environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme')) + if not os.path.exists( + self.get_setting( + 'sound', + 'theme') + + '/soundicons.conf'): + if os.path.exists(sound_root + self.get_setting('sound', 'theme')): + self.set_setting( + 'sound', + 'theme', + sound_root + + self.get_setting( + 'sound', + 'theme')) + if os.path.exists( + self.get_setting( + 'sound', + 'theme') + + '/soundicons.conf'): + environment['runtime']['SettingsManager'].load_sound_icons( + self.get_setting('sound', 'theme'), environment) else: - environment['runtime']['settingsManager'].loadSoundIcons(self.getSetting('sound','theme')) + environment['runtime']['SettingsManager'].load_sound_icons( + self.get_setting('sound', 'theme'), environment) - environment['runtime']['punctuationManager'] = punctuationManager.punctuationManager() - environment['runtime']['punctuationManager'].initialize(environment) + environment['runtime']['PunctuationManager'] = punctuationManager.PunctuationManager() + environment['runtime']['PunctuationManager'].initialize(environment) - environment['runtime']['textManager'] = textManager.textManager() - environment['runtime']['textManager'].initialize(environment) + environment['runtime']['TextManager'] = textManager.TextManager() + environment['runtime']['TextManager'].initialize(environment) - if not os.path.exists(self.getSetting('general','punctuationProfile')): - if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile')): - self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile')) - environment['runtime']['punctuationManager'].loadDicts(self.getSetting('general','punctuationProfile')) - if os.path.exists(settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf'): - self.setSetting('general', 'punctuationProfile', settingsRoot + 'punctuation/' + self.getSetting('general','punctuationProfile') + '.conf') - environment['runtime']['punctuationManager'].loadDicts(self.getSetting('general','punctuationProfile')) + if not os.path.exists( + self.get_setting( + 'general', + 'punctuationProfile')): + if os.path.exists( + settings_root + + 'punctuation/' + + self.get_setting( + 'general', + 'punctuationProfile')): + self.set_setting( + 'general', + 'punctuationProfile', + settings_root + + 'punctuation/' + + self.get_setting( + 'general', + 'punctuationProfile')) + environment['runtime']['PunctuationManager'].load_dicts( + self.get_setting('general', 'punctuationProfile')) + if os.path.exists( + settings_root + + 'punctuation/' + + self.get_setting( + 'general', + 'punctuationProfile') + + '.conf'): + self.set_setting( + 'general', + 'punctuationProfile', + settings_root + + 'punctuation/' + + self.get_setting( + 'general', + 'punctuationProfile') + + '.conf') + environment['runtime']['PunctuationManager'].load_dicts( + self.get_setting('general', 'punctuationProfile')) else: - environment['runtime']['punctuationManager'].loadDicts(self.getSetting('general','punctuationProfile')) + environment['runtime']['PunctuationManager'].load_dicts( + self.get_setting('general', 'punctuationProfile')) + if fenrir_manager: + environment['runtime']['FenrirManager'] = fenrir_manager - if fenrirManager: - environment['runtime']['fenrirManager'] = fenrirManager + environment['runtime']['MemoryManager'] = memoryManager.MemoryManager() + environment['runtime']['MemoryManager'].initialize(environment) - environment['runtime']['memoryManager'] = memoryManager.memoryManager() - environment['runtime']['memoryManager'].initialize(environment) + environment['runtime']['AttributeManager'] = attributeManager.AttributeManager() + environment['runtime']['AttributeManager'].initialize(environment) - environment['runtime']['attributeManager'] = attributeManager.attributeManager() - environment['runtime']['attributeManager'].initialize(environment) + environment['runtime']['EventManager'] = eventManager.EventManager() + environment['runtime']['EventManager'].initialize(environment) - environment['runtime']['eventManager'] = eventManager.eventManager() - environment['runtime']['eventManager'].initialize(environment) + environment['runtime']['ProcessManager'] = processManager.ProcessManager() + environment['runtime']['ProcessManager'].initialize(environment) - environment['runtime']['processManager'] = processManager.processManager() - environment['runtime']['processManager'].initialize(environment) + environment['runtime']['OutputManager'] = outputManager.OutputManager() + environment['runtime']['OutputManager'].initialize(environment) - environment['runtime']['outputManager'] = outputManager.outputManager() - environment['runtime']['outputManager'].initialize(environment) + environment['runtime']['ByteManager'] = byteManager.ByteManager() + environment['runtime']['ByteManager'].initialize(environment) - environment['runtime']['byteManager'] = byteManager.byteManager() - environment['runtime']['byteManager'].initialize(environment) + environment['runtime']['InputManager'] = inputManager.InputManager() + environment['runtime']['InputManager'].initialize(environment) - environment['runtime']['inputManager'] = inputManager.inputManager() - environment['runtime']['inputManager'].initialize(environment) + environment['runtime']['ScreenManager'] = screenManager.ScreenManager() + environment['runtime']['ScreenManager'].initialize(environment) - environment['runtime']['screenManager'] = screenManager.screenManager() - environment['runtime']['screenManager'].initialize(environment) + environment['runtime']['CommandManager'] = commandManager.CommandManager() + environment['runtime']['CommandManager'].initialize(environment) - environment['runtime']['commandManager'] = commandManager.commandManager() - environment['runtime']['commandManager'].initialize(environment) + environment['runtime']['HelpManager'] = helpManager.HelpManager() + environment['runtime']['HelpManager'].initialize(environment) - environment['runtime']['helpManager'] = helpManager.helpManager() - environment['runtime']['helpManager'].initialize(environment) + environment['runtime']['RemoteManager'] = remoteManager.RemoteManager() + environment['runtime']['RemoteManager'].initialize(environment) - environment['runtime']['remoteManager'] = remoteManager.remoteManager() - environment['runtime']['remoteManager'].initialize(environment) - - - if environment['runtime']['inputManager'].getShortcutType() == 'KEY': - if not os.path.exists(self.getSetting('keyboard','keyboardLayout')): - if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')): - self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')) - environment['runtime']['inputManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) - if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf'): - self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf') - environment['runtime']['inputManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) + if environment['runtime']['InputManager'].get_shortcut_type() == 'KEY': + if not os.path.exists( + self.get_setting( + 'keyboard', + 'keyboardLayout')): + if os.path.exists( + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout')): + self.set_setting( + 'keyboard', + 'keyboardLayout', + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout')) + environment['runtime']['InputManager'].load_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) + if os.path.exists( + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout') + + '.conf'): + self.set_setting( + 'keyboard', + 'keyboardLayout', + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout') + + '.conf') + environment['runtime']['InputManager'].load_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) else: - environment['runtime']['inputManager'].loadShortcuts(self.getSetting('keyboard','keyboardLayout')) - elif environment['runtime']['inputManager'].getShortcutType() == 'BYTE': - if not os.path.exists(self.getSetting('keyboard','keyboardLayout')): - if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')): - self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')) - environment['runtime']['byteManager'].loadByteShortcuts(self.getSetting('keyboard','keyboardLayout')) - if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf'): - self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout') + '.conf') - environment['runtime']['byteManager'].loadByteShortcuts(self.getSetting('keyboard','keyboardLayout')) + environment['runtime']['InputManager'].load_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) + elif environment['runtime']['InputManager'].get_shortcut_type() == 'BYTE': + if not os.path.exists( + self.get_setting( + 'keyboard', + 'keyboardLayout')): + if os.path.exists( + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout')): + self.set_setting( + 'keyboard', + 'keyboardLayout', + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout')) + environment['runtime']['ByteManager'].load_byte_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) + if os.path.exists( + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout') + + '.conf'): + self.set_setting( + 'keyboard', + 'keyboardLayout', + settings_root + + 'keyboard/' + + self.get_setting( + 'keyboard', + 'keyboardLayout') + + '.conf') + environment['runtime']['ByteManager'].load_byte_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) else: - environment['runtime']['byteManager'].loadByteShortcuts(self.getSetting('keyboard','keyboardLayout')) + environment['runtime']['ByteManager'].load_byte_shortcuts( + self.get_setting('keyboard', 'keyboardLayout')) - environment['runtime']['cursorManager'] = cursorManager.cursorManager() - environment['runtime']['cursorManager'].initialize(environment) - environment['runtime']['applicationManager'] = applicationManager.applicationManager() - environment['runtime']['applicationManager'].initialize(environment) - environment['runtime']['textManager'] = textManager.textManager() - environment['runtime']['textManager'].initialize(environment) - environment['runtime']['tableManager'] = tableManager.tableManager() - environment['runtime']['tableManager'].initialize(environment) - environment['runtime']['barrierManager'] = barrierManager.barrierManager() - environment['runtime']['barrierManager'].initialize(environment) - environment['runtime']['sayAllManager'] = sayAllManager.sayAllManager() - environment['runtime']['sayAllManager'].initialize(environment) - environment['runtime']['vmenuManager'] = vmenuManager.vmenuManager() - environment['runtime']['vmenuManager'].initialize(environment) - environment['runtime']['quickMenuManager'] = quickMenuManager.quickMenuManager() - environment['runtime']['quickMenuManager'].initialize(environment) + environment['runtime']['CursorManager'] = cursorManager.CursorManager() + environment['runtime']['CursorManager'].initialize(environment) + environment['runtime']['ApplicationManager'] = applicationManager.ApplicationManager() + environment['runtime']['ApplicationManager'].initialize(environment) + environment['runtime']['TextManager'] = textManager.TextManager() + environment['runtime']['TextManager'].initialize(environment) + environment['runtime']['TableManager'] = tableManager.TableManager() + environment['runtime']['TableManager'].initialize(environment) + environment['runtime']['BarrierManager'] = barrierManager.BarrierManager() + environment['runtime']['BarrierManager'].initialize(environment) + environment['runtime']['SayAllManager'] = sayAllManager.SayAllManager() + environment['runtime']['SayAllManager'].initialize(environment) + environment['runtime']['VmenuManager'] = vmenuManager.VmenuManager() + environment['runtime']['VmenuManager'].initialize(environment) + environment['runtime']['QuickMenuManager'] = quickMenuManager.QuickMenuManager() + environment['runtime']['QuickMenuManager'].initialize(environment) - # only possible after having input and screen managers with clean buffer - environment['runtime']['inputManager'].writeEventBuffer() - environment['runtime']['inputManager'].handleDeviceGrab(force = True) + # only possible after having input and screen managers with clean + # buffer + environment['runtime']['InputManager'].write_event_buffer() + environment['runtime']['InputManager'].handle_device_grab(force=True) - environment['runtime']['debug'].writeDebugOut(r'/-------environment-------/',debug.debugLevel.INFO, onAnyLevel=True) - environment['runtime']['debug'].writeDebugOut(str(environment), debug.debugLevel.INFO, onAnyLevel=True) - environment['runtime']['debug'].writeDebugOut(r'/-------settings.conf-------/', debug.debugLevel.INFO, onAnyLevel=True) - environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections) , debug.debugLevel.INFO, onAnyLevel=True) - environment['runtime']['debug'].writeDebugOut(r'/-------self.settingArgDict-------/',debug.debugLevel.INFO, onAnyLevel=True) - environment['runtime']['debug'].writeDebugOut(str( self.settingArgDict) ,debug.debugLevel.INFO, onAnyLevel=True) + environment['runtime']['DebugManager'].write_debug_out( + r'/-------environment-------/', debug.DebugLevel.INFO, on_any_level=True) + environment['runtime']['DebugManager'].write_debug_out( + str(environment), debug.DebugLevel.INFO, on_any_level=True) + environment['runtime']['DebugManager'].write_debug_out( + r'/-------settings.conf-------/', debug.DebugLevel.INFO, on_any_level=True) + environment['runtime']['DebugManager'].write_debug_out( + str(environment['settings']._sections), debug.DebugLevel.INFO, on_any_level=True) + environment['runtime']['DebugManager'].write_debug_out( + r'/-------self.settingArgDict-------/', + debug.DebugLevel.INFO, + on_any_level=True) + environment['runtime']['DebugManager'].write_debug_out( + str(self.settingArgDict), debug.DebugLevel.INFO, on_any_level=True) self.bindingsBackup = environment['bindings'].copy() return environment diff --git a/src/fenrirscreenreader/core/soundDriver.py b/src/fenrirscreenreader/core/soundDriver.py index cfeefd54..a88ce81c 100644 --- a/src/fenrirscreenreader/core/soundDriver.py +++ b/src/fenrirscreenreader/core/soundDriver.py @@ -6,7 +6,8 @@ from fenrirscreenreader.core import debug -class soundDriver(): + +class sound_driver(): def __init__(self): self.volume = None self._initialized = False @@ -19,15 +20,20 @@ class soundDriver(): if not self._initialized: return self.cancel() - self._isInitialized = False + self._is_initialized = False - def playFrequence(self, frequence, duration, adjustVolume = 0.0, interrupt=True): + def play_frequence( + self, + frequence, + duration, + adjust_volume=0.0, + interrupt=True): if not self._initialized: return if interrupt: self.cancel() - def playSoundFile(self, filePath, interrupt = True): + def play_sound_file(self, file_path, interrupt=True): if not self._initialized: return if interrupt: @@ -37,11 +43,11 @@ class soundDriver(): if not self._initialized: return - def setCallback(self, callback): + def set_callback(self, callback): if not self._initialized: return - def setVolume(self, volume): + def set_volume(self, volume): if not self._initialized: return self.volume = volume diff --git a/src/fenrirscreenreader/core/speechDriver.py b/src/fenrirscreenreader/core/speechDriver.py index 969dcbf6..9c54d04c 100644 --- a/src/fenrirscreenreader/core/speechDriver.py +++ b/src/fenrirscreenreader/core/speechDriver.py @@ -6,11 +6,13 @@ from fenrirscreenreader.core import debug -class speechDriver(): + +class speech_driver(): def __init__(self): pass + def initialize(self, environment): - self._isInitialized = False + self._is_initialized = False self.language = None self.voice = None self.module = None @@ -18,41 +20,42 @@ class speechDriver(): self.rate = None self.volume = None self.env = environment - self._isInitialized = True - def shutdown(self): - if self._isInitialized: - self.cancel() - self._isInitialized = False + self._is_initialized = True - def speak(self,text, queueable=True, ignorePunctuation=False): - if not self._isInitialized: + def shutdown(self): + if self._is_initialized: + self.cancel() + self._is_initialized = False + + def speak(self, text, queueable=True, ignore_punctuation=False): + if not self._is_initialized: return - if not queueable: + if not queueable: self.cancel() def cancel(self): - if not self._isInitialized: + if not self._is_initialized: return - def setCallback(self, callback): - if not self._isInitialized: + def set_callback(self, callback): + if not self._is_initialized: return if not callback: return def clear_buffer(self): - if not self._isInitialized: + if not self._is_initialized: return - def setVoice(self, voice): - if not self._isInitialized: + def set_voice(self, voice): + if not self._is_initialized: return if voice == '': return - self.voice = voice + self.voice = voice - def setPitch(self, pitch): - if not self._isInitialized: + def set_pitch(self, pitch): + if not self._is_initialized: return if not isinstance(pitch, float): return @@ -61,8 +64,9 @@ class speechDriver(): if pitch > 1.0: return self.pitch = pitch - def setRate(self, rate): - if not self._isInitialized: + + def set_rate(self, rate): + if not self._is_initialized: return if not isinstance(rate, float): return @@ -71,29 +75,33 @@ class speechDriver(): if rate > 1.0: return self.rate = rate - def setModule(self, module): - if not self._isInitialized: + + def set_module(self, module): + if not self._is_initialized: return if not isinstance(module, str): return if module == '': return self.module = module + def reset(self): self.shutdown() self.initialize(self.env) - def setLanguage(self, language): - if not self._isInitialized: + + def set_language(self, language): + if not self._is_initialized: return if not isinstance(language, str): return if language == '': return - self.language = language - def setVolume(self, volume): - if not self._isInitialized: - return - if not isinstance(volume,float): + self.language = language + + def set_volume(self, volume): + if not self._is_initialized: + return + if not isinstance(volume, float): return if volume < 0.0: return diff --git a/src/fenrirscreenreader/core/tableManager.py b/src/fenrirscreenreader/core/tableManager.py index b27dac0f..adde6e38 100644 --- a/src/fenrirscreenreader/core/tableManager.py +++ b/src/fenrirscreenreader/core/tableManager.py @@ -7,40 +7,47 @@ from fenrirscreenreader.core import debug import re -class tableManager(): + +class TableManager(): def __init__(self): self.headLine = '' - self.defaultSeparators = ['+',';','|',' '] + self.defaultSeparators = ['+', ';', '|', ' '] self.noOfHeadLineColumns = 0 self.headColumnSep = '' self.rowColumnSep = '' + def initialize(self, environment): - self.env = environment + self.env = environment + def shutdown(self): pass - def resetTableMode(self): - self.setHeadLine() - def setHeadColumnSep(self, columnSep = ''): - self.headColumnSep = columnSep + + def reset_table_mode(self): + self.set_head_line() + + def set_head_column_sep(self, columnSep=''): + self.headColumnSep = columnSep if columnSep == '': - self.noOfHeadLineColumns = 0 + self.noOfHeadLineColumns = 0 else: - self.counNoOfHeadColumns() - def counNoOfHeadColumns(self): + self.coun_no_of_head_columns() + + def coun_no_of_head_columns(self): pass - def searchForHeadColumnSep(self, headLine): + + def search_for_head_column_sep(self, headLine): if ' ' in headLine: return ' ' return '' - def setRowColumnSep(self, columnSep = ''): - self.rowColumnSep = columnSep - def setHeadLine(self, headLine = ''): - self.setHeadColumnSep() - self.setRowColumnSep() + def set_row_column_sep(self, columnSep=''): + self.rowColumnSep = columnSep + + def set_head_line(self, headLine=''): + self.set_head_column_sep() + self.set_row_column_sep() if headLine != '': - sep = self.searchForHeadColumnSep(headLine) + sep = self.search_for_head_column_sep(headLine) if sep != '': self.headLine = headLine - self.setHeadColumnSep(sep) - + self.set_head_column_sep(sep) diff --git a/src/fenrirscreenreader/core/textManager.py b/src/fenrirscreenreader/core/textManager.py index 827c6391..8ed52c91 100644 --- a/src/fenrirscreenreader/core/textManager.py +++ b/src/fenrirscreenreader/core/textManager.py @@ -5,59 +5,73 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -import re, string +import re +import string -class textManager(): + +class TextManager(): def __init__(self): # https://regex101.com/ self.regExSingle = re.compile(r'(([^\w\s])\2{5,})') - self.regExDouble = re.compile(r'([^\w\s]{2,}){5,}') - def initialize(self, environment): - self.env = environment - def shutdown(self): - pass + self.regExDouble = re.compile(r'([^\w\s]{2,}){5,}') - def replaceHeadLines(self, text): + def initialize(self, environment): + self.env = environment + + def shutdown(self): + pass + + def replace_head_lines(self, text): # fast len check for bigger typing echo if len(text) < 5: return text # more strong check, to not match if not needed: - if len(text.strip(string.ascii_letters+string.digits+string.whitespace)) < 5: - return text + if len( + text.strip( + string.ascii_letters + + string.digits + + string.whitespace)) < 5: + return text result = '' - newText = '' - lastPos = 0 + new_text = '' + last_pos = 0 for match in self.regExDouble.finditer(text): span = match.span() - newText += text[lastPos:span[0]] - numberOfChars = len(text[span[0]:span[1]]) + new_text += text[last_pos:span[0]] + number_of_chars = len(text[span[0]:span[1]]) name = text[span[0]:span[1]][:2] - if not self.env['runtime']['punctuationManager'].isPuctuation(name[0]): - lastPos = span[1] - continue + if not self.env['runtime']['PunctuationManager'].is_puctuation( + name[0]): + last_pos = span[1] + continue if name[0] == name[1]: - newText += ' ' + str(numberOfChars) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' ' + new_text += ' ' + \ + str(number_of_chars) + ' ' + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[0], True) + ' ' else: - newText += ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' ' + str(int(numberOfChars / 2)) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[1], True) + ' ' - lastPos = span[1] - if lastPos != 0: - newText += ' ' - newText += text[lastPos:] - lastPos = 0 - for match in self.regExSingle.finditer(newText): - span = match.span() - result += newText[lastPos:span[0]] - numberOfChars = len(newText[span[0]:span[1]]) - name = newText[span[0]:span[1]][:2] - if not self.env['runtime']['punctuationManager'].isPuctuation(name[0]): - lastPos = span[1] - continue + new_text += ' ' + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[0], True) + ' ' + str(int( + number_of_chars / 2)) + ' ' + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[1], True) + ' ' + last_pos = span[1] + if last_pos != 0: + new_text += ' ' + new_text += text[last_pos:] + last_pos = 0 + for match in self.regExSingle.finditer(new_text): + span = match.span() + result += new_text[last_pos:span[0]] + number_of_chars = len(new_text[span[0]:span[1]]) + name = new_text[span[0]:span[1]][:2] + if not self.env['runtime']['PunctuationManager'].is_puctuation( + name[0]): + last_pos = span[1] + continue if name[0] == name[1]: - result += ' ' + str(numberOfChars) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' ' + result += ' ' + str(number_of_chars) + ' ' + \ + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[0], True) + ' ' else: - result += ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[0], True) + ' ' + str(int(numberOfChars / 2)) + ' ' + self.env['runtime']['punctuationManager'].proceedPunctuation(name[1], True) + ' ' - lastPos = span[1] - if lastPos != 0: - result += ' ' - result += newText[lastPos:] - return result + result += ' ' + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[0], True) + ' ' + str(int( + number_of_chars / 2)) + ' ' + self.env['runtime']['PunctuationManager'].proceed_punctuation(name[1], True) + ' ' + last_pos = span[1] + if last_pos != 0: + result += ' ' + result += new_text[last_pos:] + return result diff --git a/src/fenrirscreenreader/core/vmenuManager.py b/src/fenrirscreenreader/core/vmenuManager.py index bf7fef43..047856a9 100755 --- a/src/fenrirscreenreader/core/vmenuManager.py +++ b/src/fenrirscreenreader/core/vmenuManager.py @@ -5,112 +5,137 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug +from fenrirscreenreader.core.i18n import _ from fenrirscreenreader.utils import module_utils -import os, inspect, time +import os +import inspect +import time -currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) -fenrirPath = os.path.dirname(currentdir) +currentdir = os.path.dirname( + os.path.realpath( + os.path.abspath( + inspect.getfile( + inspect.currentframe())))) +fenrir_path = os.path.dirname(currentdir) -class vmenuManager(): + +class VmenuManager(): def __init__(self): self.menuDict = {} - self.currIndex = None + self.curr_index = None self.currMenu = '' self.active = False self.reset = True self.useTimeout = True self.searchText = '' self.lastSearchTime = time.time() + def initialize(self, environment): self.env = environment # use default path - self.defaultVMenuPath = fenrirPath+ "/commands/vmenu-profiles/" + self.env['runtime']['inputManager'].getShortcutType() + self.defaultVMenuPath = fenrir_path + "/commands/vmenu-profiles/" + \ + self.env['runtime']['InputManager'].get_shortcut_type() # if there is no user configuration - if self.env['runtime']['settingsManager'].getSetting('menu', 'vmenuPath') != '': - self.defaultVMenuPath = self.env['runtime']['settingsManager'].getSetting('menu', 'vmenuPath') + if self.env['runtime']['SettingsManager'].get_setting( + 'menu', 'vmenuPath') != '': + self.defaultVMenuPath = self.env['runtime']['SettingsManager'].get_setting( + 'menu', 'vmenuPath') if not self.defaultVMenuPath.endswith('/'): self.defaultVMenuPath += '/' - self.defaultVMenuPath += self.env['runtime']['inputManager'].getShortcutType() + self.defaultVMenuPath += self.env['runtime']['InputManager'].get_shortcut_type() - self.createMenuTree() + self.create_menu_tree() self.closeAfterAction = False + def shutdown(self): pass - def clearSearchText(self): + + def clear_search_text(self): self.searchText = '' - def searchEntry(self, value, forceReset = False): - if self.currIndex == None: + + def search_entry(self, value, forceReset=False): + if self.curr_index is None: return '' if self.reset or forceReset: - self.clearSearchText() + self.clear_search_text() else: if self.useTimeout: if time.time() - self.lastSearchTime > 1: - self.clearSearchText() + self.clear_search_text() self.searchText += value.upper() self.lastSearchTime = time.time() - startIndex = self.getCurrIndex() + start_index = self.get_curr_index() while True: - if not self.nextIndex(): + if not self.next_index(): return '' - entry = self.getCurrentEntry() + entry = self.get_current_entry() if entry.upper().startswith(self.searchText): return entry - if startIndex == self.getCurrIndex(): + if start_index == self.get_curr_index(): return '' - def setCurrMenu(self, currMenu = ''): - self.currIndex = None + def set_curr_menu(self, currMenu=''): + self.curr_index = None self.currMenu = '' if currMenu != '': currMenu += ' ' + _('Menu') try: t = self.menuDict[currMenu] l = list(self.menuDict.keys()) - self.currIndex = [l.index(currMenu)] + self.curr_index = [l.index(currMenu)] except Exception as e: print(e) self.currMenu = '' - self.currIndex = None + self.curr_index = None return - if self.incLevel(): + if self.inc_level(): self.currMenu = currMenu else: self.currMenu = '' - self.currIndex = None - def getCurrMenu(self): + self.curr_index = None + + def get_curr_menu(self): return self.currMenu - def getActive(self): + + def get_active(self): return self.active - def togglelVMenuMode(self, closeAfterAction = True): - self.setActive(not self.getActive(), closeAfterAction) - def setActive(self, active, closeAfterAction = True): - if self.env['runtime']['helpManager'].isTutorialMode(): + + def toggle_vmenu_mode(self, closeAfterAction=True): + self.set_active(not self.get_active(), closeAfterAction) + + def set_active(self, active, closeAfterAction=True): + if self.env['runtime']['HelpManager'].is_tutorial_mode(): return self.active = active if self.active: self.closeAfterAction = closeAfterAction try: - self.createMenuTree() + self.create_menu_tree() except Exception as e: print(e) try: if self.currMenu != '': - self.setCurrMenu(self.currMenu) - if self.currIndex == None: + self.set_curr_menu(self.currMenu) + if self.curr_index is None: if len(self.menuDict) > 0: - self.currIndex = [0] + self.curr_index = [0] except Exception as e: print(e) try: # navigation - self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_VMENU_MODE' + self.env['bindings'][str( + [1, ['KEY_ESC']])] = 'TOGGLE_VMENU_MODE' self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_VMENU_ENTRY' - self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_VMENU_ENTRY' - self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_VMENU_ENTRY' - self.env['bindings'][str([1, ['KEY_LEFT']])] = 'DEC_LEVEL_VMENU' - self.env['bindings'][str([1, ['KEY_RIGHT']])] = 'INC_LEVEL_VMENU' - self.env['bindings'][str([1, ['KEY_ENTER']])] = 'EXEC_VMENU_ENTRY' + self.env['bindings'][str( + [1, ['KEY_DOWN']])] = 'NEXT_VMENU_ENTRY' + self.env['bindings'][str( + [1, ['KEY_SPACE']])] = 'CURR_VMENU_ENTRY' + self.env['bindings'][str( + [1, ['KEY_LEFT']])] = 'DEC_LEVEL_VMENU' + self.env['bindings'][str( + [1, ['KEY_RIGHT']])] = 'INC_LEVEL_VMENU' + self.env['bindings'][str( + [1, ['KEY_ENTER']])] = 'EXEC_VMENU_ENTRY' # search self.env['bindings'][str([1, ['KEY_A']])] = 'SEARCH_A' self.env['bindings'][str([1, ['KEY_B']])] = 'SEARCH_B' @@ -139,163 +164,194 @@ class vmenuManager(): self.env['bindings'][str([1, ['KEY_Y']])] = 'SEARCH_Y' self.env['bindings'][str([1, ['KEY_Z']])] = 'SEARCH_Z' # page navigation - self.env['bindings'][str([1, ['KEY_PAGEUP']])] = 'PAGE_UP_VMENU' - self.env['bindings'][str([1, ['KEY_PAGEDOWN']])] = 'PAGE_DOWN_VMENU' + self.env['bindings'][str( + [1, ['KEY_PAGEUP']])] = 'PAGE_UP_VMENU' + self.env['bindings'][str( + [1, ['KEY_PAGEDOWN']])] = 'PAGE_DOWN_VMENU' except Exception as e: print(e) else: try: - self.currIndex = None - self.env['bindings'] = self.env['runtime']['settingsManager'].getBindingBackup() + self.curr_index = None + self.env['bindings'] = self.env['runtime']['SettingsManager'].get_binding_backup( + ) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vmenuManager setActive: Error loading binding backup: ' + str(e), debug.debugLevel.ERROR) - def createMenuTree(self, resetIndex = True): + self.env['runtime']['DebugManager'].write_debug_out( + 'VmenuManager set_active: Error loading binding backup: ' + str(e), + debug.DebugLevel.ERROR) + + def create_menu_tree(self, resetIndex=True): if resetIndex: - self.currIndex = None - menu = self.fs_tree_to_dict( self.defaultVMenuPath) + self.curr_index = None + menu = self.fs_tree_to_dict(self.defaultVMenuPath) if menu: self.menuDict = menu - + # Add dynamic voice menus try: - from fenrirscreenreader.core.dynamicVoiceMenu import addDynamicVoiceMenus - addDynamicVoiceMenus(self) + from fenrirscreenreader.core.dynamicVoiceMenu import add_dynamic_voice_menus + add_dynamic_voice_menus(self) except Exception as e: print(f"Error adding dynamic voice menus: {e}") - + # index still valid? - if self.currIndex != None: + if self.curr_index is not None: try: - r = self.getValueByPath(self.menuDict, self.currIndex) + r = self.get_value_by_path(self.menuDict, self.curr_index) if r == {}: - self.currIndex = None + self.curr_index = None except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vmenuManager createMenuTree: Error checking menu index validity: ' + str(e), debug.debugLevel.ERROR) - self.currIndex = None - def executeMenu(self): - if self.currIndex == None: + self.env['runtime']['DebugManager'].write_debug_out( + 'VmenuManager create_menu_tree: Error checking menu index validity: ' + str(e), + debug.DebugLevel.ERROR) + self.curr_index = None + + def execute_menu(self): + if self.curr_index is None: return try: - command = self.getValueByPath(self.menuDict, self.currIndex) - if not command == None: + command = self.get_value_by_path(self.menuDict, self.curr_index) + if command is not None: command.run() if self.closeAfterAction: - self.setActive(False) + self.set_active(False) except Exception as e: try: - self.incLevel() - text = self.getCurrentEntry() - self.env['runtime']['outputManager'].presentText(text, interrupt=True) + self.inc_level() + text = self.get_current_entry() + self.env['runtime']['OutputManager'].present_text( + text, interrupt=True) except Exception as ex: - self.env['runtime']['debug'].writeDebugOut('vmenuManager executeMenu: Error presenting menu text: ' + str(ex), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'VmenuManager execute_menu: Error presenting menu text: ' + str(ex), + debug.DebugLevel.ERROR) - def incLevel(self): - if self.currIndex == None: + def inc_level(self): + if self.curr_index is None: return False try: - r = self.getValueByPath(self.menuDict, self.currIndex +[0]) + r = self.get_value_by_path(self.menuDict, self.curr_index + [0]) if r == {}: return False except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vmenuManager incLevel: Error accessing menu path: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'VmenuManager inc_level: Error accessing menu path: ' + str(e), + debug.DebugLevel.ERROR) return False - self.currIndex.append(0) - return True - def decLevel(self): - if self.currIndex == None: - return False - if self.currMenu != '': - if len(self.currIndex) <= 2: - return False - elif len(self.currIndex) == 1: - return False - self.currIndex = self.currIndex[:len(self.currIndex) - 1] - return True - def nextIndex(self): - if self.currIndex == None: - return False - if self.currIndex[len(self.currIndex) - 1] + 1 >= len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])): - self.currIndex[len(self.currIndex) - 1] = 0 - else: - self.currIndex[len(self.currIndex) - 1] += 1 - return True - def getCurrIndex(self): - if self.currIndex == None: - return 0 - return self.currIndex[len(self.currIndex) - 1] - def prevIndex(self): - if self.currIndex == None: - return False - if self.currIndex[len(self.currIndex) - 1] == 0: - self.currIndex[len(self.currIndex) - 1] = len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])) - 1 - else: - self.currIndex[len(self.currIndex) - 1] -= 1 - return True - - def pageUp(self): - if self.currIndex == None: - return False - menuSize = len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])) - if menuSize <= 1: - return False - jumpSize = max(1, int(menuSize * 0.1)) # 10% of menu size, minimum 1 - newIndex = self.currIndex[len(self.currIndex) - 1] - jumpSize - if newIndex < 0: - newIndex = 0 - self.currIndex[len(self.currIndex) - 1] = newIndex - return True - - def pageDown(self): - if self.currIndex == None: - return False - menuSize = len(self.getNestedByPath(self.menuDict, self.currIndex[:-1])) - if menuSize <= 1: - return False - jumpSize = max(1, int(menuSize * 0.1)) # 10% of menu size, minimum 1 - newIndex = self.currIndex[len(self.currIndex) - 1] + jumpSize - if newIndex >= menuSize: - newIndex = menuSize - 1 - self.currIndex[len(self.currIndex) - 1] = newIndex + self.curr_index.append(0) return True - def getCurrentEntry(self): - return self.getKeysByPath(self.menuDict, self.currIndex)[self.currIndex[-1]] + def dec_level(self): + if self.curr_index is None: + return False + if self.currMenu != '': + if len(self.curr_index) <= 2: + return False + elif len(self.curr_index) == 1: + return False + self.curr_index = self.curr_index[:len(self.curr_index) - 1] + return True + + def next_index(self): + if self.curr_index is None: + return False + if self.curr_index[len(self.curr_index) - 1] + 1 >= len( + self.get_nested_by_path(self.menuDict, self.curr_index[:-1])): + self.curr_index[len(self.curr_index) - 1] = 0 + else: + self.curr_index[len(self.curr_index) - 1] += 1 + return True + + def get_curr_index(self): + if self.curr_index is None: + return 0 + return self.curr_index[len(self.curr_index) - 1] + + def prev_index(self): + if self.curr_index is None: + return False + if self.curr_index[len(self.curr_index) - 1] == 0: + self.curr_index[len(self.curr_index) - 1] = len( + self.get_nested_by_path(self.menuDict, self.curr_index[:-1])) - 1 + else: + self.curr_index[len(self.curr_index) - 1] -= 1 + return True + + def page_up(self): + if self.curr_index is None: + return False + menu_size = len(self.get_nested_by_path( + self.menuDict, self.curr_index[:-1])) + if menu_size <= 1: + return False + jump_size = max(1, int(menu_size * 0.1)) # 10% of menu size, minimum 1 + new_index = self.curr_index[len(self.curr_index) - 1] - jump_size + if new_index < 0: + new_index = 0 + self.curr_index[len(self.curr_index) - 1] = new_index + return True + + def page_down(self): + if self.curr_index is None: + return False + menu_size = len(self.get_nested_by_path( + self.menuDict, self.curr_index[:-1])) + if menu_size <= 1: + return False + jump_size = max(1, int(menu_size * 0.1)) # 10% of menu size, minimum 1 + new_index = self.curr_index[len(self.curr_index) - 1] + jump_size + if new_index >= menu_size: + new_index = menu_size - 1 + self.curr_index[len(self.curr_index) - 1] = new_index + return True + + def get_current_entry(self): + return self.get_keys_by_path(self.menuDict, self.curr_index)[ + self.curr_index[-1]] + def fs_tree_to_dict(self, path_): for root, dirs, files in os.walk(path_): - tree = {d + ' ' + _('Menu'): self.fs_tree_to_dict(os.path.join(root, d)) for d in dirs if not d.startswith('__')} + tree = { + d + + ' ' + + _('Menu'): self.fs_tree_to_dict( + os.path.join( + root, + d)) for d in dirs if not d.startswith('__')} for f in files: try: - fileName, fileExtension = os.path.splitext(f) - fileName = fileName.split('/')[-1] - if fileName.startswith('__'): + file_name, file_extension = os.path.splitext(f) + file_name = file_name.split('/')[-1] + if file_name.startswith('__'): continue # Skip base classes that shouldn't be loaded as commands - if fileName.endswith('_base'): + if file_name.endswith('_base'): continue - command = self.env['runtime']['commandManager'].loadFile(root + '/' + f) - tree.update({fileName + ' ' + _('Action'): command}) + command = self.env['runtime']['CommandManager'].load_file( + root + '/' + f) + tree.update({file_name + ' ' + _('Action'): command}) except Exception as e: print(e) return tree # note we discontinue iteration trough os.walk - def getNestedByPath(self, complete, path): + + def get_nested_by_path(self, complete, path): path = path.copy() if path != []: index = list(complete.keys())[path[0]] - nested = self.getNestedByPath(complete[index], path[1:]) + nested = self.get_nested_by_path(complete[index], path[1:]) return nested else: return complete - - def getKeysByPath(self, complete, path): + def get_keys_by_path(self, complete, path): if not isinstance(complete, dict): - return[] + return [] d = complete for i in path[:-1]: d = d[list(d.keys())[i]] return list(d.keys()) - def getValueByPath(self, complete, path): + def get_value_by_path(self, complete, path): if not isinstance(complete, dict): return complete d = complete.copy() diff --git a/src/fenrirscreenreader/fenrirVersion.py b/src/fenrirscreenreader/fenrirVersion.py index aad0c9e8..4de0ef22 100644 --- a/src/fenrirscreenreader/fenrirVersion.py +++ b/src/fenrirscreenreader/fenrirVersion.py @@ -4,5 +4,5 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -version = "2025.06.30" +version = "2025.07.06" codeName = "master" diff --git a/src/fenrirscreenreader/inputDriver/debugDriver.py b/src/fenrirscreenreader/inputDriver/debugDriver.py index 1908003d..91143d67 100644 --- a/src/fenrirscreenreader/inputDriver/debugDriver.py +++ b/src/fenrirscreenreader/inputDriver/debugDriver.py @@ -6,67 +6,74 @@ import time from fenrirscreenreader.core import debug -from fenrirscreenreader.core.inputDriver import inputDriver +from fenrirscreenreader.core.inputDriver import InputDriver as inputDriver + class driver(inputDriver): def __init__(self): inputDriver.__init__(self) - + def initialize(self, environment): self.env = environment - self.env['runtime']['inputManager'].setShortcutType('KEY') + self.env['runtime']['InputManager'].set_shortcut_type('KEY') self._initialized = True print('Input Debug Driver: Initialized') - + def shutdown(self): if self._initialized: - self.removeAllDevices() + self.remove_all_devices() self._initialized = False print('Input Debug Driver: Shutdown') - - def getInputEvent(self): + + def get_input_event(self): time.sleep(0.1) if not self._initialized: return None - print('Input Debug Driver: getInputEvent') + print('Input Debug Driver: get_input_event') return None - def writeEventBuffer(self): + + def write_event_buffer(self): if not self._initialized: return - print('Input Debug Driver: writeEventBuffer') - def clearEventBuffer(self): + print('Input Debug Driver: write_event_buffer') + + def clear_event_buffer(self): if not self._initialized: return del self.env['input']['eventBuffer'][:] - print('Input Debug Driver: clearEventBuffer') - def updateInputDevices(self, newDevices = None, init = False): + print('Input Debug Driver: clear_event_buffer') + + def update_input_devices(self, new_devices=None, init=False): if not self._initialized: return - print('Input Debug Driver: updateInputDevices') - def getLedState(self, led = 0): + print('Input Debug Driver: update_input_devices') + + def get_led_state(self, led=0): if not self._initialized: return False return False - def toggleLedState(self, led = 0): + + def toggle_led_state(self, led=0): if not self._initialized: return - print('Input Debug Driver: toggleLedState') - def grabAllDevices(self): + print('Input Debug Driver: toggle_led_state') + + def grab_all_devices(self): if not self._initialized: return - print('Input Debug Driver: grabAllDevices') - def ungrabAllDevices(self): + print('Input Debug Driver: grab_all_devices') + + def ungrab_all_devices(self): if not self._initialized: return - print('Input Debug Driver: ungrabAllDevices') - - def removeAllDevices(self): + print('Input Debug Driver: ungrab_all_devices') + + def remove_all_devices(self): if not self._initialized: - return - print('Input Debug Driver: removeAllDevices') + return + print('Input Debug Driver: remove_all_devices') + def __del__(self): if self._initialized: - self.removeAllDevices() + self.remove_all_devices() print('Input Debug Driver: __del__') - - diff --git a/src/fenrirscreenreader/inputDriver/dummyDriver.py b/src/fenrirscreenreader/inputDriver/dummyDriver.py index 1c4d0ed8..22462243 100644 --- a/src/fenrirscreenreader/inputDriver/dummyDriver.py +++ b/src/fenrirscreenreader/inputDriver/dummyDriver.py @@ -6,7 +6,8 @@ import time from fenrirscreenreader.core import debug -from fenrirscreenreader.core.inputDriver import inputDriver +from fenrirscreenreader.core.inputDriver import InputDriver as inputDriver + class driver(inputDriver): def __init__(self): diff --git a/src/fenrirscreenreader/inputDriver/evdevDriver.py b/src/fenrirscreenreader/inputDriver/evdevDriver.py index 21a970ca..626655e6 100644 --- a/src/fenrirscreenreader/inputDriver/evdevDriver.py +++ b/src/fenrirscreenreader/inputDriver/evdevDriver.py @@ -1,6 +1,16 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. +from fenrirscreenreader.core.inputDriver import InputDriver as inputDriver +from fenrirscreenreader.core import debug +from fenrirscreenreader.core import inputData +from fenrirscreenreader.core.eventData import FenrirEventType +import threading +from ctypes import c_bool +from multiprocessing.sharedctypes import Value +import multiprocessing +from select import select +import time _evdevAvailable = False _udevAvailable = False _evdevAvailableError = '' @@ -19,17 +29,6 @@ try: except Exception as e: _udevAvailableError = str(e) -import time -from select import select -import multiprocessing -from multiprocessing.sharedctypes import Value -from ctypes import c_bool -import threading - -from fenrirscreenreader.core.eventData import fenrirEventType -from fenrirscreenreader.core import inputData -from fenrirscreenreader.core import debug -from fenrirscreenreader.core.inputDriver import inputDriver class driver(inputDriver): def __init__(self): @@ -40,82 +39,105 @@ class driver(inputDriver): self.uDevices = {} self.gDevices = {} self.iDeviceNo = 0 - self.watchDog = Value(c_bool, True) + self.watch_dog = Value(c_bool, True) self.UInputinject = UInput() self._deviceLock = threading.Lock() + def initialize(self, environment): self.env = environment - self.env['runtime']['inputManager'].setShortcutType('KEY') + self.env['runtime']['InputManager'].set_shortcut_type('KEY') global _evdevAvailable global _udevAvailable global _evdevAvailableError global _udevAvailableError if not _udevAvailable: - self.env['runtime']['debug'].writeDebugOut('InputDriver:' + _udevAvailableError, debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver:' + _udevAvailableError, debug.DebugLevel.ERROR) if not _evdevAvailable: - self.env['runtime']['debug'].writeDebugOut('InputDriver:' + _evdevAvailableError, debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver:' + _evdevAvailableError, debug.DebugLevel.ERROR) return if _udevAvailable: - self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev) - self.env['runtime']['processManager'].addCustomEventThread(self.inputWatchdog) + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.plug_input_device_watchdog_udev) + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.input_watchdog) self._initialized = True - def plugInputDeviceWatchdogUdev(self, active, eventQueue): + def plug_input_device_watchdog_udev(self, active, event_queue): context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by(subsystem='input') monitor.start() - ignorePlug = False + ignore_plug = False while active.value: - validDevices = [] + valid_devices = [] device = monitor.poll(1) while device: - self.env['runtime']['debug'].writeDebugOut('plugInputDeviceWatchdogUdev:' + str(device), debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'plug_input_device_watchdog_udev:' + str(device), debug.DebugLevel.INFO) try: try: # FIX: Check if attributes exist before accessing them - if hasattr(device, 'name') and device.name and device.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']: - ignorePlug = True - if hasattr(device, 'phys') and device.phys and device.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']: - ignorePlug = True - if hasattr(device, 'name') and device.name and 'BRLTTY' in device.name.upper(): - ignorePlug = True + if hasattr( + device, + 'name') and device.name and device.name.upper() in [ + '', + 'SPEAKUP', + 'FENRIR-UINPUT']: + ignore_plug = True + if hasattr( + device, + 'phys') and device.phys and device.phys.upper() in [ + '', + 'SPEAKUP', + 'FENRIR-UINPUT']: + ignore_plug = True + if hasattr( + device, + 'name') and device.name and 'BRLTTY' in device.name.upper(): + ignore_plug = True except Exception as e: - self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev CHECK NAME CRASH: " + str(e), debug.debugLevel.ERROR) - - if not ignorePlug: + self.env['runtime']['DebugManager'].write_debug_out( + "plug_input_device_watchdog_udev CHECK NAME CRASH: " + str(e), debug.DebugLevel.ERROR) + + if not ignore_plug: virtual = '/sys/devices/virtual/input/' in device.sys_path if device.device_node: - validDevices.append({'device': device.device_node, 'virtual': virtual}) + valid_devices.append( + {'device': device.device_node, 'virtual': virtual}) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev APPEND CRASH: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "plug_input_device_watchdog_udev APPEND CRASH: " + str(e), debug.DebugLevel.ERROR) try: - pollTimeout = 1 - device = monitor.poll(pollTimeout) + poll_timeout = 1 + device = monitor.poll(poll_timeout) except Exception: device = None - ignorePlug = False - if validDevices: - eventQueue.put({"Type": fenrirEventType.PlugInputDevice, "Data": validDevices}) + ignore_plug = False + if valid_devices: + event_queue.put( + {"Type": FenrirEventType.plug_input_device, "data": valid_devices}) return time.time() - def inputWatchdog(self, active, eventQueue): + def input_watchdog(self, active, event_queue): try: while active.value: - # Get a snapshot of devices for select() to avoid lock contention + # Get a snapshot of devices for select() to avoid lock + # contention with self._deviceLock: devices_snapshot = self.iDevices.copy() - + if not devices_snapshot: time.sleep(0.1) continue - + r, w, x = select(devices_snapshot, [], [], 0.8) event = None - foundKeyInSequence = False + found_key_in_sequence = False foreward = False - eventFired = False + event_fired = False for fd in r: # Check if device still exists before accessing with self._deviceLock: @@ -123,185 +145,236 @@ class driver(inputDriver): continue device = self.iDevices[fd] udevice = self.uDevices.get(fd) - + try: event = device.read_one() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver handleInputEvent: Error reading event: ' + str(e), debug.debugLevel.ERROR) - self.removeDevice(fd) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver handle_input_event: Error reading event: ' + str(e), + debug.DebugLevel.ERROR) + self.remove_device(fd) continue - while(event): - self.env['runtime']['debug'].writeDebugOut('inputWatchdog: EVENT:' + str(event), debug.debugLevel.INFO) - self.env['input']['eventBuffer'].append([device, udevice, event]) + while (event): + self.env['runtime']['DebugManager'].write_debug_out( + 'input_watchdog: EVENT:' + str(event), debug.DebugLevel.INFO) + self.env['input']['eventBuffer'].append( + [device, udevice, event]) if event.type == evdev.events.EV_KEY: - if not foundKeyInSequence: - foundKeyInSequence = True + if not found_key_in_sequence: + found_key_in_sequence = True if event.code != 0: - currMapEvent = self.mapEvent(event) - if not currMapEvent: + curr_map_event = self.map_event(event) + if not curr_map_event: event = device.read_one() continue - if not isinstance(currMapEvent['EventName'], str): + if not isinstance( + curr_map_event['EventName'], str): event = device.read_one() continue - if currMapEvent['EventState'] in [0, 1, 2]: - eventQueue.put({"Type": fenrirEventType.KeyboardInput, "Data": currMapEvent.copy()}) - eventFired = True + if curr_map_event['EventState'] in [0, 1, 2]: + event_queue.put( + {"Type": FenrirEventType.keyboard_input, "data": curr_map_event.copy()}) + event_fired = True else: if event.type in [2, 3]: foreward = True event = device.read_one() - if not foundKeyInSequence: - if foreward and not eventFired: - self.writeEventBuffer() - self.clearEventBuffer() + if not found_key_in_sequence: + if foreward and not event_fired: + self.write_event_buffer() + self.clear_event_buffer() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("INPUT WATCHDOG CRASH: " + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + "INPUT WATCHDOG CRASH: " + str(e), debug.DebugLevel.ERROR) - def writeEventBuffer(self): + def write_event_buffer(self): if not self._initialized: - return + return for iDevice, uDevice, event in self.env['input']['eventBuffer']: try: if uDevice: if self.gDevices[iDevice.fd]: - self.writeUInput(uDevice, event) + self.write_u_input(uDevice, event) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver writeEventBuffer: Error writing event: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver write_event_buffer: Error writing event: ' + str(e), + debug.DebugLevel.ERROR) - def writeUInput(self, uDevice, event): + def write_u_input(self, uDevice, event): if not self._initialized: return uDevice.write_event(event) time.sleep(0.0000002) uDevice.syn() - def updateInputDevices(self, newDevices=None, init=False): + def update_input_devices(self, new_devices=None, init=False): if init: - self.removeAllDevices() + self.remove_all_devices() - deviceFileList = None + device_file_list = None - if newDevices and not init: - if not isinstance(newDevices, list): - newDevices = [newDevices] - deviceFileList = newDevices + if new_devices and not init: + if not isinstance(new_devices, list): + new_devices = [new_devices] + device_file_list = new_devices else: - deviceFileList = evdev.list_devices() - if len(deviceFileList) == self.iDeviceNo: - return - if not deviceFileList: + device_file_list = evdev.list_devices() + if len(device_file_list) == self.iDeviceNo: + return + if not device_file_list: return - mode = self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() - - iDevicesFiles = [] - for device in self.iDevices: - iDevicesFiles.append(self.iDevices[device].fn) + mode = self.env['runtime']['SettingsManager'].get_setting( + 'keyboard', 'device').upper() - eventType = evdev.events - for deviceFile in deviceFileList: + i_devices_files = [] + for device in self.iDevices: + i_devices_files.append(self.iDevices[device].path) + + event_type = evdev.events + for deviceFile in device_file_list: try: if not deviceFile: continue if deviceFile == '': continue - if deviceFile in iDevicesFiles: + if deviceFile in i_devices_files: continue try: with open(deviceFile) as f: pass except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver updateInputDevices: Error opening device file: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver update_input_devices: Error opening device file: ' + str(e), + debug.DebugLevel.ERROR) continue # 3 pos absolute # 2 pos relative # 1 Keys try: - currDevice = evdev.InputDevice(deviceFile) + curr_device = evdev.InputDevice(deviceFile) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver createDeviceType: Error creating device: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver createDeviceType: Error creating device: ' + str(e), + debug.DebugLevel.ERROR) continue try: # FIX: Check if attributes exist before accessing them - if hasattr(currDevice, 'name') and currDevice.name and currDevice.name.upper() in ['', 'SPEAKUP', 'FENRIR-UINPUT']: + if hasattr( + curr_device, + 'name') and curr_device.name and curr_device.name.upper() in [ + '', + 'SPEAKUP', + 'FENRIR-UINPUT']: continue - if hasattr(currDevice, 'phys') and currDevice.phys and currDevice.phys.upper() in ['', 'SPEAKUP', 'FENRIR-UINPUT']: + if hasattr( + curr_device, + 'phys') and curr_device.phys and curr_device.phys.upper() in [ + '', + 'SPEAKUP', + 'FENRIR-UINPUT']: continue - if hasattr(currDevice, 'name') and currDevice.name and 'BRLTTY' in currDevice.name.upper(): + if hasattr( + curr_device, + 'name') and curr_device.name and 'BRLTTY' in curr_device.name.upper(): continue except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver: Error checking device capabilities: ' + str(e), debug.debugLevel.ERROR) - cap = currDevice.capabilities() + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver: Error checking device capabilities: ' + str(e), + debug.DebugLevel.ERROR) + cap = curr_device.capabilities() if mode in ['ALL', 'NOMICE']: - if eventType.EV_KEY in cap: - if 116 in cap[eventType.EV_KEY] and len(cap[eventType.EV_KEY]) < 10: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name, debug.debugLevel.INFO) + if event_type.EV_KEY in cap: + if 116 in cap[event_type.EV_KEY] and len( + cap[event_type.EV_KEY]) < 10: + self.env['runtime']['DebugManager'].write_debug_out( + 'Device Skipped (has 116):' + curr_device.name, debug.DebugLevel.INFO) continue - if len(cap[eventType.EV_KEY]) < 60: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name, debug.debugLevel.INFO) + if len(cap[event_type.EV_KEY]) < 60: + self.env['runtime']['DebugManager'].write_debug_out( + 'Device Skipped (< 60 keys):' + curr_device.name, debug.DebugLevel.INFO) continue if mode == 'ALL': - self.addDevice(currDevice) - self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO) + self.add_device(curr_device) + self.env['runtime']['DebugManager'].write_debug_out( + 'Device added (ALL):' + self.iDevices[curr_device.fd].name, debug.DebugLevel.INFO) elif mode == 'NOMICE': - if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)): - self.addDevice(currDevice) - self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO) + if not ( + (event_type.EV_REL in cap) or ( + event_type.EV_ABS in cap)): + self.add_device(curr_device) + self.env['runtime']['DebugManager'].write_debug_out( + 'Device added (NOMICE):' + self.iDevices[curr_device.fd].name, debug.DebugLevel.INFO) else: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name, debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'Device Skipped (NOMICE):' + curr_device.name, debug.DebugLevel.INFO) else: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (no EV_KEY):' + currDevice.name, debug.debugLevel.INFO) - elif currDevice.name.upper() in mode.split(','): - self.addDevice(currDevice) - self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'Device Skipped (no EV_KEY):' + curr_device.name, debug.DebugLevel.INFO) + elif curr_device.name.upper() in mode.split(','): + self.add_device(curr_device) + self.env['runtime']['DebugManager'].write_debug_out( + 'Device added (Name):' + self.iDevices[curr_device.fd].name, debug.DebugLevel.INFO) except Exception as e: try: - device_name = currDevice.name if hasattr(currDevice, 'name') else "unknown" - self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile + ' ' + device_name + ' ' + str(e), debug.debugLevel.INFO) + device_name = curr_device.name if hasattr( + curr_device, 'name') else "unknown" + self.env['runtime']['DebugManager'].write_debug_out( + "Device Skipped (Exception): " + + deviceFile + + ' ' + + device_name + + ' ' + + str(e), + debug.DebugLevel.INFO) except Exception as ex: - self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile + ' ' + str(ex), debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + "Device Skipped (Exception): " + deviceFile + ' ' + str(ex), + debug.DebugLevel.INFO) self.iDeviceNo = len(evdev.list_devices()) - self.updateMPiDevicesFD() + self.update_m_pi_devices_fd() - def updateMPiDevicesFD(self): + def update_m_pi_devices_fd(self): try: for fd in self.iDevices: - if not fd in self.iDevicesFD: + if fd not in self.iDevicesFD: self.iDevicesFD.append(fd) for fd in self.iDevicesFD: - if not fd in self.iDevices: + if fd not in self.iDevices: self.iDevicesFD.remove(fd) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver updateMPiDevicesFD: Error updating device file descriptors: ' + str(e), debug.debugLevel.ERROR) - - def mapEvent(self, event): + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver update_m_pi_devices_fd: Error updating device file descriptors: ' + + str(e), + debug.DebugLevel.ERROR) + + def map_event(self, event): if not self._initialized: return None if not event: return None - mEvent = inputData.inputEvent + m_event = inputData.input_event try: # mute is a list = ['KEY_MIN_INTERESTING', 'KEY_MUTE'] - mEvent['EventName'] = evdev.ecodes.keys[event.code] - if isinstance(mEvent['EventName'], list): - if len(mEvent['EventName']) > 0: - mEvent['EventName'] = mEvent['EventName'][0] - if isinstance(mEvent['EventName'], list): - if len(mEvent['EventName']) > 0: - mEvent['EventName'] = mEvent['EventName'][0] - mEvent['EventValue'] = event.code - mEvent['EventSec'] = event.sec - mEvent['EventUsec'] = event.usec - mEvent['EventState'] = event.value - mEvent['EventType'] = event.type - return mEvent + m_event['EventName'] = evdev.ecodes.keys[event.code] + if isinstance(m_event['EventName'], list): + if len(m_event['EventName']) > 0: + m_event['EventName'] = m_event['EventName'][0] + if isinstance(m_event['EventName'], list): + if len(m_event['EventName']) > 0: + m_event['EventName'] = m_event['EventName'][0] + m_event['EventValue'] = event.code + m_event['EventSec'] = event.sec + m_event['EventUsec'] = event.usec + m_event['EventState'] = event.value + m_event['EventType'] = event.type + return m_event except Exception as e: return None - def getLedState(self, led=0): - if not self.hasIDevices(): + def get_led_state(self, led=0): + if not self.has_i_devices(): return False # 0 = Numlock # 1 = Capslock @@ -310,40 +383,41 @@ class driver(inputDriver): if led in dev.leds(): return True return False - - def toggleLedState(self, led=0): - if not self.hasIDevices(): + + def toggle_led_state(self, led=0): + if not self.has_i_devices(): return False - ledState = self.getLedState(led) + led_state = self.get_led_state(led) for i in self.iDevices: if self.gDevices[i]: # 17 LEDs if 17 in self.iDevices[i].capabilities(): - if ledState == 1: + if led_state == 1: self.iDevices[i].set_led(led, 0) else: self.iDevices[i].set_led(led, 1) - - def grabAllDevices(self): + + def grab_all_devices(self): if not self._initialized: return True ok = True for fd in self.iDevices: if not self.gDevices[fd]: - ok = ok and self.grabDevice(fd) + ok = ok and self.grab_device(fd) return ok - - def ungrabAllDevices(self): + + def ungrab_all_devices(self): if not self._initialized: return True ok = True for fd in self.iDevices: if self.gDevices[fd]: - ok = ok and self.ungrabDevice(fd) + ok = ok and self.ungrab_device(fd) return ok - - def createUInputDev(self, fd): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + + def create_u_input_dev(self, fd): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): self.uDevices[fd] = None return try: @@ -351,135 +425,185 @@ class driver(inputDriver): return except KeyError: self.uDevices[fd] = None - if self.uDevices[fd] != None: + if self.uDevices[fd] is not None: return try: - self.uDevices[fd] = UInput.from_device(self.iDevices[fd], name='fenrir-uinput', phys='fenrir-uinput') + self.uDevices[fd] = UInput.from_device( + self.iDevices[fd], name='fenrir-uinput', phys='fenrir-uinput') except Exception as e: try: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback: ' + str(e), debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: compat fallback: ' + str(e), debug.DebugLevel.WARNING) dev = self.iDevices[fd] cap = dev.capabilities() del cap[0] self.uDevices[fd] = UInput( - cap, - name='fenrir-uinput', - phys='fenrir-uinput' + cap, + name='fenrir-uinput', + phys='fenrir-uinput' ) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: init Uinput not possible: ' + str(e), + debug.DebugLevel.ERROR) return - - def addDevice(self, newDevice): - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device added: ' + str(newDevice.fd) + ' ' + str(newDevice), debug.debugLevel.INFO) + + def add_device(self, newDevice): + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: device added: ' + str( + newDevice.fd) + ' ' + str(newDevice), + debug.DebugLevel.INFO) with self._deviceLock: try: - self.iDevices[newDevice.fd] = newDevice - self.createUInputDev(newDevice.fd) + self.iDevices[newDevice.fd] = newDevice + self.create_u_input_dev(newDevice.fd) self.gDevices[newDevice.fd] = False except Exception as e: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: error adding device: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: error adding device: ' + str(e), debug.DebugLevel.ERROR) # if it doesnt work clean up try: - del(self.iDevices[newDevice.fd]) + del (self.iDevices[newDevice.fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error removing iDevice: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error removing iDevice: ' + str(e), + debug.DebugLevel.ERROR) try: - del(self.uDevices[newDevice.fd]) + del (self.uDevices[newDevice.fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error removing uDevice: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error removing uDevice: ' + str(e), + debug.DebugLevel.ERROR) try: - del(self.gDevices[newDevice.fd]) + del (self.gDevices[newDevice.fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver addDevice: Error cleaning up gDevice: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver add_device: Error cleaning up gDevice: ' + str(e), + debug.DebugLevel.ERROR) - def grabDevice(self, fd): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + def grab_device(self, fd): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): return True - + # FIX: Handle exception variable scope correctly grab_error = None try: self.iDevices[fd].grab() self.gDevices[fd] = True - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grab device (' + str(self.iDevices[fd].name) + ')', debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: grab device (' + str(self.iDevices[fd].name) + ')', debug.DebugLevel.INFO) # Reset modifier keys on successful grab if self.uDevices[fd]: - modifierKeys = [e.KEY_LEFTCTRL, e.KEY_RIGHTCTRL, e.KEY_LEFTALT, e.KEY_RIGHTALT, e.KEY_LEFTSHIFT, e.KEY_RIGHTSHIFT] - for key in modifierKeys: + modifier_keys = [ + e.KEY_LEFTCTRL, + e.KEY_RIGHTCTRL, + e.KEY_LEFTALT, + e.KEY_RIGHTALT, + e.KEY_LEFTSHIFT, + e.KEY_RIGHTSHIFT] + for key in modifier_keys: try: self.uDevices[fd].write(e.EV_KEY, key, 0) # 0 = key up self.uDevices[fd].syn() except Exception as mod_error: - self.env['runtime']['debug'].writeDebugOut('Failed to reset modifier key: ' + str(mod_error), debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'Failed to reset modifier key: ' + str(mod_error), debug.DebugLevel.WARNING) except IOError: if not self.gDevices[fd]: return False except Exception as ex: grab_error = ex - + if grab_error: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(grab_error), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: grabing not possible: ' + + str(grab_error), + debug.DebugLevel.ERROR) return False - + return True - def ungrabDevice(self, fd): - if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + def ungrab_device(self, fd): + if not self.env['runtime']['SettingsManager'].get_setting_as_bool( + 'keyboard', 'grabDevices'): return True - + # FIX: Handle exception variable scope correctly ungrab_error = None try: self.iDevices[fd].ungrab() self.gDevices[fd] = False - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrab device (' + str(self.iDevices[fd].name) + ')', debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: ungrab device (' + str(self.iDevices[fd].name) + ')', debug.DebugLevel.INFO) except IOError: if self.gDevices[fd]: return False except Exception as ex: ungrab_error = ex - + if ungrab_error: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrabing not possible: ' + str(ungrab_error), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: ungrabing not possible: ' + + str(ungrab_error), + debug.DebugLevel.ERROR) return False - + return True - - def removeDevice(self, fd): + + def remove_device(self, fd): with self._deviceLock: try: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed: ' + str(fd) + ' ' + str(self.iDevices[fd]), debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: device removed: ' + str(fd) + ' ' + str( + self.iDevices[fd]), debug.DebugLevel.INFO) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed: ' + str(fd) + ' Error: ' + str(e), debug.debugLevel.INFO) - self.clearEventBuffer() + self.env['runtime']['DebugManager'].write_debug_out( + 'InputDriver evdev: device removed: ' + + str(fd) + + ' Error: ' + + str(e), + debug.DebugLevel.INFO) + self.clear_event_buffer() try: - self.ungrabDevice(fd) + self.ungrab_device(fd) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error ungrabbing device ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error ungrabbing device ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) try: self.iDevices[fd].close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error closing iDevice ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error closing iDevice ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) try: self.uDevices[fd].close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error closing uDevice ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error closing uDevice ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) try: - del(self.iDevices[fd]) + del (self.iDevices[fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error deleting iDevice ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error deleting iDevice ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) try: - del(self.uDevices[fd]) + del (self.uDevices[fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error deleting uDevice ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error deleting uDevice ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) try: - del(self.gDevices[fd]) + del (self.gDevices[fd]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver removeDevice: Error deleting gDevice ' + str(fd) + ': ' + str(e), debug.debugLevel.ERROR) - self.updateMPiDevicesFD() + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver remove_device: Error deleting gDevice ' + str(fd) + ': ' + str(e), + debug.DebugLevel.ERROR) + self.update_m_pi_devices_fd() - def hasIDevices(self): + def has_i_devices(self): if not self._initialized: return False if not self.iDevices: @@ -488,21 +612,23 @@ class driver(inputDriver): return False return True - def sendKey(self, key, state): + def send_key(self, key, state): if not self._initialized: return try: self.UInputinject.write(e.EV_KEY, e.ecodes[key], state) self.UInputinject.syn() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('evdevDriver sendKey: Error sending key ' + str(key) + ': ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'evdevDriver send_key: Error sending key ' + str(key) + ': ' + str(e), + debug.DebugLevel.ERROR) - def removeAllDevices(self): - if not self.hasIDevices(): + def remove_all_devices(self): + if not self.has_i_devices(): return devices = self.iDevices.copy() for fd in devices: - self.removeDevice(fd) + self.remove_device(fd) self.iDevices.clear() self.uDevices.clear() self.gDevices.clear() diff --git a/src/fenrirscreenreader/inputDriver/ptyDriver.py b/src/fenrirscreenreader/inputDriver/ptyDriver.py index 13a00811..87a10ba2 100644 --- a/src/fenrirscreenreader/inputDriver/ptyDriver.py +++ b/src/fenrirscreenreader/inputDriver/ptyDriver.py @@ -6,13 +6,15 @@ import time from fenrirscreenreader.core import debug -from fenrirscreenreader.core.inputDriver import inputDriver +from fenrirscreenreader.core.inputDriver import InputDriver as inputDriver + class driver(inputDriver): def __init__(self): - self._isInitialized = False + self._is_initialized = False inputDriver.__init__(self) + def initialize(self, environment): self.env = environment - self.env['runtime']['inputManager'].setShortcutType('BYTE') - self._isInitialized = True + self.env['runtime']['InputManager'].set_shortcut_type('BYTE') + self._is_initialized = True diff --git a/src/fenrirscreenreader/remoteDriver/dummyDriver.py b/src/fenrirscreenreader/remoteDriver/dummyDriver.py index aae81930..1a715036 100644 --- a/src/fenrirscreenreader/remoteDriver/dummyDriver.py +++ b/src/fenrirscreenreader/remoteDriver/dummyDriver.py @@ -5,7 +5,8 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.remoteDriver import remoteDriver +from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver + class driver(remoteDriver): def __init__(self): diff --git a/src/fenrirscreenreader/remoteDriver/tcpDriver.py b/src/fenrirscreenreader/remoteDriver/tcpDriver.py index 3073c9ec..01280b8a 100644 --- a/src/fenrirscreenreader/remoteDriver/tcpDriver.py +++ b/src/fenrirscreenreader/remoteDriver/tcpDriver.py @@ -5,23 +5,31 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.remoteDriver import remoteDriver -from fenrirscreenreader.core.eventData import fenrirEventType +from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver +from fenrirscreenreader.core.eventData import FenrirEventType + +import select +import socket +import os +import os.path -import select, socket, os, os.path class driver(remoteDriver): def __init__(self): remoteDriver.__init__(self) + def initialize(self, environment): - self.env = environment - self.env['runtime']['processManager'].addCustomEventThread(self.watchDog, multiprocess=True) - def watchDog(self, active, eventQueue): + self.env = environment + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.watch_dog, multiprocess=True) + + def watch_dog(self, active, event_queue): # echo "command say this is a test" | nc localhost 22447 self.fenrirSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.fenrirSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.host = '127.0.0.1' - self.port = self.env['runtime']['settingsManager'].getSettingAsInt('remote', 'port') + self.port = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'remote', 'port') self.fenrirSock.bind((self.host, self.port)) self.fenrirSock.listen(1) while active.value: @@ -36,18 +44,24 @@ class driver(remoteDriver): try: rawdata = client_sock.recv(8129) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('tcpDriver watchDog: Error receiving data from client: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'tcpDriver watch_dog: Error receiving data from client: ' + str(e), + debug.DebugLevel.ERROR) try: data = rawdata.decode("utf-8").rstrip().lstrip() - eventQueue.put({"Type":fenrirEventType.RemoteIncomming, - "Data": data - }) + event_queue.put({"Type": FenrirEventType.remote_incomming, + "data": data + }) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('tcpDriver watchDog: Error decoding/queuing data: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'tcpDriver watch_dog: Error decoding/queuing data: ' + str(e), + debug.DebugLevel.ERROR) try: client_sock.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('tcpDriver watchDog: Error closing client socket: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'tcpDriver watch_dog: Error closing client socket: ' + str(e), + debug.DebugLevel.ERROR) if self.fenrirSock: self.fenrirSock.close() self.fenrirSock = None diff --git a/src/fenrirscreenreader/remoteDriver/unixDriver.py b/src/fenrirscreenreader/remoteDriver/unixDriver.py index a56724ce..23294fa7 100644 --- a/src/fenrirscreenreader/remoteDriver/unixDriver.py +++ b/src/fenrirscreenreader/remoteDriver/unixDriver.py @@ -5,35 +5,47 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.remoteDriver import remoteDriver -from fenrirscreenreader.core.eventData import fenrirEventType +from fenrirscreenreader.core.remoteDriver import RemoteDriver as remoteDriver +from fenrirscreenreader.core.eventData import FenrirEventType -import select, socket, os, os.path +import select +import socket +import os +import os.path class driver(remoteDriver): def __init__(self): remoteDriver.__init__(self) + def initialize(self, environment): self.env = environment - self.env['runtime']['processManager'].addCustomEventThread(self.watchDog, multiprocess=True) - def watchDog(self, active, eventQueue): - # echo "command say this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock - socketFile = '' + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.watch_dog, multiprocess=True) + + def watch_dog(self, active, event_queue): + # echo "command say this is a test" | socat - + # UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock + socket_file = '' try: - socketFile = self.env['runtime']['settingsManager'].getSetting('remote', 'socketFile') + socket_file = self.env['runtime']['SettingsManager'].get_setting( + 'remote', 'socket_file') except Exception as e: - self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error getting socket file setting: ' + str(e), debug.debugLevel.ERROR) - if socketFile == '': - if self.env['runtime']['settingsManager'].getSetting('screen', 'driver') =='vcsaDriver': - socketFile = '/tmp/fenrirscreenreader-deamon.sock' + self.env['runtime']['DebugManager'].write_debug_out( + 'unixDriver watch_dog: Error getting socket file setting: ' + str(e), + debug.DebugLevel.ERROR) + if socket_file == '': + if self.env['runtime']['SettingsManager'].get_setting( + 'screen', 'driver') == 'vcsaDriver': + socket_file = '/tmp/fenrirscreenreader-deamon.sock' else: - socketFile = '/tmp/fenrirscreenreader-' + str(os.getppid()) + '.sock' - if os.path.exists(socketFile): - os.unlink(socketFile) + socket_file = '/tmp/fenrirscreenreader-' + \ + str(os.getppid()) + '.sock' + if os.path.exists(socket_file): + os.unlink(socket_file) self.fenrirSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - self.fenrirSock.bind(socketFile) - os.chmod(socketFile, 0o666) # Allow all users to read/write + self.fenrirSock.bind(socket_file) + os.chmod(socket_file, 0o666) # Allow all users to read/write self.fenrirSock.listen(1) while active.value: # Check if the client is still connected and if data is available: @@ -45,29 +57,36 @@ class driver(remoteDriver): continue if self.fenrirSock in r: client_sock, client_addr = self.fenrirSock.accept() - # Ensure client socket is always closed to prevent resource leaks + # Ensure client socket is always closed to prevent resource + # leaks try: try: rawdata = client_sock.recv(8129) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error receiving data from client: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'unixDriver watch_dog: Error receiving data from client: ' + str(e), + debug.DebugLevel.ERROR) rawdata = b'' # Set default empty data if recv fails - + try: data = rawdata.decode("utf-8").rstrip().lstrip() - eventQueue.put({"Type":fenrirEventType.RemoteIncomming, - "Data": data - }) + event_queue.put({"Type": FenrirEventType.remote_incomming, + "data": data + }) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error decoding/queuing data: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'unixDriver watch_dog: Error decoding/queuing data: ' + str(e), + debug.DebugLevel.ERROR) finally: # Always close client socket, even if data processing fails try: client_sock.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('unixDriver watchDog: Error closing client socket: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'unixDriver watch_dog: Error closing client socket: ' + str(e), + debug.DebugLevel.ERROR) if self.fenrirSock: self.fenrirSock.close() self.fenrirSock = None - if os.path.exists(socketFile): - os.unlink(socketFile) + if os.path.exists(socket_file): + os.unlink(socket_file) diff --git a/src/fenrirscreenreader/screenDriver/dummyDriver.py b/src/fenrirscreenreader/screenDriver/dummyDriver.py index b671a0aa..667c9a58 100644 --- a/src/fenrirscreenreader/screenDriver/dummyDriver.py +++ b/src/fenrirscreenreader/screenDriver/dummyDriver.py @@ -5,7 +5,8 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.screenDriver import screenDriver +from fenrirscreenreader.core.screenDriver import ScreenDriver as screenDriver + class driver(screenDriver): def __init__(self): diff --git a/src/fenrirscreenreader/screenDriver/ptyDriver.py b/src/fenrirscreenreader/screenDriver/ptyDriver.py index 8bf541e5..e7015a27 100644 --- a/src/fenrirscreenreader/screenDriver/ptyDriver.py +++ b/src/fenrirscreenreader/screenDriver/ptyDriver.py @@ -4,78 +4,109 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -import os, struct, sys, pty, tty, termios, shlex, signal, pyte, time, fcntl ,getpass +import os +import struct +import sys +import pty +import tty +import termios +import shlex +import signal +import pyte +import time +import fcntl +import getpass from select import select from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType -from fenrirscreenreader.core.screenDriver import screenDriver +from fenrirscreenreader.core.eventData import FenrirEventType +from fenrirscreenreader.core.screenDriver import ScreenDriver as screenDriver from fenrirscreenreader.utils import screen_utils -class fenrirScreen(pyte.Screen): +class FenrirScreen(pyte.Screen): def set_margins(self, *args, **kwargs): kwargs.pop("private", None) - super(fenrirScreen, self).set_margins(*args, **kwargs) + super(FenrirScreen, self).set_margins(*args, **kwargs) + class Terminal: def __init__(self, columns, lines, p_in): self.text = '' self.attributes = None - self.screen = fenrirScreen(columns, lines) + self.screen = FenrirScreen(columns, lines) self.screen.write_process_input = \ lambda data: p_in.write(data.encode()) self.stream = pyte.ByteStream() self.stream.attach(self.screen) + def feed(self, data): self.stream.feed(data) - def updateAttributes(self, initialize = False): + def update_attributes(self, initialize=False): buffer = self.screen.buffer lines = None if not initialize: lines = self.screen.dirty else: lines = range(self.screen.lines) - self.attributes = [[list(attribute[1:]) + [False, 'default', 'default'] for attribute in line.values()] for line in buffer.values()] + self.attributes = [[list(attribute[1:]) + [False, 'default', 'default'] + for attribute in line.values()] for line in buffer.values()] for y in lines: try: t = self.attributes[y] except Exception as e: - # Terminal class doesn't have access to env, use fallback logging - print(f'ptyDriver Terminal updateAttributes: Error accessing attributes: {e}') + # Terminal class doesn't have access to env, use fallback + # logging + print( + f'ptyDriver Terminal update_attributes: Error accessing attributes: {e}') self.attributes.append([]) - self.attributes[y] = [list(attribute[1:]) + [False, 'default', 'default'] for attribute in (buffer[y].values())] + self.attributes[y] = [list( + attribute[1:]) + [False, 'default', 'default'] for attribute in (buffer[y].values())] if len(self.attributes[y]) < self.screen.columns: diff = self.screen.columns - len(self.attributes[y]) - self.attributes[y] += [['default', 'default', False, False, False, False, False, False, 'default', 'default']] * diff + self.attributes[y] += [['default', + 'default', + False, + False, + False, + False, + False, + False, + 'default', + 'default']] * diff def resize(self, lines, columns): self.screen.resize(lines, columns) - self.setCursor() - self.updateAttributes(True) - def setCursor(self, x = -1, y = -1): - xPos = x - yPos = y - if xPos == -1: - xPos = self.screen.cursor.x - if yPos == -1: - yPos = self.screen.cursor.y - self.screen.cursor.x = min(self.screen.cursor.x, self.screen.columns - 1) + self.set_cursor() + self.update_attributes(True) + + def set_cursor(self, x=-1, y=-1): + x_pos = x + y_pos = y + if x_pos == -1: + x_pos = self.screen.cursor.x + if y_pos == -1: + y_pos = self.screen.cursor.y + self.screen.cursor.x = min( + self.screen.cursor.x, + self.screen.columns - 1) self.screen.cursor.y = min(self.screen.cursor.y, self.screen.lines - 1) - def GetScreenContent(self): + + def get_screen_content(self): cursor = self.screen.cursor self.text = '\n'.join(self.screen.display) - self.updateAttributes(self.attributes == None) + self.update_attributes(self.attributes is None) self.screen.dirty.clear() return {"cursor": (cursor.x, cursor.y), - 'lines': self.screen.lines, - 'columns': self.screen.columns, - "text": self.text, - 'attributes': self.attributes.copy(), - 'screen': 'pty', - 'screenUpdateTime': time.time(), - }.copy() + 'lines': self.screen.lines, + 'columns': self.screen.columns, + "text": self.text, + 'attributes': self.attributes.copy(), + 'screen': 'pty', + 'screenUpdateTime': time.time(), + }.copy() + class driver(screenDriver): def __init__(self): @@ -84,140 +115,168 @@ class driver(screenDriver): self.p_out = None self.terminal = None self.p_pid = -1 - signal.signal(signal.SIGWINCH, self.handleSigwinch) + signal.signal(signal.SIGWINCH, self.handle_sigwinch) + def initialize(self, environment): self.env = environment - self.command = self.env['runtime']['settingsManager'].getSetting('general','shell') - self.shortcutType = self.env['runtime']['inputManager'].getShortcutType() - self.env['runtime']['processManager'].addCustomEventThread(self.terminalEmulation) - def getCurrScreen(self): + self.command = self.env['runtime']['SettingsManager'].get_setting( + 'general', 'shell') + self.shortcutType = self.env['runtime']['InputManager'].get_shortcut_type( + ) + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.terminal_emulation) + + def get_curr_screen(self): self.env['screen']['oldTTY'] = 'pty' self.env['screen']['newTTY'] = 'pty' - - def injectTextToScreen(self, msgBytes, screen = None): + + def inject_text_to_screen(self, msg_bytes, screen=None): if not screen: screen = self.p_out.fileno() - if isinstance(msgBytes, str): - msgBytes = bytes(msgBytes, 'UTF-8') - os.write(screen, msgBytes) + if isinstance(msg_bytes, str): + msg_bytes = bytes(msg_bytes, 'UTF-8') + os.write(screen, msg_bytes) - def getSessionInformation(self): + def get_session_information(self): self.env['screen']['autoIgnoreScreens'] = [] - self.env['general']['prevUser'] = getpass.getuser() - self.env['general']['currUser'] = getpass.getuser() - def readAll(self, fd, timeout = 0.3, interruptFd = None, len = 65536): - msgBytes = b'' - fdList = [] - fdList += [fd] + self.env['general']['prev_user'] = getpass.getuser() + self.env['general']['curr_user'] = getpass.getuser() + + def read_all(self, fd, timeout=0.3, interruptFd=None, len=65536): + msg_bytes = b'' + fd_list = [] + fd_list += [fd] if interruptFd: - fdList += [interruptFd] + fd_list += [interruptFd] starttime = time.time() while True: - r = screen_utils.hasMoreWhat(fdList, 0.0001) + r = screen_utils.has_more_what(fd_list, 0.0001) # nothing more to read - if not fd in r: + if fd not in r: break data = os.read(fd, len) if data == b'': raise EOFError - msgBytes += data + msg_bytes += data # exit on interrupt available if interruptFd in r: break - # respect timeout but wait a little bit of time to see if something more is here + # respect timeout but wait a little bit of time to see if something + # more is here if (time.time() - starttime) >= timeout: break - return msgBytes - def openTerminal(self, columns, lines, command): + return msg_bytes + + def open_terminal(self, columns, lines, command): p_pid, master_fd = pty.fork() if p_pid == 0: # Child. argv = shlex.split(command) env = os.environ.copy() - #values are VT100,xterm-256color,linux - try: + # values are VT100,xterm-256color,linux + try: if env["TERM"] == '': env["TERM"] = 'linux' except Exception as e: - # Child process doesn't have access to env, use fallback logging - print(f'ptyDriver spawnTerminal: Error checking TERM environment: {e}') + # Child process doesn't have access to env, use fallback + # logging + print( + f'ptyDriver spawnTerminal: Error checking TERM environment: {e}') env["TERM"] = 'linux' os.execvpe(argv[0], argv, env) # File-like object for I/O with the child process aka command. p_out = os.fdopen(master_fd, "w+b", 0) return Terminal(columns, lines, p_out), p_pid, p_out - def resizeTerminal(self,fd): + + def resize_terminal(self, fd): s = struct.pack('HHHH', 0, 0, 0, 0) s = fcntl.ioctl(0, termios.TIOCGWINSZ, s) fcntl.ioctl(fd, termios.TIOCSWINSZ, s) lines, columns, _, _ = struct.unpack('hhhh', s) return lines, columns - def getTerminalSize(self, fd): + + def get_terminal_size(self, fd): s = struct.pack('HHHH', 0, 0, 0, 0) - lines, columns, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s)) + lines, columns, _, _ = struct.unpack( + 'HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s)) return lines, columns - def handleSigwinch(self, *args): + + def handle_sigwinch(self, *args): os.write(self.signalPipe[1], b'w') - def terminalEmulation(self,active , eventQueue): + + def terminal_emulation(self, active, event_queue): try: old_attr = termios.tcgetattr(sys.stdin) tty.setraw(0) - lines, columns = self.getTerminalSize(0) + lines, columns = self.get_terminal_size(0) if self.command == '': - self.command = screen_utils.getShell() - self.terminal, self.p_pid, self.p_out = self.openTerminal(columns, lines, self.command) - lines, columns = self.resizeTerminal(self.p_out) + self.command = screen_utils.get_shell() + self.terminal, self.p_pid, self.p_out = self.open_terminal( + columns, lines, self.command) + lines, columns = self.resize_terminal(self.p_out) self.terminal.resize(lines, columns) - fdList = [sys.stdin, self.p_out, self.signalPipe[0]] + fd_list = [sys.stdin, self.p_out, self.signalPipe[0]] while active.value: - r, _, _ = select(fdList, [], [], 1) + r, _, _ = select(fd_list, [], [], 1) # none if r == []: continue # signals if self.signalPipe[0] in r: os.read(self.signalPipe[0], 1) - lines, columns = self.resizeTerminal(self.p_out) + lines, columns = self.resize_terminal(self.p_out) self.terminal.resize(lines, columns) # input if sys.stdin in r: try: - msgBytes = self.readAll(sys.stdin.fileno(), len=4096) + msg_bytes = self.read_all(sys.stdin.fileno(), len=4096) except (EOFError, OSError): - eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) + event_queue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) break if self.shortcutType == 'KEY': try: - self.injectTextToScreen(msgBytes) + self.inject_text_to_screen(msg_bytes) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('ptyDriver getInputData: Error injecting text to screen: ' + str(e), debug.debugLevel.ERROR) - eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) + self.env['runtime']['DebugManager'].write_debug_out( + 'ptyDriver getInputData: Error injecting text to screen: ' + str(e), + debug.DebugLevel.ERROR) + event_queue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) break else: - eventQueue.put({"Type":fenrirEventType.ByteInput, - "Data":msgBytes }) + event_queue.put({"Type": FenrirEventType.byte_input, + "data": msg_bytes}) # output if self.p_out in r: try: - msgBytes = self.readAll(self.p_out.fileno(), interruptFd=sys.stdin.fileno()) + msg_bytes = self.read_all( + self.p_out.fileno(), interruptFd=sys.stdin.fileno()) except (EOFError, OSError): - eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) + event_queue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) break # feed and send event bevore write, the pyte already has the right state - # so fenrir already can progress bevore os.write what should give some better reaction time - self.terminal.feed(msgBytes) - eventQueue.put({"Type":fenrirEventType.ScreenUpdate, - "Data":screen_utils.createScreenEventData(self.terminal.GetScreenContent()) - }) - self.injectTextToScreen(msgBytes, screen=sys.stdout.fileno()) + # so fenrir already can progress bevore os.write what + # should give some better reaction time + self.terminal.feed(msg_bytes) + event_queue.put( + { + "Type": FenrirEventType.screen_update, + "data": screen_utils.create_screen_event_data( + self.terminal.get_screen_content())}) + self.inject_text_to_screen( + msg_bytes, screen=sys.stdout.fileno()) except Exception as e: # Process died? print(e) - eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) + event_queue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) finally: os.kill(self.p_pid, signal.SIGTERM) self.p_out.close() termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr) - eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None}) + event_queue.put( + {"Type": FenrirEventType.stop_main_loop, "data": None}) sys.exit(0) - - def getCurrApplication(self): + + def get_curr_application(self): pass diff --git a/src/fenrirscreenreader/screenDriver/vcsaDriver.py b/src/fenrirscreenreader/screenDriver/vcsaDriver.py index 351f293a..09705391 100644 --- a/src/fenrirscreenreader/screenDriver/vcsaDriver.py +++ b/src/fenrirscreenreader/screenDriver/vcsaDriver.py @@ -3,15 +3,16 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -#attrib: -#http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html -#0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white. -#https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py -#blink = 5 if attr & 1 else 0 -#bold = 1 if attr & 16 else 0 +# attrib: +# http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html +# 0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white. +# https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py +# blink = 5 if attr & 1 else 0 +# bold = 1 if attr & 16 else 0 import subprocess -import glob, os +import glob +import os import termios import time import select @@ -21,92 +22,134 @@ from array import array from fcntl import ioctl from struct import unpack_from, unpack, pack from fenrirscreenreader.core import debug -from fenrirscreenreader.core.eventData import fenrirEventType -from fenrirscreenreader.core.screenDriver import screenDriver +from fenrirscreenreader.core.eventData import FenrirEventType +from fenrirscreenreader.core.screenDriver import ScreenDriver as screenDriver from fenrirscreenreader.utils import screen_utils + class driver(screenDriver): def __init__(self): screenDriver.__init__(self) self.ListSessions = None self.sysBus = None self.charmap = {} - self.bgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'white'} - self.fgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'light gray', 8: 'dark gray', 9: 'light blue', 10: 'light green', 11: 'light cyan', 12: 'light red', 13: 'light magenta', 14: 'light yellow', 15: 'white'} + self.bgColorValues = { + 0: 'black', + 1: 'blue', + 2: 'green', + 3: 'cyan', + 4: 'red', + 5: 'magenta', + 6: 'brown/yellow', + 7: 'white'} + self.fgColorValues = { + 0: 'black', + 1: 'blue', + 2: 'green', + 3: 'cyan', + 4: 'red', + 5: 'magenta', + 6: 'brown/yellow', + 7: 'light gray', + 8: 'dark gray', + 9: 'light blue', + 10: 'light green', + 11: 'light cyan', + 12: 'light red', + 13: 'light magenta', + 14: 'light yellow', + 15: 'white'} self.hichar = None try: - # set workaround for paste clipboard -> injectTextToScreen - subprocess.run(['sysctl', 'dev.tty.legacy_tiocsti=1'], - check=False, capture_output=True, timeout=5) + # set workaround for paste clipboard -> inject_text_to_screen + subprocess.run(['sysctl', 'dev.tty.legacy_tiocsti=1'], + check=False, capture_output=True, timeout=5) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver shutdown: Error running fgconsole: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver shutdown: Error running fgconsole: ' + str(e), + debug.DebugLevel.ERROR) + def initialize(self, environment): self.env = environment - self.env['runtime']['attributeManager'].appendDefaultAttributes([ - self.fgColorValues[7], # fg - self.bgColorValues[0], # bg - False, # bold - False, # italics - False, # underscore - False, # strikethrough - False, # reverse - False, # blink - 'default', # fontsize - 'default' # fontfamily - ]) #end attribute ) - self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog, multiprocess=True) - def getCurrScreen(self): + self.env['runtime']['AttributeManager'].append_default_attributes([ + self.fgColorValues[7], # fg + self.bgColorValues[0], # bg + False, # bold + False, # italics + False, # underscore + False, # strikethrough + False, # reverse + False, # blink + 'default', # fontsize + 'default' # fontfamily + ]) # end attribute ) + self.env['runtime']['ProcessManager'].add_custom_event_thread( + self.update_watchdog, multiprocess=True) + + def get_curr_screen(self): self.env['screen']['oldTTY'] = self.env['screen']['newTTY'] try: - with open('/sys/devices/virtual/tty/tty0/active','r') as currScreenFile: + with open('/sys/devices/virtual/tty/tty0/active', 'r') as currScreenFile: self.env['screen']['newTTY'] = str(currScreenFile.read()[3:-1]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) - def injectTextToScreen(self, text, screen = None): - useScreen = "/dev/tty" + self.env['screen']['newTTY'] - if screen != None: - useScreen = screen - with open(useScreen, 'w') as fd: + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) + + def inject_text_to_screen(self, text, screen=None): + use_screen = "/dev/tty" + self.env['screen']['newTTY'] + if screen is not None: + use_screen = screen + with open(use_screen, 'w') as fd: for c in text: fcntl.ioctl(fd, termios.TIOCSTI, c) - def getSessionInformation(self): + def get_session_information(self): self.env['screen']['autoIgnoreScreens'] = [] try: if not self.sysBus: self.sysBus = dbus.SystemBus() - obj = self.sysBus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') + obj = self.sysBus.get_object( + 'org.freedesktop.login1', '/org/freedesktop/login1') inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager') self.ListSessions = inf.get_dbus_method('ListSessions') sessions = self.ListSessions() for session in sessions: - obj = self.sysBus.get_object('org.freedesktop.login1', session[4]) + obj = self.sysBus.get_object( + 'org.freedesktop.login1', session[4]) inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') - sessionType = inf.Get('org.freedesktop.login1.Session', 'Type') + session_type = inf.Get('org.freedesktop.login1.Session', 'Type') screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr')) - if screen == '': - screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY')) + if screen == '': + screen = str( + inf.Get( + 'org.freedesktop.login1.Session', + 'TTY')) screen = screen[screen.upper().find('TTY') + 3:] if screen == '': - self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'No TTY found for session:' + session[4], debug.DebugLevel.ERROR) return - if sessionType.upper() != 'TTY': + if session_type.upper() != 'TTY': self.env['screen']['autoIgnoreScreens'] += [screen] - if screen == self.env['screen']['newTTY'] : - if self.env['general']['currUser'] != session[2]: - self.env['general']['prevUser'] = self.env['general']['currUser'] - self.env['general']['currUser'] = session[2] + if screen == self.env['screen']['newTTY']: + if self.env['general']['curr_user'] != session[2]: + self.env['general']['prev_user'] = self.env['general']['curr_user'] + self.env['general']['curr_user'] = session[2] except Exception as e: - self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR) - #self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO) - def readFile(self, file): + self.env['runtime']['DebugManager'].write_debug_out( + 'get_session_information: Maybe no LoginD:' + str(e), debug.DebugLevel.ERROR) + # self.env['runtime']['DebugManager'].write_debug_out('get_session_information:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.DebugLevel.INFO) + + def read_file(self, file): d = b'' file.seek(0) try: d = file.read() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver getScreenText: Error reading file: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver get_screen_text: Error reading file: ' + str(e), + debug.DebugLevel.ERROR) file.seek(0) while True: # Read from file @@ -117,39 +160,42 @@ class driver(screenDriver): except Exception as e: break return d - def updateWatchdog(self, active , eventQueue): + + def update_watchdog(self, active, event_queue): vcsa = {} vcsu = {} tty = None watchdog = None try: - useVCSU = os.access('/dev/vcsu', os.R_OK) - vcsaDevices = glob.glob('/dev/vcsa*') - vcsuDevices = None - lastScreenContent = b'' - + use_vcsu = os.access('/dev/vcsu', os.R_OK) + vcsa_devices = glob.glob('/dev/vcsa*') + vcsu_devices = None + last_screen_content = b'' + # Open TTY file with proper cleanup - tty = open('/sys/devices/virtual/tty/tty0/active','r') - currScreen = str(tty.read()[3:-1]) - oldScreen = currScreen - + tty = open('/sys/devices/virtual/tty/tty0/active', 'r') + curr_screen = str(tty.read()[3:-1]) + old_screen = curr_screen + # Open VCSA devices with proper cleanup tracking - for vcsaDev in vcsaDevices: + for vcsaDev in vcsa_devices: index = str(vcsaDev[9:]) - vcsa[index] = open(vcsaDev,'rb') - if index == currScreen: - lastScreenContent = self.readFile(vcsa[index]) - + vcsa[index] = open(vcsaDev, 'rb') + if index == curr_screen: + last_screen_content = self.read_file(vcsa[index]) + # Open VCSU devices if available - if useVCSU: - vcsuDevices = glob.glob('/dev/vcsu*') - for vcsuDev in vcsuDevices: + if use_vcsu: + vcsu_devices = glob.glob('/dev/vcsu*') + for vcsuDev in vcsu_devices: index = str(vcsuDev[9:]) - vcsu[index] = open(vcsuDev,'rb') - - self.updateCharMap(currScreen) + vcsu[index] = open(vcsuDev, 'rb') + + self.update_char_map(curr_screen) watchdog = select.epoll() - watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR) + watchdog.register( + vcsa[curr_screen], + select.POLLPRI | select.POLLERR) watchdog.register(tty, select.POLLPRI | select.POLLERR) while active.value: changes = watchdog.poll(1) @@ -157,77 +203,86 @@ class driver(screenDriver): fileno = change[0] event = change[1] if fileno == tty.fileno(): - self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'ScreenChange', debug.DebugLevel.INFO) tty.seek(0) - currScreen = str(tty.read()[3:-1]) - if currScreen != oldScreen: + curr_screen = str(tty.read()[3:-1]) + if curr_screen != old_screen: try: - watchdog.unregister(vcsa[oldScreen]) + watchdog.unregister(vcsa[old_screen]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver updateWatchdog: Error unregistering watchdog: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver update_watchdog: Error unregistering watchdog: ' + str(e), + debug.DebugLevel.ERROR) try: - watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR) + watchdog.register( + vcsa[curr_screen], select.POLLPRI | select.POLLERR) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver updateWatchdog: Error registering watchdog: ' + str(e), debug.debugLevel.ERROR) - self.updateCharMap(currScreen) - oldScreen = currScreen + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver update_watchdog: Error registering watchdog: ' + str(e), + debug.DebugLevel.ERROR) + self.update_char_map(curr_screen) + old_screen = curr_screen try: - vcsa[currScreen].seek(0) - lastScreenContent = self.readFile(vcsa[currScreen]) + vcsa[curr_screen].seek(0) + last_screen_content = self.read_file( + vcsa[curr_screen]) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver updateWatchdog: Error reading screen content: ' + str(e), debug.debugLevel.ERROR) - vcsuContent = None - if useVCSU: - vcsu[currScreen].seek(0) - vcsuContent = self.readFile(vcsu[currScreen]) - eventQueue.put({"Type":fenrirEventType.ScreenChanged, - "Data":self.createScreenEventData(currScreen, lastScreenContent, vcsuContent) - }) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver update_watchdog: Error reading screen content: ' + str(e), + debug.DebugLevel.ERROR) + vcsu_content = None + if use_vcsu: + vcsu[curr_screen].seek(0) + vcsu_content = self.read_file(vcsu[curr_screen]) + event_queue.put({"Type": FenrirEventType.screen_changed, "data": self.create_screen_event_data( + curr_screen, last_screen_content, vcsu_content)}) else: - self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO) - vcsa[currScreen].seek(0) + self.env['runtime']['DebugManager'].write_debug_out( + 'screen_update', debug.DebugLevel.INFO) + vcsa[curr_screen].seek(0) time.sleep(0.01) - dirtyContent = self.readFile(vcsa[currScreen]) - screenContent = dirtyContent - vcsuContent = None + dirty_content = self.read_file(vcsa[curr_screen]) + screen_content = dirty_content + vcsu_content = None timeout = time.time() # error case - if screenContent == b'': + if screen_content == b'': continue - if lastScreenContent == b'': - lastScreenContent = screenContent - if (abs( int(screenContent[2]) - int(lastScreenContent[2])) in [1,2]) and \ - (int(screenContent[3]) == int(lastScreenContent[3])): + if last_screen_content == b'': + last_screen_content = screen_content + if (abs(int(screen_content[2]) - int(last_screen_content[2])) in [1, 2]) and ( + int(screen_content[3]) == int(last_screen_content[3])): # Skip X Movement pass - elif (abs( int(screenContent[3]) - int(lastScreenContent[3])) in [1]) and \ - (int(screenContent[2]) == int(lastScreenContent[2])): + elif (abs(int(screen_content[3]) - int(last_screen_content[3])) in [1]) and \ + (int(screen_content[2]) == int(last_screen_content[2])): # Skip Y Movement pass else: # anything else? wait for completion while True: - screenContent = dirtyContent + screen_content = dirty_content time.sleep(0.02) - #r,_,_ = select.select([vcsa[currScreen]], [], [], 0.07) - #if not vcsa[currScreen] in r: + # r,_,_ = select.select([vcsa[curr_screen]], [], [], 0.07) + # if not vcsa[curr_screen] in r: # break - vcsa[currScreen].seek(0) - dirtyContent = self.readFile(vcsa[currScreen]) - if screenContent == dirtyContent: + vcsa[curr_screen].seek(0) + dirty_content = self.read_file(vcsa[curr_screen]) + if screen_content == dirty_content: break if time.time() - timeout >= 0.1: - screenContent = dirtyContent + screen_content = dirty_content break - if useVCSU: - vcsu[currScreen].seek(0) - vcsuContent = self.readFile(vcsu[currScreen]) - lastScreenContent = screenContent - eventQueue.put({"Type":fenrirEventType.ScreenUpdate, - "Data":self.createScreenEventData(currScreen, screenContent, vcsuContent) - }) + if use_vcsu: + vcsu[curr_screen].seek(0) + vcsu_content = self.read_file(vcsu[curr_screen]) + last_screen_content = screen_content + event_queue.put({"Type": FenrirEventType.screen_update, "data": self.create_screen_event_data( + curr_screen, screen_content, vcsu_content)}) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'VCSA:update_watchdog:' + str(e), debug.DebugLevel.ERROR) time.sleep(0.2) finally: # Clean up all file handles @@ -235,52 +290,66 @@ class driver(screenDriver): if watchdog: watchdog.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver updateWatchdog: Error closing watchdog: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver update_watchdog: Error closing watchdog: ' + str(e), + debug.DebugLevel.ERROR) try: if tty: tty.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver shutdown: Error closing TTY: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver shutdown: Error closing TTY: ' + str(e), debug.DebugLevel.ERROR) for handle in vcsa.values(): try: handle.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver shutdown: Error closing VCSA handle: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver shutdown: Error closing VCSA handle: ' + str(e), + debug.DebugLevel.ERROR) for handle in vcsu.values(): try: handle.close() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver shutdown: Error closing VCSU handle: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver shutdown: Error closing VCSU handle: ' + str(e), + debug.DebugLevel.ERROR) - def createScreenEventData(self, screen, vcsaContent, vcsuContent = None): - eventData = { + def create_screen_event_data(self, screen, vcsaContent, vcsu_content=None): + event_data = { 'bytes': vcsaContent, - 'lines': int( vcsaContent[0]), - 'columns': int( vcsaContent[1]), - 'textCursor': + 'lines': int(vcsaContent[0]), + 'columns': int(vcsaContent[1]), + 'textCursor': { - 'x': int( vcsaContent[2]), - 'y': int( vcsaContent[3]) - }, + 'x': int(vcsaContent[2]), + 'y': int(vcsaContent[3]) + }, 'screen': screen, 'screenUpdateTime': time.time(), 'text': '', 'attributes': [], } try: - eventData['text'], eventData['attributes'] =\ - self.autoDecodeVCSA(vcsaContent[4:], eventData['lines'], eventData['columns']) + event_data['text'], event_data['attributes'] = self.auto_decode_vcsa( + vcsaContent[4:], event_data['lines'], event_data['columns']) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver createScreenEventData: Error decoding VCSA content: ' + str(e), debug.debugLevel.ERROR) - # VCSU seems to give b' ' instead of b'\x00\x00\x00' (tsp), deactivated until its fixed - if vcsuContent != None: + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver create_screen_event_data: Error decoding VCSA content: ' + str(e), + debug.DebugLevel.ERROR) + # VCSU seems to give b' ' instead of b'\x00\x00\x00' (tsp), + # deactivated until its fixed + if vcsu_content is not None: try: - vcsuContentAsText = vcsuContent.decode('UTF-32') - eventData['text'] = screen_utils.insertNewlines(vcsuContentAsText, eventData['columns']) + vcsu_content_as_text = vcsu_content.decode('UTF-32') + event_data['text'] = screen_utils.insert_newlines( + vcsu_content_as_text, event_data['columns']) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver createScreenEventData: Error decoding VCSU content: ' + str(e), debug.debugLevel.ERROR) - return eventData.copy() - def updateCharMap(self, screen): + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver create_screen_event_data: Error decoding VCSU content: ' + str(e), + debug.DebugLevel.ERROR) + return event_data.copy() + + def update_char_map(self, screen): self.charmap = {} try: with open('/dev/tty' + screen, 'rb') as tty: @@ -293,54 +362,59 @@ class driver(screenDriver): line = '' while True: try: - unipairs = array("H", [0]*(2*sz)) - unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) + unipairs = array("H", [0] * (2 * sz)) + unimapdesc = array( + "B", pack( + "@HP", sz, unipairs.buffer_info()[0])) ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) break except Exception as e: - self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:scaling up sz=' + str(sz) + ' ' + str(e),debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'VCSA:update_char_map:scaling up sz=' + str(sz) + ' ' + str(e), + debug.DebugLevel.WARNING) sz *= 2 except Exception as e: - self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'VCSA:update_char_map:' + str(e), debug.DebugLevel.ERROR) return ncodes, = unpack_from("@H", unimapdesc) - utable = unpack_from("@%dH" % (2*ncodes), unipairs) + utable = unpack_from("@%dH" % (2 * ncodes), unipairs) for u, b in zip(utable[::2], utable[1::2]): if self.charmap.get(b) is None: self.charmap[b] = chr(u) - def autoDecodeVCSA(self, allData, rows, cols): - allText = '' - allAttrib = [] + def auto_decode_vcsa(self, allData, rows, cols): + all_text = '' + all_attrib = [] i = 0 for y in range(rows): - lineText = '' - lineAttrib = [] + line_text = '' + line_attrib = [] blink = 0 bold = 0 ink = 7 - paper = 0 + paper = 0 for x in range(cols): data = allData[i: i + 2] i += 2 if data == b' \x07': - #attr = 7 - #ink = 7 - #paper = 0 - #ch = ' ' - charAttrib = [ - self.fgColorValues[7], # fg - self.bgColorValues[0], # bg - False, # bold - False, # italics - False, # underscore - False, # strikethrough - False, # reverse - False, # blink - 'default', # fontsize - 'default'] # fontfamily - lineAttrib.append(charAttrib) - lineText += ' ' + # attr = 7 + # ink = 7 + # paper = 0 + # ch = ' ' + char_attrib = [ + self.fgColorValues[7], # fg + self.bgColorValues[0], # bg + False, # bold + False, # italics + False, # underscore + False, # strikethrough + False, # reverse + False, # blink + 'default', # fontsize + 'default'] # fontfamily + line_attrib.append(char_attrib) + line_text += ' ' continue ch = None try: @@ -351,53 +425,65 @@ class driver(screenDriver): if sh & self.hichar: ch |= 0x100 except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver autoDecodeVCSA: Error processing character: ' + str(e), debug.debugLevel.ERROR) - ch = None + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver auto_decode_vcsa: Error processing character: ' + str(e), + debug.DebugLevel.ERROR) + ch = None if self.hichar == 0x100: attr >>= 1 ink = attr & 0x0F - paper = (attr>>4) & 0x0F - if attr & 1: + paper = (attr >> 4) & 0x0F + if attr & 1: blink = 1 # blink seems to be set always, ignore for now - blink = 0 - bold = 0 + blink = 0 + bold = 0 if attr & 16: bold = 1 - #if (ink != 7) or (paper != 0): + # if (ink != 7) or (paper != 0): # print(ink,paper) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('vcsaDriver autoDecodeVCSA: Error processing attributes: ' + str(e), debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'vcsaDriver auto_decode_vcsa: Error processing attributes: ' + str(e), + debug.DebugLevel.ERROR) try: - lineText += self.charmap[ch] + line_text += self.charmap[ch] except KeyError: - lineText += '?' + line_text += '?' - charAttrib = [ - self.fgColorValues[ink], - self.bgColorValues[paper], - bold == 1, # bold - False, # italics - False, # underscore - False, # strikethrough - False, # reverse - blink == 1, # blink - 'default', # fontsize - 'default'] # fontfamily - lineAttrib.append(charAttrib) - allText += lineText + char_attrib = [ + self.fgColorValues[ink], + self.bgColorValues[paper], + bold == 1, # bold + False, # italics + False, # underscore + False, # strikethrough + False, # reverse + blink == 1, # blink + 'default', # fontsize + 'default'] # fontfamily + line_attrib.append(char_attrib) + all_text += line_text if y + 1 < rows: - allText += '\n' - allAttrib.append(lineAttrib) - return str(allText), allAttrib - - def getCurrApplication(self): + all_text += '\n' + all_attrib.append(line_attrib) + return str(all_text), all_attrib + + def get_curr_application(self): apps = [] try: - currScreen = self.env['screen']['newTTY'] - apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n') + curr_screen = self.env['screen']['newTTY'] + apps = subprocess.Popen( + 'ps -t tty' + + curr_screen + + ' -o comm,tty,stat', + shell=True, + stdout=subprocess.PIPE).stdout.read().decode()[ + :- + 1].split('\n') except Exception as e: - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) return try: for i in apps: @@ -408,11 +494,12 @@ class driver(screenDriver): if '+' in i[2]: if i[0] != '': if not "GREP" == i[0] and \ - not "SH" == i[0] and \ - not "PS" == i[0]: - if "TTY"+currScreen in i[1]: - if self.env['screen']['newApplication'] != i[0]: - self.env['screen']['newApplication'] = i[0] + not "SH" == i[0] and \ + not "PS" == i[0]: + if "TTY" + curr_screen in i[1]: + if self.env['screen']['new_application'] != i[0]: + self.env['screen']['new_application'] = i[0] return except Exception as e: - self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + str(e), debug.DebugLevel.ERROR) diff --git a/src/fenrirscreenreader/soundDriver/debugDriver.py b/src/fenrirscreenreader/soundDriver/debugDriver.py index 24b44680..70307f51 100644 --- a/src/fenrirscreenreader/soundDriver/debugDriver.py +++ b/src/fenrirscreenreader/soundDriver/debugDriver.py @@ -5,11 +5,12 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.soundDriver import soundDriver +from fenrirscreenreader.core.soundDriver import sound_driver -class driver(soundDriver): + +class driver(sound_driver): def __init__(self): - soundDriver.__init__(self) + sound_driver.__init__(self) def initialize(self, environment): self.env = environment @@ -23,34 +24,46 @@ class driver(soundDriver): self._initialized = False print('Sound Debug Driver: Shutdown') - def playFrequence(self, frequence, duration, adjustVolume = 0.0, interrupt=True): + def play_frequence( + self, + frequence, + duration, + adjust_volume=0.0, + interrupt=True): if not self._initialized: - return + return if interrupt: self.cancel() - print('Sound Debug Driver: playFrequence:' + ' freq:' + str(frequence) + ' duration:' + str(duration) + ' adjustVolume:' + str(adjustVolume) ) + print( + 'Sound Debug Driver: play_frequence:' + + ' freq:' + + str(frequence) + + ' duration:' + + str(duration) + + ' adjust_volume:' + + str(adjust_volume)) print('Sound Debug Driver: -----------------------------------') - def playSoundFile(self, filePath, interrupt = True): + def play_sound_file(self, file_path, interrupt=True): if not self._initialized: - return + return if interrupt: self.cancel() - print('Sound Debug Driver: playSoundFile:' + str(filePath)) + print('Sound Debug Driver: play_sound_file:' + str(file_path)) print('Sound Debug Driver: -----------------------------------') def cancel(self): if not self._initialized: return - print('Sound Debug Driver: Cancel') + print('Sound Debug Driver: Cancel') - def setCallback(self, callback): + def set_callback(self, callback): if not self._initialized: return - print('Sound Debug Driver: setCallback') + print('Sound Debug Driver: set_callback') - def setVolume(self, volume): + def set_volume(self, volume): if not self._initialized: - return + return self.volume = volume - print('Sound Debug Driver: setVolume:' + str(self.volume)) + print('Sound Debug Driver: set_volume:' + str(self.volume)) diff --git a/src/fenrirscreenreader/soundDriver/dummyDriver.py b/src/fenrirscreenreader/soundDriver/dummyDriver.py index 436bff89..c2460d77 100644 --- a/src/fenrirscreenreader/soundDriver/dummyDriver.py +++ b/src/fenrirscreenreader/soundDriver/dummyDriver.py @@ -5,8 +5,9 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -from fenrirscreenreader.core.soundDriver import soundDriver +from fenrirscreenreader.core.soundDriver import sound_driver -class driver(soundDriver): + +class driver(sound_driver): def __init__(self): - soundDriver.__init__(self) + sound_driver.__init__(self) diff --git a/src/fenrirscreenreader/soundDriver/genericDriver.py b/src/fenrirscreenreader/soundDriver/genericDriver.py index 4d8e6200..8125deb3 100644 --- a/src/fenrirscreenreader/soundDriver/genericDriver.py +++ b/src/fenrirscreenreader/soundDriver/genericDriver.py @@ -7,54 +7,72 @@ from fenrirscreenreader.core import debug import subprocess import shlex -from fenrirscreenreader.core.soundDriver import soundDriver +from fenrirscreenreader.core.soundDriver import sound_driver -class driver(soundDriver): + +class driver(sound_driver): def __init__(self): - soundDriver.__init__(self) + sound_driver.__init__(self) self.proc = None self.soundType = '' self.soundFileCommand = '' self.frequenceCommand = '' + def initialize(self, environment): self.env = environment - self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand') - self.frequenceCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericFrequencyCommand') + self.soundFileCommand = self.env['runtime']['SettingsManager'].get_setting( + 'sound', 'genericPlayFileCommand') + self.frequenceCommand = self.env['runtime']['SettingsManager'].get_setting( + 'sound', 'genericFrequencyCommand') if self.soundFileCommand == '': self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile' if self.frequenceCommand == '': self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence' self._initialized = True - def playFrequence(self, frequence, duration, adjustVolume = 0.0, interrupt=True): + def play_frequence( + self, + frequence, + duration, + adjust_volume=0.0, + interrupt=True): if not self._initialized: return if interrupt: self.cancel() - popenFrequenceCommand = shlex.split(self.frequenceCommand) - for idx, word in enumerate(popenFrequenceCommand): - word = word.replace('fenrirVolume', str(self.volume * adjustVolume)) + popen_frequence_command = shlex.split(self.frequenceCommand) + for idx, word in enumerate(popen_frequence_command): + word = word.replace( + 'fenrirVolume', str( + self.volume * adjust_volume)) word = word.replace('fenrirDuration', str(duration)) word = word.replace('fenrirFrequence', str(frequence)) - popenFrequenceCommand[idx] = word - self.proc = subprocess.Popen(popenFrequenceCommand, stdin=None, stdout=None, stderr=None, shell=False) + popen_frequence_command[idx] = word + self.proc = subprocess.Popen( + popen_frequence_command, + stdin=None, + stdout=None, + stderr=None, + shell=False) self.soundType = 'frequence' - def playSoundFile(self, filePath, interrupt = True): + + def play_sound_file(self, file_path, interrupt=True): if not self._initialized: return if interrupt: self.cancel() # Validate file path to prevent injection import os - if not os.path.isfile(filePath) or '..' in filePath: + if not os.path.isfile(file_path) or '..' in file_path: return - popenSoundFileCommand = shlex.split(self.soundFileCommand) - for idx, word in enumerate(popenSoundFileCommand): - word = word.replace('fenrirVolume', str(self.volume )) - word = word.replace('fenrirSoundFile', shlex.quote(str(filePath))) - popenSoundFileCommand[idx] = word - self.proc = subprocess.Popen(popenSoundFileCommand, shell=False) + popen_sound_file_command = shlex.split(self.soundFileCommand) + for idx, word in enumerate(popen_sound_file_command): + word = word.replace('fenrirVolume', str(self.volume)) + word = word.replace('fenrirSoundFile', shlex.quote(str(file_path))) + popen_sound_file_command[idx] = word + self.proc = subprocess.Popen(popen_sound_file_command, shell=False) self.soundType = 'file' + def cancel(self): if not self._initialized: return @@ -63,7 +81,8 @@ class driver(soundDriver): if self.soundType == 'file': self.proc.kill() try: - self.proc.wait(timeout=1.0) # Wait for process to finish to prevent zombies + # Wait for process to finish to prevent zombies + self.proc.wait(timeout=1.0) except subprocess.TimeoutExpired: pass # Process already terminated except Exception as e: @@ -71,7 +90,8 @@ class driver(soundDriver): if self.soundType == 'frequence': self.proc.kill() try: - self.proc.wait(timeout=1.0) # Wait for process to finish to prevent zombies + # Wait for process to finish to prevent zombies + self.proc.wait(timeout=1.0) except subprocess.TimeoutExpired: pass # Process already terminated except Exception as e: diff --git a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py index 42926e37..722d7bb8 100644 --- a/src/fenrirscreenreader/soundDriver/gstreamerDriver.py +++ b/src/fenrirscreenreader/soundDriver/gstreamerDriver.py @@ -5,8 +5,9 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -import time, threading -from fenrirscreenreader.core.soundDriver import soundDriver +import time +import threading +from fenrirscreenreader.core.soundDriver import sound_driver _gstreamerAvailable = False try: @@ -19,29 +20,31 @@ except Exception as e: _gstreamerAvailable = False _availableError = str(e) -class driver(soundDriver): + +class driver(sound_driver): def __init__(self): - soundDriver.__init__(self) + sound_driver.__init__(self) self._source = None self._sink = None - + def initialize(self, environment): self.env = environment global _gstreamerAvailable self._initialized = _gstreamerAvailable if not self._initialized: global _availableError - self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR) + self.environment['runtime']['DebugManager'].write_debug_out( + 'Gstreamer not available ' + _availableError, debug.DebugLevel.ERROR) return self._player = Gst.ElementFactory.make('playbin', 'player') bus = self._player.get_bus() bus.add_signal_watch() - bus.connect("message", self._onPlayerMessage) + bus.connect("message", self._on_player_message) self._pipeline = Gst.Pipeline(name='fenrir-pipeline') bus = self._pipeline.get_bus() bus.add_signal_watch() - bus.connect("message", self._onPipelineMessage) + bus.connect("message", self._on_pipeline_message) self._source = Gst.ElementFactory.make('audiotestsrc', 'src') self._sink = Gst.ElementFactory.make('autoaudiosink', 'output') @@ -59,52 +62,62 @@ class driver(soundDriver): self.mainloop.quit() # Wait for the GLib MainLoop thread to finish to prevent shutdown races if hasattr(self, 'thread') and self.thread.is_alive(): - self.thread.join(timeout=2.0) # 2 second timeout to prevent hanging + # 2 second timeout to prevent hanging + self.thread.join(timeout=2.0) - def _onPlayerMessage(self, bus, message): + def _on_player_message(self, bus, message): if not self._initialized: - return + return if message.type == Gst.MessageType.EOS: self._player.set_state(Gst.State.NULL) elif message.type == Gst.MessageType.ERROR: self._player.set_state(Gst.State.NULL) error, info = message.parse_error() - self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'GSTREAMER: _on_player_message' + str(error) + str(info), + debug.DebugLevel.WARNING) - def _onPipelineMessage(self, bus, message): + def _on_pipeline_message(self, bus, message): if not self._initialized: - return + return if message.type == Gst.MessageType.EOS: self._pipeline.set_state(Gst.State.NULL) elif message.type == Gst.MessageType.ERROR: self._pipeline.set_state(Gst.State.NULL) error, info = message.parse_error() - self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING) - - def _onTimeout(self, element): + self.env['runtime']['DebugManager'].write_debug_out( + 'GSTREAMER: _on_pipeline_message' + str(error) + str(info), + debug.DebugLevel.WARNING) + + def _on_timeout(self, element): if not self._initialized: return element.set_state(Gst.State.NULL) - def playSoundFile(self, fileName, interrupt=True): + def play_sound_file(self, file_name, interrupt=True): if not self._initialized: return if interrupt: self.cancel() self._player.set_property('volume', self.volume) - self._player.set_property('uri', 'file://%s' % fileName) + self._player.set_property('uri', 'file://%s' % file_name) self._player.set_state(Gst.State.PLAYING) - def playFrequence(self, frequence, duration, adjustVolume = 0.0, interrupt=True): + def play_frequence( + self, + frequence, + duration, + adjust_volume=0.0, + interrupt=True): if not self._initialized: return if interrupt: self.cancel() duration = duration * 1000 - self._source.set_property('volume', self.volume * adjustVolume) + self._source.set_property('volume', self.volume * adjust_volume) self._source.set_property('freq', frequence) self._pipeline.set_state(Gst.State.PLAYING) - GLib.timeout_add(duration, self._onTimeout, self._pipeline) + GLib.timeout_add(duration, self._on_timeout, self._pipeline) def cancel(self, element=None): if not self._initialized: diff --git a/src/fenrirscreenreader/speechDriver/debugDriver.py b/src/fenrirscreenreader/speechDriver/debugDriver.py index d8b18051..defaf016 100644 --- a/src/fenrirscreenreader/speechDriver/debugDriver.py +++ b/src/fenrirscreenreader/speechDriver/debugDriver.py @@ -6,69 +6,71 @@ # generic driver from fenrirscreenreader.core import debug -from fenrirscreenreader.core.speechDriver import speechDriver +from fenrirscreenreader.core.speechDriver import speech_driver -class driver(speechDriver): + +class driver(speech_driver): def __init__(self): - speechDriver.__init__(self) + speech_driver.__init__(self) + def initialize(self, environment): - self._isInitialized = True + self._is_initialized = True self.env = environment print('Speech Debug Driver: Iitialized') - + def shutdown(self): - if self._isInitialized: + if self._is_initialized: self.cancel() - self._isInitialized = False + self._is_initialized = False print('Speech Debug Driver: Shutdown') - def speak(self,text, queueable=True, ignorePunctuation=False): - if not self._isInitialized: + def speak(self, text, queueable=True, ignore_punctuation=False): + if not self._is_initialized: return - if not queueable: + if not queueable: self.cancel() - print('Speech Debug Driver: Speak:'+text) + print('Speech Debug Driver: Speak:' + text) print('Speech Debug Driver: -----------------------------------') def cancel(self): - if not self._isInitialized: + if not self._is_initialized: return print('Speech Debug Driver: Cancel') - def setCallback(self, callback): - print('Speech Debug Driver: setCallback') + def set_callback(self, callback): + print('Speech Debug Driver: set_callback') def clear_buffer(self): - if not self._isInitialized: + if not self._is_initialized: return print('Speech Debug Driver: clear_buffer') - def setVoice(self, voice): - if not self._isInitialized: + def set_voice(self, voice): + if not self._is_initialized: return - print('Speech Debug Driver: setVoice:' + str(voice)) + print('Speech Debug Driver: set_voice:' + str(voice)) - def setPitch(self, pitch): - if not self._isInitialized: + def set_pitch(self, pitch): + if not self._is_initialized: return - print('Speech Debug Driver: setPitch:' + str(pitch)) + print('Speech Debug Driver: set_pitch:' + str(pitch)) - def setRate(self, rate): - if not self._isInitialized: + def set_rate(self, rate): + if not self._is_initialized: return - print('Speech Debug Driver: setRate:' + str(rate)) + print('Speech Debug Driver: set_rate:' + str(rate)) - def setModule(self, module): - if not self._isInitialized: + def set_module(self, module): + if not self._is_initialized: return - print('Speech Debug Driver: setModule:' + str(module)) + print('Speech Debug Driver: set_module:' + str(module)) - def setLanguage(self, language): - if not self._isInitialized: + def set_language(self, language): + if not self._is_initialized: return - print('Speech Debug Driver: setLanguage:' + str(language)) + print('Speech Debug Driver: set_language:' + str(language)) - def setVolume(self, volume): - if not self._isInitialized: + def set_volume(self, volume): + if not self._is_initialized: return - print('Speech Debug Driver: setVolume:' + str(volume)) + print('Speech Debug Driver: set_volume:' + str(volume)) diff --git a/src/fenrirscreenreader/speechDriver/dummyDriver.py b/src/fenrirscreenreader/speechDriver/dummyDriver.py index 8860d403..e23680c7 100644 --- a/src/fenrirscreenreader/speechDriver/dummyDriver.py +++ b/src/fenrirscreenreader/speechDriver/dummyDriver.py @@ -6,8 +6,9 @@ # generic driver from fenrirscreenreader.core import debug -from fenrirscreenreader.core.speechDriver import speechDriver +from fenrirscreenreader.core.speechDriver import speech_driver -class driver(speechDriver): + +class driver(speech_driver): def __init__(self): - speechDriver.__init__(self) + speech_driver.__init__(self) diff --git a/src/fenrirscreenreader/speechDriver/genericDriver.py b/src/fenrirscreenreader/speechDriver/genericDriver.py index 2fce657a..dd2707df 100644 --- a/src/fenrirscreenreader/speechDriver/genericDriver.py +++ b/src/fenrirscreenreader/speechDriver/genericDriver.py @@ -11,9 +11,10 @@ from queue import Queue, Empty import shlex from subprocess import Popen import subprocess -from fenrirscreenreader.core.speechDriver import speechDriver +from fenrirscreenreader.core.speechDriver import speech_driver -class speakQueue(Queue): + +class SpeakQueue(Queue): def clear(self): try: while True: @@ -21,56 +22,66 @@ class speakQueue(Queue): except Empty: pass -class driver(speechDriver): + +class driver(speech_driver): def __init__(self): - speechDriver.__init__(self) + speech_driver.__init__(self) self.proc = None self.speechThread = Thread(target=self.worker) self.lock = Lock() - self.textQueue = speakQueue() + self.textQueue = SpeakQueue() + def initialize(self, environment): - self.env = environment - self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume') - self.maxVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxVolume') - self.minPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinPitch') - self.maxPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxPitch') - self.minRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinRate') - self.maxRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxRate') - - self.speechCommand = self.env['runtime']['settingsManager'].getSetting('speech', 'genericSpeechCommand') + self.env = environment + self.minVolume = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMinVolume') + self.maxVolume = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMaxVolume') + self.minPitch = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMinPitch') + self.maxPitch = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMaxPitch') + self.minRate = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMinRate') + self.maxRate = self.env['runtime']['SettingsManager'].get_setting_as_int( + 'speech', 'fenrirMaxRate') + + self.speechCommand = self.env['runtime']['SettingsManager'].get_setting( + 'speech', 'genericSpeechCommand') if self.speechCommand == '': self.speechCommand = 'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice -- "fenrirText"' - if False: #for debugging overwrite here - #self.speechCommand = 'spd-say --wait -r 100 -i 100 "fenrirText"' + if False: # for debugging overwrite here + # self.speechCommand = 'spd-say --wait -r 100 -i 100 "fenrirText"' self.speechCommand = 'flite -t "fenrirText"' - - self._isInitialized = True - if self._isInitialized: + + self._is_initialized = True + if self._is_initialized: self.speechThread.start() + def shutdown(self): - if not self._isInitialized: + if not self._is_initialized: return self.cancel() self.textQueue.put(-1) - def speak(self,text, queueable=True, ignorePunctuation=False): - if not self._isInitialized: + def speak(self, text, queueable=True, ignore_punctuation=False): + if not self._is_initialized: return if not queueable: self.cancel() utterance = { - 'text': text, - 'volume': self.volume, - 'rate': self.rate, - 'pitch': self.pitch, - 'module': self.module, - 'language': self.language, - 'voice': self.voice, + 'text': text, + 'volume': self.volume, + 'rate': self.rate, + 'pitch': self.pitch, + 'module': self.module, + 'language': self.language, + 'voice': self.voice, } self.textQueue.put(utterance.copy()) def cancel(self): - if not self._isInitialized: + if not self._is_initialized: return self.clear_buffer() self.lock.acquire(True) @@ -86,54 +97,60 @@ class driver(speechDriver): self.proc.kill() self.proc.wait(timeout=1.0) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'speech_driver:Cancel:self.proc.terminate():' + str(e), debug.DebugLevel.WARNING) try: self.proc.kill() - self.proc.wait(timeout=1.0) # Wait after kill to prevent zombies + # Wait after kill to prevent zombies + self.proc.wait(timeout=1.0) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING) + self.env['runtime']['DebugManager'].write_debug_out( + 'speech_driver:Cancel:self.proc.kill():' + str(e), debug.DebugLevel.WARNING) self.proc = None finally: # Ensure lock is always released, even if process termination fails self.lock.release() - def setCallback(self, callback): - print('SpeechDummyDriver: setCallback') + + def set_callback(self, callback): + print('SpeechDummyDriver: set_callback') def clear_buffer(self): - if not self._isInitialized: + if not self._is_initialized: return self.textQueue.clear() - - def setVoice(self, voice): - if not self._isInitialized: + + def set_voice(self, voice): + if not self._is_initialized: return self.voice = str(voice) - def setPitch(self, pitch): - if not self._isInitialized: + def set_pitch(self, pitch): + if not self._is_initialized: return - self.pitch = str(self.minPitch + pitch * (self.maxPitch - self.minPitch )) + self.pitch = str(self.minPitch + pitch * + (self.maxPitch - self.minPitch)) - def setRate(self, rate): - if not self._isInitialized: + def set_rate(self, rate): + if not self._is_initialized: return - self.rate = str(self.minRate + rate * (self.maxRate - self.minRate )) + self.rate = str(self.minRate + rate * (self.maxRate - self.minRate)) - def setModule(self, module): - if not self._isInitialized: - return + def set_module(self, module): + if not self._is_initialized: + return self.module = str(module) - def setLanguage(self, language): - if not self._isInitialized: + def set_language(self, language): + if not self._is_initialized: return self.language = str(language) - def setVolume(self, volume): - if not self._isInitialized: - return - self.volume = str(self.minVolume + volume * (self.maxVolume - self.minVolume )) - + def set_volume(self, volume): + if not self._is_initialized: + return + self.volume = str(self.minVolume + volume * + (self.maxVolume - self.minVolume)) + def worker(self): while True: utterance = self.textQueue.get() @@ -146,60 +163,69 @@ class driver(speechDriver): elif not isinstance(utterance, dict): continue # no text means nothing to speak - if not 'text' in utterance: + if 'text' not in utterance: continue - if not isinstance(utterance['text'],str): + if not isinstance(utterance['text'], str): continue if utterance['text'] == '': continue # check for valid data fields - if not 'volume' in utterance: + if 'volume' not in utterance: utterance['volume'] = '' - if not isinstance(utterance['volume'],str): + if not isinstance(utterance['volume'], str): utterance['volume'] = '' - if not 'module' in utterance: + if 'module' not in utterance: utterance['module'] = '' - if not isinstance(utterance['module'],str): + if not isinstance(utterance['module'], str): utterance['module'] = '' - if not 'language' in utterance: + if 'language' not in utterance: utterance['language'] = '' - if not isinstance(utterance['language'],str): + if not isinstance(utterance['language'], str): utterance['language'] = '' - if not 'voice' in utterance: + if 'voice' not in utterance: utterance['voice'] = '' - if not isinstance(utterance['voice'],str): + if not isinstance(utterance['voice'], str): utterance['voice'] = '' - if not 'pitch' in utterance: + if 'pitch' not in utterance: utterance['pitch'] = '' - if not isinstance(utterance['pitch'],str): + if not isinstance(utterance['pitch'], str): utterance['pitch'] = '' - if not 'rate' in utterance: + if 'rate' not in utterance: utterance['rate'] = '' - if not isinstance(utterance['rate'],str): + if not isinstance(utterance['rate'], str): utterance['rate'] = '' - popenSpeechCommand = shlex.split(self.speechCommand) - for idx, word in enumerate(popenSpeechCommand): - word = word.replace('fenrirVolume', str(utterance['volume'] )) + popen_speech_command = shlex.split(self.speechCommand) + for idx, word in enumerate(popen_speech_command): + word = word.replace('fenrirVolume', str(utterance['volume'])) word = word.replace('fenrirModule', str(utterance['module'])) - word = word.replace('fenrirLanguage', str(utterance['language'])) + word = word.replace( + 'fenrirLanguage', str( + utterance['language'])) word = word.replace('fenrirVoice', str(utterance['voice'])) word = word.replace('fenrirPitch', str(utterance['pitch'])) word = word.replace('fenrirRate', str(utterance['rate'])) # Properly quote text to prevent command injection - word = word.replace('fenrirText', shlex.quote(str(utterance['text']))) - popenSpeechCommand[idx] = word + word = word.replace('fenrirText', + shlex.quote(str(utterance['text']))) + popen_speech_command[idx] = word try: - self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + ' '.join(popenSpeechCommand),debug.debugLevel.INFO) + self.env['runtime']['DebugManager'].write_debug_out( + 'speech_driver:worker:' + ' '.join(popen_speech_command), debug.DebugLevel.INFO) self.lock.acquire(True) - self.proc = Popen(popenSpeechCommand, stdin=None, stdout=None, stderr=None, shell=False) - self.lock.release() + self.proc = Popen( + popen_speech_command, + stdin=None, + stdout=None, + stderr=None, + shell=False) + self.lock.release() self.proc.wait() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'speech_driver:worker:' + str(e), debug.DebugLevel.ERROR) self.lock.acquire(True) self.proc = None self.lock.release() - diff --git a/src/fenrirscreenreader/speechDriver/speechdDriver.py b/src/fenrirscreenreader/speechDriver/speechdDriver.py index 57859e05..92da1d80 100644 --- a/src/fenrirscreenreader/speechDriver/speechdDriver.py +++ b/src/fenrirscreenreader/speechDriver/speechdDriver.py @@ -6,116 +6,128 @@ # speech-dispatcher driver from fenrirscreenreader.core import debug -from fenrirscreenreader.core.speechDriver import speechDriver +from fenrirscreenreader.core.speechDriver import speech_driver -class driver(speechDriver): + +class driver(speech_driver): def __init__(self): - speechDriver.__init__(self) + speech_driver.__init__(self) def initialize(self, environment): self._sd = None self.env = environment - self._isInitialized = False - - # Only set these if they haven't been set yet (preserve existing values) + self._is_initialized = False + + # Only set these if they haven't been set yet (preserve existing + # values) if not hasattr(self, 'language') or self.language is None: self.language = '' if not hasattr(self, 'voice') or self.voice is None: - self.voice = '' + self.voice = '' if not hasattr(self, 'module') or self.module is None: self.module = '' - + try: - import speechd - self._sd = speechd.SSIPClient('fenrir') + import speechd + self._sd = speechd.SSIPClient('fenrir-dev') self._punct = speechd.PunctuationMode() - self._isInitialized = True + self._is_initialized = True except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver initialize:' + str(e), debug.DebugLevel.ERROR) def shutdown(self): - if not self._isInitialized: + if not self._is_initialized: return self.cancel() try: self._sd.close() except Exception as e: pass - self._isInitialized = False + self._is_initialized = False - def speak(self,text, queueable=True, ignorePunctuation=False): + def speak(self, text, queueable=True, ignore_punctuation=False): if not queueable: self.cancel() - if not self._isInitialized: + if not self._is_initialized: self.initialize(self.env) if not queueable: self.cancel() - if not self._isInitialized: + if not self._is_initialized: return try: if self.module != '': self._sd.set_output_module(self.module) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_module:' + str(e), debug.DebugLevel.ERROR) try: if self.language != '': self._sd.set_language(self.language) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver set_language:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_language:' + str(e), debug.DebugLevel.ERROR) try: if self.voice != '': self._sd.set_synthesis_voice(self.voice) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_voice:' + str(e), debug.DebugLevel.ERROR) try: - if ignorePunctuation: + if ignore_punctuation: self._sd.set_punctuation(self._punct.ALL) else: self._sd.set_punctuation(self._punct.NONE) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver set_punctuation:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_punctuation:' + str(e), debug.DebugLevel.ERROR) try: self._sd.speak(text) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver speak:' + str(e),debug.debugLevel.ERROR) - self._isInitialized = False + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver speak:' + str(e), debug.DebugLevel.ERROR) + self._is_initialized = False def cancel(self): - if not self._isInitialized: + if not self._is_initialized: self.initialize(self.env) - if not self._isInitialized: + if not self._is_initialized: return try: self._sd.cancel() except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR) - self._isInitialized = False + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver cancel:' + str(e), debug.DebugLevel.ERROR) + self._is_initialized = False - def setPitch(self, pitch): - if not self._isInitialized: + def set_pitch(self, pitch): + if not self._is_initialized: return try: - self._sd.set_pitch(int(-100 + pitch * 200)) + self._sd.set_pitch(int(-100 + pitch * 200)) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver setPitch:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_pitch:' + str(e), debug.DebugLevel.ERROR) - def setRate(self, rate): - if not self._isInitialized: - return + def set_rate(self, rate): + if not self._is_initialized: + return try: self._sd.set_rate(int(-100 + rate * 200)) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_rate:' + str(e), debug.DebugLevel.ERROR) - def setVolume(self, volume): - if not self._isInitialized: - return + def set_volume(self, volume): + if not self._is_initialized: + return try: self._sd.set_volume(int(-100 + volume * 200)) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('speechDriver setVolume:' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['DebugManager'].write_debug_out( + 'SpeechDriver set_volume:' + str(e), debug.DebugLevel.ERROR) diff --git a/src/fenrirscreenreader/utils/char_utils.py b/src/fenrirscreenreader/utils/char_utils.py index b812ffc2..bef49d3e 100644 --- a/src/fenrirscreenreader/utils/char_utils.py +++ b/src/fenrirscreenreader/utils/char_utils.py @@ -6,129 +6,147 @@ from fenrirscreenreader.core import debug -def getPrevChar(currX,currY, currText): - lineBreak = False - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen, lineBreak - wrappedLines = currText.split('\n') - x = currX - y = currY + +def get_prev_char(curr_x, curr_y, curr_text): + line_break = False + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen, line_break + wrapped_lines = curr_text.split('\n') + x = curr_x + y = curr_y if x - 1 < 0: if y - 1 >= 0: y -= 1 - x = len(wrappedLines[y]) - 1 - lineBreak = True + x = len(wrapped_lines[y]) - 1 + line_break = True else: - lineBreak = False - endOfScreen = True + line_break = False + end_of_screen = True else: x -= 1 - currChar = '' - if not endOfScreen: - currChar = wrappedLines[y][x] - return x, y, currChar, endOfScreen, lineBreak + curr_char = '' + if not end_of_screen: + curr_char = wrapped_lines[y][x] + return x, y, curr_char, end_of_screen, line_break -def getCurrentChar(currX,currY, currText): - if currText == '': + +def get_current_char(curr_x, curr_y, curr_text): + if curr_text == '': return -1, -1, '' - wrappedLines = currText.split('\n') - currChar = wrappedLines[currY][currX] - return currX, currY, currChar + wrapped_lines = curr_text.split('\n') + curr_char = wrapped_lines[curr_y][curr_x] + return curr_x, curr_y, curr_char -def getUpChar(currX,currY, currText): - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen - wrappedLines = currText.split('\n') - currY -= 1 - if currY < 0: - currY = 0 + +def get_up_char(curr_x, curr_y, curr_text): + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen + wrapped_lines = curr_text.split('\n') + curr_y -= 1 + if curr_y < 0: + curr_y = 0 else: - endOfScreen = True - currChar = '' - if not endOfScreen: - currChar = wrappedLines[currY][currX] - return currX, currY, currChar, endOfScreen + end_of_screen = True + curr_char = '' + if not end_of_screen: + curr_char = wrapped_lines[curr_y][curr_x] + return curr_x, curr_y, curr_char, end_of_screen -def getDownChar(currX,currY, currText): - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen - wrappedLines = currText.split('\n') - currY += 1 - if currY >= len(wrappedLines): - currY = len(wrappedLines) -1 + +def get_down_char(curr_x, curr_y, curr_text): + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen + wrapped_lines = curr_text.split('\n') + curr_y += 1 + if curr_y >= len(wrapped_lines): + curr_y = len(wrapped_lines) - 1 else: - endOfScreen = True - currChar = '' - if not endOfScreen: - currChar = wrappedLines[currY][currX] - return currX, currY, currChar, endOfScreen + end_of_screen = True + curr_char = '' + if not end_of_screen: + curr_char = wrapped_lines[curr_y][curr_x] + return curr_x, curr_y, curr_char, end_of_screen -def getLastCharInLine(currY, currText): - endOfScreen = False - if currText == '': + +def get_last_char_in_line(curr_y, curr_text): + end_of_screen = False + if curr_text == '': return -1, -1, '' - wrappedLines = currText.split('\n') - currX = len(wrappedLines[currY].rstrip())-1 - if currX < 0: - currX = 0 - currChar = wrappedLines[currY][currX] - return currX, currY, currChar + wrapped_lines = curr_text.split('\n') + curr_x = len(wrapped_lines[curr_y].rstrip()) - 1 + if curr_x < 0: + curr_x = 0 + curr_char = wrapped_lines[curr_y][curr_x] + return curr_x, curr_y, curr_char -def getNextChar(currX,currY, currText): - lineBreak = False - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen, lineBreak - wrappedLines = currText.split('\n') - x = currX - y = currY - if x + 1 == len(wrappedLines[y]): - if y + 1 <= len(wrappedLines) - 1: + +def get_next_char(curr_x, curr_y, curr_text): + line_break = False + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen, line_break + wrapped_lines = curr_text.split('\n') + x = curr_x + y = curr_y + if x + 1 == len(wrapped_lines[y]): + if y + 1 <= len(wrapped_lines) - 1: y += 1 x = 0 - lineBreak = True + line_break = True else: - lineBreak = False - endOfScreen = True + line_break = False + end_of_screen = True else: - x += 1 - currChar = '' - if not endOfScreen: - currChar = wrappedLines[y][x] + x += 1 + curr_char = '' + if not end_of_screen: + curr_char = wrapped_lines[y][x] - return x, y, currChar, endOfScreen, lineBreak + return x, y, curr_char, end_of_screen, line_break -def getPhonetic(currChar): - if len(currChar) != 1: - return currChar - phoneticsDict = { - "A":"alpha", "B":"bravo", "C":"charlie", "D":"delta", "E":"echo", - "F":"foxtrot", "G":"golf", "H":"hotel", "I":"india", "J":"juliet", - "K":"kilo", "L":"lima", "M":"mike", "N":"november", "O":"oscar", - "P":"papa", "Q":"quebec", "R":"romeo", "S":"sierra", "T":"tango", - "U":"uniform", "V":"victor", "W":"whisky", "X":"x ray", - "Y":"yankee", "Z":"zulu" + +def get_phonetic(curr_char): + if len(curr_char) != 1: + return curr_char + phonetics_dict = { + "A": "alpha", "B": "bravo", "C": "charlie", "D": "delta", "E": "echo", + "F": "foxtrot", "G": "golf", "H": "hotel", "I": "india", "J": "juliet", + "K": "kilo", "L": "lima", "M": "mike", "N": "november", "O": "oscar", + "P": "papa", "Q": "quebec", "R": "romeo", "S": "sierra", "T": "tango", + "U": "uniform", "V": "victor", "W": "whisky", "X": "x ray", + "Y": "yankee", "Z": "zulu" } try: - phonChar = phoneticsDict[currChar.upper()] - if currChar.isupper(): - phonChar = phonChar[0].upper() + phonChar[1:] - return phonChar + phon_char = phonetics_dict[curr_char.upper()] + if curr_char.isupper(): + phon_char = phon_char[0].upper() + phon_char[1:] + return phon_char except Exception as e: # Utility function, no env access - return fallback - return currChar + return curr_char -def presentCharForReview(env, char, interrupt=True, announceCapital=True, flush=False): + +def present_char_for_review( + env, + char, + interrupt=True, + announce_capital=True, + flush=False): """Present a character for explicit review commands only""" if char == ' ': if ' ' in env['punctuation']['PUNCTDICT']: - announceChar = env['punctuation']['PUNCTDICT'][' '] + announce_char = env['punctuation']['PUNCTDICT'][' '] else: - announceChar = 'space' - env['runtime']['outputManager'].presentText(announceChar, interrupt=interrupt, flush=flush) + announce_char = 'space' + env['runtime']['OutputManager'].present_text( + announce_char, interrupt=interrupt, flush=flush) else: - env['runtime']['outputManager'].presentText(char, interrupt=interrupt, ignorePunctuation=True, announceCapital=announceCapital, flush=flush) - + env['runtime']['OutputManager'].present_text( + char, + interrupt=interrupt, + ignore_punctuation=True, + announce_capital=announce_capital, + flush=flush) diff --git a/src/fenrirscreenreader/utils/fenrir-config.py b/src/fenrirscreenreader/utils/fenrir-config.py index 97d1087f..455bca6e 100644 --- a/src/fenrirscreenreader/utils/fenrir-config.py +++ b/src/fenrirscreenreader/utils/fenrir-config.py @@ -10,14 +10,13 @@ from xdg import BaseDirectory # Get configuration directory if len(sys.argv) > 1: - configPath = sys.argv[1] + config_path = sys.argv[1] elif os.geteuid() == 0: # Save settings system wide - configPath = "/etc/fenrir.conf" + config_path = "/etc/fenrir.conf" else: # Use local settings - configPath = BaseDirectory.xdg_data_home + "/fenrir" - if not os.path.exists(configPath): os.makedirs(configPath) - configPath = configPath + "/fenrir.conf" - - + config_path = BaseDirectory.xdg_data_home + "/fenrir" + if not os.path.exists(config_path): + os.makedirs(config_path) + config_path = config_path + "/fenrir.conf" diff --git a/src/fenrirscreenreader/utils/line_utils.py b/src/fenrirscreenreader/utils/line_utils.py index a18caaa7..694e95da 100644 --- a/src/fenrirscreenreader/utils/line_utils.py +++ b/src/fenrirscreenreader/utils/line_utils.py @@ -6,46 +6,49 @@ from fenrirscreenreader.core import debug -def getPrevLine(currX,currY, currText): - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen - wrappedLines = currText.split('\n') - x = currX - y = currY + +def get_prev_line(curr_x, curr_y, curr_text): + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen + wrapped_lines = curr_text.split('\n') + x = curr_x + y = curr_y if y - 1 >= 0: y -= 1 else: - endOfScreen = True - x = currX - currLine = '' - if not endOfScreen: - currLine = wrappedLines[y] - return x, y, currLine, endOfScreen + end_of_screen = True + x = curr_x + curr_line = '' + if not end_of_screen: + curr_line = wrapped_lines[y] + return x, y, curr_line, end_of_screen -def getCurrentLine(currX,currY, currText): - if currText == '': + +def get_current_line(curr_x, curr_y, curr_text): + if curr_text == '': return -1, -1, '' - wrappedLines = currText.split('\n') - x = currX - y = currY + wrapped_lines = curr_text.split('\n') + x = curr_x + y = curr_y x = 0 - currLine = wrappedLines[y] - return x, y, currLine + curr_line = wrapped_lines[y] + return x, y, curr_line -def getNextLine(currX,currY, currText): - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen - wrappedLines = currText.split('\n') - x = currX - y = currY - if y + 1 < len(wrappedLines): + +def get_next_line(curr_x, curr_y, curr_text): + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen + wrapped_lines = curr_text.split('\n') + x = curr_x + y = curr_y + if y + 1 < len(wrapped_lines): y += 1 else: - endOfScreen = True - x = currX - currLine = '' - if not endOfScreen: - currLine = wrappedLines[y] - return x, y, currLine, endOfScreen + end_of_screen = True + x = curr_x + curr_line = '' + if not end_of_screen: + curr_line = wrapped_lines[y] + return x, y, curr_line, end_of_screen diff --git a/src/fenrirscreenreader/utils/mark_utils.py b/src/fenrirscreenreader/utils/mark_utils.py index c2de1f9a..1f561a9b 100644 --- a/src/fenrirscreenreader/utils/mark_utils.py +++ b/src/fenrirscreenreader/utils/mark_utils.py @@ -6,55 +6,62 @@ from fenrirscreenreader.core import debug -def getTextBetweenMarks(firstMark, secondMark, inText): - if inText == None: + +def get_text_between_marks(firstMark, secondMark, in_text): + if in_text is None: return '' - if not isinstance(inText, list): - inText = inText.split('\n') - if len(inText) < 1: - return '' - if firstMark == None: + if not isinstance(in_text, list): + in_text = in_text.split('\n') + if len(in_text) < 1: return '' - if secondMark == None: - return '' - if (firstMark['y'] + 1) * (firstMark['x'] + 1) <= (secondMark['y'] + 1) * (secondMark['x'] + 1): - startMark = firstMark.copy() - endMark = secondMark.copy() + if firstMark is None: + return '' + if secondMark is None: + return '' + if (firstMark['y'] + 1) * (firstMark['x'] + + 1) <= (secondMark['y'] + 1) * (secondMark['x'] + 1): + start_mark = firstMark.copy() + end_mark = secondMark.copy() else: - endMark = firstMark.copy() - startMark = secondMark.copy() - textPart = '' - if startMark['y'] == endMark['y']: - textPart += inText[startMark['y']][startMark['x']:endMark['x'] + 1] + end_mark = firstMark.copy() + start_mark = secondMark.copy() + text_part = '' + if start_mark['y'] == end_mark['y']: + text_part += in_text[start_mark['y']][start_mark['x']:end_mark['x'] + 1] else: - currY = startMark['y'] - while currY <= endMark['y']: - if currY < endMark['y']: - if currY == startMark['y']: - textPart += inText[currY][startMark['x']:] + curr_y = start_mark['y'] + while curr_y <= end_mark['y']: + if curr_y < end_mark['y']: + if curr_y == start_mark['y']: + text_part += in_text[curr_y][start_mark['x']:] else: - textPart += inText[currY] - if len(inText[currY].strip()) != 0: - if len(textPart) - len(textPart.rstrip()) > 0: - textPart = textPart[:len(textPart.rstrip())] + "\n" + text_part += in_text[curr_y] + if len(in_text[curr_y].strip()) != 0: + if len(text_part) - len(text_part.rstrip()) > 0: + text_part = text_part[:len(text_part.rstrip())] + "\n" else: - textPart += '\n' + text_part += '\n' else: - textPart += inText[currY][:endMark['x'] + 1] - currY += 1 - return textPart + text_part += in_text[curr_y][:end_mark['x'] + 1] + curr_y += 1 + return text_part -def getTextBeforeMark(mark, inText): - if inText == None: - return '' - if mark == None: - return '' - return getTextBetweenMarks({'x':0,'y':0}, mark, inText) -def getTextAfterMark(mark, inText): - if inText == None: +def get_text_before_mark(mark, in_text): + if in_text is None: return '' - if mark == None: + if mark is None: return '' - inText = inText.split('\n') - return getTextBetweenMarks(mark, {'x':len(inText[0])-1,'y':len(inText)-1}, inText) + return get_text_between_marks({'x': 0, 'y': 0}, mark, in_text) + + +def get_text_after_mark(mark, in_text): + if in_text is None: + return '' + if mark is None: + return '' + in_text = in_text.split('\n') + return get_text_between_marks( + mark, { + 'x': len( + in_text[0]) - 1, 'y': len(in_text) - 1}, in_text) diff --git a/src/fenrirscreenreader/utils/module_utils.py b/src/fenrirscreenreader/utils/module_utils.py index 08fbed86..2107397b 100644 --- a/src/fenrirscreenreader/utils/module_utils.py +++ b/src/fenrirscreenreader/utils/module_utils.py @@ -3,17 +3,19 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. import sys -version = sys.version[:3] # we only need major.minor version. -if version in ["3.3","3.4"]: +version = sys.version[:3] # we only need major.minor version. +if version in ["3.3", "3.4"]: from importlib.machinery import SourceFileLoader -else: # Python 3.5+, no support for python < 3.3. +else: # Python 3.5+, no support for python < 3.3. import importlib.util -def importModule(moduleName, moduleLocation): - if version in ["3.3","3.4"]: + +def import_module(moduleName, moduleLocation): + if version in ["3.3", "3.4"]: return SourceFileLoader(moduleName, moduleLocation).load_module() else: - spec = importlib.util.spec_from_file_location(moduleName, moduleLocation) + spec = importlib.util.spec_from_file_location( + moduleName, moduleLocation) driver_mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(driver_mod) return driver_mod diff --git a/src/fenrirscreenreader/utils/review_utils.py b/src/fenrirscreenreader/utils/review_utils.py index fe1afa2f..cde145bd 100644 --- a/src/fenrirscreenreader/utils/review_utils.py +++ b/src/fenrirscreenreader/utils/review_utils.py @@ -5,4 +5,3 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug - diff --git a/src/fenrirscreenreader/utils/screen_utils.py b/src/fenrirscreenreader/utils/screen_utils.py index 1fb34fc3..dfc58911 100644 --- a/src/fenrirscreenreader/utils/screen_utils.py +++ b/src/fenrirscreenreader/utils/screen_utils.py @@ -5,50 +5,63 @@ # By Chrys, Storm Dragon, and contributers. from fenrirscreenreader.core import debug -import getpass, time, string, os +import getpass +import time +import string +import os from select import select -def removeNonprintable(text): - # Get the difference of all ASCII characters from the set of printable characters - nonprintable = set([chr(i) for i in range(128)]).difference(string.printable) + +def remove_nonprintable(text): + # Get the difference of all ASCII characters from the set of printable + # characters + nonprintable = set([chr(i) for i in range(128)] + ).difference(string.printable) # Use translate to remove all non-printable characters - return text.translate({ord(character):None for character in nonprintable}) + return text.translate({ord(character): None for character in nonprintable}) -def insertNewlines(string, every=64): - return '\n'.join(string[i:i+every] for i in range(0, len(string), every)) -def splitEvery(toSplit, every=64): - return list(toSplit[i:i+every] for i in range(0, len(toSplit), every)) -def createScreenEventData(content): - eventData = { +def insert_newlines(string, every=64): + return '\n'.join(string[i:i + every] for i in range(0, len(string), every)) + + +def split_every(toSplit, every=64): + return list(toSplit[i:i + every] for i in range(0, len(toSplit), every)) + + +def create_screen_event_data(content): + event_data = { 'bytes': content, 'lines': content['lines'], 'columns': content['columns'], - 'textCursor': + 'textCursor': { - 'x': int( content['cursor'][0]), - 'y': int( content['cursor'][1]) - }, + 'x': int(content['cursor'][0]), + 'y': int(content['cursor'][1]) + }, 'screen': content['screen'], 'text': content['text'], 'attributes': content['attributes'], 'screenUpdateTime': time.time(), } - return eventData.copy() + return event_data.copy() -def hasMore(fd, timetout=0.05): + +def has_more(fd, timetout=0.05): r, _, _ = select([fd], [], [], timetout) return (fd in r) -def hasMoreWhat(fdList, timetout=0.05): - if not isinstance(fdList, list): - return [] - elif fdList == []: + +def has_more_what(fd_list, timetout=0.05): + if not isinstance(fd_list, list): return [] - r, _, _ = select(fdList, [], [], timetout) + elif fd_list == []: + return [] + r, _, _ = select(fd_list, [], [], timetout) return r -def isValidShell(shell = ''): + +def is_valid_shell(shell=''): if not isinstance(shell, str): return False if shell == '': @@ -56,25 +69,26 @@ def isValidShell(shell = ''): try: if not os.path.isfile(shell): return False - if not os.access(shell,os.X_OK): + if not os.access(shell, os.X_OK): return False except Exception as e: # Utility function, no env access - use fallback logging - print(f'screen_utils isValidShell: Error checking shell {shell}: {e}') + print(f'screen_utils is_valid_shell: Error checking shell {shell}: {e}') return False return True -def getShell(): + +def get_shell(): try: shell = os.environ["FENRIRSHELL"] - if isValidShell(shell): + if is_valid_shell(shell): return shell except Exception as e: # Utility function, no env access - continue silently - pass + pass try: shell = os.environ["SHELL"] - if isValidShell(shell): + if is_valid_shell(shell): return shell except Exception as e: # Utility function, no env access - continue silently @@ -84,14 +98,15 @@ def getShell(): with open('/etc/passwd') as f: users = f.readlines() for user in users: - (username, encrypwd, uid, gid, gecos, homedir, shell) = user.split(':') - shell = shell.replace('\n','') + (username, encrypwd, uid, gid, gecos, + homedir, shell) = user.split(':') + shell = shell.replace('\n', '') if username == getpass.getuser(): - if isValidShell(shell): + if is_valid_shell(shell): return shell except Exception as e: # Utility function, no env access - continue silently pass - if isValidShell('/bin/bash'): + if is_valid_shell('/bin/bash'): return '/bin/bash' return '/bin/sh' diff --git a/src/fenrirscreenreader/utils/word_utils.py b/src/fenrirscreenreader/utils/word_utils.py index 56c02de5..6d4b4952 100644 --- a/src/fenrirscreenreader/utils/word_utils.py +++ b/src/fenrirscreenreader/utils/word_utils.py @@ -7,116 +7,119 @@ from fenrirscreenreader.core import debug import string -def getCurrentWord(currX,currY, currText): - lineBreak = False - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen, lineBreak - if currText.strip( string.whitespace) == '': - return currX, currY, '', endOfScreen, lineBreak - x = currX - y = currY - currWord = '' - wrappedLines = currText.split('\n') - currLine = wrappedLines[y] - Found = False - while(not Found): - if not currLine[x] in string.whitespace: + +def get_current_word(curr_x, curr_y, curr_text): + line_break = False + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen, line_break + if curr_text.strip(string.whitespace) == '': + return curr_x, curr_y, '', end_of_screen, line_break + x = curr_x + y = curr_y + curr_word = '' + wrapped_lines = curr_text.split('\n') + curr_line = wrapped_lines[y] + found = False + while (not found): + if not curr_line[x] in string.whitespace: if x == 0: - Found = True + found = True else: - if currLine[x - 1] in string.whitespace: - Found = True - if not Found: + if curr_line[x - 1] in string.whitespace: + found = True + if not found: if x - 1 < 0: if y - 1 < 0: - lineBreak = False - endOfScreen = True - return currX, currY, '', endOfScreen, lineBreak + line_break = False + end_of_screen = True + return curr_x, curr_y, '', end_of_screen, line_break else: y -= 1 - currLine = wrappedLines[y] - x = len( currLine) - 1 - lineBreak = True + curr_line = wrapped_lines[y] + x = len(curr_line) - 1 + line_break = True else: x -= 1 - if Found: - currWord = currLine[x:] + if found: + curr_word = curr_line[x:] for d in string.whitespace: - delimiterPos = currWord.find(d) - if delimiterPos != -1: - currWord = currWord[:delimiterPos] - return x, y, currWord, endOfScreen, lineBreak - return currX, currY, '', False, False + delimiter_pos = curr_word.find(d) + if delimiter_pos != -1: + curr_word = curr_word[:delimiter_pos] + return x, y, curr_word, end_of_screen, line_break + return curr_x, curr_y, '', False, False -def getPrevWord(currX,currY, currText): - lineBreak = False - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen, lineBreak - if currText.strip( string.whitespace) == '': - return currX, currY, '', endOfScreen, lineBreak - x, y, currWord, endOfScreen, lineBreakCurrWord = getCurrentWord(currX,currY,currText) - if endOfScreen: - return x, y, currWord, endOfScreen, lineBreak - wrappedLines = currText.split('\n') - currLine = wrappedLines[y] + +def get_prev_word(curr_x, curr_y, curr_text): + line_break = False + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen, line_break + if curr_text.strip(string.whitespace) == '': + return curr_x, curr_y, '', end_of_screen, line_break + x, y, curr_word, end_of_screen, line_break_curr_word = get_current_word( + curr_x, curr_y, curr_text) + if end_of_screen: + return x, y, curr_word, end_of_screen, line_break + wrapped_lines = curr_text.split('\n') + curr_line = wrapped_lines[y] if x - 1 < 0: if y - 1 < 0: - lineBreak = False - endOfScreen = True - return currX, currY, '', endOfScreen, lineBreak + line_break = False + end_of_screen = True + return curr_x, curr_y, '', end_of_screen, line_break else: y -= 1 - currLine = wrappedLines[y] - x = len( currLine) - 1 - lineBreak = True + curr_line = wrapped_lines[y] + x = len(curr_line) - 1 + line_break = True else: x -= 1 - lineBreakCurrWord = lineBreak or lineBreakCurrWord - x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,currText) - lineBreak = lineBreak or lineBreakCurrWord - return x, y, currWord, endOfScreen, lineBreak + line_break_curr_word = line_break or line_break_curr_word + x, y, curr_word, end_of_screen, line_break = get_current_word(x, y, curr_text) + line_break = line_break or line_break_curr_word + return x, y, curr_word, end_of_screen, line_break -def getNextWord(currX,currY, currText): - lineBreak = False - endOfScreen = False - if currText == '': - return -1, -1, '', endOfScreen, lineBreak - if currText.strip( string.whitespace) == '': - return currX, currY, '', endOfScreen, lineBreak - x = currX - y = currY - currWord = '' - wrappedLines = currText.split('\n') - currLine = wrappedLines[y] - Found = False - while(not Found): - if not Found: - if x + 1 > len( currLine ) - 1: - if y + 1 > len( wrappedLines ) - 1: - lineBreak = False - endOfScreen = True - return currX, currY, '', endOfScreen, lineBreak + +def get_next_word(curr_x, curr_y, curr_text): + line_break = False + end_of_screen = False + if curr_text == '': + return -1, -1, '', end_of_screen, line_break + if curr_text.strip(string.whitespace) == '': + return curr_x, curr_y, '', end_of_screen, line_break + x = curr_x + y = curr_y + curr_word = '' + wrapped_lines = curr_text.split('\n') + curr_line = wrapped_lines[y] + found = False + while (not found): + if not found: + if x + 1 > len(curr_line) - 1: + if y + 1 > len(wrapped_lines) - 1: + line_break = False + end_of_screen = True + return curr_x, curr_y, '', end_of_screen, line_break else: y += 1 - currLine = wrappedLines[y] + curr_line = wrapped_lines[y] x = 0 - lineBreak = True + line_break = True else: x += 1 - if not currLine[x] in string.whitespace: + if not curr_line[x] in string.whitespace: if x == 0: - Found = True + found = True else: - if currLine[x - 1] in string.whitespace: - Found = True - if Found: - currWord = currLine[x:] + if curr_line[x - 1] in string.whitespace: + found = True + if found: + curr_word = curr_line[x:] for d in string.whitespace: - delimiterPos = currWord.find(d) - if delimiterPos != -1: - currWord = currWord[:delimiterPos] - return x, y, currWord, endOfScreen, lineBreak - return currX, currY, '', False, False - + delimiter_pos = curr_word.find(d) + if delimiter_pos != -1: + curr_word = curr_word[:delimiter_pos] + return x, y, curr_word, end_of_screen, line_break + return curr_x, curr_y, '', False, False