We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
NVDA not able to read the checkbox/radio button status in case of static non interactive(print form) pdf
<!-- 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:
Open a static non interactive pdf containing checkbox. Try to read the state of checkbox using NVDA.
### Actual behavior:
NVDA does not read check/not checked
### Expected behavior:
NVDA  should speak checkbox checked(if checked) or vise versa
### System configuration
windows 10, pdf 1.7
#### NVDA installed/portable/running from source:

#### NVDA version:
NVDA 2020.4
#### Windows version:
windows 10
#### Name and version of other software in use when reproducing the issue:
Adobe Acrobat dc pro
#### Other information about your system:

### Other questions
####Is the issue reproducible for interactive static pdf as well? 
No

###Is the issue reproducible on Jaws?
NO 
[output_non.pdf](https://github.com/nvaccess/nvda/files/7958484/output_non.pdf)

#### Does the issue still occur after restarting your computer?
yes
#### Have you tried any other versions of NVDA? If so, please report their behaviors.

#### 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?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `source/NVDAObjects/IAccessible/adobeAcrobat.py`
Content:
```
1 #braille.py
2 #A part of NonVisual Desktop Access (NVDA)
3 #Copyright (C) 2008-2014 NV Access Limited
4 #This file is covered by the GNU General Public License.
5 #See the file COPYING for more details.
6 import typing
7 
8 import api
9 import controlTypes
10 import eventHandler
11 import winUser
12 from . import IAccessible, getNVDAObjectFromEvent
13 from NVDAObjects import NVDAObjectTextInfo
14 from NVDAObjects.behaviors import EditableText
15 from comtypes import GUID, COMError, IServiceProvider
16 from comtypes.gen.AcrobatAccessLib import IAccID, IGetPDDomNode, IPDDomElement
17 from logHandler import log
18 
19 SID_AccID = GUID("{449D454B-1F46-497e-B2B6-3357AED9912B}")
20 SID_GetPDDomNode = GUID("{C0A1D5E9-1142-4cf3-B607-82FC3B96A4DF}")
21 
22 stdNamesToRoles = {
23 	# Part? Art?
24 	"Sect": controlTypes.Role.SECTION,
25 	"Div": controlTypes.Role.SECTION,
26 	"BlockQuote": controlTypes.Role.BLOCKQUOTE,
27 	"Caption": controlTypes.Role.CAPTION,
28 	# Toc? Toci? Index? Nonstruct? Private? 
29 	# Table, TR, TH, TD covered by IAccessible
30 	"L": controlTypes.Role.LIST,
31 	"LI": controlTypes.Role.LISTITEM,
32 	"Lbl": controlTypes.Role.LABEL,
33 	# LBody
34 	"P": controlTypes.Role.PARAGRAPH,
35 	"H": controlTypes.Role.HEADING,
36 	# H1 to H6 handled separately
37 	# Span, Quote, Note, Reference, BibEntry, Code, Figure
38 	"Formula": controlTypes.Role.MATH,
39 	"Form": controlTypes.Role.FORM,
40 }
41 
42 
43 def normalizeStdName(stdName: str) -> typing.Tuple[controlTypes.Role, typing.Optional[str]]:
44 	"""
45 	@param stdName:
46 	@return: Tuple with the NVDA role and optionally the level number of the heading as a string, E.G.:
47 	"H5" produces "5"
48 	"""
49 	if stdName and "H1" <= stdName <= "H6":
50 		return controlTypes.Role.HEADING, stdName[1]
51 
52 	try:
53 		return stdNamesToRoles[stdName], None
54 	except KeyError:
55 		pass
56 
57 	raise LookupError
58 
59 class AcrobatNode(IAccessible):
60 
61 	def initOverlayClass(self):
62 		try:
63 			serv = self.IAccessibleObject.QueryInterface(IServiceProvider)
64 		except COMError:
65 			log.debugWarning("Could not get IServiceProvider")
66 			return
67 
68 		if self.event_objectID is not None and self.event_objectID > 0:
69 			self.accID = self.event_objectID
70 		elif self.event_childID is not None and self.event_childID > 0:
71 			self.accID = self.event_childID
72 		else:
73 			try:
74 				self.accID = serv.QueryService(SID_AccID, IAccID).get_accID()
75 			except COMError:
76 				self.accID = None
77 
78 		# Get the IPDDomNode.
79 		try:
80 			self.pdDomNode = serv.QueryService(SID_GetPDDomNode, IGetPDDomNode).get_PDDomNode(self.IAccessibleChildID)
81 		except COMError:
82 			self.pdDomNode = None
83 
84 		if self.pdDomNode:
85 			# If this node has IPDDomElement, query to that.
86 			try:
87 				self.pdDomNode = self.pdDomNode.QueryInterface(IPDDomElement)
88 			except COMError:
89 				pass
90 
91 	def _get_role(self):
92 		try:
93 			return normalizeStdName(self.pdDomNode.GetStdName())[0]
94 		except (AttributeError, LookupError, COMError):
95 			pass
96 
97 		role = super(AcrobatNode, self).role
98 		if role == controlTypes.Role.PANE:
99 			# Pane doesn't make sense for nodes in a document.
100 			role = controlTypes.Role.TEXTFRAME
101 		return role
102 
103 	def scrollIntoView(self):
104 		try:
105 			self.pdDomNode.ScrollTo()
106 		except (AttributeError, COMError):
107 			log.debugWarning("IPDDomNode::ScrollTo failed", exc_info=True)
108 
109 	def _isEqual(self, other):
110 		if self.windowHandle == other.windowHandle and self.accID and other.accID:
111 			return self.accID == other.accID
112 		return super(AcrobatNode, self)._isEqual(other)
113 
114 	def _getNodeMathMl(self, node):
115 		tag = node.GetTagName()
116 		yield "<%s" % tag
117 		# Output relevant attributes.
118 		if tag == "mfenced":
119 			for attr in "open", "close", "separators":
120 				val = node.GetAttribute(attr, "XML-1.00")
121 				if val:
122 					yield ' %s="%s"' % (attr, val)
123 		yield ">"
124 		val = node.GetValue()
125 		if val:
126 			yield val
127 		else:
128 			for childNum in range(node.GetChildCount()):
129 				try:
130 					subNode = node.GetChild(childNum).QueryInterface(IPDDomElement)
131 				except COMError:
132 					continue
133 				for sub in self._getNodeMathMl(subNode):
134 					yield sub
135 		yield "</%s>" % tag
136 
137 	def _get_mathMl(self):
138 		# There could be other stuff before the math element. Ug.
139 		for childNum in range(self.pdDomNode.GetChildCount()):
140 			try:
141 				child = self.pdDomNode.GetChild(childNum).QueryInterface(IPDDomElement)
142 			except COMError:
143 				continue
144 			if child.GetTagName() == "math":
145 				return "".join(self._getNodeMathMl(child))
146 		raise LookupError
147 
148 class RootNode(AcrobatNode):
149 	shouldAllowIAccessibleFocusEvent = True
150 
151 	def event_valueChange(self):
152 		# Acrobat has indicated that a page has died and been replaced by a new one.
153 		if not self.isInForeground:
154 			# If this isn't in the foreground, it doesn't matter,
155 			# as focus will be fired on the correct object when it is in the foreground again.
156 			return
157 		# The new page has the same event params, so we must bypass NVDA's IAccessible caching.
158 		obj = getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0)
159 		if not obj:
160 			return
161 		eventHandler.queueEvent("gainFocus",obj)
162 
163 class Document(RootNode):
164 
165 	def _get_treeInterceptorClass(self):
166 		import virtualBuffers.adobeAcrobat
167 		return virtualBuffers.adobeAcrobat.AdobeAcrobat
168 
169 	def _get_shouldAllowIAccessibleFocusEvent(self):
170 		# HACK: #1659: When moving the focus, Acrobat sometimes fires focus on the document before firing it on the real focus;
171 		# e.g. when tabbing through a multi-page form.
172 		# This causes extraneous verbosity.
173 		# Therefore, if already focused inside this document, only allow focus on the document if it has no active descendant.
174 		if api.getFocusObject().windowHandle == self.windowHandle:
175 			try:
176 				return self.IAccessibleObject.accFocus in (None, 0)
177 			except COMError:
178 				pass
179 		return super(Document, self).shouldAllowIAccessibleFocusEvent
180 
181 class RootTextNode(RootNode):
182 	"""The message text node that appears instead of the document when the document is not available.
183 	"""
184 
185 	def _get_parent(self):
186 		#hack: This code should be taken out once the crash is fixed in Adobe Reader X.
187 		#If going parent on a root text node after saying ok to the accessibility options (untagged) and before the processing document dialog appears, Reader X will crash.
188 		return api.getDesktopObject()
189 
190 class AcrobatTextInfo(NVDAObjectTextInfo):
191 
192 	def _getStoryText(self):
193 		return self.obj.value or ""
194 
195 	def _getCaretOffset(self):
196 		caret = getNVDAObjectFromEvent(self.obj.windowHandle, winUser.OBJID_CARET, 0)
197 		if not caret:
198 			raise RuntimeError("No caret")
199 		try:
200 			return int(caret.description)
201 		except (ValueError, TypeError):
202 			raise RuntimeError("Bad caret index")
203 
204 class EditableTextNode(EditableText, AcrobatNode):
205 	TextInfo = AcrobatTextInfo
206 
207 	def event_valueChange(self):
208 		pass
209 
210 class AcrobatSDIWindowClient(IAccessible):
211 
212 	def initOverlayClass(self):
213 		if self.name or not self.parent:
214 			return
215 		# HACK: There are three client objects, one with a name and two without.
216 		# The unnamed objects (probably manufactured by Acrobat) have broken next and previous relationships.
217 		# The unnamed objects' parent/grandparent is the named object, but when descending into the named object, the unnamed objects are skipped.
218 		# Given the brokenness of the unnamed objects, just skip them completely and use the parent/grandparent when they are encountered.
219 		try:
220 			acc = self.IAccessibleObject.accParent
221 			if not acc.accName(0):
222 				acc = acc.accParent
223 		except COMError:
224 			return
225 		self.IAccessibleObject = acc
226 		self.invalidateCache()
227 
228 class BadFocusStates(AcrobatNode):
229 	"""An object which reports focus states when it shouldn't.
230 	"""
231 
232 	def _get_states(self):
233 		states = super(BadFocusStates, self).states
234 		states.difference_update({controlTypes.State.FOCUSABLE, controlTypes.State.FOCUSED})
235 		return states
236 
237 def findExtraOverlayClasses(obj, clsList):
238 	"""Determine the most appropriate class(es) for Acrobat objects.
239 	This works similarly to L{NVDAObjects.NVDAObject.findOverlayClasses} except that it never calls any other findOverlayClasses method.
240 	"""
241 	role = obj.role
242 	states = obj.states
243 	if role == controlTypes.Role.DOCUMENT or (role == controlTypes.Role.PAGE and controlTypes.State.READONLY in states):
244 		clsList.append(Document)
245 	elif obj.event_childID == 0 and obj.event_objectID == winUser.OBJID_CLIENT:
246 		# Other root node.
247 		if role == controlTypes.Role.EDITABLETEXT:
248 			clsList.append(RootTextNode)
249 		else:
250 			clsList.append(RootNode)
251 
252 	elif role == controlTypes.Role.EDITABLETEXT:
253 		if {controlTypes.State.READONLY, controlTypes.State.FOCUSABLE, controlTypes.State.LINKED} <= states:
254 			# HACK: Acrobat sets focus states on text nodes beneath links,
255 			# making them appear as read only editable text fields.
256 			clsList.append(BadFocusStates)
257 		elif controlTypes.State.FOCUSABLE in states:
258 			clsList.append(EditableTextNode)
259 
260 	clsList.append(AcrobatNode)
261
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/source/NVDAObjects/IAccessible/adobeAcrobat.py b/source/NVDAObjects/IAccessible/adobeAcrobat.py
--- a/source/NVDAObjects/IAccessible/adobeAcrobat.py
+++ b/source/NVDAObjects/IAccessible/adobeAcrobat.py
@@ -36,7 +36,7 @@
 	# H1 to H6 handled separately
 	# Span, Quote, Note, Reference, BibEntry, Code, Figure
 	"Formula": controlTypes.Role.MATH,
-	"Form": controlTypes.Role.FORM,
+	# form: a form field - MSAA roles are already much more specific here.
 }

{"golden_diff": "diff --git a/source/NVDAObjects/IAccessible/adobeAcrobat.py b/source/NVDAObjects/IAccessible/adobeAcrobat.py\n--- a/source/NVDAObjects/IAccessible/adobeAcrobat.py\n+++ b/source/NVDAObjects/IAccessible/adobeAcrobat.py\n@@ -36,7 +36,7 @@\n \t# H1 to H6 handled separately\r\n \t# Span, Quote, Note, Reference, BibEntry, Code, Figure\r\n \t\"Formula\": controlTypes.Role.MATH,\r\n-\t\"Form\": controlTypes.Role.FORM,\r\n+\t# form: a form field - MSAA roles are already much more specific here.\r\n }\n", "issue": "NVDA not able to read the checkbox/radio button status in case of static non interactive(print form) pdf\n<!-- Please read the text in this edit field before filling it in.\r\nPlease thoroughly read NVDA's wiki article on how to fill in this template, including how to provide the required files.\r\nIssues may be closed if the required information is not present.\r\nhttps://github.com/nvaccess/nvda/blob/master/devDocs/githubIssueTemplateExplanationAndExamples.md\r\nPlease 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. \r\n\r\nEach of the questions and sections below start with multiple hash symbols (#). Place your answers and information on the blank line below each question.\r\n-->\r\n\r\n### Steps to reproduce:\r\nOpen a static non interactive pdf containing checkbox. Try to read the state of checkbox using NVDA.\r\n### Actual behavior:\r\nNVDA does not read check/not checked\r\n### Expected behavior:\r\nNVDA  should speak checkbox checked(if checked) or vise versa\r\n### System configuration\r\nwindows 10, pdf 1.7\r\n#### NVDA installed/portable/running from source:\r\n\r\n#### NVDA version:\r\nNVDA 2020.4\r\n#### Windows version:\r\nwindows 10\r\n#### Name and version of other software in use when reproducing the issue:\r\nAdobe Acrobat dc pro\r\n#### Other information about your system:\r\n\r\n### Other questions\r\n####Is the issue reproducible for interactive static pdf as well? \r\nNo\r\n\r\n###Is the issue reproducible on Jaws?\r\nNO \r\n[output_non.pdf](https://github.com/nvaccess/nvda/files/7958484/output_non.pdf)\r\n\r\n#### Does the issue still occur after restarting your computer?\r\nyes\r\n#### Have you tried any other versions of NVDA? If so, please report their behaviors.\r\n\r\n#### If NVDA add-ons are disabled, is your problem still occurring?\r\n\r\n#### Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?\r\n\n", "before_files": [{"content": "#braille.py\r\n#A part of NonVisual Desktop Access (NVDA)\r\n#Copyright (C) 2008-2014 NV Access Limited\r\n#This file is covered by the GNU General Public License.\r\n#See the file COPYING for more details.\r\nimport typing\r\n\r\nimport api\r\nimport controlTypes\r\nimport eventHandler\r\nimport winUser\r\nfrom . import IAccessible, getNVDAObjectFromEvent\r\nfrom NVDAObjects import NVDAObjectTextInfo\r\nfrom NVDAObjects.behaviors import EditableText\r\nfrom comtypes import GUID, COMError, IServiceProvider\r\nfrom comtypes.gen.AcrobatAccessLib import IAccID, IGetPDDomNode, IPDDomElement\r\nfrom logHandler import log\r\n\r\nSID_AccID = GUID(\"{449D454B-1F46-497e-B2B6-3357AED9912B}\")\r\nSID_GetPDDomNode = GUID(\"{C0A1D5E9-1142-4cf3-B607-82FC3B96A4DF}\")\r\n\r\nstdNamesToRoles = {\r\n\t# Part? Art?\r\n\t\"Sect\": controlTypes.Role.SECTION,\r\n\t\"Div\": controlTypes.Role.SECTION,\r\n\t\"BlockQuote\": controlTypes.Role.BLOCKQUOTE,\r\n\t\"Caption\": controlTypes.Role.CAPTION,\r\n\t# Toc? Toci? Index? Nonstruct? Private? \r\n\t# Table, TR, TH, TD covered by IAccessible\r\n\t\"L\": controlTypes.Role.LIST,\r\n\t\"LI\": controlTypes.Role.LISTITEM,\r\n\t\"Lbl\": controlTypes.Role.LABEL,\r\n\t# LBody\r\n\t\"P\": controlTypes.Role.PARAGRAPH,\r\n\t\"H\": controlTypes.Role.HEADING,\r\n\t# H1 to H6 handled separately\r\n\t# Span, Quote, Note, Reference, BibEntry, Code, Figure\r\n\t\"Formula\": controlTypes.Role.MATH,\r\n\t\"Form\": controlTypes.Role.FORM,\r\n}\r\n\r\n\r\ndef normalizeStdName(stdName: str) -> typing.Tuple[controlTypes.Role, typing.Optional[str]]:\r\n\t\"\"\"\r\n\t@param stdName:\r\n\t@return: Tuple with the NVDA role and optionally the level number of the heading as a string, E.G.:\r\n\t\"H5\" produces \"5\"\r\n\t\"\"\"\r\n\tif stdName and \"H1\" <= stdName <= \"H6\":\r\n\t\treturn controlTypes.Role.HEADING, stdName[1]\r\n\r\n\ttry:\r\n\t\treturn stdNamesToRoles[stdName], None\r\n\texcept KeyError:\r\n\t\tpass\r\n\r\n\traise LookupError\r\n\r\nclass AcrobatNode(IAccessible):\r\n\r\n\tdef initOverlayClass(self):\r\n\t\ttry:\r\n\t\t\tserv = self.IAccessibleObject.QueryInterface(IServiceProvider)\r\n\t\texcept COMError:\r\n\t\t\tlog.debugWarning(\"Could not get IServiceProvider\")\r\n\t\t\treturn\r\n\r\n\t\tif self.event_objectID is not None and self.event_objectID > 0:\r\n\t\t\tself.accID = self.event_objectID\r\n\t\telif self.event_childID is not None and self.event_childID > 0:\r\n\t\t\tself.accID = self.event_childID\r\n\t\telse:\r\n\t\t\ttry:\r\n\t\t\t\tself.accID = serv.QueryService(SID_AccID, IAccID).get_accID()\r\n\t\t\texcept COMError:\r\n\t\t\t\tself.accID = None\r\n\r\n\t\t# Get the IPDDomNode.\r\n\t\ttry:\r\n\t\t\tself.pdDomNode = serv.QueryService(SID_GetPDDomNode, IGetPDDomNode).get_PDDomNode(self.IAccessibleChildID)\r\n\t\texcept COMError:\r\n\t\t\tself.pdDomNode = None\r\n\r\n\t\tif self.pdDomNode:\r\n\t\t\t# If this node has IPDDomElement, query to that.\r\n\t\t\ttry:\r\n\t\t\t\tself.pdDomNode = self.pdDomNode.QueryInterface(IPDDomElement)\r\n\t\t\texcept COMError:\r\n\t\t\t\tpass\r\n\r\n\tdef _get_role(self):\r\n\t\ttry:\r\n\t\t\treturn normalizeStdName(self.pdDomNode.GetStdName())[0]\r\n\t\texcept (AttributeError, LookupError, COMError):\r\n\t\t\tpass\r\n\r\n\t\trole = super(AcrobatNode, self).role\r\n\t\tif role == controlTypes.Role.PANE:\r\n\t\t\t# Pane doesn't make sense for nodes in a document.\r\n\t\t\trole = controlTypes.Role.TEXTFRAME\r\n\t\treturn role\r\n\r\n\tdef scrollIntoView(self):\r\n\t\ttry:\r\n\t\t\tself.pdDomNode.ScrollTo()\r\n\t\texcept (AttributeError, COMError):\r\n\t\t\tlog.debugWarning(\"IPDDomNode::ScrollTo failed\", exc_info=True)\r\n\r\n\tdef _isEqual(self, other):\r\n\t\tif self.windowHandle == other.windowHandle and self.accID and other.accID:\r\n\t\t\treturn self.accID == other.accID\r\n\t\treturn super(AcrobatNode, self)._isEqual(other)\r\n\r\n\tdef _getNodeMathMl(self, node):\r\n\t\ttag = node.GetTagName()\r\n\t\tyield \"<%s\" % tag\r\n\t\t# Output relevant attributes.\r\n\t\tif tag == \"mfenced\":\r\n\t\t\tfor attr in \"open\", \"close\", \"separators\":\r\n\t\t\t\tval = node.GetAttribute(attr, \"XML-1.00\")\r\n\t\t\t\tif val:\r\n\t\t\t\t\tyield ' %s=\"%s\"' % (attr, val)\r\n\t\tyield \">\"\r\n\t\tval = node.GetValue()\r\n\t\tif val:\r\n\t\t\tyield val\r\n\t\telse:\r\n\t\t\tfor childNum in range(node.GetChildCount()):\r\n\t\t\t\ttry:\r\n\t\t\t\t\tsubNode = node.GetChild(childNum).QueryInterface(IPDDomElement)\r\n\t\t\t\texcept COMError:\r\n\t\t\t\t\tcontinue\r\n\t\t\t\tfor sub in self._getNodeMathMl(subNode):\r\n\t\t\t\t\tyield sub\r\n\t\tyield \"</%s>\" % tag\r\n\r\n\tdef _get_mathMl(self):\r\n\t\t# There could be other stuff before the math element. Ug.\r\n\t\tfor childNum in range(self.pdDomNode.GetChildCount()):\r\n\t\t\ttry:\r\n\t\t\t\tchild = self.pdDomNode.GetChild(childNum).QueryInterface(IPDDomElement)\r\n\t\t\texcept COMError:\r\n\t\t\t\tcontinue\r\n\t\t\tif child.GetTagName() == \"math\":\r\n\t\t\t\treturn \"\".join(self._getNodeMathMl(child))\r\n\t\traise LookupError\r\n\r\nclass RootNode(AcrobatNode):\r\n\tshouldAllowIAccessibleFocusEvent = True\r\n\r\n\tdef event_valueChange(self):\r\n\t\t# Acrobat has indicated that a page has died and been replaced by a new one.\r\n\t\tif not self.isInForeground:\r\n\t\t\t# If this isn't in the foreground, it doesn't matter,\r\n\t\t\t# as focus will be fired on the correct object when it is in the foreground again.\r\n\t\t\treturn\r\n\t\t# The new page has the same event params, so we must bypass NVDA's IAccessible caching.\r\n\t\tobj = getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0)\r\n\t\tif not obj:\r\n\t\t\treturn\r\n\t\teventHandler.queueEvent(\"gainFocus\",obj)\r\n\r\nclass Document(RootNode):\r\n\r\n\tdef _get_treeInterceptorClass(self):\r\n\t\timport virtualBuffers.adobeAcrobat\r\n\t\treturn virtualBuffers.adobeAcrobat.AdobeAcrobat\r\n\r\n\tdef _get_shouldAllowIAccessibleFocusEvent(self):\r\n\t\t# HACK: #1659: When moving the focus, Acrobat sometimes fires focus on the document before firing it on the real focus;\r\n\t\t# e.g. when tabbing through a multi-page form.\r\n\t\t# This causes extraneous verbosity.\r\n\t\t# Therefore, if already focused inside this document, only allow focus on the document if it has no active descendant.\r\n\t\tif api.getFocusObject().windowHandle == self.windowHandle:\r\n\t\t\ttry:\r\n\t\t\t\treturn self.IAccessibleObject.accFocus in (None, 0)\r\n\t\t\texcept COMError:\r\n\t\t\t\tpass\r\n\t\treturn super(Document, self).shouldAllowIAccessibleFocusEvent\r\n\r\nclass RootTextNode(RootNode):\r\n\t\"\"\"The message text node that appears instead of the document when the document is not available.\r\n\t\"\"\"\r\n\r\n\tdef _get_parent(self):\r\n\t\t#hack: This code should be taken out once the crash is fixed in Adobe Reader X.\r\n\t\t#If going parent on a root text node after saying ok to the accessibility options (untagged) and before the processing document dialog appears, Reader X will crash.\r\n\t\treturn api.getDesktopObject()\r\n\r\nclass AcrobatTextInfo(NVDAObjectTextInfo):\r\n\r\n\tdef _getStoryText(self):\r\n\t\treturn self.obj.value or \"\"\r\n\r\n\tdef _getCaretOffset(self):\r\n\t\tcaret = getNVDAObjectFromEvent(self.obj.windowHandle, winUser.OBJID_CARET, 0)\r\n\t\tif not caret:\r\n\t\t\traise RuntimeError(\"No caret\")\r\n\t\ttry:\r\n\t\t\treturn int(caret.description)\r\n\t\texcept (ValueError, TypeError):\r\n\t\t\traise RuntimeError(\"Bad caret index\")\r\n\r\nclass EditableTextNode(EditableText, AcrobatNode):\r\n\tTextInfo = AcrobatTextInfo\r\n\r\n\tdef event_valueChange(self):\r\n\t\tpass\r\n\r\nclass AcrobatSDIWindowClient(IAccessible):\r\n\r\n\tdef initOverlayClass(self):\r\n\t\tif self.name or not self.parent:\r\n\t\t\treturn\r\n\t\t# HACK: There are three client objects, one with a name and two without.\r\n\t\t# The unnamed objects (probably manufactured by Acrobat) have broken next and previous relationships.\r\n\t\t# The unnamed objects' parent/grandparent is the named object, but when descending into the named object, the unnamed objects are skipped.\r\n\t\t# Given the brokenness of the unnamed objects, just skip them completely and use the parent/grandparent when they are encountered.\r\n\t\ttry:\r\n\t\t\tacc = self.IAccessibleObject.accParent\r\n\t\t\tif not acc.accName(0):\r\n\t\t\t\tacc = acc.accParent\r\n\t\texcept COMError:\r\n\t\t\treturn\r\n\t\tself.IAccessibleObject = acc\r\n\t\tself.invalidateCache()\r\n\r\nclass BadFocusStates(AcrobatNode):\r\n\t\"\"\"An object which reports focus states when it shouldn't.\r\n\t\"\"\"\r\n\r\n\tdef _get_states(self):\r\n\t\tstates = super(BadFocusStates, self).states\r\n\t\tstates.difference_update({controlTypes.State.FOCUSABLE, controlTypes.State.FOCUSED})\r\n\t\treturn states\r\n\r\ndef findExtraOverlayClasses(obj, clsList):\r\n\t\"\"\"Determine the most appropriate class(es) for Acrobat objects.\r\n\tThis works similarly to L{NVDAObjects.NVDAObject.findOverlayClasses} except that it never calls any other findOverlayClasses method.\r\n\t\"\"\"\r\n\trole = obj.role\r\n\tstates = obj.states\r\n\tif role == controlTypes.Role.DOCUMENT or (role == controlTypes.Role.PAGE and controlTypes.State.READONLY in states):\r\n\t\tclsList.append(Document)\r\n\telif obj.event_childID == 0 and obj.event_objectID == winUser.OBJID_CLIENT:\r\n\t\t# Other root node.\r\n\t\tif role == controlTypes.Role.EDITABLETEXT:\r\n\t\t\tclsList.append(RootTextNode)\r\n\t\telse:\r\n\t\t\tclsList.append(RootNode)\r\n\r\n\telif role == controlTypes.Role.EDITABLETEXT:\r\n\t\tif {controlTypes.State.READONLY, controlTypes.State.FOCUSABLE, controlTypes.State.LINKED} <= states:\r\n\t\t\t# HACK: Acrobat sets focus states on text nodes beneath links,\r\n\t\t\t# making them appear as read only editable text fields.\r\n\t\t\tclsList.append(BadFocusStates)\r\n\t\telif controlTypes.State.FOCUSABLE in states:\r\n\t\t\tclsList.append(EditableTextNode)\r\n\r\n\tclsList.append(AcrobatNode)\r\n", "path": "source/NVDAObjects/IAccessible/adobeAcrobat.py"}], "after_files": [{"content": "#braille.py\r\n#A part of NonVisual Desktop Access (NVDA)\r\n#Copyright (C) 2008-2014 NV Access Limited\r\n#This file is covered by the GNU General Public License.\r\n#See the file COPYING for more details.\r\nimport typing\r\n\r\nimport api\r\nimport controlTypes\r\nimport eventHandler\r\nimport winUser\r\nfrom . import IAccessible, getNVDAObjectFromEvent\r\nfrom NVDAObjects import NVDAObjectTextInfo\r\nfrom NVDAObjects.behaviors import EditableText\r\nfrom comtypes import GUID, COMError, IServiceProvider\r\nfrom comtypes.gen.AcrobatAccessLib import IAccID, IGetPDDomNode, IPDDomElement\r\nfrom logHandler import log\r\n\r\nSID_AccID = GUID(\"{449D454B-1F46-497e-B2B6-3357AED9912B}\")\r\nSID_GetPDDomNode = GUID(\"{C0A1D5E9-1142-4cf3-B607-82FC3B96A4DF}\")\r\n\r\nstdNamesToRoles = {\r\n\t# Part? Art?\r\n\t\"Sect\": controlTypes.Role.SECTION,\r\n\t\"Div\": controlTypes.Role.SECTION,\r\n\t\"BlockQuote\": controlTypes.Role.BLOCKQUOTE,\r\n\t\"Caption\": controlTypes.Role.CAPTION,\r\n\t# Toc? Toci? Index? Nonstruct? Private? \r\n\t# Table, TR, TH, TD covered by IAccessible\r\n\t\"L\": controlTypes.Role.LIST,\r\n\t\"LI\": controlTypes.Role.LISTITEM,\r\n\t\"Lbl\": controlTypes.Role.LABEL,\r\n\t# LBody\r\n\t\"P\": controlTypes.Role.PARAGRAPH,\r\n\t\"H\": controlTypes.Role.HEADING,\r\n\t# H1 to H6 handled separately\r\n\t# Span, Quote, Note, Reference, BibEntry, Code, Figure\r\n\t\"Formula\": controlTypes.Role.MATH,\r\n\t# form: a form field - MSAA roles are already much more specific here.\r\n}\r\n\r\n\r\ndef normalizeStdName(stdName: str) -> typing.Tuple[controlTypes.Role, typing.Optional[str]]:\r\n\t\"\"\"\r\n\t@param stdName:\r\n\t@return: Tuple with the NVDA role and optionally the level number of the heading as a string, E.G.:\r\n\t\"H5\" produces \"5\"\r\n\t\"\"\"\r\n\tif stdName and \"H1\" <= stdName <= \"H6\":\r\n\t\treturn controlTypes.Role.HEADING, stdName[1]\r\n\r\n\ttry:\r\n\t\treturn stdNamesToRoles[stdName], None\r\n\texcept KeyError:\r\n\t\tpass\r\n\r\n\traise LookupError\r\n\r\nclass AcrobatNode(IAccessible):\r\n\r\n\tdef initOverlayClass(self):\r\n\t\ttry:\r\n\t\t\tserv = self.IAccessibleObject.QueryInterface(IServiceProvider)\r\n\t\texcept COMError:\r\n\t\t\tlog.debugWarning(\"Could not get IServiceProvider\")\r\n\t\t\treturn\r\n\r\n\t\tif self.event_objectID is not None and self.event_objectID > 0:\r\n\t\t\tself.accID = self.event_objectID\r\n\t\telif self.event_childID is not None and self.event_childID > 0:\r\n\t\t\tself.accID = self.event_childID\r\n\t\telse:\r\n\t\t\ttry:\r\n\t\t\t\tself.accID = serv.QueryService(SID_AccID, IAccID).get_accID()\r\n\t\t\texcept COMError:\r\n\t\t\t\tself.accID = None\r\n\r\n\t\t# Get the IPDDomNode.\r\n\t\ttry:\r\n\t\t\tself.pdDomNode = serv.QueryService(SID_GetPDDomNode, IGetPDDomNode).get_PDDomNode(self.IAccessibleChildID)\r\n\t\texcept COMError:\r\n\t\t\tself.pdDomNode = None\r\n\r\n\t\tif self.pdDomNode:\r\n\t\t\t# If this node has IPDDomElement, query to that.\r\n\t\t\ttry:\r\n\t\t\t\tself.pdDomNode = self.pdDomNode.QueryInterface(IPDDomElement)\r\n\t\t\texcept COMError:\r\n\t\t\t\tpass\r\n\r\n\tdef _get_role(self):\r\n\t\ttry:\r\n\t\t\treturn normalizeStdName(self.pdDomNode.GetStdName())[0]\r\n\t\texcept (AttributeError, LookupError, COMError):\r\n\t\t\tpass\r\n\r\n\t\trole = super(AcrobatNode, self).role\r\n\t\tif role == controlTypes.Role.PANE:\r\n\t\t\t# Pane doesn't make sense for nodes in a document.\r\n\t\t\trole = controlTypes.Role.TEXTFRAME\r\n\t\treturn role\r\n\r\n\tdef scrollIntoView(self):\r\n\t\ttry:\r\n\t\t\tself.pdDomNode.ScrollTo()\r\n\t\texcept (AttributeError, COMError):\r\n\t\t\tlog.debugWarning(\"IPDDomNode::ScrollTo failed\", exc_info=True)\r\n\r\n\tdef _isEqual(self, other):\r\n\t\tif self.windowHandle == other.windowHandle and self.accID and other.accID:\r\n\t\t\treturn self.accID == other.accID\r\n\t\treturn super(AcrobatNode, self)._isEqual(other)\r\n\r\n\tdef _getNodeMathMl(self, node):\r\n\t\ttag = node.GetTagName()\r\n\t\tyield \"<%s\" % tag\r\n\t\t# Output relevant attributes.\r\n\t\tif tag == \"mfenced\":\r\n\t\t\tfor attr in \"open\", \"close\", \"separators\":\r\n\t\t\t\tval = node.GetAttribute(attr, \"XML-1.00\")\r\n\t\t\t\tif val:\r\n\t\t\t\t\tyield ' %s=\"%s\"' % (attr, val)\r\n\t\tyield \">\"\r\n\t\tval = node.GetValue()\r\n\t\tif val:\r\n\t\t\tyield val\r\n\t\telse:\r\n\t\t\tfor childNum in range(node.GetChildCount()):\r\n\t\t\t\ttry:\r\n\t\t\t\t\tsubNode = node.GetChild(childNum).QueryInterface(IPDDomElement)\r\n\t\t\t\texcept COMError:\r\n\t\t\t\t\tcontinue\r\n\t\t\t\tfor sub in self._getNodeMathMl(subNode):\r\n\t\t\t\t\tyield sub\r\n\t\tyield \"</%s>\" % tag\r\n\r\n\tdef _get_mathMl(self):\r\n\t\t# There could be other stuff before the math element. Ug.\r\n\t\tfor childNum in range(self.pdDomNode.GetChildCount()):\r\n\t\t\ttry:\r\n\t\t\t\tchild = self.pdDomNode.GetChild(childNum).QueryInterface(IPDDomElement)\r\n\t\t\texcept COMError:\r\n\t\t\t\tcontinue\r\n\t\t\tif child.GetTagName() == \"math\":\r\n\t\t\t\treturn \"\".join(self._getNodeMathMl(child))\r\n\t\traise LookupError\r\n\r\nclass RootNode(AcrobatNode):\r\n\tshouldAllowIAccessibleFocusEvent = True\r\n\r\n\tdef event_valueChange(self):\r\n\t\t# Acrobat has indicated that a page has died and been replaced by a new one.\r\n\t\tif not self.isInForeground:\r\n\t\t\t# If this isn't in the foreground, it doesn't matter,\r\n\t\t\t# as focus will be fired on the correct object when it is in the foreground again.\r\n\t\t\treturn\r\n\t\t# The new page has the same event params, so we must bypass NVDA's IAccessible caching.\r\n\t\tobj = getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0)\r\n\t\tif not obj:\r\n\t\t\treturn\r\n\t\teventHandler.queueEvent(\"gainFocus\",obj)\r\n\r\nclass Document(RootNode):\r\n\r\n\tdef _get_treeInterceptorClass(self):\r\n\t\timport virtualBuffers.adobeAcrobat\r\n\t\treturn virtualBuffers.adobeAcrobat.AdobeAcrobat\r\n\r\n\tdef _get_shouldAllowIAccessibleFocusEvent(self):\r\n\t\t# HACK: #1659: When moving the focus, Acrobat sometimes fires focus on the document before firing it on the real focus;\r\n\t\t# e.g. when tabbing through a multi-page form.\r\n\t\t# This causes extraneous verbosity.\r\n\t\t# Therefore, if already focused inside this document, only allow focus on the document if it has no active descendant.\r\n\t\tif api.getFocusObject().windowHandle == self.windowHandle:\r\n\t\t\ttry:\r\n\t\t\t\treturn self.IAccessibleObject.accFocus in (None, 0)\r\n\t\t\texcept COMError:\r\n\t\t\t\tpass\r\n\t\treturn super(Document, self).shouldAllowIAccessibleFocusEvent\r\n\r\nclass RootTextNode(RootNode):\r\n\t\"\"\"The message text node that appears instead of the document when the document is not available.\r\n\t\"\"\"\r\n\r\n\tdef _get_parent(self):\r\n\t\t#hack: This code should be taken out once the crash is fixed in Adobe Reader X.\r\n\t\t#If going parent on a root text node after saying ok to the accessibility options (untagged) and before the processing document dialog appears, Reader X will crash.\r\n\t\treturn api.getDesktopObject()\r\n\r\nclass AcrobatTextInfo(NVDAObjectTextInfo):\r\n\r\n\tdef _getStoryText(self):\r\n\t\treturn self.obj.value or \"\"\r\n\r\n\tdef _getCaretOffset(self):\r\n\t\tcaret = getNVDAObjectFromEvent(self.obj.windowHandle, winUser.OBJID_CARET, 0)\r\n\t\tif not caret:\r\n\t\t\traise RuntimeError(\"No caret\")\r\n\t\ttry:\r\n\t\t\treturn int(caret.description)\r\n\t\texcept (ValueError, TypeError):\r\n\t\t\traise RuntimeError(\"Bad caret index\")\r\n\r\nclass EditableTextNode(EditableText, AcrobatNode):\r\n\tTextInfo = AcrobatTextInfo\r\n\r\n\tdef event_valueChange(self):\r\n\t\tpass\r\n\r\nclass AcrobatSDIWindowClient(IAccessible):\r\n\r\n\tdef initOverlayClass(self):\r\n\t\tif self.name or not self.parent:\r\n\t\t\treturn\r\n\t\t# HACK: There are three client objects, one with a name and two without.\r\n\t\t# The unnamed objects (probably manufactured by Acrobat) have broken next and previous relationships.\r\n\t\t# The unnamed objects' parent/grandparent is the named object, but when descending into the named object, the unnamed objects are skipped.\r\n\t\t# Given the brokenness of the unnamed objects, just skip them completely and use the parent/grandparent when they are encountered.\r\n\t\ttry:\r\n\t\t\tacc = self.IAccessibleObject.accParent\r\n\t\t\tif not acc.accName(0):\r\n\t\t\t\tacc = acc.accParent\r\n\t\texcept COMError:\r\n\t\t\treturn\r\n\t\tself.IAccessibleObject = acc\r\n\t\tself.invalidateCache()\r\n\r\nclass BadFocusStates(AcrobatNode):\r\n\t\"\"\"An object which reports focus states when it shouldn't.\r\n\t\"\"\"\r\n\r\n\tdef _get_states(self):\r\n\t\tstates = super(BadFocusStates, self).states\r\n\t\tstates.difference_update({controlTypes.State.FOCUSABLE, controlTypes.State.FOCUSED})\r\n\t\treturn states\r\n\r\ndef findExtraOverlayClasses(obj, clsList):\r\n\t\"\"\"Determine the most appropriate class(es) for Acrobat objects.\r\n\tThis works similarly to L{NVDAObjects.NVDAObject.findOverlayClasses} except that it never calls any other findOverlayClasses method.\r\n\t\"\"\"\r\n\trole = obj.role\r\n\tstates = obj.states\r\n\tif role == controlTypes.Role.DOCUMENT or (role == controlTypes.Role.PAGE and controlTypes.State.READONLY in states):\r\n\t\tclsList.append(Document)\r\n\telif obj.event_childID == 0 and obj.event_objectID == winUser.OBJID_CLIENT:\r\n\t\t# Other root node.\r\n\t\tif role == controlTypes.Role.EDITABLETEXT:\r\n\t\t\tclsList.append(RootTextNode)\r\n\t\telse:\r\n\t\t\tclsList.append(RootNode)\r\n\r\n\telif role == controlTypes.Role.EDITABLETEXT:\r\n\t\tif {controlTypes.State.READONLY, controlTypes.State.FOCUSABLE, controlTypes.State.LINKED} <= states:\r\n\t\t\t# HACK: Acrobat sets focus states on text nodes beneath links,\r\n\t\t\t# making them appear as read only editable text fields.\r\n\t\t\tclsList.append(BadFocusStates)\r\n\t\telif controlTypes.State.FOCUSABLE in states:\r\n\t\t\tclsList.append(EditableTextNode)\r\n\r\n\tclsList.append(AcrobatNode)\r\n", "path": "source/NVDAObjects/IAccessible/adobeAcrobat.py"}]}