1 '''
2 Defines L{AccAdapt.Adapter}s for AT-SPI accessibles that manage their
3 descendants.
4
5 @author: Peter Parente
6 @organization: IBM Corporation
7 @copyright: Copyright (c) 2005, 2007 IBM Corporation
8 @license: The BSD License
9
10 All rights reserved. This program and the accompanying materials are made
11 available under the terms of the BSD license which accompanies
12 this distribution, and is available at
13 U{http://www.opensource.org/licenses/bsd-license.php}
14 '''
15 import pyLinAcc
16 from DefaultInfo import *
17 from DefaultNav import *
18 from DefaultAction import *
19 from AEInterfaces import *
20 from pyLinAcc import Interfaces, Constants
21
23 '''
24 Overrides L{DefaultAccInfoAdapter} to provide information specific to
25 containers that have STATE_MANAGES_DESCENDANTS. Expects the subject to be
26 a L{POR}.
27 '''
28 provides = [IAccessibleInfo]
29
30 @staticmethod
32 '''
33 Tests if the given subject can be adapted by this class.
34
35 @param subject: L{POR} containing an accessible to test
36 @type subject: L{POR}
37 @return: True when the subject meets the condition named in the docstring
38 for this class, False otherwise
39 @rtype: boolean
40 '''
41 ss = subject.accessible.getState()
42 return ss.contains(Constants.STATE_MANAGES_DESCENDANTS)
43
45 '''
46 Gets subitems of an item in a container that manages its descendants.
47 Subitems appear to be used to indicate items that cannot be selected
48 independently of each other in a list or tree control so they are made
49 children of a dummy accessible. This is most often observed when a list or
50 tree has an icon + plus text in one of its cells.
51
52 @param acc: Accessible that may or may not have subitems
53 @type acc: L{pyLinAcc.Accessible}
54 @return: List of accessibles, including the given one
55 @rtype: list of L{pyLinAcc.Accessible}
56 '''
57 si = [acc] + [acc.getChildAtIndex(i) for i in xrange(acc.childCount)]
58 return si
59
60 @pyLinAcc.errorToLookupError
62 '''
63 Gets all of the default text attributes assigned to the subject if item
64 offset is None, else the default attributes of the item offset child.
65
66 @return: Name:value pairs of the default text attributes
67 @rtype: dictionary
68 @raise LookupError: When the accessible object is dead
69 @raise IndexError: When the item offset is outside the bounds of the
70 number of children of the subject accessible
71 @raise NotImplementedError: When this accessible does not support the text
72 interface
73 '''
74 if self.item_offset is None:
75 return super(ContainerAccInfoAdapter, self).getAccDefTextAttrs()
76 c = self.accessible.getChildAtIndex(self.item_offset)
77 if c is None:
78 raise IndexError
79 return IAccessibleInfo(POR(c)).getAccDefTextAttrs()
80
81 @pyLinAcc.errorToLookupError
83 '''
84 Gets all the text attributes of a given accessible if item offset is None
85 or the attributes of the item offset child if it is not.
86
87 @return: Name:value pairs of the text attributes at the character offset
88 @rtype: dictionary
89 @raise LookupError: When the accessible object is dead
90 @raise IndexError: When the item offset is outside the bounds of the
91 number of children of the subject accessible
92 @raise NotImplementedError: When this accessible does not support the text
93 interface
94 '''
95 if self.item_offset is None:
96 return super(ContainerAccInfoAdapter, self).getAccAllTextAttrs()
97 c = self.accessible.getChildAtIndex(self.item_offset)
98 if c is None:
99 raise IndexError
100 return IAccessibleInfo(POR(c)).getAccAllTextAttrs()
101
102 @pyLinAcc.errorToLookupError
104 '''
105 Gets a list of L{POR}s referring to the selected items within the subject
106 accessible.
107
108 @return: Points of regard to selected items
109 @rtype: list of L{POR}s
110 @raise LookupError: When the subject accessible is dead
111 '''
112 try:
113 sel = Interfaces.ISelection(self.accessible)
114 except NotImplementedError:
115 return []
116
117 return [POR(self.accessible, sel.getSelectedChild(i).getIndexInParent(), 0)
118 for i in range(sel.nSelectedChildren)]
119
120 @pyLinAcc.errorToLookupError
122 '''
123 Gets the accessible role name of the subject if item offset is None else
124 the role name of the given item. The name is localized.
125
126 @return: Accessible role name of requested object
127 @rtype: string
128 @raise LookupError: When the subject accessible or the child is dead
129 @raise IndexError: When the item offset is outside the bounds of the
130 number of children of the subject accessible
131 '''
132 if self.item_offset is None:
133 return super(ContainerAccInfoAdapter, self).getAccRoleName()
134 try:
135 c = self.accessible.getChildAtIndex(self.item_offset)
136
137 return unicode(c.getLocalizedRoleName(), 'utf-8')
138 except AttributeError:
139 raise IndexError
140
141 @pyLinAcc.errorToLookupError
143 '''
144 Gets the accessible role of the subject if item offset is None else
145 the role name of the given item.
146
147 @return: Accessible role of requested object
148 @rtype: string
149 @raise LookupError: When the subject accessible or the child is dead
150 @raise IndexError: When the item offset is outside the bounds of the
151 number of children of the subject accessible
152 '''
153 if self.item_offset is None:
154 return super(ContainerAccInfoAdapter, self).getAccRole()
155 try:
156 c = self.accessible.getChildAtIndex(self.item_offset)
157 return c.getRoleName()
158 except AttributeError:
159 raise IndexError
160
161 @pyLinAcc.errorToLookupError
163 '''
164 Gets the accessible name of the subject if item offset is None else the
165 name of the given item.
166
167 @return: Accessible name of requested object
168 @rtype: string
169 @raise LookupError: When the subject accessible or the child is dead
170 @raise IndexError: When the item offset is outside the bounds of the
171 number of children of the subject accessible
172 '''
173 if self.item_offset is None:
174 return super(ContainerAccInfoAdapter, self).getAccName()
175 try:
176 c = self.accessible.getChildAtIndex(self.item_offset)
177 l = [i.name for i in self._getSubItems(c)]
178 return unicode(' '.join(l), 'utf-8')
179 except AttributeError:
180 raise IndexError
181
182 @pyLinAcc.errorToLookupError
184 '''
185 Gets the accessible description of the subject if item offset is None else
186 the name of the given item.
187
188 @return: Accessible description of requested object
189 @rtype: string
190 @raise LookupError: When the subject accessible or the child is dead
191 @raise IndexError: When the item offset is outside the bounds of the
192 number of children of the subject accessible
193 '''
194 if self.item_offset is None:
195 return super(ContainerAccInfoAdapter, self).getAccDescription()
196 try:
197 c = self.accessible.getChildAtIndex(self.item_offset)
198 l = [i.description for i in self._getSubItems(c)]
199 return unicode(' '.join(l), 'utf-8')
200 except AttributeError:
201 raise IndexError
202
203 @pyLinAcc.errorToLookupError
204 - def getAccItemText(self):
205 '''
206 Gets the accessible name of the subject if item offset is None else the
207 name of the given child accessible.
208
209 @return: Accessible description of requested object
210 @rtype: string
211 @raise LookupError: When the subject accessible or the child is dead
212 @raise IndexError: When the item offset is outside the bounds of the
213 number of children of the subject accessible
214 '''
215 if self.item_offset is None:
216 return super(ContainerAccInfoAdapter, self).getAccItemText()
217 try:
218 c = self.accessible.getChildAtIndex(self.item_offset)
219
220
221
222 l = [IAccessibleInfo(POR(i)).getAccItemText()
223 for i in self._getSubItems(c)]
224 return u' '.join(l)
225 except AttributeError:
226 raise IndexError
227
228 @pyLinAcc.errorToLookupError
230 '''
231 Gets a list of names of states indicating the current state of the given
232 accessible.
233
234 @return: Names of all states
235 @rtype: list of string
236 @raise LookupError: When the subject accessible or the child is dead
237 @raise IndexError: When the item offset is outside the bounds of the
238 number of children of the subject accessible
239 '''
240 if self.item_offset is None:
241 return super(ContainerAccInfoAdapter, self).getAccStates()
242 try:
243 c = self.accessible.getChildAtIndex(self.item_offset)
244 except AttributeError:
245 raise IndexError
246 return IAccessibleInfo(POR(c)).getAccStates()
247
248 @pyLinAcc.errorToLookupError
250 '''
251 Gets the index of an item as the item offset.
252
253 @return: Zero indexed item offset
254 @rtype: integer
255 @raise LookupError: When the table or item is no longer valid
256 '''
257 if self.item_offset is None:
258 return super(ContainerAccInfoAdapter, self).getAccIndex()
259 else:
260 return self.item_offset
261
262 @pyLinAcc.errorToLookupError
264 '''
265 Gets if the subject has the given state.
266
267 @param state: Name of the state (e.g. 'focused', 'selected', 'selectable')
268 @type state: string
269 @return: Does the accessible have the given state?
270 @rtype: boolean
271 @see: L{getAccStates}
272 '''
273 if self.item_offset is None:
274 return super(ContainerAccInfoAdapter, self).hasAccState(state)
275 try:
276 c = self.accessible.getChildAtIndex(self.item_offset)
277 except AttributeError:
278 raise IndexError
279 return IAccessibleInfo(POR(c)).hasAccState(state)
280
281 @pyLinAcc.errorToLookupError
283 '''
284 Gets if the subject has at least one of the given states.
285
286 @param states: State names(e.g. 'focused', 'selected', 'selectable')
287 @type states: string
288 @return: Does the accessible have at least one of the given states?
289 @rtype: boolean
290 '''
291 if self.item_offset is None:
292 return super(ContainerAccInfoAdapter, self).hasAccOneState(*states)
293 try:
294 c = self.accessible.getChildAtIndex(self.item_offset)
295 except AttributeError:
296 raise IndexError
297 return IAccessibleInfo(POR(c)).hasAccOneState(*states)
298
299 @pyLinAcc.errorToLookupError
301 '''
302 Gets if the subject has all of the given states.
303
304 @param states: State names(e.g. 'focused', 'selected', 'selectable')
305 @type states: string
306 @return: Does the accessible have all of the given states?
307 @rtype: boolean
308 '''
309 if self.item_offset is None:
310 return super(ContainerAccInfoAdapter, self).hasAccAllStates(*states)
311 try:
312 c = self.accessible.getChildAtIndex(self.item_offset)
313 except AttributeError:
314 raise IndexError
315 return IAccessibleInfo(POR(c)).hasAccAllStates(*state)
316
317 @pyLinAcc.errorToLookupError
319 '''
320 Gets the list of all action names defined by the subject.
321
322 @return: List of all action names
323 @rtype: list of string
324 @raise NotImplementedError: When the subject does not support actions
325 '''
326 if self.item_offset is None:
327 super(ContainerAccInfoAdapter, self).getAccActionNames()
328 try:
329 c = self.accessible.getChildAtIndex(self.item_offset)
330 except AttributeError:
331 raise IndexError
332 return IAccessibleInfo(POR(c)).getAccActionNames()
333
334 @pyLinAcc.errorToLookupError
336 '''
337 Gets the list of all action descriptions defined by the subject.
338
339 @return: List of all action descriptions
340 @rtype: list of string
341 @raise NotImplementedError: When the subject does not support actions
342 '''
343 if self.item_offset is None:
344 super(ContainerAccInfoAdapter, self).getAccActionDescs()
345 try:
346 c = self.accessible.getChildAtIndex(self.item_offset)
347 except AttributeError:
348 raise IndexError
349 return IAccessibleInfo(POR(c)).getAccActionDescs()
350
351 @pyLinAcc.errorToLookupError
353 '''
354 Gets the number of available actions on the subject.
355
356 @return: Number of actions available
357 @rtype: integer
358 @raise NotImplementedError: When the subject does not support actions
359 '''
360 if self.item_offset is None:
361 super(ContainerAccInfoAdapter, self).getAccActionCount()
362 try:
363 c = self.accessible.getChildAtIndex(self.item_offset)
364 except AttributeError:
365 raise IndexError
366 return IAccessibleInfo(POR(c)).getAccActionCount()
367
368 @pyLinAcc.errorToLookupError
370 '''
371 Gets the key bindings associated with all available actions. Parses the
372 key bindings into tuples since some actions can have multiple ways of
373 activating them dependent on the context.
374
375 @return: List of tuples, each containing one or more string keysym names
376 indicating the keys to press in sequence to perform the action
377 @rtype: list of tuple of string
378 @raise NotImplementedError: When the subject does not support actions
379 '''
380 if self.item_offset is None:
381 super(ContainerAccInfoAdapter, self).getAccActionKeys()
382 try:
383 c = self.accessible.getChildAtIndex(self.item_offset)
384 except AttributeError:
385 raise IndexError
386 return IAccessibleInfo(POR(c)).getAccActionKeys()
387
388 @pyLinAcc.errorToLookupError
390 '''
391 Gets the visual width and height of the subject.
392
393 @return: Width and height extents
394 @rtype: 2-tuple of integer
395 @raise LookupError: When the accessible object is dead
396 '''
397 if self.item_offset is None:
398 return super(ContainerAccInfoAdapter, self).getAccVisualExtents()
399 try:
400 c = self.accessible.getChildAtIndex(self.item_offset)
401 except AttributeError:
402
403 raise IndexError
404
405 return IAccessibleInfo(POR(c,None,self.char_offset)).getAccVisualExtents()
406
407 @pyLinAcc.errorToLookupError
409 '''
410 Gets the focal point within the subject, where the focal point is defined
411 as the center of the active item.
412
413 @return: x,y coordinates
414 @rtype: 2-tuple of integer
415 @raise LookupError: When the accessible object is dead
416 '''
417 if self.item_offset is None:
418 return super(ContainerAccInfoAdapter, self).getAccVisualPoint()
419 try:
420 c = self.accessible.getChildAtIndex(self.item_offset)
421 except AttributeError:
422
423 raise IndexError
424
425 return IAccessibleInfo(POR(c,None,self.char_offset)).getAccVisualPoint()
426
428 '''
429 Overrides L{DefaultAccActionAdapter} to provide information specific to
430 containers that have STATE_MANAGES_DESCENDANTS. Expects the subject to be a
431 L{POR}.
432 '''
433 provides = [IAccessibleAction]
434
435 @staticmethod
437 '''
438 Tests if the given subject can be adapted by this class.
439
440 @param subject: L{POR} containing an accessible to test
441 @type subject: L{POR}
442 @return: True when the subject meets the condition named in the docstring
443 for this class, False otherwise
444 @rtype: boolean
445 '''
446 acc = subject.accessible
447 c = Constants
448 ss = acc.getState()
449 return ss.contains(c.STATE_MANAGES_DESCENDANTS)
450
451 @pyLinAcc.errorToLookupError
453 '''
454 Gives the subject accessible the focus when the item offset is None or
455 one of its items when the offset is an integer.
456
457 @return: Did accessible accept (True) or refuse (False) the focus change?
458 @rtype: boolean
459 @raise LookupError: When the accessible object is dead
460 @raise NotImplementedError: When the accessible does not support an
461 interface for setting focus
462 '''
463 if self.item_offset is None:
464 super(ContainerAccActionAdapter, self).setAccFocus()
465 else:
466 child = self.accessible.getChildAtIndex(self.item_offset)
467 c = Interfaces.IComponent(child)
468 return c.grabFocus()
469
470 @pyLinAcc.errorToLookupError
472 '''
473 Selects the accessible object implementing this interface when item offset
474 is None and all is False. Selects all items when item offset is None and
475 all is True. Otherwise, selects the one item indicated by the item offset
476 in the subject L{POR}.
477
478 @param all: Select all items?
479 @type all: boolean
480 @return: Did accessible accept (True) or refuse (False) the selection?
481 @rtype: boolean
482 @raise LookupError: When the accessible object is dead
483 @raise NotImplementedError: When the accessible does not support an
484 interface for setting the selection
485 '''
486 if self.item_offset is None:
487 return super(ContainerAccActionAdapter,self).selectAcc(all)
488 else:
489 c = Interfaces.ISelection(self.accessible)
490 return c.selectChild(self.item_offset)
491
492 @pyLinAcc.errorToLookupError
494 '''
495 Executes the accessible action given by the index on the item_offset.
496
497 @param index: Index of the action to execute
498 @type index: integer
499 @return: Did the action execute (True) or not (False)?
500 @rtype: boolean
501 @raise LookupError: When the accessible object is dead
502 @raise NotImplementedError: When the accessible does not support the action
503 interface
504 '''
505 if self.item_offset is None:
506 return super(ContainerAccActionAdapter,self).doAccAction(index)
507 else:
508 child = self.accessible.getChildAtIndex(self.item_offset)
509 act = Interfaces.IAction(child)
510 return act.doAction(index)
511