1 #Copyright (C) 2008 Codethink Ltd
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.
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.
16 from dbus.proxies import Interface
17 from dbus.exceptions import *
22 "AccessibleObjectNoLongerExists",
23 "AccessibleObjectNotAvailable",
29 class AccessibleObjectNoLongerExists(Exception):
32 class AccessibleObjectNotAvailable(Exception):
35 #------------------------------------------------------------------------------
37 def _repack_tuple (tup):
39 Re-packs a tuple moving the last element to the beginning.
41 return (tup[-1] ,) + tup[:-1]
43 #------------------------------------------------------------------------------
45 class Enum(dbus.UInt32):
47 return self._enum_lookup[int(self)]
49 def __eq__(self, other):
52 if int(self) == int(other):
60 #------------------------------------------------------------------------------
63 class BaseProxyMeta(type):
64 def __new__(meta, *args, **kwargs):
65 cls = type.__new__(meta, *args, **kwargs)
67 queryable_interfaces = {
68 'Accessible':interfaces.ATSPI_ACCESSIBLE,
69 'Action':interfaces.ATSPI_ACTION,
70 'Application':interfaces.ATSPI_APPLICATION,
71 'Collection':interfaces.ATSPI_COLLECTION,
72 'Component':interfaces.ATSPI_COMPONENT,
73 'Desktop':interfaces.ATSPI_DESKTOP,
74 'Document':interfaces.ATSPI_DOCUMENT,
75 'EditableText':interfaces.ATSPI_EDITABLE_TEXT,
76 'Hypertext':interfaces.ATSPI_HYPERTEXT,
77 'Hyperlink':interfaces.ATSPI_HYPERLINK,
78 'Image':interfaces.ATSPI_IMAGE,
79 'Selection':interfaces.ATSPI_SELECTION,
80 'StreamableContent':interfaces.ATSPI_STREAMABLE_CONTENT,
81 'Table':interfaces.ATSPI_TABLE,
82 'Text':interfaces.ATSPI_TEXT,
83 'Value':interfaces.ATSPI_VALUE,
86 def return_query(interface):
88 return self.queryInterface(interface)
91 for interface in queryable_interfaces.keys():
92 name = 'query%s' % interface
93 setattr(cls, name, return_query(queryable_interfaces[interface]))
97 #------------------------------------------------------------------------------
99 class BaseProxy(object):
101 The base D-Bus proxy for a remote object that implements one or more
102 of the AT-SPI interfaces.
105 __metaclass__ = BaseProxyMeta
107 def __init__(self, app_name, acc_path, cache, interface, dbus_object=None):
109 Create a D-Bus Proxy for an ATSPI interface.
111 cache - ApplicationCache, where the cached data for the accessible can be obtained.
112 app_name - D-Bus bus name of the application this accessible belongs to.
113 acc_path - D-Bus object path of the server side accessible object.
114 parent - Parent accessible.
115 dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls.
118 self._app_name = app_name
119 self._acc_path = acc_path
120 self._dbus_interface = interface
123 dbus_object = cache.connection.get_object(self._app_name,
126 self._dbus_object = dbus_object
128 self._pgetter = self.get_dbus_method("Get",
129 dbus_interface="org.freedesktop.DBus.Properties")
130 self._psetter = self.get_dbus_method("Set",
131 dbus_interface="org.freedesktop.DBus.Properties")
135 return '[%s | %s]' % (self.getRoleName(), self.name)
139 def __eq__(self, other):
143 if self._app_name == other._app_name and \
144 self._acc_path == other._acc_path:
148 except AttributeError:
151 def __ne__(self, other):
152 return not self.__eq__(other)
155 return hash(self._app_name + self._acc_path)
157 def get_dbus_method(self, *args, **kwargs):
158 method = self._dbus_object.get_dbus_method(*args, **kwargs)
160 def dbus_method_func(*iargs, **ikwargs):
161 # TODO Need to throw an AccessibleObjectNoLongerExists exception
162 # on D-Bus error of the same type.
164 return method(*iargs, **ikwargs)
165 except UnknownMethodException, e:
166 raise NotImplementedError(e)
167 except DBusException, e:
170 return dbus_method_func
173 def cached_data(self):
175 return self._cache.get_cache_data(self._app_name, self._acc_path)
177 raise AccessibleObjectNoLongerExists, \
178 'Cache data cannot be found for path %s in app %s' % (self._acc_path, self._app_name)
181 def interfaces(self):
182 return self.cached_data.interfaces
184 def queryInterface(self, interface):
186 Gets a different accessible interface for this object
187 or raises a NotImplemented error if the given interface
190 if interface in self.interfaces:
191 return self._cache.create_accessible(self._app_name,
194 dbus_object=self._dbus_object)
196 raise NotImplementedError(
197 "%s not supported by accessible object at path %s"
198 % (interface, self._acc_path))
200 def flushCache(self):
203 #END----------------------------------------------------------------------------