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

Source Code for Module Adapters.ATSPI.TreeAdapter

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