[orca/570658] Initial playing with format-driven braille generator



commit f8ece49c9c7ff5aedcd8f2d797f78541d734a591
Author: Willie Walker <william walker sun com>
Date:   Wed Jun 24 13:17:28 2009 -0400

    Initial playing with format-driven braille generator

 po/POTFILES.in                |    1 +
 src/orca/Makefile.am          |    1 +
 src/orca/braille_generator.py |  140 +++++++++++++++++++++++++++++++++++++++++
 src/orca/braillegenerator.py  |    9 +++
 src/orca/formatting.py        |   24 +++++++
 src/orca/generator.py         |   33 ++++++++++
 src/orca/speech_generator.py  |   34 ----------
 7 files changed, 208 insertions(+), 34 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 30711ab..f0907a8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,7 @@
 orca.desktop.in
 src/orca/app_gui_prefs.py
 src/orca/bookmarks.py
+src/orca/braille_generator.py
 src/orca/braillegenerator.py
 src/orca/braille.py
 src/orca/chnames.py
diff --git a/src/orca/Makefile.am b/src/orca/Makefile.am
index 2f980e7..cfd89ae 100644
--- a/src/orca/Makefile.am
+++ b/src/orca/Makefile.am
@@ -14,6 +14,7 @@ orca_python_PYTHON = \
 	bookmarks.py \
 	braille.py \
 	braillegenerator.py \
+	braille_generator.py \
 	brlmon.py \
 	chnames.py \
 	dbusserver.py \
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
new file mode 100644
index 0000000..45e1323
--- /dev/null
+++ b/src/orca/braille_generator.py
@@ -0,0 +1,140 @@
+# Orca
+#
+# 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
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA  02110-1301 USA.
+
+"""Utilities for obtaining braille presentations for objects."""
+
+__id__        = "$Id$"
+__version__   = "$Revision$"
+__date__      = "$Date$"
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
+__license__   = "LGPL"
+
+import pyatspi
+
+import braille
+import generator
+import rolenames
+import settings
+
+class Space:
+    """A dummy class to indicate we want to insert a space into an
+    utterance, but only if there is text prior to the space."""
+    def __init__(self, delimiter=" "):
+        self.delimiter = delimiter
+
+SPACE = [Space()]
+
+class BrailleGenerator(generator.Generator):
+    """Takes accessible objects and produces a list of braille Regions
+    for those objects.  See the getBrailleRegions method, which is the
+    primary entry point.  Subclasses can feel free to override/extend
+    the brailleGenerators instance field as they see fit."""
+
+    SKIP_CONTEXT_ROLES = (pyatspi.ROLE_MENU,
+                          pyatspi.ROLE_MENU_BAR,
+                          pyatspi.ROLE_PAGE_TAB_LIST,
+                          pyatspi.ROLE_COMBO_BOX)
+
+    def __init__(self, script):
+        generator.Generator.__init__(self, script, "braille")
+
+    def _addGlobals(self, globalsDict):
+        """Other things to make available from the formatting string.
+        """
+        generator.Generator._addGlobals(self, globalsDict)
+        globalsDict['space'] = self.space
+        globalsDict['Component'] = braille.Component
+        globalsDict['asString'] = self.asString
+
+    def generateBraille(self, obj, **args):
+        result = self.generate(obj, **args)
+        for element in result:
+            if isinstance(element, braille.Region):
+                print "FOO", element.string, element.cursorOffset
+
+    #####################################################################
+    #                                                                   #
+    # Name, role, and label information                                 #
+    #                                                                   #
+    #####################################################################
+
+    def _generateRoleName(self, obj, **args):
+        """Returns the role name for the object in an array of strings (and
+        possibly voice and audio specifications), with the exception
+        that the pyatspi.ROLE_UNKNOWN role will yield an empty array.
+        Note that a 'role' attribute in args will override the
+        accessible role of the obj.
+        """
+        result = []
+        role = args.get('role', obj.getRole())
+        if (settings.brailleVerbosityLevel \
+            == settings.VERBOSITY_LEVEL_VERBOSE)\
+           and (role != pyatspi.ROLE_UNKNOWN):
+            result.append(rolenames.getBrailleForRoleName(obj, role))
+        return result
+
+    #####################################################################
+    #                                                                   #
+    # Keyboard shortcut information                                     #
+    #                                                                   #
+    #####################################################################
+
+    def _generateAccelerator(self, obj, **args):
+        """Returns an array of strings (and possibly voice and audio
+        specifications) that represent the accelerator for the object,
+        or an empty array if no accelerator can be found.
+        """
+        result = []
+        [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
+        if accelerator:
+            result.append("(" + accelerator + ")")
+        return result
+
+    #####################################################################
+    #                                                                   #
+    # Other things for spacing                                          #
+    #                                                                   #
+    #####################################################################
+
+    def space(self, delimiter=" "):
+        if delimiter == " ":
+            return SPACE
+        else:
+            return [Space(delimiter)]
+
+    def asString(self, content):
+        combined = ""
+        prior = None
+        if isinstance(content, basestring):
+            combined = content
+        elif content and isinstance(content, list):
+            # Strip off leading and trailing spaces.
+            #
+            while content and isinstance(content[0], Space):
+                content = content[1:]
+            while content and isinstance(content[-1], Space):
+                content = content[0:-1]
+            for element in content:
+                if isinstance(element, Space) and prior:
+                    combined += element.delimiter
+                    prior = None
+                else:
+                    prior = self.asString(element)
+                    combined += prior
+        return combined
diff --git a/src/orca/braillegenerator.py b/src/orca/braillegenerator.py
index baef9d3..31dbfd6 100644
--- a/src/orca/braillegenerator.py
+++ b/src/orca/braillegenerator.py
@@ -39,6 +39,8 @@ import settings
 from orca_i18n import _                     # for gettext support
 from orca_i18n import ngettext              # for ngettext support
 
+EXPERIMENTAL = True
+
 class BrailleGenerator:
     """Takes accessible objects and produces a list of braille Regions
     for those objects.  See the getBrailleRegions method, which is the
@@ -157,6 +159,10 @@ class BrailleGenerator:
         self.brailleGenerators[pyatspi.ROLE_WINDOW]              = \
              self._getBrailleRegionsForWindow
 
+        if EXPERIMENTAL:
+            import braille_generator
+            self._experimental = braille_generator.BrailleGenerator(script)
+
     def _getTextForAccelerator(self, obj):
         """Returns a string to be displayed that describes the keyboard
         accelerator (and possibly shortcut) for the given object.
@@ -1647,6 +1653,9 @@ class BrailleGenerator:
         focus.
         """
 
+        if EXPERIMENTAL:
+            self._experimental.generateBraille(obj)
+
         # If we want to group the children, first see if obj is a child of
         # something we like to group.  If so, then reset the obj to the obj's
         # parent.  If not, see if the obj is the container of things we like
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 4ba9ec3..3f67c2c 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -272,6 +272,30 @@ formatting = {
             'unfocused': 'labelAndName',
             'basicWhereAmI': 'labelAndName'
             },
+    },
+
+    'braille': {
+        'prefix': {
+            'unfocused': '[]',
+            },
+        'suffix': {
+            'unfocused': '[]',
+            },
+        'default': {
+            'unfocused': '[Component(obj, asString(label + space() + displayedText + space() + value + space() + roleName + space() + required))]',
+            },
+        pyatspi.ROLE_ANIMATION: {
+            'unfocused': '[Component(obj, asString(label + space() + displayedText + space() + roleName + space(": ") + description))]',
+            },
+        pyatspi.ROLE_CHECK_BOX: {
+            'unfocused': '[Component(obj, asString(label + space() + displayedText + space() + roleName), indicator="".join(checkedState))]'
+            },
+        pyatspi.ROLE_CHECK_MENU_ITEM: {
+            'unfocused': '[Component(obj, asString(label + space() + displayedText + space() + roleName + space() + availability + accelerator), indicator="".join(checkedState))]'
+            },
+        pyatspi.ROLE_MENU_ITEM: {
+            'unfocused': '[Component(obj, asString(label + space() + displayedText + space() + availability + accelerator), indicator="".join(menuItemCheckedState))]'
+            },
     }
 }
 
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 164b7ad..2397587 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -249,6 +249,39 @@ class Generator:
     #                                                                   #
     #####################################################################
 
+    def _generateName(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represent the name of the object.  If the object is directly
+        displaying any text, that text will be treated as the name.
+        Otherwise, the accessible name of the object will be used.  If
+        there is no accessible name, then the description of the
+        object will be used.  This method will return an empty array
+        if nothing can be found.  [[[WDW - I wonder if we should just
+        have _generateName, _generateDescription,
+        _generateDisplayedText, etc., that don't do any fallback.
+        Then, we can allow the formatting to do the fallback (e.g.,
+        'displayedText or name or description'). [[[JD to WDW - I
+        needed a _generateDescription for whereAmI. :-) See below.
+        """
+        result = []
+        name = self._script.getDisplayedText(obj)
+        if name:
+            result.append(name)
+        elif obj.description:
+            result.append(obj.description)
+        return result
+
+    def _generateDescription(self, obj, **args):
+        """Returns an array of strings fo use by speech and braille that
+        represent the description of the object, if that description
+        is different from that of the name and label.
+        """
+        result = []
+        label = self._script.getDisplayedLabel(obj)
+        if obj.description and not obj.description in [obj.name, label]:
+            result.append(obj.description)
+        return result
+
     def _generateLabel(self, obj, **args):
         """Returns the label for an object as an array of strings for use by
         speech and braille.  The label is determined by the
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 318f6da..8be47ab 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -89,40 +89,6 @@ class SpeechGenerator(generator.Generator):
     #                                                                   #
     #####################################################################
 
-    def _generateName(self, obj, **args):
-        """Returns an array of strings (and possibly voice and audio
-        specifications) that represent the name of the object.  If the
-        object is directly displaying any text, that text will be
-        treated as the name.  Otherwise, the accessible name of the
-        object will be used.  If there is no accessible name, then the
-        description of the object will be used.  This method will
-        return an empty array if nothing can be found.  [[[WDW - I
-        wonder if we should just have _generateName, _generateDescription,
-        _generateDisplayedText, etc., that don't do any fallback.  Then, we
-        can allow the formatting to do the fallback (e.g.,
-        'displayedText or name or description'). [[[JD to WDW - I needed
-        a _generateDescription for whereAmI. :-) See below.
-        """
-        result = []
-        name = self._script.getDisplayedText(obj)
-        if name:
-            result.append(name)
-        elif obj.description:
-            result.append(obj.description)
-        return result
-
-    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.
-        """
-        result = []
-        label = self._script.getDisplayedLabel(obj)
-        if obj.description and not obj.description in [obj.name, label]:
-            result.append(obj.description)
-        return result
-
     def _generateTextRole(self, obj, **args):
         """A convenience method to prevent the pyatspi.ROLE_PARAGRAPH role
         from being spoken. In the case of a pyatspi.ROLE_PARAGRAPH



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