Coverage Report - orca.braillegenerator

ModuleCoverage %
orca.braillegenerator
74%
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 braille strings for objects.  In general,
21
there probably should be a singleton instance of the BrailleGenerator
22
class.  For those wishing to override the braille generators, however,
23
one can create a new instance and replace/extend the braille
24 1
generators as they see fit."""
25
26 1
__id__        = "$Id: braillegenerator.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 braille
36 1
import debug
37 1
import orca_state
38 1
import rolenames
39 1
import settings
40
41 1
from orca_i18n import _                     # for gettext support
42
43 2
class BrailleGenerator:
44
    """Takes accessible objects and produces a list of braille Regions
45
    for those objects.  See the getBrailleRegions method, which is the
46
    primary entry point.  Subclasses can feel free to override/extend
47 1
    the brailleGenerators instance field as they see fit."""
48
49 1
    SKIP_CONTEXT_ROLES = (rolenames.ROLE_MENU,
50 1
                          rolenames.ROLE_MENU_BAR,
51 1
                          rolenames.ROLE_PAGE_TAB_LIST,
52 1
                          rolenames.ROLE_COMBO_BOX)
53
54 1
    def __init__(self, script):
55
56
        # The script that created us.  This allows us to ask the
57
        # script for information if we need it.
58
        #
59 79
        self._script = script
60
61 79
        self.brailleGenerators = {}
62
        self.brailleGenerators[rolenames.ROLE_ALERT]               = \
63 79
             self._getBrailleRegionsForAlert
64
        self.brailleGenerators[rolenames.ROLE_ANIMATION]           = \
65 79
             self._getBrailleRegionsForAnimation
66
        self.brailleGenerators[rolenames.ROLE_ARROW]               = \
67 79
             self._getBrailleRegionsForArrow
68
        self.brailleGenerators[rolenames.ROLE_CHECK_BOX]           = \
69 79
             self._getBrailleRegionsForCheckBox
70
        self.brailleGenerators[rolenames.ROLE_CHECK_MENU]          = \
71 79
             self._getBrailleRegionsForCheckMenuItem
72
        self.brailleGenerators[rolenames.ROLE_CHECK_MENU_ITEM]     = \
73 79
             self._getBrailleRegionsForCheckMenuItem
74
        self.brailleGenerators[rolenames.ROLE_COLUMN_HEADER]       = \
75 79
             self._getBrailleRegionsForColumnHeader
76
        self.brailleGenerators[rolenames.ROLE_COMBO_BOX]           = \
77 79
             self._getBrailleRegionsForComboBox
78
        self.brailleGenerators[rolenames.ROLE_DESKTOP_ICON]        = \
79 79
             self._getBrailleRegionsForDesktopIcon
80
        self.brailleGenerators[rolenames.ROLE_DIAL]                = \
81 79
             self._getBrailleRegionsForDial
82
        self.brailleGenerators[rolenames.ROLE_DIALOG]              = \
83 79
             self._getBrailleRegionsForDialog
84
        self.brailleGenerators[rolenames.ROLE_DIRECTORY_PANE]      = \
85 79
             self._getBrailleRegionsForDirectoryPane
86
        self.brailleGenerators[rolenames.ROLE_FRAME]               = \
87 79
             self._getBrailleRegionsForFrame
88
        self.brailleGenerators[rolenames.ROLE_HTML_CONTAINER]      = \
89 79
             self._getBrailleRegionsForHtmlContainer
90
        self.brailleGenerators[rolenames.ROLE_ICON]                = \
91 79
             self._getBrailleRegionsForIcon
92
        self.brailleGenerators[rolenames.ROLE_IMAGE]               = \
93 79
             self._getBrailleRegionsForImage
94
        self.brailleGenerators[rolenames.ROLE_LABEL]               = \
95 79
             self._getBrailleRegionsForLabel
96
        self.brailleGenerators[rolenames.ROLE_LIST]                = \
97 79
             self._getBrailleRegionsForList
98
        self.brailleGenerators[rolenames.ROLE_LIST_ITEM]           = \
99 79
             self._getBrailleRegionsForListItem
100
        self.brailleGenerators[rolenames.ROLE_MENU]                = \
101 79
             self._getBrailleRegionsForMenu
102
        self.brailleGenerators[rolenames.ROLE_MENU_BAR]            = \
103 79
             self._getBrailleRegionsForMenuBar
104
        self.brailleGenerators[rolenames.ROLE_MENU_ITEM]           = \
105 79
             self._getBrailleRegionsForMenuItem
106
        self.brailleGenerators[rolenames.ROLE_OPTION_PANE]         = \
107 79
             self._getBrailleRegionsForOptionPane
108
        self.brailleGenerators[rolenames.ROLE_PAGE_TAB]            = \
109 79
             self._getBrailleRegionsForPageTab
110
        self.brailleGenerators[rolenames.ROLE_PAGE_TAB_LIST]       = \
111 79
             self._getBrailleRegionsForPageTabList
112
        self.brailleGenerators[rolenames.ROLE_PARAGRAPH]           = \
113 79
             self._getBrailleRegionsForText
114
        self.brailleGenerators[rolenames.ROLE_PASSWORD_TEXT]       = \
115 79
             self._getBrailleRegionsForText
116
        self.brailleGenerators[rolenames.ROLE_PROGRESS_BAR]        = \
117 79
             self._getBrailleRegionsForProgressBar
118
        self.brailleGenerators[rolenames.ROLE_PUSH_BUTTON]         = \
119 79
             self._getBrailleRegionsForPushButton
120
        self.brailleGenerators[rolenames.ROLE_RADIO_BUTTON]        = \
121 79
             self._getBrailleRegionsForRadioButton
122
        self.brailleGenerators[rolenames.ROLE_RADIO_MENU]          = \
123 79
             self._getBrailleRegionsForRadioMenuItem
124
        self.brailleGenerators[rolenames.ROLE_RADIO_MENU_ITEM]     = \
125 79
             self._getBrailleRegionsForRadioMenuItem
126
        self.brailleGenerators[rolenames.ROLE_ROW_HEADER]          = \
127 79
             self._getBrailleRegionsForRowHeader
128
        self.brailleGenerators[rolenames.ROLE_SCROLL_BAR]          = \
129 79
             self._getBrailleRegionsForScrollBar
130
        self.brailleGenerators[rolenames.ROLE_SLIDER]              = \
131 79
             self._getBrailleRegionsForSlider
132
        self.brailleGenerators[rolenames.ROLE_SPIN_BUTTON]         = \
133 79
             self._getBrailleRegionsForSpinButton
134
        self.brailleGenerators[rolenames.ROLE_SPLIT_PANE]          = \
135 79
             self._getBrailleRegionsForSplitPane
136
        self.brailleGenerators[rolenames.ROLE_TABLE]               = \
137 79
             self._getBrailleRegionsForTable
138
        self.brailleGenerators[rolenames.ROLE_TABLE_CELL]          = \
139 79
             self._getBrailleRegionsForTableCellRow
140
        self.brailleGenerators[rolenames.ROLE_TABLE_COLUMN_HEADER] = \
141 79
             self._getBrailleRegionsForTableColumnHeader
142
        self.brailleGenerators[rolenames.ROLE_TABLE_ROW_HEADER]    = \
143 79
             self._getBrailleRegionsForTableRowHeader
144
        self.brailleGenerators[rolenames.ROLE_TEAR_OFF_MENU_ITEM]  = \
145 79
             self._getBrailleRegionsForMenu
146
        self.brailleGenerators[rolenames.ROLE_TERMINAL]            = \
147 79
             self._getBrailleRegionsForTerminal
148
        self.brailleGenerators[rolenames.ROLE_TEXT]                = \
149 79
             self._getBrailleRegionsForText
150
        self.brailleGenerators[rolenames.ROLE_TOGGLE_BUTTON]       = \
151 79
             self._getBrailleRegionsForToggleButton
152
        self.brailleGenerators[rolenames.ROLE_TOOL_BAR]            = \
153 79
             self._getBrailleRegionsForToolBar
154
        self.brailleGenerators[rolenames.ROLE_TREE]                = \
155 79
             self._getBrailleRegionsForTable
156
        self.brailleGenerators[rolenames.ROLE_TREE_TABLE]          = \
157 79
             self._getBrailleRegionsForTable
158
        self.brailleGenerators[rolenames.ROLE_WINDOW]              = \
159 79
             self._getBrailleRegionsForWindow
160
161 1
    def _getTextForAccelerator(self, obj):
162
        """Returns a string to be displayed that describes the keyboard
163
        accelerator (and possibly shortcut) for the given object.
164
165
        Arguments:
166
        - obj: the Accessible object
167
168
        Returns a string to be displayed.
169
        """
170
171 60
        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
172 60
            text = ""
173
174 60
            result = self._script.getAcceleratorAndShortcut(obj)
175
176 60
            accelerator = result[0]
177
            #shortcut = result[1]
178
179 60
            if len(accelerator) > 0:
180 23
                text += "(" + accelerator + ")"
181
182
            # [[[TODO: WDW - various stuff preserved while we work out the
183
            # desired verbosity here.]]]
184
            #
185
            #if len(shortcut) > 0:
186
            #    text += "(" + shortcut + ")"
187
188 60
            return text
189
        else:
190 0
            return None
191
192 1
    def _getTextForAvailability(self, obj):
193
        """Returns a string to be displayed that describes the availability
194
        of the given object.
195
196
        Arguments:
197
        - obj: the Accessible object
198
199
        Returns a string to be displayed.
200
        """
201
202 60
        if obj.state.count(atspi.Accessibility.STATE_SENSITIVE) == 0:
203
            # Translators: this represents an item on the screen that has
204
            # been set insensitive (or grayed out).
205
            #
206 0
            return _("grayed")
207
        else:
208 60
            return None
209
210 1
    def _getTextForValue(self, obj):
211
        """Returns the text to be displayed for the object's current value.
212
213
        Arguments:
214
        - obj: the Accessible object that may or may not have a value.
215
216
        Returns a string representing the value.
217
        """
218
219 4979
        value = obj.value
220
221 4979
        if not value:
222 4967
            return ""
223
224
        # OK, this craziness is all about trying to figure out the most
225
        # meaningful formatting string for the floating point values.
226
        # The number of places to the right of the decimal point should
227
        # be set by the minimumIncrement, but the minimumIncrement isn't
228
        # always set.  So...we'll default the minimumIncrement to 1/100
229
        # of the range.  But, if max == min, then we'll just go for showing
230
        # them off to two meaningful digits.
231
        #
232 12
        try:
233 12
            minimumIncrement = value.minimumIncrement
234 0
        except:
235 0
            minimumIncrement = 0.0
236
237 12
        if minimumIncrement == 0.0:
238 12
            minimumIncrement = (value.maximumValue - value.minimumValue) \
239 12
                               / 100.0
240
241 12
        try:
242 12
            decimalPlaces = max(0, -math.log10(minimumIncrement))
243 0
        except:
244 0
            try:
245 0
                decimalPlaces = max(0, -math.log10(value.minimumValue))
246 0
            except:
247 0
                try:
248 0
                    decimalPlaces = max(0, -math.log10(value.maximumValue))
249 0
                except:
250 0
                    decimalPlaces = 0
251
252 12
        formatter = "%%.%df" % decimalPlaces
253 12
        valueString = formatter % value.currentValue
254
        #minString   = formatter % value.minimumValue
255
        #maxString   = formatter % value.maximumValue
256
257
        # [[[TODO: WDW - probably want to do this as a percentage at some
258
        # point?  Logged as bugzilla bug 319743.]]]
259
        #
260 12
        return valueString
261
262 1
    def _getTextForRole(self, obj):
263 5211
        if (settings.brailleVerbosityLevel \
264 5211
            == settings.VERBOSITY_LEVEL_VERBOSE)\
265 4117
           and (obj.role != rolenames.ROLE_UNKNOWN):
266 4115
            return rolenames.getBrailleForRoleName(obj)
267
        else:
268 1096
            return None
269
270 1
    def _debugGenerator(self, generatorName, obj):
271
        """Prints debug.LEVEL_FINER information regarding the braille
272
        generator.
273
274
        Arguments:
275
        - generatorName: the name of the generator
276
        - obj: the object being presented
277
        """
278
279 9787
        debug.println(debug.LEVEL_FINER,
280 9787
                      "GENERATOR: %s" % generatorName)
281 9787
        debug.println(debug.LEVEL_FINER,
282 9787
                      "           obj             = %s" % obj.name)
283 9787
        debug.println(debug.LEVEL_FINER,
284 9787
                      "           role            = %s" % obj.role)
285
286 1
    def _getDefaultBrailleRegions(self, obj):
287
        """Gets text to be displayed for the current object's name,
288
        role, and any accelerators.  This is usually the fallback
289
        braille generator should no other specialized braille
290
        generator exist for this object.
291
292
        Arguments:
293
        - obj: an Accessible
294
295
        Returns a list where the first element is a list of Regions to
296
        display and the second element is the Region which should get
297
        focus.
298
        """
299
300 4979
        self._debugGenerator("_getDefaultBrailleRegions", obj)
301
302 4979
        regions = []
303
304 4979
        text = ""
305 4979
        text = self._script.appendString(
306 4979
            text, self._script.getDisplayedLabel(obj))
307 4979
        text = self._script.appendString(
308 4979
            text, self._script.getDisplayedText(obj))
309 4979
        text = self._script.appendString(text, self._getTextForValue(obj))
310 4979
        text = self._script.appendString(text, self._getTextForRole(obj))
311
312 4979
        regions = []
313 4979
        componentRegion = braille.Component(obj, text)
314 4979
        regions.append(componentRegion)
315
316 4979
        return [regions, componentRegion]
317
318 1
    def _getBrailleRegionsForAlert(self, obj):
319
        """Gets the title of the dialog and the contents of labels inside the
320
        dialog that are not associated with any other objects.
321
322
        Arguments:
323
        - obj: the Accessible dialog
324
325
        Returns a list where the first element is a list of Regions to display
326
        and the second element is the Region which should get focus.
327
        """
328
329 93
        self._debugGenerator("_getBrailleRegionsForAlert", obj)
330 93
        return self._getDefaultBrailleRegions(obj)
331
332 1
    def _getBrailleRegionsForAnimation(self, obj):
333
        """Gets the title of the dialog and the contents of labels inside the
334
        dialog that are not associated with any other objects.
335
336
        Arguments:
337
        - obj: the Accessible dialog
338
339
        Returns a list where the first element is a list of Regions to display
340
        and the second element is the Region which should get focus.
341
        """
342
343 0
        self._debugGenerator("_getBrailleRegionsForAnimation", obj)
344
345 0
        text = ""
346 0
        text = self._script.appendString(
347 0
            text, self._script.getDisplayedLabel(obj))
348 0
        text = self._script.appendString(
349 0
            text, self._script.getDisplayedText(obj))
350 0
        text = self._script.appendString(text, self._getTextForRole(obj))
351 0
        text = self._script.appendString(text, obj.description, ": ")
352
353 0
        regions = []
354 0
        componentRegion = braille.Component(obj, text)
355 0
        regions.append(componentRegion)
356
357 0
        return [regions, componentRegion]
358
359 1
    def _getBrailleRegionsForArrow(self, obj):
360
        """Gets text to be displayed for an arrow.
361
362
        Arguments:
363
        - obj: the arrow
364
365
        Returns a list where the first element is a list of Regions to display
366
        and the second element is the Region which should get focus.
367
        """
368
369 0
        self._debugGenerator("_getBrailleRegionsForArrow", obj)
370
371
        # [[[TODO: determine orientation of arrow. Logged as bugzilla bug
372
        # 319744.]]]
373
        # text = arrow direction (left, right, up, down)
374
        #
375 0
        return self._getDefaultBrailleRegions(obj)
376
377 1
    def _getBrailleRegionsForCheckBox(self, obj):
378
        """Get the braille for a check box.  If the check box already had
379
        focus, then only the state is displayed.
380
381
        Arguments:
382
        - obj: the check box
383
384
        Returns a list where the first element is a list of Regions to display
385
        and the second element is the Region which should get focus.
386
        """
387
388 65
        self._debugGenerator("_getBrailleRegionsForCheckBox", obj)
389
390 65
        text = ""
391
392 65
        text = self._script.appendString(
393 65
            text,
394 65
            settings.brailleCheckBoxIndicators[
395 65
                obj.state.count(atspi.Accessibility.STATE_CHECKED)])
396
397 65
        text = self._script.appendString(
398 65
            text, self._script.getDisplayedLabel(obj))
399 65
        text = self._script.appendString(
400 65
            text, self._script.getDisplayedText(obj))
401
402 65
        text = self._script.appendString(text, self._getTextForRole(obj))
403
404 65
        regions = []
405 65
        componentRegion = braille.Component(obj, text)
406 65
        regions.append(componentRegion)
407
408 65
        return [regions, componentRegion]
409
410 1
    def _getBrailleRegionsForCheckMenuItem(self, obj):
411
        """Get the braille for a check menu item.  If the check menu item
412
        already had focus, then only the state is displayed.
413
414
        Arguments:
415
        - obj: the check menu item
416
417
        Returns a list where the first element is a list of Regions to display
418
        and the second element is the Region which should get focus.
419
        """
420
421 12
        self._debugGenerator("_getBrailleRegionsForCheckMenuItem", obj)
422
423 12
        text = ""
424
425 12
        text = self._script.appendString(
426 12
            text,
427 12
            settings.brailleCheckBoxIndicators[
428 12
                obj.state.count(atspi.Accessibility.STATE_CHECKED)])
429
430 12
        text = self._script.appendString(
431 12
            text, self._script.getDisplayedLabel(obj))
432 12
        text = self._script.appendString(
433 12
            text, self._script.getDisplayedText(obj))
434
435 12
        if obj == orca_state.locusOfFocus:
436 12
            text = self._script.appendString(text, self._getTextForRole(obj))
437 12
            text = self._script.appendString(
438 12
                text, self._getTextForAvailability(obj))
439 12
            text = self._script.appendString(text,
440 12
                                      self._getTextForAccelerator(obj),
441 12
                                      "")
442
443 12
        regions = []
444 12
        componentRegion = braille.Component(obj, text)
445 12
        regions.append(componentRegion)
446
447 12
        return [regions, componentRegion]
448
449 1
    def _getBrailleRegionsForColumnHeader(self, obj):
450
        """Get the braille for a column header.
451
452
        Arguments:
453
        - obj: the column header
454
455
        Returns a list where the first element is a list of Regions to display
456
        and the second element is the Region which should get focus.
457
        """
458
459 5
        self._debugGenerator("_getBrailleRegionsForColumnHeader", obj)
460
461 5
        return self._getDefaultBrailleRegions(obj)
462
463 1
    def _getBrailleRegionsForComboBox(self, obj):
464
        """Get the braille for a combo box.  If the combo box already has
465
        focus, then only the selection is displayed.
466
467
        Arguments:
468
        - obj: the combo box
469
470
        Returns a list where the first element is a list of Regions to display
471
        and the second element is the Region which should get focus.
472
        """
473
474 48
        self._debugGenerator("_getBrailleRegionsForComboBox", obj)
475
476 48
        regions = []
477
478 48
        focusedRegionIndex = 0
479 48
        label = self._script.getDisplayedLabel(obj)
480 48
        if label and (len(label) > 0):
481 11
            regions.append(braille.Region(label + " "))
482 11
            focusedRegionIndex = 1
483
484 48
        displayedText = self._script.getDisplayedText(obj)
485 48
        if displayedText:
486 48
            regions.append(braille.Region(displayedText))
487
488 48
        regions.append(braille.Region(
489 48
            " " + rolenames.getBrailleForRoleName(obj)))
490
491
        # Things may not have gone as expected above, so we'll do some
492
        # defensive programming to make sure we don't get an index out
493
        # of bounds.
494
        #
495 48
        if focusedRegionIndex >= len(regions):
496 0
            focusedRegionIndex = 0
497 48
        if len(regions) == 0:
498 0
            focusedRegion = None
499
        else:
500 48
            focusedRegion = regions[focusedRegionIndex]
501
502
        # [[[TODO: WDW - perhaps if a text area was created, we should
503
        # give focus to it.]]]
504
        #
505 48
        return [regions, focusedRegion]
506
507 1
    def _getBrailleRegionsForDesktopIcon(self, obj):
508
        """Get the braille for a desktop icon.
509
510
        Arguments:
511
        - obj: the desktop icon
512
513
        Returns a list where the first element is a list of Regions to display
514
        and the second element is the Region which should get focus.
515
        """
516
517 0
        self._debugGenerator("_getBrailleRegionsForDesktopIcon", obj)
518
519 0
        return self._getDefaultBrailleRegions(obj)
520
521 1
    def _getBrailleRegionsForDial(self, obj):
522
        """Get the braille for a dial.
523
524
        Arguments:
525
        - obj: the dial
526
527
        Returns a list where the first element is a list of Regions to display
528
        and the second element is the Region which should get focus.
529
        """
530
531
        # [[[TODO: WDW - might need to include the value here?  Logged as
532
        # bugzilla bug 319746.]]]
533
        #
534 0
        self._debugGenerator("_getBrailleRegionsForDial", obj)
535
536 0
        return self._getDefaultBrailleRegions(obj)
537
538 1
    def _getBrailleRegionsForDialog(self, obj):
539
        """Get the braille for a dialog box.
540
541
        Arguments:
542
        - obj: the dialog box
543
544
        Returns a list where the first element is a list of Regions to display
545
        and the second element is the Region which should get focus.
546
        """
547
548 73
        self._debugGenerator("_getBrailleRegionsForDialog", obj)
549
550 73
        return self._getBrailleRegionsForAlert(obj)
551
552 1
    def _getBrailleRegionsForDirectoryPane(self, obj):
553
        """Get the braille for a directory pane.
554
555
        Arguments:
556
        - obj: the dial
557
558
        Returns a list where the first element is a list of Regions to display
559
        and the second element is the Region which should get focus.
560
        """
561
562 0
        self._debugGenerator("_getBrailleRegionsForDirectoryPane", obj)
563
564 0
        return self._getDefaultBrailleRegions(obj)
565
566 1
    def _getBrailleRegionsForFrame(self, obj):
567
        """Get the braille for a frame.
568
569
        Arguments:
570
        - obj: the frame
571
572
        Returns a list where the first element is a list of Regions to display
573
        and the second element is the Region which should get focus.
574
        """
575
576 863
        self._debugGenerator("_getBrailleRegionsForFrame", obj)
577
578 863
        return self._getDefaultBrailleRegions(obj)
579
580 1
    def _getBrailleRegionsForHtmlContainer(self, obj):
581
        """Get the braille for an HTML container.
582
583
        Arguments:
584
        - obj: the dial
585
586
        Returns a list where the first element is a list of Regions to display
587
        and the second element is the Region which should get focus.
588
        """
589
590 0
        self._debugGenerator("_getBrailleRegionsForHtmlContainer", obj)
591
592 0
        return self._getDefaultBrailleRegions(obj)
593
594 1
    def _getBrailleRegionsForIcon(self, obj):
595
        """Get the braille for an icon.
596
597
        Arguments:
598
        - obj: the icon
599
600
        Returns a list where the first element is a list of Regions to display
601
        and the second element is the Region which should get focus.
602
        """
603
604 17
        self._debugGenerator("_getBrailleRegionsForIcon", obj)
605
606 17
        text = ""
607 17
        text = self._script.appendString(
608 17
            text, self._script.getDisplayedLabel(obj))
609 17
        text = self._script.appendString(
610 17
            text, self._script.getDisplayedText(obj))
611
612 17
        if obj.image:
613 17
            description = obj.image.imageDescription
614 17
            if len(description):
615 0
                text = self._script.appendString(text, description)
616
617 17
        text = self._script.appendString(text, self._getTextForRole(obj))
618
619 17
        regions = []
620 17
        componentRegion = braille.Component(obj, text)
621 17
        regions.append(componentRegion)
622
623 17
        return [regions, componentRegion]
624
625 1
    def _getBrailleRegionsForImage(self, obj):
626
        """Get the braille for an image.
627
628
        Arguments:
629
        - obj: the image
630
631
        Returns a list where the first element is a list of Regions to display
632
        and the second element is the Region which should get focus.
633
        """
634
635 0
        self._debugGenerator("_getBrailleRegionsForImage", obj)
636
637 0
        return self._getDefaultBrailleRegions(obj)
638
639 1
    def _getBrailleRegionsForLabel(self, obj):
640
        """Get the braille for a label.
641
642
        Arguments:
643
        - obj: the label
644
645
        Returns a list where the first element is a list of Regions to display
646
        and the second element is the Region which should get focus.
647
        """
648
649 12
        self._debugGenerator("_getBrailleRegionsForLabel", obj)
650
651 12
        return self._getDefaultBrailleRegions(obj)
652
653 1
    def _getBrailleRegionsForList(self, obj):
654
        """Get the braille for a list.
655
656
        Arguments:
657
        - obj: the list
658
659
        Returns a list where the first element is a list of Regions to display
660
        and the second element is the Region which should get focus.
661
        """
662
663
        # [[[TODO: WDW - include how many items in the list?
664
        # Perhaps should also include current list item in here?
665
        # Logged as bugzilla bug 319749.]]]
666
        #
667 0
        self._debugGenerator("_getBrailleRegionsForList", obj)
668
669 0
        return self._getDefaultBrailleRegions(obj)
670
671 1
    def _getBrailleRegionsForListItem(self, obj):
672
        """Get the braille for a listitem.
673
674
        Arguments:
675
        - obj: the listitem
676
677
        """
678
679 0
        self._debugGenerator("_getBrailleRegionsForListItem", obj)
680
681 0
        text = ""
682 0
        text = self._script.appendString(
683 0
            text, self._script.getDisplayedLabel(obj))
684 0
        text = self._script.appendString(
685 0
            text, self._script.getDisplayedText(obj))
686
687 0
        if obj.state.count(atspi.Accessibility.STATE_EXPANDABLE):
688 0
            if obj.state.count(atspi.Accessibility.STATE_EXPANDED):
689
                # Translators: this represents the state of a node in a tree.
690
                # 'expanded' means the children are showing.
691
                # 'collapsed' means the children are not showing.
692
                #
693 0
                text = self._script.appendString(text, _('expanded'))
694
            else:
695
                # Translators: this represents the state of a node in a tree.
696
                # 'expanded' means the children are showing.
697
                # 'collapsed' means the children are not showing.
698
                #
699 0
                text = self._script.appendString(text, _('collapsed'))
700
701 0
        if obj == orca_state.locusOfFocus:
702 0
            text = self._script.appendString(
703 0
                text, self._getTextForRole(obj))
704 0
            text = self._script.appendString(
705 0
                text, self._getTextForAvailability(obj))
706 0
            text = self._script.appendString(
707 0
                text, self._getTextForAccelerator(obj), "")
708
709 0
        level = self._script.getNodeLevel(obj)
710 0
        if level >= 0:
711
            # Translators: this represents the depth of a node in a tree
712
            # view (i.e., how many ancestors a node has).
713
            #
714 0
            text = self._script.appendString(text, _("LEVEL %d") \
715 0
                                             % (level + 1))
716
717 0
        regions = []
718 0
        componentRegion = braille.Component(obj, text)
719 0
        regions.append(componentRegion)
720
721 0
        return [regions, componentRegion]
722
723 1
    def _getBrailleRegionsForMenu(self, obj):
724
        """Get the braille for a menu.
725
726
        Arguments:
727
        - obj: the menu
728
729
        Returns a list where the first element is a list of Regions to display
730
        and the second element is the Region which should get focus.
731
        """
732
733 14
        self._debugGenerator("_getBrailleRegionsForMenu", obj)
734
735 14
        text = ""
736 14
        text = self._script.appendString(
737 14
            text, self._script.getDisplayedLabel(obj))
738 14
        text = self._script.appendString(
739 14
            text, self._script.getDisplayedText(obj))
740 14
        text = self._script.appendString(
741 14
            text, rolenames.getBrailleForRoleName(obj))
742
743 14
        if obj == orca_state.locusOfFocus:
744 8
            text = self._script.appendString(
745 8
                text, self._getTextForAvailability(obj))
746 8
            text = self._script.appendString(text,
747 8
                                      self._getTextForAccelerator(obj),
748 8
                                      "")
749
750 14
        regions = []
751 14
        componentRegion = braille.Component(obj, text)
752 14
        regions.append(componentRegion)
753
754 14
        return [regions, componentRegion]
755
756 1
    def _getBrailleRegionsForMenuBar(self, obj):
757
        """Get the braille for a menu bar.
758
759
        Arguments:
760
        - obj: the menu bar
761
762
        Returns a list where the first element is a list of Regions to display
763
        and the second element is the Region which should get focus.
764
        """
765
766 32
        self._debugGenerator("_getBrailleRegionsForMenuBar", obj)
767
768 32
        return self._getDefaultBrailleRegions(obj)
769
770 1
    def _getBrailleRegionsForMenuItem(self, obj):
771
        """Get the braille for a menu item.
772
773
        Arguments:
774
        - obj: the menu item
775
776
        Returns a list where the first element is a list of Regions to display
777
        and the second element is the Region which should get focus.
778
        """
779
780 21
        self._debugGenerator("_getBrailleRegionsForMenuItem", obj)
781
782 21
        text = ""
783
784
        # OpenOffice check menu items currently have a role of "menu item"
785
        # rather then "check menu item", so we need to test if one of the
786
        # states is CHECKED. If it is, then add that in to the braille
787
        # display output. Note that we can't tell if this is a "check
788
        # menu item" that is currently unchecked and braille that state.
789
        # See Orca bug #433398 for more details.
790
        #
791 21
        if obj.state.count(atspi.Accessibility.STATE_CHECKED):
792 0
            text = self._script.appendString(
793 0
                text,
794 0
                settings.brailleCheckBoxIndicators[1])
795
796 21
        text = self._script.appendString(
797 21
            text, self._script.getDisplayedLabel(obj))
798 21
        text = self._script.appendString(
799 21
            text, self._script.getDisplayedText(obj))
800
801 21
        if obj == orca_state.locusOfFocus:
802 21
            text = self._script.appendString(
803 21
                text, self._getTextForAvailability(obj))
804 21
            text = self._script.appendString(text,
805 21
                                      self._getTextForAccelerator(obj),
806 21
                                      "")
807
808 21
        regions = []
809 21
        componentRegion = braille.Component(obj, text)
810 21
        regions.append(componentRegion)
811
812 21
        return [regions, componentRegion]
813
814 1
    def _getBrailleRegionsForText(self, obj):
815
        """Get the braille for a text component.
816
817
        Arguments:
818
        - obj: the text component
819
820
        Returns a list where the first element is a list of Regions to display
821
        and the second element is the Region which should get focus.
822
        """
823
824 1320
        self._debugGenerator("_getBrailleRegionsForText", obj)
825
826 1320
        regions = []
827
828 1320
        textRegion = braille.Text(obj,
829 1320
                                  self._script.getDisplayedLabel(obj),
830 1320
                                  " $l")
831 1320
        regions.append(textRegion)
832
833
        # We do not want the role at the end of text areas.
834
835 1320
        return [regions, textRegion]
836
837 1
    def _getBrailleRegionsForOptionPane(self, obj):
838
        """Get the braille for an option pane.
839
840
        Arguments:
841
        - obj: the option pane
842
843
        Returns a list where the first element is a list of Regions to display
844
        and the second element is the Region which should get focus.
845
        """
846
847 0
        self._debugGenerator("_getBrailleRegionsForOptionPane", obj)
848
849 0
        return self._getDefaultBrailleRegions(obj)
850
851 1
    def _getBrailleRegionsForPageTab(self, obj):
852
        """Get the braille for a page tab.
853
854
        Arguments:
855
        - obj: the page tab
856
857
        Returns a list where the first element is a list of Regions to display
858
        and the second element is the Region which should get focus.
859
        """
860
861 200
        self._debugGenerator("_getBrailleRegionsForPageTab", obj)
862
863 200
        text = ""
864 200
        text = self._script.appendString(
865 200
            text, self._script.getDisplayedLabel(obj))
866 200
        text = self._script.appendString(
867 200
            text, self._script.getDisplayedText(obj))
868
869 200
        if obj == orca_state.locusOfFocus:
870 18
            text = self._script.appendString(
871 18
                text, self._getTextForAvailability(obj))
872 18
            text = self._script.appendString(text,
873 18
                                      self._getTextForAccelerator(obj),
874 18
                                      "")
875
876 200
        regions = []
877 200
        componentRegion = braille.Component(obj, text)
878 200
        regions.append(componentRegion)
879
880 200
        return [regions, componentRegion]
881
882 1
    def _getBrailleRegionsForPageTabList(self, obj):
883
        """Get the braille for a page tab list.
884
885
        Arguments:
886
        - obj: the page tab list
887
888
        Returns a list where the first element is a list of Regions to display
889
        and the second element is the Region which should get focus.
890
        """
891
892 182
        self._debugGenerator("_getBrailleRegionsForPageTabList", obj)
893
894 182
        return self._getDefaultBrailleRegions(obj)
895
896 1
    def _getBrailleRegionsForProgressBar(self, obj):
897
        """Get the braille for a progress bar.  If the object already
898
        had focus, just the new value is displayed.
899
900
        Arguments:
901
        - obj: the progress bar
902
903
        Returns a list where the first element is a list of Regions to display
904
        and the second element is the Region which should get focus.
905
        """
906
907 0
        self._debugGenerator("_getBrailleRegionsForProgressBar", obj)
908
909 0
        return self._getDefaultBrailleRegions(obj)
910
911 1
    def _getBrailleRegionsForPushButton(self, obj):
912
        """Get the braille for a push button
913
914
        Arguments:
915
        - obj: the push button
916
917
        Returns a list where the first element is a list of Regions to display
918
        and the second element is the Region which should get focus.
919
        """
920
921 108
        self._debugGenerator("_getBrailleRegionsForPushButton", obj)
922
923 108
        regions = []
924
925 108
        text = ""
926 108
        text = self._script.appendString(
927 108
            text, self._script.getDisplayedLabel(obj))
928 108
        text = self._script.appendString(
929 108
            text, self._script.getDisplayedText(obj))
930
931
        # In Java, some push buttons don't have label and text.
932
        # In this case, we'll add to presentation the object description,
933
        # if exists.
934
        #
935 108
        if (not text) and (obj.description):
936 0
            text = self._script.appendString(text, obj.description)
937
938 108
        text = self._script.appendString(text, self._getTextForRole(obj))
939
940 108
        regions = []
941 108
        componentRegion = braille.Component(obj, text)
942 108
        regions.append(componentRegion)
943
944 108
        return [regions, componentRegion]
945
946 1
    def _getBrailleRegionsForRadioButton(self, obj):
947
        """Get the braille for a radio button.  If the button already had
948
        focus, then only the state is displayed.
949
950
        Arguments:
951
        - obj: the check box
952
953
        Returns a list where the first element is a list of Regions to display
954
        and the second element is the Region which should get focus.
955
        """
956
957 29
        self._debugGenerator("_getBrailleRegionsForRadioButton", obj)
958
959 29
        text = ""
960
961 29
        text = self._script.appendString(
962 29
            settings.brailleRadioButtonIndicators[
963 29
                obj.state.count(atspi.Accessibility.STATE_CHECKED)],
964 29
            text)
965
966 29
        text = self._script.appendString(
967 29
            text, self._script.getDisplayedLabel(obj))
968 29
        text = self._script.appendString(
969 29
            text, self._script.getDisplayedText(obj))
970
971
        # In Java, some toggle buttons don't have label and text.
972
        # In this case, we'll add to presentation the object description,
973
        # if exists.
974
        #
975 29
        if (not text) and (obj.description):
976 0
            text = self._script.appendString(text, obj.description)
977
978 29
        text = self._script.appendString(text, self._getTextForRole(obj))
979
980 29
        regions = []
981 29
        componentRegion = braille.Component(obj, text)
982 29
        regions.append(componentRegion)
983
984 29
        return [regions, componentRegion]
985
986 1
    def _getBrailleRegionsForRadioMenuItem(self, obj):
987
        """Get the braille for a radio menu item.  If the menu item
988
        already had focus, then only the state is displayed.
989
990
        Arguments:
991
        - obj: the check menu item
992
993
        Returns a list where the first element is a list of Regions to display
994
        and the second element is the Region which should get focus.
995
        """
996
997 1
        self._debugGenerator("_getBrailleRegionsForRadioMenuItem", obj)
998
999 1
        text = ""
1000
1001 1
        text = self._script.appendString(
1002 1
            settings.brailleRadioButtonIndicators[
1003 1
                obj.state.count(atspi.Accessibility.STATE_CHECKED)],
1004 1
            text)
1005
1006 1
        text = self._script.appendString(
1007 1
            text, self._script.getDisplayedLabel(obj))
1008 1
        text = self._script.appendString(
1009 1
            text, self._script.getDisplayedText(obj))
1010
1011 1
        if obj == orca_state.locusOfFocus:
1012 1
            text = self._script.appendString(text, self._getTextForRole(obj))
1013 1
            text = self._script.appendString(
1014 1
                text, self._getTextForAvailability(obj))
1015 1
            text = self._script.appendString(text,
1016 1
                                      self._getTextForAccelerator(obj),
1017 1
                                      "")
1018
1019 1
        regions = []
1020 1
        componentRegion = braille.Component(obj, text)
1021 1
        regions.append(componentRegion)
1022
1023 1
        return [regions, componentRegion]
1024
1025 1
    def _getBrailleRegionsForRowHeader(self, obj):
1026
        """Get the braille for a row header.
1027
1028
        Arguments:
1029
        - obj: the column header
1030
1031
        Returns a list where the first element is a list of Regions to display
1032
        and the second element is the Region which should get focus.
1033
        """
1034
1035 0
        self._debugGenerator("_getBrailleRegionsForRowHeader", obj)
1036
1037 0
        return self._getDefaultBrailleRegions(obj)
1038
1039 1
    def _getBrailleRegionsForScrollBar(self, obj):
1040
        """Get the braille for a scroll bar.
1041
1042
        Arguments:
1043
        - obj: the scroll bar
1044
1045
        Returns a list where the first element is a list of Regions to display
1046
        and the second element is the Region which should get focus.
1047
        """
1048
1049
        # [[[TODO: WDW - want to get orientation.  Logged as bugzilla bug
1050
        # 319744.]]]
1051
        #
1052 0
        self._debugGenerator("_getBrailleRegionsForScrollBar", obj)
1053
1054 0
        return self._getDefaultBrailleRegions(obj)
1055
1056 1
    def _getBrailleRegionsForSlider(self, obj):
1057
        """Get the braille for a slider.  If the object already
1058
        had focus, just the value is displayed.
1059
1060
        Arguments:
1061
        - obj: the slider
1062
1063
        Returns a list where the first element is a list of Regions to display
1064
        and the second element is the Region which should get focus.
1065
        """
1066
1067 0
        self._debugGenerator("_getBrailleRegionsForSlider", obj)
1068
1069 0
        regions = []
1070
1071 0
        text = ""
1072 0
        text = self._script.appendString(
1073 0
            text, self._script.getDisplayedLabel(obj))
1074
        # Ignore the text on the slider.
1075
        #text = self._script.appendString(
1076
        #    text, self._script.getDisplayedText(obj))
1077 0
        text = self._script.appendString(text, self._getTextForValue(obj))
1078 0
        text = self._script.appendString(text, self._getTextForRole(obj))
1079
1080 0
        regions = []
1081 0
        componentRegion = braille.Component(obj, text)
1082 0
        regions.append(componentRegion)
1083
1084 0
        return [regions, componentRegion]
1085
1086 1
    def _getBrailleRegionsForSpinButton(self, obj):
1087
        """Get the braille for a spin button.  If the object already has
1088
        focus, then only the new value is displayed.
1089
1090
        Arguments:
1091
        - obj: the spin button
1092
1093
        Returns a list where the first element is a list of Regions to display
1094
        and the second element is the Region which should get focus.
1095
        """
1096
1097 88
        self._debugGenerator("_getBrailleRegionsForSpinButton", obj)
1098
1099 88
        return self._getBrailleRegionsForText(obj)
1100
1101 1
    def _getBrailleRegionsForSplitPane(self, obj):
1102
        """Get the braille for a split pane.
1103
1104
        Arguments:
1105
        - obj: the split pane
1106
1107
        Returns a list where the first element is a list of Regions to display
1108
        and the second element is the Region which should get focus.
1109
        """
1110
1111 12
        self._debugGenerator("_getBrailleRegionsForSplitPane", obj)
1112
1113 12
        return self._getDefaultBrailleRegions(obj)
1114
1115 1
    def _getBrailleRegionsForTable(self, obj):
1116
        """Get the braille for a table
1117
1118
        Arguments:
1119
        - obj: the table
1120
1121
        Returns a list where the first element is a list of Regions to display
1122
        and the second element is the Region which should get focus.
1123
        """
1124
1125 238
        self._debugGenerator("_getBrailleRegionsForTable", obj)
1126
1127 238
        return self._getDefaultBrailleRegions(obj)
1128
1129 1
    def _getBrailleRegionsForTableCell(self, obj):
1130
        """Get the braille for a single table cell
1131
1132
        Arguments:
1133
        - obj: the table
1134
1135
        Returns a list where the first element is a list of Regions to display
1136
        and the second element is the Region which should get focus.
1137
        """
1138
1139 318
        self._debugGenerator("_getBrailleRegionsForTableCell", obj)
1140
1141 318
        regions = []
1142
1143
        # If this table cell has 2 children and one of them has a
1144
        # 'toggle' action and the other does not, then present this
1145
        # as a checkbox where:
1146
        # 1) we get the checked state from the cell with the 'toggle' action
1147
        # 2) we get the label from the other cell.
1148
        # See Orca bug #376015 for more details.
1149
        #
1150 318
        if obj.childCount == 2:
1151 0
            cellOrder = []
1152 0
            hasToggle = [ False, False ]
1153 0
            for i in range(0, obj.childCount):
1154 0
                action = obj.child(i).action
1155 0
                if action:
1156 0
                    for j in range(0, action.nActions):
1157 0
                        if action.getName(j) == "toggle":
1158 0
                            hasToggle[i] = True
1159 0
                            break
1160
1161 0
            if hasToggle[0] and not hasToggle[1]:
1162 0
                cellOrder = [ 0, 1 ]
1163 0
            elif not hasToggle[0] and hasToggle[1]:
1164 0
                cellOrder = [ 1, 0 ]
1165 0
            if cellOrder:
1166 0
                for i in cellOrder:
1167
                    [cellRegions, focusRegion] = \
1168 0
                            self._getBrailleRegionsForTableCell(obj.child(i))
1169 0
                    if len(regions):
1170 0
                        regions.append(braille.Region(" "))
1171
                    else:
1172 0
                        cellFocusedRegion = focusRegion
1173 0
                    regions.append(cellRegions[0])
1174 0
                regions = [regions, cellFocusedRegion]
1175 0
                return regions
1176
1177
        # [[[TODO: WDW - Attempt to infer the cell type.  There's a
1178
        # bunch of stuff we can do here, such as check the EXPANDABLE
1179
        # state, check the NODE_CHILD_OF relation, etc.  Logged as
1180
        # bugzilla bug 319750.]]]
1181
        #
1182 318
        action = obj.action
1183 318
        if action:
1184 646
            for i in range(0, action.nActions):
1185 397
                debug.println(debug.LEVEL_FINEST,
1186 397
                    "braillegenerator._getBrailleRegionsForTableCell " \
1187 397
                    + "looking at action %d" % i)
1188 397
                if action.getName(i) == "toggle":
1189 47
                    obj.role = rolenames.ROLE_CHECK_BOX
1190 47
                    regions = self._getBrailleRegionsForCheckBox(obj)
1191
1192
                    # If this table cell doesn't have any label associated 
1193
                    # with it then also braille the table column header.
1194
                    # See Orca bug #455230 for more details.
1195
                    #
1196 47
                    label = self._script.getDisplayedText( \
1197 47
                        self._script.getRealActiveDescendant(obj))
1198 47
                    action = obj.action
1199 47
                    if label == None or len(label) == 0:
1200 47
                        n = obj.parent.table.getColumnAtIndex(obj.index)
1201 47
                        header = obj.parent.table.getColumnHeader(n)
1202 47
                        accHeader = atspi.Accessible.makeAccessible(header)
1203 47
                        regions[0].append(braille.Region(" "))
1204 47
                        regions[0].append(braille.Region(accHeader.name))
1205
1206 47
                    obj.role = rolenames.ROLE_TABLE_CELL
1207 47
                    break
1208
1209 318
        if len(regions) == 0:
1210 271
            regions = self._getDefaultBrailleRegions(
1211 271
                              self._script.getRealActiveDescendant(obj))
1212
        else:
1213 47
            [cellRegions, focusRegion] = self._getDefaultBrailleRegions(\
1214 47
                self._script.getRealActiveDescendant(obj))
1215 47
            regions[0].extend(cellRegions)
1216
1217
        # [[[TODO: WDW - HACK attempt to determine if this is a node;
1218
        # if so, describe its state.]]]
1219
        #
1220 318
        if obj.state.count(atspi.Accessibility.STATE_EXPANDABLE):
1221 37
            if obj.state.count(atspi.Accessibility.STATE_EXPANDED):
1222
                # Translators: this represents the state of a node in a tree.
1223
                # 'expanded' means the children are showing.
1224
                # 'collapsed' means the children are not showing.
1225
                #
1226 20
                regions[0].append(braille.Region(" " + _("expanded")))
1227
            else:
1228
                # Translators: this represents the state of a node in a tree.
1229
                # 'expanded' means the children are showing.
1230
                # 'collapsed' means the children are not showing.
1231
                #
1232 17
                regions[0].append(braille.Region(" " + _("collapsed")))
1233
1234 318
        level = self._script.getNodeLevel(obj)
1235 318
        if level >= 0:
1236
            # Translators: this represents the depth of a node in a tree
1237
            # view (i.e., how many ancestors a node has).
1238
            #
1239 180
            regions[0].append(braille.Region(" " + _("TREE LEVEL %d") \
1240 180
                                             % (level + 1)))
1241
1242 318
        return regions
1243
1244 1
    def _getBrailleRegionsForTableCellRow(self, obj):
1245
        """Get the braille for a table cell row or a single table cell
1246
        if settings.readTableCellRow is False.
1247
1248
        Arguments:
1249
        - obj: the table
1250
1251
        Returns a list where the first element is a list of Regions to display
1252
        and the second element is the Region which should get focus.
1253
        """
1254
1255 226
        self._debugGenerator("_getBrailleRegionsForTableColumnHeader", obj)
1256
1257 226
        regions = []
1258
1259
        # Adding in a check here to make sure that the parent is a
1260
        # valid table. It's possible that the parent could be a
1261
        # table cell too (see bug #351501).
1262
        #
1263 226
        if settings.readTableCellRow and obj.parent.table \
1264 216
            and (not self._script.isLayoutOnly(obj.parent)):
1265 216
            rowRegions = []
1266 216
            savedBrailleVerbosityLevel = settings.brailleVerbosityLevel
1267
            settings.brailleVerbosityLevel = \
1268 216
                                         settings.VERBOSITY_LEVEL_BRIEF
1269
1270 216
            parent = obj.parent
1271 216
            row = parent.table.getRowAtIndex(obj.index)
1272 216
            column = parent.table.getColumnAtIndex(obj.index)
1273
1274
            # This is an indication of whether we should speak all the
1275
            # table cells (the user has moved focus up or down a row),
1276
            # or just the current one (focus has moved left or right in
1277
            # the same row).
1278
            #
1279 216
            speakAll = True
1280 216
            if parent.__dict__.has_key("lastRow") and \
1281 174
                parent.__dict__.has_key("lastColumn"):
1282 174
                speakAll = (parent.lastRow != row) or \
1283 77
                       ((row == 0 or row == parent.table.nRows-1) and \
1284 23
                        parent.lastColumn == column)
1285
1286 216
            if speakAll:
1287 157
                focusRowRegion = None
1288 406
                for i in range(0, parent.table.nColumns):
1289 249
                    accRow = parent.table.getAccessibleAt(row, i)
1290 249
                    cell = atspi.Accessible.makeAccessible(accRow)
1291 249
                    showing = cell.state.count( \
1292 249
                                    atspi.Accessibility.STATE_SHOWING)
1293 249
                    if showing:
1294
                        [cellRegions, focusRegion] = \
1295 249
                            self._getBrailleRegionsForTableCell(cell)
1296 249
                        if len(rowRegions):
1297 92
                            rowRegions.append(braille.Region(" "))
1298 249
                        rowRegions.extend(cellRegions)
1299 249
                        if i == column:
1300 157
                            focusRowRegion = cellRegions[0]
1301 157
                regions = [rowRegions, focusRowRegion]
1302 157
                settings.brailleVerbosityLevel = savedBrailleVerbosityLevel
1303
            else:
1304 59
                regions = self._getBrailleRegionsForTableCell(obj)
1305
        else:
1306 10
            regions = self._getBrailleRegionsForTableCell(obj)
1307
1308 226
        return regions
1309
1310 1
    def _getBrailleRegionsForTableColumnHeader(self, obj):
1311
        """Get the braille for a table column header
1312
1313
        Arguments:
1314
        - obj: the table column header
1315
1316
        Returns a list where the first element is a list of Regions to display
1317
        and the second element is the Region which should get focus.
1318
        """
1319
1320 5
        self._debugGenerator("_getBrailleRegionsForTableColumnHeader", obj)
1321
1322 5
        return self._getBrailleRegionsForColumnHeader(obj)
1323
1324 1
    def _getBrailleRegionsForTableRowHeader(self, obj):
1325
        """Get the braille for a table row header
1326
1327
        Arguments:
1328
        - obj: the table row header
1329
1330
        Returns a list where the first element is a list of Regions to display
1331
        and the second element is the Region which should get focus.
1332
        """
1333
1334 0
        self._debugGenerator("_getBrailleRegionsForTableRowHeader", obj)
1335
1336 0
        return self._getBrailleRegionsForRowHeader(obj)
1337
1338 1
    def _getBrailleRegionsForTearOffMenuItem(self, obj):
1339
        """Get the braille for a tear off menu item
1340
1341
        Arguments:
1342
        - obj: the tear off menu item
1343
1344
        Returns a list where the first element is a list of Regions to display
1345
        and the second element is the Region which should get focus.
1346
        """
1347
1348 0
        self._debugGenerator("_getBrailleRegionsForTearOffMenuItem", obj)
1349
1350 0
        componentRegion = braille.Component(
1351 0
            obj,
1352 0
            rolenames.getBrailleForRoleName(obj))
1353 0
        return [[componentRegion], componentRegion]
1354
1355 1
    def _getBrailleRegionsForTerminal(self, obj):
1356
        """Get the braille for a terminal
1357
1358
        Arguments:
1359
        - obj: the terminal
1360
1361
        Returns a list where the first element is a list of Regions to display
1362
        and the second element is the Region which should get focus.
1363
        """
1364
1365 0
        self._debugGenerator("_getBrailleRegionsForTerminal", obj)
1366
1367 0
        title = None
1368 0
        frame = self._script.getFrame(obj)
1369 0
        if frame:
1370 0
            title = frame.name
1371 0
        if not title:
1372 0
            title = self._script.getDisplayedLabel(obj)
1373
1374 0
        text = title
1375 0
        text = self._script.appendString(
1376 0
            text, rolenames.getBrailleForRoleName(obj))
1377
1378 0
        regions = []
1379 0
        regions.append(braille.Region(text))
1380
1381 0
        textRegion = braille.Text(obj)
1382 0
        regions.append(textRegion)
1383
1384 0
        return [regions, textRegion]
1385
1386 1
    def _getBrailleRegionsForToggleButton(self, obj):
1387
        """Get the braille for a toggle button.  If the toggle button already
1388
        had focus, then only the state is displayed.
1389
1390
        Arguments:
1391
        - obj: the check box
1392
1393
        Returns a list where the first element is a list of Regions to display
1394
        and the second element is the Region which should get focus.
1395
        """
1396
1397 17
        self._debugGenerator("_getBrailleRegionsForToggleButton", obj)
1398
1399 17
        return self._getBrailleRegionsForRadioButton(obj)
1400
1401 1
    def _getBrailleRegionsForToolBar(self, obj):
1402
        """Get the braille for a tool bar
1403
1404
        Arguments:
1405
        - obj: the tool bar
1406
1407
        Returns a list where the first element is a list of Regions to display
1408
        and the second element is the Region which should get focus.
1409
        """
1410
1411 14
        self._debugGenerator("_getBrailleRegionsForToolBar", obj)
1412
1413 14
        return self._getDefaultBrailleRegions(obj)
1414
1415 1
    def _getBrailleRegionsForTree(self, obj):
1416
        """Get the braille for a tree
1417
1418
        Arguments:
1419
        - obj: the tree
1420
1421
        Returns a list where the first element is a list of Regions to display
1422
        and the second element is the Region which should get focus.
1423
        """
1424
1425 0
        self._debugGenerator("_getBrailleRegionsForTreeTable", obj)
1426
1427 0
        return self._getDefaultBrailleRegions(obj)
1428
1429 1
    def _getBrailleRegionsForTreeTable(self, obj):
1430
        """Get the braille for a tree table
1431
1432
        Arguments:
1433
        - obj: the tree table
1434
1435
        Returns a list where the first element is a list of Regions to display
1436
        and the second element is the Region which should get focus.
1437
        """
1438
1439 0
        self._debugGenerator("_getBrailleRegionsForTreeTable", obj)
1440
1441 0
        return self._getDefaultBrailleRegions(obj)
1442
1443 1
    def _getBrailleRegionsForWindow(self, obj):
1444
        """Get the braille for a window
1445
1446
        Arguments:
1447
        - obj: the window
1448
1449
        Returns a list where the first element is a list of Regions to display
1450
        and the second element is the Region which should get focus.
1451
        """
1452
1453 795
        self._debugGenerator("_getBrailleRegionsForWindow", obj)
1454
1455 795
        return self._getDefaultBrailleRegions(obj)
1456
1457 1
    def getBrailleRegions(self, obj, groupChildren=True):
1458
        """Get the braille regions for an Accessible object.  This
1459
        will look first to the specific braille generators and then to
1460
        the default braille generator.  This method is the primary
1461
        method that external callers of this class should use.
1462
1463
        Arguments:
1464
        - obj: the object
1465
        - groupChildren: if True, children of an object should be displayed
1466
                         together with their parent, where each child is
1467
                         separated by _ and the selected child is the Region
1468
                         that should get focus.  The default here is True,
1469
                         but this also is used in conjunction with
1470
                         settings.enableBrailleGrouping.
1471
1472
        Returns a list where the first element is a list of Regions to
1473
        display and the second element is the Region which should get
1474
        focus.
1475
        """
1476
1477
        # If we want to group the children, first see if obj is a child of
1478
        # something we like to group.  If so, then reset the obj to the obj's
1479
        # parent.  If not, see if the obj is the container of things we like
1480
        # to group.  If all fails, we don't try grouping.
1481
        #
1482 6675
        reallyGroupChildren = False
1483 6675
        if settings.enableBrailleGrouping and groupChildren:
1484 0
            parent = obj.parent
1485 0
            isChild = parent \
1486 0
                      and ((parent.role == rolenames.ROLE_MENU) \
1487 0
                           or (parent.role == rolenames.ROLE_MENU_BAR) \
1488 0
                           or (parent.role == rolenames.ROLE_PAGE_TAB_LIST))
1489 0
            if isChild:
1490 0
                obj = parent
1491 0
                reallyGroupChildren = True
1492
            else:
1493
                reallyGroupChildren = \
1494 0
                    (obj.role == rolenames.ROLE_MENU) \
1495 0
                    or (obj.role == rolenames.ROLE_MENU_BAR) \
1496 0
                    or (obj.role == rolenames.ROLE_PAGE_TAB_LIST)
1497
1498 6675
        if self.brailleGenerators.has_key(obj.role):
1499 4260
            generator = self.brailleGenerators[obj.role]
1500
        else:
1501 2415
            generator = self._getDefaultBrailleRegions
1502
1503 6675
        result = generator(obj)
1504 6675
        regions = result[0]
1505 6675
        selectedRegion = result[1]
1506
1507 6675
        if reallyGroupChildren:
1508 0
            regions.append(braille.Region(" "))
1509 0
            selection = obj.selection
1510 0
            for i in range(0, obj.childCount):
1511 0
                debug.println(debug.LEVEL_FINEST,
1512 0
                    "braillegenerator.getBrailleRegions " \
1513 0
                    + "looking at child %d" % i)
1514 0
                child = obj.child(i)
1515
1516
                # [[[TODO: richb - Need to investigate further.
1517
                # Sometimes, for some unknown reason, the child is None.
1518
                # We now test for this, rather than cause a traceback.
1519
                #
1520 0
                if child and (child.role != rolenames.ROLE_SEPARATOR):
1521
1522
                # the following line has been removed because insensitive
1523
                # menu items can get focus in StarOffice.
1524
                #
1525
                # and child.state.count(atspi.Accessibility.STATE_SENSITIVE):
1526
1527 0
                    if (i > 0) and (i < (self, obj.childCount - 1)):
1528 0
                        regions.append(braille.Region(" _ "))
1529
1530 0
                    result = self.getBrailleRegions(child, False)
1531 0
                    regions.extend(result[0])
1532
1533
                    # This helps us determine which child is the selected
1534
                    # child.  Tracking the SELECTED state is not always
1535
                    # useful (it seems to be inconsistently handled by
1536
                    # toolkits), so we look at the parent's selection model.
1537
                    # In addition, we add a STATE_ARMED check here as a
1538
                    # workaround to the way OOo handles its menu items.
1539
                    #
1540 0
                    if (selection and selection.isChildSelected(i)) \
1541 0
                       or child.state.count(atspi.Accessibility.STATE_ARMED):
1542 0
                        selectedRegion = result[1]
1543
1544 6675
        return [regions, selectedRegion]
1545
1546 1
    def getBrailleContext(self, obj):
1547
        """Get the braille regions that describe the context (i.e.,
1548
        names/roles of the container hierarchy) of the object.
1549
1550
        Arguments:
1551
        - obj: the object
1552
1553
        Returns a list of Regions to display.
1554
        """
1555
1556 1845
        brailleRolenameStyle = settings.brailleRolenameStyle
1557
1558 1845
        regions = []
1559 1845
        parent = obj.parent
1560 1845
        if parent and (parent.role in self.SKIP_CONTEXT_ROLES):
1561 77
            parent = parent.parent
1562 1845
        while parent and (parent.parent != parent):
1563
            # [[[TODO: WDW - we might want to include more things here
1564
            # besides just those things that have labels.  For example,
1565
            # page tab lists might be a nice thing to include. Logged
1566
            # as bugzilla bug 319751.]]]
1567
            #
1568 7416
            if (parent.role != rolenames.ROLE_FILLER) \
1569 5539
                and (parent.role != rolenames.ROLE_SECTION) \
1570 5539
                and (parent.role != rolenames.ROLE_SPLIT_PANE) \
1571 5527
                and (not self._script.isLayoutOnly(parent)):
1572
1573
                # Announce the label and text of the object in the hierarchy.
1574
                #
1575 4437
                label = self._script.getDisplayedLabel(parent)
1576 4437
                text = self._script.getDisplayedText(parent)
1577 4437
                regions.append(braille.Region(" "))
1578 4437
                result = self.getBrailleRegions(parent, False)
1579 4437
                regions.extend(result[0])
1580
1581
            # [[[TODO: HACK - we've discovered oddness in hierarchies
1582
            # such as the gedit Edit->Preferences dialog.  In this
1583
            # dialog, we have labeled groupings of objects.  The
1584
            # grouping is done via a FILLER with two children - one
1585
            # child is the overall label, and the other is the
1586
            # container for the grouped objects.  When we detect this,
1587
            # we add the label to the overall context.]]]
1588
            #
1589 7416
            if parent.role == rolenames.ROLE_FILLER:
1590 1877
                label = self._script.getDisplayedLabel(parent)
1591 1877
                if label and len(label) and not label.isspace():
1592 23
                    regions.append(braille.Region(" "))
1593 23
                    result = self.getBrailleRegions(parent, False)
1594 23
                    regions.extend(result[0])
1595
1596 7416
            parent = parent.parent
1597
1598 1845
        regions.reverse()
1599
1600
        # Now, we'll treat table row and column headers as context as
1601
        # well.  This requires special handling because we're making
1602
        # headers seem hierarchical in the context, but they are not
1603
        # hierarchical in the containment hierarchicy.  If both exist,
1604
        # we first show the row header then the column header.
1605
        #
1606 1845
        parent = obj.parent
1607 1845
        if parent and parent.table:
1608 231
            row = parent.table.getRowAtIndex(obj.index)
1609 231
            if row >= 0:
1610 226
                desc = parent.table.getRowDescription(row)
1611
            else:
1612 5
                desc = None
1613 231
            if desc and len(desc):
1614 0
                if settings.brailleRolenameStyle \
1615 0
                       == settings.VERBOSITY_LEVEL_VERBOSE:
1616 0
                    if brailleRolenameStyle \
1617 0
                           == settings.BRAILLE_ROLENAME_STYLE_LONG:
1618
                        text = desc + " " + rolenames.rolenames[\
1619 0
                            rolenames.ROLE_ROW_HEADER].brailleLong + " "
1620
                    else:
1621
                        text = desc + " " + rolenames.rolenames[\
1622 0
                            rolenames.ROLE_ROW_HEADER].brailleShort + " "
1623
                else:
1624 0
                    text = desc
1625 0
                regions.append(braille.Region(text))
1626
1627 231
            col = parent.table.getColumnAtIndex(obj.index)
1628 231
            if col >= 0:
1629 231
                desc = parent.table.getColumnDescription(col)
1630
            else:
1631 0
                desc = None
1632 231
            if desc and len(desc):
1633 231
                if settings.brailleVerbosityLevel \
1634 231
                       == settings.VERBOSITY_LEVEL_VERBOSE:
1635 150
                    if brailleRolenameStyle \
1636 150
                           == settings.BRAILLE_ROLENAME_STYLE_LONG:
1637
                        text = desc + " " + rolenames.rolenames[\
1638 150
                            rolenames.ROLE_COLUMN_HEADER].brailleLong + " "
1639
                    else:
1640
                        text = desc + " " + rolenames.rolenames[\
1641 0
                            rolenames.ROLE_COLUMN_HEADER].brailleShort + " "
1642
                else:
1643 81
                    text = desc
1644 231
                regions.append(braille.Region(text))
1645
1646 1845
        return regions