[orca/570658] More work on braille generator
- From: William Walker <wwalker src gnome org>
- To: svn-commits-list gnome org
- Subject: [orca/570658] More work on braille generator
- Date: Sat, 27 Jun 2009 10:40:50 +0000 (UTC)
commit 8d18d21be4a19976eb582247bb8aa32e5793763d
Author: Willie Walker <william walker sun com>
Date: Sat Jun 27 06:39:09 2009 -0400
More work on braille generator
Fixed a lot with row/column headers, text context, tree/list level, etc.
Comboboxes and spin buttons still need work (the tests are failing).
src/orca/braille.py | 1 -
src/orca/braille_generator.py | 34 +++++++++++++---
src/orca/default.py | 33 +++++++++++++++-
src/orca/formatting.py | 50 +++++++++++++++++--------
src/orca/generator.py | 30 +++++++++++++++
src/orca/settings.py | 17 ++++++++-
src/orca/speech_generator.py | 20 ----------
test/keystrokes/gtk-demo/role_radio_button.py | 14 +++---
8 files changed, 144 insertions(+), 55 deletions(-)
---
diff --git a/src/orca/braille.py b/src/orca/braille.py
index 63d08fc..cdb29e8 100644
--- a/src/orca/braille.py
+++ b/src/orca/braille.py
@@ -1120,7 +1120,6 @@ def refresh(panToCursor=True, targetCursorCell=0, getLinkMask=True):
cursorCell += 1 # Normalize to 1-based offset
logLine = "BRAILLE LINE: '%s'" % string
- print logLine
debug.println(debug.LEVEL_INFO, logLine)
log.info(logLine.encode("UTF-8"))
logLine = " VISIBLE: '%s', cursor=%d" % \
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index 2dd83eb..033c669 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -73,13 +73,13 @@ class BrailleGenerator(generator.Generator):
args['formatType'] = 'focused'
result = self.generate(obj, **args)
- print "RESULTS:"
- for region in result:
- if isinstance(region, (braille.Component, braille.Text)) \
- and region.accessible == obj:
- print " (*)", region
- else:
- print " ", region
+ #print "RESULTS:"
+ #for region in result:
+ # if isinstance(region, (braille.Component, braille.Text)) \
+ # and region.accessible == obj:
+ # print " (*)", region
+ # else:
+ # print " ", region
# We guess at the focused region. It's going to be a
# Component or Text region whose accessible is the same
@@ -259,6 +259,26 @@ class BrailleGenerator(generator.Generator):
result.append(textObj)
return result
+ def _generateIncludeContext(self, obj, **args):
+ """Returns True or False to indicate whether context should be
+ included or not.
+ """
+ # For multiline text areas, we only show the context if we
+ # are on the very first line. Otherwise, we show only the
+ # line.
+ #
+ include = True
+ try:
+ text = obj.queryText()
+ except NotImplementedError:
+ text = None
+ if text and self._script.isTextArea(obj):
+ [lineString, startOffset, endOffset] = text.getTextAtOffset(
+ text.caretOffset,
+ pyatspi.TEXT_BOUNDARY_LINE_START)
+ include = startOffset == 0
+ return include
+
#####################################################################
# #
# Other things for spacing #
diff --git a/src/orca/default.py b/src/orca/default.py
index 4454776..5380bfd 100644
--- a/src/orca/default.py
+++ b/src/orca/default.py
@@ -75,6 +75,7 @@ class Script(script.Script):
DISPLAYED_LABEL = 'displayedLabel'
DISPLAYED_TEXT = 'displayedText'
KEY_BINDING = 'keyBinding'
+ NESTING_LEVEL = 'nestingLevel'
NODE_LEVEL = 'nodeLevel'
def __init__(self, app):
@@ -6950,6 +6951,32 @@ class Script(script.Script):
return [content.encode("UTF-8"), text.caretOffset, startOffset]
+ def getNestingLevel(self, obj):
+ """Determines the nesting level of this object in a list. If this
+ object is not in a list relation, then 0 will be returned.
+
+ Arguments:
+ -obj: the Accessible object
+ """
+
+ if not obj:
+ return 0
+
+ try:
+ return self.generatorCache[self.NESTING_LEVEL][obj]
+ except:
+ if not self.generatorCache.has_key(self.NESTING_LEVEL):
+ self.generatorCache[self.NESTING_LEVEL] = {}
+
+ nestingLevel = 0
+ parent = obj.parent
+ while parent.parent.getRole() == pyatspi.ROLE_LIST:
+ nestingLevel += 1
+ parent = parent.parent
+
+ self.generatorCache[self.NESTING_LEVEL][obj] = nestingLevel
+ return self.generatorCache[self.NESTING_LEVEL][obj]
+
def getNodeLevel(self, obj):
"""Determines the node level of this object if it is in a tree
relation, with 0 being the top level node. If this object is
@@ -6959,15 +6986,15 @@ class Script(script.Script):
-obj: the Accessible object
"""
+ if not obj:
+ return -1
+
try:
return self.generatorCache[self.NODE_LEVEL][obj]
except:
if not self.generatorCache.has_key(self.NODE_LEVEL):
self.generatorCache[self.NODE_LEVEL] = {}
- if not obj:
- return -1
-
nodes = []
node = obj
done = False
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 5bef7b5..b22cc30 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -59,6 +59,7 @@ formatting = {
'togglebutton' : settings.speechToggleButtonIndicators,
'expansion' : settings.speechExpansionIndicators,
'nodelevel' : settings.speechNodeLevelString,
+ 'nestinglevel' : settings.speechNestingLevelString,
'multiselect' : settings.speechMultiSelectString,
},
'braille' : {
@@ -71,6 +72,7 @@ formatting = {
'togglebutton' : settings.brailleToggleButtonIndicators,
'expansion' : settings.brailleExpansionIndicators,
'nodelevel' : settings.brailleNodeLevelString,
+ 'nestinglevel' : settings.brailleNestingLevelString,
},
},
@@ -301,7 +303,6 @@ formatting = {
},
},
-
####################################################################
# #
# Formatting for braille. #
@@ -310,16 +311,30 @@ formatting = {
'braille': {
'prefix': {
- 'focused': 'ancestors\
- + (rowHeader and [Region(" " + asString(rowHeader))])\
- + (columnHeader and [Region(" " + asString(columnHeader))])\
- + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
- + [Region(" ")]',
- 'unfocused': 'ancestors\
- + (rowHeader and [Region(" " + asString(rowHeader))])\
- + (columnHeader and [Region(" " + asString(columnHeader))])\
- + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
- + [Region(" ")]',
+# 'focused': 'ancestors\
+# + (rowHeader and [Region(" " + asString(rowHeader))])\
+# + (columnHeader and [Region(" " + asString(columnHeader))])\
+# + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+# + [Region(" ")]',
+# 'unfocused': 'ancestors\
+# + (rowHeader and [Region(" " + asString(rowHeader))])\
+# + (columnHeader and [Region(" " + asString(columnHeader))])\
+# + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+# + [Region(" ")]',
+ 'focused': '(includeContext\
+ and (ancestors\
+ + (rowHeader and [Region(" " + asString(rowHeader))])\
+ + (columnHeader and [Region(" " + asString(columnHeader))])\
+ + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+ + [Region(" ")])\
+ or [])',
+ 'unfocused': '(includeContext\
+ and (ancestors\
+ + (rowHeader and [Region(" " + asString(rowHeader))])\
+ + (columnHeader and [Region(" " + asString(columnHeader))])\
+ + (radioButtonGroup and [Region(" " + asString(radioButtonGroup))])\
+ + [Region(" ")])\
+ or [])',
},
'suffix': {
'focused': '(nodeLevel and [Region(" " + asString(nodeLevel))])',
@@ -349,9 +364,10 @@ formatting = {
},
#pyatspi.ROLE_COLUMN_HEADER: 'default'
pyatspi.ROLE_COMBO_BOX: {
- 'unfocused': '[label and Region(asString(label) + " "),\
- (comboBoxTextObj and Text(comboBoxTextObj[0])) or Component(obj, asString(displayedText)),\
- Region(" " + asString(roleName))]'
+ 'unfocused': '(label and [Region(asString(label) + " ")])\
+ + (comboBoxTextObj and [Text(comboBoxTextObj[0])])\
+ or [Component(obj, asString(displayedText)),\
+ Region(" " + asString(roleName))]'
},
#pyatspi.ROLE_DESKTOP_ICON: 'default'
#pyatspi.ROLE_DIAL: 'default'
@@ -379,9 +395,11 @@ formatting = {
#pyatspi.ROLE_LIST: 'default'
pyatspi.ROLE_LIST_ITEM: {
'focused': '[Component(obj,\
- asString(label + displayedText + expandableState + roleName + availability) + asString(accelerator))]',
+ asString(label + displayedText + expandableState + roleName + availability) + asString(accelerator))]\
+ + nestingLevel',
'unfocused': '[Component(obj,\
- asString(label + displayedText + expandableState))]',
+ asString(label + displayedText + expandableState))]\
+ + nestingLevel',
},
pyatspi.ROLE_MENU: {
'focused': '[Component(obj,\
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 27e1539..a504a87 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -533,6 +533,14 @@ class Generator:
it exists. Otherwise, an empty array is returned.
"""
result = []
+
+ # Do not return yourself as a header.
+ #
+ role = args.get('role', obj.getRole())
+ if role in [pyatspi.ROLE_ROW_HEADER,
+ pyatspi.ROLE_TABLE_ROW_HEADER]:
+ return result
+
if not args.get('mode', None):
args['mode'] = self._mode
try:
@@ -588,6 +596,14 @@ class Generator:
is returned.
"""
result = []
+
+ # Do not return yourself as a header.
+ #
+ role = args.get('role', obj.getRole())
+ if role in [pyatspi.ROLE_COLUMN_HEADER,
+ pyatspi.ROLE_TABLE_COLUMN_HEADER]:
+ return result
+
try:
table = obj.parent.queryTable()
except:
@@ -899,6 +915,20 @@ class Generator:
pass
return result
+ def _generateNestingLevel(self, obj, **args):
+ """Returns an array of strings for use by speech and braille that
+ represent the nesting level of an object in a list.
+ """
+ result = []
+ if not args.get('mode', None):
+ args['mode'] = self._mode
+ args['stringType'] = 'nestinglevel'
+ nestingLevel = self._script.getNestingLevel(obj)
+ if nestingLevel:
+ result.append(self._script.formatting.getString(**args)\
+ % nestingLevel)
+ return result
+
def _generateRadioButtonGroup(self, obj, **args):
"""Returns an array of strings for use by speech and braille that
represents the radio button group label for the object, or an
diff --git a/src/orca/settings.py b/src/orca/settings.py
index 9fbf62b..8048d82 100644
--- a/src/orca/settings.py
+++ b/src/orca/settings.py
@@ -1257,6 +1257,13 @@ speechMultiSelectString = _("multi-select")
#
speechNodeLevelString = _("tree level %d")
+# Translators: this represents a list item in a document.
+# The nesting level is how 'deep' the item is (e.g., a
+# level of 2 represents a list item inside a list that's
+# inside another list). This is meant to be spoken.
+#
+speechNestingLevelString = _("Nesting level %d")
+
# string to indicate end of printed line for braille displays:
#
disableBrailleEOL = False
@@ -1297,7 +1304,15 @@ brailleExpansionIndicators = [_("collapsed"), _("expanded")]
# view (i.e., how many ancestors a node has). It is meant to
# be presented on a braille display.
#
-brailleNodeLevelString = _("LEVEL %d")
+brailleNodeLevelString = _("TREE LEVEL %d")
+
+# Translators: this represents a list item in a document.
+# The nesting level is how 'deep' the item is (e.g., a
+# level of 2 represents a list item inside a list that's
+# inside another list). It is meant to be presented on
+# the braille display.
+#
+brailleNestingLevelString = _("LEVEL %d")
# String for delimiters between table cells
#
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 1162d52..4b347d8 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -1306,26 +1306,6 @@ class SpeechGenerator(generator.Generator):
return result
- def _generateNestingLevel(self, obj, **args):
- """Returns an array of strings (and possibly voice and audio
- specifications) that represent the nesting level of an object
- in a list.
- """
- result = []
- nestingLevel = 0
- parent = obj.parent
- while parent.parent.getRole() == pyatspi.ROLE_LIST:
- nestingLevel += 1
- parent = parent.parent
- if nestingLevel:
- # Translators: this represents a list item in a document.
- # The nesting level is how 'deep' the item is (e.g., a
- # level of 2 represents a list item inside a list that's
- # inside another list).
- #
- result.append(_("Nesting level %d") % nestingLevel)
- return result
-
def _generateDefaultButton(self, obj, **args):
"""Returns an array of strings (and possibly voice and audio
specifications) that represent the default button in a dialog.
diff --git a/test/keystrokes/gtk-demo/role_radio_button.py b/test/keystrokes/gtk-demo/role_radio_button.py
index 2b5d929..162555e 100644
--- a/test/keystrokes/gtk-demo/role_radio_button.py
+++ b/test/keystrokes/gtk-demo/role_radio_button.py
@@ -33,7 +33,7 @@ sequence.append(KeyComboAction("<Alt>a", 500))
sequence.append(WaitForFocus("All Pages", acc_role=pyatspi.ROLE_RADIO_BUTTON))
sequence.append(utils.AssertPresentationAction(
"All Pages radio button",
- ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+ ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler Range &=y All Pages RadioButton'",
" VISIBLE: '&=y All Pages RadioButton', cursor=1",
"SPEECH OUTPUT: 'Range All Pages selected radio button'"]))
@@ -45,9 +45,9 @@ sequence.append(KeyComboAction("KP_Enter"))
sequence.append(PauseAction(3000))
sequence.append(utils.AssertPresentationAction(
"All Pages radio button Where Am I",
- ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler &=y All Pages RadioButton'",
+ ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler Range &=y All Pages RadioButton'",
" VISIBLE: '&=y All Pages RadioButton', cursor=1",
- "SPEECH OUTPUT: 'Range All Pages radio button selected item 1 of 3.",
+ "SPEECH OUTPUT: 'Range All Pages radio button selected item 1 of 3.'",
"SPEECH OUTPUT: 'Alt a'"]))
########################################################################
@@ -67,7 +67,7 @@ sequence.append(WaitForFocus("Pages:", acc_role=pyatspi.ROLE_RADIO_BUTTON))
sequence.append(utils.AssertPresentationAction(
"Range radio button",
["KNOWN ISSUE - the radio button should be presented as selected.",
- "BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler & y Pages: RadioButton'",
+ "BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler Range & y Pages: RadioButton'",
" VISIBLE: '& y Pages: RadioButton', cursor=1",
"SPEECH OUTPUT: 'Pages: not selected radio button'"]))
@@ -79,9 +79,9 @@ sequence.append(KeyComboAction("KP_Enter"))
sequence.append(PauseAction(3000))
sequence.append(utils.AssertPresentationAction(
"Range radio button Where Am I",
- ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler &=y Pages: RadioButton'",
+ ["BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler Range &=y Pages: RadioButton'",
" VISIBLE: '&=y Pages: RadioButton', cursor=1",
- "SPEECH OUTPUT: 'Range Pages: radio button selected item 3 of 3.",
+ "SPEECH OUTPUT: 'Range Pages: radio button selected item 3 of 3.'",
"SPEECH OUTPUT: 'Alt e'"]))
########################################################################
@@ -93,7 +93,7 @@ sequence.append(WaitForFocus("All Pages", acc_role=pyatspi.ROLE_RADIO_BUTTON))
sequence.append(utils.AssertPresentationAction(
"All Pages radio button",
["KNOWN ISSUE - the radio button should be presented as selected.",
- "BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler & y All Pages RadioButton'",
+ "BRAILLE LINE: 'gtk-demo Application Print Dialog TabList General Page Range Filler Range & y All Pages RadioButton'",
" VISIBLE: '& y All Pages RadioButton', cursor=1",
"SPEECH OUTPUT: 'All Pages not selected radio button'"]))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]