[orca/570658] Move us over to the new speech generator, eliminating the old one.
- From: William Walker <wwalker src gnome org>
- To: svn-commits-list gnome org
- Subject: [orca/570658] Move us over to the new speech generator, eliminating the old one.
- Date: Thu, 14 May 2009 11:20:21 -0400 (EDT)
commit d278a8a8f196e60c7a1114bfb844f13ad814c07d
Author: Willie Walker <william walker sun com>
Date: Thu May 14 11:16:07 2009 -0400
Move us over to the new speech generator, eliminating the old one.
There is still work to be done:
1) All the SpeechGenerator subclasses need to be updated
2) Calls to getTutorial need to be replaced with additions
of 'tutorial' in formatting.py
3) Gecko's script.py:getACSS stuff should be moved to the generator
4) structural_navigation.py:_getVoice needs to be moved to the
generator
5) soffice's script.py code that deals with 'blank' needs to
make sure the assumption about utterances[0] is still valid
6) Speech context needs addressing
---
src/orca/Makefile.am | 1 -
src/orca/altspeechgenerator.py | 819 ---------
src/orca/bookmarks.py | 8 +-
src/orca/default.py | 24 +-
src/orca/liveregions.py | 10 +-
src/orca/mouse_review.py | 2 +-
src/orca/scripts/apps/Thunderbird/script.py | 4 +-
src/orca/scripts/apps/acroread.py | 6 +-
src/orca/scripts/apps/evolution/script.py | 20 +-
src/orca/scripts/apps/gcalctool/where_am_i.py | 2 +-
src/orca/scripts/apps/gedit/script.py | 4 +-
src/orca/scripts/apps/gnome-system-monitor.py | 2 +-
src/orca/scripts/apps/gnome-terminal.py | 2 +-
src/orca/scripts/apps/liferea.py | 2 +-
src/orca/scripts/apps/pidgin/where_am_i.py | 8 +-
src/orca/scripts/apps/soffice/script.py | 13 +-
src/orca/scripts/apps/soffice/where_am_i.py | 10 +-
src/orca/scripts/apps/yelp.py | 3 +-
src/orca/scripts/toolkits/Gecko/bookmarks.py | 2 +-
src/orca/scripts/toolkits/Gecko/script.py | 17 +-
src/orca/scripts/toolkits/Gecko/where_am_i.py | 2 +-
src/orca/speech.py | 136 +-
src/orca/speechgenerator.py | 2441 +++++++------------------
src/orca/structural_navigation.py | 2 +
src/orca/where_am_I.py | 54 +-
25 files changed, 794 insertions(+), 2800 deletions(-)
diff --git a/src/orca/Makefile.am b/src/orca/Makefile.am
index b4a026d..7aaff74 100644
--- a/src/orca/Makefile.am
+++ b/src/orca/Makefile.am
@@ -9,7 +9,6 @@ orca_pathdir=$(pyexecdir)
orca_python_PYTHON = \
__init__.py \
acss.py \
- altspeechgenerator.py \
app_gui_prefs.py \
app_prefs.py \
bookmarks.py \
diff --git a/src/orca/altspeechgenerator.py b/src/orca/altspeechgenerator.py
deleted file mode 100755
index 971fad0..0000000
--- a/src/orca/altspeechgenerator.py
+++ /dev/null
@@ -1,819 +0,0 @@
-# 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 speech utterances for objects. In general,
-there probably should be a singleton instance of the SpeechGenerator
-class."""
-
-__id__ = "$Id:$"
-__version__ = "$Revision:$"
-__date__ = "$Date:$"
-__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
-__license__ = "LGPL"
-
-import sys
-import traceback
-
-import debug
-import pyatspi
-import rolenames
-import settings
-
-from orca_i18n import _ # for gettext support
-from orca_i18n import ngettext # for ngettext support
-from orca_i18n import C_ # to provide qualified translatable strings
-
-def _formatExceptionInfo(maxTBlevel=5):
- cla, exc, trbk = sys.exc_info()
- excName = cla.__name__
- try:
- excArgs = exc.args
- except KeyError:
- excArgs = "<no args>"
- excTb = traceback.format_tb(trbk, maxTBlevel)
- return (excName, excArgs, excTb)
-
-def _overrideRole(newRole, args):
- oldRole = args.get('role', None)
- args['role'] = newRole
- return oldRole
-
-def _restoreRole(oldRole, args):
- if oldRole:
- args['role'] = oldRole
- else:
- del args['role']
-
-class AltSpeechGenerator:
- """Takes accessible objects and produces a string to speak for
- those objects. See the getSpeech method, which is the primary
- entry point. Subclasses can feel free to override/extend the
- speechGenerators instance field as they see fit."""
-
- def __init__(self, script):
- self._script = script
- self._methodsDict = {}
- for method in \
- filter(lambda z: callable(z),
- map(lambda y: getattr(self, y).__get__(self, self.__class__),
- filter(lambda x: x.startswith("_get"), dir(self)))):
- name = method.__name__[4:]
- name = name[0].lower() + name[1:]
- self._methodsDict[name] = method
-
- # Verify the formatting strings are OK. This is only
- # for verification and does not effect the function of
- # Orca at all.
- #
- # Populate the entire globals with empty arrays
- # for the results of all the legal method names.
- #
- methods = {}
- for key in self._methodsDict.keys():
- methods[key] = []
- methods["voice"] = self.voice
- methods["obj"] = None
- methods["role"] = None
- for roleKey in self._script.formatting["speech"]:
- for speechKey in ["focused", "unfocused"]:
- try:
- evalString = \
- self._script.formatting["speech"][roleKey][speechKey]
- except:
- continue
- else:
- if not evalString:
- # It's legal to have an empty string for speech.
- #
- continue
- while True:
- try:
- eval(evalString, methods)
- break
- except NameError:
- info = _formatExceptionInfo()
- arg = info[1][0]
- arg = arg.replace("name '", "")
- arg = arg.replace("' is not defined", "")
- if not self._methodsDict.has_key(arg):
- debug.printException(
- debug.LEVEL_SEVERE,
- "Unable to find function for '%s'\n" % arg)
- except:
- debug.printException(debug.LEVEL_SEVERE)
- debug.println(
- debug.LEVEL_SEVERE,
- "While processing '%s' '%s' '%s' '%s'" \
- % (roleKey, speechKey, evalString, methods))
- break
-
- #####################################################################
- # #
- # Name, role, and label information #
- # #
- #####################################################################
-
- def _getName(self, obj, **args):
- result = []
- name = self._script.getDisplayedText(obj)
- if name:
- result.append(name)
- elif obj.description:
- result.append(obj.description)
- return result
-
- def _getTextRole(self, obj, **args):
- result = []
- # pylint: disable-msg=W0142
- role = args.get('role', obj.getRole())
- if role != pyatspi.ROLE_PARAGRAPH:
- result.extend(self._getRoleName(obj, **args))
- return result
-
- def _getRoleName(self, obj, **args):
- result = []
- role = args.get('role', obj.getRole())
- if (role != pyatspi.ROLE_UNKNOWN):
- result.append(rolenames.getSpeechForRoleName(obj, role))
- return result
-
- def _getLabel(self, obj, **args):
- result = []
- label = self._script.getDisplayedLabel(obj)
- if label:
- result = [label]
- return result
-
- def _getLabelAndName(self, obj, **args):
- """Gets the label and the name if the name is different from the label.
- """
- # pylint: disable-msg=W0142
- result = []
- label = self._getLabel(obj, **args)
- name = self._getName(obj, **args)
- result.extend(label)
- if not len(label):
- result.extend(name)
- elif len(name) and name[0] != label[0]:
- result.extend(name)
- return result
-
- def _getLabelOrName(self, obj, **args):
- """Gets the label or the name if the label is not preset."""
- result = []
- # pylint: disable-msg=W0142
- result.extend(self._getLabel(obj, **args))
- if not result:
- if obj.name and (len(obj.name)):
- result.append(obj.name)
- return result
-
- def _getUnrelatedLabels(self, obj, **args):
- """Finds all labels not in a label for or labelled by relation."""
- # pylint: disable-msg=W0142
- labels = self._script.findUnrelatedLabels(obj)
- result = []
- for label in labels:
- name = self._getName(label, **args)
- result.extend(name)
- return result
-
- def _getEmbedded(self, obj, **args):
- # pylint: disable-msg=W0142
- result = self._getLabelOrName(obj, **args)
- if not result:
- try:
- result.append(obj.getApplication().name)
- except:
- pass
- return result
-
- #####################################################################
- # #
- # State information #
- # #
- #####################################################################
-
- def _getCheckedState(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_INDETERMINATE):
- # Translators: this represents the state of a checkbox.
- #
- result.append(_("partially checked"))
- elif state.contains(pyatspi.STATE_CHECKED):
- # Translators: this represents the state of a checkbox.
- #
- result.append(_("checked"))
- else:
- # Translators: this represents the state of a checkbox.
- #
- result.append(_("not checked"))
- return result
-
- def _getCellCheckedState(self, obj, **args):
- # pylint: disable-msg=W0142
- result = []
- try:
- action = obj.queryAction()
- except NotImplementedError:
- action = None
- if action:
- for i in range(0, action.nActions):
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(i) in ["toggle", _("toggle")]:
- oldRole = _overrideRole(pyatspi.ROLE_CHECK_BOX,
- args)
- result.extend(self.getSpeech(obj, **args))
- _restoreRole(oldRole, args)
- return result
-
- def _getRadioState(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_CHECKED):
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- result.append(C_("radiobutton", "selected"))
- else:
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- result.append(C_("radiobutton", "not selected"))
- return result
-
- def _getToggleState(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_CHECKED) \
- or state.contains(pyatspi.STATE_PRESSED):
- # Translators: the state of a toggle button.
- #
- result.append(_("pressed"))
- else:
- # Translators: the state of a toggle button.
- #
- result.append(_("not pressed"))
- return result
-
- def _getExpandableState(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_EXPANDABLE):
- if state.contains(pyatspi.STATE_EXPANDED):
- # Translators: this represents the state of a node in a tree.
- # 'expanded' means the children are showing.
- # 'collapsed' means the children are not showing.
- #
- result.append(_("expanded"))
- else:
- # Translators: this represents the state of a node in a tree.
- # 'expanded' means the children are showing.
- # 'collapsed' means the children are not showing.
- #
- result.append(_("collapsed"))
- return result
-
- def _getMenuItemCheckedState(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_CHECKED):
- # Translators: this represents the state of a checked menu item.
- #
- result.append(_("checked"))
- return result
-
- def _getAvailability(self, obj, **args):
- result = []
- state = obj.getState()
- if not state.contains(pyatspi.STATE_SENSITIVE):
- # Translators: this represents an item on the screen that has
- # been set insensitive (or grayed out).
- #
- result.append(_("grayed"))
- return result
-
- def _getRequired(self, obj, **args):
- result = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_REQUIRED):
- result = [settings.speechRequiredStateString]
- return result
-
- def _getReadOnly(self, obj, **args):
- result = []
- if settings.presentReadOnlyText \
- and self._script.isReadOnlyTextArea(obj):
- result.append(settings.speechReadOnlyString)
- return result
-
- #####################################################################
- # #
- # Image information #
- # #
- #####################################################################
-
- def _getImageDescription(self, obj, **args ):
- result = []
- try:
- image = obj.queryImage()
- except NotImplementedError:
- pass
- else:
- description = image.imageDescription
- if description and len(description):
- result.append(description)
- return result
-
- def _getImage(self, obj, **args):
- result = []
- try:
- image = obj.queryImage()
- except:
- pass
- else:
- role = pyatspi.ROLE_IMAGE
- result.extend(self.getSpeech(obj, role=role))
- return result
-
- #####################################################################
- # #
- # Table interface information #
- # #
- #####################################################################
-
- def _getTableCell2ChildLabel(self, obj, **args):
- """Get the speech utterances for the label of a toggle in a table cell
- that has a special 2 child pattern that we run into."""
- # pylint: disable-msg=W0142
- result = []
-
- # If this table cell has 2 children and one of them has a
- # 'toggle' action and the other does not, then present this
- # as a checkbox where:
- # 1) we get the checked state from the cell with the 'toggle' action
- # 2) we get the label from the other cell.
- # See Orca bug #376015 for more details.
- #
- if obj.childCount == 2:
- cellOrder = []
- hasToggle = [False, False]
- for i, child in enumerate(obj):
- try:
- action = child.queryAction()
- except NotImplementedError:
- continue
- else:
- for j in range(0, action.nActions):
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(j) in ["toggle", _("toggle")]:
- hasToggle[i] = True
- break
- if hasToggle[0] and not hasToggle[1]:
- cellOrder = [ 1, 0 ]
- elif not hasToggle[0] and hasToggle[1]:
- cellOrder = [ 0, 1 ]
- if cellOrder:
- for i in cellOrder:
- if not hasToggle[i]:
- result.extend(self.getSpeech(obj[i], **args))
- return result
-
- def _getTableCell2ChildToggle(self, obj, **args):
- """Get the speech utterances for the toggle value in a table cell that
- has a special 2 child pattern that we run into."""
- # pylint: disable-msg=W0142
- result = []
-
- # If this table cell has 2 children and one of them has a
- # 'toggle' action and the other does not, then present this
- # as a checkbox where:
- # 1) we get the checked state from the cell with the 'toggle' action
- # 2) we get the label from the other cell.
- # See Orca bug #376015 for more details.
- #
- if obj.childCount == 2:
- cellOrder = []
- hasToggle = [False, False]
- for i, child in enumerate(obj):
- try:
- action = child.queryAction()
- except NotImplementedError:
- continue
- else:
- for j in range(0, action.nActions):
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(j) in ["toggle", _("toggle")]:
- hasToggle[i] = True
- break
-
- if hasToggle[0] and not hasToggle[1]:
- cellOrder = [ 1, 0 ]
- elif not hasToggle[0] and hasToggle[1]:
- cellOrder = [ 0, 1 ]
- if cellOrder:
- for i in cellOrder:
- if hasToggle[i]:
- result.extend(self.getSpeech(obj[i], **args))
- return result
-
- def _getTableCellRow(self, obj, **args):
- """Get the speech for a table cell row or a single table cell
- if settings.readTableCellRow is False."""
- # pylint: disable-msg=W0142
- result = []
-
- try:
- parentTable = obj.parent.queryTable()
- except NotImplementedError:
- parentTable = None
- if settings.readTableCellRow and parentTable \
- and (not self._script.isLayoutOnly(obj.parent)):
- parent = obj.parent
- index = self._script.getCellIndex(obj)
- row = parentTable.getRowAtIndex(index)
- column = parentTable.getColumnAtIndex(index)
-
- # This is an indication of whether we should speak all the
- # table cells (the user has moved focus up or down a row),
- # or just the current one (focus has moved left or right in
- # the same row).
- #
- speakAll = True
- if "lastRow" in self._script.pointOfReference \
- and "lastColumn" in self._script.pointOfReference:
- pointOfReference = self._script.pointOfReference
- speakAll = \
- (pointOfReference["lastRow"] != row) \
- or ((row == 0 or row == parentTable.nRows-1) \
- and pointOfReference["lastColumn"] == column)
- if speakAll:
- for i in range(0, parentTable.nColumns):
- cell = parentTable.getAccessibleAt(row, i)
- if not cell:
- continue
- state = cell.getState()
- showing = state.contains(pyatspi.STATE_SHOWING)
- if showing:
- # If this table cell has a "toggle" action, and
- # doesn't have any label associated with it then
- # also speak the table column header.
- # See Orca bug #455230 for more details.
- #
- label = self._script.getDisplayedText(
- self._script.getRealActiveDescendant(cell))
- try:
- action = cell.queryAction()
- except NotImplementedError:
- action = None
- if action and (label == None or len(label) == 0):
- for j in range(0, action.nActions):
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(j) in ["toggle",
- _("toggle")]:
- accHeader = \
- parentTable.getColumnHeader(i)
- result.append(accHeader.name)
- oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
- args)
- result.extend(
- self.getSpeech(cell,
- **args))
- _restoreRole(oldRole, args)
- else:
- oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
- args)
- result.extend(
- self.getSpeech(obj, **args))
- _restoreRole(oldRole, args)
- else:
- oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
- args)
- result = self.getSpeech(obj, **args)
- _restoreRole(oldRole, args)
- return result
-
- #####################################################################
- # #
- # Terminal information #
- # #
- #####################################################################
-
- def _getTerminal(self, obj, **args):
- result = []
- title = None
- frame = self._script.getFrame(obj)
- if frame:
- title = frame.name
- if not title:
- title = self._script.getDisplayedLabel(obj)
- result.append(title)
- return result
-
- #####################################################################
- # #
- # Text interface information #
- # #
- #####################################################################
-
- def _getCurrentLineText(self, obj, **args ):
- [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
- return [text]
-
- def _getDisplayedText(self, obj, **args ):
- """Returns the text being displayed for an object or the object's
- name if no text is being displayed."""
- return [self._script.getDisplayedText(obj)]
-
- def _getAllTextSelection(self, obj, **args):
- """Check if this object has text associated with it and it's
- completely selected."""
- result = []
- try:
- textObj = obj.queryText()
- except:
- pass
- else:
- noOfSelections = textObj.getNSelections()
- if noOfSelections == 1:
- [string, startOffset, endOffset] = \
- textObj.getTextAtOffset(0, pyatspi.TEXT_BOUNDARY_LINE_START)
- if startOffset == 0 and endOffset == len(string):
- # Translators: when the user selects (highlights) text in
- # a document, Orca lets them know this.
- #
- result = [C_("text", "selected")]
- return result
-
- #####################################################################
- # #
- # Value interface information #
- # #
- #####################################################################
-
- def _getValue(self, obj, **args):
- return [self._script.getTextForValue(obj)]
-
- def _getPercentage(self, obj, **args ):
- result = []
- try:
- value = obj.queryValue()
- except NotImplementedError:
- pass
- else:
- percentValue = \
- (value.currentValue
- / (value.maximumValue - value.minimumValue)) \
- * 100.0
- # Translators: this is the percentage value of a progress bar.
- #
- percentage = _("%d percent.") % percentValue + " "
- result.append(percentage)
- return result
-
- #####################################################################
- # #
- # Hierarchy and related dialog information #
- # #
- #####################################################################
-
- def _getRealActiveDescendantDisplayedText(self, obj, **args ):
- text = self._script.getDisplayedText(
- self._script.getRealActiveDescendant(obj))
- if text:
- return [text]
- else:
- return []
-
- def _getNumberOfChildren(self, obj, **args):
- result = []
- childNodes = self._script.getChildNodes(obj)
- children = len(childNodes)
- if children:
- # Translators: this is the number of items in a layered
- # pane or table.
- #
- itemString = ngettext("%d item", "%d items", children) % children
- result.append(itemString)
- return result
-
- def _getNoShowingChildren(self, obj, **args):
- result = []
- hasItems = False
- for child in obj:
- state = child.getState()
- if state.contains(pyatspi.STATE_SHOWING):
- hasItems = True
- break
- if not hasItems:
- # Translators: this is the number of items in a layered pane
- # or table.
- #
- result.append(_("0 items"))
- return result
-
- def _getNoChildren(self, obj, **args ):
- result = []
- if not obj.childCount:
- # Translators: this is the number of items in a layered pane
- # or table.
- #
- result.append(_("0 items"))
- return result
-
- def _getUnfocusedDialogCount(self, obj, **args):
- result = []
- # If this application has more than one unfocused alert or
- # dialog window, then speak '<m> unfocused dialogs'
- # to let the user know.
- #
- alertAndDialogCount = \
- self._script.getUnfocusedAlertAndDialogCount(obj)
- if alertAndDialogCount > 0:
- # Translators: this tells the user how many unfocused
- # alert and dialog windows that this application has.
- #
- result.append(ngettext("%d unfocused dialog",
- "%d unfocused dialogs",
- alertAndDialogCount) % alertAndDialogCount)
- return result
-
- #####################################################################
- # #
- # Keyboard shortcut information #
- # #
- #####################################################################
-
- def _getAccelerator(self, obj, **args):
- result = []
- [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
- if accelerator:
- # Add punctuation for better prosody.
- #
- #if result:
- # result[-1] += "."
- result.append(accelerator)
- return result
-
- def _getMnemonic(self, obj, **args):
- result = []
- [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
- if mnemonic:
- mnemonic = mnemonic[-1] # we just want a single character
- if not mnemonic and shortcut:
- mnemonic = shortcut
- if mnemonic:
- # Add punctuation for better prosody.
- #
- #if result:
- # utterances[-1] += "."
- result = [mnemonic]
- return result
-
-
- #####################################################################
- # #
- # Get the context of where the object is. #
- # #
- #####################################################################
-
- def _getContext(self, obj, stopAncestor=None, **args):
- """Get the information that describes the names and role of
- the container hierarchy of the object, stopping at and
- not including the stopAncestor.
-
- Arguments:
- - obj: the object
- - stopAncestor: the anscestor to stop at and not include (None
- means include all ancestors)
-
- """
-
- result = []
-
- if not obj or obj == stopAncestor:
- return result
-
- parent = obj.parent
- if parent \
- and (obj.getRole() == pyatspi.ROLE_TABLE_CELL) \
- and (parent.getRole() == pyatspi.ROLE_TABLE_CELL):
- parent = parent.parent
-
- while parent and (parent.parent != parent):
- if parent == stopAncestor:
- break
- if not self._script.isLayoutOnly(parent):
- text = self._script.getDisplayedLabel(parent)
- if not text and 'Text' in pyatspi.listInterfaces(parent):
- text = self._script.getDisplayedText(parent)
- if text and len(text.strip()):
- # Push announcement of cell to the end
- #
- if parent.getRole() not in [pyatspi.ROLE_TABLE_CELL,
- pyatspi.ROLE_FILLER]:
- result.extend(self._getRoleName(parent))
- result.append(text)
- if parent.getRole() == pyatspi.ROLE_TABLE_CELL:
- result.extend(self._getRoleName(parent))
-
- parent = parent.parent
-
- result.reverse()
-
- return result
-
- def _getTutorial(self, obj, **args):
- already_focused = args.get('already_focused')
- forceMessage = args.get('forceMessage', False)
- return self._script.tutorialGenerator.getTutorial(obj, \
- already_focused, forceMessage)
-
- #####################################################################
- # #
- # Tie it all together #
- # #
- #####################################################################
-
- def voice(self, key=None):
- try:
- voice = settings.voices[key]
- except:
- voice = settings.voices[settings.DEFAULT_VOICE]
- return [voice]
-
- def getSpeech(self, obj, already_focused=False, **args):
- # pylint: disable-msg=W0142
- result = []
- methods = {}
- methods["voice"] = self.voice
- methods["obj"] = obj
- methods["role"] = args.get('role', obj.getRole())
-
- try:
- # We sometimes want to override the role. We'll keep the
- # role in the args dictionary as a means to let us do so.
- #
- args['role'] = methods["role"]
-
- # We loop through the format string, catching each error
- # as we go. Each error should always be a NameError,
- # where the name is the name of one of our generator
- # functions. When we encounter this, we call the function
- # and get its results, placing them in the globals for the
- # the call to eval.
- #
- args['already_focused'] = already_focused
- format = self._script.formatting.getFormat('speech',
- **args)
- assert(format)
- while True:
- try:
- result = eval(format, methods)
- break
- except NameError:
- result = []
- info = _formatExceptionInfo()
- arg = info[1][0]
- arg = arg.replace("name '", "")
- arg = arg.replace("' is not defined", "")
- if not self._methodsDict.has_key(arg):
- debug.printException(
- debug.LEVEL_SEVERE,
- "Unable to find function for '%s'\n" % arg)
- break
- methods[arg] = self._methodsDict[arg](obj, **args)
- except:
- debug.printException(debug.LEVEL_SEVERE)
- result = []
-
- return result
diff --git a/src/orca/bookmarks.py b/src/orca/bookmarks.py
index 3a95d66..1d73107 100644
--- a/src/orca/bookmarks.py
+++ b/src/orca/bookmarks.py
@@ -77,9 +77,11 @@ class Bookmarks:
# those spots. These spots are known as 'bookmarks'.
#
utterances = [_('bookmark entered')]
- utterances.extend(self._script.speechGenerator.getSpeech( \
- context.getCurrentAccessible(), False))
- speech.speakUtterances(utterances)
+ utterances.extend(
+ self._script.speechGenerator.getSpeech(
+ context.getCurrentAccessible(),
+ False))
+ speech.speak(utterances)
def bookmarkCurrentWhereAmI(self, inputEvent):
""" Report "Where am I" information for this bookmark relative to the
diff --git a/src/orca/default.py b/src/orca/default.py
index 60a5195..f95140b 100644
--- a/src/orca/default.py
+++ b/src/orca/default.py
@@ -2048,7 +2048,7 @@ class Script(script.Script):
if not moved:
break
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
elif self.isTextArea(orca_state.locusOfFocus):
try:
@@ -2058,7 +2058,7 @@ class Script(script.Script):
orca_state.locusOfFocus, False)
utterances.extend(self.tutorialGenerator.getTutorial(
orca_state.locusOfFocus, False))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
except AttributeError:
pass
else:
@@ -2710,7 +2710,7 @@ class Script(script.Script):
percentage = _("%d percent.") % percentValue + " "
utterances.append(percentage)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
self.lastProgressBarTime[obj] = currentTime
self.lastProgressBarValue[obj] = percentValue
@@ -3014,7 +3014,7 @@ class Script(script.Script):
else:
voice = self.voices[settings.DEFAULT_VOICE]
- speech.speakUtterances(utterances, voice, not shouldNotInterrupt)
+ speech.speak(utterances, voice, not shouldNotInterrupt)
# If this is a table cell, save the current row and column
# information in the table cell's table, so that we can use
@@ -3106,7 +3106,7 @@ class Script(script.Script):
for label in labels:
utterances.append(label.name)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return
@@ -3123,7 +3123,7 @@ class Script(script.Script):
utterances = self.speechGenerator.getSpeech(target, True)
utterances.extend(self.tutorialGenerator.getTutorial(
target, True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return
# If this object is a label, and if it has a LABEL_FOR relation
@@ -3142,7 +3142,7 @@ class Script(script.Script):
target, True)
utterances.extend(self.tutorialGenerator.getTutorial(
target, True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return
if not self.isSameObject(obj, orca_state.locusOfFocus):
@@ -3175,7 +3175,7 @@ class Script(script.Script):
self.updateBraille(obj)
utterances = self.speechGenerator.getSpeech(obj, True)
utterances.extend(self.tutorialGenerator.getTutorial(obj, True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def updateBraille(self, obj, extraRegion=None):
"""Updates the braille display to show the give object.
@@ -3947,12 +3947,12 @@ class Script(script.Script):
and (orca_state.lastNonModifierKeyEvent.event_string \
== "F1"):
self.updateBraille(orca_state.locusOfFocus)
- utterances = self.speechGenerator.getSpeech(\
+ utterances = self.speechGenerator.getSpeech(
orca_state.locusOfFocus,
False)
utterances.extend(self.tutorialGenerator.getTutorial(
orca_state.locusOfFocus, False))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return
if event.source.getRole() in state_change_notifiers:
@@ -4277,7 +4277,7 @@ class Script(script.Script):
# a document, Orca lets them know this.
#
utterances.append(C_("text", "selected"))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
self.updateBraille(orca_state.locusOfFocus)
def noOp(self, event):
@@ -5286,7 +5286,7 @@ class Script(script.Script):
context.getCurrentAccessible(), False)
utterances.extend(self.tutorialGenerator.getTutorial(
context.getCurrentAccessible(), False))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return True
def reviewPreviousItem(self, inputEvent):
diff --git a/src/orca/liveregions.py b/src/orca/liveregions.py
index 4669993..a318812 100644
--- a/src/orca/liveregions.py
+++ b/src/orca/liveregions.py
@@ -215,7 +215,7 @@ class LiveRegionManager:
utts = message['content']
else:
utts = message['labels'] + message['content']
- speech.speakUtterances(utts)
+ speech.speak(utts)
# set the last live obj to be announced
self.lastliveobj = obj
@@ -279,7 +279,7 @@ class LiveRegionManager:
#
utterances.append(_('setting live region to off'))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def goLastLiveRegion(self):
"""Move the caret to the last announced live region and speak the
@@ -298,7 +298,7 @@ class LiveRegionManager:
#
speech.speak(_('no live message saved'))
else:
- speech.speakUtterances(self.msg_cache[-msgnum])
+ speech.speak(self.msg_cache[-msgnum])
def setLivePolitenessOff(self):
"""User toggle to set all live regions to LIVE_OFF or back to their
@@ -384,7 +384,7 @@ class LiveRegionManager:
# Translators: output the politeness level
#
utterances.append(_('politeness level %s') %liveprioritystr)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def matchLiveRegion(self, obj):
"""Predicate used to find a live region"""
@@ -460,7 +460,7 @@ class LiveRegionManager:
speech.stop()
# Note: we would like to use a different ACSS for alerts. This work
# should be done as part of bug #412656.
- speech.speakUtterances(utts)
+ speech.speak(utts)
return None
else:
return {'content':content, 'labels':labels}
diff --git a/src/orca/mouse_review.py b/src/orca/mouse_review.py
index 4f7c83a..ed7d73d 100644
--- a/src/orca/mouse_review.py
+++ b/src/orca/mouse_review.py
@@ -265,7 +265,7 @@ class MouseReviewer:
# display.
braille.displayMessage(obj)
else:
- speech.speakUtterances(
+ speech.speak(
self._currentMouseOver.script.speechGenerator.getSpeech(
obj,
False))
diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index 982eb33..dcf90e1 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -549,7 +549,7 @@ class Script(Gecko.Script):
#
text = _("%s panel") % parent.name
utterances.append(text)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
else:
grandparent = parent.parent
if grandparent \
@@ -566,7 +566,7 @@ class Script(Gecko.Script):
#
text = _("%s panel") % grandparent.name
utterances.append(text)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _presentMessage(self, documentFrame):
"""Presents the first line of the message, or the entire message,
diff --git a/src/orca/scripts/apps/acroread.py b/src/orca/scripts/apps/acroread.py
index df5fc0b..cefb1da 100644
--- a/src/orca/scripts/apps/acroread.py
+++ b/src/orca/scripts/apps/acroread.py
@@ -437,7 +437,7 @@ class Script(default.Script):
utterances = \
self.speechGenerator.getSpeech(newLocusOfFocus, False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
brailleRegions = \
self.brailleGenerator.getBrailleRegions(newLocusOfFocus)
braille.displayRegions(brailleRegions)
@@ -469,7 +469,7 @@ class Script(default.Script):
adjustedUtterances = []
for utterance in utterances:
adjustedUtterances.append(self.adjustForRepeats(utterance))
- speech.speakUtterances(adjustedUtterances)
+ speech.speak(adjustedUtterances)
brailleRegions = \
self.brailleGenerator.getBrailleRegions(newLocusOfFocus)
braille.displayRegions(brailleRegions)
@@ -550,7 +550,7 @@ class Script(default.Script):
#
utterances = \
self.speechGenerator.getSpeech(event.source, False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
brailleRegions = \
self.brailleGenerator.getBrailleRegions(event.source)
braille.displayRegions(brailleRegions)
diff --git a/src/orca/scripts/apps/evolution/script.py b/src/orca/scripts/apps/evolution/script.py
index b78bb4e..ea2c7bb 100644
--- a/src/orca/scripts/apps/evolution/script.py
+++ b/src/orca/scripts/apps/evolution/script.py
@@ -283,8 +283,8 @@ class Script(default.Script):
getState().contains( \
pyatspi.STATE_SENSITIVE)):
self.updateBraille(orca_state.locusOfFocus)
- speech.speakUtterances(
- self.speechGenerator.getSpeech( \
+ speech.speak(
+ self.speechGenerator.getSpeech(
orca_state.locusOfFocus, False))
except NotImplementedError:
pass
@@ -338,7 +338,7 @@ class Script(default.Script):
savedSpeechVerbosityLevel = settings.speechVerbosityLevel
settings.speechVerbosityLevel = settings.VERBOSITY_LEVEL_BRIEF
utterances = speechGen.getSpeech(tab, False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
settings.speechVerbosityLevel = savedSpeechVerbosityLevel
braille.displayRegions(brailleGen.getBrailleRegions(tab))
@@ -771,7 +771,7 @@ class Script(default.Script):
utterances.append(string)
braille.displayRegions([regions, regions[0]])
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
return
# 3) Mail view: message header list
@@ -951,7 +951,7 @@ class Script(default.Script):
if column == i:
cellWithFocus = focusedRegion
if speakAll or (column == i):
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Speak/braille the table cell.
#
@@ -1020,7 +1020,7 @@ class Script(default.Script):
cellWithFocus = focusedRegion
if speakAll or (column == i):
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
if brailleRegions != []:
braille.displayRegions([brailleRegions, cellWithFocus])
@@ -1062,7 +1062,7 @@ class Script(default.Script):
utterances = speechGen.getSpeech(parent, False)
[brailleRegions, focusedRegion] = \
brailleGen.getBrailleRegions(parent)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
apptExtents = event.source.queryComponent().getExtents(0)
@@ -1075,12 +1075,12 @@ class Script(default.Script):
appt = childTable.getAccessibleAt(row, 0)
extents = appt.queryComponent().getExtents(0)
if extents.y == apptExtents.y:
- utterances = speechGen.getSpeech(event.source, \
+ utterances = speechGen.getSpeech(event.source,
False)
[apptRegions, focusedRegion] = \
brailleGen.getBrailleRegions(event.source)
brailleRegions.extend(apptRegions)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
startTime = 'Start time ' + \
self.getTimeForCalRow(j, noRows)
@@ -1141,7 +1141,7 @@ class Script(default.Script):
[apptRegions, focusedRegion] = \
brailleGen.getBrailleRegions(child)
brailleRegions.extend(apptRegions)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
startTime = 'Start time ' + \
self.getTimeForCalRow(index, noRows)
diff --git a/src/orca/scripts/apps/gcalctool/where_am_i.py b/src/orca/scripts/apps/gcalctool/where_am_i.py
index 10a6e96..45bbfb9 100644
--- a/src/orca/scripts/apps/gcalctool/where_am_i.py
+++ b/src/orca/scripts/apps/gcalctool/where_am_i.py
@@ -46,4 +46,4 @@ class WhereAmI(where_am_I.WhereAmI):
utterances = []
text = self.getObjLabelAndName(self._statusBar)
utterances.append(text)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
diff --git a/src/orca/scripts/apps/gedit/script.py b/src/orca/scripts/apps/gedit/script.py
index a889ff4..5131fb2 100644
--- a/src/orca/scripts/apps/gedit/script.py
+++ b/src/orca/scripts/apps/gedit/script.py
@@ -427,7 +427,7 @@ class Script(default.Script):
line.addRegion(braille.Region(" " + label1))
line.addRegion(braille.Region(" " + label2))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
braille.refresh()
# This method tries to detect and handle the following cases:
@@ -570,7 +570,7 @@ class Script(default.Script):
#
speech.speak(_("Phrase found."))
utterances = self.speechGenerator.getSpeech(event.source, True)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# If Ctrl+G was used to repeat a find command, speak the line that
# the caret moved to.
diff --git a/src/orca/scripts/apps/gnome-system-monitor.py b/src/orca/scripts/apps/gnome-system-monitor.py
index 6cfa173..fc8922d 100644
--- a/src/orca/scripts/apps/gnome-system-monitor.py
+++ b/src/orca/scripts/apps/gnome-system-monitor.py
@@ -94,5 +94,5 @@ class Script(default.Script):
line.addRegion(braille.Region(" " + label.name))
utterances.append(label.name)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
braille.refresh()
diff --git a/src/orca/scripts/apps/gnome-terminal.py b/src/orca/scripts/apps/gnome-terminal.py
index 3e35a38..006af43 100644
--- a/src/orca/scripts/apps/gnome-terminal.py
+++ b/src/orca/scripts/apps/gnome-terminal.py
@@ -101,7 +101,7 @@ class Script(default.Script):
pageTab.getState().contains(pyatspi.STATE_SENSITIVE):
self.updateBraille(newLocusOfFocus)
utterances = self.speechGenerator.getSpeech(pageTab, False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
default.Script.locusOfFocusChanged(self, event,
oldLocusOfFocus, newLocusOfFocus)
diff --git a/src/orca/scripts/apps/liferea.py b/src/orca/scripts/apps/liferea.py
index 876b117..a3172cb 100644
--- a/src/orca/scripts/apps/liferea.py
+++ b/src/orca/scripts/apps/liferea.py
@@ -123,7 +123,7 @@ class Script(default.Script):
# Finally we speak/braille the utterances/regions.
#
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
regions = brailleGen.getBrailleRegions(event.source)
regions[0].insert(0, braille.Region(utterances[0] + " "))
diff --git a/src/orca/scripts/apps/pidgin/where_am_i.py b/src/orca/scripts/apps/pidgin/where_am_i.py
index f3de065..9e7008f 100644
--- a/src/orca/scripts/apps/pidgin/where_am_i.py
+++ b/src/orca/scripts/apps/pidgin/where_am_i.py
@@ -88,7 +88,7 @@ class WhereAmI(where_am_I.WhereAmI):
utterances.append(text)
debug.println(self._debugLevel, "first table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
utterances = []
if doubleClick:
@@ -99,14 +99,14 @@ class WhereAmI(where_am_I.WhereAmI):
#
text = _("row %d of %d") % ((row+1), table.nRows)
utterances.append(text)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Speak the current row
#
utterances = self._getTableRow(obj)
debug.println(self._debugLevel, "second table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Speak the remaining items.
#
@@ -159,4 +159,4 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel, "third table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
diff --git a/src/orca/scripts/apps/soffice/script.py b/src/orca/scripts/apps/soffice/script.py
index fadfa4c..24c411a 100644
--- a/src/orca/scripts/apps/soffice/script.py
+++ b/src/orca/scripts/apps/soffice/script.py
@@ -742,13 +742,16 @@ class Script(default.Script):
self.updateBraille(cell)
utterances = self.speechGenerator.getSpeech(cell, False)
+ # [[[TODO: WDW - need to make sure assumption about utterances[0]
+ # is still correct with the new speech generator stuff.]]]
+ #
if not len(utterances[0]) and self.speakBlankLine(newFocus):
# Translators: "blank" is a short word to mean the
# user has navigated to an empty line.
#
speech.speak(_("blank"), None, False)
else:
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
if not settings.readTableCellRow:
self.speakCellName(cell.name)
@@ -1498,7 +1501,7 @@ class Script(default.Script):
self.updateBraille(newLocusOfFocus)
utterances = self.speechGenerator.getSpeech(newLocusOfFocus,
False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Save the current row and column information in the table
# cell's table, so that we can use it the next time.
@@ -1536,7 +1539,7 @@ class Script(default.Script):
if eventState.contains(pyatspi.STATE_SELECTED):
utterances = self.speechGenerator.getSpeech(tab,
False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Fall-thru to process the event with the default handler.
# If we are focused on a place holder element in the slide
@@ -1827,8 +1830,8 @@ class Script(default.Script):
weToggledIt = wasCommand and keyString not in navKeys
if weToggledIt:
- speech.speakUtterances(self.speechGenerator.getSpeech( \
- event.source, False))
+ speech.speak(self.speechGenerator.getSpeech(event.source,
+ False))
# When a new paragraph receives focus, we get a caret-moved event and
# two focus events (the first being object:state-changed:focused).
diff --git a/src/orca/scripts/apps/soffice/where_am_i.py b/src/orca/scripts/apps/soffice/where_am_i.py
index 8b557f3..c1b909e 100644
--- a/src/orca/scripts/apps/soffice/where_am_i.py
+++ b/src/orca/scripts/apps/soffice/where_am_i.py
@@ -124,7 +124,7 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel, "calc table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakParagraph(self, obj, basicOnly):
"""OpenOffice Calc cells have the role "paragraph" when
@@ -161,7 +161,7 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel, "editable table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getCalcFrameAndSheet(self, obj):
"""Returns the Calc frame and sheet
@@ -196,7 +196,7 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel, "Calc statusbar utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def speakTitle(self, obj):
"""Speak the title bar.
@@ -226,7 +226,7 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel,
"Calc titlebar and sheet utterances=%s" % utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def speakStatusBar(self, obj):
"""Speak the status bar contents.
@@ -250,7 +250,7 @@ class WhereAmI(where_am_I.WhereAmI):
debug.println(self._debugLevel,
"Calc status bar utterances=%s" % utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getObjLabel(self, obj):
"""Returns the label to speak for an object.
diff --git a/src/orca/scripts/apps/yelp.py b/src/orca/scripts/apps/yelp.py
index 5964582..8e95ecb 100644
--- a/src/orca/scripts/apps/yelp.py
+++ b/src/orca/scripts/apps/yelp.py
@@ -202,8 +202,7 @@ class Script(Gecko.Script):
self._currentFrameName = event.source.name
self.setCaretPosition(obj, characterOffset)
if obj.getState().contains(pyatspi.STATE_FOCUSED):
- speech.speakUtterances(\
- self.speechGenerator.getSpeech(obj, False))
+ speech.speak(self.speechGenerator.getSpeech(obj, False))
elif not Gecko.script_settings.sayAllOnLoad:
self.speakContents(\
self.getLineContentsAtOffset(obj, characterOffset))
diff --git a/src/orca/scripts/toolkits/Gecko/bookmarks.py b/src/orca/scripts/toolkits/Gecko/bookmarks.py
index faab4f8..5f97392 100644
--- a/src/orca/scripts/toolkits/Gecko/bookmarks.py
+++ b/src/orca/scripts/toolkits/Gecko/bookmarks.py
@@ -62,7 +62,7 @@ class GeckoBookmarks(bookmarks.Bookmarks):
utterances = [(_('entered bookmark'))]
utterances.extend(self._script.speechGenerator.getSpeech \
(obj, False))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def goToBookmark(self, inputEvent, index=None):
""" Go to the bookmark indexed at this key and this page's URI """
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index 8231b95..12fd408 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -1548,9 +1548,9 @@ class Script(default.Script):
utterances.append(rolenames.getSpeechForRoleName(event.any_data))
if settings.speechVerbosityLevel == \
settings.VERBOSITY_LEVEL_VERBOSE:
- utterances.extend(\
+ utterances.extend(
self.speechGenerator.getSpeech(event.any_data, False))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def onDocumentReload(self, event):
"""Called when the reload button is hit for a web page."""
@@ -1681,8 +1681,8 @@ class Script(default.Script):
# http://bugzilla.gnome.org/show_bug.cgi?id=570551
#
if eventSourceRole == pyatspi.ROLE_ALERT:
- speech.speakUtterances(\
- self.speechGenerator.getSpeech(event.source, False))
+ speech.speak(self.speechGenerator.getSpeech(
+ event.source, False))
self.updateBraille(obj)
else:
self.presentLine(obj, characterOffset)
@@ -1871,8 +1871,7 @@ class Script(default.Script):
self.updateBraille(obj)
if obj.getState().contains(pyatspi.STATE_FOCUSABLE):
- speech.speakUtterances(\
- self.speechGenerator.getSpeech(obj, False))
+ speech.speak(self.speechGenerator.getSpeech(obj, False))
elif not script_settings.sayAllOnLoad:
self.speakContents(\
self.getLineContentsAtOffset(obj,
@@ -2442,7 +2441,7 @@ class Script(default.Script):
else:
[textObj, startOffset, endOffset, word] = wordContents[0]
word = textObj.queryText().getText(startOffset, endOffset)
- speech.speakUtterances([word], self.getACSS(textObj, word))
+ speech.speak([word], self.getACSS(textObj, word))
def sayLine(self, obj):
"""Speaks the line at the current caret position."""
@@ -5333,6 +5332,8 @@ class Script(default.Script):
# #
####################################################################
+ # [[[TODO: WDW - this needs to be moved to the speech generator.]]]
+ #
def getACSS(self, obj, string):
"""Returns the ACSS to speak anything for the given obj."""
if obj.getRole() == pyatspi.ROLE_LINK:
@@ -5506,7 +5507,7 @@ class Script(default.Script):
# speak the entire component.
#
utterances = self.speechGenerator.getSpeech(obj, False)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
####################################################################
# #
diff --git a/src/orca/scripts/toolkits/Gecko/where_am_i.py b/src/orca/scripts/toolkits/Gecko/where_am_i.py
index 5da20d7..ac7e570 100644
--- a/src/orca/scripts/toolkits/Gecko/where_am_i.py
+++ b/src/orca/scripts/toolkits/Gecko/where_am_i.py
@@ -258,5 +258,5 @@ class GeckoWhereAmI(where_am_I.WhereAmI):
#
utterances.append(_('%d percent of document read') %percent)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
diff --git a/src/orca/speech.py b/src/orca/speech.py
index 87d2422..3be4a82 100755
--- a/src/orca/speech.py
+++ b/src/orca/speech.py
@@ -137,54 +137,8 @@ def sayAll(utteranceIterator, progressCallback):
debug.println(debug.LEVEL_INFO, logLine)
log.info(logLine)
-def altspeak(result, voice=None):
- """Speaks the array-based speech from the alternate speech generator."""
- subString = None
- for element in result:
- if isinstance(element, basestring):
- if subString:
- subString += " " + element
- else:
- subString = element
- else:
- if subString:
- print "Speaking '%s' with" % subString, voice
- speak(subString, voice)
- subString = None
- if isinstance(element, list):
- altspeak(element, voice)
- elif isinstance(element, ACSS):
- voice = ACSS(voice)
- voice.update(element)
- else:
- print indent + "UNKNOWN element", element
- if subString:
- print "Speaking '%s' with" % subString, voice
- speak(subString, voice)
-
-def speak(text, acss=None, interrupt=True):
- """Speaks all queued text immediately. If text is not None,
- it is added to the queue before speaking.
-
- Arguments:
- - text: optional text to add to the queue before speaking
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- - interrupt: if True, stops any speech in progress before
- speaking the text
- """
-
- # We will not interrupt a key echo in progress.
- #
- if orca_state.lastKeyEchoTime:
- interrupt = interrupt \
- and ((time.time() - orca_state.lastKeyEchoTime) > 0.5)
-
- if settings.silenceSpeech:
- return
+def _speak(text, acss, interrupt):
+ """Speaks the individual string using the given ACSS."""
if settings.speakMultiCaseStringsAsWords:
text = _processMultiCaseString(text)
@@ -200,6 +154,51 @@ def speak(text, acss=None, interrupt=True):
if _speechserver:
_speechserver.speak(text, __resolveACSS(acss), interrupt)
+
+def speak(content, acss=None, interrupt=True):
+ """Speaks the given content. The content can be either a simple
+ string or an array of arrays of objects returned by a speech
+ generator."""
+
+ # We will not interrupt a key echo in progress.
+ #
+ if orca_state.lastKeyEchoTime:
+ interrupt = interrupt \
+ and ((time.time() - orca_state.lastKeyEchoTime) > 0.5)
+
+ if settings.silenceSpeech:
+ return
+
+ if isinstance(content, basestring):
+ subString = content
+ elif isinstance(content, list):
+ subString = None
+ for element in content:
+ if isinstance(element, basestring):
+ if subString:
+ subString += " " + element
+ else:
+ subString = element
+ else:
+ if subString:
+ _speak(subString, acss, interrupt)
+ subString = None
+ if isinstance(element, list):
+ speak(element, acss, interrupt)
+ elif isinstance(element, ACSS):
+ acss = ACSS(acss)
+ acss.update(element)
+ else:
+ debug.println(debug.LEVEL_WARNING,
+ "UNKNOWN speech element: '%s'" % element)
+ else:
+ debug.printStack(debug.LEVEL_WARNING)
+ debug.println(debug.LEVEL_WARNING,
+ "bad content send to speech.speak: '%s'", repr(content))
+
+ if subString:
+ _speak(subString, acss, interrupt)
+
def speakKeyEvent(event_string, eventType):
"""Speaks a key event immediately.
@@ -263,47 +262,6 @@ def isSpeaking():
else:
return False
-def speakUtterances(utterances, acss=None, interrupt=True):
- """Speaks the given list of utterances immediately.
-
- Arguments:
- - list: list of strings to be spoken
- - acss: acss.ACSS instance; if None,
- the default voice settings will be used.
- Otherwise, the acss settings will be
- used to augment/override the default
- voice settings.
- - interrupt: if True, stop any speech currently in progress.
- """
-
- # We will not interrupt a key echo in progress.
- #
- if orca_state.lastKeyEchoTime:
- interrupt = interrupt \
- and ((time.time() - orca_state.lastKeyEchoTime) > 0.5)
-
- if settings.silenceSpeech:
- return
- i = 0
- length = len(utterances)
- while ( i < length ):
- if settings.speakMultiCaseStringsAsWords:
- utterances[i] = _processMultiCaseString(utterances[i])
- if orca_state.activeScript and orca_state.usePronunciationDictionary:
- utterances[i] = orca_state.activeScript.adjustForPronunciation(\
- utterances[i])
- if settings.speakMultiCaseStringsAsWords:
- utterances[i] = _processMultiCaseString(utterances[i])
- logLine = "SPEECH OUTPUT: '" + utterances[i] + "'"
- debug.println(debug.LEVEL_INFO, logLine)
- log.info(logLine)
- i = i + 1
-
- if _speechserver:
- _speechserver.speakUtterances(utterances,
- __resolveACSS(acss),
- interrupt)
-
def getInfo():
info = None
if _speechserver:
diff --git a/src/orca/speechgenerator.py b/src/orca/speechgenerator.py
index 330a8b2..5279774 100755
--- a/src/orca/speechgenerator.py
+++ b/src/orca/speechgenerator.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
@@ -19,27 +19,47 @@
"""Utilities for obtaining speech utterances for objects. In general,
there probably should be a singleton instance of the SpeechGenerator
-class. For those wishing to override the speech generators, however,
-one can create a new instance and replace/extend the speech generators
-as they see fit."""
-
-__id__ = "$Id$"
-__version__ = "$Revision$"
-__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+class."""
+
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2009 Sun Microsystems Inc."
__license__ = "LGPL"
-import pyatspi
+import sys
+import traceback
+
import debug
-import orca_state
+import pyatspi
import rolenames
import settings
-import altspeechgenerator
from orca_i18n import _ # for gettext support
from orca_i18n import ngettext # for ngettext support
from orca_i18n import C_ # to provide qualified translatable strings
+def _formatExceptionInfo(maxTBlevel=5):
+ cla, exc, trbk = sys.exc_info()
+ excName = cla.__name__
+ try:
+ excArgs = exc.args
+ except KeyError:
+ excArgs = "<no args>"
+ excTb = traceback.format_tb(trbk, maxTBlevel)
+ return (excName, excArgs, excTb)
+
+def _overrideRole(newRole, args):
+ oldRole = args.get('role', None)
+ args['role'] = newRole
+ return oldRole
+
+def _restoreRole(oldRole, args):
+ if oldRole:
+ args['role'] = oldRole
+ else:
+ del args['role']
+
class SpeechGenerator:
"""Takes accessible objects and produces a string to speak for
those objects. See the getSpeech method, which is the primary
@@ -47,865 +67,217 @@ class SpeechGenerator:
speechGenerators instance field as they see fit."""
def __init__(self, script):
-
- # The script that created us. This allows us to ask the
- # script for information if we need it.
- #
self._script = script
-
- # Set up a dictionary that maps role names to functions
- # that generate speech for objects that implement that role.
+ self._methodsDict = {}
+ for method in \
+ filter(lambda z: callable(z),
+ map(lambda y: getattr(self, y).__get__(self, self.__class__),
+ filter(lambda x: x.startswith("_get"), dir(self)))):
+ name = method.__name__[4:]
+ name = name[0].lower() + name[1:]
+ self._methodsDict[name] = method
+
+ # Verify the formatting strings are OK. This is only
+ # for verification and does not effect the function of
+ # Orca at all.
#
- self.speechGenerators = {}
- self.speechGenerators[pyatspi.ROLE_ALERT] = \
- self._getSpeechForAlert
- self.speechGenerators[pyatspi.ROLE_ANIMATION] = \
- self._getSpeechForAnimation
- self.speechGenerators[pyatspi.ROLE_ARROW] = \
- self._getSpeechForArrow
- self.speechGenerators[pyatspi.ROLE_CHECK_BOX] = \
- self._getSpeechForCheckBox
- self.speechGenerators[pyatspi.ROLE_CHECK_MENU_ITEM] = \
- self._getSpeechForCheckMenuItem
- self.speechGenerators[pyatspi.ROLE_COLUMN_HEADER] = \
- self._getSpeechForColumnHeader
- self.speechGenerators[pyatspi.ROLE_COMBO_BOX] = \
- self._getSpeechForComboBox
- self.speechGenerators[pyatspi.ROLE_DESKTOP_ICON] = \
- self._getSpeechForDesktopIcon
- self.speechGenerators[pyatspi.ROLE_DIAL] = \
- self._getSpeechForDial
- self.speechGenerators[pyatspi.ROLE_DIALOG] = \
- self._getSpeechForDialog
- self.speechGenerators[pyatspi.ROLE_DIRECTORY_PANE] = \
- self._getSpeechForDirectoryPane
- self.speechGenerators[pyatspi.ROLE_EMBEDDED] = \
- self._getSpeechForEmbedded
- self.speechGenerators[pyatspi.ROLE_FRAME] = \
- self._getSpeechForFrame
- self.speechGenerators[pyatspi.ROLE_HTML_CONTAINER] = \
- self._getSpeechForHtmlContainer
- self.speechGenerators[pyatspi.ROLE_ICON] = \
- self._getSpeechForIcon
- self.speechGenerators[pyatspi.ROLE_IMAGE] = \
- self._getSpeechForImage
- self.speechGenerators[pyatspi.ROLE_LABEL] = \
- self._getSpeechForLabel
- self.speechGenerators[pyatspi.ROLE_LAYERED_PANE] = \
- self._getSpeechForLayeredPane
- self.speechGenerators[pyatspi.ROLE_LIST] = \
- self._getSpeechForList
- self.speechGenerators[pyatspi.ROLE_LIST_ITEM] = \
- self._getSpeechForListItem
- self.speechGenerators[pyatspi.ROLE_MENU] = \
- self._getSpeechForMenu
- self.speechGenerators[pyatspi.ROLE_MENU_BAR] = \
- self._getSpeechForMenuBar
- self.speechGenerators[pyatspi.ROLE_MENU_ITEM] = \
- self._getSpeechForMenuItem
- self.speechGenerators[pyatspi.ROLE_OPTION_PANE] = \
- self._getSpeechForOptionPane
- self.speechGenerators[pyatspi.ROLE_PAGE_TAB] = \
- self._getSpeechForPageTab
- self.speechGenerators[pyatspi.ROLE_PAGE_TAB_LIST] = \
- self._getSpeechForPageTabList
- self.speechGenerators[pyatspi.ROLE_PARAGRAPH] = \
- self._getSpeechForText
- self.speechGenerators[pyatspi.ROLE_PASSWORD_TEXT] = \
- self._getSpeechForText
- self.speechGenerators[pyatspi.ROLE_PROGRESS_BAR] = \
- self._getSpeechForProgressBar
- self.speechGenerators[pyatspi.ROLE_PUSH_BUTTON] = \
- self._getSpeechForPushButton
- self.speechGenerators[pyatspi.ROLE_RADIO_BUTTON] = \
- self._getSpeechForRadioButton
- self.speechGenerators[pyatspi.ROLE_RADIO_MENU_ITEM] = \
- self._getSpeechForRadioMenuItem
- self.speechGenerators[pyatspi.ROLE_ROW_HEADER] = \
- self._getSpeechForRowHeader
- self.speechGenerators[pyatspi.ROLE_SCROLL_BAR] = \
- self._getSpeechForScrollBar
- self.speechGenerators[pyatspi.ROLE_SLIDER] = \
- self._getSpeechForSlider
- self.speechGenerators[pyatspi.ROLE_SPIN_BUTTON] = \
- self._getSpeechForSpinButton
- self.speechGenerators[pyatspi.ROLE_SPLIT_PANE] = \
- self._getSpeechForSplitPane
- self.speechGenerators[pyatspi.ROLE_TABLE] = \
- self._getSpeechForTable
- self.speechGenerators[pyatspi.ROLE_TABLE_CELL] = \
- self._getSpeechForTableCellRow
- self.speechGenerators[pyatspi.ROLE_TABLE_COLUMN_HEADER] = \
- self._getSpeechForTableColumnHeader
- self.speechGenerators[pyatspi.ROLE_TABLE_ROW_HEADER] = \
- self._getSpeechForTableRowHeader
- self.speechGenerators[pyatspi.ROLE_TEAROFF_MENU_ITEM] = \
- self._getSpeechForMenu
- self.speechGenerators[pyatspi.ROLE_TERMINAL] = \
- self._getSpeechForTerminal
- self.speechGenerators[pyatspi.ROLE_TEXT] = \
- self._getSpeechForText
- self.speechGenerators[pyatspi.ROLE_TOGGLE_BUTTON] = \
- self._getSpeechForToggleButton
- self.speechGenerators[pyatspi.ROLE_TOOL_BAR] = \
- self._getSpeechForToolBar
- self.speechGenerators[pyatspi.ROLE_TREE] = \
- self._getSpeechForTable
- self.speechGenerators[pyatspi.ROLE_TREE_TABLE] = \
- self._getSpeechForTable
- self.speechGenerators[pyatspi.ROLE_WINDOW] = \
- self._getSpeechForWindow
- #--- mesar----
- self.alt = altspeechgenerator.AltSpeechGenerator(script)
-
- def _addSpeechForObjectAccelerator(self, obj, utterances):
- """Adds an utterance that describes the keyboard accelerator for the
- given object to the list of utterances passed in.
-
- Arguments:
- - obj: the Accessible object
- - utterances: the list of utterances to add to.
-
- Returns a list of utterances to be spoken.
- """
-
- if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
- if accelerator:
- # Add punctuation for better prosody.
- #
- #if utterances:
- # utterances[-1] += "."
- utterances.append(accelerator)
-
- def _addSpeechForObjectMnemonic(self, obj, utterances):
- """Adds an utterance that describes the mnemonic for the given object
- to the utterances passed in.
-
- Arguments:
- - obj: the Accessible object
- - utterances: the list of utterances to add to.
- """
-
- if settings.enableMnemonicSpeaking:
- # The mnemonic is what we're really looking for. But,
- # some objects (e.g., menu items) only expose the mnemonic
- # via the full shortcut (e.g., "Alt f c" for a "Close"
- # menu item). So, we fall back to the last character in
- # the shortcut if the shortcut exists.
- #
- [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
- if mnemonic:
- mnemonic = mnemonic[-1] # we just want a single character
- if not mnemonic and shortcut:
- mnemonic = shortcut
- if mnemonic:
- # Add punctuation for better prosody.
- #
- #if utterances:
- # utterances[-1] += "."
- utterances.append(mnemonic)
-
- def _getSpeechForObjectAvailability(self, obj):
- """Returns a list of utterances that describes the availability
- of the given object.
-
- Arguments:
- - obj: the Accessible object
-
- Returns a list of utterances to be spoken.
- """
- state = obj.getState()
- if not state.contains(pyatspi.STATE_SENSITIVE):
- # Translators: this represents an item on the screen that has
- # been set insensitive (or grayed out).
- #
- return [_("grayed")]
- else:
- return []
+ # Populate the entire globals with empty arrays
+ # for the results of all the legal method names.
+ #
+ methods = {}
+ for key in self._methodsDict.keys():
+ methods[key] = []
+ methods["voice"] = self.voice
+ methods["obj"] = None
+ methods["role"] = None
+ for roleKey in self._script.formatting["speech"]:
+ for speechKey in ["focused", "unfocused"]:
+ try:
+ evalString = \
+ self._script.formatting["speech"][roleKey][speechKey]
+ except:
+ continue
+ else:
+ if not evalString:
+ # It's legal to have an empty string for speech.
+ #
+ continue
+ while True:
+ try:
+ eval(evalString, methods)
+ break
+ except NameError:
+ info = _formatExceptionInfo()
+ arg = info[1][0]
+ arg = arg.replace("name '", "")
+ arg = arg.replace("' is not defined", "")
+ if not self._methodsDict.has_key(arg):
+ debug.printException(
+ debug.LEVEL_SEVERE,
+ "Unable to find function for '%s'\n" % arg)
+ except:
+ debug.printException(debug.LEVEL_SEVERE)
+ debug.println(
+ debug.LEVEL_SEVERE,
+ "While processing '%s' '%s' '%s' '%s'" \
+ % (roleKey, speechKey, evalString, methods))
+ break
- def _getSpeechForObjectLabel(self, obj):
- label = self._script.getDisplayedLabel(obj)
- if label:
- return [label]
- else:
- return []
+ #####################################################################
+ # #
+ # Name, role, and label information #
+ # #
+ #####################################################################
- def _getSpeechForObjectName(self, obj):
+ def _getName(self, obj, **args):
+ result = []
name = self._script.getDisplayedText(obj)
if name:
- return [name]
+ result.append(name)
elif obj.description:
- return [obj.description]
- else:
- return []
-
- def getSpeechForObjectRole(self, obj, role=None):
- if (obj.getRole() != pyatspi.ROLE_UNKNOWN):
- return [rolenames.getSpeechForRoleName(obj, role)]
- else:
- return []
-
- def _getSpeechForAllTextSelection(self, obj):
- """Check if this object has text associated with it and it's
- completely selected.
-
- Arguments:
- - obj: the object being presented
- """
-
- utterance = []
- try:
- textObj = obj.queryText()
- except:
- pass
- else:
- noOfSelections = textObj.getNSelections()
- if noOfSelections == 1:
- [string, startOffset, endOffset] = \
- textObj.getTextAtOffset(0, pyatspi.TEXT_BOUNDARY_LINE_START)
- if startOffset == 0 and endOffset == len(string):
- # Translators: when the user selects (highlights) text in
- # a document, Orca lets them know this.
- #
- utterance = [C_("text", "selected")]
-
- return utterance
-
- def _getSpeechForRequiredObject(self, obj):
- """Returns the list of utterances that describe the required state
- of the given object.
-
- Arguments:
- - obj: the Accessible object
-
- Returns a list of utterances to be spoken.
- """
-
- if not settings.presentRequiredState:
- return []
-
- state = obj.getState()
- if state.contains(pyatspi.STATE_REQUIRED):
- return [settings.speechRequiredStateString]
- else:
- return []
-
- def _debugGenerator(self, generatorName, obj, already_focused, utterances):
- """Prints debug.LEVEL_FINER information regarding the speech generator.
-
- Arguments:
- - generatorName: the name of the generator
- - obj: the object being presented
- - already_focused: False if object just received focus
- - utterances: the generated text
- """
-
- debug.println(debug.LEVEL_FINER,
- "GENERATOR: %s" % generatorName)
- debug.println(debug.LEVEL_FINER,
- " obj = %s" % obj.name)
- debug.println(debug.LEVEL_FINER,
- " role = %s" % obj.getRoleName())
- debug.println(debug.LEVEL_FINER,
- " already_focused = %s" % already_focused)
- debug.println(debug.LEVEL_FINER,
- " utterances:")
- for text in utterances:
- debug.println(debug.LEVEL_FINER,
- " (%s)" % text)
-
- def _getDefaultSpeech(self, obj, already_focused, role=None):
- """Gets a list of utterances to be spoken for the current
- object's name, role, and any accelerators. This is usually the
- fallback speech generator should no other specialized speech
- generator exist for this object.
-
- The default speech will be of the following form:
-
- label name role availability mnemonic
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
- - role: A role that should be used instead of the Accessible's
- possible role.
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self._getSpeechForAllTextSelection(obj))
- utterances.extend(self.getSpeechForObjectRole(obj, role))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- if obj == orca_state.locusOfFocus:
- self._addSpeechForObjectMnemonic(obj, utterances)
-
- self._debugGenerator("_getDefaultSpeech",
- obj,
- already_focused,
- utterances)
+ result.append(obj.description)
+ return result
- return utterances
-
- def _getSpeechForAlert(self, obj, already_focused):
- """Gets the title of the dialog and the contents of labels inside the
- dialog that are not associated with any other objects.
-
- Arguments:
- - obj: the Accessible dialog
- - already_focused: False if object just received focus
+ def _getTextRole(self, obj, **args):
+ result = []
+ # pylint: disable-msg=W0142
+ role = args.get('role', obj.getRole())
+ if role != pyatspi.ROLE_PARAGRAPH:
+ result.extend(self._getRoleName(obj, **args))
+ return result
+
+ def _getRoleName(self, obj, **args):
+ result = []
+ role = args.get('role', obj.getRole())
+ if (role != pyatspi.ROLE_UNKNOWN):
+ result.append(rolenames.getSpeechForRoleName(obj, role))
+ return result
+
+ def _getLabel(self, obj, **args):
+ result = []
+ label = self._script.getDisplayedLabel(obj)
+ if label:
+ result = [label]
+ return result
- Returns a list of utterances be spoken.
+ def _getLabelAndName(self, obj, **args):
+ """Gets the label and the name if the name is different from the label.
"""
+ # pylint: disable-msg=W0142
+ result = []
+ label = self._getLabel(obj, **args)
+ name = self._getName(obj, **args)
+ result.extend(label)
+ if not len(label):
+ result.extend(name)
+ elif len(name) and name[0] != label[0]:
+ result.extend(name)
+ return result
+
+ def _getLabelOrName(self, obj, **args):
+ """Gets the label or the name if the label is not preset."""
+ result = []
+ # pylint: disable-msg=W0142
+ result.extend(self._getLabel(obj, **args))
+ if not result:
+ if obj.name and (len(obj.name)):
+ result.append(obj.name)
+ return result
- utterances = []
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
- # Find all the unrelated labels in the dialog and speak them.
- #
+ def _getUnrelatedLabels(self, obj, **args):
+ """Finds all labels not in a label for or labelled by relation."""
+ # pylint: disable-msg=W0142
labels = self._script.findUnrelatedLabels(obj)
+ result = []
for label in labels:
- name = self._getSpeechForObjectName(label)
- utterances.extend(name)
-
- self._debugGenerator("_getSpeechForAlert",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForAnimation(self, obj, already_focused):
- """Gets the speech for an animation.
-
- Arguments:
- - obj: the animation
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken.
- """
-
- utterances = []
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
- self._debugGenerator("_getSpeechForAnimation",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForArrow(self, obj, already_focused):
- """Gets a list of utterances to be spoken for an arrow.
+ name = self._getName(label, **args)
+ result.extend(name)
+ return result
- Arguments:
- - obj: the arrow
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: determine orientation of arrow. Logged as bugzilla bug
- # 319744.]]]
- # text = arrow direction (left, right, up, down)
- #
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForArrow",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForCheckBox(self, obj, already_focused):
- """Get the speech for a check box. If the check box already had
- focus, then only the state is spoken.
-
- Arguments:
- - obj: the check box
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
+ def _getEmbedded(self, obj, **args):
+ # pylint: disable-msg=W0142
+ result = self._getLabelOrName(obj, **args)
+ if not result:
+ try:
+ result.append(obj.getApplication().name)
+ except:
+ pass
+ return result
- utterances = []
+ #####################################################################
+ # #
+ # State information #
+ # #
+ #####################################################################
+ def _getCheckedState(self, obj, **args):
+ result = []
state = obj.getState()
if state.contains(pyatspi.STATE_INDETERMINATE):
# Translators: this represents the state of a checkbox.
#
- checkedState = _("partially checked")
+ result.append(_("partially checked"))
elif state.contains(pyatspi.STATE_CHECKED):
# Translators: this represents the state of a checkbox.
#
- checkedState = _("checked")
+ result.append(_("checked"))
else:
# Translators: this represents the state of a checkbox.
#
- checkedState = _("not checked")
-
- # If it's not already focused, say it's name
- #
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- if obj.getRole() == pyatspi.ROLE_TABLE_CELL:
- utterances.extend(
- self.getSpeechForObjectRole(
- obj, pyatspi.ROLE_CHECK_BOX))
- else:
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(checkedState)
- utterances.extend(self._getSpeechForRequiredObject(obj))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
- else:
- utterances.append(checkedState)
-
- self._debugGenerator("_getSpeechForCheckBox",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForCheckMenuItem(self, obj, already_focused):
- """Get the speech for a check menu item. If the check menu item
- already had focus, then only the state is spoken.
-
- Arguments:
- - obj: the check menu item
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getSpeechForCheckBox(obj, already_focused)
-
- if not already_focused:
- self._addSpeechForObjectAccelerator(obj, utterances)
-
- self._debugGenerator("_getSpeechForCheckMenuItem",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForColumnHeader(self, obj, already_focused):
- """Get the speech for a column header.
-
- Arguments:
- - obj: the column header
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForColumnHeader",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForComboBox(self, obj, already_focused):
- """Get the speech for a combo box. If the combo box already has focus,
- then only the selection is spoken.
-
- Arguments:
- - obj: the combo box
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- else:
- label = None
-
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
- if not already_focused:
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- for child in obj:
- if child.getRole() == pyatspi.ROLE_TEXT:
- utterances.extend(self._getSpeechForAllTextSelection(child))
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
-
- self._debugGenerator("_getSpeechForComboBox",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForDesktopIcon(self, obj, already_focused):
- """Get the speech for a desktop icon.
-
- Arguments:
- - obj: the desktop icon
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForDesktopIcon",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForDial(self, obj, already_focused):
- """Get the speech for a dial.
-
- Arguments:
- - obj: the dial
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: WDW - might need to include the value here? Logged as
- # bugzilla bug 319746.]]]
- #
- utterances = self._getDefaultSpeech(obj, already_focused)
+ result.append(_("not checked"))
+ return result
- self._debugGenerator("_getSpeechForDial",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForDialog(self, obj, already_focused):
- """Get the speech for a dialog box.
-
- Arguments:
- - obj: the dialog box
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getSpeechForAlert(obj, already_focused)
-
- self._debugGenerator("_getSpeechForDialog",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForDirectoryPane(self, obj, already_focused):
- """Get the speech for a directory pane.
-
- Arguments:
- - obj: the dial
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForDirectoryPane",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForEmbedded(self, obj, already_focused, role=None):
- """Gets a list of utterances to be spoken for the current
- embedded component (i.e., something in a panel).
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
- - role: A role that should be used instead of the Accessible's
- possible role.
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- if not utterances:
- try:
- utterances.append(obj.getApplication().name)
- except:
- pass
-
- self._debugGenerator("_getSpeechForEmbedded",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForFrame(self, obj, already_focused):
- """Get the speech for a frame.
-
- Arguments:
- - obj: the frame
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self._getSpeechForAllTextSelection(obj))
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- # If this application has more than one unfocused alert or
- # dialog window, then speak '<m> unfocused dialogs'
- # to let the user know.
- #
- alertAndDialogCount = \
- self._script.getUnfocusedAlertAndDialogCount(obj)
- if alertAndDialogCount > 0:
- # Translators: this tells the user how many unfocused
- # alert and dialog windows that this application has.
- #
- line = ngettext("%d unfocused dialog",
- "%d unfocused dialogs",
- alertAndDialogCount) % alertAndDialogCount
- utterances.append(line)
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- self._debugGenerator("_getSpeechForFrame",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForHtmlContainer(self, obj, already_focused):
- """Get the speech for an HTML container.
-
- Arguments:
- - obj: the dial
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForHtmlContainer",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForIcon(self, obj, already_focused):
- """Get the speech for an icon.
-
- Arguments:
- - obj: the icon
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: WDW - HACK to remove availability output because nautilus
- # doesn't include this information for desktop icons. If, at some
- # point, it is determined that availability should be added back in,
- # then a custom script for nautilus needs to be written to remove the
- # availability.]]]
- #
- utterances = []
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
+ def _getCellCheckedState(self, obj, **args):
+ # pylint: disable-msg=W0142
+ result = []
try:
- image = obj.queryImage()
+ action = obj.queryAction()
except NotImplementedError:
- pass
+ action = None
+ if action:
+ for i in range(0, action.nActions):
+ # Translators: this is the action name for
+ # the 'toggle' action. It must be the same
+ # string used in the *.po file for gail.
+ #
+ if action.getName(i) in ["toggle", _("toggle")]:
+ oldRole = _overrideRole(pyatspi.ROLE_CHECK_BOX,
+ args)
+ result.extend(self.getSpeech(obj, **args))
+ _restoreRole(oldRole, args)
+ return result
+
+ def _getRadioState(self, obj, **args):
+ result = []
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_CHECKED):
+ # Translators: this is in reference to a radio button being
+ # selected or not.
+ #
+ result.append(C_("radiobutton", "selected"))
else:
- description = image.imageDescription
- if description and len(description):
- utterances.append(description)
-
- if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- utterances.append(
- rolenames.getSpeechForRoleName(
- obj, pyatspi.ROLE_ICON))
-
- self._debugGenerator("_getSpeechForIcon",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForImage(self, obj, already_focused):
- """Get the speech for an image.
-
- Arguments:
- - obj: the image
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(
- obj, already_focused, pyatspi.ROLE_IMAGE)
-
- self._debugGenerator("_getSpeechForImage",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForLabel(self, obj, already_focused):
- """Get the speech for a label.
-
- Arguments:
- - obj: the label
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForLabel",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForLayeredPane(self, obj, already_focused):
- """Get the speech for a layered pane
-
- Arguments:
- - obj: the table
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForLayeredPane",
- obj,
- already_focused,
- utterances)
-
- # If this has no children, then let the user know.
- #
- hasItems = False
- for child in obj:
- state = child.getState()
- if state.contains(pyatspi.STATE_SHOWING):
- hasItems = True
- break
- if not hasItems:
- # Translators: this is the number of items in a layered pane
- # or table.
+ # Translators: this is in reference to a radio button being
+ # selected or not.
#
- utterances.append(_("0 items"))
+ result.append(C_("radiobutton", "not selected"))
+ return result
- return utterances
-
- def _getSpeechForList(self, obj, already_focused):
- """Get the speech for a list.
-
- Arguments:
- - obj: the list
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: WDW - include how many items in the list?
- # Logged as bugzilla bug 319749.]]]
- #
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForList",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForListItem(self, obj, already_focused):
- """Get the speech for a listitem.
-
- Arguments:
- - obj: the listitem
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self._getSpeechForAllTextSelection(obj))
+ def _getToggleState(self, obj, **args):
+ result = []
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_CHECKED) \
+ or state.contains(pyatspi.STATE_PRESSED):
+ # Translators: the state of a toggle button.
+ #
+ result.append(_("pressed"))
+ else:
+ # Translators: the state of a toggle button.
+ #
+ result.append(_("not pressed"))
+ return result
- # If already in focus then the tree probably collapsed or expanded
+ def _getExpandableState(self, obj, **args):
+ result = []
state = obj.getState()
if state.contains(pyatspi.STATE_EXPANDABLE):
if state.contains(pyatspi.STATE_EXPANDED):
@@ -913,526 +285,91 @@ class SpeechGenerator:
# 'expanded' means the children are showing.
# 'collapsed' means the children are not showing.
#
- utterances.append(_("expanded"))
+ result.append(_("expanded"))
else:
# Translators: this represents the state of a node in a tree.
# 'expanded' means the children are showing.
# 'collapsed' means the children are not showing.
#
- utterances.append(_("collapsed"))
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
+ result.append(_("collapsed"))
+ return result
- self._debugGenerator("_getSpeechForListItem",
- obj,
- already_focused,
- utterances)
- return utterances
-
- def _getSpeechForMenu(self, obj, already_focused):
- """Get the speech for a menu.
-
- Arguments:
- - obj: the menu
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self._getSpeechForAllTextSelection(obj))
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
- self._addSpeechForObjectAccelerator(obj, utterances)
-
- self._debugGenerator("_getSpeechForMenu",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForMenuBar(self, obj, already_focused):
- """Get the speech for a menu bar.
-
- Arguments:
- - obj: the menu bar
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
- self._debugGenerator("_getSpeechForMenuBar",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForMenuItem(self, obj, already_focused):
- """Get the speech for a menu item.
-
- Arguments:
- - obj: the menu item
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- # No need to say "menu item" because we already know that.
- #
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
- # OpenOffice check menu items currently have a role of "menu item"
- # rather then "check menu item", so we need to test if one of the
- # states is CHECKED. If it is, then add that in to the list of
- # speech utterances. Note that we can't tell if this is a "check
- # menu item" that is currently unchecked and speak that state.
- # See Orca bug #433398 for more details.
- #
+ def _getMenuItemCheckedState(self, obj, **args):
+ result = []
state = obj.getState()
if state.contains(pyatspi.STATE_CHECKED):
# Translators: this represents the state of a checked menu item.
#
- utterances.append(_("checked"))
-
- if not already_focused:
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
- self._addSpeechForObjectAccelerator(obj, utterances)
-
- self._debugGenerator("_getSpeechForMenuItem",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForText(self, obj, already_focused):
- """Get the speech for a text component.
-
- Arguments:
- - obj: the text component
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: WDW - HACK to remove availability because some text
- # areas, such as those in yelp, come up as insensitive though
- # they really are ineditable.]]]
- #
- utterances = []
- utterances.extend(self._getSpeechForObjectLabel(obj))
- if len(utterances) == 0:
- if obj.name and (len(obj.name)):
- utterances.append(obj.name)
-
- if settings.presentReadOnlyText \
- and self._script.isReadOnlyTextArea(obj):
- utterances.append(settings.speechReadOnlyString)
-
- if obj.getRole() != pyatspi.ROLE_PARAGRAPH:
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
- utterances.append(text)
-
- utterances.extend(self._getSpeechForAllTextSelection(obj))
-
- self._addSpeechForObjectMnemonic(obj, utterances)
-
- self._debugGenerator("_getSpeechForText",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForOptionPane(self, obj, already_focused):
- """Get the speech for an option pane.
-
- Arguments:
- - obj: the option pane
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForOptionPane",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForPageTab(self, obj, already_focused):
- """Get the speech for a page tab.
-
- Arguments:
- - obj: the page tab
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForPageTab",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForPageTabList(self, obj, already_focused):
- """Get the speech for a page tab list.
-
- Arguments:
- - obj: the page tab list
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- #if obj.childCount == 1:
- # utterances.append(_("one tab"))
- #else:
- # utterances.append(("%d " % obj.childCount) + _("tabs"))
-
- self._debugGenerator("_getSpeechForPageTabList",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForProgressBar(self, obj, already_focused):
- """Get the speech for a progress bar. If the object already
- had focus, just the new value is spoken.
-
- Arguments:
- - obj: the progress bar
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- value = obj.queryValue()
- percentValue = (value.currentValue / \
- (value.maximumValue - value.minimumValue)) * 100.0
-
- # Translators: this is the percentage value of a progress bar.
- #
- percentage = _("%d percent.") % percentValue + " "
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- utterances.append(percentage)
-
- self._debugGenerator("_getSpeechForProgressBar",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForPushButton(self, obj, already_focused):
- """Get the speech for a push button
-
- Arguments:
- - obj: the push button
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForPushButton",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForRadioButton(self, obj, already_focused):
- """Get the speech for a radio button. If the button already had
- focus, then only the state is spoken.
-
- Arguments:
- - obj: the check box
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
+ result.append(_("checked"))
+ return result
+ def _getAvailability(self, obj, **args):
+ result = []
state = obj.getState()
- if state.contains(pyatspi.STATE_CHECKED):
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- selectionState = C_("radiobutton", "selected")
- else:
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- selectionState = C_("radiobutton", "not selected")
-
- # If it's not already focused, say it's name
- #
- if not already_focused:
- # The label is handled as a context in default.py
+ if not state.contains(pyatspi.STATE_SENSITIVE):
+ # Translators: this represents an item on the screen that has
+ # been set insensitive (or grayed out).
#
- #utterances.extend(self._getSpeechForObjectLabel(obj))
- utterances.extend(self._getSpeechForObjectName(obj))
- utterances.append(selectionState)
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
- else:
- utterances.append(selectionState)
-
- self._debugGenerator("_getSpeechForRadioButton",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForRadioMenuItem(self, obj, already_focused):
- """Get the speech for a radio menu item. If the menu item
- already had focus, then only the state is spoken.
-
- Arguments:
- - obj: the radio menu item
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
- utterances.extend(self._getSpeechForRadioButton(obj, False))
-
- if not already_focused:
- self._addSpeechForObjectAccelerator(obj, utterances)
-
- self._debugGenerator("_getSpeechForRadioMenuItem",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForRowHeader(self, obj, already_focused):
- """Get the speech for a row header.
-
- Arguments:
- - obj: the column header
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForRowHeader",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForScrollBar(self, obj, already_focused):
- """Get the speech for a scroll bar.
-
- Arguments:
- - obj: the scroll bar
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # [[[TODO: WDW - want to get orientation and maybe the
- # percentage scrolled so far. Logged as bugzilla bug
- # 319744.]]]
- #
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForScrollBar",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForSlider(self, obj, already_focused):
- """Get the speech for a slider. If the object already
- had focus, just the value is spoken.
-
- Arguments:
- - obj: the slider
- - already_focused: False if object just received focus
+ result.append(_("grayed"))
+ return result
- Returns a list of utterances to be spoken for the object.
- """
-
- valueString = self._script.getTextForValue(obj)
-
- if already_focused:
- utterances = [valueString]
- else:
- utterances = []
- utterances.extend(self._getSpeechForObjectLabel(obj))
- # Ignore the text on the slider. See bug 340559
- # (http://bugzilla.gnome.org/show_bug.cgi?id=340559): the
- # implementors of the slider support decided to put in a
- # Unicode left-to-right character as part of the text,
- # even though that is not painted on the screen.
- #
- # In Java, however, there are sliders without a label. In
- # this case, we'll add to presentation the slider name if
- # it exists and we haven't found anything yet.
- #
- if not utterances:
- utterances.extend(self._getSpeechForObjectName(obj))
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(valueString)
- utterances.extend(self._getSpeechForRequiredObject(obj))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
- self._debugGenerator("_getSpeechForSlider",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForSpinButton(self, obj, already_focused):
- """Get the speech for a spin button. If the object already has
- focus, then only the new value is spoken.
+ def _getRequired(self, obj, **args):
+ result = []
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_REQUIRED):
+ result = [settings.speechRequiredStateString]
+ return result
- Arguments:
- - obj: the spin button
- - already_focused: False if object just received focus
+ def _getReadOnly(self, obj, **args):
+ result = []
+ if settings.presentReadOnlyText \
+ and self._script.isReadOnlyTextArea(obj):
+ result.append(settings.speechReadOnlyString)
+ return result
- Returns a list of utterances to be spoken for the object.
- """
+ #####################################################################
+ # #
+ # Image information #
+ # #
+ #####################################################################
- if already_focused:
- utterances = [self._script.getDisplayedText(obj)]
+ def _getImageDescription(self, obj, **args ):
+ result = []
+ try:
+ image = obj.queryImage()
+ except NotImplementedError:
+ pass
else:
- utterances = self._getDefaultSpeech(obj, already_focused)
- utterances.extend(self._getSpeechForRequiredObject(obj))
-
- self._debugGenerator("_getSpeechForSpinButton",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForSplitPane(self, obj, already_focused):
- """Get the speech for a split pane.
-
- Arguments:
- - obj: the split pane
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- valueString = self._script.getTextForValue(obj)
+ description = image.imageDescription
+ if description and len(description):
+ result.append(description)
+ return result
- if already_focused:
- utterances = [valueString]
+ def _getImage(self, obj, **args):
+ result = []
+ try:
+ image = obj.queryImage()
+ except:
+ pass
else:
- utterances = []
- utterances.extend(self._getSpeechForObjectLabel(obj))
- if not utterances:
- utterances.extend(self._getSpeechForObjectName(obj))
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(valueString)
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
-
- self._debugGenerator("_getSpeechForSplitPane",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTable(self, obj, already_focused):
- """Get the speech for a table
-
- Arguments:
- - obj: the table
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTable",
- obj,
- already_focused,
- utterances)
-
- # If this is a table with no children, then let the user know.
- #
- if not obj.childCount:
- # Translators: this is the number of items in a layered pane
- # or table.
- #
- utterances.append(_("0 items"))
-
- return utterances
-
- def _getSpeechForTableCell(self, obj, already_focused):
- """Get the speech utterances for a single table cell
-
- Arguments:
- - obj: the table
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
+ role = pyatspi.ROLE_IMAGE
+ result.extend(self.getSpeech(obj, role=role))
+ return result
+
+ #####################################################################
+ # #
+ # Table interface information #
+ # #
+ #####################################################################
+
+ def _getTableCell2ChildLabel(self, obj, **args):
+ """Get the speech utterances for the label of a toggle in a table cell
+ that has a special 2 child pattern that we run into."""
+ # pylint: disable-msg=W0142
+ result = []
- # If this table cell has 2 children and one of them has a
- # 'toggle' action and the other does not, then present this
+ # If this table cell has 2 children and one of them has a
+ # 'toggle' action and the other does not, then present this
# as a checkbox where:
# 1) we get the checked state from the cell with the 'toggle' action
# 2) we get the label from the other cell.
@@ -1440,7 +377,7 @@ class SpeechGenerator:
#
if obj.childCount == 2:
cellOrder = []
- hasToggle = [ False, False ]
+ hasToggle = [False, False]
for i, child in enumerate(obj):
try:
action = child.queryAction()
@@ -1455,485 +392,336 @@ class SpeechGenerator:
if action.getName(j) in ["toggle", _("toggle")]:
hasToggle[i] = True
break
-
if hasToggle[0] and not hasToggle[1]:
- cellOrder = [ 1, 0 ]
+ cellOrder = [ 1, 0 ]
elif not hasToggle[0] and hasToggle[1]:
cellOrder = [ 0, 1 ]
if cellOrder:
for i in cellOrder:
- # Don't speak the label if just the checkbox state has
- # changed.
- #
- if already_focused and not hasToggle[i]:
- pass
- else:
- utterances.extend( \
- self._getSpeechForTableCell(obj[i],
- already_focused))
- return utterances
-
- # [[[TODO: WDW - Attempt to infer the cell type. There's a
- # bunch of stuff we can do here, such as check the EXPANDABLE
- # state, check the NODE_CHILD_OF relation, etc. Logged as
- # bugzilla bug 319750.]]]
- #
- try:
- action = obj.queryAction()
- except NotImplementedError:
- action = None
- if action:
- for i in range(0, action.nActions):
- debug.println(debug.LEVEL_FINEST,
- "speechgenerator.__getTableCellUtterances " \
- + "looking at action %d" % i)
+ if not hasToggle[i]:
+ result.extend(self.getSpeech(obj[i], **args))
+ return result
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(i) in ["toggle", _("toggle")]:
- utterances = self._getSpeechForCheckBox(obj,
- already_focused)
- break
+ def _getTableCell2ChildToggle(self, obj, **args):
+ """Get the speech utterances for the toggle value in a table cell that
+ has a special 2 child pattern that we run into."""
+ # pylint: disable-msg=W0142
+ result = []
- displayedText = self._script.getDisplayedText( \
- self._script.getRealActiveDescendant(obj))
- if not already_focused and not displayedText in utterances:
- utterances.append(displayedText)
-
- # If there is no displayed text, check to see if this table cell
- # contains an icon (image). If yes:
- # 1/ Try to get a description for it and speak that.
- # 2/ Treat the object of role type ROLE_IMAGE and speak
- # the role name.
- # See bug #465989 for more details.
+ # If this table cell has 2 children and one of them has a
+ # 'toggle' action and the other does not, then present this
+ # as a checkbox where:
+ # 1) we get the checked state from the cell with the 'toggle' action
+ # 2) we get the label from the other cell.
+ # See Orca bug #376015 for more details.
#
- # [[TODO: eitani - incorprate this in new rolenames ]]
- try:
- image = obj.queryImage()
- except:
- image = None
-
- if (not displayedText or len(displayedText) == 0) and image:
- if not already_focused:
- if image.imageDescription:
- utterances.append(image.imageDescription)
- utterances.extend(self._getSpeechForImage(obj, already_focused))
-
- state = obj.getState()
- if state.contains(pyatspi.STATE_EXPANDABLE):
- if state.contains(pyatspi.STATE_EXPANDED):
- # Translators: this represents the state of a node in a tree.
- # 'expanded' means the children are showing.
- # 'collapsed' means the children are not showing.
- #
- utterances.append(_("expanded"))
- childNodes = self._script.getChildNodes(obj)
- children = len(childNodes)
-
- if not children \
- or (settings.speechVerbosityLevel == \
- settings.VERBOSITY_LEVEL_VERBOSE):
- # Translators: this is the number of items in a layered
- # pane or table.
- #
- itemString = ngettext("%d item",
- "%d items",
- children) % children
- utterances.append(itemString)
- else:
- # Translators: this represents the state of a node in a tree.
- # 'expanded' means the children are showing.
- # 'collapsed' means the children are not showing.
- #
- utterances.append(_("collapsed"))
-
- utterances.extend(self._getSpeechForRequiredObject(obj))
-
- self._debugGenerator("_getSpeechForTableCell",
- obj,
- already_focused,
- utterances)
+ if obj.childCount == 2:
+ cellOrder = []
+ hasToggle = [False, False]
+ for i, child in enumerate(obj):
+ try:
+ action = child.queryAction()
+ except NotImplementedError:
+ continue
+ else:
+ for j in range(0, action.nActions):
+ # Translators: this is the action name for
+ # the 'toggle' action. It must be the same
+ # string used in the *.po file for gail.
+ #
+ if action.getName(j) in ["toggle", _("toggle")]:
+ hasToggle[i] = True
+ break
- return utterances
+ if hasToggle[0] and not hasToggle[1]:
+ cellOrder = [ 1, 0 ]
+ elif not hasToggle[0] and hasToggle[1]:
+ cellOrder = [ 0, 1 ]
+ if cellOrder:
+ for i in cellOrder:
+ if hasToggle[i]:
+ result.extend(self.getSpeech(obj[i], **args))
+ return result
- def _getSpeechForTableCellRow(self, obj, already_focused):
+ def _getTableCellRow(self, obj, **args):
"""Get the speech for a table cell row or a single table cell
- if settings.readTableCellRow is False.
-
- Arguments:
- - obj: the table
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
+ if settings.readTableCellRow is False."""
+ # pylint: disable-msg=W0142
+ result = []
- if (not already_focused):
- try:
- parent_table = obj.parent.queryTable()
- except NotImplementedError:
- parent_table = None
- if settings.readTableCellRow and parent_table \
- and (not self._script.isLayoutOnly(obj.parent)):
- parent = obj.parent
- index = self._script.getCellIndex(obj)
- row = parent_table.getRowAtIndex(index)
- column = parent_table.getColumnAtIndex(index)
-
- # This is an indication of whether we should speak all the
- # table cells (the user has moved focus up or down a row),
- # or just the current one (focus has moved left or right in
- # the same row).
- #
- speakAll = True
- if "lastRow" in self._script.pointOfReference and \
- "lastColumn" in self._script.pointOfReference:
- pointOfReference = self._script.pointOfReference
- speakAll = (pointOfReference["lastRow"] != row) or \
- ((row == 0 or row == parent_table.nRows-1) and \
- pointOfReference["lastColumn"] == column)
-
- if speakAll:
- for i in range(0, parent_table.nColumns):
- cell = parent_table.getAccessibleAt(row, i)
- if not cell:
- debug.println(debug.LEVEL_WARNING,
- "ERROR: speechgenerator." \
- + "_getSpeechForTableCellRow" \
- + " no accessible at (%d, %d)" % (row, i))
- continue
- state = cell.getState()
- showing = state.contains(pyatspi.STATE_SHOWING)
- if showing:
- # If this table cell has a "toggle" action, and
- # doesn't have any label associated with it then
- # also speak the table column header.
- # See Orca bug #455230 for more details.
- #
- label = self._script.getDisplayedText( \
- self._script.getRealActiveDescendant(cell))
- try:
- action = cell.queryAction()
- except NotImplementedError:
- action = None
- if action and (label == None or len(label) == 0):
- for j in range(0, action.nActions):
- # Translators: this is the action name for
- # the 'toggle' action. It must be the same
- # string used in the *.po file for gail.
- #
- if action.getName(j) in ["toggle", \
- _("toggle")]:
- accHeader = \
- parent_table.getColumnHeader(i)
- utterances.append(accHeader.name)
-
- utterances.extend(self._getSpeechForTableCell(cell,
- already_focused))
- else:
- utterances.extend(self._getSpeechForTableCell(obj,
- already_focused))
+ try:
+ parentTable = obj.parent.queryTable()
+ except NotImplementedError:
+ parentTable = None
+ if settings.readTableCellRow and parentTable \
+ and (not self._script.isLayoutOnly(obj.parent)):
+ parent = obj.parent
+ index = self._script.getCellIndex(obj)
+ row = parentTable.getRowAtIndex(index)
+ column = parentTable.getColumnAtIndex(index)
+
+ # This is an indication of whether we should speak all the
+ # table cells (the user has moved focus up or down a row),
+ # or just the current one (focus has moved left or right in
+ # the same row).
+ #
+ speakAll = True
+ if "lastRow" in self._script.pointOfReference \
+ and "lastColumn" in self._script.pointOfReference:
+ pointOfReference = self._script.pointOfReference
+ speakAll = \
+ (pointOfReference["lastRow"] != row) \
+ or ((row == 0 or row == parentTable.nRows-1) \
+ and pointOfReference["lastColumn"] == column)
+ if speakAll:
+ for i in range(0, parentTable.nColumns):
+ cell = parentTable.getAccessibleAt(row, i)
+ if not cell:
+ continue
+ state = cell.getState()
+ showing = state.contains(pyatspi.STATE_SHOWING)
+ if showing:
+ # If this table cell has a "toggle" action, and
+ # doesn't have any label associated with it then
+ # also speak the table column header.
+ # See Orca bug #455230 for more details.
+ #
+ label = self._script.getDisplayedText(
+ self._script.getRealActiveDescendant(cell))
+ try:
+ action = cell.queryAction()
+ except NotImplementedError:
+ action = None
+ if action and (label == None or len(label) == 0):
+ for j in range(0, action.nActions):
+ # Translators: this is the action name for
+ # the 'toggle' action. It must be the same
+ # string used in the *.po file for gail.
+ #
+ if action.getName(j) in ["toggle",
+ _("toggle")]:
+ accHeader = \
+ parentTable.getColumnHeader(i)
+ result.append(accHeader.name)
+ oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
+ args)
+ result.extend(
+ self.getSpeech(cell,
+ **args))
+ _restoreRole(oldRole, args)
else:
- utterances = self._getSpeechForTableCell(obj, already_focused)
- else:
- utterances = self._getSpeechForTableCell(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTableCellRow",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTableColumnHeader(self, obj, already_focused):
- """Get the speech for a table column header
-
- Arguments:
- - obj: the table column header
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getSpeechForColumnHeader(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTableColumnHeader",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTableRowHeader(self, obj, already_focused):
- """Get the speech for a table row header
-
- Arguments:
- - obj: the table row header
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getSpeechForRowHeader(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTableRowHeader",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTearOffMenuItem(self, obj, already_focused):
- """Get the speech for a tear off menu item
-
- Arguments:
- - obj: the tear off menu item
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- if settings.speechVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- utterances = [rolenames.getSpeechForRoleName(obj)]
+ oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
+ args)
+ result.extend(
+ self.getSpeech(obj, **args))
+ _restoreRole(oldRole, args)
else:
- # Translators: brief spoken words for the rolename of a tear off
- # menu item.
- #
- utterances = [_("tear off")]
-
- self._debugGenerator("_getSpeechForTearOffMenuItem",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTerminal(self, obj, already_focused):
- """Get the speech for a terminal
-
- Arguments:
- - obj: the terminal
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
+ oldRole = _overrideRole('REAL_ROLE_TABLE_CELL',
+ args)
+ result = self.getSpeech(obj, **args)
+ _restoreRole(oldRole, args)
+ return result
+
+ #####################################################################
+ # #
+ # Terminal information #
+ # #
+ #####################################################################
+
+ def _getTerminal(self, obj, **args):
+ result = []
title = None
frame = self._script.getFrame(obj)
if frame:
title = frame.name
if not title:
title = self._script.getDisplayedLabel(obj)
+ result.append(title)
+ return result
- utterances = [title]
+ #####################################################################
+ # #
+ # Text interface information #
+ # #
+ #####################################################################
- self._debugGenerator("_getSpeechForTerminal",
- obj,
- already_focused,
- utterances)
-
- return utterances
+ def _getCurrentLineText(self, obj, **args ):
+ [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
+ return [text]
- def _getSpeechForToggleButton(self, obj, already_focused):
- """Get the speech for a toggle button. If the toggle button already
- had focus, then only the state is spoken.
+ def _getDisplayedText(self, obj, **args ):
+ """Returns the text being displayed for an object or the object's
+ name if no text is being displayed."""
+ return [self._script.getDisplayedText(obj)]
- Arguments:
- - obj: the check box
- - already_focused: False if object just received focus
+ def _getAllTextSelection(self, obj, **args):
+ """Check if this object has text associated with it and it's
+ completely selected."""
+ result = []
+ try:
+ textObj = obj.queryText()
+ except:
+ pass
+ else:
+ noOfSelections = textObj.getNSelections()
+ if noOfSelections == 1:
+ [string, startOffset, endOffset] = \
+ textObj.getTextAtOffset(0, pyatspi.TEXT_BOUNDARY_LINE_START)
+ if startOffset == 0 and endOffset == len(string):
+ # Translators: when the user selects (highlights) text in
+ # a document, Orca lets them know this.
+ #
+ result = [C_("text", "selected")]
+ return result
- Returns a list of utterances to be spoken for the object.
- """
+ #####################################################################
+ # #
+ # Value interface information #
+ # #
+ #####################################################################
- utterances = []
+ def _getValue(self, obj, **args):
+ return [self._script.getTextForValue(obj)]
- state = obj.getState()
- if state.contains(pyatspi.STATE_CHECKED) \
- or state.contains(pyatspi.STATE_PRESSED):
- # Translators: the state of a toggle button.
- #
- checkedState = _("pressed")
+ def _getPercentage(self, obj, **args ):
+ result = []
+ try:
+ value = obj.queryValue()
+ except NotImplementedError:
+ pass
else:
- # Translators: the state of a toggle button.
+ percentValue = \
+ (value.currentValue
+ / (value.maximumValue - value.minimumValue)) \
+ * 100.0
+ # Translators: this is the percentage value of a progress bar.
#
- checkedState = _("not pressed")
-
- # If it's not already focused, say it's name
- #
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(checkedState)
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- self._addSpeechForObjectMnemonic(obj, utterances)
+ percentage = _("%d percent.") % percentValue + " "
+ result.append(percentage)
+ return result
+
+ #####################################################################
+ # #
+ # Hierarchy and related dialog information #
+ # #
+ #####################################################################
+
+ def _getRealActiveDescendantDisplayedText(self, obj, **args ):
+ text = self._script.getDisplayedText(
+ self._script.getRealActiveDescendant(obj))
+ if text:
+ return [text]
else:
- utterances.append(checkedState)
-
- self._debugGenerator("_getSpeechForToggleButton",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForToolBar(self, obj, already_focused):
- """Get the speech for a tool bar
-
- Arguments:
- - obj: the tool bar
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForToolBar",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTree(self, obj, already_focused):
- """Get the speech for a tree
-
- Arguments:
- - obj: the tree
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTree",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForTreeTable(self, obj, already_focused):
- """Get the speech for a tree table
-
- Arguments:
- - obj: the tree table
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForTreeTable",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForWindow(self, obj, already_focused):
- """Get the speech for a window
-
- Arguments:
- - obj: the window
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- self._debugGenerator("_getSpeechForWindow",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _dumpAndStripAltSpeech(self, result, voice=None, indent=""):
- """Dumps and strips the array-based speech from the
- alternate speech generator. The full result is
- dumped to stdout and the return value is a single
- depth array of only strings."""
- import acss
- import speech
- newResult = []
- subString = None
- didACSS = False
- for element in result:
- if isinstance(element, basestring):
- if subString:
- subString += " " + element
- else:
- subString = element
- newResult.append(element)
- else:
- if subString:
- print indent + subString
- subString = None
- if isinstance(element, list):
- newResult.extend(
- self._dumpAndStripAltSpeech(element, voice, indent))
- elif isinstance(element, acss.ACSS):
- print indent + '<voice acss=\"%s">' % element
- indent += " "
- didACSS = True
- voice=acss.ACSS(voice)
- voice.update(element)
- else:
- print indent + "UNKNOWN element", element
- if subString:
- print indent + subString
- if didACSS:
- print indent[:-2] + '</voice>'
-
- return newResult
-
- def getSpeech(self, obj, already_focused, **args):
- """Get the speech for an Accessible object. This will look
- first to the specific speech generators and then to the
- default speech generator. This method is the primary method
- that external callers of this class should use.
+ return []
- Arguments:
- - obj: the object
- - already_focused: False if object just received focus
+ def _getNumberOfChildren(self, obj, **args):
+ result = []
+ childNodes = self._script.getChildNodes(obj)
+ children = len(childNodes)
+ if children:
+ # Translators: this is the number of items in a layered
+ # pane or table.
+ #
+ itemString = ngettext("%d item", "%d items", children) % children
+ result.append(itemString)
+ return result
- Returns a list of utterances to be spoken.
- """
- # pylint: disable-msg=W0142
- role = obj.getRole()
- if role in self.speechGenerators:
- generator = self.speechGenerators[role]
- else:
- generator = self._getDefaultSpeech
- print("processing obj of role %s\n" % obj.getRoleName())
- result1 = [" ".join(generator(obj, already_focused))]
- print("r%d='%s'\n" %(len(result1[0]), result1))
-
- result2 = self.alt.getSpeech(obj, \
- already_focused=already_focused, **args)
- import speech
- speech.altspeak(result2)
- result2 = self._dumpAndStripAltSpeech(result2)
-
- # making the returned values from alt.getSpeech into a string.
- speak = [" ".join(result2)]
- print("s%d='%s'\n" %(len(speak[0]), speak))
- print("r==s=%s\n" %cmp(result1[0], speak[0]))
- return speak
+ def _getNoShowingChildren(self, obj, **args):
+ result = []
+ hasItems = False
+ for child in obj:
+ state = child.getState()
+ if state.contains(pyatspi.STATE_SHOWING):
+ hasItems = True
+ break
+ if not hasItems:
+ # Translators: this is the number of items in a layered pane
+ # or table.
+ #
+ result.append(_("0 items"))
+ return result
- def getSpeechContext(self, obj, stopAncestor=None):
- """Get the speech that describes the names and role of
+ def _getNoChildren(self, obj, **args ):
+ result = []
+ if not obj.childCount:
+ # Translators: this is the number of items in a layered pane
+ # or table.
+ #
+ result.append(_("0 items"))
+ return result
+
+ def _getUnfocusedDialogCount(self, obj, **args):
+ result = []
+ # If this application has more than one unfocused alert or
+ # dialog window, then speak '<m> unfocused dialogs'
+ # to let the user know.
+ #
+ alertAndDialogCount = \
+ self._script.getUnfocusedAlertAndDialogCount(obj)
+ if alertAndDialogCount > 0:
+ # Translators: this tells the user how many unfocused
+ # alert and dialog windows that this application has.
+ #
+ result.append(ngettext("%d unfocused dialog",
+ "%d unfocused dialogs",
+ alertAndDialogCount) % alertAndDialogCount)
+ return result
+
+ #####################################################################
+ # #
+ # Keyboard shortcut information #
+ # #
+ #####################################################################
+
+ def _getAccelerator(self, obj, **args):
+ result = []
+ [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
+ if accelerator:
+ # Add punctuation for better prosody.
+ #
+ #if result:
+ # result[-1] += "."
+ result.append(accelerator)
+ return result
+
+ def _getMnemonic(self, obj, **args):
+ result = []
+ [mnemonic, shortcut, accelerator] = self._script.getKeyBinding(obj)
+ if mnemonic:
+ mnemonic = mnemonic[-1] # we just want a single character
+ if not mnemonic and shortcut:
+ mnemonic = shortcut
+ if mnemonic:
+ # Add punctuation for better prosody.
+ #
+ #if result:
+ # utterances[-1] += "."
+ result = [mnemonic]
+ return result
+
+
+ #####################################################################
+ # #
+ # Tutorial information #
+ # #
+ #####################################################################
+
+ def _getTutorial(self, obj, **args):
+ already_focused = args.get('already_focused')
+ forceMessage = args.get('forceMessage', False)
+ return self._script.tutorialGenerator.getTutorial(
+ obj,
+ already_focused,
+ forceMessage)
+
+ #####################################################################
+ # #
+ # Get the context of where the object is. #
+ # #
+ #####################################################################
+
+ def _getContext(self, obj, stopAncestor=None):
+ """Get the information that describes the names and role of
the container hierarchy of the object, stopping at and
not including the stopAncestor.
@@ -1942,16 +730,12 @@ class SpeechGenerator:
- stopAncestor: the anscestor to stop at and not include (None
means include all ancestors)
- Returns a list of utterances to be spoken.
"""
- utterances = []
-
- if not obj:
- return utterances
+ result = []
- if obj == stopAncestor:
- return utterances
+ if not obj or obj == stopAncestor:
+ return result
parent = obj.parent
if parent \
@@ -1971,13 +755,78 @@ class SpeechGenerator:
#
if parent.getRole() not in [pyatspi.ROLE_TABLE_CELL,
pyatspi.ROLE_FILLER]:
- utterances.extend(self.getSpeechForObjectRole(parent))
- utterances.append(text)
+ result.extend(self._getRoleName(parent))
+ result.append(text)
if parent.getRole() == pyatspi.ROLE_TABLE_CELL:
- utterances.extend(self.getSpeechForObjectRole(parent))
+ result.extend(self._getRoleName(parent))
parent = parent.parent
- utterances.reverse()
+ result.reverse()
+
+ return result
+
+ # [[[TODO: WDW - need to figure out the context stuff still.
+ #
+ def getSpeechContext(self, obj, stopAncestor=None):
+ return self._getContext(obj, stopAncestor)
+
+ #####################################################################
+ # #
+ # Tie it all together #
+ # #
+ #####################################################################
+
+ def voice(self, key=None):
+ try:
+ voice = settings.voices[key]
+ except:
+ voice = settings.voices[settings.DEFAULT_VOICE]
+ return [voice]
+
+ def getSpeech(self, obj, already_focused=False, **args):
+ # pylint: disable-msg=W0142
+ result = []
+ methods = {}
+ methods["voice"] = self.voice
+ methods["obj"] = obj
+ methods["role"] = args.get('role', obj.getRole())
+
+ try:
+ # We sometimes want to override the role. We'll keep the
+ # role in the args dictionary as a means to let us do so.
+ #
+ args['role'] = methods["role"]
+
+ # We loop through the format string, catching each error
+ # as we go. Each error should always be a NameError,
+ # where the name is the name of one of our generator
+ # functions. When we encounter this, we call the function
+ # and get its results, placing them in the globals for the
+ # the call to eval.
+ #
+ args['already_focused'] = already_focused
+ format = self._script.formatting.getFormat('speech',
+ **args)
+ assert(format)
+ while True:
+ try:
+ result = eval(format, methods)
+ break
+ except NameError:
+ result = []
+ info = _formatExceptionInfo()
+ arg = info[1][0]
+ arg = arg.replace("name '", "")
+ arg = arg.replace("' is not defined", "")
+ if not self._methodsDict.has_key(arg):
+ debug.printException(
+ debug.LEVEL_SEVERE,
+ "Unable to find function for '%s'\n" % arg)
+ break
+ methods[arg] = self._methodsDict[arg](obj, **args)
+ except:
+ debug.printException(debug.LEVEL_SEVERE)
+ result = []
- return utterances
+ return result
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 133ac0f..abae738 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -1771,6 +1771,8 @@ class StructuralNavigation:
voice = self._getVoice(obj, string)
speech.speak(string, voice)
+ # [[[TODO: WDW - this needs to be moved to the speech generator.]]]
+ #
def _getVoice(self, obj, string):
"""Returns the voice to speak anything for the given obj.
diff --git a/src/orca/where_am_I.py b/src/orca/where_am_I.py
index 1eefad8..66f4f10 100644
--- a/src/orca/where_am_I.py
+++ b/src/orca/where_am_I.py
@@ -190,7 +190,7 @@ class WhereAmI:
debug.println(self._debugLevel, "check box utterances=%s" \
% utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakRadioButton(self, obj, basicOnly):
"""Radio Buttons present the following information (an example is
@@ -242,7 +242,7 @@ class WhereAmI:
debug.println(self._debugLevel, "radio button utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakComboBox(self, obj, basicOnly):
"""Comboboxes present the following information (an example is
@@ -278,7 +278,7 @@ class WhereAmI:
debug.println(self._debugLevel, "combo box utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakSpinButton(self, obj, basicOnly):
"""Spin Buttons present the following information (an example is
@@ -317,7 +317,7 @@ class WhereAmI:
debug.println(self._debugLevel, "spin button utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakPushButton(self, obj, basicOnly):
""" Push Buttons present the following information (an example is
@@ -344,7 +344,7 @@ class WhereAmI:
debug.println(self._debugLevel, "push button utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakSlider(self, obj, basicOnly):
"""Sliders present the following information (examples include
@@ -383,7 +383,7 @@ class WhereAmI:
debug.println(self._debugLevel, "slider utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakMenuItem(self, obj, basicOnly):
"""Menu items present the following information (examples include
@@ -458,7 +458,7 @@ class WhereAmI:
debug.println(self._debugLevel, "menu item utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakPageTab(self, obj, basicOnly):
"""Tabs in a Tab List present the following information (an example
@@ -492,7 +492,7 @@ class WhereAmI:
debug.println(self._debugLevel, "page utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakText(self, obj, basicOnly):
"""Text boxes present the following information (an example is
@@ -552,7 +552,7 @@ class WhereAmI:
debug.println(self._debugLevel, "first text utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
if not basicOnly:
settings.verbalizePunctuationStyle = savedStyle
@@ -573,7 +573,7 @@ class WhereAmI:
debug.println(self._debugLevel, "text utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakTableCell(self, obj, basicOnly):
"""Tree Tables present the following information (an example is
@@ -635,7 +635,7 @@ class WhereAmI:
debug.println(self._debugLevel, "first table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
utterances = []
if table:
@@ -648,7 +648,7 @@ class WhereAmI:
#
text = _("row %d of %d") % ((row + 1), table.nRows)
utterances.append(text)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
# Speak the current row if performing a "detailed" whereAmI.
#
@@ -657,7 +657,7 @@ class WhereAmI:
debug.println(self._debugLevel, \
"second table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
utterances = []
state = obj.getState()
@@ -688,7 +688,7 @@ class WhereAmI:
debug.println(self._debugLevel, "third table cell utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakListItem(self, obj, basicOnly):
"""List items should be treated like tree cells:
@@ -753,7 +753,7 @@ class WhereAmI:
debug.println(self._debugLevel, "list item utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakParagraph(self, obj, basicOnly):
"""Speak a paragraph object.
@@ -787,7 +787,7 @@ class WhereAmI:
[frame, dialogue] = self._getFrameAndDialog(obj)
utterances.extend(getTutorial(frame, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakLink(self, obj, basicOnly):
"""Speaks information about a link including protocol, domain
@@ -876,7 +876,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakToggleButton(self, obj, basicOnly):
"""Speak toggle button information:
@@ -906,7 +906,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakSplitPane(self, obj, basicOnly):
"""Speak split pane information:
@@ -929,7 +929,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakLabel(self, obj, basicOnly):
"""Speak label information:
@@ -951,7 +951,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakLayeredPane(self, obj, basicOnly):
@@ -973,7 +973,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getSpeechForAllTextSelection(self, obj):
@@ -1097,7 +1097,7 @@ class WhereAmI:
getTutorial = self._script.tutorialGenerator.getTutorial
utterances.extend(getTutorial(obj, False, forceMessage=True))
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getObjName(self, obj):
@@ -1799,7 +1799,7 @@ class WhereAmI:
debug.println(self._debugLevel, "titlebar utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def speakStatusBar(self, obj):
"""Speak the contents of the status bar of the window with focus.
@@ -1820,7 +1820,7 @@ class WhereAmI:
debug.println(self._debugLevel, "status bar utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getFrameAndDialog(self, obj):
"""Returns the frame and (possibly) the dialog containing
@@ -1886,7 +1886,7 @@ class WhereAmI:
debug.println(self._debugLevel, "statusbar utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getDefaultButton(self, obj):
"""Gets the default button in a dialog.
@@ -1940,7 +1940,7 @@ class WhereAmI:
debug.println(self._debugLevel, "default button utterances=%s" % \
utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _speakObjDescription(self, obj):
"""Speaks the object's description if it is not the same as
@@ -1978,7 +1978,7 @@ class WhereAmI:
debug.println(self._debugLevel, "toolbar utterances=%s" \
% utterances)
- speech.speakUtterances(utterances)
+ speech.speak(utterances)
def _getRequiredState(self, obj):
"""Returns a string describing the required state of the given
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]