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