2008-08-27 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / pyatspi / desktop.py
1 #Copyright (C) 2008 Codethink Ltd
2
3 #This library is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU Lesser General Public
5 #License version 2 as published by the Free Software Foundation.
6
7 #This program is distributed in the hope that it will be useful,
8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 #GNU General Public License for more details.
11 #You should have received a copy of the GNU Lesser General Public License
12 #along with this program; if not, write to the Free Software
13 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14
15 import interfaces
16 from base import BaseProxyMeta
17 from accessible import BoundingBox
18 from cache import AccessibleCache
19 from state import StateSet
20 from role import ROLE_UNKNOWN
21 from component import LAYER_WIDGET
22
23 __all__ = [
24            "Desktop",
25           ]
26
27 #------------------------------------------------------------------------------
28
29 class ApplicationCache(object):
30
31         def __init__(self, connection, bus_name):
32                 self._connection = connection
33                 self._bus_name = bus_name
34                 self._accessible_cache = AccessibleCache(connection, bus_name)
35
36         def __getitem__(self, key):
37                 return self._accessible_cache
38
39         def __contains__(self, key):
40                 if key == self._bus_name:
41                         return True
42                 else:
43                         return False
44
45         def get_application_at_index(self, index):
46                 pass
47
48         def get_application_count(self):
49                 return 1
50
51 #------------------------------------------------------------------------------
52
53 class DesktopComponent(object):
54     """
55     The Component interface is implemented by objects which occupy
56     on-screen space, e.g. objects which have onscreen visual representations.
57     The methods in Component allow clients to identify where the
58     objects lie in the onscreen coordinate system, their relative
59     size, stacking order, and position. It also provides a mechanism
60     whereby keyboard focus may be transferred to specific user interface
61     elements programmatically. This is a 2D API, coordinates of 3D
62     objects are projected into the 2-dimensional screen view for
63     purposes of this interface.
64     """
65
66     def contains(self, *args, **kwargs):
67         """
68         @return True if the specified point lies within the Component's
69         bounding box, False otherwise.
70         """
71         return False
72     
73     def deregisterFocusHandler(self, *args, **kwargs):
74         """
75         Request that an EventListener registered via registerFocusHandler
76         no longer be notified when this object receives keyboard focus.
77         """
78         pass
79     
80     def getAccessibleAtPoint(self, *args, **kwargs):
81         """
82         @return the Accessible child whose bounding box contains the
83         specified point.
84         """
85         return None
86     
87     def getAlpha(self, *args, **kwargs):
88         """
89         Obtain the alpha value of the component. An alpha value of 1.0
90         or greater indicates that the object is fully opaque, and an
91         alpha value of 0.0 indicates that the object is fully transparent.
92         Negative alpha values have no defined meaning at this time.
93         """
94         return 1.0
95     
96     def getExtents(self, coord_type):
97         """
98         Obtain the Component's bounding box, in pixels, relative to the
99         specified coordinate system. 
100         @param coord_type
101         @return a BoundingBox which entirely contains the object's onscreen
102         visual representation.
103         """
104         #TODO This needs to return the window size
105         return BoundingBox(*(0,0,1024,768))
106     
107     def getLayer(self, *args, **kwargs):
108         """
109         @return the ComponentLayer in which this object resides.
110         """
111         return LAYER_WIDGET
112     
113     def getMDIZOrder(self):
114         """
115         Obtain the relative stacking order (i.e. 'Z' order) of an object.
116         Larger values indicate that an object is on "top" of the stack,
117         therefore objects with smaller MDIZOrder may be obscured by objects
118         with a larger MDIZOrder, but not vice-versa. 
119         @return an integer indicating the object's place in the stacking
120         order.
121         """
122         return 0
123     
124     def getPosition(self, coord_type):
125         """
126         Obtain the position of the current component in the coordinate
127         system specified by coord_type. 
128         @param : coord_type
129         @param : x
130         an out parameter which will be back-filled with the returned
131         x coordinate. 
132         @param : y
133         an out parameter which will be back-filled with the returned
134         y coordinate.
135         """
136         return (0,0)
137     
138     def getSize(self, *args, **kwargs):
139         """
140         Obtain the size, in the coordinate system specified by coord_type,
141         of the rectangular area which fully contains the object's visual
142         representation, without accounting for viewport clipping. 
143         @param : width
144         the object's horizontal extents in the specified coordinate system.
145         @param : height
146         the object's vertical extents in the specified coordinate system.
147         """
148         #TODO Need to return window size
149         return (1024, 768)
150     
151     def grabFocus(self, *args, **kwargs):
152         """
153         Request that the object obtain keyboard focus.
154         @return True if keyboard focus was successfully transferred to
155         the Component.
156         """
157         return False
158     
159     def registerFocusHandler(self, *args, **kwargs):
160         """
161         Register an EventListener for notification when this object receives
162         keyboard focus.
163         """
164         pass
165
166 #------------------------------------------------------------------------------
167
168 class Desktop(object):
169     """
170     The base interface which is implemented by all accessible objects.
171     All objects support interfaces for querying their contained
172     'children' and position in the accessible-object hierarchy,
173     whether or not they actually have children.
174     """
175
176     __metaclass__ = BaseProxyMeta
177
178     def __init__(self, cache):
179         """
180         Creates a desktop object. There should be one single desktop
181         object for the Registry object.
182
183         @param cache - The application cache.
184         @kwarf application - The application D-Bus name
185         
186         If the application name is provided the Desktop is being used for
187         test and will only report the application provided as its single child.
188         """
189         self._cache = cache
190         self._app_name = '/'
191
192     def __len__(self):
193             return self.getChildCount()
194
195     def __getitem__(self, index):
196             return self.getChildAtIndex(index)
197         
198     def getApplication(self):
199         """
200         Get the containing Application for this object.
201         @return the Application instance to which this object belongs.
202         """
203         return None
204     
205     def getAttributes(self):
206         """
207         Get a list of properties applied to this object as a whole, as
208         an AttributeSet consisting of name-value pairs. As such these
209         attributes may be considered weakly-typed properties or annotations,
210         as distinct from the strongly-typed interface instance data declared
211         using the IDL "attribute" keyword.
212         Not all objects have explicit "name-value pair" AttributeSet
213         properties.
214         Attribute names and values may have any UTF-8 string value, however
215         where possible, in order to facilitate consistent use and exposure
216         of "attribute" properties by applications and AT clients, attribute
217         names and values should chosen from a publicly-specified namespace
218         where appropriate.
219         Where possible, the names and values in the name-value pairs
220         should be chosen from well-established attribute namespaces using
221         standard semantics. For example, attributes of Accessible objects
222         corresponding to XHTML content elements should correspond to
223         attribute names and values specified in the w3c XHTML specification,
224         at http://www.w3.org/TR/xhtml2, where such values are not already
225         exposed via a more strongly-typed aspect of the AT-SPI API. Metadata
226         names and values should be chosen from the 'Dublin Core' Metadata
227         namespace using Dublin Core semantics: http://dublincore.org/dcregistry/
228         Similarly, relevant structural metadata should be exposed using
229         attribute names and values chosen from the CSS2 and WICD specification:
230         http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/).
231
232         @return : An AttributeSet encapsulating any "attribute values"
233         currently defined for the object. An attribute set is a list of strings
234         with each string comprising an name-value pair format 'name:value'.
235         """
236         return []
237     
238     def getChildAtIndex(self, index):
239         """
240         Get the accessible child of this object at index. 
241         @param : index
242         an in parameter indicating which child is requested (zero-indexed).
243         @return : the 'nth' Accessible child of this object.
244         """
245         return self._cache.get_application_at_index(index)
246     
247     def getIndexInParent(self):
248         """
249         Get the index of this object in its parent's child list. 
250         @return : a long integer indicating this object's index in the
251         parent's list.
252         """
253         return -1
254     
255     def getLocalizedRoleName(self):
256         """
257         Get a string indicating the type of UI role played by this object,
258         translated to the current locale.
259         @return : a UTF-8 string indicating the type of UI role played
260         by this object.
261         """
262         #TODO Need to localize this somehow. Hmmmmm
263         return 'unknown'
264     
265     def getRelationSet(self):
266         """
267         Get a set defining this object's relationship to other accessible
268         objects. 
269         @return : a RelationSet defining this object's relationships.
270         """
271         return []
272     
273     def getRole(self):
274         """
275         Get the Role indicating the type of UI role played by this object.
276         @return : a Role indicating the type of UI role played by this
277         object.
278         """
279         return ROLE_UNKNOWN
280     
281     def getRoleName(self):
282         """
283         Get a string indicating the type of UI role played by this object.
284         @return : a UTF-8 string indicating the type of UI role played
285         by this object.
286         """
287         return 'unknown'
288     
289     def getState(self):
290         """
291         Get the current state of the object as a StateSet. 
292         @return : a StateSet encapsulating the currently true states
293         of the object.
294         """
295         return StateSet()
296     
297     def isEqual(self, accessible):
298         """
299         Determine whether an Accessible refers to the same object as
300         another. This method should be used rather than brute-force comparison
301         of object references (i.e. "by-value" comparison), as two object
302         references may have different apparent values yet refer to the
303         same object.
304         @param : obj
305         an Accessible object reference to compare to 
306         @return : a boolean indicating whether the two object references
307         point to the same object.
308         """
309         return self == accessible
310     
311     def get_childCount(self):
312         return self._cache.get_application_count()
313     _childCountDoc = \
314         """
315         childCount: the number of children contained by this object.
316         """
317     childCount = property(fget=get_childCount, doc=_childCountDoc)
318     
319     def get_description(self):
320         return ''
321     _descriptionDoc = \
322         """
323         a string describing the object in more detail than name.
324         """
325     description = property(fget=get_description, doc=_descriptionDoc)
326     
327     def get_name(self):
328         return 'main'
329     _nameDoc = \
330         """
331         a (short) string representing the object's name.
332         """
333     name = property(fget=get_name, doc=_nameDoc)
334     
335     def get_parent(self):
336         return None
337     _parentDoc = \
338         """
339         An Accessible object which is this object's containing object.
340         """
341     parent = property(fget=get_parent, doc=_parentDoc)
342
343     def queryInterface(self, interface):
344         """
345         Gets a different accessible interface for this object
346         or raises a NotImplemented error if the given interface
347         is not supported.
348         """
349         if interface == interfaces.ATSPI_ACCESSIBLE:
350                 return self
351         elif interface == interfaces.ATSPI_COMPONENT:
352                 return DesktopComponent()
353         else:
354                 raise NotImplementedError(
355                         "%s not supported by accessible object at path %s"
356                         % (interface, self.path))
357
358 #END----------------------------------------------------------------------------