|
Module DefaultDialogScript
|
|
1 '''
2 Defines tasks for managing the chooser dialogs packaged with the SUE core.
3
4 @author: Peter Parente
5 @organization: IBM Corporation
6 @copyright: Copyright (c) 2005, 2007 IBM Corporation
7 @license: The BSD License
8
9 @author: Frank Zenker
10 @author: Nicole Anacker
11 @organization: IT Science Center Ruegen gGmbH, Germany
12 @copyright: Copyright (c) 2007, 2008 ITSC Ruegen
13 @license: The BSD License
14
15 All rights reserved. This program and the accompanying materials are made
16 available under the terms of the BSD license which accompanies
17 this distribution, and is available at
18 U{http://www.opensource.org/licenses/bsd-license.php}
19 '''
20
21 from AccessEngine import AEScript, AccessEngineAPI
22 from AccessEngine import AEConstants
23 import AccessEngine
24
25 from Tools.i18n import _
26
27 __uie__ = dict(kind='script', all_tiers=True)
28
30 '''
31 Manages the basic SUE dialogs for configuring settings and loading Scripts.
32
33 Shows and hides default SUE chooser dialogs for configuring SUE settings,
34 loading and unloading extensions at run time, and so on. Tasks for starting
35 choosers are defined, but not mapped to any particular input device. Some
36 other Script must define the input mappings.
37
38 @ivar installed: All UIE class names, human readable names, and descriptions
39 installed keyed by their type
40 @type installed: dictionary of string : list of 3-tuple of string
41 @ivar associated: All UIE class names, human readable names, and descriptions
42 associated with this profile keyed by their type
43 @type associated: dictionary of string : list of 3-tuple of string
44 '''
46 '''
47 Registers named tasks for script chooser, settings chooser, and
48 command chooser
49 '''
50
51 self.registerTask('show settings chooser', self.onChooserChange)
52 self.registerTask('show script chooser', self.onChooserChange)
53 self.registerTask('show command chooser', self.onChooserChange)
54
55
56 kbd = AccessEngineAPI.getInputDevice(None, 'keyboard')
57 AccessEngineAPI.addInputModifiers(self, kbd, kbd.AEK_ALT_L,
58 kbd.AEK_SHIFT_L, kbd.AEK_ALT_R,
59 kbd.AEK_SHIFT_R, kbd.AEK_CAPS_LOCK)
60
61
62 pairs = [[kbd.AEK_ALT_L, kbd.AEK_SHIFT_L], [kbd.AEK_ALT_R, kbd.AEK_SHIFT_R]]
63
64 for pair in pairs:
65 self.registerCommand(kbd, 'show settings chooser',
66 _('show settings chooser'),
67 False, pair+[kbd.AEK_F2])
68 self.registerCommand(kbd, 'show script chooser',
69 _('show script chooser'),
70 False, pair+[kbd.AEK_F3])
71 self.registerCommand(kbd, 'show command chooser',
72 _('show command chooser'),
73 False, pair+[kbd.AEK_F4])
74
75
77 '''
78 Provides the localized name of this L{AccessEngine.AEScript}.
79 '''
80 return _('Basic dialogs')
81
83 '''
84 Decides wich chooser shall be started.
85 '''
86 if kwargs['task_name'] == 'show script chooser':
87 return self.onScriptChooserStart(**kwargs)
88 elif kwargs['task_name'] == 'show settings chooser':
89 return self.onSettingsChooserStart(**kwargs)
90 elif kwargs['task_name'] == 'show command chooser':
91 return self.onCommandChooserStart(**kwargs)
92 else:
93 return True
94
96 '''
97 Decides wich chooser shall get the signal.
98 '''
99 if kwargs['task_name'] == 'show script chooser':
100 return self.onScriptChooserSignal(**kwargs)
101 elif kwargs['task_name'] == 'show settings chooser':
102 return self.onSettingsChooserSignal(**kwargs)
103 elif kwargs['task_name'] == 'show command chooser':
104 return self.onCommandChooserSignal(**kwargs)
105 else:
106 return True
107
108
109
110
112 '''
113 Shows the Script chooser which allows a user to pick Scripts to load and
114 unload from the current application at runtime.
115 Runs when an input gesture is given to start the chooser. Buids lists of
116 currently loaded and available L{AccessEngine.AEScript}s, shows the chooser,
117 and provides it with the lists.
118
119 @param timestamp: Time to provide to the chooser dialog so it can raise
120 itself to the foreground properly
121 @type timestamp: float
122 '''
123
124 loaded = AccessEngineAPI.getScriptMetadata(self.tier)
125
126
127 installed = AccessEngineAPI.getScriptMetadata(self.tier,
128 AEConstants.UIE_INSTALLED)
129
130 unloaded = list(set(installed) - set(loaded))
131
132 unloaded.sort()
133
134 AccessEngineAPI.loadChooser(self, 'ScriptChooser', loaded=loaded,
135 unloaded=unloaded,
136 app_name=AccessEngineAPI.getAppName(kwargs.get('por')),
137 timestamp=timestamp, **kwargs)
138
140 '''
141 Runs when the chooser sends a signal to this L{AccessEngine.AEScript}
142 indicating some change in the dialog that the L{AccessEngine.AEScript}
143 should be aware of. Signals of interest defined by this particular chooser
144 include:
145
146 - OK: Complete the dialog accepting current load/unload configuration
147 - APPLY: Accept current load/unload configuration without completing
148 - RAISE: Move a L{AccessEngine.AEScript} up in the load order
149 - LOWER: Move a L{AccessEngine.AEScript} down in the load order
150 - TO_LOAD: Add a L{AccessEngine.AEScript} to the list of
151 L{AccessEngine.AEScript}s to load
152 - TO_UNLOAD: Remove a L{AccessEngine.AEScript} from the list of
153 L{AccessEngine.AEScript}s to load
154
155 @param kwargs: Keyword arguments specific to each signal type
156 @type kwargs: dictionary
157 @keyword kwargs['chooser']: Reference to the chooser object that sent the signal
158 @type kwargs['chooser']: L{AEChooser}
159 @keyword kwargs['kind']: Signal name
160 @type kwargs['kind']: string
161 '''
162 kind = kwargs['kind']
163 chooser = kwargs['chooser']
164
165 AccessEngineAPI.stopNow(self, cap='audio', role='output', **kwargs)
166
167 AccessEngineAPI.inhibitMayStop()
168 por = kwargs['por']
169 if kind == chooser.APPLY:
170 text=_('applied changes to %s') % AccessEngineAPI.getAppName(por)
171 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
172 elif kind == chooser.RAISE:
173 text = _('raised %(name)s above %(below)s, below %(above)s') % kwargs
174 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
175 elif kind == chooser.LOWER:
176 text = _('lowered %(name)s below %(above)s, above %(below)s') % kwargs
177 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
178 elif kind == chooser.TO_LOAD:
179 kwargs['app'] = AccessEngineAPI.getAppName(por)
180 text = _('added %(name)s to %(app)s as first') % kwargs
181 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
182 elif kind == chooser.TO_UNLOAD:
183 kwargs['app'] = AccessEngineAPI.getAppName(por)
184 text = _('removed %(name)s from %(app)s') % kwargs
185 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
186
187 if kind in (chooser.OK, chooser.APPLY):
188
189 self._doScriptLoad(**kwargs)
190
192 '''
193 Loads and unloads L{AccessEngine.AEScript}s according to the current state
194 of the chooser dialog.
195
196 @param loaded: Names of L{AccessEngine.AEScript}s to load on this L{AETier}
197 @type loaded: list
198 @param unloaded: Names of L{AccessEngine.AEScript}s not to load on this
199 L{AETier}
200 @type unloaded: list
201 '''
202
203 curr_loaded = AccessEngineAPI.getScriptClassNames(self.tier)
204
205
206 to_load = set(loaded) - set(curr_loaded)
207
208
209 to_unload = set(curr_loaded).intersection(unloaded)
210
211 indices = [curr_loaded.index(script) for script in to_unload]
212 AccessEngineAPI.popScript(self.getAETier() ,*indices)
213
214 for script in to_load:
215
216 i = loaded.index(script)
217
218 AccessEngineAPI.insertScript(self.tier, i, script)
219
220
221
222
224 '''
225 Initialize installed, associated, and chooser variables.
226 '''
227 self.installed = None
228 self.associated = None
229
231 '''
232 Shows the settings chooser which allows a user to configure SUE devices,
233 Scripts, profiles, and general system settings.
234 Load the L{SettingsChooser} and give it the required settings model for
235 the system, L{AccessEngine.AEScript}s, devices, and profile.
236
237 @param timestamp: Time to provide to the chooser dialog so it can raise
238 itself to the foreground properly
239 @type timestamp: float
240 '''
241 self.initSettingsChooser()
242
243 self._getProfileInfo()
244 profile = AccessEngineAPI.getProfileName()
245
246 system = AccessEngine.AETierManager.getState()
247 system.save()
248
249
250
251
252 md = set(AccessEngineAPI.getScriptMetadata(self.tier,
253 AEConstants.UIE_ALL_ASSOCIATED))
254 md.update(AccessEngineAPI.getScriptMetadata(self.tier, AEConstants.UIE_LOADED))
255
256 states = [(name, AccessEngineAPI.getScriptState(self.tier, cls_name))
257 for (cls_name, name, desc) in md]
258 scripts = self._readyStates(states)
259
260
261 names = AccessEngineAPI.getDeviceClassNames(AEConstants.UIE_LOADED)
262
263 states = [AccessEngineAPI.getDeviceState(name) for name in names]
264 states = zip(AccessEngineAPI.getDeviceNames(AEConstants.UIE_LOADED), states)
265 devices = self._readyStates(states)
266
267
268 chooser = AccessEngineAPI.loadChooser(self, 'SettingsChooser', system=system,
269 scripts=scripts, associated=self.associated,
270 installed=self.installed,
271 profile=profile, devices=devices,
272 timestamp=timestamp, **kwargs)
273
291
293 '''
294 Prepare settings objects by storing a copy of the current settings so
295 that they may be restored at a later time.
296
297 @param states: States paired with the names of the UIEs having those
298 states
299 @type states: list of 2-tuple of string, L{AEState}
300 @return: Dictionary pairing UIE name with its state object
301 @rtype: dictionary
302 '''
303 uies = {}
304 for name, state in states:
305 try:
306 state.save()
307 except AttributeError:
308
309 continue
310 state.save()
311 uies[name] = state
312 return uies
313
315 '''
316 Runs when the chooser sends a signal to this L{AccessEngine.AEScript}
317 indicating some change in the chooser that the L{AccessEngine.AEScript}
318 should be aware of. Signals of interest defined by this particular chooser
319 include:
320
321 - OK: Complete the dialog accepting current values
322 - APPLY: Accept current values without completing
323 - RAISE: Move a L{AEUserInterface} up in the load order
324 - LOWER: Move a L{AEUserInterface} down in the load order
325 - TO_LOAD: Add a L{AEUserInterface} to the list to load
326 - TO_UNLOAD: Remove a L{AEUserInterface} from the list to load
327
328 @param kwargs: Keyword arguments specific to each signal type
329 @type kwargs: dictionary
330 @keyword kwargs['chooser']: Reference to the chooser object that sent the
331 signal
332 @type kwargs['chooser']: L{AEChooser}
333 @keyword kwargs['kind']: Signal name
334 @type kwargs['kind']: string
335 '''
336 kind = kwargs['kind']
337 chooser = kwargs['chooser']
338
339 if kind == chooser.APPLY:
340 self._doApply(**kwargs)
341 elif kind == chooser.OK:
342 self._doApply(**kwargs)
343 elif kind == chooser.CANCEL:
344
345 self._doCancel(**kwargs)
346
347
348 AccessEngineAPI.stopNow(self, cap='audio', role='output', **kwargs)
349
350
351 AccessEngineAPI.inhibitMayStop()
352 if kind == chooser.APPLY:
353 text=_('applied changes to settings')
354 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
355 elif kind == chooser.RAISE:
356 text = _('raised %(name)s above %(below)s, below %(above)s') % kwargs
357 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
358 elif kind == chooser.LOWER:
359 text = _('lowered %(name)s below %(above)s, above %(below)s') % kwargs
360 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
361 elif kind == chooser.TO_LOAD:
362 text = _('added %(name)s as first') % kwargs
363 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
364 elif kind == chooser.TO_UNLOAD:
365 text = _('removed %(name)s') % kwargs
366 self.doTask('read message', 'BasicSpeechScript', text=text, **kwargs)
367
368 - def _doApply(self, chooser, system, scripts, devices, associated,
369 installed=None, **kwargs):
370 '''
371 Apply all system, L{AccessEngine.AEScript}, and device settings. Make any
372 necessary changes to the current profile and install/uninstall any
373 L{AEUserInterface}s.
374
375 @param chooser: Reference to the chooser object that sent the signal
376 @type chooser: L{AEChooser}
377 @param system: System state
378 @type system: L{AEState}
379 @param scripts: L{AccessEngine.AEScript} state to apply
380 @type scripts: list of L{AEState}
381 @param devices: Device state to apply
382 @type devices: list of L{AEState}
383 @param installed: All UIE class names selected for installation keyed by
384 their type
385 @type installed: dictionary of string : list of string
386 @param associated: All UIE class names selected for association with this
387 profile keyed by their type
388 @type associated: dictionary of string : list of string
389 '''
390
391 system.save()
392 [state.save() for state in scripts.values()]
393 [state.save() for state in devices.values()]
394
395 tools = {'scripts' : (AccessEngineAPI.associateScript,
396 AccessEngineAPI.disassociateScript),
397 'monitors' : (AccessEngineAPI.associateMonitor,
398 AccessEngineAPI.disassociateMonitor),
399 'devices' : (AccessEngineAPI.associateDevice,
400 AccessEngineAPI.disassociateDevice)}
401
402 for kind in associated:
403 new = associated[kind]
404 old = [metadata[0] for metadata in self.associated[kind]]
405 to_remove = set(old) - set(new)
406 to_add = set(new) - set(old)
407 if len(to_add) > 0 or len(to_remove) > 0:
408
409 map(tools[kind][1], to_remove)
410 if kind == 'devices':
411
412 map(tools[kind][0], new)
413
414 AccessEngineAPI.refreshDevices()
415 if chooser is not None:
416
417
418 names = AccessEngineAPI.getDeviceClassNames(AEConstants.UIE_LOADED)
419
420 states = [AccessEngineAPI.getDeviceState(name) for name in names]
421 states = zip(AccessEngineAPI.getDeviceNames(AEConstants.UIE_LOADED),
422 states)
423 devices = self._readyStates(states)
424 chooser.updateDevices(devices)
425 else:
426
427 map(tools[kind][0], to_add)
428
429 self._getProfileInfo()
430
431 - def _doCancel(self, system, scripts, devices, **kwargs):
432 '''
433 Cancel all system, L{AccessEngine.AEScript}, and device setting changes.
434 Ignore changes to the current profile.
435
436 @param system: System state
437 @type system: L{AEState}
438 @param scripts: L{AccessEngine.AEScript} state to apply
439 @type scripts: list of L{AEState}
440 @param devices: Device state to apply
441 @type devices: list of L{AEState}
442 '''
443 system.restore()
444 for state in scripts.values():
445 state.restore()
446 for state in devices.values():
447 state.restore()
448
450 '''
451 Starts the command chooser providing a list of all currently registered
452 key commands sorted by their respective parent scripts.
453 '''
454 AccessEngineAPI.loadChooser(self, 'CommandChooser', timestamp=timestamp,
455 **kwargs)
456
458 '''
459 Runs when the chooser sends a signal to this L{AccessEngine.AEScript}
460 indicating some change in the chooser that the L{AccessEngine.AEScript}
461 should be aware of. There's only one signals of interest defined by this
462 particular chooser that we want to react upon:
463 - OK: Complete the dialog accepting current values
464
465 @param kwargs: Keyword arguments specific to each signal type
466 @type kwargs: dictionary
467 @keyword kwargs['chooser']: Reference to the chooser object that sent the
468 signal
469 @type kwargs['chooser']: L{AEChooser}
470 @keyword kwargs['kind']: Signal name
471 @type kwargs['kind']: string
472 '''
473
474 self.stopNow(self, cap='audio', role='output', **kwargs)
475
476 self.inhibitMayStop(self, **kwargs)
477 if kwargs['kind'] == kwargs['chooser'].OK:
478 self.doTask('read message', 'BasicSpeechScript',
479 text=_('leaving command chooser'), **kwargs)
480