2008-08-27 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / pyatspi / accessible.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 BaseProxy, Enum
17 from factory import create_accessible, add_accessible_class
18 from state import StateSet, _marshal_state_set
19 from relation import _marshal_relation_set
20 from role import Role
21
22 __all__ = [
23            "LOCALE_TYPE",
24            "LOCALE_TYPE_COLLATE",
25            "LOCALE_TYPE_CTYPE",
26            "LOCALE_TYPE_MESSAGES",
27            "LOCALE_TYPE_MONETARY",
28            "LOCALE_TYPE_NUMERIC",
29            "LOCALE_TYPE_TIME",
30            "BoundingBox",
31            "Accessible",
32           ]
33
34 #------------------------------------------------------------------------------
35
36 class LOCALE_TYPE(Enum):
37     _enum_lookup = {
38         0:'LOCALE_TYPE_MESSAGES',
39         1:'LOCALE_TYPE_COLLATE',
40         2:'LOCALE_TYPE_CTYPE',
41         3:'LOCALE_TYPE_MONETARY',
42         4:'LOCALE_TYPE_NUMERIC',
43         5:'LOCALE_TYPE_TIME',
44     }
45
46 LOCALE_TYPE_COLLATE = LOCALE_TYPE(1)
47 LOCALE_TYPE_CTYPE = LOCALE_TYPE(2)
48 LOCALE_TYPE_MESSAGES = LOCALE_TYPE(0)
49 LOCALE_TYPE_MONETARY = LOCALE_TYPE(3)
50 LOCALE_TYPE_NUMERIC = LOCALE_TYPE(4)
51 LOCALE_TYPE_TIME = LOCALE_TYPE(5)
52
53 #------------------------------------------------------------------------------
54
55 class BoundingBox(list):
56     def __new__(cls, x, y, width, height):
57         return list.__new__(cls, (x, y, width, height))
58     def __init__(self, x, y, width, height):
59         list.__init__(self, (x, y, width, height))
60     
61     def _get_x(self):
62         return self[0]
63     def _set_x(self, val):
64         self[0] = val
65     x = property(fget=_get_x, fset=_set_x)
66     def _get_y(self):
67         return self[1]
68     def _set_y(self, val):
69         self[1] = val
70     y = property(fget=_get_y, fset=_set_y)
71     def _get_width(self):
72         return self[2]
73     def _set_width(self, val):
74         self[2] = val
75     width = property(fget=_get_width, fset=_set_width)
76     def _get_height(self):
77         return self[3]
78     def _set_height(self, val):
79         self[3] = val
80     height = property(fget=_get_height, fset=_set_height)
81
82 #------------------------------------------------------------------------------
83
84 class Accessible(BaseProxy):
85     """
86     The base interface which is implemented by all accessible objects.
87     All objects support interfaces for querying their contained
88     'children' and position in the accessible-object hierarchy,
89     whether or not they actually have children.
90     """
91
92     def __len__(self):
93             return self.getChildCount()
94
95     def __getitem__(self, index):
96             return self.getChildAtIndex(index)
97     
98     def getApplication(self):
99         """
100         Get the containing Application for this object.
101         @return the Application instance to which this object belongs.
102         """
103         application_root = self._cache[self._app_name]._get_root()
104         #TODO Set the desktop object as the parent of this.
105         return create_accessible(self._cache,
106                                  self._app_name,
107                                  application_root,
108                                  interfaces.ATSPI_APPLICATION,
109                                  connection=self._cache._connection)
110     
111     def getAttributes(self):
112         """
113         Get a list of properties applied to this object as a whole, as
114         an AttributeSet consisting of name-value pairs. As such these
115         attributes may be considered weakly-typed properties or annotations,
116         as distinct from the strongly-typed interface instance data declared
117         using the IDL "attribute" keyword.
118         Not all objects have explicit "name-value pair" AttributeSet
119         properties.
120         Attribute names and values may have any UTF-8 string value, however
121         where possible, in order to facilitate consistent use and exposure
122         of "attribute" properties by applications and AT clients, attribute
123         names and values should chosen from a publicly-specified namespace
124         where appropriate.
125         Where possible, the names and values in the name-value pairs
126         should be chosen from well-established attribute namespaces using
127         standard semantics. For example, attributes of Accessible objects
128         corresponding to XHTML content elements should correspond to
129         attribute names and values specified in the w3c XHTML specification,
130         at http://www.w3.org/TR/xhtml2, where such values are not already
131         exposed via a more strongly-typed aspect of the AT-SPI API. Metadata
132         names and values should be chosen from the 'Dublin Core' Metadata
133         namespace using Dublin Core semantics: http://dublincore.org/dcregistry/
134         Similarly, relevant structural metadata should be exposed using
135         attribute names and values chosen from the CSS2 and WICD specification:
136         http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/).
137
138         @return : An AttributeSet encapsulating any "attribute values"
139         currently defined for the object. An attribute set is a list of strings
140         with each string comprising an name-value pair format 'name:value'.
141         """
142         func = self.get_dbus_method("getAttributes")
143         return func()
144     
145     def getChildAtIndex(self, index):
146         """
147         Get the accessible child of this object at index. 
148         @param : index
149         an in parameter indicating which child is requested (zero-indexed).
150         @return : the 'nth' Accessible child of this object.
151         """
152         path = self.cached_data.children[index]
153         return create_accessible(self._cache,
154                                  self._app_name,
155                                  path,
156                                  interfaces.ATSPI_ACCESSIBLE,
157                                  connection=self._cache._connection)
158     
159     def getIndexInParent(self):
160         """
161         Get the index of this object in its parent's child list. 
162         @return : a long integer indicating this object's index in the
163         parent's list.
164         """
165         for i in range(0, self.parent.childCount):
166                 child = self.parent.getChildAtIndex(i)
167                 if self.isEqual(child):
168                         return i
169         raise AccessibleObjectNoLongerExists("Child not found within parent")
170     
171     def getLocalizedRoleName(self):
172         """
173         Get a string indicating the type of UI role played by this object,
174         translated to the current locale.
175         @return : a UTF-8 string indicating the type of UI role played
176         by this object.
177         """
178         func = self.get_dbus_method("getLocalizedRoleName")
179         return func()
180     
181     def getRelationSet(self):
182         """
183         Get a set defining this object's relationship to other accessible
184         objects. 
185         @return : a RelationSet defining this object's relationships.
186         """
187         func = self.get_dbus_method("getRelationSet")
188         relation_set = func()
189         return _marshal_relation_set(self._cache, self._app_name, relation_set)
190     
191     def getRole(self):
192         """
193         Get the Role indicating the type of UI role played by this object.
194         @return : a Role indicating the type of UI role played by this
195         object.
196         """
197         return Role(self.cached_data.role)
198     
199     def getRoleName(self):
200         """
201         Get a string indicating the type of UI role played by this object.
202         @return : a UTF-8 string indicating the type of UI role played
203         by this object.
204         """
205         func = self.get_dbus_method("getRoleName")
206         return func()
207     
208     def getState(self):
209         """
210         Get the current state of the object as a StateSet. 
211         @return : a StateSet encapsulating the currently true states
212         of the object.
213         """
214         func = self.get_dbus_method("getState")
215         bitfield = func()
216         return _marshal_state_set(bitfield)
217     
218     def isEqual(self, accessible):
219         """
220         Determine whether an Accessible refers to the same object as
221         another. This method should be used rather than brute-force comparison
222         of object references (i.e. "by-value" comparison), as two object
223         references may have different apparent values yet refer to the
224         same object.
225         @param : obj
226         an Accessible object reference to compare to 
227         @return : a boolean indicating whether the two object references
228         point to the same object.
229         """
230         return  (self._app_name == accessible._app_name) and \
231                 (self._acc_path == accessible._acc_path)        
232     
233     def get_childCount(self):
234         return len(self.cached_data.children)
235     _childCountDoc = \
236         """
237         childCount: the number of children contained by this object.
238         """
239     childCount = property(fget=get_childCount, doc=_childCountDoc)
240     
241     def get_description(self):
242         return self.cached_data.description
243     _descriptionDoc = \
244         """
245         a string describing the object in more detail than name.
246         """
247     description = property(fget=get_description, doc=_descriptionDoc)
248     
249     def get_name(self):
250         return self.cached_data.name
251     _nameDoc = \
252         """
253         a (short) string representing the object's name.
254         """
255     name = property(fget=get_name, doc=_nameDoc)
256     
257     def get_parent(self):
258         if self._parent:
259                 return self._parent
260         else:
261                 return create_accessible(self._cache,
262                                          self._app_name,
263                                          self.cached_data.parent,
264                                          interfaces.ATSPI_ACCESSIBLE,
265                                          connection=self._cache._connection)
266
267     _parentDoc = \
268         """
269         an Accessible object which is this object's containing object.
270         """
271     parent = property(fget=get_parent, doc=_parentDoc)
272
273 # Register the Accessible class with the accessible factory.
274 add_accessible_class(interfaces.ATSPI_ACCESSIBLE, Accessible)
275
276 #END----------------------------------------------------------------------------