1 '''
2 Defines a gtk window L{AEChooser} showing a list of all available key commands.
3 (Inspired by ScriptChooser and Orca's settings dialog (Keybindings Tab))
4
5 Use + and - to expand and collapse tree view items (for all gtk tree views).
6
7 @author: Frank Zenker
8 @author: Martina Weicht
9 @organization: IT Science Center Ruegen gGmbH, Germany
10 @copyright: Copyright (c) 2007, 2008 ITSC Ruegen
11 @license: The BSD License
12
13 All rights reserved. This program and the accompanying materials are made
14 available under the terms of the BSD license which accompanies
15 this distribution, and is available at
16 U{http://www.opensource.org/licenses/bsd-license.php}
17 '''
18
19 import pygtk
20 pygtk.require('2.0')
21 import gtk, gobject, logging, pango, unicodedata, string
22 import gtk.gdk as gdk
23 import gtk.glade
24 import AccessEngine
25 from AccessEngine import AEChooser
26 import AccessEngine.AEConstants.Spelling as Spelling
27 from Tools.i18n import _, DOMAIN
28 import gettext
29 from GTKUIEView import *
30
31 __uie__ = dict(kind='chooser')
32
33 log = logging.getLogger('CommandChooser')
34
36 '''
37 Window presenting a list of all currently available key commands.
38
39 @note: MW: constant SEPARATOR should be turned into a setting so users
40 can decided on which characters to use (comma, plus, ...)
41
42 @ivar dialog: Window widget for looking at keybindings
43 @type dialog: gtk.Window
44 @ivar DESCRIPTION: constant for column named 'description'
45 @type DESCRIPTION: integer
46 @ivar KEYBINDINGS: constant for column named 'keybindung'
47 @type KEYBINDINGS: integer
48 @ivar DEVICE: constant for column named 'device'
49 @type DEVICE: integer
50 @ivar SEPARATOR: string separating keys within keybindings string
51 @type SEPARATOR: string
52 '''
53
54 DESCRIPTION = 0
55 KEYBINDINGS = 1
56 DEVICE = 2
57
58
59 SEPARATOR = ', '
60
61 - def init(self, **kwargs):
62 '''
63 Creates and shows the chooser dialog and its components.
64 '''
65
66 source = gtk.glade.XML(self._getResource('command_chooser.glade'),
67 'main window',
68 DOMAIN)
69 self.window = source.get_widget('main window')
70 self.kb_tree_view = source.get_widget('kb tree view')
71
72
73 self._createKeyBindingsView()
74
75
76 source.signal_autoconnect(self)
77
78 self.window.show_all()
79
80
82 '''
83 Creates an ordered chooser widget.
84
85 @note: mw: The UIEView was not suitable since they have a fixed set of
86 columns for their list. Also, I wanted the keybindings to be assigned to
87 their parent script, so TreeStore was a better choice than ListStore.
88 Maybe a more generic approach to the UIEView can combine those two views
89 allowing the columns and the model to be specified individually.
90 '''
91 self.kb_model = gtk.TreeStore(
92 gobject.TYPE_STRING,
93 gobject.TYPE_STRING,
94 gobject.TYPE_STRING)
95
96 self.kb_tree_view.set_model(self.kb_model)
97 self.kb_tree_view.set_headers_visible(True)
98
99 rendererText = gtk.CellRendererText()
100 rendererText.set_property("ellipsize", pango.ELLIPSIZE_END)
101
102
103 column = gtk.TreeViewColumn(_("description"),
104 rendererText,
105 text=self.DESCRIPTION)
106 column.set_resizable(True)
107 column.set_min_width(250)
108 column.set_sort_column_id(self.DESCRIPTION)
109 self.kb_tree_view.append_column(column)
110
111
112 column = gtk.TreeViewColumn( _("keybinding"),
113 rendererText,
114 text=self.KEYBINDINGS)
115 column.set_resizable(True)
116 column.set_min_width(250)
117 column.set_sort_column_id(self.KEYBINDINGS)
118 self.kb_tree_view.append_column(column)
119
120
121 column = gtk.TreeViewColumn(_("device"),
122 rendererText,
123 text=self.DEVICE)
124 column.set_resizable(True)
125 column.set_sort_column_id(self.DEVICE)
126 self.kb_tree_view.append_column(column)
127
128
129 self._populateKeyBindings()
130 self.kb_model.set_sort_column_id(self.DESCRIPTION, gtk.SORT_ASCENDING)
131
132
134 '''
135 Populates the list of currently registered keybindings.
136 Traverses the list of all registered scripts (per tier, but excluding doubles)
137 and creates a list of all keybindings along with their description.
138 '''
139 def_keymap = gdk.keymap_get_default()
140
141 kb_list = {}
142 kb_array = []
143 queue2 = []
144
145
146 tiers = AccessEngine.AETierManager.tiers.values()
147 for tier in tiers:
148
149
150 scripts = tier.getScripts()
151 for script in scripts:
152
153
154 if self._getIterator( script.getName() ) == None:
155
156
157 script_iterator = self._createNode( script.getName())
158
159
160 for command, id in script.commands.iteritems():
161
162
163 id = script.commands[command]
164
165
166 id, name = id
167
168
169 device = command.getDevice()
170
171
172 description = script.command_descriptions[id]
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208 code_string = ''
209 command_string = command.asString().strip('()')
210 for code in command_string.split(','):
211
212
213 code_string += _(code)
214 code_string += self.SEPARATOR
215
216
217 code_string = code_string[0:len(code_string)-len(self.SEPARATOR)]
218
219
220
221
222
223
224
225
226
227
228 kb_list[code_string] = description
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270 for entry in kb_list:
271 self._insertRow(kb_list[entry], entry, device.getName(), script_iterator)
272
273
274
275 kb_list = {}
276
277
278
279 if not self.kb_model.iter_has_child(script_iterator):
280 self.kb_model.remove(script_iterator)
281
282
283 first = self.kb_model.get_iter_first()
284 if first is not None:
285 self.kb_tree_view.set_cursor_on_cell(self.kb_model.get_path(first))
286
287
288
289
290
291
292
293
294
295
296
297
298
300 '''
301 Creates a new root node in the TreeStore model with the name of the script.
302
303 @author: Orca authors (orca_gui_prefs.py)
304 @param scriptName: the name of the new TreeStore Node = name of the script
305 @type scriptName: string
306 @return iterator at the new node
307 @rtype gtk.TreeIter
308 '''
309
310 model = self.kb_model
311 iterator = model.append(None)
312 model.set(iterator,
313 self.DESCRIPTION, scriptName,
314 self.KEYBINDINGS, None,
315 self.DEVICE, None )
316 return iterator
317
318 - def _insertRow(self, desc, kb, device, parent=None):
319 '''
320 Appends a new row with the new keybinding data to the treeview.
321
322 @author: Orca authors (orca_gui_prefs.py)
323 @param kb: the new keybinding to be appended
324 @type kb: string
325 @param desc: description of the keybinding to be appended
326 @type desc: string
327 @param device: name of the device of which the keys are pressed
328 @type device: string
329 @param parent: the parent node on which to append
330 @type parent: gtk.TreeIter
331 @return iterator at the new row
332 @rtype gtk.TreeIter
333 '''
334 model = self.kb_model
335 if parent != None:
336 iterator = model.append(parent)
337 model.set (iterator,
338 self.DESCRIPTION, desc,
339 self.KEYBINDINGS, kb,
340 self.DEVICE, device )
341 return iterator
342 else:
343 return None
344
346 '''
347 Returns the iterator matching the node name passed as argument or
348 None if the node was not found.
349
350 @author: Orca authors (orca_gui_prefs.py)
351 @param nodeName: a string providing the name the node wanted
352 @type nodeName: string
353 @return: iterator matching the nodeName passed as argument
354 @rtype: gtk.TreeIter or None
355 '''
356 model = self.kb_model
357 for row in model:
358 if ((model.iter_depth(row.iter) == 0) \
359 and (row[ self.DESCRIPTION ] == nodeName)):
360 return row.iter
361 return None
362
363
364 - def _onOK(self, widget):
365 '''
366 Handles 'OK' button 'clicked' events.
367
368 @param widget: source of GUI event
369 @type widget: gtk.Widget
370 '''
371
372
373 self.close()
374
376 '''
377 Closes the chooser, preventing further chooser interaction with the user.
378 '''
379 self.window.destroy()
380
382 '''
383 Gets the name of the chooser.
384
385 @return: Human readable name of the chooser
386 @rtype: string
387 '''
388 return _('Command Chooser')
389