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

Source Code for Module AccessEngine.AEAccAdapters.ATSPI.TreeAdapter

  1  ''' 
  2  Defines L{AEAccAdapter.AEAccAdapter}s for AT-SPI tree accessibles. Trees  
  3  implement both the Table and the Selection interfaces. 
  4   
  5  @author: Peter Parente 
  6  @author: Eirikur Hallgrimsson 
  7  @organization: IBM Corporation 
  8  @copyright: Copyright (c) 2005, 2007 IBM Corporation 
  9  @license: The BSD License 
 10   
 11  @author: Frank Zenker 
 12  @organization: IT Science Center Ruegen gGmbH, Germany 
 13  @copyright: Copyright (c) 2007, 2008 ITSC Ruegen 
 14  @license: The BSD License 
 15   
 16  All rights reserved. This program and the accompanying materials are made 
 17  available under the terms of the BSD license which accompanies 
 18  this distribution, and is available at 
 19  U{http://www.opensource.org/licenses/bsd-license.php} 
 20  ''' 
 21   
 22  import pyatspi 
 23  from ContainerAdapter import * 
 24  from TableAdapter import * 
 25  from DefaultNav import * 
 26  from AccessEngine.AEAccInterfaces import * 
 27  from AccessEngine.AEPor import AEPor 
 28   
29 -class TreeAccInfoAdapter(TableAccInfoAdapter):
30 ''' 31 Overrides L{TableAccInfoAdapter} to generate selector events on focus 32 and on selection. Expects the subject to be a C{pyatspi.Accessible}. 33 34 Adapts subject accessibles that provide the C{pyatspi.Accessibility.Accessible.Table} 35 interface and have ROLE_TREE_TABLE. 36 ''' 37 provides = [IAccessibleInfo] 38 39 @staticmethod
40 - def when(por):
41 ''' 42 Tests if the given subject can be adapted by this class. 43 44 @param por: Point of regard to test 45 @type por: L{AEPor} 46 @return: True when the subject meets the condition named in the docstring 47 for this class, False otherwise 48 @rtype: boolean 49 ''' 50 acc = por.accessible 51 r = acc.getRole() 52 # make sure the role indicates it is a tree table 53 if r != pyatspi.ROLE_TREE_TABLE: 54 return False 55 # make sure the table interface exists 56 tab = acc.queryTable() 57 return True
58 59
60 - def getAccLevel(self):
61 ''' 62 Gets the level of a node in a tree where zero is the root. 63 64 @return: Level of the node 65 @rtype: integer 66 @raise NotImplementedError: When a tree doesn't support the NODE_OF 67 accessible relation 68 ''' 69 # don't count any level when we're on the tree itself, not one of its nodes 70 if self.item_offset is None: 71 raise NotImplementedError 72 73 count = 0 74 node = self.accessible.getChildAtIndex(self.item_offset) 75 relations = node.getRelationSet() 76 if not relations: 77 # some tree nodes don't have relations (e.g. multicolumn tree tables) 78 # but the node in the first column in this row will have the relation 79 table = (self.accessible).queryTable() 80 row = table.getRowAtIndex(self.item_offset) 81 node = table.getAccessibleAt(row, 0) 82 relations = node.getRelationSet() 83 84 if not relations: 85 # can't get level if there are no relations at this point 86 raise NotImplementedError 87 88 def parent(relations): 89 for rel in relations: 90 if rel.getRelationType() == pyatspi.RELATION_NODE_CHILD_OF: 91 return rel.getTarget(0).getRelationSet() # return parent's relation set 92 return None # end of Parent(relations)
93 94 while True: 95 temp = parent(relations) 96 if temp: 97 count +=1 98 relations = temp # Set up for looking up. 99 else: 100 return count
101
102 -class TreeNavAdapter(DefaultNavAdapter):
103 ''' 104 Overrides L{DefaultNavAdapter} to provide navigation over tree cells as items. 105 Expects the subject to be a L{AEPor}. 106 107 Adapts subject accessibles that provide the C{pyatspi.Accessibility.Accessible..ITable} 108 interface and have ROLE_TREE_TABLE. 109 ''' 110 provides = [IAccessibleNav, IItemNav] 111 112 @staticmethod
113 - def when(subject):
114 ''' 115 Tests if the given subject can be adapted by this class. 116 117 @param subject: L{AEPor} containing an accessible to test 118 @type subject: L{AEPor} 119 @return: True when the subject meets the condition named in the docstring 120 for this class, False otherwise 121 @rtype: boolean 122 ''' 123 acc = subject.accessible 124 r = acc.getRole() 125 return (r == pyatspi.ROLE_TREE_TABLE and acc.queryTable())
126 127
128 - def _getVisibleItemExtents(self, only_visible):
129 ''' 130 Gets the item offsets of the first and last items in a tree of cells. 131 132 @param only_visible: Only consider the first and last cells visible in 133 the tree (True) or the absolute first and last cells (False)? 134 @return: First and last item offsets 135 @rtype: 2-tuple of integer 136 @raise LookupError: When the first or last item or parent accessible is 137 not available 138 ''' 139 acc = self.accessible 140 if only_visible: 141 comp = acc.queryComponent() 142 e = comp.getExtents(pyatspi.DESKTOP_COORDS) 143 # get the first item 144 x, y = e.x+FUDGE_PX, e.y+FUDGE_PX 145 first = comp.getAccessibleAtPoint(x, y, pyatspi.DESKTOP_COORDS) 146 # get the last item 147 x, y = e.x+e.width-FUDGE_PX, e.y+e.height-FUDGE_PX 148 last = comp.getAccessibleAtPoint(x, y, pyatspi.DESKTOP_COORDS) 149 else: 150 first = None 151 last = None 152 # compute indices 153 if first: 154 i = first.getIndexInParent() 155 else: 156 i = 0 157 if last: 158 j = last.getIndexInParent() 159 else: 160 t = acc.queryTable() 161 j = t.getIndexAt(t.nRows-1, t.nColumns-1) 162 return i, j
163 164
165 - def getNextItem(self, only_visible=True):
166 ''' 167 Gets the next item relative to the one indicated by the L{AEPor} 168 providing this interface. 169 170 @param only_visible: True when Item in the returned L{AEPor} must be visible 171 @type only_visible: boolean 172 @return: Point of regard to the next item in the same accessible 173 @rtype: L{AEPor} 174 @raise IndexError: When there is no next item 175 @raise LookupError: When lookup for the next item fails even though it may 176 exist 177 ''' 178 acc = self.accessible 179 off = self.item_offset 180 # get the first and last indicies 181 i, j = self._getVisibleItemExtents(only_visible) 182 # and check if the first item is visible since it might be a header 183 #v = IAccessibleInfo(AEPor(acc.getChildAtIndex(0))).isAccVisible() 184 #if off is None and v: 185 # # return the possible header 186 # return AEPor(acc, 0, 0) 187 if off is None or off < i: 188 # return the first visible, non-header item 189 return AEPor(acc, i, 0) 190 elif off+1 >= i and off+1 <= j: 191 # compute the row and column offsets 192 t = acc.queryTable() 193 r, c = t.getRowAtIndex(off), t.getColumnAtIndex(off) 194 # now find the next item offsets 195 if c < t.nColumns-1: 196 c += 1 197 else: 198 r += 1 199 c = 0 200 # return the previous visible item 201 n_off = t.getIndexAt(r, c) 202 return AEPor(acc, n_off, 0) 203 else: 204 # no more visible items 205 raise IndexError
206 207
208 - def getPrevItem(self, only_visible=True):
209 ''' 210 Gets the previous item relative to the one indicated by the L{AEPor} 211 providing this interface. 212 213 @param only_visible: True when Item in the returned L{AEPor} must be visible 214 @type only_visible: boolean 215 @return: Point of regard to the previous item in the same accessible 216 @rtype: L{AEPor} 217 @raise IndexError: When there is no previous item 218 @raise LookupError: When lookup for the previous item fails even though it 219 may exist 220 ''' 221 acc = self.accessible 222 off = self.item_offset 223 comp = acc.queryComponent() 224 # get the first and last indicies 225 i, j = self._getVisibleItemExtents(only_visible) 226 # and check if the first item is visible since it might be a header 227 #v = IAccessibleInfo(AEPor(acc.getChildAtIndex(0))).isAccVisible() 228 if off is None: 229 # no more visible items 230 raise IndexError 231 elif off > j: 232 # return the last visible item 233 return AEPor(acc, j, 0) 234 elif off-1 >= i and off-1 <= j: 235 # compute the row and column offsets 236 t = acc.queryTable() 237 r, c = t.getRowAtIndex(off), t.getColumnAtIndex(off) 238 # now find the previous item offsets 239 if c: 240 c -= 1 241 else: 242 r -= 1 243 c = t.nColumns-1 244 # return the previous visible item 245 p_off = t.getIndexAt(r, c) 246 return AEPor(acc, p_off, 0) 247 #elif off > 0 and v: 248 # # return the visible header item 249 # return AEPor(acc, 0, 0) 250 else: 251 # return the tree iteself 252 return AEPor(acc, None, 0)
253 254
255 - def getLastItem(self, only_visible=True):
256 ''' 257 Gets the last item relative to the one indicated by the L{AEPor} 258 providing this interface. 259 260 @param only_visible: True when Item in the returned L{AEPor} must be visible 261 @type only_visible: boolean 262 @return: Point of regard to the last item in the same accessible 263 @rtype: L{AEPor} 264 @raise LookupError: When lookup for the last item fails even though it may 265 exist 266 ''' 267 acc = self.accessible 268 comp = acc.queryComponent() 269 # try getting the last item by index first 270 child = acc.getChildAtIndex(acc.childCount-1) 271 if IAccessibleInfo(AEPor(child)).isAccVisible() or not only_visible: 272 return AEPor(acc, acc.childCount-1, 0) 273 # use coords to get the last visible item 274 i, j = self._getVisibleItemExtents(only_visible) 275 return AEPor(acc, j, 0)
276 277
278 - def getFirstItem(self, only_visible=True):
279 ''' 280 Gets the first item relative to the one indicated by the L{AEPor} 281 providing this interface. 282 283 @param only_visible: True when Item in the returned L{AEPor} must be visible 284 @type only_visible: boolean 285 @return: Point of regard to the last item in the same accessible 286 @rtype: L{AEPor} 287 @raise LookupError: When lookup for the last item fails even though it may 288 exist 289 ''' 290 acc = self.accessible 291 comp = acc.queryComponent() 292 # try getting the first item by index first 293 child = acc.getChildAtIndex(0) 294 if IAccessibleInfo(AEPor(child)).isAccVisible() or not only_visible: 295 return AEPor(acc, 0, 0) 296 # use coords to get the last visible item 297 i, j = self._getVisibleItemExtents(only_visible) 298 return AEPor(acc, i, 0)
299 300
301 - def getFirstAccChild(self):
302 ''' 303 Always raises LookupError. Tables have items but no children. 304 305 @raise LookupError: Always 306 ''' 307 raise LookupError
308 309
310 - def getLastAccChild(self):
311 ''' 312 Always raises LookupError. Tables have items but no children. 313 314 @raise LookupError: Always 315 ''' 316 raise LookupError
317 318 319 #def getChildAcc(self, index): 320 #''' 321 #Always raises LookupError. Tables have items but no children. 322 323 #@raise LookupError: Always 324 #''' 325 #raise LookupError 326