Repository: nvaccess/nvda

Issue:
Enabling UIA Support in Word Causes Paragraph Indentation Not to be Reported
<!-- Please read the text in this edit field before filling it in.
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/blob/master/devDocs/githubIssueTemplateExplanationAndExamples.md
Please also note that the NVDA project has a Citizen and Contributor Code of Conduct which can be found at https://github.com/nvaccess/nvda/blob/master/CODE_OF_CONDUCT.md. NV Access expects that all contributors and other community members read and abide by the rules set out in this document while participating or contributing to this project. This includes creating or commenting on issues and pull requests. 

Each of the questions and sections below start with multiple hash symbols (#). Place your answers and information on the blank line below each question.
-->

### Steps to reproduce:
1. Enable UIA support for Word in NVDA avnaced settings.
2. Open a word document.
3. Locate the indented first line of a paragraph.
4. Optionally, press NVDA+F to report formatting at current location.

### Actual behavior:
When I arrow down to the indented first line of a paragraph, NVDA doesn't announce indentation when UIA is enabled. When UIA is disabled, the problem is resolved. Pressing NVDA+F doesn't help.

### Expected behavior:
NVDA should report indentation when I locate the indented first line of a paragraph.

### System configuration
#### NVDA installed/portable/running from source:
Installed.

#### NVDA version:
2021.2

#### Windows version:
Windows 10 21H1 x64 build 19043.1266

#### Name and version of other software in use when reproducing the issue:
Office 16/365

#### Other information about your system:

### Other questions
#### Does the issue still occur after restarting your computer?
yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
no

#### If NVDA add-ons are disabled, is your problem still occurring?

#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?
yes


Discussion:
Relates to #12770 - cc @michaelDCurran 

Resolving patch:
diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py
--- a/source/NVDAObjects/UIA/__init__.py
+++ b/source/NVDAObjects/UIA/__init__.py
@@ -43,6 +43,12 @@
 import winVersion
 
 
+paragraphIndentIDs = {
+	UIAHandler.UIA_IndentationFirstLineAttributeId: "first-line-indent",
+	UIAHandler.UIA_IndentationLeadingAttributeId: "left-indent",
+	UIAHandler.UIA_IndentationTrailingAttributeId: "right-indent",
+}
+
 class UIATextInfo(textInfos.TextInfo):
 
 	_cache_controlFieldNVDAObjectClass=True
@@ -168,6 +174,8 @@ def _getFormatFieldAtRange(self,textRange,formatConfig,ignoreMixedValues=False):
 					UIAHandler.UIA_IsSuperscriptAttributeId,
 					UIAHandler.UIA_IsSubscriptAttributeId
 				})
+			if formatConfig["reportParagraphIndentation"]:
+				IDs.update(set(paragraphIndentIDs))
 			if formatConfig["reportAlignment"]:
 				IDs.add(UIAHandler.UIA_HorizontalTextAlignmentAttributeId)
 			if formatConfig["reportColor"]:
@@ -223,6 +231,21 @@ def _getFormatFieldAtRange(self,textRange,formatConfig,ignoreMixedValues=False):
 			val=fetcher.getValue(UIAHandler.UIA_StyleNameAttributeId,ignoreMixedValues=ignoreMixedValues)
 			if val!=UIAHandler.handler.reservedNotSupportedValue:
 				formatField["style"]=val
+		if formatConfig["reportParagraphIndentation"]:
+			for ID, fieldAttr in paragraphIndentIDs.items():
+				val = fetcher.getValue(ID, ignoreMixedValues=ignoreMixedValues)
+				if isinstance(val, float):
+					# val is in points (1/72 of an inch)
+					val /= 72.0
+					if languageHandler.useImperialMeasurements():
+						# Translators: a measurement in inches
+						valText = _("{val:.2f} in").format(val=val)
+					else:
+						# Convert from inches to centermetres
+						val *= 2.54
+						# Translators: a measurement in centermetres
+						valText = _("{val:.2f} cm").format(val=val)
+					formatField[fieldAttr] = valText
 		if formatConfig["reportAlignment"]:
 			val=fetcher.getValue(UIAHandler.UIA_HorizontalTextAlignmentAttributeId,ignoreMixedValues=ignoreMixedValues)
 			if val==UIAHandler.HorizontalTextAlignment_Left:
diff --git a/source/languageHandler.py b/source/languageHandler.py
--- a/source/languageHandler.py
+++ b/source/languageHandler.py
@@ -43,6 +43,7 @@ class LOCALE(enum.IntEnum):
 	# https://docs.microsoft.com/en-us/windows/win32/intl/locale-information-constants
 	SLANGUAGE = 0x2
 	SLIST = 0xC
+	IMEASURE = 0xD
 	SLANGDISPLAYNAME = 0x6f
 	SENGLISHLANGUAGENAME = 0x00001001
 	SENGLISHCOUNTRYNAME = 0x00001002
@@ -437,6 +438,18 @@ def normalizeLanguage(lang) -> Optional[str]:
 		ld[1]=ld[1].upper()
 	return "_".join(ld)
 
+
+def useImperialMeasurements() -> bool:
+	"""
+	Whether or not measurements should be reported as imperial, rather than metric.
+	"""
+	bufLength = 2
+	buf = ctypes.create_unicode_buffer(bufLength)
+	if not winKernel.kernel32.GetLocaleInfoEx(None, LOCALE.IMEASURE, buf, bufLength):
+		raise RuntimeError("LOCALE.IMEASURE not supported")
+	return buf.value == '1'
+
+
 # Map Windows primary locale identifiers to locale names
 # Note these are only primary language codes (I.e. no country information)
 # For full locale identifiers we use Python's own locale.windows_locale.


Test patch: