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