Coverage Report - orca.braillegenerator

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