1 #Copyright (C) 2008 Codethink Ltd
2 #copyright: Copyright (c) 2005, 2007 IBM Corporation
4 #This library is free software; you can redistribute it and/or
5 #modify it under the terms of the GNU Lesser General Public
6 #License version 2 as published by the Free Software Foundation.
8 #This program is distributed in the hope that it will be useful,
9 #but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 #GNU General Public License for more details.
12 #You should have received a copy of the GNU Lesser General Public License
13 #along with this program; if not, write to the Free Software
14 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 #Portions of this code originally licensed and copyright (c) 2005, 2007
17 #IBM Corporation under the BSD license, available at
18 #U{http://www.opensource.org/licenses/bsd-license.php}
20 #authors: Peter Parente, Mark Doffman
44 def setCacheLevel(level):
54 print "Print cache function is deprecated";
56 def getInterfaceIID(obj):
58 Gets the ID of an interface class or object in string format for use in
61 @param obj: Class representing an AT-SPI interface or instance
63 @return: IID for the interface
65 @raise AttributeError: When the parameter does not provide typecode info
67 WARNING!! DEPRECATED!!
69 In current D-Bus version of pyatspi this simply returns a null string.
73 def getInterfaceName(obj):
75 Gets the human readable name of an interface class or object in string
78 @param obj: Class representing an AT-SPI interface or instance
80 @return: Name of the interface
82 @raise AttributeError: When the parameter does not provide typecode info
84 return obj._dbus_interface.lstrip("org.freedesktop.atspi.")
86 def listInterfaces(obj):
88 Gets a list of the names of all interfaces supported by this object. The
89 names are the short-hand interface names like "Accessible" and "Component",
90 not the full interface identifiers.
92 @param obj: Arbitrary object to query for all accessibility related
93 interfaces. Must provide a queryInterface method.
95 @return: Set of supported interface names
97 @raise AttributeError: If the object provide does not implement
100 return [itf.lstrip("org.freedesktop.atspi.") for itf in obj.interfaces]
102 def stringToConst(prefix, suffix):
104 Maps a string name to an AT-SPI constant. The rules for the mapping are as
106 - The prefix is captalized and has an _ appended to it.
107 - All spaces in the suffix are mapped to the _ character.
108 - All alpha characters in the suffix are mapped to their uppercase.
110 The resulting name is used with getattr to look up a constant with that name
111 in the L{constants} module. If such a constant does not exist, the string
112 suffix is returned instead.
114 This method allows strings to be used to refer to roles, relations, etc.
115 without direct access to the constants. It also supports the future expansion
116 of roles, relations, etc. by allowing arbitrary strings which may or may not
117 map to the current standard set of roles, relations, etc., but may still
118 match some non-standard role, relation, etc. being reported by an
121 @param prefix: Prefix of the constant name such as role, relation, state,
124 @param suffix: Name of the role, relation, etc. to use to lookup the constant
126 @return: The matching constant value
129 name = prefix.upper()+'_'+suffix.upper().replace(' ', '_')
130 return getattr(constants, name, suffix)
132 def stateToString(value):
134 Converts a state value to a string based on the name of the state constant in
135 the L{constants} module that has the given value.
137 @param value: An AT-SPI state
138 @type value: Accessibility.StateType
139 @return: Human readable, untranslated name of the state
142 return state.STATE_VALUE_TO_NAME.get(value)
144 def relationToString(value):
146 Converts a relation value to a string based on the name of the state constant
147 in the L{constants} module that has the given value.
149 @param value: An AT-SPI relation
150 @type value: Accessibility.RelationType
151 @return: Human readable, untranslated name of the relation
154 return relation.RELATION_VALUE_TO_NAME.get(value)
158 Generates all possible keyboard modifiers for use with
159 L{registry.Registry.registerKeystrokeListener}.
162 while mask <= (1 << registry.MODIFIER_NUMLOCK):
166 def findDescendant(acc, pred, breadth_first=False):
168 Searches for a descendant node satisfying the given predicate starting at
169 this node. The search is performed in depth-first order by default or
170 in breadth first order if breadth_first is True. For example,
172 my_win = findDescendant(lambda x: x.name == 'My Window')
174 will search all descendants of x until one is located with the name 'My
175 Window' or all nodes are exausted. Calls L{_findDescendantDepth} or
176 L{_findDescendantBreadth} to start the recursive search.
178 @param acc: Root accessible of the search
179 @type acc: Accessibility.Accessible
180 @param pred: Search predicate returning True if accessible matches the
181 search criteria or False otherwise
183 @param breadth_first: Search breadth first (True) or depth first (False)?
184 @type breadth_first: boolean
185 @return: Accessible matching the criteria or None if not found
186 @rtype: Accessibility.Accessible or None
189 return _findDescendantBreadth(acc, pred)
193 ret = _findDescendantDepth(acc, pred)
196 if ret is not None: return ret
198 def _findDescendantBreadth(acc, pred):
200 Internal function for locating one descendant. Called by L{findDescendant} to
203 @param acc: Root accessible of the search
204 @type acc: Accessibility.Accessible
205 @param pred: Search predicate returning True if accessible matches the
206 search criteria or False otherwise
208 @return: Matching node or None to keep searching
209 @rtype: Accessibility.Accessible or None
213 if pred(child): return child
218 ret = _findDescendantBreadth(child, pred)
221 if ret is not None: return ret
223 def _findDescendantDepth(acc, pred):
225 Internal function for locating one descendant. Called by L{findDescendant} to
228 @param acc: Root accessible of the search
229 @type acc: Accessibility.Accessible
230 @param pred: Search predicate returning True if accessible matches the
231 search criteria or False otherwise
233 @return: Matching node or None to keep searching
234 @rtype: Accessibility.Accessible or None
237 if pred(acc): return acc
242 ret = _findDescendantDepth(child, pred)
245 if ret is not None: return ret
247 def findAllDescendants(acc, pred):
249 Searches for all descendant nodes satisfying the given predicate starting at
250 this node. Does an in-order traversal. For example,
252 pred = lambda x: x.getRole() == pyatspi.ROLE_PUSH_BUTTON
253 buttons = pyatspi.findAllDescendants(node, pred)
255 will locate all push button descendants of node.
257 @param acc: Root accessible of the search
258 @type acc: Accessibility.Accessible
259 @param pred: Search predicate returning True if accessible matches the
260 search criteria or False otherwise
262 @return: All nodes matching the search criteria
266 _findAllDescendants(acc, pred, matches)
269 def _findAllDescendants(acc, pred, matches):
271 Internal method for collecting all descendants. Reuses the same matches
272 list so a new one does not need to be built on each recursive step.
276 if pred(child): matches.append(child)
279 _findAllDescendants(child, pred, matches)
281 def findAncestor(acc, pred):
283 Searches for an ancestor satisfying the given predicate. Note that the
284 AT-SPI hierarchy is not always doubly linked. Node A may consider node B its
285 child, but B is not guaranteed to have node A as its parent (i.e. its parent
286 may be set to None). This means some searches may never make it all the way
287 up the hierarchy to the desktop level.
289 @param acc: Starting accessible object
290 @type acc: Accessibility.Accessible
291 @param pred: Search predicate returning True if accessible matches the
292 search criteria or False otherwise
294 @return: Node matching the criteria or None if not found
295 @rtype: Accessibility.Accessible
298 # guard against bad start condition
301 if acc.parent is None:
302 # stop if there is no parent and we haven't returned yet
305 if pred(acc.parent): return acc.parent
313 Gets the path from the application ancestor to the given accessible in
314 terms of its child index at each level.
316 @param acc: Target accessible
317 @type acc: Accessibility.Accessible
318 @return: Path to the target
319 @rtype: list of integer
320 @raise LookupError: When the application accessible cannot be reached
324 if acc.parent is None:
328 path.append(acc.getIndexInParent())