Package AccessEngine :: Package AEAccAdapters :: Package ATSPI :: Module ContainerAdapter
[hide private]
[frames] | no frames]

Source Code for Module AccessEngine.AEAccAdapters.ATSPI.ContainerAdapter

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