X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=pyatspi%2Fcache.py;h=8b2bde924c1a20836442ddc4df2c3192c1cd01ee;hb=d4b0723f4b3378f27dc15b76a549a5712673860c;hp=9113c76381bd946590df05adaef81f78a2500660;hpb=44f09457a5943064561849630015596a4d4528e6;p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git diff --git a/pyatspi/cache.py b/pyatspi/cache.py index 9113c76..8b2bde9 100644 --- a/pyatspi/cache.py +++ b/pyatspi/cache.py @@ -14,113 +14,162 @@ import dbus as _dbus -#------------------------------------------------------------------------------ - -class _CacheData(object): - __slots__ = [ - 'parent', - 'interfaces', - 'children', - 'role', - 'name', - 'description', - ] - - def __init__(self, data): - self.update(data) - - def update(self, data): - #Don't cache the path here, used as lookup in cache object dict. - (path, - self.parent, - self.children, - self.interfaces, - self.name, - self.role, - self.description) = data +from event import Event as _Event #------------------------------------------------------------------------------ -class _BaseCache(object): - - def __init__(self, connection, bus_name): - """ - Creates a cache. - - connection - DBus connection. - busName - Name of DBus connection where cache interface resides. - """ - self._connection = connection - self._bus_name = bus_name - - obj = connection.get_object(bus_name, self._PATH, introspect=False) - itf = _dbus.Interface(obj, self._INTERFACE) - - self._objects = {} - - get_method = itf.get_dbus_method(self._GET_METHOD) - self._update_objects(get_method()) - - self._signalMatch = itf.connect_to_signal(self._UPDATE_SIGNAL, self._update_handler) - - def __getitem__(self, key): - return self._objects[key] - - def __contains__(self, key): - return key in self._objects - - def _update_handler(self, updates): - update, remove = updates - self._remove_objects(update) - self._update_objects(remove) - - def _update_objects(self, objects): - for data in objects: - #First element is the object path. - path = data[0] - if path in self._objects: - cachedata = self._objects[path] - cachedata.update(data) - else: - self._objects[path] = _CacheData(data) - - def _remove_objects(self, paths): - for path in paths: - del(self._objects[path]) - +class _CacheData(object): + __slots__ = [ + 'parent', + 'interfaces', + 'children', + 'role', + 'name', + 'description', + ] + + def __init__(self, data): + self._update(data) + + def _update(self, data): + #Don't cache the path here, used as lookup in cache object dict. + (path, + self.parent, + self.children, + self.interfaces, + self.name, + self.role, + self.description) = data #------------------------------------------------------------------------------ -class AccessibleCache(_BaseCache): - """ - There is one accessible cache per application. - For each application the accessible cache stores - data on every accessible object within the app. - - It also acts as the factory for creating client - side proxies for these accessible objects. - - connection - DBus connection. - busName - Name of DBus connection where cache interface resides. - """ - - _PATH = '/org/freedesktop/atspi/tree' - _INTERFACE = 'org.freedesktop.atspi.Tree' - _GET_METHOD = 'getTree' - _UPDATE_SIGNAL = 'updateTree' - - def __init__(self, connection, bus_name): - _BaseCache.__init__(self, connection, bus_name) - - obj = connection.get_object(self._bus_name, self._PATH, introspect=False) - itf = _dbus.Interface(obj, self._INTERFACE) - - self._root = itf.getRoot() - - def _get_root(self): - return self._root - - root = property(fget=_get_root) - +class AccessibleCache(object): + """ + There is one accessible cache per application. + For each application the accessible cache stores + data on every accessible object within the app. + + It also acts as the factory for creating client + side proxies for these accessible objects. + + connection - DBus connection. + busName - Name of DBus connection where cache interface resides. + """ + + _PATH = '/org/freedesktop/atspi/tree' + _INTERFACE = 'org.freedesktop.atspi.Tree' + _GET_METHOD = 'getTree' + _UPDATE_SIGNAL = 'updateTree' + + def __init__(self, registry, connection, bus_name): + """ + Creates a cache. + + connection - DBus connection. + busName - Name of DBus connection where cache interface resides. + """ + self._registry = registry + self._connection = connection + self._bus_name = bus_name + + obj = connection.get_object(bus_name, self._PATH, introspect=False) + itf = _dbus.Interface(obj, self._INTERFACE) + + self._objects = {} + + get_method = itf.get_dbus_method(self._GET_METHOD) + self._update_objects(get_method()) + + self._signalMatch = itf.connect_to_signal(self._UPDATE_SIGNAL, self._update_handler) + + obj = connection.get_object(self._bus_name, self._PATH, introspect=False) + itf = _dbus.Interface(obj, self._INTERFACE) + + self._root = itf.getRoot() + + def __getitem__(self, key): + return self._objects[key] + + def __contains__(self, key): + return key in self._objects + + def _update_cache_dispatch_events(self, cachedata, data): + (path, + parent, + children, + interfaces, + name, + role, + description) = data + + # TODO The 'self._registry._cache' statement makes me think + # I have serious modularization FAIL here. + + if name != cachedata.name: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("name", 0, 0, name)) + self._registry._notifyNameChange(event) + + if description != cachedata.description: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("description", 0, 0, description)) + self._registry._notifyDescriptionChange(event) + + if parent != cachedata.parent: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("parent", 0, 0, "")) + self._registry._notifyParentChange(event) + + if children != cachedata.children: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "children-changed", + ("", 0, 0, "")) + self._registry._notifyChildrenChange(event) + + cachedata._update(data) + + def _update_handler(self, update, remove): + self._remove_objects(remove) + self._update_objects(update) + + def _update_objects(self, objects): + for data in objects: + #First element is the object path. + path = data[0] + if path in self._objects: + cachedata = self._objects[path] + self._update_cache_dispatch_events(cachedata, data) + else: + self._objects[path] = _CacheData(data) + + def _remove_objects(self, paths): + for path in paths: + # TODO I'm squashing a possible error here + # I've seen things appear to be deleted twice + # which needs investigation + try: + del(self._objects[path]) + except KeyError: + pass + + def _get_root(self): + return self._root + + root = property(fget=_get_root) #END---------------------------------------------------------------------------