1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2005-2007 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Utilities for obtaining speech utterances for objects. In general, |
21 |
|
there probably should be a singleton instance of the SpeechGenerator |
22 |
|
class. For those wishing to override the speech generators, however, |
23 |
|
one can create a new instance and replace/extend the speech generators |
24 |
1 |
as they see fit.""" |
25 |
|
|
26 |
1 |
__id__ = "$Id: speechgenerator.py 2650 2007-08-15 19:03:42Z shaeger $" |
27 |
1 |
__version__ = "$Revision: 2650 $" |
28 |
1 |
__date__ = "$Date: 2007-08-15 15:03:42 -0400 (Wed, 15 Aug 2007) $" |
29 |
1 |
__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc." |
30 |
1 |
__license__ = "LGPL" |
31 |
|
|
32 |
1 |
import math |
33 |
|
|
34 |
1 |
import atspi |
35 |
1 |
import debug |
36 |
1 |
import orca_state |
37 |
1 |
import rolenames |
38 |
1 |
import settings |
39 |
|
|
40 |
1 |
from orca_i18n import _ # for gettext support |
41 |
|
|
42 |
2 |
class SpeechGenerator: |
43 |
|
"""Takes accessible objects and produces a string to speak for |
44 |
|
those objects. See the getSpeech method, which is the primary |
45 |
|
entry point. Subclasses can feel free to override/extend the |
46 |
1 |
speechGenerators instance field as they see fit.""" |
47 |
|
|
48 |
1 |
def __init__(self, script): |
49 |
|
|
50 |
|
# The script that created us. This allows us to ask the |
51 |
|
# script for information if we need it. |
52 |
|
# |
53 |
79 |
self._script = script |
54 |
|
|
55 |
|
# Set up a dictionary that maps role names to functions |
56 |
|
# that generate speech for objects that implement that role. |
57 |
|
# |
58 |
79 |
self.speechGenerators = {} |
59 |
|
self.speechGenerators[rolenames.ROLE_ALERT] = \ |
60 |
79 |
self._getSpeechForAlert |
61 |
|
self.speechGenerators[rolenames.ROLE_ANIMATION] = \ |
62 |
79 |
self._getSpeechForAnimation |
63 |
|
self.speechGenerators[rolenames.ROLE_ARROW] = \ |
64 |
79 |
self._getSpeechForArrow |
65 |
|
self.speechGenerators[rolenames.ROLE_CHECK_BOX] = \ |
66 |
79 |
self._getSpeechForCheckBox |
67 |
|
self.speechGenerators[rolenames.ROLE_CHECK_MENU] = \ |
68 |
79 |
self._getSpeechForCheckMenuItem |
69 |
|
self.speechGenerators[rolenames.ROLE_CHECK_MENU_ITEM] = \ |
70 |
79 |
self._getSpeechForCheckMenuItem |
71 |
|
self.speechGenerators[rolenames.ROLE_COLUMN_HEADER] = \ |
72 |
79 |
self._getSpeechForColumnHeader |
73 |
|
self.speechGenerators[rolenames.ROLE_COMBO_BOX] = \ |
74 |
79 |
self._getSpeechForComboBox |
75 |
|
self.speechGenerators[rolenames.ROLE_DESKTOP_ICON] = \ |
76 |
79 |
self._getSpeechForDesktopIcon |
77 |
|
self.speechGenerators[rolenames.ROLE_DIAL] = \ |
78 |
79 |
self._getSpeechForDial |
79 |
|
self.speechGenerators[rolenames.ROLE_DIALOG] = \ |
80 |
79 |
self._getSpeechForDialog |
81 |
|
self.speechGenerators[rolenames.ROLE_DIRECTORY_PANE] = \ |
82 |
79 |
self._getSpeechForDirectoryPane |
83 |
|
self.speechGenerators[rolenames.ROLE_FRAME] = \ |
84 |
79 |
self._getSpeechForFrame |
85 |
|
self.speechGenerators[rolenames.ROLE_HTML_CONTAINER] = \ |
86 |
79 |
self._getSpeechForHtmlContainer |
87 |
|
self.speechGenerators[rolenames.ROLE_ICON] = \ |
88 |
79 |
self._getSpeechForIcon |
89 |
|
self.speechGenerators[rolenames.ROLE_IMAGE] = \ |
90 |
79 |
self._getSpeechForImage |
91 |
|
self.speechGenerators[rolenames.ROLE_LABEL] = \ |
92 |
79 |
self._getSpeechForLabel |
93 |
|
self.speechGenerators[rolenames.ROLE_LAYERED_PANE] = \ |
94 |
79 |
self._getSpeechForLayeredPane |
95 |
|
self.speechGenerators[rolenames.ROLE_LIST] = \ |
96 |
79 |
self._getSpeechForList |
97 |
|
self.speechGenerators[rolenames.ROLE_LIST_ITEM] = \ |
98 |
79 |
self._getSpeechForListItem |
99 |
|
self.speechGenerators[rolenames.ROLE_MENU] = \ |
100 |
79 |
self._getSpeechForMenu |
101 |
|
self.speechGenerators[rolenames.ROLE_MENU_BAR] = \ |
102 |
79 |
self._getSpeechForMenuBar |
103 |
|
self.speechGenerators[rolenames.ROLE_MENU_ITEM] = \ |
104 |
79 |
self._getSpeechForMenuItem |
105 |
|
self.speechGenerators[rolenames.ROLE_OPTION_PANE] = \ |
106 |
79 |
self._getSpeechForOptionPane |
107 |
|
self.speechGenerators[rolenames.ROLE_PAGE_TAB] = \ |
108 |
79 |
self._getSpeechForPageTab |
109 |
|
self.speechGenerators[rolenames.ROLE_PAGE_TAB_LIST] = \ |
110 |
79 |
self._getSpeechForPageTabList |
111 |
|
self.speechGenerators[rolenames.ROLE_PARAGRAPH] = \ |
112 |
79 |
self._getSpeechForText |
113 |
|
self.speechGenerators[rolenames.ROLE_PASSWORD_TEXT] = \ |
114 |
79 |
self._getSpeechForText |
115 |
|
self.speechGenerators[rolenames.ROLE_PROGRESS_BAR] = \ |
116 |
79 |
self._getSpeechForProgressBar |
117 |
|
self.speechGenerators[rolenames.ROLE_PUSH_BUTTON] = \ |
118 |
79 |
self._getSpeechForPushButton |
119 |
|
self.speechGenerators[rolenames.ROLE_RADIO_BUTTON] = \ |
120 |
79 |
self._getSpeechForRadioButton |
121 |
|
self.speechGenerators[rolenames.ROLE_RADIO_MENU] = \ |
122 |
79 |
self._getSpeechForRadioMenuItem |
123 |
|
self.speechGenerators[rolenames.ROLE_RADIO_MENU_ITEM] = \ |
124 |
79 |
self._getSpeechForRadioMenuItem |
125 |
|
self.speechGenerators[rolenames.ROLE_ROW_HEADER] = \ |
126 |
79 |
self._getSpeechForRowHeader |
127 |
|
self.speechGenerators[rolenames.ROLE_SCROLL_BAR] = \ |
128 |
79 |
self._getSpeechForScrollBar |
129 |
|
self.speechGenerators[rolenames.ROLE_SLIDER] = \ |
130 |
79 |
self._getSpeechForSlider |
131 |
|
self.speechGenerators[rolenames.ROLE_SPIN_BUTTON] = \ |
132 |
79 |
self._getSpeechForSpinButton |
133 |
|
self.speechGenerators[rolenames.ROLE_SPLIT_PANE] = \ |
134 |
79 |
self._getSpeechForSplitPane |
135 |
|
self.speechGenerators[rolenames.ROLE_TABLE] = \ |
136 |
79 |
self._getSpeechForTable |
137 |
|
self.speechGenerators[rolenames.ROLE_TABLE_CELL] = \ |
138 |
79 |
self._getSpeechForTableCellRow |
139 |
|
self.speechGenerators[rolenames.ROLE_TABLE_COLUMN_HEADER] = \ |
140 |
79 |
self._getSpeechForTableColumnHeader |
141 |
|
self.speechGenerators[rolenames.ROLE_TABLE_ROW_HEADER] = \ |
142 |
79 |
self._getSpeechForTableRowHeader |
143 |
|
self.speechGenerators[rolenames.ROLE_TEAR_OFF_MENU_ITEM] = \ |
144 |
79 |
self._getSpeechForMenu |
145 |
|
self.speechGenerators[rolenames.ROLE_TERMINAL] = \ |
146 |
79 |
self._getSpeechForTerminal |
147 |
|
self.speechGenerators[rolenames.ROLE_TEXT] = \ |
148 |
79 |
self._getSpeechForText |
149 |
|
self.speechGenerators[rolenames.ROLE_TOGGLE_BUTTON] = \ |
150 |
79 |
self._getSpeechForToggleButton |
151 |
|
self.speechGenerators[rolenames.ROLE_TOOL_BAR] = \ |
152 |
79 |
self._getSpeechForToolBar |
153 |
|
self.speechGenerators[rolenames.ROLE_TREE] = \ |
154 |
79 |
self._getSpeechForTable |
155 |
|
self.speechGenerators[rolenames.ROLE_TREE_TABLE] = \ |
156 |
79 |
self._getSpeechForTable |
157 |
|
self.speechGenerators[rolenames.ROLE_WINDOW] = \ |
158 |
79 |
self._getSpeechForWindow |
159 |
|
|
160 |
1 |
def _getSpeechForObjectAccelerator(self, obj): |
161 |
|
"""Returns a list of utterances that describes the keyboard |
162 |
|
accelerator (and possibly shortcut) for the given object. |
163 |
|
|
164 |
|
Arguments: |
165 |
|
- obj: the Accessible object |
166 |
|
|
167 |
|
Returns a list of utterances to be spoken. |
168 |
|
""" |
169 |
|
|
170 |
36 |
result = self._script.getAcceleratorAndShortcut(obj) |
171 |
|
|
172 |
36 |
accelerator = result[0] |
173 |
|
#shortcut = result[1] |
174 |
|
|
175 |
36 |
utterances = [] |
176 |
|
|
177 |
|
# [[[TODO: WDW - various stuff preserved while we work out the |
178 |
|
# desired verbosity here.]]] |
179 |
|
# |
180 |
|
#if len(shortcut) > 0: |
181 |
|
# utterances.append(_("shortcut") + " " + shortcut) |
182 |
|
# utterances.append(accelerator) |
183 |
36 |
if len(accelerator) > 0: |
184 |
|
#utterances += (_("accelerator") + " " + accelerator) |
185 |
17 |
utterances.append(accelerator) |
186 |
|
|
187 |
36 |
return utterances |
188 |
|
|
189 |
1 |
def _getSpeechForObjectAvailability(self, obj): |
190 |
|
"""Returns a list of utterances that describes the availability |
191 |
|
of the given object. |
192 |
|
|
193 |
|
Arguments: |
194 |
|
- obj: the Accessible object |
195 |
|
|
196 |
|
Returns a list of utterances to be spoken. |
197 |
|
""" |
198 |
396 |
if obj.state.count(atspi.Accessibility.STATE_SENSITIVE) == 0: |
199 |
|
# Translators: this represents an item on the screen that has |
200 |
|
# been set insensitive (or grayed out). |
201 |
|
# |
202 |
0 |
return [_("grayed")] |
203 |
|
else: |
204 |
396 |
return [] |
205 |
|
|
206 |
1 |
def _getSpeechForObjectLabel(self, obj): |
207 |
442 |
label = self._script.getDisplayedLabel(obj) |
208 |
442 |
if label: |
209 |
12 |
return [label] |
210 |
|
else: |
211 |
430 |
return [] |
212 |
|
|
213 |
1 |
def _getSpeechForObjectName(self, obj): |
214 |
408 |
name = self._script.getDisplayedText(obj) |
215 |
408 |
if name: |
216 |
342 |
return [name] |
217 |
66 |
elif obj.description: |
218 |
0 |
return [obj.description] |
219 |
|
else: |
220 |
66 |
return [] |
221 |
|
|
222 |
1 |
def _getSpeechForObjectRole(self, obj): |
223 |
426 |
if (obj.role != rolenames.ROLE_UNKNOWN): |
224 |
424 |
return [rolenames.getSpeechForRoleName(obj)] |
225 |
|
else: |
226 |
2 |
return [] |
227 |
|
|
228 |
1 |
def _debugGenerator(self, generatorName, obj, already_focused, utterances): |
229 |
|
"""Prints debug.LEVEL_FINER information regarding the speech generator. |
230 |
|
|
231 |
|
Arguments: |
232 |
|
- generatorName: the name of the generator |
233 |
|
- obj: the object being presented |
234 |
|
- already_focused: False if object just received focus |
235 |
|
- utterances: the generated text |
236 |
|
""" |
237 |
|
|
238 |
1285 |
debug.println(debug.LEVEL_FINER, |
239 |
1285 |
"GENERATOR: %s" % generatorName) |
240 |
1285 |
debug.println(debug.LEVEL_FINER, |
241 |
1285 |
" obj = %s" % obj.name) |
242 |
1285 |
debug.println(debug.LEVEL_FINER, |
243 |
1285 |
" role = %s" % obj.role) |
244 |
1285 |
debug.println(debug.LEVEL_FINER, |
245 |
1285 |
" already_focused = %s" % already_focused) |
246 |
1285 |
debug.println(debug.LEVEL_FINER, |
247 |
1285 |
" utterances:") |
248 |
3796 |
for text in utterances: |
249 |
2511 |
debug.println(debug.LEVEL_FINER, |
250 |
2511 |
" (%s)" % text) |
251 |
|
|
252 |
1 |
def _getDefaultSpeech(self, obj, already_focused): |
253 |
|
"""Gets a list of utterances to be spoken for the current |
254 |
|
object's name, role, and any accelerators. This is usually the |
255 |
|
fallback speech generator should no other specialized speech |
256 |
|
generator exist for this object. |
257 |
|
|
258 |
|
The default speech will be of the following form: |
259 |
|
|
260 |
|
label name role availability |
261 |
|
|
262 |
|
Arguments: |
263 |
|
- obj: an Accessible |
264 |
|
- already_focused: False if object just received focus |
265 |
|
|
266 |
|
Returns a list of utterances to be spoken for the object. |
267 |
|
""" |
268 |
|
|
269 |
282 |
utterances = [] |
270 |
|
|
271 |
282 |
if not already_focused: |
272 |
272 |
label = self._getSpeechForObjectLabel(obj) |
273 |
272 |
utterances.extend(label) |
274 |
272 |
name = self._getSpeechForObjectName(obj) |
275 |
272 |
if name != label: |
276 |
256 |
utterances.extend(name) |
277 |
272 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
278 |
|
|
279 |
282 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
280 |
|
|
281 |
282 |
self._debugGenerator("_getDefaultSpeech", |
282 |
282 |
obj, |
283 |
282 |
already_focused, |
284 |
282 |
utterances) |
285 |
|
|
286 |
282 |
return utterances |
287 |
|
|
288 |
1 |
def _getSpeechForAlert(self, obj, already_focused): |
289 |
|
"""Gets the title of the dialog and the contents of labels inside the |
290 |
|
dialog that are not associated with any other objects. |
291 |
|
|
292 |
|
Arguments: |
293 |
|
- obj: the Accessible dialog |
294 |
|
- already_focused: False if object just received focus |
295 |
|
|
296 |
|
Returns a list of utterances be spoken. |
297 |
|
""" |
298 |
|
|
299 |
14 |
utterances = [] |
300 |
14 |
label = self._getSpeechForObjectLabel(obj) |
301 |
14 |
utterances.extend(label) |
302 |
14 |
name = self._getSpeechForObjectName(obj) |
303 |
14 |
if name != label: |
304 |
13 |
utterances.extend(name) |
305 |
|
|
306 |
|
# Find all the unrelated labels in the dialog and speak them. |
307 |
|
# |
308 |
14 |
labels = self._script.findUnrelatedLabels(obj) |
309 |
39 |
for label in labels: |
310 |
25 |
utterances.append(label.name) |
311 |
|
|
312 |
14 |
self._debugGenerator("_getSpeechForAlert", |
313 |
14 |
obj, |
314 |
14 |
already_focused, |
315 |
14 |
utterances) |
316 |
|
|
317 |
14 |
return utterances |
318 |
|
|
319 |
1 |
def _getSpeechForAnimation(self, obj, already_focused): |
320 |
|
"""Gets the speech for an animation. |
321 |
|
|
322 |
|
Arguments: |
323 |
|
- obj: the animation |
324 |
|
- already_focused: False if object just received focus |
325 |
|
|
326 |
|
Returns a list of utterances to be spoken. |
327 |
|
""" |
328 |
|
|
329 |
0 |
utterances = [] |
330 |
0 |
label = self._getSpeechForObjectLabel(obj) |
331 |
0 |
utterances.extend(label) |
332 |
0 |
name = self._getSpeechForObjectName(obj) |
333 |
0 |
if name != label: |
334 |
0 |
utterances.extend(name) |
335 |
|
|
336 |
0 |
self._debugGenerator("_getSpeechForAnimation", |
337 |
0 |
obj, |
338 |
0 |
already_focused, |
339 |
0 |
utterances) |
340 |
|
|
341 |
0 |
return utterances |
342 |
|
|
343 |
1 |
def _getSpeechForArrow(self, obj, already_focused): |
344 |
|
"""Gets a list of utterances to be spoken for an arrow. |
345 |
|
|
346 |
|
Arguments: |
347 |
|
- obj: the arrow |
348 |
|
- already_focused: False if object just received focus |
349 |
|
|
350 |
|
Returns a list of utterances to be spoken for the object. |
351 |
|
""" |
352 |
|
|
353 |
|
# [[[TODO: determine orientation of arrow. Logged as bugzilla bug |
354 |
|
# 319744.]]] |
355 |
|
# text = arrow direction (left, right, up, down) |
356 |
|
# |
357 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
358 |
|
|
359 |
0 |
self._debugGenerator("_getSpeechForArrow", |
360 |
0 |
obj, |
361 |
0 |
already_focused, |
362 |
0 |
utterances) |
363 |
|
|
364 |
0 |
return utterances |
365 |
|
|
366 |
1 |
def _getSpeechForCheckBox(self, obj, already_focused): |
367 |
|
"""Get the speech for a check box. If the check box already had |
368 |
|
focus, then only the state is spoken. |
369 |
|
|
370 |
|
Arguments: |
371 |
|
- obj: the check box |
372 |
|
- already_focused: False if object just received focus |
373 |
|
|
374 |
|
Returns a list of utterances to be spoken for the object. |
375 |
|
""" |
376 |
|
|
377 |
72 |
utterances = [] |
378 |
72 |
if obj.state.count(atspi.Accessibility.STATE_CHECKED): |
379 |
|
# Translators: this represents the state of a checkbox. |
380 |
|
# |
381 |
30 |
checkedState = _("checked") |
382 |
|
else: |
383 |
|
# Translators: this represents the state of a checkbox. |
384 |
|
# |
385 |
42 |
checkedState = _("not checked") |
386 |
|
|
387 |
|
# If it's not already focused, say it's name |
388 |
|
# |
389 |
72 |
if not already_focused: |
390 |
63 |
label = self._getSpeechForObjectLabel(obj) |
391 |
63 |
utterances.extend(label) |
392 |
63 |
name = self._getSpeechForObjectName(obj) |
393 |
63 |
if name != label: |
394 |
16 |
utterances.extend(name) |
395 |
63 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
396 |
63 |
utterances.append(checkedState) |
397 |
63 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
398 |
|
else: |
399 |
9 |
utterances.append(checkedState) |
400 |
|
|
401 |
72 |
self._debugGenerator("_getSpeechForCheckBox", |
402 |
72 |
obj, |
403 |
72 |
already_focused, |
404 |
72 |
utterances) |
405 |
|
|
406 |
72 |
return utterances |
407 |
|
|
408 |
1 |
def _getSpeechForCheckMenuItem(self, obj, already_focused): |
409 |
|
"""Get the speech for a check menu item. If the check menu item |
410 |
|
already had focus, then only the state is spoken. |
411 |
|
|
412 |
|
Arguments: |
413 |
|
- obj: the check menu item |
414 |
|
- already_focused: False if object just received focus |
415 |
|
|
416 |
|
Returns a list of utterances to be spoken for the object. |
417 |
|
""" |
418 |
|
|
419 |
9 |
utterances = self._getSpeechForCheckBox(obj, already_focused) |
420 |
|
|
421 |
9 |
if (settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE)\ |
422 |
9 |
and not already_focused: |
423 |
9 |
utterances.extend(self._getSpeechForObjectAccelerator(obj)) |
424 |
|
|
425 |
9 |
self._debugGenerator("_getSpeechForCheckMenuItem", |
426 |
9 |
obj, |
427 |
9 |
already_focused, |
428 |
9 |
utterances) |
429 |
|
|
430 |
9 |
return utterances |
431 |
|
|
432 |
1 |
def _getSpeechForColumnHeader(self, obj, already_focused): |
433 |
|
"""Get the speech for a column header. |
434 |
|
|
435 |
|
Arguments: |
436 |
|
- obj: the column header |
437 |
|
- already_focused: False if object just received focus |
438 |
|
|
439 |
|
Returns a list of utterances to be spoken for the object. |
440 |
|
""" |
441 |
|
|
442 |
5 |
utterances = self._getDefaultSpeech(obj, already_focused) |
443 |
|
|
444 |
5 |
self._debugGenerator("_getSpeechForColumnHeader", |
445 |
5 |
obj, |
446 |
5 |
already_focused, |
447 |
5 |
utterances) |
448 |
|
|
449 |
5 |
return utterances |
450 |
|
|
451 |
1 |
def _getSpeechForComboBox(self, obj, already_focused): |
452 |
|
"""Get the speech for a combo box. If the combo box already has focus, |
453 |
|
then only the selection is spoken. |
454 |
|
|
455 |
|
Arguments: |
456 |
|
- obj: the combo box |
457 |
|
- already_focused: False if object just received focus |
458 |
|
|
459 |
|
Returns a list of utterances to be spoken for the object. |
460 |
|
""" |
461 |
|
|
462 |
20 |
utterances = [] |
463 |
|
|
464 |
20 |
if not already_focused: |
465 |
16 |
label = self._getSpeechForObjectLabel(obj) |
466 |
16 |
utterances.extend(label) |
467 |
|
else: |
468 |
4 |
label = None |
469 |
|
|
470 |
20 |
name = self._getSpeechForObjectName(obj) |
471 |
20 |
if name != label: |
472 |
20 |
utterances.extend(name) |
473 |
|
|
474 |
20 |
if not already_focused: |
475 |
16 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
476 |
|
|
477 |
20 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
478 |
|
|
479 |
20 |
self._debugGenerator("_getSpeechForComboBox", |
480 |
20 |
obj, |
481 |
20 |
already_focused, |
482 |
20 |
utterances) |
483 |
|
|
484 |
20 |
return utterances |
485 |
|
|
486 |
1 |
def _getSpeechForDesktopIcon(self, obj, already_focused): |
487 |
|
"""Get the speech for a desktop icon. |
488 |
|
|
489 |
|
Arguments: |
490 |
|
- obj: the desktop icon |
491 |
|
- already_focused: False if object just received focus |
492 |
|
|
493 |
|
Returns a list of utterances to be spoken for the object. |
494 |
|
""" |
495 |
|
|
496 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
497 |
|
|
498 |
0 |
self._debugGenerator("_getSpeechForDesktopIcon", |
499 |
0 |
obj, |
500 |
0 |
already_focused, |
501 |
0 |
utterances) |
502 |
|
|
503 |
0 |
return utterances |
504 |
|
|
505 |
1 |
def _getSpeechForDial(self, obj, already_focused): |
506 |
|
"""Get the speech for a dial. |
507 |
|
|
508 |
|
Arguments: |
509 |
|
- obj: the dial |
510 |
|
- already_focused: False if object just received focus |
511 |
|
|
512 |
|
Returns a list of utterances to be spoken for the object. |
513 |
|
""" |
514 |
|
|
515 |
|
# [[[TODO: WDW - might need to include the value here? Logged as |
516 |
|
# bugzilla bug 319746.]]] |
517 |
|
# |
518 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
519 |
|
|
520 |
0 |
self._debugGenerator("_getSpeechForDial", |
521 |
0 |
obj, |
522 |
0 |
already_focused, |
523 |
0 |
utterances) |
524 |
|
|
525 |
0 |
return utterances |
526 |
|
|
527 |
1 |
def _getSpeechForDialog(self, obj, already_focused): |
528 |
|
"""Get the speech for a dialog box. |
529 |
|
|
530 |
|
Arguments: |
531 |
|
- obj: the dialog box |
532 |
|
- already_focused: False if object just received focus |
533 |
|
|
534 |
|
Returns a list of utterances to be spoken for the object. |
535 |
|
""" |
536 |
|
|
537 |
11 |
utterances = self._getSpeechForAlert(obj, already_focused) |
538 |
|
|
539 |
11 |
self._debugGenerator("_getSpeechForDialog", |
540 |
11 |
obj, |
541 |
11 |
already_focused, |
542 |
11 |
utterances) |
543 |
|
|
544 |
11 |
return utterances |
545 |
|
|
546 |
1 |
def _getSpeechForDirectoryPane(self, obj, already_focused): |
547 |
|
"""Get the speech for a directory pane. |
548 |
|
|
549 |
|
Arguments: |
550 |
|
- obj: the dial |
551 |
|
- already_focused: False if object just received focus |
552 |
|
|
553 |
|
Returns a list of utterances to be spoken for the object. |
554 |
|
""" |
555 |
|
|
556 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
557 |
|
|
558 |
0 |
self._debugGenerator("_getSpeechForDirectoryPane", |
559 |
0 |
obj, |
560 |
0 |
already_focused, |
561 |
0 |
utterances) |
562 |
|
|
563 |
0 |
return utterances |
564 |
|
|
565 |
1 |
def _getSpeechForFrame(self, obj, already_focused): |
566 |
|
"""Get the speech for a frame. |
567 |
|
|
568 |
|
Arguments: |
569 |
|
- obj: the frame |
570 |
|
- already_focused: False if object just received focus |
571 |
|
|
572 |
|
Returns a list of utterances to be spoken for the object. |
573 |
|
""" |
574 |
|
|
575 |
|
# [[[TODO: richb - readjusted to just get the default speech instead |
576 |
|
# of treating the frame like an alert and speaking all unrelated |
577 |
|
# labels. We'll need to see if this has any adverse effects and |
578 |
|
# adjust accordingly.]]] |
579 |
|
# |
580 |
114 |
utterances = self._getDefaultSpeech(obj, already_focused) |
581 |
|
#utterances = self._getSpeechForAlert(obj, already_focused) |
582 |
|
|
583 |
114 |
self._debugGenerator("_getSpeechForFrame", |
584 |
114 |
obj, |
585 |
114 |
already_focused, |
586 |
114 |
utterances) |
587 |
|
|
588 |
114 |
return utterances |
589 |
|
|
590 |
1 |
def _getSpeechForHtmlContainer(self, obj, already_focused): |
591 |
|
"""Get the speech for an HTML container. |
592 |
|
|
593 |
|
Arguments: |
594 |
|
- obj: the dial |
595 |
|
- already_focused: False if object just received focus |
596 |
|
|
597 |
|
Returns a list of utterances to be spoken for the object. |
598 |
|
""" |
599 |
|
|
600 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
601 |
|
|
602 |
0 |
self._debugGenerator("_getSpeechForHtmlContainer", |
603 |
0 |
obj, |
604 |
0 |
already_focused, |
605 |
0 |
utterances) |
606 |
|
|
607 |
0 |
return utterances |
608 |
|
|
609 |
1 |
def _getSpeechForIcon(self, obj, already_focused): |
610 |
|
"""Get the speech for an icon. |
611 |
|
|
612 |
|
Arguments: |
613 |
|
- obj: the icon |
614 |
|
- already_focused: False if object just received focus |
615 |
|
|
616 |
|
Returns a list of utterances to be spoken for the object. |
617 |
|
""" |
618 |
|
|
619 |
|
# [[[TODO: WDW - HACK to remove availability output because nautilus |
620 |
|
# doesn't include this information for desktop icons. If, at some |
621 |
|
# point, it is determined that availability should be added back in, |
622 |
|
# then a custom script for nautilus needs to be written to remove the |
623 |
|
# availability.]]] |
624 |
|
# |
625 |
9 |
utterances = [] |
626 |
9 |
label = self._getSpeechForObjectLabel(obj) |
627 |
9 |
utterances.extend(label) |
628 |
9 |
name = self._getSpeechForObjectName(obj) |
629 |
9 |
if name != label: |
630 |
9 |
utterances.extend(name) |
631 |
|
|
632 |
9 |
if obj.image: |
633 |
9 |
description = obj.image.imageDescription |
634 |
9 |
if description and len(description): |
635 |
0 |
utterances.append(description) |
636 |
|
|
637 |
9 |
if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE: |
638 |
9 |
utterances.append(rolenames.getSpeechForRoleName(obj)) |
639 |
|
|
640 |
9 |
self._debugGenerator("_getSpeechForIcon", |
641 |
9 |
obj, |
642 |
9 |
already_focused, |
643 |
9 |
utterances) |
644 |
|
|
645 |
9 |
return utterances |
646 |
|
|
647 |
1 |
def _getSpeechForImage(self, obj, already_focused): |
648 |
|
"""Get the speech for an image. |
649 |
|
|
650 |
|
Arguments: |
651 |
|
- obj: the image |
652 |
|
- already_focused: False if object just received focus |
653 |
|
|
654 |
|
Returns a list of utterances to be spoken for the object. |
655 |
|
""" |
656 |
|
|
657 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
658 |
|
|
659 |
0 |
self._debugGenerator("_getSpeechForImage", |
660 |
0 |
obj, |
661 |
0 |
already_focused, |
662 |
0 |
utterances) |
663 |
|
|
664 |
0 |
return utterances |
665 |
|
|
666 |
1 |
def _getSpeechForLabel(self, obj, already_focused): |
667 |
|
"""Get the speech for a label. |
668 |
|
|
669 |
|
Arguments: |
670 |
|
- obj: the label |
671 |
|
- already_focused: False if object just received focus |
672 |
|
|
673 |
|
Returns a list of utterances to be spoken for the object. |
674 |
|
""" |
675 |
|
|
676 |
4 |
utterances = self._getDefaultSpeech(obj, already_focused) |
677 |
|
|
678 |
4 |
self._debugGenerator("_getSpeechForLabel", |
679 |
4 |
obj, |
680 |
4 |
already_focused, |
681 |
4 |
utterances) |
682 |
|
|
683 |
4 |
return utterances |
684 |
|
|
685 |
1 |
def _getSpeechForLayeredPane(self, obj, already_focused): |
686 |
|
"""Get the speech for a layered pane |
687 |
|
|
688 |
|
Arguments: |
689 |
|
- obj: the table |
690 |
|
- already_focused: False if object just received focus |
691 |
|
|
692 |
|
Returns a list of utterances to be spoken for the object. |
693 |
|
""" |
694 |
|
|
695 |
2 |
utterances = self._getDefaultSpeech(obj, already_focused) |
696 |
|
|
697 |
2 |
self._debugGenerator("_getSpeechForLayeredPane", |
698 |
2 |
obj, |
699 |
2 |
already_focused, |
700 |
2 |
utterances) |
701 |
|
|
702 |
|
# If this has no children, then let the user know. |
703 |
|
# |
704 |
2 |
hasItems = False |
705 |
2 |
for i in range(0, obj.childCount): |
706 |
2 |
child = obj.child(i) |
707 |
2 |
if child.state.count(atspi.Accessibility.STATE_SHOWING): |
708 |
2 |
hasItems = True |
709 |
2 |
break |
710 |
2 |
if not hasItems: |
711 |
|
# Translators: this is the number of items in a layered pane |
712 |
|
# or table. |
713 |
|
# |
714 |
0 |
utterances.append(_("0 items")) |
715 |
|
|
716 |
2 |
return utterances |
717 |
|
|
718 |
1 |
def _getSpeechForList(self, obj, already_focused): |
719 |
|
"""Get the speech for a list. |
720 |
|
|
721 |
|
Arguments: |
722 |
|
- obj: the list |
723 |
|
- already_focused: False if object just received focus |
724 |
|
|
725 |
|
Returns a list of utterances to be spoken for the object. |
726 |
|
""" |
727 |
|
|
728 |
|
# [[[TODO: WDW - include how many items in the list? |
729 |
|
# Logged as bugzilla bug 319749.]]] |
730 |
|
# |
731 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
732 |
|
|
733 |
0 |
self._debugGenerator("_getSpeechForList", |
734 |
0 |
obj, |
735 |
0 |
already_focused, |
736 |
0 |
utterances) |
737 |
|
|
738 |
0 |
return utterances |
739 |
|
|
740 |
1 |
def _getSpeechForListItem(self, obj, already_focused): |
741 |
|
"""Get the speech for a listitem. |
742 |
|
|
743 |
|
Arguments: |
744 |
|
- obj: the listitem |
745 |
|
- already_focused: False if object just received focus |
746 |
|
|
747 |
|
Returns a list of utterances to be spoken for the object. |
748 |
|
""" |
749 |
|
|
750 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
751 |
|
|
752 |
|
# If already in focus then the tree probably collapsed or expanded |
753 |
0 |
if obj.state.count(atspi.Accessibility.STATE_EXPANDABLE): |
754 |
0 |
if obj.state.count(atspi.Accessibility.STATE_EXPANDED): |
755 |
|
# Translators: this represents the state of a node in a tree. |
756 |
|
# 'expanded' means the children are showing. |
757 |
|
# 'collapsed' means the children are not showing. |
758 |
|
# |
759 |
0 |
utterances.append(_("expanded")) |
760 |
|
else: |
761 |
|
# Translators: this represents the state of a node in a tree. |
762 |
|
# 'expanded' means the children are showing. |
763 |
|
# 'collapsed' means the children are not showing. |
764 |
|
# |
765 |
0 |
utterances.append(_("collapsed")) |
766 |
|
|
767 |
|
# Translators: this is the role name for this object |
768 |
|
# |
769 |
0 |
utterances.append(rolenames.getSpeechForRoleName(obj)) |
770 |
0 |
level = self._script.getNodeLevel(obj) |
771 |
0 |
if level >= 0: |
772 |
|
# Translators: this represents the depth of a node in a tree |
773 |
|
# view (i.e., how many ancestors a node has). |
774 |
|
# |
775 |
0 |
utterances.append(_('level %d') %(level + 1)) |
776 |
|
|
777 |
0 |
self._debugGenerator("_getSpeechForListItem", |
778 |
0 |
obj, |
779 |
0 |
already_focused, |
780 |
0 |
utterances) |
781 |
0 |
return utterances |
782 |
|
|
783 |
1 |
def _getSpeechForMenu(self, obj, already_focused): |
784 |
|
"""Get the speech for a menu. |
785 |
|
|
786 |
|
Arguments: |
787 |
|
- obj: the menu |
788 |
|
- already_focused: False if object just received focus |
789 |
|
|
790 |
|
Returns a list of utterances to be spoken for the object. |
791 |
|
""" |
792 |
|
|
793 |
8 |
utterances = self._getDefaultSpeech(obj, already_focused) |
794 |
|
|
795 |
8 |
if (obj == orca_state.locusOfFocus) \ |
796 |
8 |
and (settings.speechVerbosityLevel \ |
797 |
8 |
== settings.VERBOSITY_LEVEL_VERBOSE): |
798 |
8 |
utterances.extend(self._getSpeechForObjectAccelerator(obj)) |
799 |
|
|
800 |
8 |
self._debugGenerator("_getSpeechForMenu", |
801 |
8 |
obj, |
802 |
8 |
already_focused, |
803 |
8 |
utterances) |
804 |
|
|
805 |
8 |
return utterances |
806 |
|
|
807 |
1 |
def _getSpeechForMenuBar(self, obj, already_focused): |
808 |
|
"""Get the speech for a menu bar. |
809 |
|
|
810 |
|
Arguments: |
811 |
|
- obj: the menu bar |
812 |
|
- already_focused: False if object just received focus |
813 |
|
|
814 |
|
Returns a list of utterances to be spoken for the object. |
815 |
|
""" |
816 |
|
|
817 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
818 |
|
|
819 |
0 |
self._debugGenerator("_getSpeechForMenuBar", |
820 |
0 |
obj, |
821 |
0 |
already_focused, |
822 |
0 |
utterances) |
823 |
|
|
824 |
0 |
return utterances |
825 |
|
|
826 |
1 |
def _getSpeechForMenuItem(self, obj, already_focused): |
827 |
|
"""Get the speech for a menu item. |
828 |
|
|
829 |
|
Arguments: |
830 |
|
- obj: the menu item |
831 |
|
- already_focused: False if object just received focus |
832 |
|
|
833 |
|
Returns a list of utterances to be spoken for the object. |
834 |
|
""" |
835 |
|
|
836 |
|
# No need to say "menu item" because we already know that. |
837 |
|
# |
838 |
18 |
utterances = self._getSpeechForObjectName(obj) |
839 |
18 |
if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE: |
840 |
18 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
841 |
18 |
utterances.extend(self._getSpeechForObjectAccelerator(obj)) |
842 |
|
|
843 |
|
# OpenOffice check menu items currently have a role of "menu item" |
844 |
|
# rather then "check menu item", so we need to test if one of the |
845 |
|
# states is CHECKED. If it is, then add that in to the list of |
846 |
|
# speech utterances. Note that we can't tell if this is a "check |
847 |
|
# menu item" that is currently unchecked and speak that state. |
848 |
|
# See Orca bug #433398 for more details. |
849 |
|
# |
850 |
18 |
if obj.state.count(atspi.Accessibility.STATE_CHECKED): |
851 |
|
# Translators: this represents the state of a checked menu item. |
852 |
|
# |
853 |
0 |
utterances.append(_("checked")) |
854 |
|
|
855 |
18 |
self._debugGenerator("_getSpeechForMenuItem", |
856 |
18 |
obj, |
857 |
18 |
already_focused, |
858 |
18 |
utterances) |
859 |
|
|
860 |
18 |
return utterances |
861 |
|
|
862 |
1 |
def _getSpeechForText(self, obj, already_focused): |
863 |
|
"""Get the speech for a text component. |
864 |
|
|
865 |
|
Arguments: |
866 |
|
- obj: the text component |
867 |
|
- already_focused: False if object just received focus |
868 |
|
|
869 |
|
Returns a list of utterances to be spoken for the object. |
870 |
|
""" |
871 |
|
|
872 |
|
# [[[TODO: WDW - HACK to remove availability because some text |
873 |
|
# areas, such as those in yelp, come up as insensitive though |
874 |
|
# they really are ineditable.]]] |
875 |
|
# |
876 |
63 |
utterances = [] |
877 |
63 |
utterances.extend(self._getSpeechForObjectLabel(obj)) |
878 |
63 |
if len(utterances) == 0: |
879 |
58 |
if obj.name and (len(obj.name)): |
880 |
0 |
utterances.append(obj.name) |
881 |
63 |
if obj.role != rolenames.ROLE_PARAGRAPH: |
882 |
63 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
883 |
|
|
884 |
63 |
[text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj) |
885 |
63 |
utterances.append(text) |
886 |
|
|
887 |
63 |
self._debugGenerator("_getSpeechForText", |
888 |
63 |
obj, |
889 |
63 |
already_focused, |
890 |
63 |
utterances) |
891 |
|
|
892 |
63 |
return utterances |
893 |
|
|
894 |
1 |
def _getSpeechForOptionPane(self, obj, already_focused): |
895 |
|
"""Get the speech for an option pane. |
896 |
|
|
897 |
|
Arguments: |
898 |
|
- obj: the option pane |
899 |
|
- already_focused: False if object just received focus |
900 |
|
|
901 |
|
Returns a list of utterances to be spoken for the object. |
902 |
|
""" |
903 |
|
|
904 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
905 |
|
|
906 |
0 |
self._debugGenerator("_getSpeechForOptionPane", |
907 |
0 |
obj, |
908 |
0 |
already_focused, |
909 |
0 |
utterances) |
910 |
|
|
911 |
0 |
return utterances |
912 |
|
|
913 |
1 |
def _getSpeechForPageTab(self, obj, already_focused): |
914 |
|
"""Get the speech for a page tab. |
915 |
|
|
916 |
|
Arguments: |
917 |
|
- obj: the page tab |
918 |
|
- already_focused: False if object just received focus |
919 |
|
|
920 |
|
Returns a list of utterances to be spoken for the object. |
921 |
|
""" |
922 |
|
|
923 |
12 |
utterances = self._getDefaultSpeech(obj, already_focused) |
924 |
|
|
925 |
12 |
self._debugGenerator("_getSpeechForPageTab", |
926 |
12 |
obj, |
927 |
12 |
already_focused, |
928 |
12 |
utterances) |
929 |
|
|
930 |
12 |
return utterances |
931 |
|
|
932 |
1 |
def _getSpeechForPageTabList(self, obj, already_focused): |
933 |
|
"""Get the speech for a page tab list. |
934 |
|
|
935 |
|
Arguments: |
936 |
|
- obj: the page tab list |
937 |
|
- already_focused: False if object just received focus |
938 |
|
|
939 |
|
Returns a list of utterances to be spoken for the object. |
940 |
|
""" |
941 |
|
|
942 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
943 |
|
|
944 |
|
#if obj.childCount == 1: |
945 |
|
# utterances.append(_("one tab")) |
946 |
|
#else: |
947 |
|
# utterances.append(("%d " % obj.childCount) + _("tabs")) |
948 |
|
|
949 |
0 |
self._debugGenerator("_getSpeechForPageTabList", |
950 |
0 |
obj, |
951 |
0 |
already_focused, |
952 |
0 |
utterances) |
953 |
|
|
954 |
0 |
return utterances |
955 |
|
|
956 |
1 |
def _getSpeechForProgressBar(self, obj, already_focused): |
957 |
|
"""Get the speech for a progress bar. If the object already |
958 |
|
had focus, just the new value is spoken. |
959 |
|
|
960 |
|
Arguments: |
961 |
|
- obj: the progress bar |
962 |
|
- already_focused: False if object just received focus |
963 |
|
|
964 |
|
Returns a list of utterances to be spoken for the object. |
965 |
|
""" |
966 |
|
|
967 |
0 |
percentValue = (obj.value.currentValue / \ |
968 |
0 |
(obj.value.maximumValue - obj.value.minimumValue)) * 100.0 |
969 |
|
|
970 |
|
# Translators: this is the percentage value of a progress bar. |
971 |
|
# |
972 |
0 |
percentage = _("%d percent.") % percentValue + " " |
973 |
|
|
974 |
0 |
utterances = [] |
975 |
|
|
976 |
0 |
if not already_focused: |
977 |
0 |
label = self._getSpeechForObjectLabel(obj) |
978 |
0 |
utterances.extend(label) |
979 |
0 |
name = self._getSpeechForObjectName(obj) |
980 |
0 |
if name != label: |
981 |
0 |
utterances.extend(name) |
982 |
0 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
983 |
|
|
984 |
0 |
utterances.append(percentage) |
985 |
|
|
986 |
0 |
self._debugGenerator("_getSpeechForProgressBar", |
987 |
0 |
obj, |
988 |
0 |
already_focused, |
989 |
0 |
utterances) |
990 |
|
|
991 |
0 |
return utterances |
992 |
|
|
993 |
1 |
def _getSpeechForPushButton(self, obj, already_focused): |
994 |
|
"""Get the speech for a push button |
995 |
|
|
996 |
|
Arguments: |
997 |
|
- obj: the push button |
998 |
|
- already_focused: False if object just received focus |
999 |
|
|
1000 |
|
Returns a list of utterances to be spoken for the object. |
1001 |
|
""" |
1002 |
|
|
1003 |
106 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1004 |
|
|
1005 |
106 |
self._debugGenerator("_getSpeechForPushButton", |
1006 |
106 |
obj, |
1007 |
106 |
already_focused, |
1008 |
106 |
utterances) |
1009 |
|
|
1010 |
106 |
return utterances |
1011 |
|
|
1012 |
1 |
def _getSpeechForRadioButton(self, obj, already_focused): |
1013 |
|
"""Get the speech for a radio button. If the button already had |
1014 |
|
focus, then only the state is spoken. |
1015 |
|
|
1016 |
|
Arguments: |
1017 |
|
- obj: the check box |
1018 |
|
- already_focused: False if object just received focus |
1019 |
|
|
1020 |
|
Returns a list of utterances to be spoken for the object. |
1021 |
|
""" |
1022 |
|
|
1023 |
7 |
utterances = [] |
1024 |
7 |
if obj.state.count(atspi.Accessibility.STATE_CHECKED): |
1025 |
|
# Translators: this is in reference to a radio button being |
1026 |
|
# selected or not. |
1027 |
|
# |
1028 |
7 |
selectionState = _("selected") |
1029 |
|
else: |
1030 |
|
# Translators: this is in reference to a radio button being |
1031 |
|
# selected or not. |
1032 |
|
# |
1033 |
0 |
selectionState = _("not selected") |
1034 |
|
|
1035 |
|
# If it's not already focused, say it's name |
1036 |
|
# |
1037 |
7 |
if not already_focused: |
1038 |
|
# The label is handled as a context in default.py |
1039 |
|
# |
1040 |
|
#utterances.extend(self._getSpeechForObjectLabel(obj)) |
1041 |
7 |
utterances.extend(self._getSpeechForObjectName(obj)) |
1042 |
7 |
utterances.append(selectionState) |
1043 |
7 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
1044 |
7 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
1045 |
|
else: |
1046 |
0 |
utterances.append(selectionState) |
1047 |
|
|
1048 |
7 |
self._debugGenerator("_getSpeechForRadioButton", |
1049 |
7 |
obj, |
1050 |
7 |
already_focused, |
1051 |
7 |
utterances) |
1052 |
|
|
1053 |
7 |
return utterances |
1054 |
|
|
1055 |
1 |
def _getSpeechForRadioMenuItem(self, obj, already_focused): |
1056 |
|
"""Get the speech for a radio menu item. If the menu item |
1057 |
|
already had focus, then only the state is spoken. |
1058 |
|
|
1059 |
|
Arguments: |
1060 |
|
- obj: the check menu item |
1061 |
|
- already_focused: False if object just received focus |
1062 |
|
|
1063 |
|
Returns a list of utterances to be spoken for the object. |
1064 |
|
""" |
1065 |
|
|
1066 |
1 |
utterances = self._getSpeechForRadioButton(obj, False) |
1067 |
|
|
1068 |
1 |
if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE: |
1069 |
1 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
1070 |
1 |
utterances.extend(self._getSpeechForObjectAccelerator(obj)) |
1071 |
|
|
1072 |
1 |
self._debugGenerator("_getSpeechForRadioMenuItem", |
1073 |
1 |
obj, |
1074 |
1 |
already_focused, |
1075 |
1 |
utterances) |
1076 |
|
|
1077 |
1 |
return utterances |
1078 |
|
|
1079 |
1 |
def _getSpeechForRowHeader(self, obj, already_focused): |
1080 |
|
"""Get the speech for a row header. |
1081 |
|
|
1082 |
|
Arguments: |
1083 |
|
- obj: the column header |
1084 |
|
- already_focused: False if object just received focus |
1085 |
|
|
1086 |
|
Returns a list of utterances to be spoken for the object. |
1087 |
|
""" |
1088 |
|
|
1089 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1090 |
|
|
1091 |
0 |
self._debugGenerator("_getSpeechForRowHeader", |
1092 |
0 |
obj, |
1093 |
0 |
already_focused, |
1094 |
0 |
utterances) |
1095 |
|
|
1096 |
0 |
return utterances |
1097 |
|
|
1098 |
1 |
def _getSpeechForScrollBar(self, obj, already_focused): |
1099 |
|
"""Get the speech for a scroll bar. |
1100 |
|
|
1101 |
|
Arguments: |
1102 |
|
- obj: the scroll bar |
1103 |
|
- already_focused: False if object just received focus |
1104 |
|
|
1105 |
|
Returns a list of utterances to be spoken for the object. |
1106 |
|
""" |
1107 |
|
|
1108 |
|
# [[[TODO: WDW - want to get orientation and maybe the |
1109 |
|
# percentage scrolled so far. Logged as bugzilla bug |
1110 |
|
# 319744.]]] |
1111 |
|
# |
1112 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1113 |
|
|
1114 |
0 |
self._debugGenerator("_getSpeechForScrollBar", |
1115 |
0 |
obj, |
1116 |
0 |
already_focused, |
1117 |
0 |
utterances) |
1118 |
|
|
1119 |
0 |
return utterances |
1120 |
|
|
1121 |
1 |
def _getSpeechForSlider(self, obj, already_focused): |
1122 |
|
"""Get the speech for a slider. If the object already |
1123 |
|
had focus, just the value is spoken. |
1124 |
|
|
1125 |
|
Arguments: |
1126 |
|
- obj: the slider |
1127 |
|
- already_focused: False if object just received focus |
1128 |
|
|
1129 |
|
Returns a list of utterances to be spoken for the object. |
1130 |
|
""" |
1131 |
|
|
1132 |
0 |
value = obj.value |
1133 |
|
|
1134 |
|
# OK, this craziness is all about trying to figure out the most |
1135 |
|
# meaningful formatting string for the floating point values. |
1136 |
|
# The number of places to the right of the decimal point should |
1137 |
|
# be set by the minimumIncrement, but the minimumIncrement isn't |
1138 |
|
# always set. So...we'll default the minimumIncrement to 1/100 |
1139 |
|
# of the range. But, if max == min, then we'll just go for showing |
1140 |
|
# them off to two meaningful digits. |
1141 |
|
# |
1142 |
0 |
try: |
1143 |
0 |
minimumIncrement = value.minimumIncrement |
1144 |
0 |
except: |
1145 |
0 |
minimumIncrement = 0.0 |
1146 |
|
|
1147 |
0 |
if minimumIncrement == 0.0: |
1148 |
0 |
minimumIncrement = (value.maximumValue - value.minimumValue) \ |
1149 |
0 |
/ 100.0 |
1150 |
|
|
1151 |
0 |
try: |
1152 |
0 |
decimalPlaces = max(0, -math.log10(minimumIncrement)) |
1153 |
0 |
except: |
1154 |
0 |
try: |
1155 |
0 |
decimalPlaces = max(0, -math.log10(value.minimumValue)) |
1156 |
0 |
except: |
1157 |
0 |
try: |
1158 |
0 |
decimalPlaces = max(0, -math.log10(value.maximumValue)) |
1159 |
0 |
except: |
1160 |
0 |
decimalPlaces = 0 |
1161 |
|
|
1162 |
0 |
formatter = "%%.%df" % decimalPlaces |
1163 |
0 |
valueString = formatter % value.currentValue |
1164 |
|
#minString = formatter % value.minimumValue |
1165 |
|
#maxString = formatter % value.maximumValue |
1166 |
|
|
1167 |
0 |
if already_focused: |
1168 |
0 |
utterances = [valueString] |
1169 |
|
else: |
1170 |
0 |
utterances = [] |
1171 |
0 |
utterances.extend(self._getSpeechForObjectLabel(obj)) |
1172 |
|
|
1173 |
|
# Ignore the text on the slider. See bug 340559 |
1174 |
|
# (http://bugzilla.gnome.org/show_bug.cgi?id=340559): the |
1175 |
|
# implementors of the slider support decided to put in a |
1176 |
|
# Unicode left-to-right character as part of the text, |
1177 |
|
# even though that is not painted on the screen. |
1178 |
|
# |
1179 |
|
# In Java, however, there are sliders without a label. In |
1180 |
|
# this case, we'll add to presentation the slider name if |
1181 |
|
# it exists and we haven't found anything yet. |
1182 |
|
# |
1183 |
0 |
if not utterances: |
1184 |
0 |
utterances.extend(self._getSpeechForObjectName(obj)) |
1185 |
|
|
1186 |
0 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
1187 |
0 |
utterances.append(valueString) |
1188 |
0 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
1189 |
|
|
1190 |
0 |
self._debugGenerator("_getSpeechForSlider", |
1191 |
0 |
obj, |
1192 |
0 |
already_focused, |
1193 |
0 |
utterances) |
1194 |
|
|
1195 |
0 |
return utterances |
1196 |
|
|
1197 |
1 |
def _getSpeechForSpinButton(self, obj, already_focused): |
1198 |
|
"""Get the speech for a spin button. If the object already has |
1199 |
|
focus, then only the new value is spoken. |
1200 |
|
|
1201 |
|
Arguments: |
1202 |
|
- obj: the spin button |
1203 |
|
- already_focused: False if object just received focus |
1204 |
|
|
1205 |
|
Returns a list of utterances to be spoken for the object. |
1206 |
|
""" |
1207 |
|
|
1208 |
5 |
if already_focused: |
1209 |
0 |
utterances = [self._script.getDisplayedText(obj)] |
1210 |
|
else: |
1211 |
5 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1212 |
|
|
1213 |
5 |
self._debugGenerator("_getSpeechForSpinButton", |
1214 |
5 |
obj, |
1215 |
5 |
already_focused, |
1216 |
5 |
utterances) |
1217 |
|
|
1218 |
5 |
return utterances |
1219 |
|
|
1220 |
1 |
def _getSpeechForSplitPane(self, obj, already_focused): |
1221 |
|
"""Get the speech for a split pane. |
1222 |
|
|
1223 |
|
Arguments: |
1224 |
|
- obj: the split pane |
1225 |
|
- already_focused: False if object just received focus |
1226 |
|
|
1227 |
|
Returns a list of utterances to be spoken for the object. |
1228 |
|
""" |
1229 |
|
|
1230 |
12 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1231 |
|
|
1232 |
12 |
self._debugGenerator("_getSpeechForSplitPane", |
1233 |
12 |
obj, |
1234 |
12 |
already_focused, |
1235 |
12 |
utterances) |
1236 |
|
|
1237 |
12 |
return utterances |
1238 |
|
|
1239 |
1 |
def _getSpeechForTable(self, obj, already_focused): |
1240 |
|
"""Get the speech for a table |
1241 |
|
|
1242 |
|
Arguments: |
1243 |
|
- obj: the table |
1244 |
|
- already_focused: False if object just received focus |
1245 |
|
|
1246 |
|
Returns a list of utterances to be spoken for the object. |
1247 |
|
""" |
1248 |
|
|
1249 |
5 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1250 |
|
|
1251 |
5 |
self._debugGenerator("_getSpeechForTable", |
1252 |
5 |
obj, |
1253 |
5 |
already_focused, |
1254 |
5 |
utterances) |
1255 |
|
|
1256 |
|
# If this is a table with no children, then let the user know. |
1257 |
|
# |
1258 |
5 |
hasItems = False |
1259 |
41 |
for i in range(0, obj.childCount): |
1260 |
41 |
child = obj.child(i) |
1261 |
41 |
if child.state.count(atspi.Accessibility.STATE_SHOWING): |
1262 |
5 |
hasItems = True |
1263 |
5 |
break |
1264 |
5 |
if not hasItems: |
1265 |
|
# Translators: this is the number of items in a layered pane |
1266 |
|
# or table. |
1267 |
|
# |
1268 |
0 |
utterances.append(_("0 items")) |
1269 |
|
|
1270 |
5 |
return utterances |
1271 |
|
|
1272 |
1 |
def _getSpeechForTableCell(self, obj, already_focused): |
1273 |
|
"""Get the speech utterances for a single table cell |
1274 |
|
|
1275 |
|
Arguments: |
1276 |
|
- obj: the table |
1277 |
|
- already_focused: False if object just received focus |
1278 |
|
|
1279 |
|
Returns a list of utterances to be spoken for the object. |
1280 |
|
""" |
1281 |
|
|
1282 |
281 |
utterances = [] |
1283 |
|
|
1284 |
|
# If this table cell has 2 children and one of them has a |
1285 |
|
# 'toggle' action and the other does not, then present this |
1286 |
|
# as a checkbox where: |
1287 |
|
# 1) we get the checked state from the cell with the 'toggle' action |
1288 |
|
# 2) we get the label from the other cell. |
1289 |
|
# See Orca bug #376015 for more details. |
1290 |
|
# |
1291 |
281 |
if obj.childCount == 2: |
1292 |
0 |
cellOrder = [] |
1293 |
0 |
hasToggle = [ False, False ] |
1294 |
0 |
for i in range(0, obj.childCount): |
1295 |
0 |
action = obj.child(i).action |
1296 |
0 |
if action: |
1297 |
0 |
for j in range(0, action.nActions): |
1298 |
0 |
if action.getName(j) == "toggle": |
1299 |
0 |
hasToggle[i] = True |
1300 |
0 |
break |
1301 |
|
|
1302 |
0 |
if hasToggle[0] and not hasToggle[1]: |
1303 |
0 |
cellOrder = [ 1, 0 ] |
1304 |
0 |
elif not hasToggle[0] and hasToggle[1]: |
1305 |
0 |
cellOrder = [ 0, 1 ] |
1306 |
0 |
if cellOrder: |
1307 |
0 |
for i in cellOrder: |
1308 |
|
# Don't speak the label if just the checkbox state has |
1309 |
|
# changed. |
1310 |
|
# |
1311 |
0 |
if already_focused and not hasToggle[i]: |
1312 |
0 |
pass |
1313 |
|
else: |
1314 |
0 |
utterances.extend( \ |
1315 |
0 |
self._getSpeechForTableCell(obj.child(i), |
1316 |
0 |
already_focused)) |
1317 |
0 |
return utterances |
1318 |
|
|
1319 |
|
# [[[TODO: WDW - Attempt to infer the cell type. There's a |
1320 |
|
# bunch of stuff we can do here, such as check the EXPANDABLE |
1321 |
|
# state, check the NODE_CHILD_OF relation, etc. Logged as |
1322 |
|
# bugzilla bug 319750.]]] |
1323 |
|
# |
1324 |
281 |
action = obj.action |
1325 |
281 |
if action: |
1326 |
561 |
for i in range(0, action.nActions): |
1327 |
343 |
debug.println(debug.LEVEL_FINEST, |
1328 |
343 |
"speechgenerator.__getTableCellUtterances " \ |
1329 |
343 |
+ "looking at action %d" % i) |
1330 |
343 |
if action.getName(i) == "toggle": |
1331 |
47 |
obj.role = rolenames.ROLE_CHECK_BOX |
1332 |
47 |
utterances = self._getSpeechForCheckBox(obj, |
1333 |
47 |
already_focused) |
1334 |
47 |
obj.role = rolenames.ROLE_TABLE_CELL |
1335 |
47 |
break |
1336 |
|
|
1337 |
281 |
utterances.append(self._script.getDisplayedText(\ |
1338 |
281 |
self._script.getRealActiveDescendant(obj))) |
1339 |
|
|
1340 |
|
# [[[TODO: WDW - HACK attempt to determine if this is a node; |
1341 |
|
# if so, describe its state.]]] |
1342 |
|
# |
1343 |
281 |
if obj.state.count(atspi.Accessibility.STATE_EXPANDABLE): |
1344 |
34 |
if obj.state.count(atspi.Accessibility.STATE_EXPANDED): |
1345 |
|
# Translators: this represents the state of a node in a tree. |
1346 |
|
# 'expanded' means the children are showing. |
1347 |
|
# 'collapsed' means the children are not showing. |
1348 |
|
# |
1349 |
18 |
utterances.append(_("expanded")) |
1350 |
|
else: |
1351 |
|
# Translators: this represents the state of a node in a tree. |
1352 |
|
# 'expanded' means the children are showing. |
1353 |
|
# 'collapsed' means the children are not showing. |
1354 |
|
# |
1355 |
16 |
utterances.append(_("collapsed")) |
1356 |
|
|
1357 |
|
# If this is an expandable table cell with no children, then |
1358 |
|
# let the user know. |
1359 |
|
# |
1360 |
34 |
if obj.childCount == 0: |
1361 |
|
# Translators: this is the number of items in a layered pane |
1362 |
|
# or table. |
1363 |
|
# |
1364 |
34 |
utterances.append(_("0 items")) |
1365 |
|
|
1366 |
281 |
self._debugGenerator("_getSpeechForTableCell", |
1367 |
281 |
obj, |
1368 |
281 |
already_focused, |
1369 |
281 |
utterances) |
1370 |
|
|
1371 |
281 |
return utterances |
1372 |
|
|
1373 |
1 |
def _getSpeechForTableCellRow(self, obj, already_focused): |
1374 |
|
"""Get the speech for a table cell row or a single table cell |
1375 |
|
if settings.readTableCellRow is False. |
1376 |
|
|
1377 |
|
Arguments: |
1378 |
|
- obj: the table |
1379 |
|
- already_focused: False if object just received focus |
1380 |
|
|
1381 |
|
Returns a list of utterances to be spoken for the object. |
1382 |
|
""" |
1383 |
|
|
1384 |
201 |
utterances = [] |
1385 |
|
|
1386 |
201 |
if (not already_focused): |
1387 |
183 |
if settings.readTableCellRow and obj.parent.table \ |
1388 |
173 |
and (not self._script.isLayoutOnly(obj.parent)): |
1389 |
173 |
parent = obj.parent |
1390 |
173 |
row = parent.table.getRowAtIndex(obj.index) |
1391 |
173 |
column = parent.table.getColumnAtIndex(obj.index) |
1392 |
|
|
1393 |
|
# This is an indication of whether we should speak all the |
1394 |
|
# table cells (the user has moved focus up or down a row), |
1395 |
|
# or just the current one (focus has moved left or right in |
1396 |
|
# the same row). |
1397 |
|
# |
1398 |
173 |
speakAll = True |
1399 |
173 |
if parent.__dict__.has_key("lastRow") and \ |
1400 |
131 |
parent.__dict__.has_key("lastColumn"): |
1401 |
131 |
speakAll = (parent.lastRow != row) or \ |
1402 |
34 |
((row == 0 or row == parent.table.nRows-1) and \ |
1403 |
17 |
parent.lastColumn == column) |
1404 |
|
|
1405 |
173 |
if speakAll: |
1406 |
382 |
for i in range(0, parent.table.nColumns): |
1407 |
231 |
accRow = parent.table.getAccessibleAt(row, i) |
1408 |
231 |
cell = atspi.Accessible.makeAccessible(accRow) |
1409 |
231 |
showing = cell.state.count( \ |
1410 |
231 |
atspi.Accessibility.STATE_SHOWING) |
1411 |
231 |
if showing: |
1412 |
|
# If this table cell has a "toggle" action, and |
1413 |
|
# doesn't have any label associated with it then |
1414 |
|
# also speak the table column header. |
1415 |
|
# See Orca bug #455230 for more details. |
1416 |
|
# |
1417 |
231 |
label = self._script.getDisplayedText( \ |
1418 |
231 |
self._script.getRealActiveDescendant(cell)) |
1419 |
231 |
action = cell.action |
1420 |
231 |
if action and (label == None or len(label) == 0): |
1421 |
138 |
for j in range(0, action.nActions): |
1422 |
92 |
if action.getName(j) == "toggle": |
1423 |
46 |
header = parent.table.getColumnHeader(i) |
1424 |
46 |
accHeader = atspi.Accessible.makeAccessible(header) |
1425 |
46 |
utterances.append(accHeader.name) |
1426 |
|
|
1427 |
231 |
utterances.extend(self._getSpeechForTableCell(cell, |
1428 |
231 |
already_focused)) |
1429 |
|
else: |
1430 |
22 |
utterances.extend(self._getSpeechForTableCell(obj, |
1431 |
22 |
already_focused)) |
1432 |
|
else: |
1433 |
10 |
utterances = self._getSpeechForTableCell(obj, already_focused) |
1434 |
|
else: |
1435 |
18 |
utterances = self._getSpeechForTableCell(obj, already_focused) |
1436 |
|
|
1437 |
201 |
self._debugGenerator("_getSpeechForTableCellRow", |
1438 |
201 |
obj, |
1439 |
201 |
already_focused, |
1440 |
201 |
utterances) |
1441 |
|
|
1442 |
201 |
return utterances |
1443 |
|
|
1444 |
1 |
def _getSpeechForTableColumnHeader(self, obj, already_focused): |
1445 |
|
"""Get the speech for a table column header |
1446 |
|
|
1447 |
|
Arguments: |
1448 |
|
- obj: the table column header |
1449 |
|
- already_focused: False if object just received focus |
1450 |
|
|
1451 |
|
Returns a list of utterances to be spoken for the object. |
1452 |
|
""" |
1453 |
|
|
1454 |
5 |
utterances = self._getSpeechForColumnHeader(obj, already_focused) |
1455 |
|
|
1456 |
5 |
self._debugGenerator("_getSpeechForTableColumnHeader", |
1457 |
5 |
obj, |
1458 |
5 |
already_focused, |
1459 |
5 |
utterances) |
1460 |
|
|
1461 |
5 |
return utterances |
1462 |
|
|
1463 |
1 |
def _getSpeechForTableRowHeader(self, obj, already_focused): |
1464 |
|
"""Get the speech for a table row header |
1465 |
|
|
1466 |
|
Arguments: |
1467 |
|
- obj: the table row header |
1468 |
|
- already_focused: False if object just received focus |
1469 |
|
|
1470 |
|
Returns a list of utterances to be spoken for the object. |
1471 |
|
""" |
1472 |
|
|
1473 |
0 |
utterances = self._getSpeechForRowHeader(obj, already_focused) |
1474 |
|
|
1475 |
0 |
self._debugGenerator("_getSpeechForTableRowHeader", |
1476 |
0 |
obj, |
1477 |
0 |
already_focused, |
1478 |
0 |
utterances) |
1479 |
|
|
1480 |
0 |
return utterances |
1481 |
|
|
1482 |
1 |
def _getSpeechForTearOffMenuItem(self, obj, already_focused): |
1483 |
|
"""Get the speech for a tear off menu item |
1484 |
|
|
1485 |
|
Arguments: |
1486 |
|
- obj: the tear off menu item |
1487 |
|
- already_focused: False if object just received focus |
1488 |
|
|
1489 |
|
Returns a list of utterances to be spoken for the object. |
1490 |
|
""" |
1491 |
|
|
1492 |
0 |
if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE: |
1493 |
0 |
utterances = [rolenames.getSpeechForRoleName(obj)] |
1494 |
|
else: |
1495 |
|
# Translators: brief spoken words for the rolename of a tear off |
1496 |
|
# menu item. |
1497 |
|
# |
1498 |
0 |
utterances = [_("tear off")] |
1499 |
|
|
1500 |
0 |
self._debugGenerator("_getSpeechForTearOffMenuItem", |
1501 |
0 |
obj, |
1502 |
0 |
already_focused, |
1503 |
0 |
utterances) |
1504 |
|
|
1505 |
0 |
return utterances |
1506 |
|
|
1507 |
1 |
def _getSpeechForTerminal(self, obj, already_focused): |
1508 |
|
"""Get the speech for a terminal |
1509 |
|
|
1510 |
|
Arguments: |
1511 |
|
- obj: the terminal |
1512 |
|
- already_focused: False if object just received focus |
1513 |
|
|
1514 |
|
Returns a list of utterances to be spoken for the object. |
1515 |
|
""" |
1516 |
|
|
1517 |
0 |
title = None |
1518 |
0 |
frame = self._script.getFrame(obj) |
1519 |
0 |
if frame: |
1520 |
0 |
title = frame.name |
1521 |
0 |
if not title: |
1522 |
0 |
title = self._script.getDisplayedLabel(obj) |
1523 |
|
|
1524 |
0 |
utterances = [title] |
1525 |
|
|
1526 |
0 |
self._debugGenerator("_getSpeechForTerminal", |
1527 |
0 |
obj, |
1528 |
0 |
already_focused, |
1529 |
0 |
utterances) |
1530 |
|
|
1531 |
0 |
return utterances |
1532 |
|
|
1533 |
1 |
def _getSpeechForToggleButton(self, obj, already_focused): |
1534 |
|
"""Get the speech for a toggle button. If the toggle button already |
1535 |
|
had focus, then only the state is spoken. |
1536 |
|
|
1537 |
|
Arguments: |
1538 |
|
- obj: the check box |
1539 |
|
- already_focused: False if object just received focus |
1540 |
|
|
1541 |
|
Returns a list of utterances to be spoken for the object. |
1542 |
|
""" |
1543 |
|
|
1544 |
14 |
utterances = [] |
1545 |
14 |
if obj.state.count(atspi.Accessibility.STATE_CHECKED): |
1546 |
|
# Translators: the state of a toggle button. |
1547 |
|
# |
1548 |
7 |
checkedState = _("pressed") |
1549 |
|
else: |
1550 |
|
# Translators: the state of a toggle button. |
1551 |
|
# |
1552 |
7 |
checkedState = _("not pressed") |
1553 |
|
|
1554 |
|
# If it's not already focused, say it's name |
1555 |
|
# |
1556 |
14 |
if not already_focused: |
1557 |
5 |
label = self._getSpeechForObjectLabel(obj) |
1558 |
5 |
utterances.extend(label) |
1559 |
5 |
name = self._getSpeechForObjectName(obj) |
1560 |
5 |
if name != label: |
1561 |
3 |
utterances.extend(name) |
1562 |
5 |
utterances.extend(self._getSpeechForObjectRole(obj)) |
1563 |
5 |
utterances.append(checkedState) |
1564 |
5 |
utterances.extend(self._getSpeechForObjectAvailability(obj)) |
1565 |
|
else: |
1566 |
9 |
utterances.append(checkedState) |
1567 |
|
|
1568 |
14 |
self._debugGenerator("_getSpeechForToggleButton", |
1569 |
14 |
obj, |
1570 |
14 |
already_focused, |
1571 |
14 |
utterances) |
1572 |
|
|
1573 |
14 |
return utterances |
1574 |
|
|
1575 |
1 |
def _getSpeechForToolBar(self, obj, already_focused): |
1576 |
|
"""Get the speech for a tool bar |
1577 |
|
|
1578 |
|
Arguments: |
1579 |
|
- obj: the tool bar |
1580 |
|
- already_focused: False if object just received focus |
1581 |
|
|
1582 |
|
Returns a list of utterances to be spoken for the object. |
1583 |
|
""" |
1584 |
|
|
1585 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1586 |
|
|
1587 |
0 |
self._debugGenerator("_getSpeechForToolBar", |
1588 |
0 |
obj, |
1589 |
0 |
already_focused, |
1590 |
0 |
utterances) |
1591 |
|
|
1592 |
0 |
return utterances |
1593 |
|
|
1594 |
1 |
def _getSpeechForTree(self, obj, already_focused): |
1595 |
|
"""Get the speech for a tree |
1596 |
|
|
1597 |
|
Arguments: |
1598 |
|
- obj: the tree |
1599 |
|
- already_focused: False if object just received focus |
1600 |
|
|
1601 |
|
Returns a list of utterances to be spoken for the object. |
1602 |
|
""" |
1603 |
|
|
1604 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1605 |
|
|
1606 |
0 |
self._debugGenerator("_getSpeechForTree", |
1607 |
0 |
obj, |
1608 |
0 |
already_focused, |
1609 |
0 |
utterances) |
1610 |
|
|
1611 |
0 |
return utterances |
1612 |
|
|
1613 |
1 |
def _getSpeechForTreeTable(self, obj, already_focused): |
1614 |
|
"""Get the speech for a tree table |
1615 |
|
|
1616 |
|
Arguments: |
1617 |
|
- obj: the tree table |
1618 |
|
- already_focused: False if object just received focus |
1619 |
|
|
1620 |
|
Returns a list of utterances to be spoken for the object. |
1621 |
|
""" |
1622 |
|
|
1623 |
0 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1624 |
|
|
1625 |
0 |
self._debugGenerator("_getSpeechForTreeTable", |
1626 |
0 |
obj, |
1627 |
0 |
already_focused, |
1628 |
0 |
utterances) |
1629 |
|
|
1630 |
0 |
return utterances |
1631 |
|
|
1632 |
1 |
def _getSpeechForWindow(self, obj, already_focused): |
1633 |
|
"""Get the speech for a window |
1634 |
|
|
1635 |
|
Arguments: |
1636 |
|
- obj: the window |
1637 |
|
- already_focused: False if object just received focus |
1638 |
|
|
1639 |
|
Returns a list of utterances to be spoken for the object. |
1640 |
|
""" |
1641 |
|
|
1642 |
5 |
utterances = self._getDefaultSpeech(obj, already_focused) |
1643 |
|
|
1644 |
5 |
self._debugGenerator("_getSpeechForWindow", |
1645 |
5 |
obj, |
1646 |
5 |
already_focused, |
1647 |
5 |
utterances) |
1648 |
|
|
1649 |
5 |
return utterances |
1650 |
|
|
1651 |
1 |
def getSpeech(self, obj, already_focused): |
1652 |
|
"""Get the speech for an Accessible object. This will look |
1653 |
|
first to the specific speech generators and then to the |
1654 |
|
default speech generator. This method is the primary method |
1655 |
|
that external callers of this class should use. |
1656 |
|
|
1657 |
|
Arguments: |
1658 |
|
- obj: the object |
1659 |
|
- already_focused: False if object just received focus |
1660 |
|
|
1661 |
|
Returns a list of utterances to be spoken. |
1662 |
|
""" |
1663 |
|
|
1664 |
653 |
if self.speechGenerators.has_key(obj.role): |
1665 |
649 |
generator = self.speechGenerators[obj.role] |
1666 |
|
else: |
1667 |
4 |
generator = self._getDefaultSpeech |
1668 |
|
|
1669 |
653 |
return [" ".join(generator(obj, already_focused))] |
1670 |
|
|
1671 |
1 |
def getSpeechContext(self, obj, stopAncestor=None): |
1672 |
|
"""Get the speech that describes the names and role of |
1673 |
|
the container hierarchy of the object, stopping at and |
1674 |
|
not including the stopAncestor. |
1675 |
|
|
1676 |
|
Arguments: |
1677 |
|
- obj: the object |
1678 |
|
- stopAncestor: the anscestor to stop at and not include (None |
1679 |
|
means include all ancestors) |
1680 |
|
|
1681 |
|
Returns a list of utterances to be spoken. |
1682 |
|
""" |
1683 |
|
|
1684 |
418 |
utterances = [] |
1685 |
|
|
1686 |
418 |
if not obj: |
1687 |
0 |
return utterances |
1688 |
|
|
1689 |
418 |
if obj is stopAncestor: |
1690 |
13 |
return utterances |
1691 |
|
|
1692 |
405 |
parent = obj.parent |
1693 |
405 |
if parent \ |
1694 |
405 |
and (obj.role == rolenames.ROLE_TABLE_CELL) \ |
1695 |
132 |
and (parent.role == rolenames.ROLE_TABLE_CELL): |
1696 |
0 |
parent = parent.parent |
1697 |
|
|
1698 |
405 |
while parent and (parent.parent != parent): |
1699 |
1294 |
if parent == stopAncestor: |
1700 |
369 |
break |
1701 |
925 |
if not self._script.isLayoutOnly(parent): |
1702 |
795 |
text = self._script.getDisplayedLabel(parent) |
1703 |
795 |
if not text and parent.text: |
1704 |
82 |
text = self._script.getDisplayedText(parent) |
1705 |
795 |
if text and len(text.strip()): |
1706 |
|
# Push announcement of cell to the end |
1707 |
|
# |
1708 |
124 |
if not parent.role in [rolenames.ROLE_TABLE_CELL, |
1709 |
124 |
rolenames.ROLE_FILLER]: |
1710 |
120 |
utterances.append(\ |
1711 |
120 |
rolenames.getSpeechForRoleName(parent)) |
1712 |
124 |
utterances.append(text) |
1713 |
124 |
if parent.role == rolenames.ROLE_TABLE_CELL: |
1714 |
0 |
utterances.append(\ |
1715 |
0 |
rolenames.getSpeechForRoleName(parent)) |
1716 |
925 |
parent = parent.parent |
1717 |
|
|
1718 |
405 |
utterances.reverse() |
1719 |
|
|
1720 |
405 |
return utterances |