From df92ef663f3b5c36fc778a8a2e4d4dd9cecceb0f Mon Sep 17 00:00:00 2001 From: Michael Curran Date: Fri, 1 Oct 2021 10:52:11 +1000 Subject: [PATCH] MS Word with UIA: support moving by sentence with legacy object model when available (#12874) Fixes #9254 Summary of the issue: In the past, NVDA has had the functionality to move by sentence in MS word (alt+downArrow and alt+upArrow). This functionality used the MS Word object model. With the switch to using UI automation to access MS Word, move by sentence was lost, as MS Word's UI automation implementation provides no concept of a sentence unit. Description of how this pull request fixes the issue: This pr provides an implementation of moving by sentence for MS Word with UIA by falling back to the MS word object model for this specific feature, if the object model is available. This therefore will work in MS Word and Outlook, but not in Windows Mail. --- source/NVDAObjects/UIA/wordDocument.py | 48 +++++++++++++++++++++++++- user_docs/en/changes.t2t | 1 + 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/source/NVDAObjects/UIA/wordDocument.py b/source/NVDAObjects/UIA/wordDocument.py index 62f666515bd..93e3dd1aecf 100644 --- a/source/NVDAObjects/UIA/wordDocument.py +++ b/source/NVDAObjects/UIA/wordDocument.py @@ -5,6 +5,7 @@ from comtypes import COMError from collections import defaultdict +from scriptHandler import isScriptWaiting import textInfos import eventHandler import UIAHandler @@ -12,12 +13,17 @@ import controlTypes import ui import speech +import review +import braille import api import browseMode from UIABrowseMode import UIABrowseModeDocument, UIADocumentWithTableNavigation, UIATextAttributeQuicknavIterator, TextAttribUIATextInfoQuickNavItem from UIAUtils import * from . import UIA, UIATextInfo -from NVDAObjects.window.winword import WordDocument as WordDocumentBase +from NVDAObjects.window.winword import ( + WordDocument as WordDocumentBase, + WordDocumentTextInfo as LegacyWordDocumentTextInfo +) from scriptHandler import script @@ -413,6 +419,46 @@ def event_UIA_notification(self, activityId=None, **kwargs): return super(WordDocument, self).event_UIA_notification(**kwargs) + # The following overide of the EditableText._caretMoveBySentenceHelper private method + # Falls back to the MS Word object model if available. + # This override should be removed as soon as UI Automation in MS Word has the ability to move by sentence. + def _caretMoveBySentenceHelper(self, gesture, direction): + if isScriptWaiting(): + return + if not self.WinwordSelectionObject: + # Legacy object model not available. + # Translators: a message when navigating by sentence is unavailable in MS Word + ui.message(_("Navigating by sentence not supported in this document")) + gesture.send() + return + # Using the legacy object model, + # Move the caret to the next sentence in the requested direction. + legacyInfo = LegacyWordDocumentTextInfo(self, textInfos.POSITION_CARET) + legacyInfo.move(textInfos.UNIT_SENTENCE, direction) + # Save the start of the sentence for future use + legacyStart = legacyInfo.copy() + # With the legacy object model, + # Move the caret to the end of the new sentence. + legacyInfo.move(textInfos.UNIT_SENTENCE, 1) + legacyInfo.updateCaret() + # Fetch the caret position (end of the next sentence) with UI automation. + endInfo = self.makeTextInfo(textInfos.POSITION_CARET) + # Move the caret back to the start of the next sentence, + # where it should be left for the user. + legacyStart.updateCaret() + # Fetch the new caret position (start of the next sentence) with UI Automation. + startInfo = self.makeTextInfo(textInfos.POSITION_CARET) + # Make a UI automation text range spanning the entire next sentence. + info = startInfo.copy() + info.end = endInfo.end + # Speak the sentence moved to + speech.speakTextInfo(info, unit=textInfos.UNIT_SENTENCE, reason=controlTypes.OutputReason.CARET) + # Forget the word currently being typed as the user has moved the caret somewhere else. + speech.clearTypedWordBuffer() + # Alert review and braille the caret has moved to its new position + review.handleCaretMove(info) + braille.handler.handleCaretMove(self) + @script( gesture="kb:NVDA+alt+c", # Translators: a description for a script that reports the comment at the caret. diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index 12278974051..6e5e109ed9d 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -52,6 +52,7 @@ If you need this functionality please assign a gesture to the appropriate script - Input with literary braille tables should behave more reliably when in edit fields. (#12667) - When navigating the Windows system tray calendar, NVDA now reports the day of the week in full. (#12757) - When using a Chinese input method such as Taiwan - Microsoft Quick in Microsoft Word, scrolling the braille display forward and backward no longer incorrectly keeps jumping back to the original caret position. (#12855) +- When accessing Microsoft Word documents via UIA, navigating by sentence (alt+downArrow / alt+upArrow) is again possible. (#9254) -