2009-27-09 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 from interfaces import ATSPI_ACCESSIBLE, ATSPI_APPLICATION
16 from base import BaseProxy, Enum
17 from factory import accessible_factory
18 from state import StateSet, _marshal_state_set
19 from relation import _marshal_relation_set
20 from role import Role, ROLE_NAMES
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     _relation_set = None
96
97     def __nonzero__(self):
98             return True
99
100     def __len__(self):
101             return self.getChildCount()
102
103     def __getitem__(self, index):
104             return self.getChildAtIndex(index)
105
106     def getApplication(self):
107         """
108         Get the containing Application for this object.
109         @return the Application instance to which this object belongs.
110         """
111         return self._cache.create_application(self._app_name)
112
113     def getAttributes(self):
114         """
115         Get a list of properties applied to this object as a whole, as
116         an AttributeSet consisting of name-value pairs. As such these
117         attributes may be considered weakly-typed properties or annotations,
118         as distinct from the strongly-typed interface instance data declared
119         using the IDL "attribute" keyword.
120         Not all objects have explicit "name-value pair" AttributeSet
121         properties.
122         Attribute names and values may have any UTF-8 string value, however
123         where possible, in order to facilitate consistent use and exposure
124         of "attribute" properties by applications and AT clients, attribute
125         names and values should chosen from a publicly-specified namespace
126         where appropriate.
127         Where possible, the names and values in the name-value pairs
128         should be chosen from well-established attribute namespaces using
129         standard semantics. For example, attributes of Accessible objects
130         corresponding to XHTML content elements should correspond to
131         attribute names and values specified in the w3c XHTML specification,
132         at http://www.w3.org/TR/xhtml2, where such values are not already
133         exposed via a more strongly-typed aspect of the AT-SPI API. Metadata
134         names and values should be chosen from the 'Dublin Core' Metadata
135         namespace using Dublin Core semantics: http://dublincore.org/dcregistry/
136         Similarly, relevant structural metadata should be exposed using
137         attribute names and values chosen from the CSS2 and WICD specification:
138         http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/).
139
140         @return : An AttributeSet encapsulating any "attribute values"
141         currently defined for the object. An attribute set is a list of strings
142         with each string comprising an name-value pair format 'name:value'.
143         """
144         func = self.get_dbus_method("getAttributes", dbus_interface=ATSPI_ACCESSIBLE)
145         return [key + ':' + value for key, value in func().iteritems()]
146
147     def getChildAtIndex(self, index):
148         """
149         Get the accessible child of this object at index. 
150         @param : index
151         an in parameter indicating which child is requested (zero-indexed).
152         @return : the 'nth' Accessible child of this object.
153         """
154         path = self.cached_data.children[index]
155         return self._cache.create_accessible(self._app_name, path, ATSPI_ACCESSIBLE)
156
157     def getIndexInParent(self):
158         """
159         Get the index of this object in its parent's child list.
160         @return : a long integer indicating this object's index in the
161         parent's list.
162         """
163         if self.parent == None:
164                 return -1
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", dbus_interface=ATSPI_ACCESSIBLE)
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         if self._relation_set:
188                 return self._relation_set
189         else:
190                 func = self.get_dbus_method("getRelationSet", dbus_interface=ATSPI_ACCESSIBLE)
191                 relation_set = func()
192                 self._relation_set = _marshal_relation_set(self._cache, self._app_name, relation_set)
193                 return self._relation_set
194
195     def getRole(self):
196         """
197         Get the Role indicating the type of UI role played by this object.
198         @return : a Role indicating the type of UI role played by this
199         object.
200         """
201         return Role(self.cached_data.role)
202
203     def getRoleName(self):
204         """
205         Get a string indicating the type of UI role played by this object.
206         @return : a UTF-8 string indicating the type of UI role played
207         by this object.
208         """
209         """
210         func = self.get_dbus_method("getRoleName", dbus_interface=ATSPI_ACCESSIBLE)
211         return func()
212         """
213         return ROLE_NAMES[self.cached_data.role]
214
215     def getState(self):
216         """
217         Get the current state of the object as a StateSet. 
218         @return : a StateSet encapsulating the currently true states
219         of the object.
220         """
221         return _marshal_state_set(self.cached_data.state)
222
223     def isEqual(self, accessible):
224         """
225         Determine whether an Accessible refers to the same object as
226         another. This method should be used rather than brute-force comparison
227         of object references (i.e. "by-value" comparison), as two object
228         references may have different apparent values yet refer to the
229         same object.
230         @param : obj
231         an Accessible object reference to compare to 
232         @return : a boolean indicating whether the two object references
233         point to the same object.
234         """
235         return  (self._app_name == accessible._app_name) and \
236                 (self._acc_path == accessible._acc_path)
237
238
239     def get_childCount(self):
240         return len(self.cached_data.children)
241     _childCountDoc = \
242         """
243         childCount: the number of children contained by this object.
244         """
245     childCount = property(fget=get_childCount, doc=_childCountDoc)
246
247     getChildCount = get_childCount
248
249     def get_description(self):
250         return self.cached_data.description
251     _descriptionDoc = \
252         """
253         a string describing the object in more detail than name.
254         """
255     description = property(fget=get_description, doc=_descriptionDoc)
256
257     def get_name(self):
258         return self.cached_data.name
259     _nameDoc = \
260         """
261         a (short) string representing the object's name.
262         """
263     name = property(fget=get_name, doc=_nameDoc)
264
265     def get_parent(self):
266         return self._cache.create_accessible(self._app_name,
267                                              self.cached_data.parent,
268                                              ATSPI_ACCESSIBLE)
269
270     _parentDoc = \
271         """
272         an Accessible object which is this object's containing object.
273         """
274     parent = property(fget=get_parent, doc=_parentDoc)
275
276     def refresh(self):
277             self._relation_set = None
278             self._cache.application_cache[self._app_name]._refresh()
279
280 # Register the accessible class with the factory.
281 accessible_factory.register_accessible_class(ATSPI_ACCESSIBLE, Accessible)
282
283 #END----------------------------------------------------------------------------