[orca/570658] Initial playing with format-driven braille generator
- From: William Walker <wwalker src gnome org>
- To: svn-commits-list gnome org
- Subject: [orca/570658] Initial playing with format-driven braille generator
- Date: Wed, 24 Jun 2009 17:18:20 +0000 (UTC)
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]