| Trees | Indices | Help |
|---|
|
|
1 import api
2 import controlTypes
3 import eventHandler
4 import winUser
5 from . import IAccessible, getNVDAObjectFromEvent
6 from NVDAObjects import NVDAObjectTextInfo
7 from NVDAObjects.behaviors import EditableText
8 from comtypes import GUID, COMError, IServiceProvider
9 from comtypes.gen.AcrobatAccessLib import IAccID, IGetPDDomNode, IPDDomElement
10 from logHandler import log
11
12 SID_AccID = GUID("{449D454B-1F46-497e-B2B6-3357AED9912B}")
13 SID_GetPDDomNode = GUID("{C0A1D5E9-1142-4cf3-B607-82FC3B96A4DF}")
14
15 stdNamesToRoles = {
16 # Part? Art?
17 "Sect": controlTypes.ROLE_SECTION,
18 "Div": controlTypes.ROLE_SECTION,
19 "BlockQuote": controlTypes.ROLE_BLOCKQUOTE,
20 "Caption": controlTypes.ROLE_CAPTION,
21 # Toc? Toci? Index? Nonstruct? Private?
22 # Table, TR, TH, TD covered by IAccessible
23 "L": controlTypes.ROLE_LIST,
24 "LI": controlTypes.ROLE_LISTITEM,
25 "Lbl": controlTypes.ROLE_LABEL,
26 # LBody
27 "P": controlTypes.ROLE_PARAGRAPH,
28 "H": controlTypes.ROLE_HEADING,
29 # H1 to H6 handled separately
30 # Span, Quote, Note, Reference, BibEntry, Code, Figure, Formula
31 "Form": controlTypes.ROLE_FORM,
32 }
33
35 if "H1" <= stdName <= "H6":
36 return controlTypes.ROLE_HEADING, stdName[1]
37
38 try:
39 return stdNamesToRoles[stdName], None
40 except KeyError:
41 pass
42
43 raise LookupError
44
46
48 try:
49 serv = self.IAccessibleObject.QueryInterface(IServiceProvider)
50 except COMError:
51 log.debugWarning("Could not get IServiceProvider")
52 return
53
54 if self.event_objectID > 0:
55 self.accID = self.event_objectID
56 elif self.event_childID > 0:
57 self.accID = self.event_childID
58 else:
59 try:
60 self.accID = serv.QueryService(SID_AccID, IAccID).get_accID()
61 except COMError:
62 log.debugWarning("Failed to get ID from IAccID", exc_info=True)
63 self.accID = None
64
65 # Get the IPDDomNode.
66 try:
67 self.pdDomNode = serv.QueryService(SID_GetPDDomNode, IGetPDDomNode).get_PDDomNode(self.IAccessibleChildID)
68 except COMError:
69 self.pdDomNode = None
70 log.debugWarning("Error getting IPDDomNode")
71
72 if self.pdDomNode:
73 # If this node has IPDDomElement, query to that.
74 try:
75 self.pdDomNode = self.pdDomNode.QueryInterface(IPDDomElement)
76 except COMError:
77 pass
78
80 try:
81 return normalizeStdName(self.pdDomNode.GetStdName())[0]
82 except (AttributeError, LookupError, COMError):
83 pass
84
85 role = super(AcrobatNode, self).role
86 if role == controlTypes.ROLE_PANE:
87 # Pane doesn't make sense for nodes in a document.
88 role = controlTypes.ROLE_TEXTFRAME
89 return role
90
92 try:
93 self.pdDomNode.ScrollTo()
94 except (AttributeError, COMError):
95 log.debugWarning("IPDDomNode::ScrollTo failed", exc_info=True)
96
98 if self.windowHandle == other.windowHandle and self.accID and other.accID:
99 return self.accID == other.accID
100 return super(AcrobatNode, self)._isEqual(other)
101
103 shouldAllowIAccessibleFocusEvent = True
104
106 # Acrobat has indicated that a page has died and been replaced by a new one.
107 if not self.isInForeground:
108 # If this isn't in the foreground, it doesn't matter,
109 # as focus will be fired on the correct object when it is in the foreground again.
110 return
111 # The new page has the same event params, so we must bypass NVDA's IAccessible caching.
112 obj = getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0)
113 if not obj:
114 return
115 eventHandler.queueEvent("gainFocus",obj)
116
118
122
124 # HACK: #1659: When moving the focus, Acrobat sometimes fires focus on the document before firing it on the real focus;
125 # e.g. when tabbing through a multi-page form.
126 # This causes extraneous verbosity.
127 # Therefore, if already focused inside this document, only allow focus on the document if it has no active descendant.
128 if api.getFocusObject().windowHandle == self.windowHandle:
129 try:
130 return self.IAccessibleObject.accFocus in (None, 0)
131 except COMError:
132 pass
133 return super(Document, self).shouldAllowIAccessibleFocusEvent
134
136 """The message text node that appears instead of the document when the document is not available.
137 """
138
140 #hack: This code should be taken out once the crash is fixed in Adobe Reader X.
141 #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.
142 return api.getDesktopObject()
143
145
147 return self.obj.value or ""
148
150 caret = getNVDAObjectFromEvent(self.obj.windowHandle, winUser.OBJID_CARET, 0)
151 if not caret:
152 raise RuntimeError("No caret")
153 try:
154 return int(caret.description)
155 except (ValueError, TypeError):
156 raise RuntimeError("Bad caret index")
157
163
165
167 super(AcrobatSDIWindowClient, self).__init__(**kwargs)
168 if not self.name and self.parent:
169 # There are two client objects, one with a name and one without.
170 # The unnamed object (probably manufactured by Acrobat) has broken next and previous relationships.
171 # The unnamed object's parent is the named object, but when descending into the named object, the unnamed object is skipped.
172 # Given the brokenness of the unnamed object, just skip it completely and use the parent when it is encountered.
173 self.IAccessibleObject = self.IAccessibleObject.accParent
174
176 """Determine the most appropriate class(es) for Acrobat objects.
177 This works similarly to L{NVDAObjects.NVDAObject.findOverlayClasses} except that it never calls any other findOverlayClasses method.
178 """
179 role = obj.role
180 if obj.event_childID == 0 and obj.event_objectID == winUser.OBJID_CLIENT:
181 # Root node.
182 if role in (controlTypes.ROLE_DOCUMENT,controlTypes.ROLE_PAGE):
183 clsList.append(Document)
184 elif role == controlTypes.ROLE_EDITABLETEXT:
185 clsList.append(RootTextNode)
186 else:
187 clsList.append(RootNode)
188
189 elif role == controlTypes.ROLE_EDITABLETEXT and controlTypes.STATE_FOCUSABLE in obj.states:
190 clsList.append(EditableTextNode)
191
192 clsList.append(AcrobatNode)
193
| Trees | Indices | Help |
|---|
| Generated by Epydoc 3.0.1 on Fri Nov 18 17:46:13 2011 | http://epydoc.sourceforge.net |