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