Repository: nvaccess/nvda

Issue:
Unwanted extra speech when shift+tabbing bfrom e-mail body to subject field in MS Outlook
<!--
Please thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.
Issues may be closed if the required information is not present.
https://github.com/nvaccess/nvda/wiki/Github-issue-template-explanation-and-examples
-->

### Steps to reproduce:
* In MS Outlook, open a new message in edition
* Go to message body
* Press shift+tab to go back to subject field

### Actual behavior:
NVDA announces the indent measurement ("0.265 centimètres") and then announces the newly focused subject field.

### Expected behavior:
NVDA announces only the newly focused subject field.

### System configuration

#### NVDA installed/portable/running from source:
Either installed or running from source

#### NVDA version:
NVDA 2019.2 and last alpha

#### Windows version:
Test performed on Windows 10 1709 and Windows 10 1903

#### Name and version of other software in use when reproducing the issue:
Outlook 2016

#### Other information about your system:
Option to use UIA in MS Word ON or OFF; same behavior.

### Other questions
#### Does the issue still occur after restarting your PC?
Yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Same behavior on 2019.2 and alpha



Discussion:

Resolving patch:
diff --git a/source/NVDAObjects/window/winword.py b/source/NVDAObjects/window/winword.py
--- a/source/NVDAObjects/window/winword.py
+++ b/source/NVDAObjects/window/winword.py
@@ -1402,6 +1402,9 @@ def script_tab(self,gesture):
 		* If not in a table, announces the distance of the caret from the left edge of the document, and any remaining text on that line.
 		"""
 		gesture.send()
+		self.reportTab()
+
+	def reportTab(self):
 		selectionObj=self.WinwordSelectionObject
 		inTable=selectionObj.tables.count>0 if selectionObj else False
 		info=self.makeTextInfo(textInfos.POSITION_SELECTION)
diff --git a/source/appModules/outlook.py b/source/appModules/outlook.py
--- a/source/appModules/outlook.py
+++ b/source/appModules/outlook.py
@@ -11,6 +11,7 @@
 import ctypes
 from hwPortUtils import SYSTEMTIME
 import scriptHandler
+from scriptHandler import script
 import winKernel
 import comHelper
 import NVDAHelper
@@ -29,6 +30,7 @@
 import ui
 from NVDAObjects.IAccessible import IAccessible
 from NVDAObjects.window import Window
+from NVDAObjects.window.winword import WordDocument as BaseWordDocument
 from NVDAObjects.IAccessible.winword import WordDocument, WordDocumentTreeInterceptor, BrowseModeWordDocumentTextInfo, WordDocumentTextInfo
 from NVDAObjects.IAccessible.MSHTML import MSHTML
 from NVDAObjects.behaviors import RowWithFakeNavigation, Dialog
@@ -552,7 +554,20 @@ def script_tab(self,gesture):
 		"kb:shift+tab":"tab",
 	}
 
-class OutlookWordDocument(WordDocument):
+
+class BaseOutlookWordDocument(BaseWordDocument):
+
+	@script(gestures=["kb:tab", "kb:shift+tab"])
+	def script_tab(self, gesture):
+		bookmark = self.makeTextInfo(textInfos.POSITION_SELECTION).bookmark
+		gesture.send()
+		info, caretMoved = self._hasCaretMoved(bookmark)
+		if not caretMoved:
+			return
+		self.reportTab()
+
+
+class OutlookWordDocument(WordDocument, BaseOutlookWordDocument):
 
 	def _get_isReadonlyViewer(self):
 		# #2975: The only way we know an email is read-only is if the underlying email has been sent.
@@ -575,7 +590,8 @@ def _get_role(self):
 	ignoreEditorRevisions=True
 	ignorePageNumbers=True # This includes page sections, and page columns. None of which are appropriate for outlook.
 
-class OutlookUIAWordDocument(UIAWordDocument):
+
+class OutlookUIAWordDocument(UIAWordDocument, BaseOutlookWordDocument):
 	""" Forces browse mode to be used on the UI Automation Outlook message viewer if the message is being read)."""
 
 	def _get_isReadonlyViewer(self):


Test patch: