msOffice.py
5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#NVDAObjects/IAccessible/msOffice.py
#A part of NonVisual Desktop Access (NVDA)
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
#Copyright (C) 2006-2010 Michael Curran <mick@kulgan.net>, James Teh <jamie@jantrid.net>
import oleacc
import IAccessibleHandler
import controlTypes
import winUser
import api
from . import IAccessible, getNVDAObjectFromEvent
import eventHandler
import re
"""Miscellaneous support for Microsoft Office applications.
"""
class SDM(IAccessible):
def _get_shouldAllowIAccessibleFocusEvent(self):
# #4199: Some SDM controls can incorrectly firefocus when they are not focused
# E.g. File recovery pane, clipboard manager pane
if winUser.getGUIThreadInfo(0).hwndFocus!=self.windowHandle:
return False
return super(SDM,self).shouldAllowIAccessibleFocusEvent
def _get_name(self):
name=super(SDM,self).name
if not name and self.role==controlTypes.ROLE_LISTITEM:
name=self.displayText
return name
def _get_positionInfo(self):
if self.role!=controlTypes.ROLE_LISTITEM:
return {}
return super(SDM,self).positionInfo
def _get_parent(self):
if self.IAccessibleChildID == 0 and self.role not in (controlTypes.ROLE_DIALOG, controlTypes.ROLE_PROPERTYPAGE, controlTypes.ROLE_WINDOW):
# SDM child IAccessible objects have a broken accParent.
# The parent should be the dialog.
return getNVDAObjectFromEvent(self.windowHandle, winUser.OBJID_CLIENT, 0)
return super(SDM, self).parent
def _get_presentationType(self):
t=super(SDM,self).presentationType
if t==self.presType_content and self.SDMChild:
t=self.presType_layout
return t
def _get_firstChild(self):
child=super(SDM,self).firstChild
if not child:
child=self.SDMChild
return child
def _get_lastChild(self):
child=super(SDM,self).lastChild
if not child:
child=self.SDMChild
return child
def _get_SDMChild(self):
if controlTypes.STATE_FOCUSED in self.states:
hwndFocus=winUser.getGUIThreadInfo(0).hwndFocus
if hwndFocus and hwndFocus!=self.windowHandle and winUser.isDescendantWindow(self.windowHandle,hwndFocus) and not winUser.getClassName(hwndFocus).startswith('bosa_sdm'):
obj=getNVDAObjectFromEvent(hwndFocus,winUser.OBJID_CLIENT,0)
if not obj: return None
if getattr(obj,'parentSDMCanOverrideName',True):
obj.name=self.name
obj.keyboardShortcut=self.keyboardShortcut
obj.parent=self
return obj
return None
class MSOUNISTAT(IAccessible):
def _get_role(self):
return controlTypes.ROLE_STATICTEXT
class MsoCommandBarToolBar(IAccessible):
def _get_isPresentableFocusAncestor(self):
# #4096: Many single controls are wrapped in their own SmoCommandBar toolbar.
# Therefore suppress reporting of these toolbars in focus ancestry if they only have one child.
if self.childCount==1:
return False
return super(MsoCommandBarToolBar,self).isPresentableFocusAncestor
def _get_name(self):
name=super(MsoCommandBarToolBar,self).name
# #3407: overly verbose and programmatic toolbar label
if name and name.startswith('MSO Generic Control Container'):
name=u""
return name
description=None
class BrokenMsoCommandBar(IAccessible):
"""Work around broken IAccessible implementation for Microsoft Office XP-2003 toolbars.
For these IAccessibles, accNavigate is rather broken
and retrieving only the first child with AccessibleChildren causes a crash.
"""
@classmethod
def appliesTo(cls, obj):
return obj.childCount > 0 and not IAccessibleHandler.accNavigate(obj.IAccessibleObject, obj.IAccessibleChildID, oleacc.NAVDIR_FIRSTCHILD)
def _get_firstChild(self):
# accNavigate incorrectly returns nothing for NAVDIR_FIRSTCHILD and requesting one child with AccessibleChildren causes a crash.
# Therefore, we must use accChild(1).
child = IAccessibleHandler.accChild(self.IAccessibleObject, 1)
if not child:
return None
return IAccessible(IAccessibleObject=child[0], IAccessibleChildID=child[1])
# accNavigate incorrectly returns the first child for NAVDIR_NEXT.
next = None
# description is redundant.
description = None
def _get_name(self):
name = super(BrokenMsoCommandBar, self).name
if name == "MSO Generic Control Container":
return None
return name
class CommandBarListItem(IAccessible):
"""A list item in an MSO commandbar, that may be part of a color palet."""
COMPILED_RE = re.compile(r'RGB\(\d+, \d+, \d+\)',re.I)
def _get_rgbNameAndMatch(self):
name = super(CommandBarListItem,self).name
if self.COMPILED_RE.match(name):
matchRGB = True
else:
matchRGB = False
return name, matchRGB
def _get_name(self):
name, matchRGB = self.rgbNameAndMatch
if matchRGB:
import colors
return colors.RGB.fromString(name).name
else:
return name
def _get_description(self):
name, matchRGB = self.rgbNameAndMatch
if matchRGB:
import colors
rgb=colors.RGB.fromString(name)
# Translators: a color, broken down into its RGB red, green, blue parts.
return _("RGB red {rgb.red}, green {rgb.green}, blue {rgb.blue}").format(rgb=colors.RGB.fromString(name))
else:
return super(CommandBarListItem,self).description
class SDMSymbols(SDM):
def _get_value(self):
#The value (symbol) is in a static text field somewhere in the direction of next.
# There can be multiple symbol lists all in a row, and these lists have their own static text labels, yet the active list's value field is always after them all.
# static text labels for these lists seem to have a keyboardShortcut, therefore we can skip over those.
next=self.next
while next:
if not next.keyboardShortcut and next.role==controlTypes.ROLE_STATICTEXT:
return next.name
next=next.next
def script_selectGraphic(self, gesture):
gesture.send()
eventHandler.queueEvent("valueChange",self)
__gestures = {
"kb:downArrow": "selectGraphic",
"kb:upArrow": "selectGraphic",
"kb:home": "selectGraphic",
"kb:end": "selectGraphic",
"kb:leftArrow": "selectGraphic",
"kb:rightArrow": "selectGraphic",
}