From 3cbfec7a988c3913fbb44620e1ab222c3d7c3228 Mon Sep 17 00:00:00 2001 From: Leonard de Ruijter Date: Fri, 2 Aug 2024 18:59:06 +0200 Subject: [PATCH 1/2] Add ability to speak character when cursor routing --- source/braille.py | 15 +++++++++++++++ source/config/configSpec.py | 1 + source/globalCommands.py | 16 ++++++++++++++++ source/gui/settingsDialogs.py | 9 +++++++++ user_docs/en/changes.md | 2 ++ user_docs/en/userGuide.md | 6 ++++++ 6 files changed, 49 insertions(+) diff --git a/source/braille.py b/source/braille.py index bf5a55bcdc..85e9d0e91d 100644 --- a/source/braille.py +++ b/source/braille.py @@ -1640,6 +1640,7 @@ def _routeToTextInfo(self, info: textInfos.TextInfo): pass return self._setCursor(info) + _speakOnRouting(info.copy()) def nextLine(self): dest = self._readingInfo.copy() @@ -3679,3 +3680,17 @@ def getDisplayDrivers( continue if not filterFunc or filterFunc(display): yield display + + +def _speakOnRouting(info: textInfos.TextInfo): + """Speaks the character at the cursor position after routing. + + :param info: The TextInfo at the cursor position after routing. + """ + if not config.conf["braille"]["speakOnRouting"]: + return + # Import late to avoid circular import. + from speech.speech import spellTextInfo + + info.expand(textInfos.UNIT_CHARACTER) + spellTextInfo(info) diff --git a/source/config/configSpec.py b/source/config/configSpec.py index 4f315dceaa..fe440fe9a1 100644 --- a/source/config/configSpec.py +++ b/source/config/configSpec.py @@ -90,6 +90,7 @@ unicodeNormalization = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="disabled") focusContextPresentation = option("changedContext", "fill", "scroll", default="changedContext") interruptSpeechWhileScrolling = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled") + speakOnRouting = boolean(default=false) showSelection = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled") reportLiveRegions = featureFlag(optionsEnum="BoolFlag", behaviorOfDefault="enabled") fontFormattingDisplay = featureFlag(optionsEnum="FontFormattingBrailleModeFlag", behaviorOfDefault="LIBLOUIS") diff --git a/source/globalCommands.py b/source/globalCommands.py index 19b83490b7..a7dfd515da 100755 --- a/source/globalCommands.py +++ b/source/globalCommands.py @@ -3593,6 +3593,22 @@ def script_braille_toggleShowCursor(self, gesture): braille.handler._updateDisplay() ui.message(state) + @script( + # Translators: Input help mode message for speak on routing command. + description=_("Toggles speaking the character under the cursor when routing cursor in text"), + category=SCRCAT_BRAILLE, + ) + @gui.blockAction.when(gui.blockAction.Context.BRAILLE_MODE_SPEECH_OUTPUT) + def script_braille_toggleSpeakOnRouting(self, gesture): + state = config.conf["braille"]["speakOnRouting"] = not config.conf["braille"]["speakOnRouting"] + if state: + # Translators: The message announced when toggling on speaking character when routing. + state = _("Speak character when routing cursor in text on") + else: + # Translators: The message announced when toggling off speaking character when routing. + state = _("Speak character when routing cursor in text off") + ui.message(state) + @script( # Translators: Input help mode message for cycle braille cursor shape command. description=_("Cycle through the braille cursor shapes"), diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index 0b51acc1dc..1e33b286d5 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -4447,6 +4447,14 @@ def makeSettings(self, settingsSizer): ) self.bindHelpEvent("BrailleFormattingDisplay", self.formattingDisplayCombo) + # Translators: The label for a setting in braille settings to speak the character under the cursor when cursor routing in text. + speakOnRoutingText = _("Spea&k character when routing cursor in text") + self.speakOnRoutingCheckBox = followCursorGroupHelper.addItem( + wx.CheckBox(self, label=speakOnRoutingText), + ) + self.bindHelpEvent("BrailleSettingsSpeakOnRouting", self.speakOnRoutingCheckBox) + self.speakOnRoutingCheckBox.Value = config.conf["braille"]["speakOnRouting"] + self.followCursorGroupBox.Enable( list(braille.BrailleMode)[self.brailleModes.GetSelection()] is braille.BrailleMode.FOLLOW_CURSORS, ) @@ -4514,6 +4522,7 @@ def onSave(self): config.conf["braille"]["paragraphStartMarker"] = [marker.value for marker in ParagraphStartMarker][ self.paragraphStartMarkersComboBox.GetSelection() ] + config.conf["braille"]["speakOnRouting"] = self.speakOnRoutingCheckBox.Value config.conf["braille"]["wordWrap"] = self.wordWrapCheckBox.Value self.unicodeNormalizationCombo.saveCurrentValueToConf() config.conf["braille"]["focusContextPresentation"] = self.focusContextPresentationValues[ diff --git a/user_docs/en/changes.md b/user_docs/en/changes.md index 5009fe7bb3..ed56d3ec46 100644 --- a/user_docs/en/changes.md +++ b/user_docs/en/changes.md @@ -15,6 +15,8 @@ The available options are: * Tags: Uses start and end tags to denote where certain font attributes begin and end. (#16864) * When the "Read by paragraph" option is enabled, NVDA can now be configured to indicate the start of paragraphs in braille. (#16895, @nvdaes) * The timeout to perform a multiple keypress is now configurable; this may be especially useful for people with dexterity impairment. (#11929, @CyrilleB79) +* When performing a braille cursor routing action, NVDA can now automatically speak the character ath the cursor. (#8072, @LeonarddeR) + * This option is disabled by default. You can enable "Speak character when routing cursor in text" in NVDA's braille settings. ### Changes diff --git a/user_docs/en/userGuide.md b/user_docs/en/userGuide.md index c651d48ffe..7f100de0ee 100644 --- a/user_docs/en/userGuide.md +++ b/user_docs/en/userGuide.md @@ -2250,6 +2250,12 @@ The following symbols are defined: | ⠎ ("s")| Start strikethrough | | ⡎ ("s" with dot 7) | End strikethrough | +##### Speak character when routing cursor in text {#BrailleSettingsSpeakOnRouting} + +If this is enabled, NVDA will automatically speak the character at the cursor when routing to it with braille cursor routing keys. + +To toggle this option from anywhere, please assign a custom gesture using the [Input Gestures dialog](#InputGestures). + ##### Avoid splitting words when possible {#BrailleSettingsWordWrap} If this is enabled, a word which is too large to fit at the end of the braille display will not be split. From 3b0ac706b6db0dceb7aa5571823fa7a0312d2375 Mon Sep 17 00:00:00 2001 From: "korbit-ai[bot]" <131444098+korbit-ai[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 19:19:36 +0000 Subject: [PATCH 2/2] [skip ci]