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.
17 from accessiblecache import AccessibleCache
18 from desktop import Desktop
19 from factory import accessible_factory
20 from event import Event as _Event
21 from base import AccessibleObjectNotAvailable
23 from interfaces import *
27 "TestApplicationCache",
30 #------------------------------------------------------------------------------
32 class TestApplicationCache(object):
33 _DESKTOP_PATH = '/org/freedesktop/atspi/accessible/desktop'
36 Test application store, accesses a single application.
38 The store object acts as a central class for creating accessible objects.
39 It interfaces with the ATSPI registry to keep account of all accessible
40 applications. It contains the accessible cache objects from each application.
42 @registry: Each accessible cache object must have a reference to the registry
43 object to send update events.
45 @connection: D-Bus connection used to access applications.
47 @bus_name: The test store only accesses one accessible application, this is its
51 def __init__(self, registry, connection, bus_name):
52 self._connection = connection
54 self.application_list = [bus_name]
55 self.application_cache = {bus_name:AccessibleCache(registry, connection, bus_name)}
57 def get_cache_data(self, app_name, acc_path):
59 Returns the cache tuple for the given application and accessible
60 object path. Throws an IndexError if the cache data is not found.
62 return self.application_cache[app_name][acc_path]
64 def create_application(self, app_name):
66 Creates an accessible object for the root of the application
67 available at the given D-Bus name.
69 cls = accessible_factory.get_accessible_class(ATSPI_APPLICATION)
71 return cls(app_name, self.application_cache[app_name].root, self, ATSPI_APPLICATION)
73 raise AccessibleObjectNotAvailable ()
75 def create_accessible(self, app_name, acc_path, interface, dbus_object=None):
77 Creates an accessible object.
79 @app_name: D-Bus name of the application where the accessible object resides.
81 @acc_path: D-Bus path of the object within the application.
83 @interface: D-Bus interface of the requested object. A different accessible object
84 class will be created depending on this. Making the function much like
85 an accessible object factory.
87 @dbus_object: If a D-Bus object already exists for the accessible object it can be
88 provided here so that another one is not created.
90 # An acc_path of '/' implies the desktop object, whatever the app_name.
91 if acc_path == TestApplicationCache._DESKTOP_PATH:
94 cls = accessible_factory.get_accessible_class(interface)
96 return cls(app_name, acc_path, self, interface, dbus_object=dbus_object)
98 raise AccessibleObjectNotAvailable ()
101 def connection(self):
103 D-Bus connection used by the store.
105 return self._connection
107 #------------------------------------------------------------------------------
109 class ApplicationCache(object):
111 Test application store, accesses a single application.
113 The store object acts as a central class for creating accessible objects.
114 It interfaces with the ATSPI registry to keep account of all accessible
115 applications. It contains the accessible cache objects from each application.
117 @registry: Each accessible cache object must have a reference to the registry
118 object to send update events.
120 @connection: D-Bus connection used to access applications.
122 @bus_name: The test store only accesses one accessible application, this is its
126 # An accessible path of '/' implies the desktop object, whatever the application name.
127 _DESKTOP_PATH = '/org/freedesktop/atspi/accessible/root'
129 _APPLICATIONS_ADD = 1
130 _APPLICATIONS_REMOVE = 0
132 def __init__(self, registry, connection):
133 self._connection = connection
134 self._registry = registry
136 self.application_list = []
137 self.application_cache = {}
139 self._regsig = connection.add_signal_receiver(self.update_handler,
140 dbus_interface=ATSPI_REGISTRY_INTERFACE,
141 signal_name="updateApplications")
143 obj = connection.get_object(ATSPI_REGISTRY_NAME,
146 self._app_register = dbus.Interface(obj, ATSPI_REGISTRY_INTERFACE)
148 self.application_list.extend(self._app_register.getApplications())
149 for bus_name in self.application_list:
150 self.application_cache[bus_name] = AccessibleCache(self._registry, self._connection, bus_name)
152 def update_handler (self, update_type, bus_name):
153 if update_type == ApplicationCache._APPLICATIONS_ADD:
154 #TODO Check that app does not already exist
155 self.application_list.append(bus_name)
156 self.application_cache[bus_name] = AccessibleCache(self._registry, self._connection, bus_name)
158 ApplicationCache._DESKTOP_PATH,
160 "org.freedesktop.atspi.Event.Object",
163 elif update_type == ApplicationCache._APPLICATIONS_REMOVE:
164 #TODO Fail safely if app does not exist
165 self.application_list.remove(bus_name)
166 del(self.application_cache[bus_name])
168 ApplicationCache._DESKTOP_PATH,
170 "org.freedesktop.atspi.Event.Object",
172 ("remove", 0, 0, ""))
174 self._registry._notifyChildrenChange(event)
176 def get_cache_data(self, app_name, acc_path):
178 Returns the cache tuple for the given application and accessible
179 object path. Throws an IndexError if the cache data is not found.
181 return self.application_cache[app_name][acc_path]
183 def create_application(self, app_name):
185 Creates an accessible object for the root of the application
186 available at the given D-Bus name.
188 if app_name == ATSPI_REGISTRY_NAME:
191 cls = accessible_factory.get_accessible_class(ATSPI_APPLICATION)
193 return cls(app_name, self.application_cache[app_name].root, self, ATSPI_APPLICATION)
195 raise AccessibleObjectNotAvailable ()
197 def create_accessible(self, app_name, acc_path, interface, dbus_object=None):
199 Creates an accessible object.
201 @app_name: D-Bus name of the application where the accessible object resides.
203 @acc_path: D-Bus path of the object within the application.
205 @interface: D-Bus interface of the requested object. A different accessible object
206 class will be created depending on this. Making the function much like
207 an accessible object factory.
209 @dbus_object: If a D-Bus object already exists for the accessible object it can be
210 provided here so that another one is not created.
212 if acc_path == ApplicationCache._DESKTOP_PATH:
215 cls = accessible_factory.get_accessible_class(interface)
217 return cls(app_name, acc_path, self, interface, dbus_object=dbus_object)
219 raise AccessibleObjectNotAvailable ()
222 def connection(self):
224 D-Bus connection used by the store.
226 return self._connection
228 #END----------------------------------------------------------------------------