X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=pyatspi%2Fbase.py;h=438f9e5dee7d6498ad3a15e12d1d3ecce2e30617;hb=a84790a040a990322261952a8e6dc7939c5f92b3;hp=8f237133b104654cd04539c6190f398761c71294;hpb=91308d34413609f0d82dd0e280d3ee76229bd555;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/pyatspi/base.py b/pyatspi/base.py index 8f23713..438f9e5 100644 --- a/pyatspi/base.py +++ b/pyatspi/base.py @@ -12,115 +12,169 @@ #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from weakref import ref - -from dbus.proxies import Interface, ProxyObject +import dbus +from dbus.proxies import Interface from dbus.exceptions import * -from factory import interfaceFactory +import interfaces + +__all__ = [ + "AccessibleObjectNoLongerExists", + "AccessibleObjectNotAvailable", + "Enum", + "BaseProxy", + ] class AccessibleObjectNoLongerExists(Exception): - pass + pass + +class AccessibleObjectNotAvailable(Exception): + pass #------------------------------------------------------------------------------ -class Enum(object): - def __str__(self): - return self._enum_lookup(int(self)) +class Enum(uint): + def __str__(self): + return self._enum_lookup[int(self)] #------------------------------------------------------------------------------ + class BaseProxyMeta(type): - def __init__(cls): - type.__init__(cls) - - queryable_interfaces = { - 'Accessible':ATSPI_ACCESSIBLE, - 'Action':ATSPI_ACTION, - 'Application':ATSPI_APPLICATION, - 'Collection':ATSPI_COLLECTION, - 'Component':ATSPI_COMPONENT, - 'Desktop':ATSPI_DESKTOP, - 'Document':ATSPI_DOCUMENT, - 'EditableText':ATSPI_EDITABLE_TEXT, - 'Hypertext':ATSPI_HYPERTEXT, - 'Hyperlink':ATSPI_HYPERLINK, - 'Image':ATSPI_IMAGE, - 'Selection':ATSPI_SELECTION, - 'StreamableContent':ATSPI_STREAMABLE_CONTENT, - 'Table':ATSPI_TABLE, - 'Text':ATSPI_TEXT, - 'Value':ATSPI_VALUE, - } - - for interface in queryable_interfaces.keys(): - name = 'query%s' % interface - def new_query(self, object): - return self.queryInterface(object, queryable_interfaces[interface]) - setattr(cls, name, new_query) + def __new__(meta, *args, **kwargs): + cls = type.__new__(meta, *args, **kwargs) + + queryable_interfaces = { + 'Accessible':interfaces.ATSPI_ACCESSIBLE, + 'Action':interfaces.ATSPI_ACTION, + 'Application':interfaces.ATSPI_APPLICATION, + 'Collection':interfaces.ATSPI_COLLECTION, + 'Component':interfaces.ATSPI_COMPONENT, + 'Desktop':interfaces.ATSPI_DESKTOP, + 'Document':interfaces.ATSPI_DOCUMENT, + 'EditableText':interfaces.ATSPI_EDITABLE_TEXT, + 'Hypertext':interfaces.ATSPI_HYPERTEXT, + 'Hyperlink':interfaces.ATSPI_HYPERLINK, + 'Image':interfaces.ATSPI_IMAGE, + 'Selection':interfaces.ATSPI_SELECTION, + 'StreamableContent':interfaces.ATSPI_STREAMABLE_CONTENT, + 'Table':interfaces.ATSPI_TABLE, + 'Text':interfaces.ATSPI_TEXT, + 'Value':interfaces.ATSPI_VALUE, + } + + def return_query(interface): + def new_query(self): + return self.queryInterface(interface) + return new_query + + for interface in queryable_interfaces.keys(): + name = 'query%s' % interface + setattr(cls, name, return_query(queryable_interfaces[interface])) + + return cls #------------------------------------------------------------------------------ -class BaseProxy(Interface): - """ - A D-Bus proxy for a remote object that implements one or more of the AT-SPI - Accessibility interfaces. - """ - - __metaclass__ = BaseProxyMeta - - def __init__(self, busobject, cache, app, path, interface): - """ - Create a D-Bus Proxy for an ATSPI interface. - - busobject - The D-Bus proxy object this interface uses for D-Bus calls. - cache - The accessible cache that this object is owned by. - path - The object path of the remote object. - app - The bus name of the application this object belongs to. - interface - The name of the ATSPI interface that this proxy implements. - """ - Interface.__init__(self, busobject, interface) - - self._cache = cache - - self._path = path - self._app = app - - self._pgetter = self.get_dbus_method("Get", dbus_interface="org.freedesktop.DBus.Properties") - self._psetter = self.get_dbus_method("Set", dbus_interface="org.freedesktop.DBus.Properties") - - def __getattr__(self, *args, **kwargs): - """ - The __getattr__ function must return the D-Bus method wrapped in a - method to translate exceptions. - """ - # Need to throw an AccessibleObjectNoLongerExists exception - # on D-Bus error of the same type. - try: - return Interface.__getattr__(self, *args, **kwargs) - except UnknownMethodException, e: - raise NotImplementedError(e) - except DBusException, e: - raise LookupError(e) - - @property - def _data(self): - try: - data = self._cache._objects[self._path] - except KeyError: - raise AccessibleObjectNoLongerExists, 'Cache data cannot be found for path %s' % (self._path,) - return data - - @property - def interfaces(self): - return self._data.interfaces - - def queryInterface(self, interface): - if interface in self._data.interfaces: - return interfaceFactory(self._obj, self._cache, self._app, self._path, interface) - else: - raise NotImplementedError( - "%s not supported by accessible object at path %s" - % (interface, self.path)) +class BaseProxy(object): + """ + The base D-Bus proxy for a remote object that implements one or more + of the AT-SPI interfaces. + """ + + __metaclass__ = BaseProxyMeta + + def __init__(self, app_name, acc_path, cache, interface, dbus_object=None): + """ + Create a D-Bus Proxy for an ATSPI interface. + + cache - ApplicationCache, where the cached data for the accessible can be obtained. + app_name - D-Bus bus name of the application this accessible belongs to. + acc_path - D-Bus object path of the server side accessible object. + parent - Parent accessible. + dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls. + """ + self._cache = cache + self._app_name = app_name + self._acc_path = acc_path + self._dbus_interface = interface + + if not dbus_object: + dbus_object = cache.connection.get_object(self._app_name, + self._acc_path, + introspect=False) + self._dbus_object = dbus_object + + self._pgetter = self.get_dbus_method("Get", + dbus_interface="org.freedesktop.DBus.Properties") + self._psetter = self.get_dbus_method("Set", + dbus_interface="org.freedesktop.DBus.Properties") + + def __str__(self): + try: + return '[%s | %s]' % (self.getRoleName(), self.name) + except Exception: + return '[DEAD]' + + def __eq__(self, other): + if other is None: + return False + try: + if self._app_name == other._app_name and \ + self._acc_path == other._acc_path: + return True + else: + return False + except AttributeError: + return False + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return hash(self._app_name + self._acc_path) + + def get_dbus_method(self, *args, **kwargs): + method = self._dbus_object.get_dbus_method(*args, **kwargs) + + def dbus_method_func(*iargs, **ikwargs): + # TODO Need to throw an AccessibleObjectNoLongerExists exception + # on D-Bus error of the same type. + try: + return method(*iargs, **ikwargs) + except UnknownMethodException, e: + raise NotImplementedError(e) + except DBusException, e: + raise LookupError(e) + + return dbus_method_func + + @property + def cached_data(self): + try: + return self._cache.get_cache_data(self._app_name, self._acc_path) + except KeyError: + raise AccessibleObjectNoLongerExists, \ + 'Cache data cannot be found for path %s in app %s' % (self._acc_path, self._app_name) + + @property + def interfaces(self): + return self.cached_data.interfaces + + def queryInterface(self, interface): + """ + Gets a different accessible interface for this object + or raises a NotImplemented error if the given interface + is not supported. + """ + if interface in self.interfaces: + return self._cache.create_accessible(self._app_name, + self._acc_path, + interface, + dbus_object=self._dbus_object) + else: + raise NotImplementedError( + "%s not supported by accessible object at path %s" + % (interface, self._acc_path)) #END----------------------------------------------------------------------------