22
33import addonHandler
44import api
5- import characterProcessing
5+ import config
66import globalCommands
77import globalPluginHandler
8- import languageHandler
98import nvwave
109import scriptHandler
1110import speech
1211import textInfos
1312
14- SOUNDS_DIR = Path (__file__ ).parent / "media"
13+ from . import interface
14+ from .features .diff_sounds import DiffSoundsFeature
15+ from .features .space_folding import SpaceFoldingFeature
16+
17+ config .conf .spec ["devBox" ] = {
18+ "features" : {
19+ "diffSounds" : "boolean(default=false)" ,
20+ "spaceFolding" : "boolean(default=false)" ,
21+ },
22+ }
23+ ADDON_ROOT = Path (addonHandler .getCodeAddon ().installPath ).resolve ()
24+ SOUNDS_DIR = ADDON_ROOT / "media"
1525DIFF_SOUNDS = {
1626 "-" : "diffLineDeleted.wav" ,
1727 "+" : "diffLineInserted.wav" ,
1828}
1929DIFF_SOUNDS = {k : str (SOUNDS_DIR / v ) for k , v in DIFF_SOUNDS .items ()}
2030
21- SPACE = characterProcessing .processSpeechSymbol (languageHandler .getLanguage (), " " )
22- end_utterance_command = speech .commands .EndUtteranceCommand ()
2331
2432# We need this to get translations fromNVDA standard catalog.
2533gettext = _
26- addonHandler .initTranslation ()
2734
2835
29- def get_spelling_speech_decorator (func ):
30- def wrapper (* args , ** kwargs ):
31- original_commands = list (func (* args , ** kwargs ))
32- new_commands = []
33- spaces_buffer = []
34-
35- def flush_spaces_buffer ():
36- spaces_amount = len (spaces_buffer ) // 2
37- if spaces_amount < 2 :
38- new_commands .extend (spaces_buffer )
39- else :
40- new_commands .append (f"{ spaces_amount } { SPACE } " )
41- new_commands .append (end_utterance_command )
42- spaces_buffer .clear ()
43-
44- cursor = 0
45- while cursor < len (original_commands ):
46- command = original_commands [cursor ]
47- if isinstance (command , str ) and command == SPACE :
48- spaces_buffer .extend (original_commands [cursor : cursor + 2 ])
49- cursor += 2 # Space and end utterance command
50- continue
51- flush_spaces_buffer ()
52- new_commands .append (command )
53- cursor += 1
54- flush_spaces_buffer ()
55- return new_commands
56-
57- return wrapper
36+ addonHandler .initTranslation ()
5837
5938
6039class GlobalPlugin (globalPluginHandler .GlobalPlugin ):
6140 scriptCategory = "Dev Box"
6241
6342 def __init__ (self , * args , ** kwargs ):
6443 super ().__init__ (* args , ** kwargs )
65- self ._speech__getSpellingSpeechWithoutCharMode = (
66- speech ._getSpellingSpeechWithoutCharMode
67- )
68- speech ._getSpellingSpeechWithoutCharMode = get_spelling_speech_decorator (
69- speech ._getSpellingSpeechWithoutCharMode
70- )
71- self ._speech_speech__getSpellingSpeechWithoutCharMode = (
72- speech .speech ._getSpellingSpeechWithoutCharMode
73- )
74- speech .speech ._getSpellingSpeechWithoutCharMode = get_spelling_speech_decorator (
75- speech .speech ._getSpellingSpeechWithoutCharMode
76- )
44+ self .config = config .conf ["devBox" ]
45+ self ._diff_sounds_enabled = False
46+ self .features = [SpaceFoldingFeature (self ), DiffSoundsFeature (self )]
47+ self .sync_features ()
48+ interface .add_settings (self .on_config_change )
49+ config .post_configProfileSwitch .register (self .on_profile_switch )
50+
51+ def on_config_change (self ):
52+ self .sync_features ()
53+
54+ def on_profile_switch (self ):
55+ self .sync_features ()
56+
57+ def sync_features (self ):
58+ [feature .sync () for feature in self .features ]
7759
7860 def terminate (self ):
79- speech ._getSpellingSpeechWithoutCharMode = (
80- self ._speech__getSpellingSpeechWithoutCharMode
81- )
82- speech .speech ._getSpellingSpeechWithoutCharMode = (
83- self ._speech_speech__getSpellingSpeechWithoutCharMode
84- )
61+ [feature .terminate () for feature in self .features ]
62+ interface .remove_settings ()
63+ config .post_configProfileSwitch .unregister (self .on_profile_switch )
8564
8665 @scriptHandler .script (
8766 description = gettext (
88- # Translators: Input help mode message for move review cursor to previous line command.
8967 "Moves the review cursor to the previous line of the current navigator object and speaks it" ,
9068 ),
9169 resumeSayAllMode = speech .sayAll .CURSOR .REVIEW ,
@@ -99,7 +77,6 @@ def script_review_previous_line(self, gesture):
9977
10078 @scriptHandler .script (
10179 description = gettext (
102- # Translators: Input help mode message for read current line under review cursor command.
10380 "Reports the line of the current navigator object where the review cursor is situated. "
10481 "If this key is pressed twice, the current line will be spelled. "
10582 "Pressing three times will spell the line using character descriptions." ,
@@ -116,7 +93,6 @@ def script_review_currentLine(self, gesture):
11693
11794 @scriptHandler .script (
11895 description = gettext (
119- # Translators: Input help mode message for move review cursor to next line command.
12096 "Moves the review cursor to the next line of the current navigator object and speaks it" ,
12197 ),
12298 resumeSayAllMode = speech .sayAll .CURSOR .REVIEW ,
@@ -129,6 +105,8 @@ def script_review_nextLine(self, gesture):
129105 return result
130106
131107 def report_diff_line_status (self ):
108+ if not self ._diff_sounds_enabled :
109+ return
132110 info = api .getReviewPosition ().copy ()
133111 info .expand (textInfos .UNIT_LINE )
134112 text = info .text
0 commit comments