orca r4016 - in trunk: . po src/orca src/orca/scripts/toolkits src/orca/scripts/toolkits/J2SE-access-bridge
- From: wwalker svn gnome org
- To: svn-commits-list gnome org
- Subject: orca r4016 - in trunk: . po src/orca src/orca/scripts/toolkits src/orca/scripts/toolkits/J2SE-access-bridge
- Date: Tue, 1 Jul 2008 17:40:13 +0000 (UTC)
Author: wwalker
Date: Tue Jul 1 17:40:13 2008
New Revision: 4016
URL: http://svn.gnome.org/viewvc/orca?rev=4016&view=rev
Log:
Work on bug #435623 - Java platform accessibility.
Added:
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/braillegenerator.py
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/speechgenerator.py
trunk/src/orca/scripts/toolkits/J2SE-access-bridge/where_am_I.py
Removed:
trunk/src/orca/scripts/toolkits/J2SE-access-bridge.py
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/po/POTFILES.in
trunk/src/orca/braillegenerator.py
trunk/src/orca/default.py
trunk/src/orca/orca.py
trunk/src/orca/scripts/toolkits/Makefile.am
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Tue Jul 1 17:40:13 2008
@@ -187,6 +187,7 @@
src/orca/scripts/apps/gnome-window-properties/Makefile
src/orca/scripts/toolkits/Makefile
src/orca/scripts/toolkits/Gecko/Makefile
+src/orca/scripts/toolkits/J2SE-access-bridge/Makefile
src/orca/orca
src/orca/orca_i18n.py
src/orca/platform.py
Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in (original)
+++ trunk/po/POTFILES.in Tue Jul 1 17:40:13 2008
@@ -60,7 +60,8 @@
src/orca/scripts/toolkits/Gecko/speech_generator.py
src/orca/scripts/toolkits/Gecko/structural_navigation.py
src/orca/scripts/toolkits/Gecko/where_am_i.py
-src/orca/scripts/toolkits/J2SE-access-bridge.py
+src/orca/scripts/toolkits/J2SE-access-bridge/braillegenerator.py
+src/orca/scripts/toolkits/J2SE-access-bridge/speechgenerator.py
src/orca/settings.py
src/orca/speechdispatcherfactory.py
src/orca/speechgenerator.py
Modified: trunk/src/orca/braillegenerator.py
==============================================================================
--- trunk/src/orca/braillegenerator.py (original)
+++ trunk/src/orca/braillegenerator.py Tue Jul 1 17:40:13 2008
@@ -1719,7 +1719,22 @@
if (row >= 0) \
and (not obj.getRole() in [pyatspi.ROLE_ROW_HEADER,
pyatspi.ROLE_TABLE_ROW_HEADER]):
+ # Get the header information. In Java Swing, the
+ # information is not exposed via the description
+ # but is instead a header object, so we fall back
+ # to that if it exists.
+ #
+ # [[[TODO: WDW - the more correct thing to do, I
+ # think, is to look at the row header object.
+ # We've been looking at the description for so
+ # long, though, that we'll give the description
+ # preference for now.]]]
+ #
desc = table.getRowDescription(row)
+ if not desc:
+ header = table.getRowHeader(row)
+ if header:
+ desc = self._script.getDisplayedText(header)
else:
desc = None
if desc and len(desc):
@@ -1740,7 +1755,22 @@
if (col >= 0) \
and (not obj.getRole() in [pyatspi.ROLE_COLUMN_HEADER,
pyatspi.ROLE_TABLE_COLUMN_HEADER]):
+ # Get the header information. In Java Swing, the
+ # information is not exposed via the description
+ # but is instead a header object, so we fall back
+ # to that if it exists.
+ #
+ # [[[TODO: WDW - the more correct thing to do, I
+ # think, is to look at the row header object.
+ # We've been looking at the description for so
+ # long, though, that we'll give the description
+ # preference for now.]]]
+ #
desc = table.getColumnDescription(col)
+ if not desc:
+ header = table.getColumnHeader(col)
+ if header:
+ desc = self._script.getDisplayedText(header)
else:
desc = None
if desc and len(desc):
Modified: trunk/src/orca/default.py
==============================================================================
--- trunk/src/orca/default.py (original)
+++ trunk/src/orca/default.py Tue Jul 1 17:40:13 2008
@@ -2754,15 +2754,21 @@
# We also keep track of tree level depth and only announce
# that if it changes.
#
+ # Note that Java Swing allows things like ROLE_LABEL objects
+ # in trees and tables, so we'll check the parent's role to
+ # see if it is a table.
+ #
oldNodeLevel = -1
newNodeLevel = -1
- if newLocusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL:
+ if (newLocusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL) \
+ or (newParent.getRole() == pyatspi.ROLE_TABLE):
try:
table = oldParent.queryTable()
except:
table = None
if table and \
- oldLocusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL:
+ ((oldLocusOfFocus.getRole() == pyatspi.ROLE_TABLE_CELL) \
+ or (oldParent.getRole() == pyatspi.ROLE_TABLE)):
index = self.getCellIndex(oldLocusOfFocus)
oldRow = table.getRowAtIndex(index)
oldCol = table.getColumnAtIndex(index)
@@ -2780,7 +2786,22 @@
newCol = table.getColumnAtIndex(index)
if (newRow != oldRow) or (oldParent != newParent):
+ # Get the header information. In Java Swing, the
+ # information is not exposed via the description
+ # but is instead a header object, so we fall back
+ # to that if it exists.
+ #
+ # [[[TODO: WDW - the more correct thing to do, I
+ # think, is to look at the row header object.
+ # We've been looking at the description for so
+ # long, though, that we'll give the description
+ # preference for now.]]]
+ #
desc = table.getRowDescription(newRow)
+ if not desc:
+ header = table.getRowHeader(newRow)
+ if header:
+ desc = self.getDisplayedText(header)
if desc and len(desc):
text = desc
if settings.speechVerbosityLevel \
@@ -2794,7 +2815,22 @@
# it's not possible to navigate across a row.
topName = self.getTopLevelName(newLocusOfFocus)
if not topName.endswith(" - Thunderbird"):
+ # Get the header information. In Java Swing, the
+ # information is not exposed via the description
+ # but is instead a header object, so we fall back
+ # to that if it exists.
+ #
+ # [[[TODO: WDW - the more correct thing to do, I
+ # think, is to look at the row header object.
+ # We've been looking at the description for so
+ # long, though, that we'll give the description
+ # preference for now.]]]
+ #
desc = table.getColumnDescription(newCol)
+ if not desc:
+ header = table.getColumnHeader(newCol)
+ if header:
+ desc = self.getDisplayedText(header)
cellText = self.getDisplayedText(newLocusOfFocus)
if desc and len(desc) and cellText != desc:
text = desc
@@ -3046,7 +3082,7 @@
self.speechGenerator.getSpeech(target, True))
return
- if obj != orca_state.locusOfFocus:
+ if not self.isSameObject(obj, orca_state.locusOfFocus):
return
if event:
@@ -3279,8 +3315,11 @@
return selSpoken
- def _presentTextAtNewCaretPosition(self, event):
- obj = event.source
+ def _presentTextAtNewCaretPosition(self, event, otherObj=None):
+ """Updates braille, magnification, and outputs speech for the
+ event.source or the otherObj."""
+
+ obj = otherObj or event.source
text = obj.queryText()
if obj:
Modified: trunk/src/orca/orca.py
==============================================================================
--- trunk/src/orca/orca.py (original)
+++ trunk/src/orca/orca.py Tue Jul 1 17:40:13 2008
@@ -607,7 +607,9 @@
def _setClickCount(inputEvent):
"""Sets the count of the number of clicks a user has made to one
- of the non-modifier keys on the keyboard.
+ of the non-modifier keys on the keyboard. Note that this looks at
+ the event_string (keysym) instead of hw_code (keycode) because
+ the Java platform gives us completely different keycodes for keys.
Arguments:
- inputEvent: the current input event.
@@ -621,7 +623,7 @@
orca_state.clickCount = 0
elif not isinstance(lastInputEvent, KeyboardEvent):
orca_state.clickCount = 1
- elif (lastInputEvent.hw_code != inputEvent.hw_code) or \
+ elif (lastInputEvent.event_string != inputEvent.event_string) or \
(lastInputEvent.modifiers != inputEvent.modifiers):
orca_state.clickCount = 1
elif (inputEvent.time - lastInputEvent.time) < \
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/Makefile.am Tue Jul 1 17:40:13 2008
@@ -0,0 +1,11 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ braillegenerator.py \
+ script.py \
+ speechgenerator.py \
+ where_am_I.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/toolkits/J2SE-access-bridge
+
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/__init__.py Tue Jul 1 17:40:13 2008
@@ -0,0 +1,4 @@
+from script import Script
+from speechgenerator import SpeechGenerator
+from braillegenerator import BrailleGenerator
+from where_am_I import WhereAmI
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/braillegenerator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/braillegenerator.py Tue Jul 1 17:40:13 2008
@@ -0,0 +1,89 @@
+# Orca
+#
+# Copyright 2006-2008 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.
+
+__id__ = "$Id: J2SE-access-bridge.py 3882 2008-05-07 18:22:10Z richb $"
+__version__ = "$Revision: 3882 $"
+__date__ = "$Date: 2008-05-07 14:22:10 -0400 (Wed, 07 May 2008) $"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.braille as braille
+import orca.braillegenerator as braillegenerator
+
+from orca.orca_i18n import _ # for gettext support
+
+########################################################################
+# #
+# Braille Generator #
+# #
+########################################################################
+
+class BrailleGenerator(braillegenerator.BrailleGenerator):
+ def __init__(self, script):
+ braillegenerator.BrailleGenerator.__init__(self, script)
+
+ def _getBrailleRegionsForLabel(self, obj):
+ """Get the braille for a label.
+
+ Arguments:
+ - obj: the label
+
+ Returns a list where the first element is a list of Regions to display
+ and the second element is the Region which should get focus.
+ """
+
+ self._debugGenerator("J2SE-access-bridge:_getBrailleRegionsForLabel",
+ obj)
+
+ regions = []
+
+ text = self._script.getDisplayedText(obj)
+
+ # In Java, tree objects are labels, so we need to look at their
+ # states in order to tell whether they are expanded or collapsed.
+ #
+ 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.
+ #
+ text = self._script.appendString(text, _('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.
+ #
+ text = self._script.appendString(text, _('collapsed'))
+
+ level = self._script.getNodeLevel(obj)
+ if level >= 0:
+ # Translators: this represents the depth of a node in a tree
+ # view (i.e., how many ancestors a node has).
+ #
+ text = self._script.appendString(text,
+ _("TREE LEVEL %d") % (level + 1))
+
+ region = braille.Component(obj, text)
+ regions.append(region)
+
+ return [regions, region]
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/script.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/script.py Tue Jul 1 17:40:13 2008
@@ -0,0 +1,305 @@
+# Orca
+#
+# Copyright 2006-2008 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.
+
+__id__ = "$Id: J2SE-access-bridge.py 3882 2008-05-07 18:22:10Z richb $"
+__version__ = "$Revision: 3882 $"
+__date__ = "$Date: 2008-05-07 14:22:10 -0400 (Wed, 07 May 2008) $"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.default as default
+import orca.input_event as input_event
+import orca.orca as orca
+import orca.orca_state as orca_state
+import orca.keybindings as keybindings
+
+from braillegenerator import BrailleGenerator
+from speechgenerator import SpeechGenerator
+from where_am_I import WhereAmI
+
+########################################################################
+# #
+# The Java script class. #
+# #
+########################################################################
+
+class Script(default.Script):
+
+ def __init__(self, app):
+ """Creates a new script for Java applications.
+
+ Arguments:
+ - app: the application to create a script for.
+ """
+ default.Script.__init__(self, app)
+
+ def getWhereAmI(self):
+ """Returns the "where am I" class for this script.
+ """
+ return WhereAmI(self)
+
+ def getBrailleGenerator(self):
+ """Returns the braille generator for this script.
+ """
+ return BrailleGenerator(self)
+
+ def getSpeechGenerator(self):
+ """Returns the braille generator for this script.
+ """
+ return SpeechGenerator(self)
+
+ def consumesKeyboardEvent(self, keyboardEvent):
+ """Called when a key is pressed on the keyboard.
+
+ Arguments:
+ - keyboardEvent: an instance of input_event.KeyboardEvent
+
+ Returns True if the event is of interest.
+ """
+
+ # The Java platform chooses to give us keycodes different from
+ # the native platform keycodes. So, we hack here by converting
+ # the keysym we get from Java into a keycode.
+
+ keysym = keyboardEvent.event_string
+
+ # We need to make sure we have a keysym-like thing. The space
+ # character is not a keysym, so we convert it into the string,
+ # 'space', which is.
+ #
+ if keysym == " ":
+ keysym = "space"
+
+ keyboardEvent.hw_code = keybindings.getKeycode(keysym)
+ return default.Script.consumesKeyboardEvent(self, keyboardEvent)
+
+ def getNodeLevel(self, obj):
+ """Determines the node level of this object if it is in a tree
+ relation, with 0 being the top level node. If this object is
+ not in a tree relation, then -1 will be returned.
+
+ Arguments:
+ -obj: the Accessible object
+ """
+
+ if not obj:
+ return -1
+
+ treeLikeThing = self.getAncestor(obj,
+ [pyatspi.ROLE_TREE,
+ pyatspi.ROLE_TABLE,
+ pyatspi.ROLE_TREE_TABLE],
+ None)
+ if not treeLikeThing:
+ return -1
+
+ count = 0
+ while True:
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_EXPANDABLE) \
+ or state.contains(pyatspi.STATE_COLLAPSED):
+ if state.contains(pyatspi.STATE_VISIBLE):
+ count += 1
+ obj = obj.parent
+ else:
+ break
+
+ return count - 1
+
+ def onFocus(self, event):
+ """Called whenever an object gets focus.
+
+ Arguments:
+ - event: the Event
+ """
+
+ role = event.source.getRole()
+
+ if role == pyatspi.ROLE_MENU:
+ # Override default.py's onFocus decision to ignore focus
+ # events on MENU items with selected children. This is
+ # because JMenu's pop up without their children selected,
+ # but for some reason they always have
+ # selection.nSelectedChildren > 0. I suspect this is a
+ # bug in JMenu.java:getAccessibleSelectionCount, but the
+ # details of Swing's MenuSelectionManager are foreign to
+ # me. So, for now, we'll just be happy knowing that
+ # Java's menu items will give us focus events when they
+ # are selected.
+ #
+ orca.setLocusOfFocus(event, event.source)
+ return
+
+ default.Script.onFocus(self, event)
+
+ def onActiveDescendantChanged(self, event):
+ """Called when an object who manages its own descendants detects a
+ change in one of its children.
+
+ Arguments:
+ - event: the Event
+ """
+
+ # In Java comboboxes, when the list of options is popped up via
+ # an up or down action, control (but not focus) goes to a LIST
+ # object that manages the descendants. So, we detect that here
+ # and keep focus on the combobox.
+ #
+ if event.source.getRole() == pyatspi.ROLE_COMBO_BOX:
+ orca.visualAppearanceChanged(event, event.source)
+ return
+
+ if event.source.getRole() == pyatspi.ROLE_LIST:
+ combobox = self.getAncestor(event.source,
+ [pyatspi.ROLE_COMBO_BOX],
+ [pyatspi.ROLE_PANEL])
+ if combobox:
+ orca.visualAppearanceChanged(event, combobox)
+ return
+
+ default.Script.onActiveDescendantChanged(self, event)
+
+ def onCaretMoved(self, event):
+ # Java's SpinButtons are the most caret movement happy thing
+ # I've seen to date. If you Up or Down on the keyboard to
+ # change the value, they typically emit three caret movement
+ # events, first to the beginning, then to the end, and then
+ # back to the beginning. It's a very excitable little widget.
+ # Luckily, it only issues one value changed event. So, we'll
+ # ignore caret movement events caused by value changes and
+ # just process the single value changed event.
+ #
+ isSpinBox = self.isDesiredFocusedItem(event.source,
+ [pyatspi.ROLE_TEXT,
+ pyatspi.ROLE_PANEL,
+ pyatspi.ROLE_SPIN_BUTTON])
+ if isSpinBox:
+ if isinstance(orca_state.lastInputEvent,
+ input_event.KeyboardEvent):
+ eventStr = orca_state.lastNonModifierKeyEvent.event_string
+ else:
+ eventStr = None
+ if (eventStr in ["Up", "Down"]) \
+ or isinstance(orca_state.lastInputEvent,
+ input_event.MouseButtonEvent):
+ return
+
+ default.Script.onCaretMoved(self, event)
+
+ def onSelectionChanged(self, event):
+ """Called when an object's selection changes.
+
+ Arguments:
+ - event: the Event
+ """
+
+ # Ignore selection in TREE and TABLE objects since they send us
+ # an active descendant changed event.
+ #
+ if event.source.getRole() in [pyatspi.ROLE_TREE, pyatspi.ROLE_TABLE]:
+ return
+
+ default.Script.onSelectionChanged(self, event)
+
+ def onStateChanged(self, event):
+ """Called whenever an object's state changes.
+
+ Arguments:
+ - event: the Event
+ """
+
+ # Handle state changes when JTree labels become expanded
+ # or collapsed.
+ #
+ if (event.source.getRole() == pyatspi.ROLE_LABEL) and \
+ event.type.startswith("object:state-changed:expanded"):
+ orca.visualAppearanceChanged(event, event.source)
+ return
+
+ # This is a workaround for a java-access-bridge bug (Bug 355011)
+ # where popup menu events are not sent to Orca.
+ #
+ # When a root pane gets focus, a popup menu may have been invoked.
+ # If there is a popup menu, give locus of focus to the armed menu
+ # item.
+ #
+ if event.source.getRole() == pyatspi.ROLE_ROOT_PANE and \
+ event.type.startswith("object:state-changed:focused") and \
+ event.detail1 == 1:
+
+ for child in event.source:
+ # search the layered pane for a popup menu
+ if child.getRole() == pyatspi.ROLE_LAYERED_PANE:
+ popup = self.findByRole(child,
+ pyatspi.ROLE_POPUP_MENU, False)
+ if len(popup) > 0:
+ # set the locus of focus to the armed menu item
+ items = self.findByRole(popup[0],
+ pyatspi.ROLE_MENU_ITEM, False)
+ for item in items:
+ if item.getState().contains(pyatspi.STATE_ARMED):
+ orca.setLocusOfFocus(event, item)
+ return
+
+ # Present a value change in case of an focused popup menu.
+ # Fix for Swing file chooser.
+ #
+ if event.type.startswith("object:state-changed:visible") and \
+ event.source.getRole() == pyatspi.ROLE_POPUP_MENU and \
+ event.source.parent.getState().contains(pyatspi.STATE_FOCUSED):
+ orca.setLocusOfFocus(event, event.source.parent)
+ return
+
+ default.Script.onStateChanged(self, event)
+
+ def onValueChanged(self, event):
+ """Called whenever an object's value changes.
+
+ Arguments:
+ - event: the Event
+ """
+
+ # We'll ignore value changed events for Java's toggle buttons since
+ # they also send a redundant object:state-changed:checked event.
+ #
+ if event.source.getRole() == pyatspi.ROLE_TOGGLE_BUTTON:
+ return
+
+ # Java's SpinButtons are the most caret movement happy thing
+ # I've seen to date. If you Up or Down on the keyboard to
+ # change the value, they typically emit three caret movement
+ # events, first to the beginning, then to the end, and then
+ # back to the beginning. It's a very excitable little widget.
+ # Luckily, it only issues one value changed event. So, we'll
+ # ignore caret movement events caused by value changes and
+ # just process the single value changed event.
+ #
+ if event.source.getRole() == pyatspi.ROLE_SPIN_BUTTON:
+ try:
+ thisBox = orca_state.locusOfFocus.parent.parent == event.source
+ except:
+ thisBox = False
+ if thisBox:
+ self._presentTextAtNewCaretPosition(event,
+ orca_state.locusOfFocus)
+ return
+
+ default.Script.onValueChanged(self, event)
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/speechgenerator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/speechgenerator.py Tue Jul 1 17:40:13 2008
@@ -0,0 +1,141 @@
+# Orca
+#
+# Copyright 2006-2008 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.
+
+__id__ = "$Id: J2SE-access-bridge.py 3882 2008-05-07 18:22:10Z richb $"
+__version__ = "$Revision: 3882 $"
+__date__ = "$Date: 2008-05-07 14:22:10 -0400 (Wed, 07 May 2008) $"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.rolenames as rolenames
+import orca.speechgenerator as speechgenerator
+
+from orca.orca_i18n import _ # for gettext support
+
+########################################################################
+# #
+# Speech Generator #
+# #
+########################################################################
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ 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 = []
+ if (not already_focused):
+ text = self._script.getDisplayedText(obj)
+ if not text:
+ text = rolenames.getSpeechForRoleName(obj)
+ if text:
+ utterances.append(text)
+
+ # In Java, tree objects are labels, so we need to look at their
+ # states in order to tell whether they are expanded or collapsed.
+ #
+ state = obj.getState()
+ 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"))
+ elif not state.contains(pyatspi.STATE_EXPANDED) and \
+ state.contains(pyatspi.STATE_EXPANDABLE):
+ # 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"))
+
+ self._debugGenerator("J2SE-access-bridge:_getSpeechForLabel",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def getSpeechContext(self, obj, stopAncestor=None):
+ """This method is identical to speechgeneratior.getSpeechContext
+ with one exception. The following test in
+ speechgenerator.getSpeechContext:
+
+ if not text and 'Text' in pyatspi.listInterfaces(parent):
+ text = self._script.getDisplayedText(parent)
+
+ has be replaced by
+
+ if not text:
+ text = self._script.getDisplayedText(parent)
+
+ The Swing toolkit has labelled panels that do not implement the
+ AccessibleText interface, but getDisplayedText returns
+ a meaningful string that needs to be used if getDisplayedLabel
+ returns None.
+ """
+
+ utterances = []
+
+ if not obj:
+ return utterances
+
+ if obj == stopAncestor:
+ return utterances
+
+ 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 (parent.getRole() == pyatspi.ROLE_PANEL):
+ 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]:
+ utterances.append(\
+ rolenames.getSpeechForRoleName(parent))
+ utterances.append(text)
+ if parent.getRole() == pyatspi.ROLE_TABLE_CELL:
+ utterances.append(\
+ rolenames.getSpeechForRoleName(parent))
+ parent = parent.parent
+
+ utterances.reverse()
+
+ return utterances
Added: trunk/src/orca/scripts/toolkits/J2SE-access-bridge/where_am_I.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge/where_am_I.py Tue Jul 1 17:40:13 2008
@@ -0,0 +1,55 @@
+# Orca
+#
+# Copyright 2006-2008 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.
+
+__id__ = "$Id: J2SE-access-bridge.py 3882 2008-05-07 18:22:10Z richb $"
+__version__ = "$Revision: 3882 $"
+__date__ = "$Date: 2008-05-07 14:22:10 -0400 (Wed, 07 May 2008) $"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.where_am_I as where_am_I
+
+########################################################################
+# #
+# Custom WhereAmI #
+# #
+########################################################################
+
+class WhereAmI(where_am_I.WhereAmI):
+ def __init__(self, script):
+ where_am_I.WhereAmI.__init__(self, script)
+
+ def whereAmI(self, obj, basicOnly):
+ """Calls the base class method for basic information and Java
+ specific presentation methods for detailed/custom information.
+ """
+
+ # If we're in the text area of a spin button, then we'll do the
+ # where am I for the spin button.
+ #
+ if obj and obj.getRole() == pyatspi.ROLE_TEXT:
+ spinbox = self._script.getAncestor(obj,
+ [pyatspi.ROLE_SPIN_BUTTON],
+ None)
+ if spinbox:
+ obj = spinbox
+
+ where_am_I.WhereAmI.whereAmI(self, obj, basicOnly)
Modified: trunk/src/orca/scripts/toolkits/Makefile.am
==============================================================================
--- trunk/src/orca/scripts/toolkits/Makefile.am (original)
+++ trunk/src/orca/scripts/toolkits/Makefile.am Tue Jul 1 17:40:13 2008
@@ -1,11 +1,10 @@
-SUBDIRS = Gecko
+SUBDIRS = Gecko J2SE-access-bridge
orca_pathdir=$(pyexecdir)
orca_python_PYTHON = \
__init__.py \
GAIL.py \
- J2SE-access-bridge.py \
VCL.py
orca_pythondir=$(pyexecdir)/orca/scripts/toolkits
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]