Merge branch 'master' of git+ssh://git.codethink.co.uk/git/atspi-dbus
[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 __nonzero__(self):
193                         return True
194
195         def __len__(self):
196                         return self.getChildCount()
197
198         def __getitem__(self, index):
199                         return self.getChildAtIndex(index)
200
201         def getApplication(self):
202                 """
203                 Get the containing Application for this object.
204                 @return the Application instance to which this object belongs.
205                 """
206                 return None
207
208         def getAttributes(self):
209                 """
210                 Get a list of properties applied to this object as a whole, as
211                 an AttributeSet consisting of name-value pairs. As such these
212                 attributes may be considered weakly-typed properties or annotations,
213                 as distinct from the strongly-typed interface instance data declared
214                 using the IDL "attribute" keyword.
215                 Not all objects have explicit "name-value pair" AttributeSet
216                 properties.
217                 Attribute names and values may have any UTF-8 string value, however
218                 where possible, in order to facilitate consistent use and exposure
219                 of "attribute" properties by applications and AT clients, attribute
220                 names and values should chosen from a publicly-specified namespace
221                 where appropriate.
222                 Where possible, the names and values in the name-value pairs
223                 should be chosen from well-established attribute namespaces using
224                 standard semantics. For example, attributes of Accessible objects
225                 corresponding to XHTML content elements should correspond to
226                 attribute names and values specified in the w3c XHTML specification,
227                 at http://www.w3.org/TR/xhtml2, where such values are not already
228                 exposed via a more strongly-typed aspect of the AT-SPI API. Metadata
229                 names and values should be chosen from the 'Dublin Core' Metadata
230                 namespace using Dublin Core semantics: http://dublincore.org/dcregistry/
231                 Similarly, relevant structural metadata should be exposed using
232                 attribute names and values chosen from the CSS2 and WICD specification:
233                 http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/).
234
235                 @return : An AttributeSet encapsulating any "attribute values"
236                 currently defined for the object. An attribute set is a list of strings
237                 with each string comprising an name-value pair format 'name:value'.
238                 """
239                 return []
240
241         def getChildAtIndex(self, index):
242                 """
243                 Get the accessible child of this object at index. 
244                 @param : index
245                 an in parameter indicating which child is requested (zero-indexed).
246                 @return : the 'nth' Accessible child of this object.
247                 """
248                 return self._cache.get_application_at_index(index, self)
249
250         def getIndexInParent(self):
251                 """
252                 Get the index of this object in its parent's child list. 
253                 @return : a long integer indicating this object's index in the
254                 parent's list.
255                 """
256                 return -1
257
258         def getLocalizedRoleName(self):
259                 """
260                 Get a string indicating the type of UI role played by this object,
261                 translated to the current locale.
262                 @return : a UTF-8 string indicating the type of UI role played
263                 by this object.
264                 """
265                 #TODO Need to localize this somehow. Hmmmmm
266                 return 'unknown'
267
268         def getRelationSet(self):
269                 """
270                 Get a set defining this object's relationship to other accessible
271                 objects. 
272                 @return : a RelationSet defining this object's relationships.
273                 """
274                 return []
275
276         def getRole(self):
277                 """
278                 Get the Role indicating the type of UI role played by this object.
279                 @return : a Role indicating the type of UI role played by this
280                 object.
281                 """
282                 return ROLE_UNKNOWN
283
284         def getRoleName(self):
285                 """
286                 Get a string indicating the type of UI role played by this object.
287                 @return : a UTF-8 string indicating the type of UI role played
288                 by this object.
289                 """
290                 return 'unknown'
291
292         def getState(self):
293                 """
294                 Get the current state of the object as a StateSet. 
295                 @return : a StateSet encapsulating the currently true states
296                 of the object.
297                 """
298                 return StateSet()
299
300         def isEqual(self, accessible):
301                 """
302                 Determine whether an Accessible refers to the same object as
303                 another. This method should be used rather than brute-force comparison
304                 of object references (i.e. "by-value" comparison), as two object
305                 references may have different apparent values yet refer to the
306                 same object.
307                 @param : obj
308                 an Accessible object reference to compare to 
309                 @return : a boolean indicating whether the two object references
310                 point to the same object.
311                 """
312                 return self == accessible
313
314         def get_childCount(self):
315                 return self._cache.get_application_count()
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 [interfaces.ATSPI_ACCESSIBLE, interfaces.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 == interfaces.ATSPI_ACCESSIBLE:
359                                 return self
360                 elif interface == interfaces.ATSPI_COMPONENT:
361                                 return DesktopComponent()
362                 else:
363                                 raise NotImplementedError(
364                                                 "%s not supported by accessible object at path %s"
365                                                 % (interface, self.path))
366
367 #END----------------------------------------------------------------------------