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