[orca/570658] Begin work on Gecko's braille generator



commit 14259296e499e572334155b66bec817fea98920c
Author: Willie Walker <william walker sun com>
Date:   Tue Jun 30 10:52:34 2009 -0400

    Begin work on Gecko's braille generator
    
    This is very minimalist and not at all complete.  Much work to do,
    but I needed to do something so as to prevent the gtk-demo tests
    from failing (the orca-customizations.py for the test was importing
    Gecko, so Gecko needed to migrate to the new generator).

 src/orca/braille_generator.py                      |    1 +
 .../scripts/toolkits/Gecko/braille_generator.py    | 1153 ++++++++++++--------
 src/orca/scripts/toolkits/Gecko/formatting.py      |   26 +
 src/orca/scripts/toolkits/Gecko/script.py          |    2 +-
 4 files changed, 717 insertions(+), 465 deletions(-)
---
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index dc6af33..fb74c2b 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -65,6 +65,7 @@ class BrailleGenerator(generator.Generator):
         globalsDict['Component'] = braille.Component
         globalsDict['Region'] = braille.Region
         globalsDict['Text'] = braille.Text
+        globalsDict['Link'] = braille.Link
         globalsDict['asString'] = self.asString
 
     def generateBraille(self, obj, **args):
diff --git a/src/orca/scripts/toolkits/Gecko/braille_generator.py b/src/orca/scripts/toolkits/Gecko/braille_generator.py
index de22c19..e777f20 100644
--- a/src/orca/scripts/toolkits/Gecko/braille_generator.py
+++ b/src/orca/scripts/toolkits/Gecko/braille_generator.py
@@ -1,6 +1,6 @@
 # Orca
 #
-# Copyright 2005-2008 Sun Microsystems Inc.
+# Copyright 2005-2009 Sun Microsystems Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -27,13 +27,13 @@ http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
 __id__        = "$Id$"
 __version__   = "$Revision$"
 __date__      = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
 import pyatspi
 
 import orca.braille as braille
-import orca.braillegenerator as braillegenerator
+import orca.braille_generator as braille_generator
 import orca.rolenames as rolenames
 import orca.settings as settings
 
@@ -43,485 +43,710 @@ import orca.settings as settings
 #                                                                      #
 ########################################################################
 
-class BrailleGenerator(braillegenerator.BrailleGenerator):
+class BrailleGenerator(braille_generator.BrailleGenerator):
     """Provides a braille generator specific to Gecko.
     """
 
     def __init__(self, script):
-        braillegenerator.BrailleGenerator.__init__(self, script)
-        self.brailleGenerators[pyatspi.ROLE_AUTOCOMPLETE] = \
-             self._getBrailleRegionsForAutocomplete
-        self.brailleGenerators[pyatspi.ROLE_ENTRY]        = \
-             self._getBrailleRegionsForText
-        self.brailleGenerators[pyatspi.ROLE_LINK]         = \
-             self._getBrailleRegionsForLink
+        braille_generator.BrailleGenerator.__init__(self, script)
 
-    def _getTextForRole(self, obj, role=None):
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \
-           and not obj.getRole() in [pyatspi.ROLE_SECTION,
-                                     pyatspi.ROLE_FORM,
-                                     pyatspi.ROLE_UNKNOWN]:
-            return rolenames.getBrailleForRoleName(obj, role)
-        else:
-            return None
-
-    def _getBrailleRegionsForAutocomplete(self, obj):
-        """Gets the braille for an autocomplete box.  We let the
-        handlers for the children do the rest.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForAutocomplete", obj)
-
-        # [[[TODO: WDW - we're doing very little here.  The goal for
-        # autocomplete boxes at the moment is that their children (e.g.,
-        # a text area, a menu, etc., do all the interactive work and
-        # the autocomplete acts as more of a container.]]]
-        #
-        regions = []
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                rolenames.getBrailleForRoleName(obj)))
-        else:
-            regions.append(braille.Region(""))
-
-        return (regions, regions[0])
-
-    def _getBrailleRegionsForCheckBox(self, obj):
-        """Get the braille for a check box.  If the check box already had
-        focus, then only the state is displayed.
-
-        Arguments:
-        - obj: the check box
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForCheckBox", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForCheckBox(self, obj)
-        
-        # In document content (I'm not sure about XUL widgets yet), a
-        # checkbox is its own little beast with no text.  So...  if it
-        # is in document content and has a label, we're likely to be
-        # displaying that label already.  If it doesn't have a label,
-        # though, we'll display its name.
-        #
-        text = ""
-        if not self._script.inDocumentContent():
-            text = self._script.appendString(
-                text, self._script.getDisplayedLabel(obj))
-            text = self._script.appendString(
-                text, self._script.getDisplayedText(obj))
-        else:
-            isLabelled = False
-            relationSet = obj.getRelationSet()
-            if relationSet:
-                for relation in relationSet:
-                    if relation.getRelationType() \
-                        == pyatspi.RELATION_LABELLED_BY:
-                        isLabelled = True
-                        break
-            if not isLabelled and obj.name and len(obj.name):
-                text = self._script.appendString(text, obj.name)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        # get the Braille indicator
-        state = obj.getState()
-        if state.contains(pyatspi.STATE_INDETERMINATE):
-            indicatorIndex = 2
-        elif state.contains(pyatspi.STATE_CHECKED):
-            indicatorIndex = 1
-        else:
-            indicatorIndex = 0
-
-        regions = []
-
-        componentRegion = braille.Component(
-            obj, text,
-            indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
-        regions.append(componentRegion)
-
-        return [regions, componentRegion]
-
-    def _getBrailleRegionsForRadioButton(self, obj):
-        """Get the braille for a radio button.  If the radio button already
-        had focus, then only the state is displayed.
+    def _generateRoleName(self, obj, **args):
+        """Prevents some roles from being spoken."""
+        result = []
+        role = args.get('role', obj.getRole())
+        force = args.get('force', False)
 
-        Arguments:
-        - obj: the radio button
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForRadioButton", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForRadioButton(self, obj)
-        
-        # In document content (I'm not sure about XUL widgets yet), a
-        # radio button is its own little beast with no text.  So...  if it
-        # is in document content and has a label, we're likely to be
-        # displaying that label already.  If it doesn't have a label,
-        # though, we'll display its name.
+        # Saying "menu item" for a combo box can confuse users. Therefore,
+        # speak the combo box role instead.  Also, only do it if the menu
+        # item is not focused (if the menu item is focused, it means we're
+        # navigating in the combo box)
         #
-        text = ""
-        if not self._script.inDocumentContent():
-            text = self._script.appendString(
-                text, self._script.getDisplayedLabel(obj))
-            text = self._script.appendString(
-                text, self._script.getDisplayedText(obj))
+        if not obj.getState().contains(pyatspi.STATE_FOCUSED):
+            comboBox = self._script.getAncestor(obj,
+                                                [pyatspi.ROLE_COMBO_BOX],
+                                                [pyatspi.ROLE_DOCUMENT_FRAME])
+            if comboBox:
+                return self._generateRoleName(comboBox, **args)
+
+        if not force:
+            doNotSpeak = [pyatspi.ROLE_FORM,
+                          pyatspi.ROLE_LABEL,
+                          pyatspi.ROLE_MENU_ITEM,
+                          pyatspi.ROLE_PARAGRAPH,
+                          pyatspi.ROLE_SECTION,
+                          pyatspi.ROLE_UNKNOWN]
         else:
-            isLabelled = False
-            relationSet = obj.getRelationSet()
-            if relationSet:
-                for relation in relationSet:
-                    if relation.getRelationType() \
-                        == pyatspi.RELATION_LABELLED_BY:
-                        isLabelled = True
-                        break
-
-            if not isLabelled and obj.name and len(obj.name):
-                text = self._script.appendString(text, obj.name)
-
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
-
-        regions = []
-        componentRegion = braille.Component(
-            obj, text,
-            indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
-        regions.append(componentRegion)
-
-        return [regions, componentRegion]
-
-    def _getBrailleRegionsForText(self, obj):
-        """Gets text to be displayed for the entry of an autocomplete box.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForText", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForText(self, obj)
-        
-        parent = obj.parent
-        if parent.getRole() != pyatspi.ROLE_AUTOCOMPLETE:
-            return braillegenerator.BrailleGenerator._getBrailleRegionsForText(
-                self, obj)
-
-        regions = []
-
-        # This is the main difference between this class and the default
-        # class - we'll give this thing a name here, and we'll make it
-        # be the name of the autocomplete.
-        #
-        label = self._script.getDisplayedLabel(parent)
-        if not label or not len(label):
-            label = parent.name
-
-        textRegion = braille.Text(obj, label, settings.brailleEOLIndicator)
-        regions.append(textRegion)
-
-        if settings.presentReadOnlyText \
-           and self._script.isReadOnlyTextArea(obj):
-            regions.append(braille.Region(" " \
-                                          + settings.brailleReadOnlyString))
-
-        return [regions, textRegion]
-
-    def _getBrailleRegionsForComboBox(self, obj):
-        """Get the braille for a combo box.  If the combo box already has
-        focus, then only the selection is displayed.
-
-        Arguments:
-        - obj: the combo box
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForComboBox", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                     _getBrailleRegionsForComboBox(self, obj)
-        
-        regions = []
-
-        label = self._script.getDisplayedLabel(obj)
-        if not label and not self._script.inDocumentContent():
-            label = obj.name
-
-        focusedRegionIndex = 0
-        if label and len(label):
-            regions.append(braille.Region(label + " "))
-            focusedRegionIndex = 1
-
-        # With Gecko, a combo box has a menu as a child.  The text being
-        # displayed for the combo box can be obtained via the selected
-        # menu item.
-        #
-        menu = None
-        for child in obj:
-            if child.getRole() == pyatspi.ROLE_MENU:
-                menu = child
-                break
-        if menu:
-            child = None
-            try:
-                # This should work...
-                #
-                child = menu.querySelection().getSelectedChild(0)
-                if not child:
-                    # It's probably a Gtk combo box.
+            # We never ever want to speak 'unknown'
+            #
+            doNotSpeak = [pyatspi.ROLE_UNKNOWN]
+
+        if not force and self._script.inDocumentContent(obj):
+            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
+            if not self._script.isAriaWidget(obj) \
+               and args.get('formatType', 'unfocused') != 'basicWhereAmI':
+                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
+                doNotSpeak.append(pyatspi.ROLE_LIST)
+
+        if not (role in doNotSpeak):
+            if role == pyatspi.ROLE_IMAGE:
+                link = self._script.getAncestor(obj,
+                                                [pyatspi.ROLE_LINK],
+                                                [pyatspi.ROLE_DOCUMENT_FRAME])
+                if link:
+                    result.append(rolenames.getBrailleForRoleName(link))
+
+            if role == pyatspi.ROLE_HEADING:
+                level = self._script.getHeadingLevel(obj)
+                if level:
+                    # Translators: the %(level)d is in reference to a heading
+                    # level in HTML (e.g., For <h3>, the level is 3)
+                    # and the %(role)s is in reference to a previously
+                    # translated rolename for the heading.
                     #
-                    return braillegenerator.BrailleGenerator.\
-                        _getBrailleRegionsForComboBox(self, obj)
-            except:
-                # But just in case, we'll fall back on this.
-                # [[[TODO - JD: Will we ever have a case where the first
-                # fails, but this will succeed???]]]
+                    result.append(_("%(role)s level %(level)d") % {
+                        'role': rolenames.getBrailleForRoleName(obj, role),
+                        'level': level})
+                else:
+                    result.append(rolenames.getBrailleForRoleName(obj, role))
+            else:
+                result.append(rolenames.getBrailleForRoleName(obj, role))
+
+            if role == pyatspi.ROLE_LINK \
+               and obj.childCount and obj[0].getRole() == pyatspi.ROLE_IMAGE:
+                # If this is a link with a child which is an image, we
+                # want to indicate that.
                 #
-                for item in menu:
-                    if item.getState().contains(pyatspi.STATE_SELECTED):
-                        child = item
-                        break
-            if child:
-                regions.append(braille.Region(child.name))
-
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                " " + rolenames.getBrailleForRoleName(obj)))
-
-        # Things may not have gone as expected above, so we'll do some
-        # defensive programming to make sure we don't get an index out
-        # of bounds.
-        #
-        if focusedRegionIndex >= len(regions):
-            focusedRegionIndex = 0
-
-        if obj.getState().contains(pyatspi.STATE_FOCUSED):
-            focusedRegion = regions[focusedRegionIndex]
+                result.append(rolenames.getBrailleForRoleName(obj[0]))
+
+        return result
+
+    def _generateName(self, obj, **args):
+        result = []
+        role = args.get('role', obj.getRole())
+        if role == pyatspi.ROLE_COMBO_BOX:
+            # With Gecko, a combo box has a menu as a child.  The text being
+            # displayed for the combo box can be obtained via the selected
+            # menu item.
+            #
+            menu = None
+            for child in obj:
+                if child.getRole() == pyatspi.ROLE_MENU:
+                    menu = child
+                    break
+            if menu:
+                child = None
+                try:
+                    # This should work...
+                    #
+                    child = menu.querySelection().getSelectedChild(0)
+                    if not child:
+                        # It's probably a Gtk combo box.
+                        #
+                        result = braille_generator.BrailleGenerator.\
+                            _generateDisplayedText(self, obj, **args)
+                except:
+                    # But just in case, we'll fall back on this.
+                    # [[[TODO - JD: Will we ever have a case where the first
+                    # fails, but this will succeed???]]]
+                    #
+                    for item in menu:
+                        if item.getState().contains(pyatspi.STATE_SELECTED):
+                            child = item
+                            break
+                if child and child.name:
+                    result.append(child.name)
         else:
-            focusedRegion = None
-
-        # [[[TODO: WDW - perhaps if a text area was created, we should
-        # give focus to it.]]]
-        #
-        return [regions, focusedRegion]
-
-    def _getBrailleRegionsForMenuItem(self, obj):
-        """Get the braille for a menu item.
+            result.extend(braille_generator.BrailleGenerator._generateName(
+                              self, obj, **args))
+        if not result and role == pyatspi.ROLE_LIST_ITEM:
+            result.append(self._script.expandEOCs(obj))
+
+        link = None
+        if role == pyatspi.ROLE_LINK:
+            link = obj
+        elif role == pyatspi.ROLE_IMAGE and not result:
+            link = self._script.getAncestor(obj,
+                                            [pyatspi.ROLE_LINK],
+                                            [pyatspi.ROLE_DOCUMENT_FRAME])
+        if link and (not result or len(result[0].strip()) == 0):
+            # If there's no text for the link, expose part of the
+            # URI to the user.
+            #
+            basename = self._script.getLinkBasename(link)
+            if basename:
+                result.append(basename)
 
-        Arguments:
-        - obj: the menu item
+        return result
 
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
+    def _generateDescription(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represent the description of the object,
+        if that description is different from that of the name and
+        label.
         """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForMenuItem", obj)
-
-        # Treat ARIA widgets like default.py widgets
-        #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                     _getBrailleRegionsForMenuItem(self, obj)
-        
-        if not self._script.inDocumentContent():
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForMenuItem(self, obj)
-
-        regions = []
-
-        # Displaying "menu item" for a combo box can confuse users. Therefore,
-        # display the combo box role instead.  Also, only do it if the menu
-        # item is not focused (if the menu item is focused, it means we're
-        # navigating in the combo box).
+        if args.get('role', obj.getRole()) == pyatspi.ROLE_LINK \
+           and obj.parent.getRole() == pyatspi.ROLE_IMAGE:
+            result = self._generateName(obj, **args)
+            # Translators: The following string is spoken to let the user
+            # know that he/she is on a link within an image map. An image
+            # map is an image/graphic which has been divided into regions.
+            # Each region can be clicked on and has an associated link.
+            # Please see http://en.wikipedia.org/wiki/Imagemap for more
+            # information and examples.
+            #
+            result.append(_("image map link"))
+        else:
+            result = braille_generator.BrailleGenerator.\
+                           _generateDescription(self, obj, **args)
+        return result
+
+    def _generateLabel(self, obj, **args):
+        result = braille_generator.BrailleGenerator._generateLabel(self,
+                                                                   obj,
+                                                                   **args)
+        role = args.get('role', obj.getRole())
+        # We'll attempt to guess the label under some circumstances.
         #
-        label = self._script.getDisplayedLabel(obj)
-        focusedRegionIndex = 0
-        if label and len(label):
-            regions.append(braille.Region(label + " "))
-            focusedRegionIndex = 1
-        regions.append(braille.Region(obj.name))
-
-        comboBox = \
-                 self._script.getAncestor(obj,
-                                          [pyatspi.ROLE_COMBO_BOX],
-                                          [pyatspi.ROLE_DOCUMENT_FRAME])
-        if comboBox \
-           and not obj.getState().contains(pyatspi.STATE_FOCUSED) \
-           and (settings.brailleVerbosityLevel == \
-                settings.VERBOSITY_LEVEL_VERBOSE):
-            regions.append(braille.Region(
-                " " + rolenames.getBrailleForRoleName(comboBox)))
-
-        return [regions, regions[focusedRegionIndex]]
-
-    def _getBrailleRegionsForList(self, obj):
-        """Get the braille for a list in a form.  If the list already has
-        focus, then only the selection is displayed.
-
-        Arguments:
-        - obj: the list
-
-        Returns a list where the first element is a list of Regions to display
-        and the second element is the Region which should get focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForList", obj)
-
-        # Treat ARIA widgets like default.py widgets
+        if not len(result) \
+           and role in [pyatspi.ROLE_CHECK_BOX,
+                        pyatspi.ROLE_COMBO_BOX,
+                        pyatspi.ROLE_ENTRY,
+                        pyatspi.ROLE_LIST,
+                        pyatspi.ROLE_PARAGRAPH,
+                        pyatspi.ROLE_PASSWORD_TEXT,
+                        pyatspi.ROLE_RADIO_BUTTON,
+                        pyatspi.ROLE_TEXT] \
+           and self._script.inDocumentContent() \
+           and not self._script.isAriaWidget(obj):
+            label = self._script.guessTheLabel(obj)
+            if label:
+                result.append(label)
+
+        # XUL combo boxes don't always have a label for/by
+        # relationship.  But, they will make their names be
+        # the string of the thing labelling them.
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForList(self, obj)
-        
-        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForList(self, obj)
-
-        regions = []
-        focusedRegionIndex = 0
-
-        if obj.getState().contains(pyatspi.STATE_FOCUSED):
-            label = self._script.getDisplayedLabel(obj)
-            if not label:
-                label = obj.name
-
-            if label and len(label):
-                regions.append(braille.Region(label + " "))
-                focusedRegionIndex = 1
+        if not len(result) \
+           and role == pyatspi.ROLE_COMBO_BOX \
+           and not self._script.inDocumentContent():
+            result.append(obj.name)
 
-            item = None
-            selection = obj.querySelection()
-            for i in xrange(obj.childCount):
-                if selection.isChildSelected(i):
-                    item = obj[i]
-                    break
-            if not item:
-                item = obj[0]
-            regions.append(braille.Region(item.name + " "))
-        elif obj.getState().contains(pyatspi.STATE_FOCUSABLE):
-            focusedRegionIndex = -1
-
-        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
-            regions.append(braille.Region(
-                rolenames.getBrailleForRoleName(obj)))
-
-        if focusedRegionIndex > -1:
-            focusedRegion = regions[focusedRegionIndex]
-        else:
-            focusedRegion = None
-
-        return [regions, focusedRegion]
-
-    def _getBrailleRegionsForImage(self, obj):
-        """Get the braille regions for an image.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForImage", obj)
-
-        # Treat ARIA widgets like default.py widgets
+        # If this is an autocomplete, and we'll make the label be the
+        # name of the autocomplete.
         #
-        if self._script.isAriaWidget(obj):
-            return braillegenerator.BrailleGenerator.\
-                       _getBrailleRegionsForImage(self, obj)
-        
-        text = ""
-        text = self._script.appendString(text, 
-                                         self._script.getDisplayedLabel(obj))
-        text = self._script.appendString(text,
-                                         self._script.getDisplayedText(obj))
-        link = self._script.getAncestor(obj, 
-                                        [pyatspi.ROLE_LINK],
-                                        [pyatspi.ROLE_DOCUMENT_FRAME])
-        if link:
-            if len(text) == 0:
-                # If there's no text for the link, expose part of the
-                # link to the user if the image is in a link.
-                #
-                basename = self._script.getLinkBasename(link)
-                if basename:
-                    text = basename
-
-        text = self._script.appendString(text,
-                                         self._script.getTextForValue(obj))
-        text = self._script.appendString(text, self._getTextForRole(obj))
-
-        regions = []
-        if link:
-            region = braille.Link(obj, text)
-        else:
-            region = braille.Component(obj, text)
-        regions.append(region)
-
-        return [regions, region]
-
-    def _getBrailleRegionsForLink(self, obj):
-        """Gets text to be displayed for a link.
-
-        Arguments:
-        - obj: an Accessible
-
-        Returns a list where the first element is a list of Regions to
-        display and the second element is the Region which should get
-        focus.
-        """
-
-        self._debugGenerator("Gecko._getBrailleRegionsForLink", obj)
-
-        text, caretOffset, startOffset = self._script.getTextLineAtCaret(obj)
-        if not len(text):
-            text = self._script.getDisplayedText(obj)
-
-        # If there's no text for the link, expose part of the
-        # URI to the user.
+        if not len(result):
+            parent = obj.parent
+            if parent and parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
+                label = self._script.getDisplayedLabel(parent)
+                if not label or not len(label):
+                    label = parent.name
+                result.append(label)
+
+        return result
+
+    def _generateExpandedEOCs(self, obj, **args):
+        """Returns the expanded embedded object characters for an object."""
+        result = []
+        text = self._script.expandEOCs(obj)
+        if text:
+            result.append(text)
+        return result
+
+    def generateBraille(self, obj, **args):
+        result = []
+        # ARIA widgets get treated like regular default widgets.
         #
-        if len(text) == 0:
-            basename = self._script.getLinkBasename(obj)
-            if basename:
-                text = basename
+        args['isAria'] = self._script.isAriaWidget(obj)
+        result.extend(braille_generator.BrailleGenerator.\
+                          generateBraille(self, obj, **args))
+        del args['isAria']
+        return result
 
-        regions = []
-        linkRegion = braille.Link(obj, text, caretOffset - startOffset)
-        regions.append(linkRegion)
+########################################################################
+#                                                                      #
+# OLD CODE FOR REFERENCE                                               #
+#                                                                      #
+########################################################################
 
-        return [regions, linkRegion]
+#class BrailleGenerator(braillegenerator.BrailleGenerator):
+#    """Provides a braille generator specific to Gecko.
+#    """
+#
+#    def __init__(self, script):
+#        braillegenerator.BrailleGenerator.__init__(self, script)
+#        self.brailleGenerators[pyatspi.ROLE_AUTOCOMPLETE] = \
+#             self._getBrailleRegionsForAutocomplete
+#        self.brailleGenerators[pyatspi.ROLE_ENTRY]        = \
+#             self._getBrailleRegionsForText
+#        self.brailleGenerators[pyatspi.ROLE_LINK]         = \
+#             self._getBrailleRegionsForLink
+#
+#    def _getTextForRole(self, obj, role=None):
+#        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \
+#           and not obj.getRole() in [pyatspi.ROLE_SECTION,
+#                                     pyatspi.ROLE_FORM,
+#                                     pyatspi.ROLE_UNKNOWN]:
+#            return rolenames.getBrailleForRoleName(obj, role)
+#        else:
+#            return None
+#
+#    def _getBrailleRegionsForAutocomplete(self, obj):
+#        """Gets the braille for an autocomplete box.  We let the
+#        handlers for the children do the rest.
+#
+#        Arguments:
+#        - obj: an Accessible
+#
+#        Returns a list where the first element is a list of Regions to
+#        display and the second element is the Region which should get
+#        focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForAutocomplete", obj)
+#
+#        # [[[TODO: WDW - we're doing very little here.  The goal for
+#        # autocomplete boxes at the moment is that their children (e.g.,
+#        # a text area, a menu, etc., do all the interactive work and
+#        # the autocomplete acts as more of a container.]]]
+#        #
+#        regions = []
+#        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+#            regions.append(braille.Region(
+#                rolenames.getBrailleForRoleName(obj)))
+#        else:
+#            regions.append(braille.Region(""))
+#
+#        return (regions, regions[0])
+#
+#    def _getBrailleRegionsForCheckBox(self, obj):
+#        """Get the braille for a check box.  If the check box already had
+#        focus, then only the state is displayed.
+#
+#        Arguments:
+#        - obj: the check box
+#
+#        Returns a list where the first element is a list of Regions to display
+#        and the second element is the Region which should get focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForCheckBox", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForCheckBox(self, obj)
+#        
+#        # In document content (I'm not sure about XUL widgets yet), a
+#        # checkbox is its own little beast with no text.  So...  if it
+#        # is in document content and has a label, we're likely to be
+#        # displaying that label already.  If it doesn't have a label,
+#        # though, we'll display its name.
+#        #
+#        text = ""
+#        if not self._script.inDocumentContent():
+#            text = self._script.appendString(
+#                text, self._script.getDisplayedLabel(obj))
+#            text = self._script.appendString(
+#                text, self._script.getDisplayedText(obj))
+#        else:
+#            isLabelled = False
+#            relationSet = obj.getRelationSet()
+#            if relationSet:
+#                for relation in relationSet:
+#                    if relation.getRelationType() \
+#                        == pyatspi.RELATION_LABELLED_BY:
+#                        isLabelled = True
+#                        break
+#            if not isLabelled and obj.name and len(obj.name):
+#                text = self._script.appendString(text, obj.name)
+#
+#        text = self._script.appendString(text, self._getTextForRole(obj))
+#
+#        # get the Braille indicator
+#        state = obj.getState()
+#        if state.contains(pyatspi.STATE_INDETERMINATE):
+#            indicatorIndex = 2
+#        elif state.contains(pyatspi.STATE_CHECKED):
+#            indicatorIndex = 1
+#        else:
+#            indicatorIndex = 0
+#
+#        regions = []
+#
+#        componentRegion = braille.Component(
+#            obj, text,
+#            indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
+#        regions.append(componentRegion)
+#
+#        return [regions, componentRegion]
+#
+#    def _getBrailleRegionsForRadioButton(self, obj):
+#        """Get the braille for a radio button.  If the radio button already
+#        had focus, then only the state is displayed.
+#
+#        Arguments:
+#        - obj: the radio button
+#
+#        Returns a list where the first element is a list of Regions to display
+#        and the second element is the Region which should get focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForRadioButton", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForRadioButton(self, obj)
+#        
+#        # In document content (I'm not sure about XUL widgets yet), a
+#        # radio button is its own little beast with no text.  So...  if it
+#        # is in document content and has a label, we're likely to be
+#        # displaying that label already.  If it doesn't have a label,
+#        # though, we'll display its name.
+#        #
+#        text = ""
+#        if not self._script.inDocumentContent():
+#            text = self._script.appendString(
+#                text, self._script.getDisplayedLabel(obj))
+#            text = self._script.appendString(
+#                text, self._script.getDisplayedText(obj))
+#        else:
+#            isLabelled = False
+#            relationSet = obj.getRelationSet()
+#            if relationSet:
+#                for relation in relationSet:
+#                    if relation.getRelationType() \
+#                        == pyatspi.RELATION_LABELLED_BY:
+#                        isLabelled = True
+#                        break
+#
+#            if not isLabelled and obj.name and len(obj.name):
+#                text = self._script.appendString(text, obj.name)
+#
+#        text = self._script.appendString(text, self._getTextForRole(obj))
+#
+#        indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
+#
+#        regions = []
+#        componentRegion = braille.Component(
+#            obj, text,
+#            indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
+#        regions.append(componentRegion)
+#
+#        return [regions, componentRegion]
+#
+#    def _getBrailleRegionsForText(self, obj):
+#        """Gets text to be displayed for the entry of an autocomplete box.
+#
+#        Arguments:
+#        - obj: an Accessible
+#
+#        Returns a list where the first element is a list of Regions to
+#        display and the second element is the Region which should get
+#        focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForText", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForText(self, obj)
+#        
+#        parent = obj.parent
+#        if parent.getRole() != pyatspi.ROLE_AUTOCOMPLETE:
+#            return braillegenerator.BrailleGenerator._getBrailleRegionsForText(
+#                self, obj)
+#
+#        regions = []
+#
+#        # This is the main difference between this class and the default
+#        # class - we'll give this thing a name here, and we'll make it
+#        # be the name of the autocomplete.
+#        #
+#        label = self._script.getDisplayedLabel(parent)
+#        if not label or not len(label):
+#            label = parent.name
+#
+#        textRegion = braille.Text(obj, label, settings.brailleEOLIndicator)
+#        regions.append(textRegion)
+#
+#        if settings.presentReadOnlyText \
+#           and self._script.isReadOnlyTextArea(obj):
+#            regions.append(braille.Region(" " \
+#                                          + settings.brailleReadOnlyString))
+#
+#        return [regions, textRegion]
+#
+#    def _getBrailleRegionsForComboBox(self, obj):
+#        """Get the braille for a combo box.  If the combo box already has
+#        focus, then only the selection is displayed.
+#
+#        Arguments:
+#        - obj: the combo box
+#
+#        Returns a list where the first element is a list of Regions to display
+#        and the second element is the Region which should get focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForComboBox", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                     _getBrailleRegionsForComboBox(self, obj)
+#        
+#        regions = []
+#
+#        label = self._script.getDisplayedLabel(obj)
+#        if not label and not self._script.inDocumentContent():
+#            label = obj.name
+#
+#        focusedRegionIndex = 0
+#        if label and len(label):
+#            regions.append(braille.Region(label + " "))
+#            focusedRegionIndex = 1
+#
+#        # With Gecko, a combo box has a menu as a child.  The text being
+#        # displayed for the combo box can be obtained via the selected
+#        # menu item.
+#        #
+#        menu = None
+#        for child in obj:
+#            if child.getRole() == pyatspi.ROLE_MENU:
+#                menu = child
+#                break
+#        if menu:
+#            child = None
+#            try:
+#                # This should work...
+#                #
+#                child = menu.querySelection().getSelectedChild(0)
+#                if not child:
+#                    # It's probably a Gtk combo box.
+#                    #
+#                    return braillegenerator.BrailleGenerator.\
+#                        _getBrailleRegionsForComboBox(self, obj)
+#            except:
+#                # But just in case, we'll fall back on this.
+#                # [[[TODO - JD: Will we ever have a case where the first
+#                # fails, but this will succeed???]]]
+#                #
+#                for item in menu:
+#                    if item.getState().contains(pyatspi.STATE_SELECTED):
+#                        child = item
+#                        break
+#            if child:
+#                regions.append(braille.Region(child.name))
+#
+#        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+#            regions.append(braille.Region(
+#                " " + rolenames.getBrailleForRoleName(obj)))
+#
+#        # Things may not have gone as expected above, so we'll do some
+#        # defensive programming to make sure we don't get an index out
+#        # of bounds.
+#        #
+#        if focusedRegionIndex >= len(regions):
+#            focusedRegionIndex = 0
+#
+#        if obj.getState().contains(pyatspi.STATE_FOCUSED):
+#            focusedRegion = regions[focusedRegionIndex]
+#        else:
+#            focusedRegion = None
+#
+#        # [[[TODO: WDW - perhaps if a text area was created, we should
+#        # give focus to it.]]]
+#        #
+#        return [regions, focusedRegion]
+#
+#    def _getBrailleRegionsForMenuItem(self, obj):
+#        """Get the braille for a menu item.
+#
+#        Arguments:
+#        - obj: the menu item
+#
+#        Returns a list where the first element is a list of Regions to display
+#        and the second element is the Region which should get focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForMenuItem", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                     _getBrailleRegionsForMenuItem(self, obj)
+#        
+#        if not self._script.inDocumentContent():
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForMenuItem(self, obj)
+#
+#        regions = []
+#
+#        # Displaying "menu item" for a combo box can confuse users. Therefore,
+#        # display the combo box role instead.  Also, only do it if the menu
+#        # item is not focused (if the menu item is focused, it means we're
+#        # navigating in the combo box).
+#        #
+#        label = self._script.getDisplayedLabel(obj)
+#        focusedRegionIndex = 0
+#        if label and len(label):
+#            regions.append(braille.Region(label + " "))
+#            focusedRegionIndex = 1
+#        regions.append(braille.Region(obj.name))
+#
+#        comboBox = \
+#                 self._script.getAncestor(obj,
+#                                          [pyatspi.ROLE_COMBO_BOX],
+#                                          [pyatspi.ROLE_DOCUMENT_FRAME])
+#        if comboBox \
+#           and not obj.getState().contains(pyatspi.STATE_FOCUSED) \
+#           and (settings.brailleVerbosityLevel == \
+#                settings.VERBOSITY_LEVEL_VERBOSE):
+#            regions.append(braille.Region(
+#                " " + rolenames.getBrailleForRoleName(comboBox)))
+#
+#        return [regions, regions[focusedRegionIndex]]
+#
+#    def _getBrailleRegionsForList(self, obj):
+#        """Get the braille for a list in a form.  If the list already has
+#        focus, then only the selection is displayed.
+#
+#        Arguments:
+#        - obj: the list
+#
+#        Returns a list where the first element is a list of Regions to display
+#        and the second element is the Region which should get focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForList", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForList(self, obj)
+#        
+#        if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForList(self, obj)
+#
+#        regions = []
+#        focusedRegionIndex = 0
+#
+#        if obj.getState().contains(pyatspi.STATE_FOCUSED):
+#            label = self._script.getDisplayedLabel(obj)
+#            if not label:
+#                label = obj.name
+#
+#            if label and len(label):
+#                regions.append(braille.Region(label + " "))
+#                focusedRegionIndex = 1
+#
+#            item = None
+#            selection = obj.querySelection()
+#            for i in xrange(obj.childCount):
+#                if selection.isChildSelected(i):
+#                    item = obj[i]
+#                    break
+#            if not item:
+#                item = obj[0]
+#            regions.append(braille.Region(item.name + " "))
+#        elif obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+#            focusedRegionIndex = -1
+#
+#        if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+#            regions.append(braille.Region(
+#                rolenames.getBrailleForRoleName(obj)))
+#
+#        if focusedRegionIndex > -1:
+#            focusedRegion = regions[focusedRegionIndex]
+#        else:
+#            focusedRegion = None
+#
+#        return [regions, focusedRegion]
+#
+#    def _getBrailleRegionsForImage(self, obj):
+#        """Get the braille regions for an image.
+#
+#        Arguments:
+#        - obj: an Accessible
+#
+#        Returns a list where the first element is a list of Regions to
+#        display and the second element is the Region which should get
+#        focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForImage", obj)
+#
+#        # Treat ARIA widgets like default.py widgets
+#        #
+#        if self._script.isAriaWidget(obj):
+#            return braillegenerator.BrailleGenerator.\
+#                       _getBrailleRegionsForImage(self, obj)
+#        
+#        text = ""
+#        text = self._script.appendString(text, 
+#                                         self._script.getDisplayedLabel(obj))
+#        text = self._script.appendString(text,
+#                                         self._script.getDisplayedText(obj))
+#        link = self._script.getAncestor(obj, 
+#                                        [pyatspi.ROLE_LINK],
+#                                        [pyatspi.ROLE_DOCUMENT_FRAME])
+#        if link:
+#            if len(text) == 0:
+#                # If there's no text for the link, expose part of the
+#                # link to the user if the image is in a link.
+#                #
+#                basename = self._script.getLinkBasename(link)
+#                if basename:
+#                    text = basename
+#
+#        text = self._script.appendString(text,
+#                                         self._script.getTextForValue(obj))
+#        text = self._script.appendString(text, self._getTextForRole(obj))
+#
+#        regions = []
+#        if link:
+#            region = braille.Link(obj, text)
+#        else:
+#            region = braille.Component(obj, text)
+#        regions.append(region)
+#
+#        return [regions, region]
+#
+#    def _getBrailleRegionsForLink(self, obj):
+#        """Gets text to be displayed for a link.
+#
+#        Arguments:
+#        - obj: an Accessible
+#
+#        Returns a list where the first element is a list of Regions to
+#        display and the second element is the Region which should get
+#        focus.
+#        """
+#
+#        self._debugGenerator("Gecko._getBrailleRegionsForLink", obj)
+#
+#        text, caretOffset, startOffset = self._script.getTextLineAtCaret(obj)
+#        if not len(text):
+#            text = self._script.getDisplayedText(obj)
+#
+#        # If there's no text for the link, expose part of the
+#        # URI to the user.
+#        #
+#        if len(text) == 0:
+#            basename = self._script.getLinkBasename(obj)
+#            if basename:
+#                text = basename
+#
+#        regions = []
+#        linkRegion = braille.Link(obj, text, caretOffset - startOffset)
+#        regions.append(linkRegion)
+#
+#        return [regions, linkRegion]
diff --git a/src/orca/scripts/toolkits/Gecko/formatting.py b/src/orca/scripts/toolkits/Gecko/formatting.py
index 9232c15..9d3c15b 100644
--- a/src/orca/scripts/toolkits/Gecko/formatting.py
+++ b/src/orca/scripts/toolkits/Gecko/formatting.py
@@ -69,6 +69,32 @@ formatting = {
         pyatspi.ROLE_TABLE: {
             'unfocused': '[]'
             },
+    },
+    'braille': {
+        'prefix': {
+            'focused':   '[]',
+            'unfocused': '[]'
+        },
+        'suffix': {
+            'focused':   '[]',
+            'unfocused': '[]'
+        },
+        # [[[TODO: WDW - we're doing very little here.  The goal for
+        # autocomplete boxes at the moment is that their children (e.g.,
+        # a text area, a menu, etc., do all the interactive work and
+        # the autocomplete acts as more of a container.]]]
+        #
+        pyatspi.ROLE_AUTOCOMPLETE: {
+            'focused':   '[Component(obj, asString(roleName))]',
+            'unfocused': '[Component(obj, asString(roleName))]'
+        },
+        # [[[TODO: WDW - yikes!  We need more parameters to send to
+        # the Link constructor.]]]
+        #
+        pyatspi.ROLE_LINK: {
+            'focused':   '[Link(obj, asString(displayedText))]',
+            'unfocused': '[Link(obj, asString(displayedText))]'
+        }
     }
 }
 
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index d4d4501..29a5cd9 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -2266,7 +2266,7 @@ class Script(default.Script):
                            pyatspi.ROLE_PASSWORD_TEXT,
                            pyatspi.ROLE_LINK]:
                 [regions, fRegion] = \
-                          self.brailleGenerator.getBrailleRegions(obj)
+                          self.brailleGenerator.generateBraille(obj)
 
                 if isFocusedObj:
                     focusedRegion = fRegion



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]