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, DESKTOP_PATH
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 ROOT_PATH = '/org/freedesktop/atspi/accessible/root'
34 #------------------------------------------------------------------------------
36 class TestApplicationCache(object):
39 Test application store, accesses a single application.
41 The store object acts as a central class for creating accessible objects.
42 It interfaces with the ATSPI registry to keep account of all accessible
43 applications. It contains the accessible cache objects from each application.
45 @registry: Each accessible cache object must have a reference to the registry
46 object to send update events.
48 @connection: D-Bus connection used to access applications.
50 @bus_name: The test store only accesses one accessible application, this is its
54 def __init__(self, registry, connection, bus_name):
55 self._connection = connection
57 self.application_list = [bus_name]
58 self.application_cache = {bus_name:AccessibleCache(registry, connection, bus_name)}
60 def get_cache_data(self, app_name, acc_path):
62 Returns the cache tuple for the given application and accessible
63 object path. Throws an IndexError if the cache data is not found.
65 return self.application_cache[app_name][acc_path]
67 def create_application(self, app_name):
69 Creates an accessible object for the root of the application
70 available at the given D-Bus name.
72 cls = accessible_factory.get_accessible_class(ATSPI_APPLICATION)
74 return cls(app_name, self.application_cache[app_name].root, self, ATSPI_APPLICATION)
76 raise AccessibleObjectNotAvailable ()
78 def create_accessible(self, app_name, acc_path, interface, dbus_object=None):
80 Creates an accessible object.
82 @app_name: D-Bus name of the application where the accessible object resides.
84 @acc_path: D-Bus path of the object within the application.
86 @interface: D-Bus interface of the requested object. A different accessible object
87 class will be created depending on this. Making the function much like
88 an accessible object factory.
90 @dbus_object: If a D-Bus object already exists for the accessible object it can be
91 provided here so that another one is not created.
93 # An acc_path of '/' implies the desktop object, whatever the app_name.
94 if acc_path == DESKTOP_PATH:
96 if acc_path == ROOT_PATH:
99 cls = accessible_factory.get_accessible_class(interface)
101 return cls(app_name, acc_path, self, interface, dbus_object=dbus_object)
103 raise AccessibleObjectNotAvailable ()
106 def connection(self):
108 D-Bus connection used by the store.
110 return self._connection
112 #------------------------------------------------------------------------------
114 class ApplicationCache(object):
116 Test application store, accesses a single application.
118 The store object acts as a central class for creating accessible objects.
119 It interfaces with the ATSPI registry to keep account of all accessible
120 applications. It contains the accessible cache objects from each application.
122 @registry: Each accessible cache object must have a reference to the registry
123 object to send update events.
125 @connection: D-Bus connection used to access applications.
127 @bus_name: The test store only accesses one accessible application, this is its
131 _APPLICATIONS_ADD = 1
132 _APPLICATIONS_REMOVE = 0
134 def __init__(self, registry, connection):
135 self._connection = connection
136 self._registry = registry
138 self.application_list = []
139 self.application_cache = {}
141 self._regsig = connection.add_signal_receiver(self.update_handler,
142 dbus_interface=ATSPI_REGISTRY_INTERFACE,
143 signal_name="updateApplications")
145 obj = connection.get_object(ATSPI_REGISTRY_NAME,
148 self._app_register = dbus.Interface(obj, ATSPI_REGISTRY_INTERFACE)
150 self.application_list.extend(self._app_register.getApplications())
151 for bus_name in self.application_list:
152 self.application_cache[bus_name] = AccessibleCache(self._registry, self._connection, bus_name)
154 def update_handler (self, update_type, bus_name):
155 if update_type == ApplicationCache._APPLICATIONS_ADD:
156 #TODO Check that app does not already exist
157 #TODO Excuding this app is a hack, need to have re-entrant method calls.
158 if bus_name != self._connection.get_unique_name ():
159 self.application_list.append(bus_name)
160 self.application_cache[bus_name] = AccessibleCache(self._registry,
166 "org.freedesktop.atspi.Event.Object",
169 elif update_type == ApplicationCache._APPLICATIONS_REMOVE:
170 #TODO Fail safely if app does not exist
171 self.application_list.remove(bus_name)
172 del(self.application_cache[bus_name])
176 "org.freedesktop.atspi.Event.Object",
178 ("remove", 0, 0, ""))
180 self._registry._notifyChildrenChange(event)
182 def get_cache_data(self, app_name, acc_path):
184 Returns the cache tuple for the given application and accessible
185 object path. Throws an IndexError if the cache data is not found.
187 return self.application_cache[app_name][acc_path]
189 def create_application(self, app_name):
191 Creates an accessible object for the root of the application
192 available at the given D-Bus name.
194 if app_name == ATSPI_REGISTRY_NAME:
197 cls = accessible_factory.get_accessible_class(ATSPI_APPLICATION)
199 return cls(app_name, self.application_cache[app_name].root, self, ATSPI_APPLICATION)
201 raise AccessibleObjectNotAvailable ()
203 def create_accessible(self, app_name, acc_path, interface, dbus_object=None):
205 Creates an accessible object.
207 @app_name: D-Bus name of the application where the accessible object resides.
209 @acc_path: D-Bus path of the object within the application.
211 @interface: D-Bus interface of the requested object. A different accessible object
212 class will be created depending on this. Making the function much like
213 an accessible object factory.
215 @dbus_object: If a D-Bus object already exists for the accessible object it can be
216 provided here so that another one is not created.
218 if acc_path == DESKTOP_PATH:
220 if acc_path == ROOT_PATH:
223 cls = accessible_factory.get_accessible_class(interface)
225 return cls(app_name, acc_path, self, interface, dbus_object=dbus_object)
227 raise AccessibleObjectNotAvailable ()
230 def connection(self):
232 D-Bus connection used by the store.
234 return self._connection
236 #END----------------------------------------------------------------------------