orca r3876 - in trunk: . src/orca src/orca/scripts src/orca/scripts/apps src/orca/scripts/apps/Thunderbird src/orca/scripts/apps/evolution src/orca/scripts/apps/gcalctool src/orca/scripts/apps/gedit src/orca/scripts/apps/gnome-window-properties src/orca/scripts/apps/pidgin src/orca/scripts/apps/planner src/orca/scripts/apps/rhythmbox src/orca/scripts/apps/soffice src/orca/scripts/toolkits src/orca/scripts/toolkits/Gecko test/harness
- From: eitani svn gnome org
- To: svn-commits-list gnome org
- Subject: orca r3876 - in trunk: . src/orca src/orca/scripts src/orca/scripts/apps src/orca/scripts/apps/Thunderbird src/orca/scripts/apps/evolution src/orca/scripts/apps/gcalctool src/orca/scripts/apps/gedit src/orca/scripts/apps/gnome-window-properties src/orca/scripts/apps/pidgin src/orca/scripts/apps/planner src/orca/scripts/apps/rhythmbox src/orca/scripts/apps/soffice src/orca/scripts/toolkits src/orca/scripts/toolkits/Gecko test/harness
- Date: Fri, 2 May 2008 22:21:21 +0100 (BST)
Author: eitani
Date: Fri May 2 21:21:19 2008
New Revision: 3876
URL: http://svn.gnome.org/viewvc/orca?rev=3876&view=rev
Log:
* configure.in:
pylintrc:
src/orca/Gecko.py:
src/orca/J2SE-access-bridge.py:
src/orca/Makefile.am:
src/orca/focus_tracking_presenter.py:
src/orca/scripts/Evolution.py:
src/orca/scripts/Makefile.am:
src/orca/scripts/Mozilla.py:
src/orca/scripts/StarOffice.py:
src/orca/scripts/Thunderbird.py:
src/orca/scripts/acroread.py:
src/orca/scripts/apps/Makefile.am:
src/orca/scripts/apps/Mozilla.py:
src/orca/scripts/apps/Thunderbird/Makefile.am:
src/orca/scripts/apps/Thunderbird/__init__.py:
src/orca/scripts/apps/Thunderbird/script.py:
src/orca/scripts/apps/Thunderbird/speech_generator.py:
src/orca/scripts/apps/acroread.py:
src/orca/scripts/apps/evolution/Makefile.am:
src/orca/scripts/apps/evolution/__init__.py:
src/orca/scripts/apps/evolution/script.py:
src/orca/scripts/apps/evolution/speech_generator.py:
src/orca/scripts/apps/evolution/where_am_i.py:
src/orca/scripts/apps/gcalctool/Makefile.am:
src/orca/scripts/apps/gcalctool/__init__.py:
src/orca/scripts/apps/gcalctool/script.py:
src/orca/scripts/apps/gcalctool/speech_generator.py:
src/orca/scripts/apps/gcalctool/where_am_i.py:
src/orca/scripts/apps/gdmlogin.py:
src/orca/scripts/apps/gedit/Makefile.am:
src/orca/scripts/apps/gedit/__init__.py:
src/orca/scripts/apps/gedit/script.py:
src/orca/scripts/apps/gedit/speech_generator.py:
src/orca/scripts/apps/gnome-keyring-ask.py:
src/orca/scripts/apps/gnome-mud.py:
src/orca/scripts/apps/gnome-panel.py:
src/orca/scripts/apps/gnome-search-tool.py:
src/orca/scripts/apps/gnome-system-monitor.py:
src/orca/scripts/apps/gnome-terminal.py:
src/orca/scripts/apps/gnome-window-properties/Makefile.am:
src/orca/scripts/apps/gnome-window-properties/__init__.py:
src/orca/scripts/apps/gnome-window-properties/script.py:
src/orca/scripts/apps/gnome-window-properties/speech_generator.py:
src/orca/scripts/apps/gnome_segv2.py:
src/orca/scripts/apps/liferea.py:
src/orca/scripts/apps/metacity.py:
src/orca/scripts/apps/nautilus.py:
src/orca/scripts/apps/notification-daemon.py:
src/orca/scripts/apps/pidgin/Makefile.am:
src/orca/scripts/apps/pidgin/__init__.py:
src/orca/scripts/apps/pidgin/constants.py:
src/orca/scripts/apps/pidgin/script.py:
src/orca/scripts/apps/pidgin/speech_generator.py:
src/orca/scripts/apps/pidgin/where_am_i.py:
src/orca/scripts/apps/planner/Makefile.am:
src/orca/scripts/apps/planner/__init__.py:
src/orca/scripts/apps/planner/braille_generator.py:
src/orca/scripts/apps/planner/script.py:
src/orca/scripts/apps/planner/speech_generator.py:
src/orca/scripts/apps/rhythmbox/Makefile.am:
src/orca/scripts/apps/rhythmbox/__init__.py:
src/orca/scripts/apps/rhythmbox/braille_generator.py:
src/orca/scripts/apps/rhythmbox/script.py:
src/orca/scripts/apps/rhythmbox/speech_generator.py:
src/orca/scripts/apps/soffice/Makefile.am:
src/orca/scripts/apps/soffice/__init__.py:
src/orca/scripts/apps/soffice/braille_generator.py:
src/orca/scripts/apps/soffice/constants.py:
src/orca/scripts/apps/soffice/script.py:
src/orca/scripts/apps/soffice/speech_generator.py:
src/orca/scripts/apps/soffice/where_am_i.py:
src/orca/scripts/gaim.py:
src/orca/scripts/gcalctool.py:
src/orca/scripts/gdmlogin.py:
src/orca/scripts/gedit.py:
src/orca/scripts/gnome-keyring-ask.py:
src/orca/scripts/gnome-mud.py:
src/orca/scripts/gnome-panel.py:
src/orca/scripts/gnome-search-tool.py:
src/orca/scripts/gnome-system-monitor.py:
src/orca/scripts/gnome-terminal.py:
src/orca/scripts/gnome-window-properties.py:
src/orca/scripts/gnome_segv2.py:
src/orca/scripts/liferea.py:
src/orca/scripts/metacity.py:
src/orca/scripts/nautilus.py:
src/orca/scripts/notification-daemon.py:
src/orca/scripts/planner.py:
src/orca/scripts/rhythmbox.py:
src/orca/scripts/toolkits/GAIL.py:
src/orca/scripts/toolkits/Gecko/Makefile.am:
src/orca/scripts/toolkits/Gecko/__init__.py:
src/orca/scripts/toolkits/Gecko/bookmarks.py:
src/orca/scripts/toolkits/Gecko/braille_generator.py:
src/orca/scripts/toolkits/Gecko/constants.py:
src/orca/scripts/toolkits/Gecko/script.py:
src/orca/scripts/toolkits/Gecko/speech_generator.py:
src/orca/scripts/toolkits/Gecko/where_am_i.py:
src/orca/scripts/toolkits/J2SE-access-bridge.py:
src/orca/scripts/toolkits/Makefile.am:
src/orca/scripts/toolkits/VCL.py:
src/orca/settings.py:
test/harness/orca-customizations.py.in:
Fixed bug #528147: Broke up multi-class scripts into packages.
Put toolkit scripts into their own directory, and application
scripts into one too.
Added:
trunk/src/orca/scripts/apps/
trunk/src/orca/scripts/apps/Makefile.am
- copied, changed from r3875, /trunk/src/orca/scripts/Makefile.am
trunk/src/orca/scripts/apps/Mozilla.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/Thunderbird/
trunk/src/orca/scripts/apps/Thunderbird/Makefile.am
trunk/src/orca/scripts/apps/Thunderbird/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/Thunderbird/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/Thunderbird.py
trunk/src/orca/scripts/apps/Thunderbird/speech_generator.py
- copied, changed from r3875, /trunk/src/orca/scripts/notification-daemon.py
trunk/src/orca/scripts/apps/__init__.py
trunk/src/orca/scripts/apps/acroread.py
- copied, changed from r3875, /trunk/src/orca/scripts/acroread.py
trunk/src/orca/scripts/apps/evolution/
trunk/src/orca/scripts/apps/evolution/Makefile.am
trunk/src/orca/scripts/apps/evolution/__init__.py
trunk/src/orca/scripts/apps/evolution/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/Evolution.py
trunk/src/orca/scripts/apps/evolution/speech_generator.py
trunk/src/orca/scripts/apps/evolution/where_am_i.py
trunk/src/orca/scripts/apps/gcalctool/
trunk/src/orca/scripts/apps/gcalctool/Makefile.am
trunk/src/orca/scripts/apps/gcalctool/__init__.py
trunk/src/orca/scripts/apps/gcalctool/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/gcalctool.py
trunk/src/orca/scripts/apps/gcalctool/speech_generator.py
trunk/src/orca/scripts/apps/gcalctool/where_am_i.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/gdmlogin.py
- copied, changed from r3875, /trunk/src/orca/scripts/gdmlogin.py
trunk/src/orca/scripts/apps/gedit/
trunk/src/orca/scripts/apps/gedit/Makefile.am
trunk/src/orca/scripts/apps/gedit/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/gedit/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/gedit.py
trunk/src/orca/scripts/apps/gedit/speech_generator.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-window-properties.py
trunk/src/orca/scripts/apps/gnome-keyring-ask.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py
trunk/src/orca/scripts/apps/gnome-mud.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-mud.py
trunk/src/orca/scripts/apps/gnome-panel.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-panel.py
trunk/src/orca/scripts/apps/gnome-search-tool.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-search-tool.py
trunk/src/orca/scripts/apps/gnome-system-monitor.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-system-monitor.py
trunk/src/orca/scripts/apps/gnome-terminal.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-terminal.py
trunk/src/orca/scripts/apps/gnome-window-properties/
trunk/src/orca/scripts/apps/gnome-window-properties/Makefile.am
trunk/src/orca/scripts/apps/gnome-window-properties/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/gnome-window-properties/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py
trunk/src/orca/scripts/apps/gnome-window-properties/speech_generator.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-window-properties.py
trunk/src/orca/scripts/apps/gnome_segv2.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome_segv2.py
trunk/src/orca/scripts/apps/liferea.py
- copied, changed from r3875, /trunk/src/orca/scripts/liferea.py
trunk/src/orca/scripts/apps/metacity.py
- copied, changed from r3875, /trunk/src/orca/scripts/metacity.py
trunk/src/orca/scripts/apps/nautilus.py
- copied, changed from r3875, /trunk/src/orca/scripts/nautilus.py
trunk/src/orca/scripts/apps/notification-daemon.py
- copied, changed from r3875, /trunk/src/orca/scripts/notification-daemon.py
trunk/src/orca/scripts/apps/pidgin/
trunk/src/orca/scripts/apps/pidgin/Makefile.am
trunk/src/orca/scripts/apps/pidgin/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/pidgin/constants.py
trunk/src/orca/scripts/apps/pidgin/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/gaim.py
trunk/src/orca/scripts/apps/pidgin/speech_generator.py
trunk/src/orca/scripts/apps/pidgin/where_am_i.py
trunk/src/orca/scripts/apps/planner/
trunk/src/orca/scripts/apps/planner/Makefile.am
trunk/src/orca/scripts/apps/planner/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/planner/braille_generator.py
trunk/src/orca/scripts/apps/planner/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py
trunk/src/orca/scripts/apps/planner/speech_generator.py
trunk/src/orca/scripts/apps/rhythmbox/
trunk/src/orca/scripts/apps/rhythmbox/Makefile.am
trunk/src/orca/scripts/apps/rhythmbox/__init__.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/apps/rhythmbox/braille_generator.py
trunk/src/orca/scripts/apps/rhythmbox/script.py
trunk/src/orca/scripts/apps/rhythmbox/speech_generator.py
trunk/src/orca/scripts/apps/soffice/
trunk/src/orca/scripts/apps/soffice/Makefile.am
trunk/src/orca/scripts/apps/soffice/__init__.py
trunk/src/orca/scripts/apps/soffice/braille_generator.py
trunk/src/orca/scripts/apps/soffice/constants.py
trunk/src/orca/scripts/apps/soffice/script.py
- copied, changed from r3875, /trunk/src/orca/scripts/StarOffice.py
trunk/src/orca/scripts/apps/soffice/speech_generator.py
trunk/src/orca/scripts/apps/soffice/where_am_i.py
trunk/src/orca/scripts/toolkits/
trunk/src/orca/scripts/toolkits/GAIL.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/toolkits/Gecko/
trunk/src/orca/scripts/toolkits/Gecko/Makefile.am
trunk/src/orca/scripts/toolkits/Gecko/__init__.py
trunk/src/orca/scripts/toolkits/Gecko/bookmarks.py
trunk/src/orca/scripts/toolkits/Gecko/braille_generator.py
trunk/src/orca/scripts/toolkits/Gecko/constants.py
trunk/src/orca/scripts/toolkits/Gecko/script.py
- copied, changed from r3875, /trunk/src/orca/Gecko.py
trunk/src/orca/scripts/toolkits/Gecko/speech_generator.py
trunk/src/orca/scripts/toolkits/Gecko/where_am_i.py
trunk/src/orca/scripts/toolkits/J2SE-access-bridge.py
- copied, changed from r3875, /trunk/src/orca/J2SE-access-bridge.py
trunk/src/orca/scripts/toolkits/Makefile.am
trunk/src/orca/scripts/toolkits/VCL.py
- copied, changed from r3875, /trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/toolkits/__init__.py
Removed:
trunk/src/orca/Gecko.py
trunk/src/orca/J2SE-access-bridge.py
trunk/src/orca/scripts/Evolution.py
trunk/src/orca/scripts/Mozilla.py
trunk/src/orca/scripts/StarOffice.py
trunk/src/orca/scripts/Thunderbird.py
trunk/src/orca/scripts/acroread.py
trunk/src/orca/scripts/gaim.py
trunk/src/orca/scripts/gcalctool.py
trunk/src/orca/scripts/gdmlogin.py
trunk/src/orca/scripts/gedit.py
trunk/src/orca/scripts/gnome-keyring-ask.py
trunk/src/orca/scripts/gnome-mud.py
trunk/src/orca/scripts/gnome-panel.py
trunk/src/orca/scripts/gnome-search-tool.py
trunk/src/orca/scripts/gnome-system-monitor.py
trunk/src/orca/scripts/gnome-terminal.py
trunk/src/orca/scripts/gnome-window-properties.py
trunk/src/orca/scripts/gnome_segv2.py
trunk/src/orca/scripts/liferea.py
trunk/src/orca/scripts/metacity.py
trunk/src/orca/scripts/nautilus.py
trunk/src/orca/scripts/notification-daemon.py
trunk/src/orca/scripts/planner.py
trunk/src/orca/scripts/rhythmbox.py
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/pylintrc
trunk/src/orca/Makefile.am
trunk/src/orca/focus_tracking_presenter.py
trunk/src/orca/scripts/Makefile.am
trunk/src/orca/settings.py
trunk/test/harness/orca-customizations.py.in
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Fri May 2 21:21:19 2008
@@ -175,6 +175,18 @@
src/louis/constants.py
src/orca/Makefile
src/orca/scripts/Makefile
+src/orca/scripts/apps/Makefile
+src/orca/scripts/apps/soffice/Makefile
+src/orca/scripts/apps/evolution/Makefile
+src/orca/scripts/apps/gcalctool/Makefile
+src/orca/scripts/apps/pidgin/Makefile
+src/orca/scripts/apps/planner/Makefile
+src/orca/scripts/apps/rhythmbox/Makefile
+src/orca/scripts/apps/Thunderbird/Makefile
+src/orca/scripts/apps/gedit/Makefile
+src/orca/scripts/apps/gnome-window-properties/Makefile
+src/orca/scripts/toolkits/Makefile
+src/orca/scripts/toolkits/Gecko/Makefile
src/orca/orca
src/orca/orca_i18n.py
src/orca/platform.py
Modified: trunk/pylintrc
==============================================================================
--- trunk/pylintrc (original)
+++ trunk/pylintrc Fri May 2 21:21:19 2008
@@ -64,6 +64,7 @@
#
# W0102: Default argument is a mutable value (list or dictionary)
# W0141: Used builtin function 'map'
+# W0401: Wildcard import constants
# W0403: Relative import
# W0511: Warning note (FIXME or XXX) detected.
# W0603: Using the global statement
@@ -85,7 +86,7 @@
# R0914: Function or method has too many local variables
# R0915: Function or method has too many statements
#
-disable-msg=E0611,C0111,R0201,W0102,W0141,W0403,W0603,W0612,W0613,W0702,W0704,W0511,R0801,R0912,R0915,R0914,R0904,R0903,R0401,R0911,R0913,C0302,R0902
+disable-msg=E0611,C0111,R0201,W0102,W0141,W0401,W0403,W0603,W0612,W0613,W0702,W0704,W0511,R0801,R0912,R0915,R0914,R0904,R0903,R0401,R0911,R0913,C0302,R0902
[REPORTS]
Modified: trunk/src/orca/Makefile.am
==============================================================================
--- trunk/src/orca/Makefile.am (original)
+++ trunk/src/orca/Makefile.am Fri May 2 21:21:19 2008
@@ -25,11 +25,9 @@
find.py \
flat_review.py \
focus_tracking_presenter.py \
- Gecko.py \
gnomespeechfactory.py \
httpserver.py \
input_event.py \
- J2SE-access-bridge.py \
keybindings.py \
keynames.py \
liveregions.py \
Modified: trunk/src/orca/focus_tracking_presenter.py
==============================================================================
--- trunk/src/orca/focus_tracking_presenter.py (original)
+++ trunk/src/orca/focus_tracking_presenter.py Fri May 2 21:21:19 2008
@@ -240,26 +240,31 @@
# package for now.
#
if (not script) and app and getattr(app, "toolkitName", None):
- try:
- debug.println(
- debug.LEVEL_FINE,
- "Looking for toolkit script %s.py..." % app.toolkitName)
- module = __import__(app.toolkitName,
- globals(),
- locals(),
- [''])
- script = module.Script(app)
- debug.println(debug.LEVEL_FINE,
- "...found %s.py" % name)
- except ImportError:
- debug.println(
- debug.LEVEL_FINE,
- "...could not find %s.py" % app.toolkitName)
- except:
- debug.printException(debug.LEVEL_SEVERE)
- debug.println(
- debug.LEVEL_SEVERE,
- "While attempting to import %s" % app.toolkitName)
+ for package in scriptPackages:
+ if package:
+ name = '.'.join((package, app.toolkitName))
+ else:
+ name = app.toolkitName
+ try:
+ debug.println(
+ debug.LEVEL_FINE,
+ "Looking for toolkit script %s.py..." % app.toolkitName)
+ module = __import__(name,
+ globals(),
+ locals(),
+ [''])
+ script = module.Script(app)
+ debug.println(debug.LEVEL_FINE,
+ "...found %s.py" % name)
+ except ImportError:
+ debug.println(
+ debug.LEVEL_FINE,
+ "...could not find %s.py" % app.toolkitName)
+ except:
+ debug.printException(debug.LEVEL_SEVERE)
+ debug.println(
+ debug.LEVEL_SEVERE,
+ "While attempting to import %s" % app.toolkitName)
if not script:
script = default.Script(app)
Modified: trunk/src/orca/scripts/Makefile.am
==============================================================================
--- trunk/src/orca/scripts/Makefile.am (original)
+++ trunk/src/orca/scripts/Makefile.am Fri May 2 21:21:19 2008
@@ -1,31 +1,10 @@
+SUBDIRS = apps toolkits
+
orca_pathdir=$(pyexecdir)
orca_python_PYTHON = \
__init__.py \
- acroread.py \
- Evolution.py \
- gaim.py \
- gcalctool.py \
- gdmlogin.py \
- gedit.py \
- gnome_segv2.py \
- gnome-keyring-ask.py \
- gnome-mud.py \
- gnome-panel.py \
- gnome-search-tool.py \
- gnome-system-monitor.py \
- gnome-terminal.py \
- gnome-window-properties.py \
- liferea.py \
- metacity.py \
- Mozilla.py \
- nautilus.py \
- notification-daemon.py \
- planner.py \
- rhythmbox.py \
- self_voicing.py \
- StarOffice.py \
- Thunderbird.py
+ self_voicing.py
orca_pythondir=$(pyexecdir)/orca/scripts
Copied: trunk/src/orca/scripts/apps/Makefile.am (from r3875, /trunk/src/orca/scripts/Makefile.am)
==============================================================================
--- /trunk/src/orca/scripts/Makefile.am (original)
+++ trunk/src/orca/scripts/apps/Makefile.am Fri May 2 21:21:19 2008
@@ -1,31 +1,32 @@
+SUBDIRS = \
+ soffice \
+ evolution \
+ gcalctool \
+ pidgin \
+ planner \
+ rhythmbox \
+ Thunderbird \
+ gedit \
+ gnome-window-properties
+
orca_pathdir=$(pyexecdir)
orca_python_PYTHON = \
__init__.py \
acroread.py \
- Evolution.py \
- gaim.py \
- gcalctool.py \
gdmlogin.py \
- gedit.py \
- gnome_segv2.py \
gnome-keyring-ask.py \
gnome-mud.py \
gnome-panel.py \
gnome-search-tool.py \
+ gnome_segv2.py \
gnome-system-monitor.py \
gnome-terminal.py \
- gnome-window-properties.py \
liferea.py \
metacity.py \
Mozilla.py \
nautilus.py \
- notification-daemon.py \
- planner.py \
- rhythmbox.py \
- self_voicing.py \
- StarOffice.py \
- Thunderbird.py
+ notification-daemon.py
-orca_pythondir=$(pyexecdir)/orca/scripts
+orca_pythondir=$(pyexecdir)/orca/scripts/apps
Copied: trunk/src/orca/scripts/apps/Mozilla.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
Added: trunk/src/orca/scripts/apps/Thunderbird/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/Thunderbird/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,9 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ script.py \
+ speech_generator.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/Thunderbird
+
Copied: trunk/src/orca/scripts/apps/Thunderbird/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/Thunderbird/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2004-2007 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
@@ -17,20 +17,13 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+""" Custom script for Thunderbird 3.
+"""
-__id__ = "$Id$"
-__version__ = "$Revision$"
-__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__id__ = "$Id: $"
+__version__ = "$Revision: $"
+__date__ = "$Date: $"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
Copied: trunk/src/orca/scripts/apps/Thunderbird/script.py (from r3875, /trunk/src/orca/scripts/Thunderbird.py)
==============================================================================
--- /trunk/src/orca/scripts/Thunderbird.py (original)
+++ trunk/src/orca/scripts/apps/Thunderbird/script.py Fri May 2 21:21:19 2008
@@ -32,32 +32,11 @@
import orca.debug as debug
import orca.default as default
import orca.speech as speech
-import orca.Gecko as Gecko
+import orca.scripts.toolkits.Gecko as Gecko
from orca.orca_i18n import _
-########################################################################
-# #
-# Custom SpeechGenerator for Thunderbird #
-# #
-########################################################################
-
-class SpeechGenerator(Gecko.SpeechGenerator):
- """Provides a speech generator specific to Thunderbird.
- """
-
- def __init__(self, script):
- # Set the debug level for all the methods in this script.
- #
- self.debugLevel = debug.LEVEL_FINEST
-
- self._debug("__init__")
- Gecko.SpeechGenerator.__init__(self, script)
-
- def _debug(self, msg):
- """ Convenience method for printing debug messages
- """
- debug.println(self.debugLevel, "Thunderbird.SpeechGenerator: "+msg)
+from speech_generator import SpeechGenerator
########################################################################
# #
Copied: trunk/src/orca/scripts/apps/Thunderbird/speech_generator.py (from r3875, /trunk/src/orca/scripts/notification-daemon.py)
==============================================================================
--- /trunk/src/orca/scripts/notification-daemon.py (original)
+++ trunk/src/orca/scripts/apps/Thunderbird/speech_generator.py Fri May 2 21:21:19 2008
@@ -17,50 +17,38 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-""" Custom script for The notification daemon.
+""" Custom script for Thunderbird 3.
"""
-__id__ = ""
-__version__ = ""
-__date__ = ""
+__id__ = "$Id: $"
+__version__ = "$Revision: $"
+__date__ = "$Date: $"
__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.default as default
-import orca.speech as speech
-import pyatspi
+import orca.debug as debug
+import orca.scripts.toolkits.Gecko as Gecko
-from orca.orca_i18n import _
########################################################################
# #
-# The notification-daemon script class. #
+# Custom SpeechGenerator for Thunderbird #
# #
########################################################################
-class Script(default.Script):
- def getListeners(self):
- """Sets up the AT-SPI event listeners for this script.
- """
- listeners = default.Script.getListeners(self)
-
- listeners["window:create"] = \
- self.onWindowCreate
+class SpeechGenerator(Gecko.SpeechGenerator):
+ """Provides a speech generator specific to Thunderbird.
+ """
- return listeners
+ def __init__(self, script):
+ # Set the debug level for all the methods in this script.
+ #
+ self.debugLevel = debug.LEVEL_FINEST
- def onWindowCreate(self, event):
- """Called whenever a window is created in the notification-daemon
- application.
+ self._debug("__init__")
+ Gecko.SpeechGenerator.__init__(self, script)
- Arguments:
- - event: the Event.
+ def _debug(self, msg):
+ """ Convenience method for printing debug messages
"""
- a = self.findByRole(event.source, pyatspi.ROLE_LABEL)
- print a
- texts = [self.getDisplayedText(acc) for acc in a]
- # Translators: This denotes a notification to the user of some sort.
- #
- text = _('Notification %s') % ' '.join(texts)
- speech.speak(text, None, True)
-
+ debug.println(self.debugLevel, "Thunderbird.SpeechGenerator: "+msg)
Added: trunk/src/orca/scripts/apps/__init__.py
==============================================================================
Copied: trunk/src/orca/scripts/apps/acroread.py (from r3875, /trunk/src/orca/scripts/acroread.py)
==============================================================================
Added: trunk/src/orca/scripts/apps/evolution/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/evolution/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,10 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ script.py \
+ speech_generator.py \
+ where_am_i.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/evolution
+
Added: trunk/src/orca/scripts/apps/evolution/__init__.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/evolution/__init__.py Fri May 2 21:21:19 2008
@@ -0,0 +1,22 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Evolution."""
+
+from script import Script
Copied: trunk/src/orca/scripts/apps/evolution/script.py (from r3875, /trunk/src/orca/scripts/Evolution.py)
==============================================================================
--- /trunk/src/orca/scripts/Evolution.py (original)
+++ trunk/src/orca/scripts/apps/evolution/script.py Fri May 2 21:21:19 2008
@@ -36,246 +36,14 @@
import orca.orca as orca
import orca.orca_state as orca_state
import orca.speech as speech
-import orca.speechgenerator as speechgenerator
import orca.speechserver as speechserver
import orca.settings as settings
import orca.chnames as chnames
-import orca.where_am_I as where_am_I
from orca.orca_i18n import _ # for gettext support
-class WhereAmI(where_am_I.WhereAmI):
-
- def __init__(self, script):
- """Create a new WhereAmI that will be used to speak information
- about the current object of interest.
- """
-
- where_am_I.WhereAmI.__init__(self, script)
-
- def _getTableCell(self, obj):
- """Get the speech utterances for a single table cell.
- """
-
- # Don't speak check box cells that area not checked.
- notChecked = False
- 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")]:
- if not obj.getState().contains(pyatspi.STATE_CHECKED):
- notChecked = True
- break
-
- if notChecked:
- return ""
-
- descendant = self._script.getRealActiveDescendant(obj)
- text = self._script.getDisplayedText(descendant)
-
- # For Evolution mail header list.
- if text == "Status":
- # Translators: this in reference to an e-mail message status of
- # having been read or unread.
- #
- text = _("Read")
-
- debug.println(self._debugLevel, "cell=<%s>" % text)
-
- return text
-
- def _hasTextSelections(self, obj):
- """Return an indication of whether this object has selected text.
- Note that it's possible that this object has no text, but is part
- of a selected text area. Because of this, we need to check the
- objects on either side to see if they are none zero length and
- have text selections.
-
- Arguments:
- - obj: the text object to start checking for selected text.
-
- Returns: an indication of whether this object has selected text,
- or adjacent text objects have selected text.
- """
-
- currentSelected = False
- otherSelected = False
- nSelections = obj.queryText().getNSelections()
- if nSelections:
- currentSelected = True
- else:
- otherSelected = False
- displayedText = obj.queryText().getText(0, -1)
- if len(displayedText) == 0:
- container = obj.parent.parent
- current = obj.parent.getIndexInParent()
- morePossibleSelections = True
- while morePossibleSelections:
- morePossibleSelections = False
- if (current-1) >= 0:
- prevPanel = container[current-1]
- prevObj = prevPanel[0]
- try:
- prevObjText = prevObj.queryText()
- except:
- prevObjText = None
-
- if prevObj and prevObjText:
- if prevObjText.getNSelections() > 0:
- otherSelected = True
- else:
- displayedText = prevObjText.getText(0, -1)
- if len(displayedText) == 0:
- current -= 1
- morePossibleSelections = True
-
- current = obj.parent.getIndexInParent()
- morePossibleSelections = True
- while morePossibleSelections:
- morePossibleSelections = False
- if (current+1) < container.childCount:
- nextPanel = container[current+1]
- nextObj = nextPanel[0]
- try:
- nextObjText = nextObj.queryText()
- except:
- nextObjText = None
-
- if nextObj and nextObjText:
- if nextObjText.getNSelections() > 0:
- otherSelected = True
- else:
- displayedText = nextObjText.getText(0, -1)
- if len(displayedText) == 0:
- current += 1
- morePossibleSelections = True
-
- return [currentSelected, otherSelected]
-
- def _getTextSelections(self, obj, doubleClick):
- """Get all the text applicable text selections for the given object.
- If the user doubleclicked, look to see if there are any previous
- or next text objects that also have selected text and add in their
- text contents.
-
- Arguments:
- - obj: the text object to start extracting the selected text from.
- - doubleClick: True if the user double-clicked the "where am I" key.
-
- Returns: all the selected text contents plus the start and end
- offsets within the text for the given object.
- """
-
- textContents = ""
- startOffset = 0
- endOffset = 0
- if obj.queryText().getNSelections() > 0:
- [textContents, startOffset, endOffset] = \
- self._getTextSelection(obj)
-
- if doubleClick:
- # Unfortunately, Evolution doesn't use the FLOWS_FROM and
- # FLOWS_TO relationships to easily allow us to get to previous
- # and next text objects. Instead we have to move up the
- # component hierarchy until we get to the object containing all
- # the panels (with each line containing a single text item).
- # We can then check in both directions to see if there is other
- # contiguous text that is selected. We also have to jump over
- # zero length (empty) text lines and continue checking on the
- # other side.
- #
- container = obj.parent.parent
- current = obj.parent.getIndexInParent()
- morePossibleSelections = True
- while morePossibleSelections:
- morePossibleSelections = False
- if (current-1) >= 0:
- prevPanel = container[current-1]
- try:
- prevObj = prevPanel[0]
- displayedText = prevObj.queryText().getText(0, -1)
- if len(displayedText) == 0:
- current -= 1
- morePossibleSelections = True
- elif prevObj.queryText().getNSelections() > 0:
- [newTextContents, start, end] = \
- self._getTextSelection(prevObj)
- textContents = newTextContents + " " + textContents
- current -= 1
- morePossibleSelections = True
- except:
- pass
-
- current = obj.parent.getIndexInParent()
- morePossibleSelections = True
- while morePossibleSelections:
- morePossibleSelections = False
- if (current+1) < container.childCount:
- nextPanel = container[current+1]
- try:
- nextObj = nextPanel[0]
- displayedText = nextObj.queryText().getText(0, -1)
- if len(displayedText) == 0:
- current += 1
- morePossibleSelections = True
- elif nextObj.queryText().getNSelections() > 0:
- [newTextContents, start, end] = \
- self._getTextSelection(nextObj)
- textContents += " " + newTextContents
- current += 1
- morePossibleSelections = True
- except:
- pass
-
- return [textContents, startOffset, endOffset]
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Overrides _getSpeechForTableCell so that, if this is an expanded
- table cell, we can strip off the "0 items".
- """
-
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
-
- 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 = speechgenerator.SpeechGenerator.\
- _getSpeechForTableCell(self, obj, already_focused)
-
- # Check that we are in a table cell in the mail message header list.
- # If we are and this table cell has an expanded state, and the first
- # token of the last utterances is "0", then strip off that last
- # utterance ("0 items"). See bug #432308 for more details.
- #
- rolesList = [pyatspi.ROLE_TABLE_CELL, \
- pyatspi.ROLE_TREE_TABLE, \
- pyatspi.ROLE_UNKNOWN]
- if self._script.isDesiredFocusedItem(obj, rolesList):
- state = obj.getState()
- if state and state.contains(pyatspi.STATE_EXPANDABLE):
- if state.contains(pyatspi.STATE_EXPANDED):
- tokens = utterances[-1].split()
- if tokens[0] == "0":
- utterances = utterances[0:-1]
-
- return utterances
-
+from where_am_i import WhereAmI
+from speech_generator import SpeechGenerator
########################################################################
# #
# The Evolution script class. #
Added: trunk/src/orca/scripts/apps/evolution/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/evolution/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,69 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Evolution."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.speechgenerator as speechgenerator
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Overrides _getSpeechForTableCell so that, if this is an expanded
+ table cell, we can strip off the "0 items".
+ """
+
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ 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 = speechgenerator.SpeechGenerator.\
+ _getSpeechForTableCell(self, obj, already_focused)
+
+ # Check that we are in a table cell in the mail message header list.
+ # If we are and this table cell has an expanded state, and the first
+ # token of the last utterances is "0", then strip off that last
+ # utterance ("0 items"). See bug #432308 for more details.
+ #
+ rolesList = [pyatspi.ROLE_TABLE_CELL, \
+ pyatspi.ROLE_TREE_TABLE, \
+ pyatspi.ROLE_UNKNOWN]
+ if self._script.isDesiredFocusedItem(obj, rolesList):
+ state = obj.getState()
+ if state and state.contains(pyatspi.STATE_EXPANDABLE):
+ if state.contains(pyatspi.STATE_EXPANDED):
+ tokens = utterances[-1].split()
+ if tokens[0] == "0":
+ utterances = utterances[0:-1]
+
+ return utterances
Added: trunk/src/orca/scripts/apps/evolution/where_am_i.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/evolution/where_am_i.py Fri May 2 21:21:19 2008
@@ -0,0 +1,226 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Evolution."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.debug as debug
+import orca.where_am_I as where_am_I
+
+from orca.orca_i18n import _ # for gettext support
+
+class WhereAmI(where_am_I.WhereAmI):
+
+ def __init__(self, script):
+ """Create a new WhereAmI that will be used to speak information
+ about the current object of interest.
+ """
+
+ where_am_I.WhereAmI.__init__(self, script)
+
+ def _getTableCell(self, obj):
+ """Get the speech utterances for a single table cell.
+ """
+
+ # Don't speak check box cells that area not checked.
+ notChecked = False
+ 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")]:
+ if not obj.getState().contains(pyatspi.STATE_CHECKED):
+ notChecked = True
+ break
+
+ if notChecked:
+ return ""
+
+ descendant = self._script.getRealActiveDescendant(obj)
+ text = self._script.getDisplayedText(descendant)
+
+ # For Evolution mail header list.
+ if text == "Status":
+ # Translators: this in reference to an e-mail message status of
+ # having been read or unread.
+ #
+ text = _("Read")
+
+ debug.println(self._debugLevel, "cell=<%s>" % text)
+
+ return text
+
+ def _hasTextSelections(self, obj):
+ """Return an indication of whether this object has selected text.
+ Note that it's possible that this object has no text, but is part
+ of a selected text area. Because of this, we need to check the
+ objects on either side to see if they are none zero length and
+ have text selections.
+
+ Arguments:
+ - obj: the text object to start checking for selected text.
+
+ Returns: an indication of whether this object has selected text,
+ or adjacent text objects have selected text.
+ """
+
+ currentSelected = False
+ otherSelected = False
+ nSelections = obj.queryText().getNSelections()
+ if nSelections:
+ currentSelected = True
+ else:
+ otherSelected = False
+ displayedText = obj.queryText().getText(0, -1)
+ if len(displayedText) == 0:
+ container = obj.parent.parent
+ current = obj.parent.getIndexInParent()
+ morePossibleSelections = True
+ while morePossibleSelections:
+ morePossibleSelections = False
+ if (current-1) >= 0:
+ prevPanel = container[current-1]
+ prevObj = prevPanel[0]
+ try:
+ prevObjText = prevObj.queryText()
+ except:
+ prevObjText = None
+
+ if prevObj and prevObjText:
+ if prevObjText.getNSelections() > 0:
+ otherSelected = True
+ else:
+ displayedText = prevObjText.getText(0, -1)
+ if len(displayedText) == 0:
+ current -= 1
+ morePossibleSelections = True
+
+ current = obj.parent.getIndexInParent()
+ morePossibleSelections = True
+ while morePossibleSelections:
+ morePossibleSelections = False
+ if (current+1) < container.childCount:
+ nextPanel = container[current+1]
+ nextObj = nextPanel[0]
+ try:
+ nextObjText = nextObj.queryText()
+ except:
+ nextObjText = None
+
+ if nextObj and nextObjText:
+ if nextObjText.getNSelections() > 0:
+ otherSelected = True
+ else:
+ displayedText = nextObjText.getText(0, -1)
+ if len(displayedText) == 0:
+ current += 1
+ morePossibleSelections = True
+
+ return [currentSelected, otherSelected]
+
+ def _getTextSelections(self, obj, doubleClick):
+ """Get all the text applicable text selections for the given object.
+ If the user doubleclicked, look to see if there are any previous
+ or next text objects that also have selected text and add in their
+ text contents.
+
+ Arguments:
+ - obj: the text object to start extracting the selected text from.
+ - doubleClick: True if the user double-clicked the "where am I" key.
+
+ Returns: all the selected text contents plus the start and end
+ offsets within the text for the given object.
+ """
+
+ textContents = ""
+ startOffset = 0
+ endOffset = 0
+ if obj.queryText().getNSelections() > 0:
+ [textContents, startOffset, endOffset] = \
+ self._getTextSelection(obj)
+
+ if doubleClick:
+ # Unfortunately, Evolution doesn't use the FLOWS_FROM and
+ # FLOWS_TO relationships to easily allow us to get to previous
+ # and next text objects. Instead we have to move up the
+ # component hierarchy until we get to the object containing all
+ # the panels (with each line containing a single text item).
+ # We can then check in both directions to see if there is other
+ # contiguous text that is selected. We also have to jump over
+ # zero length (empty) text lines and continue checking on the
+ # other side.
+ #
+ container = obj.parent.parent
+ current = obj.parent.getIndexInParent()
+ morePossibleSelections = True
+ while morePossibleSelections:
+ morePossibleSelections = False
+ if (current-1) >= 0:
+ prevPanel = container[current-1]
+ try:
+ prevObj = prevPanel[0]
+ displayedText = prevObj.queryText().getText(0, -1)
+ if len(displayedText) == 0:
+ current -= 1
+ morePossibleSelections = True
+ elif prevObj.queryText().getNSelections() > 0:
+ [newTextContents, start, end] = \
+ self._getTextSelection(prevObj)
+ textContents = newTextContents + " " + textContents
+ current -= 1
+ morePossibleSelections = True
+ except:
+ pass
+
+ current = obj.parent.getIndexInParent()
+ morePossibleSelections = True
+ while morePossibleSelections:
+ morePossibleSelections = False
+ if (current+1) < container.childCount:
+ nextPanel = container[current+1]
+ try:
+ nextObj = nextPanel[0]
+ displayedText = nextObj.queryText().getText(0, -1)
+ if len(displayedText) == 0:
+ current += 1
+ morePossibleSelections = True
+ elif nextObj.queryText().getNSelections() > 0:
+ [newTextContents, start, end] = \
+ self._getTextSelection(nextObj)
+ textContents += " " + newTextContents
+ current += 1
+ morePossibleSelections = True
+ except:
+ pass
+
+ return [textContents, startOffset, endOffset]
Added: trunk/src/orca/scripts/apps/gcalctool/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/gcalctool/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,10 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ script.py \
+ speech_generator.py \
+ where_am_i.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/gcalctool
+
Added: trunk/src/orca/scripts/apps/gcalctool/__init__.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/gcalctool/__init__.py Fri May 2 21:21:19 2008
@@ -0,0 +1,22 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Evolution."""
+
+from script import Script
Copied: trunk/src/orca/scripts/apps/gcalctool/script.py (from r3875, /trunk/src/orca/scripts/gcalctool.py)
==============================================================================
--- /trunk/src/orca/scripts/gcalctool.py (original)
+++ trunk/src/orca/scripts/apps/gcalctool/script.py Fri May 2 21:21:19 2008
@@ -30,58 +30,10 @@
import orca.input_event as input_event
import orca.orca_state as orca_state
import orca.speech as speech
-import orca.speechgenerator as speechgenerator
-import orca.where_am_I as where_am_I
import pyatspi
-class WhereAmI(where_am_I.WhereAmI):
-
- def __init__(self, script):
- """Create a new WhereAmI that will be used to speak information
- about the current object of interest.
- """
-
- where_am_I.WhereAmI.__init__(self, script)
-
- def _speakStatusBar(self):
- """Speaks the status bar."""
-
- if not self._statusBar:
- return
-
- utterances = []
- text = self.getObjLabelAndName(self._statusBar)
- utterances.append(text)
- speech.speakUtterances(utterances)
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Overrides _getSpeechForPushButton to handle 'unspeakable'
- button labels displayed on the screen.
- """
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
-
- def _getSpeechForObjectName(self, obj):
- """Gives preference to the object name versus what is being
- displayed on the screen. This helps accomodate the naming
- hints being given to us by gcalctool for it's mathematical
- operator buttons."""
-
- if obj.getRole() != pyatspi.ROLE_PUSH_BUTTON:
- return speechgenerator.SpeechGenerator._getSpeechForObjectName(\
- self, obj)
-
- if obj.name:
- name = obj.name
- else:
- name = self._script.getDisplayedText(obj)
-
- if name:
- return [name]
- elif obj.description:
- return [obj.description]
- else:
- return []
+from speech_generator import SpeechGenerator
+from where_am_i import WhereAmI
########################################################################
# #
Added: trunk/src/orca/scripts/apps/gcalctool/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/gcalctool/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,58 @@
+# Orca
+#
+# Copyright 2004-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Provides a custom script for gcalctool."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.speechgenerator as speechgenerator
+import pyatspi
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Overrides _getSpeechForPushButton to handle 'unspeakable'
+ button labels displayed on the screen.
+ """
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ def _getSpeechForObjectName(self, obj):
+ """Gives preference to the object name versus what is being
+ displayed on the screen. This helps accomodate the naming
+ hints being given to us by gcalctool for it's mathematical
+ operator buttons."""
+
+ if obj.getRole() != pyatspi.ROLE_PUSH_BUTTON:
+ return speechgenerator.SpeechGenerator._getSpeechForObjectName(\
+ self, obj)
+
+ if obj.name:
+ name = obj.name
+ else:
+ name = self._script.getDisplayedText(obj)
+
+ if name:
+ return [name]
+ elif obj.description:
+ return [obj.description]
+ else:
+ return []
Copied: trunk/src/orca/scripts/apps/gcalctool/where_am_i.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/gcalctool/where_am_i.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2004-2007 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
@@ -17,20 +17,33 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Provides a custom script for gcalctool."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
+import orca.speech as speech
+import orca.where_am_I as where_am_I
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+class WhereAmI(where_am_I.WhereAmI):
+
+ def __init__(self, script):
+ """Create a new WhereAmI that will be used to speak information
+ about the current object of interest.
+ """
+
+ where_am_I.WhereAmI.__init__(self, script)
+
+ def _speakStatusBar(self):
+ """Speaks the status bar."""
+
+ if not self._statusBar:
+ return
+
+ utterances = []
+ text = self.getObjLabelAndName(self._statusBar)
+ utterances.append(text)
+ speech.speakUtterances(utterances)
Copied: trunk/src/orca/scripts/apps/gdmlogin.py (from r3875, /trunk/src/orca/scripts/gdmlogin.py)
==============================================================================
Added: trunk/src/orca/scripts/apps/gedit/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/gedit/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,9 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ script.py \
+ speech_generator.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/gedit
+
Copied: trunk/src/orca/scripts/apps/gedit/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/gedit/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2004-2007 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
@@ -17,20 +17,12 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for gedit."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
Copied: trunk/src/orca/scripts/apps/gedit/script.py (from r3875, /trunk/src/orca/scripts/gedit.py)
==============================================================================
--- /trunk/src/orca/scripts/gedit.py (original)
+++ trunk/src/orca/scripts/apps/gedit/script.py Fri May 2 21:21:19 2008
@@ -34,49 +34,11 @@
import orca.orca_state as orca_state
import orca.settings as settings
import orca.speech as speech
-import orca.speechgenerator as speechgenerator
import orca.speechserver as speechserver
from orca.orca_i18n import _
-########################################################################
-# #
-# The GEdit script class. #
-# #
-########################################################################
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Overrides _getSpeechForFrame so as to avoid digging into the
- gedit hierarchy and tickling a bug in gedit.
- """
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
-
- def _getSpeechForFrame(self, obj, already_focused):
- """Get the speech for a frame. [[[TODO: WDW - This avoids
- digging into the component hierarchy so as to avoid tickling
- a bug in GEdit (see module comment above).]]]
-
- Arguments:
- - obj: the frame
- - already_focused: if False, the obj just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = self._getDefaultSpeech(obj, already_focused)
-
- # This will dig deep into the hierarchy, causing issues with
- # gedit. So, we won't do this.
- #
- #utterances = self._getSpeechForAlert(obj, already_focused)
-
- self._debugGenerator("GEditSpeechGenerator._getSpeechForFrame",
- obj,
- already_focused,
- utterances)
-
- return utterances
+from speech_generator import SpeechGenerator
class Script(default.Script):
Copied: trunk/src/orca/scripts/apps/gedit/speech_generator.py (from r3875, /trunk/src/orca/scripts/gnome-window-properties.py)
==============================================================================
--- /trunk/src/orca/scripts/gnome-window-properties.py (original)
+++ trunk/src/orca/scripts/apps/gedit/speech_generator.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2006 Sun Microsystems Inc.
+# Copyright 2004-2007 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
@@ -17,20 +17,19 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for gnome-window-properties."""
+"""Custom script for gedit."""
-__id__ = "$Id$"
+__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.default as default
import orca.speechgenerator as speechgenerator
########################################################################
# #
-# The gnome-window-properties script class. #
+# The GEdit script class. #
# #
########################################################################
@@ -41,41 +40,28 @@
def __init__(self, script):
speechgenerator.SpeechGenerator.__init__(self, script)
- def _getSpeechForAlert(self, obj, already_focused):
- """Gets the title of the dialog. Do NOT get the contents
- of labels inside the dialog that are not associated with any
- other objects.
+ def _getSpeechForFrame(self, obj, already_focused):
+ """Get the speech for a frame. [[[TODO: WDW - This avoids
+ digging into the component hierarchy so as to avoid tickling
+ a bug in GEdit (see module comment above).]]]
Arguments:
- - obj: the Accessible dialog
- - already_focused: False if object just received focus
+ - obj: the frame
+ - already_focused: if False, the obj just received focus
- Returns a list of utterances be spoken.
+ Returns a list of utterances to be spoken for the object.
"""
- utterances = []
- utterances.extend(self._getSpeechForObjectLabel(obj))
- utterances.extend(self._getSpeechForObjectName(obj))
- utterances.extend(self._getSpeechForObjectRole(obj))
+ utterances = self._getDefaultSpeech(obj, already_focused)
- self._debugGenerator("gnome-window-properties._getSpeechForAlert",
+ # This will dig deep into the hierarchy, causing issues with
+ # gedit. So, we won't do this.
+ #
+ #utterances = self._getSpeechForAlert(obj, already_focused)
+
+ self._debugGenerator("GEditSpeechGenerator._getSpeechForFrame",
obj,
already_focused,
utterances)
return utterances
-
-class Script(default.Script):
-
- def __init__(self, app):
- """Creates a new script for the given application.
-
- Arguments:
- - app: the application to create a script for.
- """
- default.Script.__init__(self, app)
-
- def getSpeechGenerator(self):
- """Returns the speech generator for this script.
- """
- return SpeechGenerator(self)
Copied: trunk/src/orca/scripts/apps/gnome-keyring-ask.py (from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/gnome-mud.py (from r3875, /trunk/src/orca/scripts/gnome-mud.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/gnome-panel.py (from r3875, /trunk/src/orca/scripts/gnome-panel.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/gnome-search-tool.py (from r3875, /trunk/src/orca/scripts/gnome-search-tool.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/gnome-system-monitor.py (from r3875, /trunk/src/orca/scripts/gnome-system-monitor.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/gnome-terminal.py (from r3875, /trunk/src/orca/scripts/gnome-terminal.py)
==============================================================================
Added: trunk/src/orca/scripts/apps/gnome-window-properties/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/gnome-window-properties/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,9 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ script.py \
+ speech_generator.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/gnome-window-properties
+
Copied: trunk/src/orca/scripts/apps/gnome-window-properties/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/gnome-window-properties/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2006 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
@@ -17,20 +17,12 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for gnome-window-properties."""
-__id__ = "$Id$"
+__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
Copied: trunk/src/orca/scripts/apps/gnome-window-properties/script.py (from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py)
==============================================================================
--- /trunk/src/orca/scripts/gnome-keyring-ask.py (original)
+++ trunk/src/orca/scripts/apps/gnome-window-properties/script.py Fri May 2 21:21:19 2008
@@ -17,9 +17,9 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for gnome-keyring-ask"""
+"""Custom script for gnome-window-properties."""
-__id__ = "$Id$"
+__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
@@ -27,12 +27,15 @@
import orca.default as default
+from speech_generator import SpeechGenerator
+
########################################################################
# #
-# The gnome-keyring-ask script class. #
+# The gnome-window-properties script class. #
# #
########################################################################
+
class Script(default.Script):
def __init__(self, app):
@@ -41,22 +44,9 @@
Arguments:
- app: the application to create a script for.
"""
-
default.Script.__init__(self, app)
- def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus):
- """Called when the visual object with focus changes.
-
- Arguments:
- - event: if not None, the Event that caused the change
- - oldLocusOfFocus: Accessible that is the old locus of focus
- - newLocusOfFocus: Accessible that is the new locus of focus
+ def getSpeechGenerator(self):
+ """Returns the speech generator for this script.
"""
-
- # If the gnome-keyring-ask application starts up, don't compare
- # it with the application that previously had focus because it
- # more often than not will just hang (see bug #351569).
- # We do this by setting the old locus of focus to None, then
- # we can safely call the locusOfFocusChanged() method in default.py.
- #
- default.Script.locusOfFocusChanged(self, event, None, newLocusOfFocus)
+ return SpeechGenerator(self)
Copied: trunk/src/orca/scripts/apps/gnome-window-properties/speech_generator.py (from r3875, /trunk/src/orca/scripts/gnome-window-properties.py)
==============================================================================
--- /trunk/src/orca/scripts/gnome-window-properties.py (original)
+++ trunk/src/orca/scripts/apps/gnome-window-properties/speech_generator.py Fri May 2 21:21:19 2008
@@ -25,15 +25,8 @@
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.default as default
import orca.speechgenerator as speechgenerator
-########################################################################
-# #
-# The gnome-window-properties script class. #
-# #
-########################################################################
-
class SpeechGenerator(speechgenerator.SpeechGenerator):
"""Overrides _getSpeechForFrame so as to avoid digging into the
gedit hierarchy and tickling a bug in gedit.
@@ -64,18 +57,3 @@
utterances)
return utterances
-
-class Script(default.Script):
-
- def __init__(self, app):
- """Creates a new script for the given application.
-
- Arguments:
- - app: the application to create a script for.
- """
- default.Script.__init__(self, app)
-
- def getSpeechGenerator(self):
- """Returns the speech generator for this script.
- """
- return SpeechGenerator(self)
Copied: trunk/src/orca/scripts/apps/gnome_segv2.py (from r3875, /trunk/src/orca/scripts/gnome_segv2.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/liferea.py (from r3875, /trunk/src/orca/scripts/liferea.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/metacity.py (from r3875, /trunk/src/orca/scripts/metacity.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/nautilus.py (from r3875, /trunk/src/orca/scripts/nautilus.py)
==============================================================================
Copied: trunk/src/orca/scripts/apps/notification-daemon.py (from r3875, /trunk/src/orca/scripts/notification-daemon.py)
==============================================================================
Added: trunk/src/orca/scripts/apps/pidgin/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/pidgin/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,11 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ constants.py \
+ script.py \
+ speech_generator.py \
+ where_am_i.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/pidgin
+
Copied: trunk/src/orca/scripts/apps/pidgin/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/pidgin/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2005-2007 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
@@ -17,20 +17,7 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for Evolution."""
-__id__ = "$Id$"
-__version__ = "$Revision$"
-__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
-__license__ = "LGPL"
-
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
+from constants import *
Added: trunk/src/orca/scripts/apps/pidgin/constants.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/pidgin/constants.py Fri May 2 21:21:19 2008
@@ -0,0 +1,57 @@
+# Orca
+#
+# Copyright 2004-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for gaim. This provides the ability for Orca to
+monitor both the IM input and IM output text areas at the same time.
+
+The following script specific key sequences are supported:
+
+ Insert-h - Toggle whether we prefix chat room messages with
+ the name of the chat room.
+ Insert-[1-9] - Speak and braille a previous chat room message.
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+# Whether we prefix chat room messages with the name of the chat room.
+#
+prefixChatMessage = False
+
+# Whether we announce when a buddy is typing.
+#
+announceBuddyTyping = False
+
+# Whether we provide chat room specific message histories.
+#
+chatRoomHistories = False
+
+# Possible ways of how Orca should speak pidgin chat messages.
+#
+SPEAK_ALL_MESSAGES = 0
+SPEAK_CHANNEL_WITH_FOCUS = 1
+SPEAK_ALL_CHANNELS_WHEN_FOCUSED = 2
+
+# Indicates how pidgin chat messages should be spoken.
+#
+speakMessages = SPEAK_ALL_MESSAGES
+
Copied: trunk/src/orca/scripts/apps/pidgin/script.py (from r3875, /trunk/src/orca/scripts/gaim.py)
==============================================================================
--- /trunk/src/orca/scripts/gaim.py (original)
+++ trunk/src/orca/scripts/apps/pidgin/script.py Fri May 2 21:21:19 2008
@@ -42,36 +42,14 @@
import orca.input_event as input_event
import orca.keybindings as keybindings
import orca.orca_state as orca_state
-import orca.rolenames as rolenames
import orca.settings as settings
import orca.speech as speech
-import orca.speechgenerator as speechgenerator
-import orca.where_am_I as where_am_I
from orca.orca_i18n import _
-from orca.orca_i18n import ngettext # for ngettext support
-# Whether we prefix chat room messages with the name of the chat room.
-#
-prefixChatMessage = False
-
-# Whether we announce when a buddy is typing.
-#
-announceBuddyTyping = False
-
-# Whether we provide chat room specific message histories.
-#
-chatRoomHistories = False
-
-# Possible ways of how Orca should speak pidgin chat messages.
-#
-SPEAK_ALL_MESSAGES = 0
-SPEAK_CHANNEL_WITH_FOCUS = 1
-SPEAK_ALL_CHANNELS_WHEN_FOCUSED = 2
-
-# Indicates how pidgin chat messages should be spoken.
-#
-speakMessages = SPEAK_ALL_MESSAGES
+from speech_generator import SpeechGenerator
+from where_am_i import WhereAmI
+from constants import *
########################################################################
# #
@@ -115,199 +93,6 @@
def __str__(self):
return ''.join(self.__data__)
-########################################################################
-# #
-# Custom SpeechGenerator #
-# #
-########################################################################
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Overrides _getSpeechForTableCell() so that we can provide access
- to the expanded/collapsed state and node count for the buddy list.
- """
-
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
-
- def _getSpeechForTableCell(self, obj, already_focused):
- """Get the speech utterances for a single table cell
-
- Arguments:
- - obj: the table cell
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = speechgenerator.SpeechGenerator._getSpeechForTableCell( \
- self, obj, already_focused)
-
- if not self._script.isInBuddyList(obj):
- return utterances
-
- # The Pidgin buddy list consists of two columns. The column which
- # is set as the expander column and which also contains the node
- # relationship is hidden. Hidden columns are not included among
- # a table's columns. The hidden object of interest seems to always
- # immediately precede the visible object.
- #
- expanderCell = obj.parent[obj.getIndexInParent() - 1]
- if not expanderCell:
- return utterances
-
- state = expanderCell.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(expanderCell)
- 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"))
-
- self._debugGenerator("gaim._getSpeechForTableCell",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
-########################################################################
-# #
-# Custom WhereAmI #
-# #
-########################################################################
-
-class WhereAmI(where_am_I.WhereAmI):
- """Overrides _speakTableCell() so that we can provide access
- to the expanded/collapsed state for items in the buddy list.
- """
-
- def __init__(self, script):
- where_am_I.WhereAmI.__init__(self, script)
- self._script = script
-
- def _speakTableCell(self, obj, doubleClick):
- """Tree Tables present the following information (an example is
- 'Tree table, Mike Pedersen, row 8 of 10, tree level 2'):
-
- 1. label, if any
- 2. role
- 3. current row (regardless of speak cell/row setting)
- 4. relative position
- 5. if expandable/collapsible: expanded/collapsed
- 6. if applicable, the level
-
- """
-
- if not self._script.isInBuddyList(obj):
- return where_am_I.WhereAmI._speakTableCell(self, obj, doubleClick)
-
- # Speak the first two items (and possibly the position)
- #
- utterances = []
- if obj.parent.getRole() == pyatspi.ROLE_TABLE_CELL:
- obj = obj.parent
- parent = obj.parent
-
- text = self._getObjLabel(obj)
- utterances.append(text)
-
- text = rolenames.getSpeechForRoleName(obj)
- utterances.append(text)
- debug.println(self._debugLevel, "first table cell utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
-
- utterances = []
- if doubleClick:
- table = parent.queryTable()
- row = table.getRowAtIndex(
- orca_state.locusOfFocus.getIndexInParent())
- # Translators: this in reference to a row in a table.
- #
- text = _("row %d of %d") % ((row+1), table.nRows)
- utterances.append(text)
- speech.speakUtterances(utterances)
-
- # Speak the current row
- #
- utterances = self._getTableRow(obj)
- debug.println(self._debugLevel, "second table cell utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
-
- # Speak the remaining items.
- #
- utterances = []
-
- if not doubleClick:
- try:
- table = parent.queryTable()
- except NotImplementedError:
- debug.println(self._debugLevel,
- "??? parent=%s" % parent.getRoleName())
- return
- else:
- row = \
- table.getRowAtIndex(
- orca_state.locusOfFocus.getIndexInParent())
- # Translators: this in reference to a row in a table.
- #
- text = _("row %d of %d") % ((row+1), table.nRows)
- utterances.append(text)
-
- # The difference/reason for overriding: We obtain the expanded
- # state from the hidden object that immediately precedes obj.
- #
- try:
- state = obj.parent[obj.getIndexInParent() - 1].getState()
- except:
- 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 = _("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 = _("collapsed")
- utterances.append(text)
-
- level = self._script.getNodeLevel(orca_state.locusOfFocus)
- if level >= 0:
- # Translators: this represents the depth of a node in a tree
- # view (i.e., how many ancestors a node has).
- #
- utterances.append(_("tree level %d") % (level + 1))
-
- debug.println(self._debugLevel, "third table cell utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
########################################################################
# #
Added: trunk/src/orca/scripts/apps/pidgin/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/pidgin/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,118 @@
+# Orca
+#
+# Copyright 2004-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for gaim. This provides the ability for Orca to
+monitor both the IM input and IM output text areas at the same time.
+
+The following script specific key sequences are supported:
+
+ Insert-h - Toggle whether we prefix chat room messages with
+ the name of the chat room.
+ Insert-[1-9] - Speak and braille a previous chat room message.
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.settings as settings
+import orca.speechgenerator as speechgenerator
+
+from orca.orca_i18n import _
+from orca.orca_i18n import ngettext # for ngettext support
+
+########################################################################
+# #
+# Custom SpeechGenerator #
+# #
+########################################################################
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Overrides _getSpeechForTableCell() so that we can provide access
+ to the expanded/collapsed state and node count for the buddy list.
+ """
+
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ def _getSpeechForTableCell(self, obj, already_focused):
+ """Get the speech utterances for a single table cell
+
+ Arguments:
+ - obj: the table cell
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ utterances = speechgenerator.SpeechGenerator._getSpeechForTableCell( \
+ self, obj, already_focused)
+
+ if not self._script.isInBuddyList(obj):
+ return utterances
+
+ # The Pidgin buddy list consists of two columns. The column which
+ # is set as the expander column and which also contains the node
+ # relationship is hidden. Hidden columns are not included among
+ # a table's columns. The hidden object of interest seems to always
+ # immediately precede the visible object.
+ #
+ expanderCell = obj.parent[obj.getIndexInParent() - 1]
+ if not expanderCell:
+ return utterances
+
+ state = expanderCell.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(expanderCell)
+ 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"))
+
+ self._debugGenerator("gaim._getSpeechForTableCell",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
Added: trunk/src/orca/scripts/apps/pidgin/where_am_i.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/pidgin/where_am_i.py Fri May 2 21:21:19 2008
@@ -0,0 +1,163 @@
+# Orca
+#
+# Copyright 2004-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for gaim. This provides the ability for Orca to
+monitor both the IM input and IM output text areas at the same time.
+
+The following script specific key sequences are supported:
+
+ Insert-h - Toggle whether we prefix chat room messages with
+ the name of the chat room.
+ Insert-[1-9] - Speak and braille a previous chat room message.
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.debug as debug
+import orca.orca_state as orca_state
+import orca.rolenames as rolenames
+import orca.speech as speech
+import orca.where_am_I as where_am_I
+
+from orca.orca_i18n import _
+
+########################################################################
+# #
+# Custom WhereAmI #
+# #
+########################################################################
+
+class WhereAmI(where_am_I.WhereAmI):
+ """Overrides _speakTableCell() so that we can provide access
+ to the expanded/collapsed state for items in the buddy list.
+ """
+
+ def __init__(self, script):
+ where_am_I.WhereAmI.__init__(self, script)
+ self._script = script
+
+ def _speakTableCell(self, obj, doubleClick):
+ """Tree Tables present the following information (an example is
+ 'Tree table, Mike Pedersen, row 8 of 10, tree level 2'):
+
+ 1. label, if any
+ 2. role
+ 3. current row (regardless of speak cell/row setting)
+ 4. relative position
+ 5. if expandable/collapsible: expanded/collapsed
+ 6. if applicable, the level
+
+ """
+
+ if not self._script.isInBuddyList(obj):
+ return where_am_I.WhereAmI._speakTableCell(self, obj, doubleClick)
+
+ # Speak the first two items (and possibly the position)
+ #
+ utterances = []
+ if obj.parent.getRole() == pyatspi.ROLE_TABLE_CELL:
+ obj = obj.parent
+ parent = obj.parent
+
+ text = self._getObjLabel(obj)
+ utterances.append(text)
+
+ text = rolenames.getSpeechForRoleName(obj)
+ utterances.append(text)
+ debug.println(self._debugLevel, "first table cell utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
+
+ utterances = []
+ if doubleClick:
+ table = parent.queryTable()
+ row = table.getRowAtIndex(
+ orca_state.locusOfFocus.getIndexInParent())
+ # Translators: this in reference to a row in a table.
+ #
+ text = _("row %d of %d") % ((row+1), table.nRows)
+ utterances.append(text)
+ speech.speakUtterances(utterances)
+
+ # Speak the current row
+ #
+ utterances = self._getTableRow(obj)
+ debug.println(self._debugLevel, "second table cell utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
+
+ # Speak the remaining items.
+ #
+ utterances = []
+
+ if not doubleClick:
+ try:
+ table = parent.queryTable()
+ except NotImplementedError:
+ debug.println(self._debugLevel,
+ "??? parent=%s" % parent.getRoleName())
+ return
+ else:
+ row = \
+ table.getRowAtIndex(
+ orca_state.locusOfFocus.getIndexInParent())
+ # Translators: this in reference to a row in a table.
+ #
+ text = _("row %d of %d") % ((row+1), table.nRows)
+ utterances.append(text)
+
+ # The difference/reason for overriding: We obtain the expanded
+ # state from the hidden object that immediately precedes obj.
+ #
+ try:
+ state = obj.parent[obj.getIndexInParent() - 1].getState()
+ except:
+ 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 = _("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 = _("collapsed")
+ utterances.append(text)
+
+ level = self._script.getNodeLevel(orca_state.locusOfFocus)
+ if level >= 0:
+ # Translators: this represents the depth of a node in a tree
+ # view (i.e., how many ancestors a node has).
+ #
+ utterances.append(_("tree level %d") % (level + 1))
+
+ debug.println(self._debugLevel, "third table cell utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
Added: trunk/src/orca/scripts/apps/planner/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/planner/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,10 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ braille_generator.py \
+ script.py \
+ speech_generator.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/planner
+
Copied: trunk/src/orca/scripts/apps/planner/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/planner/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 2006-2007 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
@@ -17,20 +17,12 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for planner."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2006-2007 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
Added: trunk/src/orca/scripts/apps/planner/braille_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/planner/braille_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,87 @@
+# Orca
+#
+# Copyright 2006-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for planner."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2006-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.braille as braille
+import orca.settings as settings
+import orca.braillegenerator as braillegenerator
+import pyatspi
+
+from orca.orca_i18n import _ # for gettext support
+
+class BrailleGenerator(braillegenerator.BrailleGenerator):
+ """We make this to appropiately present ribbon's toggle button in
+ a toolbar used to display in a menu those options that doesn't
+ fill in toolbar when the application is resized. Also for each one
+ of the grphics buttons in the main window."""
+
+ def __init__(self, script):
+ braillegenerator.BrailleGenerator.__init__(self, script)
+
+ def _getBrailleRegionsForToggleButton(self, obj):
+ """Get the braille for a radio button. If the button already had
+ focus, then only the state is displayed.
+
+ Arguments:
+ - obj: the check box
+
+ 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("_getBrailleRegionsForRadioButton", obj)
+
+ text = ""
+ text = self._script.appendString(text,
+ self._script.getDisplayedLabel(obj))
+ text = self._script.appendString(text,
+ self._script.getDisplayedText(obj))
+
+ # First special toggle button is the one in the toolbar and
+ # that it has no name Application should implement an
+ # accessible name in this component, but until this is made We
+ # speech/braille "display more options" when the focus is in
+ # one of these toggle buttons.
+ #
+ roleList = [pyatspi.ROLE_TOGGLE_BUTTON, pyatspi.ROLE_TOOL_BAR]
+
+ if self._script.isDesiredFocusedItem(obj, roleList) and not obj.name:
+ text += _("Display more options")
+
+ text = self._script.appendString(text, self._getTextForRole(obj))
+
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ brailleindicatorindex = 1
+ else:
+ brailleindicatorindex = 0
+
+ regions = []
+ indicator = \
+ settings.brailleRadioButtonIndicators[brailleindicatorindex]
+ componentRegion = braille.Component(obj, text, indicator=indicator)
+ regions.append(componentRegion)
+
+ return [regions, componentRegion]
Copied: trunk/src/orca/scripts/apps/planner/script.py (from r3875, /trunk/src/orca/scripts/gnome-keyring-ask.py)
==============================================================================
--- /trunk/src/orca/scripts/gnome-keyring-ask.py (original)
+++ trunk/src/orca/scripts/apps/planner/script.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2006 Sun Microsystems Inc.
+# Copyright 2006-2007 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
@@ -17,19 +17,22 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for gnome-keyring-ask"""
+"""Custom script for planner."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2006-2007 Sun Microsystems Inc."
__license__ = "LGPL"
import orca.default as default
+from speech_generator import SpeechGenerator
+from braille_generator import BrailleGenerator
+
########################################################################
# #
-# The gnome-keyring-ask script class. #
+# The planner script class. #
# #
########################################################################
@@ -41,22 +44,14 @@
Arguments:
- app: the application to create a script for.
"""
-
default.Script.__init__(self, app)
- def locusOfFocusChanged(self, event, oldLocusOfFocus, newLocusOfFocus):
- """Called when the visual object with focus changes.
-
- Arguments:
- - event: if not None, the Event that caused the change
- - oldLocusOfFocus: Accessible that is the old locus of focus
- - newLocusOfFocus: Accessible that is the new locus of focus
- """
+ # This method tries to detect and handle the following cases:
+ # 1) Toolbar: the last toggle button to show 'more options'
+ # 2) Main window: one of the four graphic toggle buttons.
+ #
+ def getBrailleGenerator(self):
+ return BrailleGenerator(self)
- # If the gnome-keyring-ask application starts up, don't compare
- # it with the application that previously had focus because it
- # more often than not will just hang (see bug #351569).
- # We do this by setting the old locus of focus to None, then
- # we can safely call the locusOfFocusChanged() method in default.py.
- #
- default.Script.locusOfFocusChanged(self, event, None, newLocusOfFocus)
+ def getSpeechGenerator(self):
+ return SpeechGenerator(self)
Added: trunk/src/orca/scripts/apps/planner/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/planner/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,77 @@
+# Orca
+#
+# Copyright 2006-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for planner."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2006-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.speechgenerator as speechgenerator
+import pyatspi
+
+from orca.orca_i18n import _ # for gettext support
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ # We make this to appropiately present ribbon's toggle button in a
+ # toolbar used to display in a menu those options that doesn fill
+ # in toolbar when the application is resized.
+ #
+ # Also for each one of the grphics buttons in the main window
+ #
+ def _getSpeechForToggleButton(self, obj, already_focused):
+ utterances = []
+ tmp = []
+
+ # Application should implement an accessible name in this
+ # component, but until this is made We speech/braille "display
+ # more options" when the focus is in one of these toggle
+ # buttons.
+ #
+
+ roleList = [pyatspi.ROLE_TOGGLE_BUTTON, \
+ pyatspi.ROLE_TOOL_BAR]
+
+ if self._script.isDesiredFocusedItem(obj, roleList) and not obj.name:
+ if not already_focused:
+ tmp.append(_("Display more options"))
+ tmp.extend(self._getDefaultSpeech(obj, already_focused))
+
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ tmp.append(_("pressed"))
+ else:
+ tmp.append(_("not pressed"))
+
+ utterances.extend(tmp)
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+ else:
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ utterances.append(_("pressed"))
+ else:
+ utterances.append(_("not pressed"))
+
+ return utterances
+
+ return self._getSpeechForLabel(obj, already_focused)
Added: trunk/src/orca/scripts/apps/rhythmbox/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/rhythmbox/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,10 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ braille_generator.py \
+ script.py \
+ speech_generator.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/rhythmbox
+
Copied: trunk/src/orca/scripts/apps/rhythmbox/__init__.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/apps/rhythmbox/__init__.py Fri May 2 21:21:19 2008
@@ -1,6 +1,6 @@
# Orca
#
-# Copyright 2005-2006 Sun Microsystems Inc.
+# Copyright 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
@@ -17,20 +17,12 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for rhythmbox."""
-__id__ = "$Id$"
-__version__ = "$Revision$"
-__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
-
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+from script import Script
Added: trunk/src/orca/scripts/apps/rhythmbox/braille_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/rhythmbox/braille_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,56 @@
+# Orca
+#
+# Copyright 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for rhythmbox."""
+
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.braillegenerator as braillegenerator
+
+class BrailleGenerator(braillegenerator.BrailleGenerator):
+ """Overrides _getBrailleRegionsForTableCell to correctly handle
+ the table cells in the Library table.
+ """
+
+ def __init__(self, script):
+ braillegenerator.BrailleGenerator.__init__(self, script)
+
+ def _getBrailleRegionsForTableCell(self, obj):
+ """Get the braille for a single table cell
+
+ Arguments:
+ - obj: the table
+
+ 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.
+ """
+
+ # Check to see if this is a table cell from the Library table.
+ # If so, it'll have five children and we are interested in the
+ # penultimate one. See bug #512639 for more details.
+ #
+ if obj.childCount == 5:
+ obj = obj[3]
+
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForTableCell(self, obj)
Added: trunk/src/orca/scripts/apps/rhythmbox/script.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/rhythmbox/script.py Fri May 2 21:21:19 2008
@@ -0,0 +1,52 @@
+# Orca
+#
+# Copyright 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for rhythmbox."""
+
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.default as default
+
+from speech_generator import SpeechGenerator
+from braille_generator import BrailleGenerator
+
+class Script(default.Script):
+
+ def __init__(self, app):
+ """Creates a new script for the given application.
+
+ Arguments:
+ - app: the application to create a script for.
+ """
+ default.Script.__init__(self, app)
+
+ def getBrailleGenerator(self):
+ """Returns the braille generator for this script.
+ """
+
+ return BrailleGenerator(self)
+
+ def getSpeechGenerator(self):
+ """Returns the speech generator for this script.
+ """
+ return SpeechGenerator(self)
Added: trunk/src/orca/scripts/apps/rhythmbox/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/rhythmbox/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,55 @@
+# Orca
+#
+# Copyright 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for rhythmbox."""
+
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import orca.speechgenerator as speechgenerator
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Overrides _getSpeechForTableCell to correctly handle the table
+ cells in the Library table.
+ """
+
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ 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.
+ """
+
+ # Check to see if this is a table cell from the Library table.
+ # If so, it'll have five children and we are interested in the
+ # penultimate one. See bug #512639 for more details.
+ #
+ if obj.childCount == 5:
+ obj = obj[3]
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForTableCell(self, obj, already_focused)
Added: trunk/src/orca/scripts/apps/soffice/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,12 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ braille_generator.py \
+ constants.py \
+ __init__.py \
+ script.py \
+ speech_generator.py \
+ where_am_i.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/apps/soffice
+
Added: trunk/src/orca/scripts/apps/soffice/__init__.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/__init__.py Fri May 2 21:21:19 2008
@@ -0,0 +1,2 @@
+from script import Script
+from constants import speakCellCoordinates
Added: trunk/src/orca/scripts/apps/soffice/braille_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/braille_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,233 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for StarOffice and OpenOffice."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.braille as braille
+import orca.braillegenerator as braillegenerator
+import orca.settings as settings
+
+class BrailleGenerator(braillegenerator.BrailleGenerator):
+ """Overrides _getBrailleRegionsForTableCellRow so that , when we are
+ in a spread sheet, we can braille the dynamic row and column headers
+ (assuming they are set).
+ Overrides _getBrailleRegionsForTableCell so that, when we are in
+ a spread sheet, we can braille the location of the table cell as well
+ as the contents.
+ """
+
+ def __init__(self, script):
+ braillegenerator.BrailleGenerator.__init__(self, script)
+
+ def _getBrailleRegionsForTableCellRow(self, obj):
+ """Get the braille for a table cell row or a single table cell
+ if settings.readTableCellRow is False.
+
+ Arguments:
+ - obj: the table cell
+
+ 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.
+ """
+
+ focusRegion = None
+ regions = []
+
+ # Check to see if this spread sheet cell has either a dynamic
+ # column heading or row heading (or both) associated with it.
+ # If it does, then braille those first before brailling the
+ # cell contents.
+ #
+ table = self._script.getTable(obj)
+ parent = obj.parent
+ try:
+ parentTable = parent.queryTable()
+ except NotImplementedError:
+ parentTable = None
+
+ if self._script.pointOfReference.has_key("lastColumn") and \
+ self._script.pointOfReference["lastColumn"] != \
+ parentTable.getColumnAtIndex(obj.getIndexInParent()):
+ if self._script.dynamicColumnHeaders.has_key(table):
+ row = self._script.dynamicColumnHeaders[table]
+ header = self._script.getDynamicRowHeaderCell(obj, row)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ regions.append(braille.Region(" " + text + " "))
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ regions.append(braille.Region(" " + text + " "))
+
+ if self._script.pointOfReference.has_key("lastRow") and \
+ self._script.pointOfReference['lastRow'] != \
+ parentTable.getRowAtIndex(obj.getIndexInParent()):
+ if self._script.dynamicRowHeaders.has_key(table):
+ column = self._script.dynamicRowHeaders[table]
+ header = self._script.getDynamicColumnHeaderCell(obj, column)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ regions.append(braille.Region(" " + text + " "))
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ regions.append(braille.Region(" " + text + " "))
+
+ if self._script.isSpreadSheetCell(obj):
+
+ # Adding in a check here to make sure that the parent is a
+ # valid table. It's possible that the parent could be a
+ # table cell too (see bug #351501).
+ #
+ if settings.readTableCellRow and parentTable:
+ rowRegions = []
+ savedBrailleVerbosityLevel = settings.brailleVerbosityLevel
+ settings.brailleVerbosityLevel = \
+ settings.VERBOSITY_LEVEL_BRIEF
+
+ parent = obj.parent
+ row = parentTable.getRowAtIndex(obj.getIndexInParent())
+ column = parentTable.getColumnAtIndex(obj.getIndexInParent())
+
+ # 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 self._script.pointOfReference.has_key("lastRow") and \
+ self._script.pointOfReference.has_key("lastColumn"):
+ pointOfReference = self._script.pointOfReference
+ speakAll = \
+ (pointOfReference["lastRow"] != row) or \
+ ((row == 0 or row == parentTable.nRows-1) and \
+ pointOfReference["lastColumn"] == column)
+
+ if speakAll:
+ [startIndex, endIndex] = \
+ self._script.getSpreadSheetRowRange(obj)
+ for i in range(startIndex, endIndex+1):
+ cell = parentTable.getAccessibleAt(row, i)
+ showing = cell.getState().contains( \
+ pyatspi.STATE_SHOWING)
+ if showing:
+ [cellRegions, focusRegion] = \
+ self._getBrailleRegionsForTableCell(cell)
+ if len(rowRegions):
+ rowRegions.append(braille.Region(" "))
+ rowRegions.append(cellRegions[0])
+ regions.extend(rowRegions)
+ settings.brailleVerbosityLevel = savedBrailleVerbosityLevel
+ else:
+ [cellRegions, focusRegion] = \
+ self._getBrailleRegionsForTableCell(obj)
+ regions.extend(cellRegions)
+ else:
+ [cellRegions, focusRegion] = \
+ self._getBrailleRegionsForTableCell(obj)
+ regions.extend(cellRegions)
+ regions = [regions, focusRegion]
+ else:
+ [cellRegions, focusRegion] = \
+ braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForTableCellRow(self, obj)
+ regions.extend(cellRegions)
+ regions = [regions, focusRegion]
+
+ return regions
+
+ def _getBrailleRegionsForTableCell(self, obj):
+ """Get the braille for a table cell. If this isn't inside a
+ spread sheet, just return the regions returned by the default
+ table cell braille handler.
+
+ Arguments:
+ - obj: the table cell
+
+ 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.
+ """
+
+ if self._script.isSpreadSheetCell(obj):
+ if self._script.inputLineForCell == None:
+ self._script.inputLineForCell = \
+ self._script.locateInputLine(obj)
+
+ regions = []
+ text = self._script.getDisplayedText(obj)
+ componentRegion = braille.Component(obj, text)
+ regions.append(componentRegion)
+
+ # If the spread sheet table cell has something in it, then we
+ # want to append the name of the cell (which will be its location).
+ # Note that if the cell was empty, then
+ # self._script.getDisplayedText will have already done this for us.
+ #
+ try:
+ if obj.queryText():
+ objectText = self._script.getText(obj, 0, -1)
+ if objectText and len(objectText) != 0:
+ regions.append(braille.Region(" " + obj.name))
+ except NotImplementedError:
+ pass
+
+ return [regions, componentRegion]
+
+ else:
+ # Check to see how many children this table cell has. If it's
+ # just one (or none), then pass it on to the superclass to be
+ # processed.
+ #
+ # If it's more than one, then get the braille regions for each
+ # child, and call this method again.
+ #
+ if obj.childCount <= 1:
+ regions = braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForTableCell(self, obj)
+ else:
+ regions = []
+ for child in obj:
+ [cellRegions, focusRegion] = \
+ self._getBrailleRegionsForTableCell(child)
+ regions.extend(cellRegions)
+ return [regions, focusRegion]
+
+ return regions
Added: trunk/src/orca/scripts/apps/soffice/constants.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/constants.py Fri May 2 21:21:19 2008
@@ -0,0 +1,3 @@
+# Whether we speak spread sheet cell coordinates as the user moves around.
+#
+speakCellCoordinates = True
Copied: trunk/src/orca/scripts/apps/soffice/script.py (from r3875, /trunk/src/orca/scripts/StarOffice.py)
==============================================================================
--- /trunk/src/orca/scripts/StarOffice.py (original)
+++ trunk/src/orca/scripts/apps/soffice/script.py Fri May 2 21:21:19 2008
@@ -33,758 +33,18 @@
import orca.default as default
import orca.input_event as input_event
import orca.braille as braille
-import orca.braillegenerator as braillegenerator
import orca.orca as orca
import orca.orca_state as orca_state
import orca.speech as speech
-import orca.speechgenerator as speechgenerator
import orca.settings as settings
import orca.keybindings as keybindings
-import orca.where_am_I as where_am_I
from orca.orca_i18n import _ # for gettext support
-from orca.orca_i18n import Q_ # to provide qualified translatable strings
-# Whether we speak spread sheet cell coordinates as the user moves around.
-#
-speakCellCoordinates = True
-
-class WhereAmI(where_am_I.WhereAmI):
-
- def __init__(self, script):
- """Create a new WhereAmI that will be used to speak information
- about the current object of interest.
- """
-
- where_am_I.WhereAmI.__init__(self, script)
-
- def _speakTableCell(self, obj, basicOnly):
- """Given the nature of OpenOffice Calc, Orca should override the
- default whereAmI behavior when the item with focus is a cell
- within Calc. In this instance, the following information should
- be spoken/displayed:
-
- 1. "Cell"
- 2. the cell coordinates
- 3. the cell contents:
- A. if the cell is empty, "blank"
- B. if the cell is being edited AND if some text within the cell
- is selected, the selected text followed by "selected"
- C. otherwise, the full contents of the cell
- """
-
- if not self._script.isSpreadSheetCell(obj):
- return where_am_I.WhereAmI._speakTableCell(self, obj, basicOnly)
-
- utterances = []
- utterances.append(_("cell"))
-
- table = obj.parent.queryTable()
-
- # Translators: this represents the column we're
- # on in a table.
- #
- text = _("column %d") % \
- (table.getColumnAtIndex(obj.getIndexInParent()) + 1)
- utterances.append(text)
-
- # Speak the dynamic column header (if any).
- #
- if self._script.dynamicColumnHeaders.has_key(table):
- row = self._script.dynamicColumnHeaders[table]
- header = self._script.getDynamicRowHeaderCell(obj, row)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- utterances.append(text)
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- utterances.append(text)
-
- # Translators: this represents the row number of a table.
- #
- text = _("row %d") % (table.getRowAtIndex(obj.getIndexInParent()) + 1)
- utterances.append(text)
-
- # Speak the dynamic row header (if any).
- #
- if self._script.dynamicRowHeaders.has_key(table):
- column = self._script.dynamicRowHeaders[table]
- header = self._script.getDynamicColumnHeaderCell(obj, column)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- utterances.append(text)
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- utterances.append(text)
-
- text = obj.queryText().getText(0, -1)
- utterances.append(text)
-
- debug.println(self._debugLevel, "calc table cell utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
-
- def _speakParagraph(self, obj, basicOnly):
- """OpenOffice Calc cells have the role "paragraph" when
- they are being edited.
- """
-
- top = self._script.getTopLevel(obj)
- if top and top.name.endswith(" Calc"):
- self._speakCalc(obj, basicOnly)
- elif top and top.name.endswith(" Writer"):
- self._speakText(obj, basicOnly)
-
- def _speakCalc(self, obj, basicOnly):
- """Speak a OpenOffice Calc cell.
- """
-
- utterances = []
- utterances.append(_("cell"))
-
- # No way to get cell coordinates?
-
- [textContents, startOffset, endOffset, selected] = \
- self._getTextContents(obj, basicOnly)
- text = textContents
- utterances.append(text)
- if selected:
- # Translators: when the user selects (highlights) text in
- # a document, Orca lets them know this.
- #
- # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
- #
- text = Q_("text|selected")
- utterances.append(text)
-
- debug.println(self._debugLevel, "editable table cell utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
-
- def _getCalcFrameAndSheet(self, obj):
- """Returns the Calc frame and sheet
- """
-
- mylist = [None, None]
-
- parent = obj.parent
- while parent and (parent.parent != parent):
- # debug.println(self._debugLevel,
- # "_getCalcFrameAndSheet: parent=%s, %s" % \
- # (parent.getRole(), self._getObjLabelAndName(parent)))
- if parent.getRole() == pyatspi.ROLE_FRAME:
- mylist[0] = parent
- if parent.getRole() == pyatspi.ROLE_TABLE:
- mylist[1] = parent
- parent = parent.parent
-
- return mylist
-
- def _speakCalcStatusBar(self):
- """Speaks the OpenOffice Calc statusbar.
- """
-
- if not self._statusBar:
- return
-
- utterances = []
- for child in self._statusBar:
- text = self._getObjName(child)
- utterances.append(text)
-
- debug.println(self._debugLevel, "Calc statusbar utterances=%s" % \
- utterances)
- speech.speakUtterances(utterances)
-
- def speakTitle(self, obj):
- """Speak the title bar.
-
- Calc-Specific Handling:
-
- 1. The contents of the title bar of the application main window
- 2. The title of the current worksheet
-
- Note that if the application with focus is Calc, but a cell does not
- have focus, the default behavior should be used.
- """
-
- top = self._script.getTopLevel(obj)
- if top and not top.name.endswith(" Calc"):
- return where_am_I.WhereAmI.speakTitle(self, obj)
-
- utterances = []
-
- mylist = self._getCalcFrameAndSheet(obj)
- if mylist[0]:
- text = self.getObjLabelAndName(mylist[0])
- utterances.append(text)
- if mylist[1]:
- text = self.getObjLabelAndName(mylist[1])
- utterances.append(text)
-
- debug.println(self._debugLevel,
- "Calc titlebar and sheet utterances=%s" % utterances)
- speech.speakUtterances(utterances)
-
- def speakStatusBar(self, obj):
- """Speak the status bar contents.
-
- Note that if the application with focus is Calc, but a cell does not
- have focus, the default behavior should be used.
- """
-
- top = self._script.getTopLevel(obj)
- if top and not top.name.endswith(" Calc"):
- return where_am_I.WhereAmI.speakStatusBar(self, obj)
-
- utterances = []
-
- mylist = self._getCalcFrameAndSheet(obj)
- if mylist[0]:
- self._statusBar = None
- self._getStatusBar(mylist[0])
- if self._statusBar:
- self._speakCalcStatusBar()
-
- debug.println(self._debugLevel,
- "Calc status bar utterances=%s" % utterances)
- speech.speakUtterances(utterances)
-
-class BrailleGenerator(braillegenerator.BrailleGenerator):
- """Overrides _getBrailleRegionsForTableCellRow so that , when we are
- in a spread sheet, we can braille the dynamic row and column headers
- (assuming they are set).
- Overrides _getBrailleRegionsForTableCell so that, when we are in
- a spread sheet, we can braille the location of the table cell as well
- as the contents.
- """
-
- def __init__(self, script):
- braillegenerator.BrailleGenerator.__init__(self, script)
-
- def _getBrailleRegionsForTableCellRow(self, obj):
- """Get the braille for a table cell row or a single table cell
- if settings.readTableCellRow is False.
-
- Arguments:
- - obj: the table cell
-
- 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.
- """
-
- focusRegion = None
- regions = []
-
- # Check to see if this spread sheet cell has either a dynamic
- # column heading or row heading (or both) associated with it.
- # If it does, then braille those first before brailling the
- # cell contents.
- #
- table = self._script.getTable(obj)
- parent = obj.parent
- try:
- parentTable = parent.queryTable()
- except NotImplementedError:
- parentTable = None
-
- if self._script.pointOfReference.has_key("lastColumn") and \
- self._script.pointOfReference["lastColumn"] != \
- parentTable.getColumnAtIndex(obj.getIndexInParent()):
- if self._script.dynamicColumnHeaders.has_key(table):
- row = self._script.dynamicColumnHeaders[table]
- header = self._script.getDynamicRowHeaderCell(obj, row)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- regions.append(braille.Region(" " + text + " "))
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- regions.append(braille.Region(" " + text + " "))
-
- if self._script.pointOfReference.has_key("lastRow") and \
- self._script.pointOfReference['lastRow'] != \
- parentTable.getRowAtIndex(obj.getIndexInParent()):
- if self._script.dynamicRowHeaders.has_key(table):
- column = self._script.dynamicRowHeaders[table]
- header = self._script.getDynamicColumnHeaderCell(obj, column)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- regions.append(braille.Region(" " + text + " "))
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- regions.append(braille.Region(" " + text + " "))
-
- if self._script.isSpreadSheetCell(obj):
-
- # Adding in a check here to make sure that the parent is a
- # valid table. It's possible that the parent could be a
- # table cell too (see bug #351501).
- #
- if settings.readTableCellRow and parentTable:
- rowRegions = []
- savedBrailleVerbosityLevel = settings.brailleVerbosityLevel
- settings.brailleVerbosityLevel = \
- settings.VERBOSITY_LEVEL_BRIEF
-
- parent = obj.parent
- row = parentTable.getRowAtIndex(obj.getIndexInParent())
- column = parentTable.getColumnAtIndex(obj.getIndexInParent())
-
- # 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 self._script.pointOfReference.has_key("lastRow") and \
- self._script.pointOfReference.has_key("lastColumn"):
- pointOfReference = self._script.pointOfReference
- speakAll = \
- (pointOfReference["lastRow"] != row) or \
- ((row == 0 or row == parentTable.nRows-1) and \
- pointOfReference["lastColumn"] == column)
-
- if speakAll:
- [startIndex, endIndex] = \
- self._script.getSpreadSheetRowRange(obj)
- for i in range(startIndex, endIndex+1):
- cell = parentTable.getAccessibleAt(row, i)
- showing = cell.getState().contains( \
- pyatspi.STATE_SHOWING)
- if showing:
- [cellRegions, focusRegion] = \
- self._getBrailleRegionsForTableCell(cell)
- if len(rowRegions):
- rowRegions.append(braille.Region(" "))
- rowRegions.append(cellRegions[0])
- regions.extend(rowRegions)
- settings.brailleVerbosityLevel = savedBrailleVerbosityLevel
- else:
- [cellRegions, focusRegion] = \
- self._getBrailleRegionsForTableCell(obj)
- regions.extend(cellRegions)
- else:
- [cellRegions, focusRegion] = \
- self._getBrailleRegionsForTableCell(obj)
- regions.extend(cellRegions)
- regions = [regions, focusRegion]
- else:
- [cellRegions, focusRegion] = \
- braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForTableCellRow(self, obj)
- regions.extend(cellRegions)
- regions = [regions, focusRegion]
-
- return regions
-
- def _getBrailleRegionsForTableCell(self, obj):
- """Get the braille for a table cell. If this isn't inside a
- spread sheet, just return the regions returned by the default
- table cell braille handler.
-
- Arguments:
- - obj: the table cell
-
- 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.
- """
-
- if self._script.isSpreadSheetCell(obj):
- if self._script.inputLineForCell == None:
- self._script.inputLineForCell = \
- self._script.locateInputLine(obj)
-
- regions = []
- text = self._script.getDisplayedText(obj)
- componentRegion = braille.Component(obj, text)
- regions.append(componentRegion)
-
- # If the spread sheet table cell has something in it, then we
- # want to append the name of the cell (which will be its location).
- # Note that if the cell was empty, then
- # self._script.getDisplayedText will have already done this for us.
- #
- try:
- if obj.queryText():
- objectText = self._script.getText(obj, 0, -1)
- if objectText and len(objectText) != 0:
- regions.append(braille.Region(" " + obj.name))
- except NotImplementedError:
- pass
-
- return [regions, componentRegion]
-
- else:
- # Check to see how many children this table cell has. If it's
- # just one (or none), then pass it on to the superclass to be
- # processed.
- #
- # If it's more than one, then get the braille regions for each
- # child, and call this method again.
- #
- if obj.childCount <= 1:
- regions = braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForTableCell(self, obj)
- else:
- regions = []
- for child in obj:
- [cellRegions, focusRegion] = \
- self._getBrailleRegionsForTableCell(child)
- regions.extend(cellRegions)
- return [regions, focusRegion]
-
- return regions
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Overrides _getSpeechForComboBox so that we can provide a name for
- the Calc Name combo box.
- Overrides _getSpeechForTableCellRow so that , when we are in a
- spread sheet, we can speak the dynamic row and column headers
- (assuming they are set).
- Overrides _getSpeechForTableCell so that, when we are in a spread
- sheet, we can speak the location of the table cell as well as the
- contents.
- Overrides _getSpeechForToggleButton so that, when the toggle buttons
- on the Formatting toolbar change state, we provide both the name and
- the state (as "on" or "off")
- Overrides _getSpeechForPushButton because sometimes the toggle buttons
- on the Formatting toolbar claim to be push buttons.
- """
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
-
- 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.
- Also provides a name for the OOo Calc Name combo box. This name is
- provided in clause 5) of locusOfFocusChanged() below.
-
- 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)
- if not label:
- label = [ obj.name ]
- 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))
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- self._debugGenerator("_getSpeechForComboBox",
- 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 indicates that there are zero items in
- # a layered pane or table.
- #
- utterances.append(_("0 items"))
-
- return utterances
-
- def _getSpeechForTableCellRow(self, obj, already_focused):
- """Get the speech for a table cell row or a single table cell
- if settings.readTableCellRow is False. If this isn't inside a
- spread sheet, just return the utterances returned by the default
- table cell speech handler.
-
- Arguments:
- - obj: the table cell
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- if not already_focused:
-
- # Check to see if this spread sheet cell has either a dynamic
- # column heading or row heading (or both) associated with it.
- # If it does, then speak those first before speaking the cell
- # contents.
- #
- table = self._script.getTable(obj)
- parent = obj.parent
- try:
- parentTable = parent.queryTable()
- except NotImplementedError:
- parentTable = None
-
- if self._script.pointOfReference.has_key("lastColumn") and \
- self._script.pointOfReference["lastColumn"] != \
- parentTable.getColumnAtIndex(obj.getIndexInParent()):
- if self._script.dynamicColumnHeaders.has_key(table):
- row = self._script.dynamicColumnHeaders[table]
- header = self._script.getDynamicRowHeaderCell(obj, row)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- utterances.append(text)
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- utterances.append(text)
-
- if self._script.pointOfReference.has_key("lastRow") and \
- self._script.pointOfReference["lastRow"] != \
- parentTable.getRowAtIndex(obj.getIndexInParent()):
- if self._script.dynamicRowHeaders.has_key(table):
- column = self._script.dynamicRowHeaders[table]
- header = self._script.getDynamicColumnHeaderCell(obj,
- column)
- try:
- headerText = header.queryText()
- except:
- headerText = None
-
- if header.childCount > 0:
- for child in header:
- text = self._script.getText(child, 0, -1)
- if text:
- utterances.append(text)
- elif headerText:
- text = self._script.getText(header, 0, -1)
- if text:
- utterances.append(text)
-
- if self._script.isSpreadSheetCell(obj):
- if not already_focused:
- if settings.readTableCellRow:
- parent = obj.parent
- row = parentTable.getRowAtIndex(obj.getIndexInParent())
- column = \
- parentTable.getColumnAtIndex(obj.getIndexInParent())
-
- # 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 self._script.pointOfReference.has_key("lastRow") and \
- self._script.pointOfReference.has_key("lastColumn"):
- pointOfReference = self._script.pointOfReference
- speakAll = (pointOfReference["lastRow"] != row) or \
- ((row == 0 or row == parentTable.nRows-1) and \
- pointOfReference["lastColumn"] == column)
-
- if speakAll:
- [startIndex, endIndex] = \
- self._script.getSpreadSheetRowRange(obj)
- for i in range(startIndex, endIndex+1):
- cell = parentTable.getAccessibleAt(row, i)
- showing = cell.getState().contains( \
- pyatspi.STATE_SHOWING)
- if showing:
- utterances.extend(self._getSpeechForTableCell(\
- cell, already_focused))
- else:
- utterances.extend(self._getSpeechForTableCell(obj,
- already_focused))
- else:
- utterances.extend(self._getSpeechForTableCell(obj,
- already_focused))
- else:
- utterances.extend(speechgenerator.SpeechGenerator.\
- _getSpeechForTableCellRow(self, obj, already_focused))
-
- return utterances
-
- def _getSpeechForTableCell(self, obj, already_focused):
- """Get the speech for a table cell. If this isn't inside a
- spread sheet, just return the utterances returned by the default
- table cell speech handler.
-
- Arguments:
- - obj: the table cell
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- if self._script.isSpreadSheetCell(obj):
- utterances = []
-
- if self._script.inputLineForCell == None:
- self._script.inputLineForCell = \
- self._script.locateInputLine(obj)
-
- try:
- if obj.queryText():
- objectText = self._script.getText(obj, 0, -1)
- if not speakCellCoordinates and len(objectText) == 0:
- # Translators: this indicates an empty (blank) spread
- # sheet cell.
- #
- objectText = _("blank")
-
- utterances.append(objectText)
- except NotImplementedError:
- pass
-
- if speakCellCoordinates:
- nameList = obj.name.split()
- utterances.append(nameList[1])
- else:
- # Check to see how many children this table cell has. If it's
- # just one (or none), then pass it on to the superclass to be
- # processed.
- #
- # If it's more than one, then get the speech for each child,
- # and call this method again.
- #
- if obj.childCount <= 1:
- utterances = speechgenerator.SpeechGenerator.\
- _getSpeechForTableCell(self, obj, already_focused)
- else:
- utterances = []
- for child in obj:
- utterances.extend(self._getSpeechForTableCell(child,
- already_focused))
-
- return utterances
-
- def _getSpeechForToggleButton(self, obj, already_focused):
- """Get the speech for a toggle button. We always want to speak the
- state if it's on a toolbar.
-
- Arguments:
- - obj: the toggle button
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
- if obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR:
- if obj.getState().contains(pyatspi.STATE_CHECKED):
- # Translators: this represents the state of a check box
- #
- checkedState = _("on")
- else:
- # Translators: this represents the state of a check box
- #
- checkedState = _("off")
-
- utterances.append(obj.name)
- utterances.append(checkedState)
- else:
- utterances.extend(speechgenerator.SpeechGenerator.\
- _getSpeechForToggleButton(self, obj, already_focused))
-
- return utterances
-
- def _getSpeechForPushButton(self, obj, already_focused):
- """Get the speech for a push button. We always want to speak the
- state if it's on a toolbar.
-
- 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 = []
- if obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR:
- if obj.getState().contains(pyatspi.STATE_CHECKED):
- # Translators: this represents the state of a check box
- #
- checkedState = _("on")
- else:
- # Translators: this represents the state of a check box
- #
- checkedState = _("off")
-
- utterances.append(obj.name)
- utterances.append(checkedState)
- else:
- utterances.extend(speechgenerator.SpeechGenerator.\
- _getSpeechForPushButton(self, obj, already_focused))
-
- return utterances
-
-########################################################################
-# #
-# The StarOffice script class. #
-# #
-########################################################################
+from speech_generator import SpeechGenerator
+from braille_generator import BrailleGenerator
+from where_am_i import WhereAmI
+from constants import speakCellCoordinates
class Script(default.Script):
Added: trunk/src/orca/scripts/apps/soffice/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,348 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for StarOffice and OpenOffice."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.speechgenerator as speechgenerator
+import orca.settings as settings
+
+from orca.orca_i18n import _ # for gettext support
+
+from constants import speakCellCoordinates
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Overrides _getSpeechForComboBox so that we can provide a name for
+ the Calc Name combo box.
+ Overrides _getSpeechForTableCellRow so that , when we are in a
+ spread sheet, we can speak the dynamic row and column headers
+ (assuming they are set).
+ Overrides _getSpeechForTableCell so that, when we are in a spread
+ sheet, we can speak the location of the table cell as well as the
+ contents.
+ Overrides _getSpeechForToggleButton so that, when the toggle buttons
+ on the Formatting toolbar change state, we provide both the name and
+ the state (as "on" or "off")
+ Overrides _getSpeechForPushButton because sometimes the toggle buttons
+ on the Formatting toolbar claim to be push buttons.
+ """
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+
+ 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.
+ Also provides a name for the OOo Calc Name combo box. This name is
+ provided in clause 5) of locusOfFocusChanged() below.
+
+ 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)
+ if not label:
+ label = [ obj.name ]
+ 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))
+
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+
+ self._debugGenerator("_getSpeechForComboBox",
+ 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 indicates that there are zero items in
+ # a layered pane or table.
+ #
+ utterances.append(_("0 items"))
+
+ return utterances
+
+ def _getSpeechForTableCellRow(self, obj, already_focused):
+ """Get the speech for a table cell row or a single table cell
+ if settings.readTableCellRow is False. If this isn't inside a
+ spread sheet, just return the utterances returned by the default
+ table cell speech handler.
+
+ Arguments:
+ - obj: the table cell
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ utterances = []
+
+ if not already_focused:
+
+ # Check to see if this spread sheet cell has either a dynamic
+ # column heading or row heading (or both) associated with it.
+ # If it does, then speak those first before speaking the cell
+ # contents.
+ #
+ table = self._script.getTable(obj)
+ parent = obj.parent
+ try:
+ parentTable = parent.queryTable()
+ except NotImplementedError:
+ parentTable = None
+
+ if self._script.pointOfReference.has_key("lastColumn") and \
+ self._script.pointOfReference["lastColumn"] != \
+ parentTable.getColumnAtIndex(obj.getIndexInParent()):
+ if self._script.dynamicColumnHeaders.has_key(table):
+ row = self._script.dynamicColumnHeaders[table]
+ header = self._script.getDynamicRowHeaderCell(obj, row)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ utterances.append(text)
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ utterances.append(text)
+
+ if self._script.pointOfReference.has_key("lastRow") and \
+ self._script.pointOfReference["lastRow"] != \
+ parentTable.getRowAtIndex(obj.getIndexInParent()):
+ if self._script.dynamicRowHeaders.has_key(table):
+ column = self._script.dynamicRowHeaders[table]
+ header = self._script.getDynamicColumnHeaderCell(obj,
+ column)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ utterances.append(text)
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ utterances.append(text)
+
+ if self._script.isSpreadSheetCell(obj):
+ if not already_focused:
+ if settings.readTableCellRow:
+ parent = obj.parent
+ row = parentTable.getRowAtIndex(obj.getIndexInParent())
+ column = \
+ parentTable.getColumnAtIndex(obj.getIndexInParent())
+
+ # 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 self._script.pointOfReference.has_key("lastRow") and \
+ self._script.pointOfReference.has_key("lastColumn"):
+ pointOfReference = self._script.pointOfReference
+ speakAll = (pointOfReference["lastRow"] != row) or \
+ ((row == 0 or row == parentTable.nRows-1) and \
+ pointOfReference["lastColumn"] == column)
+
+ if speakAll:
+ [startIndex, endIndex] = \
+ self._script.getSpreadSheetRowRange(obj)
+ for i in range(startIndex, endIndex+1):
+ cell = parentTable.getAccessibleAt(row, i)
+ showing = cell.getState().contains( \
+ pyatspi.STATE_SHOWING)
+ if showing:
+ utterances.extend(self._getSpeechForTableCell(\
+ cell, already_focused))
+ else:
+ utterances.extend(self._getSpeechForTableCell(obj,
+ already_focused))
+ else:
+ utterances.extend(self._getSpeechForTableCell(obj,
+ already_focused))
+ else:
+ utterances.extend(speechgenerator.SpeechGenerator.\
+ _getSpeechForTableCellRow(self, obj, already_focused))
+
+ return utterances
+
+ def _getSpeechForTableCell(self, obj, already_focused):
+ """Get the speech for a table cell. If this isn't inside a
+ spread sheet, just return the utterances returned by the default
+ table cell speech handler.
+
+ Arguments:
+ - obj: the table cell
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ if self._script.isSpreadSheetCell(obj):
+ utterances = []
+
+ if self._script.inputLineForCell == None:
+ self._script.inputLineForCell = \
+ self._script.locateInputLine(obj)
+
+ try:
+ if obj.queryText():
+ objectText = self._script.getText(obj, 0, -1)
+ if not speakCellCoordinates and len(objectText) == 0:
+ # Translators: this indicates an empty (blank) spread
+ # sheet cell.
+ #
+ objectText = _("blank")
+
+ utterances.append(objectText)
+ except NotImplementedError:
+ pass
+
+ if speakCellCoordinates:
+ nameList = obj.name.split()
+ utterances.append(nameList[1])
+ else:
+ # Check to see how many children this table cell has. If it's
+ # just one (or none), then pass it on to the superclass to be
+ # processed.
+ #
+ # If it's more than one, then get the speech for each child,
+ # and call this method again.
+ #
+ if obj.childCount <= 1:
+ utterances = speechgenerator.SpeechGenerator.\
+ _getSpeechForTableCell(self, obj, already_focused)
+ else:
+ utterances = []
+ for child in obj:
+ utterances.extend(self._getSpeechForTableCell(child,
+ already_focused))
+
+ return utterances
+
+ def _getSpeechForToggleButton(self, obj, already_focused):
+ """Get the speech for a toggle button. We always want to speak the
+ state if it's on a toolbar.
+
+ Arguments:
+ - obj: the toggle button
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ utterances = []
+ if obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR:
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ # Translators: this represents the state of a check box
+ #
+ checkedState = _("on")
+ else:
+ # Translators: this represents the state of a check box
+ #
+ checkedState = _("off")
+
+ utterances.append(obj.name)
+ utterances.append(checkedState)
+ else:
+ utterances.extend(speechgenerator.SpeechGenerator.\
+ _getSpeechForToggleButton(self, obj, already_focused))
+
+ return utterances
+
+ def _getSpeechForPushButton(self, obj, already_focused):
+ """Get the speech for a push button. We always want to speak the
+ state if it's on a toolbar.
+
+ 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 = []
+ if obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR:
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ # Translators: this represents the state of a check box
+ #
+ checkedState = _("on")
+ else:
+ # Translators: this represents the state of a check box
+ #
+ checkedState = _("off")
+
+ utterances.append(obj.name)
+ utterances.append(checkedState)
+ else:
+ utterances.extend(speechgenerator.SpeechGenerator.\
+ _getSpeechForPushButton(self, obj, already_focused))
+
+ return utterances
Added: trunk/src/orca/scripts/apps/soffice/where_am_i.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/soffice/where_am_i.py Fri May 2 21:21:19 2008
@@ -0,0 +1,252 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for StarOffice and OpenOffice."""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.debug as debug
+import orca.speech as speech
+import orca.where_am_I as where_am_I
+
+from orca.orca_i18n import _ # for gettext support
+from orca.orca_i18n import Q_ # to provide qualified translatable strings
+
+class WhereAmI(where_am_I.WhereAmI):
+
+ def __init__(self, script):
+ """Create a new WhereAmI that will be used to speak information
+ about the current object of interest.
+ """
+
+ where_am_I.WhereAmI.__init__(self, script)
+
+ def _speakTableCell(self, obj, basicOnly):
+ """Given the nature of OpenOffice Calc, Orca should override the
+ default whereAmI behavior when the item with focus is a cell
+ within Calc. In this instance, the following information should
+ be spoken/displayed:
+
+ 1. "Cell"
+ 2. the cell coordinates
+ 3. the cell contents:
+ A. if the cell is empty, "blank"
+ B. if the cell is being edited AND if some text within the cell
+ is selected, the selected text followed by "selected"
+ C. otherwise, the full contents of the cell
+ """
+
+ if not self._script.isSpreadSheetCell(obj):
+ return where_am_I.WhereAmI._speakTableCell(self, obj, basicOnly)
+
+ utterances = []
+ utterances.append(_("cell"))
+
+ table = obj.parent.queryTable()
+
+ # Translators: this represents the column we're
+ # on in a table.
+ #
+ text = _("column %d") % \
+ (table.getColumnAtIndex(obj.getIndexInParent()) + 1)
+ utterances.append(text)
+
+ # Speak the dynamic column header (if any).
+ #
+ if self._script.dynamicColumnHeaders.has_key(table):
+ row = self._script.dynamicColumnHeaders[table]
+ header = self._script.getDynamicRowHeaderCell(obj, row)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ utterances.append(text)
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ utterances.append(text)
+
+ # Translators: this represents the row number of a table.
+ #
+ text = _("row %d") % (table.getRowAtIndex(obj.getIndexInParent()) + 1)
+ utterances.append(text)
+
+ # Speak the dynamic row header (if any).
+ #
+ if self._script.dynamicRowHeaders.has_key(table):
+ column = self._script.dynamicRowHeaders[table]
+ header = self._script.getDynamicColumnHeaderCell(obj, column)
+ try:
+ headerText = header.queryText()
+ except:
+ headerText = None
+
+ if header.childCount > 0:
+ for child in header:
+ text = self._script.getText(child, 0, -1)
+ if text:
+ utterances.append(text)
+ elif headerText:
+ text = self._script.getText(header, 0, -1)
+ if text:
+ utterances.append(text)
+
+ text = obj.queryText().getText(0, -1)
+ utterances.append(text)
+
+ debug.println(self._debugLevel, "calc table cell utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
+
+ def _speakParagraph(self, obj, basicOnly):
+ """OpenOffice Calc cells have the role "paragraph" when
+ they are being edited.
+ """
+
+ top = self._script.getTopLevel(obj)
+ if top and top.name.endswith(" Calc"):
+ self._speakCalc(obj, basicOnly)
+ elif top and top.name.endswith(" Writer"):
+ self._speakText(obj, basicOnly)
+
+ def _speakCalc(self, obj, basicOnly):
+ """Speak a OpenOffice Calc cell.
+ """
+
+ utterances = []
+ utterances.append(_("cell"))
+
+ # No way to get cell coordinates?
+
+ [textContents, startOffset, endOffset, selected] = \
+ self._getTextContents(obj, basicOnly)
+ text = textContents
+ utterances.append(text)
+ if selected:
+ # Translators: when the user selects (highlights) text in
+ # a document, Orca lets them know this.
+ #
+ # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+ #
+ text = Q_("text|selected")
+ utterances.append(text)
+
+ debug.println(self._debugLevel, "editable table cell utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
+
+ def _getCalcFrameAndSheet(self, obj):
+ """Returns the Calc frame and sheet
+ """
+
+ mylist = [None, None]
+
+ parent = obj.parent
+ while parent and (parent.parent != parent):
+ # debug.println(self._debugLevel,
+ # "_getCalcFrameAndSheet: parent=%s, %s" % \
+ # (parent.getRole(), self._getObjLabelAndName(parent)))
+ if parent.getRole() == pyatspi.ROLE_FRAME:
+ mylist[0] = parent
+ if parent.getRole() == pyatspi.ROLE_TABLE:
+ mylist[1] = parent
+ parent = parent.parent
+
+ return mylist
+
+ def _speakCalcStatusBar(self):
+ """Speaks the OpenOffice Calc statusbar.
+ """
+
+ if not self._statusBar:
+ return
+
+ utterances = []
+ for child in self._statusBar:
+ text = self._getObjName(child)
+ utterances.append(text)
+
+ debug.println(self._debugLevel, "Calc statusbar utterances=%s" % \
+ utterances)
+ speech.speakUtterances(utterances)
+
+ def speakTitle(self, obj):
+ """Speak the title bar.
+
+ Calc-Specific Handling:
+
+ 1. The contents of the title bar of the application main window
+ 2. The title of the current worksheet
+
+ Note that if the application with focus is Calc, but a cell does not
+ have focus, the default behavior should be used.
+ """
+
+ top = self._script.getTopLevel(obj)
+ if top and not top.name.endswith(" Calc"):
+ return where_am_I.WhereAmI.speakTitle(self, obj)
+
+ utterances = []
+
+ mylist = self._getCalcFrameAndSheet(obj)
+ if mylist[0]:
+ text = self.getObjLabelAndName(mylist[0])
+ utterances.append(text)
+ if mylist[1]:
+ text = self.getObjLabelAndName(mylist[1])
+ utterances.append(text)
+
+ debug.println(self._debugLevel,
+ "Calc titlebar and sheet utterances=%s" % utterances)
+ speech.speakUtterances(utterances)
+
+ def speakStatusBar(self, obj):
+ """Speak the status bar contents.
+
+ Note that if the application with focus is Calc, but a cell does not
+ have focus, the default behavior should be used.
+ """
+
+ top = self._script.getTopLevel(obj)
+ if top and not top.name.endswith(" Calc"):
+ return where_am_I.WhereAmI.speakStatusBar(self, obj)
+
+ utterances = []
+
+ mylist = self._getCalcFrameAndSheet(obj)
+ if mylist[0]:
+ self._statusBar = None
+ self._getStatusBar(mylist[0])
+ if self._statusBar:
+ self._speakCalcStatusBar()
+
+ debug.println(self._debugLevel,
+ "Calc status bar utterances=%s" % utterances)
+ speech.speakUtterances(utterances)
Copied: trunk/src/orca/scripts/toolkits/GAIL.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/toolkits/GAIL.py Fri May 2 21:21:19 2008
@@ -17,7 +17,7 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for GAIL toolkit applications"""
__id__ = "$Id$"
__version__ = "$Revision$"
@@ -25,12 +25,7 @@
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
+import orca.default
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+class Script(orca.default.Script):
+ pass
Added: trunk/src/orca/scripts/toolkits/Gecko/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,13 @@
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ bookmarks.py \
+ braille_generator.py \
+ constants.py \
+ __init__.py \
+ script.py \
+ speech_generator.py \
+ where_am_i.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/toolkits/Gecko
+
Added: trunk/src/orca/scripts/toolkits/Gecko/__init__.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/__init__.py Fri May 2 21:21:19 2008
@@ -0,0 +1,4 @@
+from script import Script
+from speech_generator import SpeechGenerator
+from braille_generator import BrailleGenerator
+from constants import *
Added: trunk/src/orca/scripts/toolkits/Gecko/bookmarks.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/bookmarks.py Fri May 2 21:21:19 2008
@@ -0,0 +1,292 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Gecko toolkit.
+Please refer to the following URL for more information on the AT-SPI
+implementation in Gecko:
+http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+import urlparse
+
+import orca.speech as speech
+import orca.bookmarks as bookmarks
+
+from orca.orca_i18n import _
+
+####################################################################
+# #
+# Custom bookmarks class #
+# #
+####################################################################
+class GeckoBookmarks(bookmarks.Bookmarks):
+ def __init__(self, script):
+ bookmarks.Bookmarks.__init__(self, script)
+ self._currentbookmarkindex = {}
+
+
+ def addBookmark(self, inputEvent):
+ """ Add an in-page accessible object bookmark for this key and
+ webpage URI. """
+ # form bookmark dictionary key
+ index = (inputEvent.hw_code, self.getURIKey())
+ # convert the current object to a path and bookmark it
+ obj, characterOffset = self._script.getCaretContext()
+ path = self._objToPath()
+ self._bookmarks[index] = path, characterOffset
+ # Translators: this announces that a bookmark has been entered
+ #
+ utterances = [(_('entered bookmark'))]
+ utterances.extend(self._script.speechGenerator.getSpeech \
+ (obj, False))
+ speech.speakUtterances(utterances)
+
+ def goToBookmark(self, inputEvent, index=None):
+ """ Go to the bookmark indexed at this key and this page's URI """
+ index = index or (inputEvent.hw_code, self.getURIKey())
+
+ try:
+ path, characterOffset = self._bookmarks[index]
+ except KeyError:
+ self._script.systemBeep()
+ return
+ # convert our path to an object
+ obj = self.pathToObj(path)
+
+ if obj:
+ # restore the location
+ self._script.setCaretPosition(obj, characterOffset)
+ self._script.updateBraille(obj)
+ self._script.speakContents( \
+ self._script.getObjectContentsAtOffset(obj, characterOffset))
+ # update the currentbookmark
+ self._currentbookmarkindex[index[1]] = index[0]
+ else:
+ self._script.systemBeep()
+
+ def bookmarkCurrentWhereAmI(self, inputEvent):
+ """ Report "Where am I" information for this bookmark relative to the
+ current pointer location."""
+ index = (inputEvent.hw_code, self.getURIKey())
+ try:
+ path, characterOffset = self._bookmarks[index]
+ obj = self.pathToObj(path)
+ except KeyError:
+ self._script.systemBeep()
+ return
+
+ [cur_obj, cur_characterOffset] = self._script.getCaretContext()
+
+ # Are they the same object?
+ if self._script.isSameObject(cur_obj, obj):
+ # Translators: this announces that the current object is the same
+ # object pointed to by the bookmark.
+ #
+ speech.speak(_('bookmark is current object'))
+ return
+ # Are their parents the same?
+ elif self._script.isSameObject(cur_obj.parent, obj.parent):
+ # Translators: this announces that the current object's parent and
+ # the parent of the object pointed to by the bookmark are the same.
+ #
+ speech.speak(_('bookmark and current object have same parent'))
+ return
+
+ # Do they share a common ancestor?
+ # bookmark's ancestors
+ bookmark_ancestors = []
+ p = obj.parent
+ while p:
+ bookmark_ancestors.append(p)
+ p = p.parent
+ # look at current object's ancestors to compare to bookmark's ancestors
+ p = cur_obj.parent
+ while p:
+ if bookmark_ancestors.count(p) > 0:
+ # Translators: this announces that the bookmark and the current
+ # object share a common ancestor
+ #
+ speech.speak(_('shared ancestor %s') %p.getRole())
+ return
+ p = p.parent
+
+ # Translators: This announces that a comparison between the bookmark
+ # and the current object can not be determined.
+ #
+ speech.speak(_('comparison unknown'))
+
+ def saveBookmarks(self, inputEvent):
+ """ Save the bookmarks for this script. """
+ saved = {}
+
+ # save obj as a path instead of an accessible
+ for index, bookmark in self._bookmarks.iteritems():
+ saved[index] = bookmark[0], bookmark[1]
+
+ try:
+ self.saveBookmarksToDisk(saved)
+ # Translators: this announces that a bookmark has been saved to
+ # disk
+ #
+ speech.speak(_('bookmarks saved'))
+ except IOError:
+ # Translators: this announces that a bookmark could not be saved to
+ # disk
+ #
+ speech.speak(_('bookmarks could not be saved'))
+
+ # Notify the observers
+ for o in self._saveObservers:
+ o()
+
+ def goToNextBookmark(self, inputEvent):
+ """ Go to the next bookmark location. If no bookmark has yet to be
+ selected, the first bookmark will be used. """
+ # The convenience of using a dictionary to add/goto a bookmark is
+ # offset by the difficulty in finding the next bookmark. We will
+ # need to sort our keys to determine the next bookmark on a page by
+ # page basis.
+ bm_keys = self._bookmarks.keys()
+ current_uri = self.getURIKey()
+
+ # mine out the hardware keys for this page and sort them
+ thispage_hwkeys = []
+ for bm_key in bm_keys:
+ if bm_key[1] == current_uri:
+ thispage_hwkeys.append(bm_key[0])
+ thispage_hwkeys.sort()
+
+ # no bookmarks for this page
+ if len(thispage_hwkeys) == 0:
+ self._script.systemBeep()
+ return
+ # only 1 bookmark or we are just starting out
+ elif len(thispage_hwkeys) == 1 or \
+ not self._currentbookmarkindex.has_key(current_uri):
+ self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
+ return
+
+ # find current bookmark hw_code in our sorted list.
+ # Go to next one if possible
+ try:
+ index = thispage_hwkeys.index( \
+ self._currentbookmarkindex[current_uri])
+ self.goToBookmark(None, index=( \
+ thispage_hwkeys[index+1], current_uri))
+ except (ValueError, KeyError, IndexError):
+ self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
+
+ def goToPrevBookmark(self, inputEvent):
+ """ Go to the previous bookmark location. If no bookmark has yet to be
+ selected, the first bookmark will be used. """
+ bm_keys = self._bookmarks.keys()
+ current_uri = self.getURIKey()
+
+ # mine out the hardware keys for this page and sort them
+ thispage_hwkeys = []
+ for bm_key in bm_keys:
+ if bm_key[1] == current_uri:
+ thispage_hwkeys.append(bm_key[0])
+ thispage_hwkeys.sort()
+
+ # no bookmarks for this page
+ if len(thispage_hwkeys) == 0:
+ self._script.systemBeep()
+ return
+ # only 1 bookmark or we are just starting out
+ elif len(thispage_hwkeys) == 1 or \
+ not self._currentbookmarkindex.has_key(current_uri):
+ self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
+ return
+
+ # find current bookmark hw_code in our sorted list.
+ # Go to next one if possible
+ try:
+ index = thispage_hwkeys.index( \
+ self._currentbookmarkindex[current_uri])
+ self.goToBookmark(None,
+ index=(thispage_hwkeys[index-1], current_uri))
+ except (ValueError, KeyError, IndexError):
+ self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
+
+ def _objToPickle(self, obj=None):
+ """Given an object, return it's saving (pickleable) format. In this
+ case, the obj path is determined relative to the document frame and is
+ returned as a list. If obj is not provided, the current caret context
+ is used. """
+ return self._objToPath(start_obj=obj)
+
+ def _objToPath(self, start_obj=None):
+ """Given an object, return it's path from the root accessible. If obj
+ is not provided, the current caret context is used. """
+ if not start_obj:
+ [start_obj, characterOffset] = self._script.getCaretContext()
+
+ if start_obj is None \
+ or start_obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+ return []
+ else:
+ path = []
+ path.append(start_obj.getIndexInParent())
+ p = start_obj.parent
+ while p:
+ if p.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+ path.reverse()
+ return path
+ path.append(p.getIndexInParent())
+ p = p.parent
+
+ return []
+
+ def _pickleToObj(self, obj):
+ """Return the s with the given path (relative to the
+ document frame). """
+
+ # could test for different obj types. We'll just assume it is
+ # list that represents a path for now.
+ return self.pathToObj(obj)
+
+ def pathToObj(self, path):
+ """Return the object with the given path (relative to the
+ document frame). """
+ returnobj = self._script.getDocumentFrame()
+ for childnumber in path:
+ try:
+ returnobj = returnobj[childnumber]
+ except IndexError:
+ return None
+
+ return returnobj
+
+ def getURIKey(self):
+ """Returns the URI key for a given page as a URI stripped of
+ parameters?query#fragment as seen in urlparse."""
+ uri = self._script.getDocumentFrameURI()
+ if uri:
+ parsed_uri = urlparse.urlparse(uri)
+ return ''.join(parsed_uri[0:3])
+ else:
+ return None
Added: trunk/src/orca/scripts/toolkits/Gecko/braille_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/braille_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,521 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+
+"""Custom script for Gecko toolkit.
+Please refer to the following URL for more information on the AT-SPI
+implementation in Gecko:
+http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.braille as braille
+import orca.braillegenerator as braillegenerator
+import orca.rolenames as rolenames
+import orca.settings as settings
+
+########################################################################
+# #
+# Custom BrailleGenerator #
+# #
+########################################################################
+
+class BrailleGenerator(braillegenerator.BrailleGenerator):
+ """Provides a braille generator specific to Gecko.
+ """
+
+ def __init__(self, script):
+ braillegenerator.BrailleGenerator.__init__(self, script)
+ self.brailleGenerators[pyatspi.ROLE_AUTOCOMPLETE] = \
+ self._getBrailleRegionsForAutocomplete
+ self.brailleGenerators[pyatspi.ROLE_ENTRY] = \
+ self._getBrailleRegionsForText
+ self.brailleGenerators[pyatspi.ROLE_LINK] = \
+ self._getBrailleRegionsForLink
+
+ def _getTextForRole(self, obj, role=None):
+ if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \
+ and not obj.getRole() in [pyatspi.ROLE_SECTION,
+ pyatspi.ROLE_FORM,
+ pyatspi.ROLE_UNKNOWN]:
+ return rolenames.getBrailleForRoleName(obj, role)
+ else:
+ return None
+
+ def _getBrailleRegionsForAutocomplete(self, obj):
+ """Gets the braille for an autocomplete box. We let the
+ handlers for the children do the rest.
+
+ Arguments:
+ - obj: an Accessible
+
+ 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("Gecko._getBrailleRegionsForAutocomplete", obj)
+
+ # [[[TODO: WDW - we're doing very little here. The goal for
+ # autocomplete boxes at the moment is that their children (e.g.,
+ # a text area, a menu, etc., do all the interactive work and
+ # the autocomplete acts as more of a container.]]]
+ #
+ regions = []
+ if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+ regions.append(braille.Region(
+ rolenames.getBrailleForRoleName(obj)))
+ else:
+ regions.append(braille.Region(""))
+
+ return (regions, regions[0])
+
+ def _getBrailleRegionsForCheckBox(self, obj):
+ """Get the braille for a check box. If the check box already had
+ focus, then only the state is displayed.
+
+ Arguments:
+ - obj: the check box
+
+ 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("Gecko._getBrailleRegionsForCheckBox", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForCheckBox(self, obj)
+
+ # In document content (I'm not sure about XUL widgets yet), a
+ # checkbox is its own little beast with no text. So... if it
+ # is in document content and has a label, we're likely to be
+ # displaying that label already. If it doesn't have a label,
+ # though, we'll display its name.
+ #
+ text = ""
+ if not self._script.inDocumentContent():
+ text = self._script.appendString(
+ text, self._script.getDisplayedLabel(obj))
+ text = self._script.appendString(
+ text, self._script.getDisplayedText(obj))
+ else:
+ isLabelled = False
+ relationSet = obj.getRelationSet()
+ if relationSet:
+ for relation in relationSet:
+ if relation.getRelationType() \
+ == pyatspi.RELATION_LABELLED_BY:
+ isLabelled = True
+ break
+ if not isLabelled and obj.name and len(obj.name):
+ text = self._script.appendString(text, obj.name)
+
+ text = self._script.appendString(text, self._getTextForRole(obj))
+
+ # get the Braille indicator
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_INDETERMINATE):
+ indicatorIndex = 2
+ elif state.contains(pyatspi.STATE_CHECKED):
+ indicatorIndex = 1
+ else:
+ indicatorIndex = 0
+
+ regions = []
+
+ componentRegion = braille.Component(
+ obj, text,
+ indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
+ regions.append(componentRegion)
+
+ return [regions, componentRegion]
+
+ def _getBrailleRegionsForRadioButton(self, obj):
+ """Get the braille for a radio button. If the radio button already
+ had focus, then only the state is displayed.
+
+ Arguments:
+ - obj: the radio button
+
+ 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("Gecko._getBrailleRegionsForRadioButton", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForRadioButton(self, obj)
+
+ # In document content (I'm not sure about XUL widgets yet), a
+ # radio button is its own little beast with no text. So... if it
+ # is in document content and has a label, we're likely to be
+ # displaying that label already. If it doesn't have a label,
+ # though, we'll display its name.
+ #
+ text = ""
+ if not self._script.inDocumentContent():
+ text = self._script.appendString(
+ text, self._script.getDisplayedLabel(obj))
+ text = self._script.appendString(
+ text, self._script.getDisplayedText(obj))
+ else:
+ isLabelled = False
+ relationSet = obj.getRelationSet()
+ if relationSet:
+ for relation in relationSet:
+ if relation.getRelationType() \
+ == pyatspi.RELATION_LABELLED_BY:
+ isLabelled = True
+ break
+
+ if not isLabelled and obj.name and len(obj.name):
+ text = self._script.appendString(text, obj.name)
+
+ text = self._script.appendString(text, self._getTextForRole(obj))
+
+ indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
+
+ regions = []
+ componentRegion = braille.Component(
+ obj, text,
+ indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
+ regions.append(componentRegion)
+
+ return [regions, componentRegion]
+
+ def _getBrailleRegionsForText(self, obj):
+ """Gets text to be displayed for the entry of an autocomplete box.
+
+ Arguments:
+ - obj: an Accessible
+
+ 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("Gecko._getBrailleRegionsForText", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForText(self, obj)
+
+ parent = obj.parent
+ if parent.getRole() != pyatspi.ROLE_AUTOCOMPLETE:
+ return braillegenerator.BrailleGenerator._getBrailleRegionsForText(
+ self, obj)
+
+ regions = []
+
+ # This is the main difference between this class and the default
+ # class - we'll give this thing a name here, and we'll make it
+ # be the name of the autocomplete.
+ #
+ label = self._script.getDisplayedLabel(parent)
+ if not label or not len(label):
+ label = parent.name
+
+ textRegion = braille.Text(obj, label, " $l")
+ regions.append(textRegion)
+ return [regions, textRegion]
+
+ def _getBrailleRegionsForComboBox(self, obj):
+ """Get the braille for a combo box. If the combo box already has
+ focus, then only the selection is displayed.
+
+ Arguments:
+ - obj: the combo box
+
+ 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("Gecko._getBrailleRegionsForComboBox", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForComboBox(self, obj)
+
+ regions = []
+
+ label = self._script.getDisplayedLabel(obj)
+ if not label and not self._script.inDocumentContent():
+ label = obj.name
+
+ focusedRegionIndex = 0
+ if label and len(label):
+ regions.append(braille.Region(label + " "))
+ focusedRegionIndex = 1
+
+ # With Gecko, a combo box has a menu as a child. The text being
+ # displayed for the combo box can be obtained via the selected
+ # menu item.
+ #
+ menu = None
+ for child in obj:
+ if child.getRole() == pyatspi.ROLE_MENU:
+ menu = child
+ break
+ if menu:
+ child = None
+ try:
+ # This should work...
+ #
+ child = menu.querySelection().getSelectedChild(0)
+ except:
+ # But just in case, we'll fall back on this.
+ # [[[TODO - JD: Will we ever have a case where the first
+ # fails, but this will succeed???]]]
+ #
+ for item in menu:
+ if item.getState().contains(pyatspi.STATE_SELECTED):
+ child = item
+ break
+ if child:
+ regions.append(braille.Region(child.name))
+
+ if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+ regions.append(braille.Region(
+ " " + rolenames.getBrailleForRoleName(obj)))
+
+ # Things may not have gone as expected above, so we'll do some
+ # defensive programming to make sure we don't get an index out
+ # of bounds.
+ #
+ if focusedRegionIndex >= len(regions):
+ focusedRegionIndex = 0
+
+ # [[[TODO: WDW - perhaps if a text area was created, we should
+ # give focus to it.]]]
+ #
+ return [regions, regions[focusedRegionIndex]]
+
+ def _getBrailleRegionsForMenuItem(self, obj):
+ """Get the braille for a menu item.
+
+ Arguments:
+ - obj: the menu item
+
+ 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("Gecko._getBrailleRegionsForMenuItem", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForMenuItem(self, obj)
+
+ if not self._script.inDocumentContent():
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForMenuItem(self, obj)
+
+ regions = []
+
+ # Displaying "menu item" for a combo box can confuse users. Therefore,
+ # display the combo box role instead. Also, only do it if the menu
+ # item is not focused (if the menu item is focused, it means we're
+ # navigating in the combo box).
+ #
+ label = self._script.getDisplayedLabel(obj)
+ focusedRegionIndex = 0
+ if label and len(label):
+ regions.append(braille.Region(label + " "))
+ focusedRegionIndex = 1
+ regions.append(braille.Region(obj.name))
+
+ comboBox = \
+ self._script.getAncestor(obj,
+ [pyatspi.ROLE_COMBO_BOX],
+ [pyatspi.ROLE_DOCUMENT_FRAME])
+ if comboBox \
+ and not obj.getState().contains(pyatspi.STATE_FOCUSED) \
+ and (settings.brailleVerbosityLevel == \
+ settings.VERBOSITY_LEVEL_VERBOSE):
+ regions.append(braille.Region(
+ " " + rolenames.getBrailleForRoleName(comboBox)))
+
+ return [regions, regions[focusedRegionIndex]]
+
+ def _getBrailleRegionsForList(self, obj):
+ """Get the braille for a list in a form. If the list already has
+ focus, then only the selection is displayed.
+
+ Arguments:
+ - obj: the list
+
+ 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("Gecko._getBrailleRegionsForList", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForList(self, obj)
+
+ if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForList(self, obj)
+
+ regions = []
+ focusedRegionIndex = 0
+
+ if obj.getState().contains(pyatspi.STATE_FOCUSED):
+ label = self._script.getDisplayedLabel(obj)
+ if not label:
+ label = obj.name
+
+ if label and len(label):
+ regions.append(braille.Region(label + " "))
+ focusedRegionIndex = 1
+
+ item = None
+ selection = obj.querySelection()
+ for i in xrange(obj.childCount):
+ if selection.isChildSelected(i):
+ item = obj[i]
+ break
+ if not item:
+ item = obj[0]
+ regions.append(braille.Region(item.name + " "))
+
+ if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
+ regions.append(braille.Region(
+ rolenames.getBrailleForRoleName(obj)))
+
+ return [regions, regions[focusedRegionIndex]]
+
+ def _getBrailleRegionsForImage(self, obj):
+ """Get the braille regions for an image.
+
+ Arguments:
+ - obj: an Accessible
+
+ 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("Gecko._getBrailleRegionsForImage", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getBrailleRegionsForImage(self, obj)
+
+ regions = []
+
+ text = ""
+ text = self._script.appendString(text,
+ self._script.getDisplayedLabel(obj))
+ text = self._script.appendString(text,
+ self._script.getDisplayedText(obj))
+
+ # If there's no text for the link, expose part of the
+ # link to the user if the image is in a link.
+ #
+ link = self._script.getAncestor(obj,
+ [pyatspi.ROLE_LINK],
+ [pyatspi.ROLE_DOCUMENT_FRAME])
+ if len(text) == 0:
+ if link:
+ [linkRegions, focusedRegion] = \
+ self._getBrailleRegionsForLink(link)
+ for region in linkRegions:
+ text += region.string
+ elif link:
+ text = self._script.appendString(text, self._getTextForRole(link))
+
+ text = self._script.appendString(text,
+ self._script.getTextForValue(obj))
+ text = self._script.appendString(text, self._getTextForRole(obj))
+
+ regions = []
+ componentRegion = braille.Component(obj, text)
+ regions.append(componentRegion)
+
+ return [regions, componentRegion]
+
+ def _getBrailleRegionsForLink(self, obj):
+ """Gets text to be displayed for a link.
+
+ Arguments:
+ - obj: an Accessible
+
+ 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("Gecko._getBrailleRegionsForLink", obj)
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return braillegenerator.BrailleGenerator.\
+ _getDefaultBrailleRegions(self, obj)
+
+ regions = []
+
+ text = ""
+ text = self._script.appendString(text,
+ self._script.getDisplayedLabel(obj))
+ text = self._script.appendString(text,
+ self._script.getDisplayedText(obj))
+
+ # If there's no text for the link, expose part of the
+ # URI to the user.
+ #
+ if len(text) == 0:
+ basename = self._script.getLinkBasename(obj)
+ if basename:
+ text = basename
+
+ text = self._script.appendString(text,
+ self._script.getTextForValue(obj))
+ text = self._script.appendString(text, self._getTextForRole(obj))
+
+ regions = []
+ componentRegion = braille.Component(obj, text)
+ regions.append(componentRegion)
+
+ return [regions, componentRegion]
Added: trunk/src/orca/scripts/toolkits/Gecko/constants.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/constants.py Fri May 2 21:21:19 2008
@@ -0,0 +1,85 @@
+import pyatspi
+
+# If True, it tells us to take over caret navigation. This is something
+# that can be set in user-settings.py:
+#
+# import orca.Gecko
+# orca.Gecko.controlCaretNavigation = True
+#
+controlCaretNavigation = True
+
+# If True, it tells us to position the caret at the beginning of a
+# line when arrowing up and down. If False, we'll try to position the
+# caret directly above or below the current caret position.
+#
+arrowToLineBeginning = True
+
+# If True, it tells Orca to automatically perform a SayAll operation
+# when a page is first loaded.
+#
+sayAllOnLoad = True
+
+# Whether or not to use the structrual navigation commands (e.g. H
+# for heading, T for table, and so on).
+#
+structuralNavigationEnabled = True
+
+# Whether or not to speak the cell's coordinates when navigating
+# from cell to cell in HTML tables.
+#
+speakCellCoordinates = True
+
+# Whether or not to speak the number of cells spanned by a cell
+# that occupies more than one row or column of an HTML table.
+#
+speakCellSpan = True
+
+# Whether or not to announce the header that applies to the current
+# when navigating from cell to cell in HTML tables.
+#
+speakCellHeaders = True
+
+# Whether blank cells should be skipped when navigating in an HTML
+# table using table navigation commands
+#
+skipBlankCells = False
+
+# Whether or not Orca should speak the changing location within the
+# document frame *during* a find (i.e. while focus is still in the
+# Find toolbar).
+#
+speakResultsDuringFind = True
+
+# The minimum number of characters that must be matched during
+# a find before Orca speaks the changed location, assuming that
+# speakResultsDuringFind is True.
+#
+minimumFindLength = 4
+
+# Whether or not to continue speaking the same line if the match
+# has not changed with additional keystrokes. This setting comes
+# in handy for fast typists who might inadvertantly interrupt the
+# speaking of the line that matches by continuing to type in the
+# Find entry. This is the equivalent of what we do in autocompletes
+# throughout GNOME. For power-users of the Find toolbar, however,
+# that may be too verbose so it's configurable.
+#
+onlySpeakChangedLinesDuringFind = False
+
+# The minimum number of characters of text that an accessible object must
+# contain to be considered a match in go to next/prev large object
+largeObjectTextLength = 75
+
+# Roles that represent a logical chunk of information in a document
+#
+OBJECT_ROLES = [pyatspi.ROLE_HEADING,
+ pyatspi.ROLE_PARAGRAPH,
+ pyatspi.ROLE_TABLE,
+ pyatspi.ROLE_TABLE_CELL,
+ pyatspi.ROLE_TEXT,
+ pyatspi.ROLE_SECTION,
+ pyatspi.ROLE_DOCUMENT_FRAME,
+ pyatspi.ROLE_AUTOCOMPLETE]
+
+ARIA_LANDMARKS = ["banner", "contentinfo", "definition", "main", "navigation",
+ "note", "search", "secondary", "seealso"]
Copied: trunk/src/orca/scripts/toolkits/Gecko/script.py (from r3875, /trunk/src/orca/Gecko.py)
==============================================================================
--- /trunk/src/orca/Gecko.py (original)
+++ trunk/src/orca/scripts/toolkits/Gecko/script.py Fri May 2 21:21:19 2008
@@ -42,1799 +42,32 @@
import atk
import gtk
-import math
import pyatspi
import re
-import urlparse
-
-import braille
-import braillegenerator
-import debug
-import default
-import input_event
-import keybindings
-import liveregions
-import mag
-import orca
-import orca_state
-import rolenames
-import settings
-import speech
-import speechgenerator
-import speechserver
import time
-import where_am_I
-import bookmarks
-
-from orca_i18n import _
-from orca_i18n import ngettext # for ngettext support
-from orca_i18n import Q_ # to provide qualified translatable strings
-
-# If True, it tells us to take over caret navigation. This is something
-# that can be set in user-settings.py:
-#
-# import orca.Gecko
-# orca.Gecko.controlCaretNavigation = True
-#
-controlCaretNavigation = True
-
-# If True, it tells us to position the caret at the beginning of a
-# line when arrowing up and down. If False, we'll try to position the
-# caret directly above or below the current caret position.
-#
-arrowToLineBeginning = True
-
-# If True, it tells Orca to automatically perform a SayAll operation
-# when a page is first loaded.
-#
-sayAllOnLoad = True
-
-# Whether or not to use the structrual navigation commands (e.g. H
-# for heading, T for table, and so on).
-#
-structuralNavigationEnabled = True
-
-# Whether or not to speak the cell's coordinates when navigating
-# from cell to cell in HTML tables.
-#
-speakCellCoordinates = True
-
-# Whether or not to speak the number of cells spanned by a cell
-# that occupies more than one row or column of an HTML table.
-#
-speakCellSpan = True
-
-# Whether or not to announce the header that applies to the current
-# when navigating from cell to cell in HTML tables.
-#
-speakCellHeaders = True
-
-# Whether blank cells should be skipped when navigating in an HTML
-# table using table navigation commands
-#
-skipBlankCells = False
-
-# Whether or not Orca should speak the changing location within the
-# document frame *during* a find (i.e. while focus is still in the
-# Find toolbar).
-#
-speakResultsDuringFind = True
-
-# The minimum number of characters that must be matched during
-# a find before Orca speaks the changed location, assuming that
-# speakResultsDuringFind is True.
-#
-minimumFindLength = 4
-
-# Whether or not to continue speaking the same line if the match
-# has not changed with additional keystrokes. This setting comes
-# in handy for fast typists who might inadvertantly interrupt the
-# speaking of the line that matches by continuing to type in the
-# Find entry. This is the equivalent of what we do in autocompletes
-# throughout GNOME. For power-users of the Find toolbar, however,
-# that may be too verbose so it's configurable.
-#
-onlySpeakChangedLinesDuringFind = False
-
-# The minimum number of characters of text that an accessible object must
-# contain to be considered a match in go to next/prev large object
-largeObjectTextLength = 75
-
-# Roles that imply their text starts on a new line.
-#
-NEWLINE_ROLES = [pyatspi.ROLE_PARAGRAPH,
- pyatspi.ROLE_SEPARATOR,
- pyatspi.ROLE_LIST_ITEM,
- pyatspi.ROLE_HEADING]
-
-# Roles that represent a logical chunk of information in a document
-#
-OBJECT_ROLES = [pyatspi.ROLE_HEADING,
- pyatspi.ROLE_PARAGRAPH,
- pyatspi.ROLE_TABLE,
- pyatspi.ROLE_TABLE_CELL,
- pyatspi.ROLE_TEXT,
- pyatspi.ROLE_SECTION,
- pyatspi.ROLE_DOCUMENT_FRAME,
- pyatspi.ROLE_AUTOCOMPLETE]
-
-ARIA_LANDMARKS = ["banner", "contentinfo", "definition", "main", "navigation",
- "note", "search", "secondary", "seealso"]
-
-########################################################################
-# #
-# Custom BrailleGenerator #
-# #
-########################################################################
-
-class BrailleGenerator(braillegenerator.BrailleGenerator):
- """Provides a braille generator specific to Gecko.
- """
-
- def __init__(self, script):
- braillegenerator.BrailleGenerator.__init__(self, script)
- self.brailleGenerators[pyatspi.ROLE_AUTOCOMPLETE] = \
- self._getBrailleRegionsForAutocomplete
- self.brailleGenerators[pyatspi.ROLE_ENTRY] = \
- self._getBrailleRegionsForText
- self.brailleGenerators[pyatspi.ROLE_LINK] = \
- self._getBrailleRegionsForLink
-
- def _getTextForRole(self, obj, role=None):
- if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE \
- and not obj.getRole() in [pyatspi.ROLE_SECTION,
- pyatspi.ROLE_FORM,
- pyatspi.ROLE_UNKNOWN]:
- return rolenames.getBrailleForRoleName(obj, role)
- else:
- return None
-
- def _getBrailleRegionsForAutocomplete(self, obj):
- """Gets the braille for an autocomplete box. We let the
- handlers for the children do the rest.
-
- Arguments:
- - obj: an Accessible
-
- 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("Gecko._getBrailleRegionsForAutocomplete", obj)
-
- # [[[TODO: WDW - we're doing very little here. The goal for
- # autocomplete boxes at the moment is that their children (e.g.,
- # a text area, a menu, etc., do all the interactive work and
- # the autocomplete acts as more of a container.]]]
- #
- regions = []
- if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- regions.append(braille.Region(
- rolenames.getBrailleForRoleName(obj)))
- else:
- regions.append(braille.Region(""))
-
- return (regions, regions[0])
-
- def _getBrailleRegionsForCheckBox(self, obj):
- """Get the braille for a check box. If the check box already had
- focus, then only the state is displayed.
-
- Arguments:
- - obj: the check box
-
- 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("Gecko._getBrailleRegionsForCheckBox", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForCheckBox(self, obj)
-
- # In document content (I'm not sure about XUL widgets yet), a
- # checkbox is its own little beast with no text. So... if it
- # is in document content and has a label, we're likely to be
- # displaying that label already. If it doesn't have a label,
- # though, we'll display its name.
- #
- text = ""
- if not self._script.inDocumentContent():
- text = self._script.appendString(
- text, self._script.getDisplayedLabel(obj))
- text = self._script.appendString(
- text, self._script.getDisplayedText(obj))
- else:
- isLabelled = False
- relationSet = obj.getRelationSet()
- if relationSet:
- for relation in relationSet:
- if relation.getRelationType() \
- == pyatspi.RELATION_LABELLED_BY:
- isLabelled = True
- break
- if not isLabelled and obj.name and len(obj.name):
- text = self._script.appendString(text, obj.name)
-
- text = self._script.appendString(text, self._getTextForRole(obj))
-
- # get the Braille indicator
- state = obj.getState()
- if state.contains(pyatspi.STATE_INDETERMINATE):
- indicatorIndex = 2
- elif state.contains(pyatspi.STATE_CHECKED):
- indicatorIndex = 1
- else:
- indicatorIndex = 0
-
- regions = []
-
- componentRegion = braille.Component(
- obj, text,
- indicator=settings.brailleCheckBoxIndicators[indicatorIndex])
- regions.append(componentRegion)
-
- return [regions, componentRegion]
- def _getBrailleRegionsForRadioButton(self, obj):
- """Get the braille for a radio button. If the radio button already
- had focus, then only the state is displayed.
+import orca.braille as braille
+import orca.debug as debug
+import orca.default as default
+import orca.input_event as input_event
+import orca.keybindings as keybindings
+import orca.liveregions as liveregions
+import orca.mag as mag
+import orca.orca as orca
+import orca.orca_state as orca_state
+import orca.rolenames as rolenames
+import orca.settings as settings
+import orca.speech as speech
+import orca.speechserver as speechserver
+
+from constants import *
+from braille_generator import BrailleGenerator
+from speech_generator import SpeechGenerator
+from where_am_i import GeckoWhereAmI
+from bookmarks import GeckoBookmarks
- Arguments:
- - obj: the radio button
-
- 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("Gecko._getBrailleRegionsForRadioButton", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForRadioButton(self, obj)
-
- # In document content (I'm not sure about XUL widgets yet), a
- # radio button is its own little beast with no text. So... if it
- # is in document content and has a label, we're likely to be
- # displaying that label already. If it doesn't have a label,
- # though, we'll display its name.
- #
- text = ""
- if not self._script.inDocumentContent():
- text = self._script.appendString(
- text, self._script.getDisplayedLabel(obj))
- text = self._script.appendString(
- text, self._script.getDisplayedText(obj))
- else:
- isLabelled = False
- relationSet = obj.getRelationSet()
- if relationSet:
- for relation in relationSet:
- if relation.getRelationType() \
- == pyatspi.RELATION_LABELLED_BY:
- isLabelled = True
- break
-
- if not isLabelled and obj.name and len(obj.name):
- text = self._script.appendString(text, obj.name)
-
- text = self._script.appendString(text, self._getTextForRole(obj))
-
- indicatorIndex = int(obj.getState().contains(pyatspi.STATE_CHECKED))
-
- regions = []
- componentRegion = braille.Component(
- obj, text,
- indicator=settings.brailleRadioButtonIndicators[indicatorIndex])
- regions.append(componentRegion)
-
- return [regions, componentRegion]
-
- def _getBrailleRegionsForText(self, obj):
- """Gets text to be displayed for the entry of an autocomplete box.
-
- Arguments:
- - obj: an Accessible
-
- 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("Gecko._getBrailleRegionsForText", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForText(self, obj)
-
- parent = obj.parent
- if parent.getRole() != pyatspi.ROLE_AUTOCOMPLETE:
- return braillegenerator.BrailleGenerator._getBrailleRegionsForText(
- self, obj)
-
- regions = []
-
- # This is the main difference between this class and the default
- # class - we'll give this thing a name here, and we'll make it
- # be the name of the autocomplete.
- #
- label = self._script.getDisplayedLabel(parent)
- if not label or not len(label):
- label = parent.name
-
- textRegion = braille.Text(obj, label, " $l")
- regions.append(textRegion)
- return [regions, textRegion]
-
- def _getBrailleRegionsForComboBox(self, obj):
- """Get the braille for a combo box. If the combo box already has
- focus, then only the selection is displayed.
-
- Arguments:
- - obj: the combo box
-
- 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("Gecko._getBrailleRegionsForComboBox", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForComboBox(self, obj)
-
- regions = []
-
- label = self._script.getDisplayedLabel(obj)
- if not label and not self._script.inDocumentContent():
- label = obj.name
-
- focusedRegionIndex = 0
- if label and len(label):
- regions.append(braille.Region(label + " "))
- focusedRegionIndex = 1
-
- # With Gecko, a combo box has a menu as a child. The text being
- # displayed for the combo box can be obtained via the selected
- # menu item.
- #
- menu = None
- for child in obj:
- if child.getRole() == pyatspi.ROLE_MENU:
- menu = child
- break
- if menu:
- child = None
- try:
- # This should work...
- #
- child = menu.querySelection().getSelectedChild(0)
- except:
- # But just in case, we'll fall back on this.
- # [[[TODO - JD: Will we ever have a case where the first
- # fails, but this will succeed???]]]
- #
- for item in menu:
- if item.getState().contains(pyatspi.STATE_SELECTED):
- child = item
- break
- if child:
- regions.append(braille.Region(child.name))
-
- if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- regions.append(braille.Region(
- " " + rolenames.getBrailleForRoleName(obj)))
-
- # Things may not have gone as expected above, so we'll do some
- # defensive programming to make sure we don't get an index out
- # of bounds.
- #
- if focusedRegionIndex >= len(regions):
- focusedRegionIndex = 0
-
- # [[[TODO: WDW - perhaps if a text area was created, we should
- # give focus to it.]]]
- #
- return [regions, regions[focusedRegionIndex]]
-
- def _getBrailleRegionsForMenuItem(self, obj):
- """Get the braille for a menu item.
-
- Arguments:
- - obj: the menu item
-
- 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("Gecko._getBrailleRegionsForMenuItem", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForMenuItem(self, obj)
-
- if not self._script.inDocumentContent():
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForMenuItem(self, obj)
-
- regions = []
-
- # Displaying "menu item" for a combo box can confuse users. Therefore,
- # display the combo box role instead. Also, only do it if the menu
- # item is not focused (if the menu item is focused, it means we're
- # navigating in the combo box).
- #
- label = self._script.getDisplayedLabel(obj)
- focusedRegionIndex = 0
- if label and len(label):
- regions.append(braille.Region(label + " "))
- focusedRegionIndex = 1
- regions.append(braille.Region(obj.name))
-
- comboBox = \
- self._script.getAncestor(obj,
- [pyatspi.ROLE_COMBO_BOX],
- [pyatspi.ROLE_DOCUMENT_FRAME])
- if comboBox \
- and not obj.getState().contains(pyatspi.STATE_FOCUSED) \
- and (settings.brailleVerbosityLevel == \
- settings.VERBOSITY_LEVEL_VERBOSE):
- regions.append(braille.Region(
- " " + rolenames.getBrailleForRoleName(comboBox)))
-
- return [regions, regions[focusedRegionIndex]]
-
- def _getBrailleRegionsForList(self, obj):
- """Get the braille for a list in a form. If the list already has
- focus, then only the selection is displayed.
-
- Arguments:
- - obj: the list
-
- 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("Gecko._getBrailleRegionsForList", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForList(self, obj)
-
- if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForList(self, obj)
-
- regions = []
- focusedRegionIndex = 0
-
- if obj.getState().contains(pyatspi.STATE_FOCUSED):
- label = self._script.getDisplayedLabel(obj)
- if not label:
- label = obj.name
-
- if label and len(label):
- regions.append(braille.Region(label + " "))
- focusedRegionIndex = 1
-
- item = None
- selection = obj.querySelection()
- for i in xrange(obj.childCount):
- if selection.isChildSelected(i):
- item = obj[i]
- break
- if not item:
- item = obj[0]
- regions.append(braille.Region(item.name + " "))
-
- if settings.brailleVerbosityLevel == settings.VERBOSITY_LEVEL_VERBOSE:
- regions.append(braille.Region(
- rolenames.getBrailleForRoleName(obj)))
-
- return [regions, regions[focusedRegionIndex]]
-
- def _getBrailleRegionsForImage(self, obj):
- """Get the braille regions for an image.
-
- Arguments:
- - obj: an Accessible
-
- 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("Gecko._getBrailleRegionsForImage", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getBrailleRegionsForImage(self, obj)
-
- regions = []
-
- text = ""
- text = self._script.appendString(text,
- self._script.getDisplayedLabel(obj))
- text = self._script.appendString(text,
- self._script.getDisplayedText(obj))
-
- # If there's no text for the link, expose part of the
- # link to the user if the image is in a link.
- #
- link = self._script.getAncestor(obj,
- [pyatspi.ROLE_LINK],
- [pyatspi.ROLE_DOCUMENT_FRAME])
- if len(text) == 0:
- if link:
- [linkRegions, focusedRegion] = \
- self._getBrailleRegionsForLink(link)
- for region in linkRegions:
- text += region.string
- elif link:
- text = self._script.appendString(text, self._getTextForRole(link))
-
- text = self._script.appendString(text,
- self._script.getTextForValue(obj))
- text = self._script.appendString(text, self._getTextForRole(obj))
-
- regions = []
- componentRegion = braille.Component(obj, text)
- regions.append(componentRegion)
-
- return [regions, componentRegion]
-
- def _getBrailleRegionsForLink(self, obj):
- """Gets text to be displayed for a link.
-
- Arguments:
- - obj: an Accessible
-
- 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("Gecko._getBrailleRegionsForLink", obj)
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return braillegenerator.BrailleGenerator.\
- _getDefaultBrailleRegions(self, obj)
-
- regions = []
-
- text = ""
- text = self._script.appendString(text,
- self._script.getDisplayedLabel(obj))
- text = self._script.appendString(text,
- self._script.getDisplayedText(obj))
-
- # If there's no text for the link, expose part of the
- # URI to the user.
- #
- if len(text) == 0:
- basename = self._script.getLinkBasename(obj)
- if basename:
- text = basename
-
- text = self._script.appendString(text,
- self._script.getTextForValue(obj))
- text = self._script.appendString(text, self._getTextForRole(obj))
-
- regions = []
- componentRegion = braille.Component(obj, text)
- regions.append(componentRegion)
-
- return [regions, componentRegion]
-
-########################################################################
-# #
-# Custom SpeechGenerator #
-# #
-########################################################################
-
-class SpeechGenerator(speechgenerator.SpeechGenerator):
- """Provides a speech generator specific to Gecko.
- """
-
- def __init__(self, script):
- speechgenerator.SpeechGenerator.__init__(self, script)
- self.speechGenerators[pyatspi.ROLE_DOCUMENT_FRAME] = \
- self._getSpeechForDocumentFrame
- self.speechGenerators[pyatspi.ROLE_ENTRY] = \
- self._getSpeechForText
- self.speechGenerators[pyatspi.ROLE_LINK] = \
- self._getSpeechForLink
- self.speechGenerators[pyatspi.ROLE_LIST_ITEM] = \
- self._getSpeechForListItem
- self.speechGenerators[pyatspi.ROLE_SLIDER] = \
- self._getSpeechForSlider
-
- def getSpeechForObjectRole(self, obj, role=None):
- """Prevents some roles from being spoken."""
- if obj.getRole() in [pyatspi.ROLE_PARAGRAPH,
- pyatspi.ROLE_SECTION,
- pyatspi.ROLE_LABEL,
- pyatspi.ROLE_FORM,
- pyatspi.ROLE_LIST_ITEM,
- pyatspi.ROLE_MENU_ITEM,
- pyatspi.ROLE_UNKNOWN]:
- return []
- else:
- return [rolenames.getSpeechForRoleName(obj, role)]
-
- def _getSpeechForDocumentFrame(self, obj, already_focused):
- """Gets the speech for a document frame.
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- utterances = []
-
- name = obj.name
- if name and len(name):
- utterances.append(name)
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- self._debugGenerator("Gecko._getSpeechForDocumentFrame",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForText(self, obj, already_focused):
- """Gets the speech for an autocomplete box.
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForText(self, obj, already_focused)
-
- utterances = []
- parent = obj.parent
- if parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
- # This is the main difference between this class and the default
- # class - we'll give this thing a name here, and we'll make it
- # be the name of the autocomplete.
- #
- label = self._script.getDisplayedLabel(parent)
- if not label or not len(label):
- label = parent.name
- utterances.append(label)
- elif obj.getRole() in [pyatspi.ROLE_ENTRY,
- pyatspi.ROLE_PASSWORD_TEXT] \
- and self._script.inDocumentContent():
- # This is a form field in web content. If we don't get a label,
- # we'll try to guess what text on the page is functioning as
- # the label.
- #
- label = self._script.getDisplayedLabel(obj)
- if not label or not len(label):
- label = self._script.guessTheLabel(obj)
- if label:
- utterances.append(label)
- else:
- return speechgenerator.SpeechGenerator._getSpeechForText(
- self, obj, already_focused)
-
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
- utterances.append(text)
-
- self._debugGenerator("Gecko._getSpeechForText",
- 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.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForComboBox(self, obj, already_focused)
-
- utterances = []
-
- label = self._script.getDisplayedLabel(obj)
- if not label:
- if not self._script.inDocumentContent():
- label = obj.name
- else:
- label = self._script.guessTheLabel(obj)
-
- if not already_focused and label:
- utterances.append(label)
-
- # With Gecko, a combo box has a menu as a child. The text being
- # displayed for the combo box can be obtained via the selected
- # menu item.
- #
- menu = None
- for child in obj:
- if child.getRole() == pyatspi.ROLE_MENU:
- menu = child
- break
- if menu:
- child = None
- try:
- # This should work...
- #
- child = menu.querySelection().getSelectedChild(0)
- except:
- # But just in case, we'll fall back on this.
- # [[[TODO - JD: Will we ever have a case where the first
- # fails, but this will succeed???]]]
- #
- for item in menu:
- if item.getState().contains(pyatspi.STATE_SELECTED):
- child = item
- break
- if child:
- utterances.append(child.name)
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- if not already_focused:
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- self._debugGenerator("Gecko._getSpeechForComboBox",
- 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.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForMenuItem(self, obj, already_focused)
-
- if not self._script.inDocumentContent():
- return speechgenerator.SpeechGenerator.\
- _getSpeechForMenuItem(self, obj, already_focused)
-
- utterances = self._getSpeechForObjectName(obj)
-
- # Saying "menu item" for a combo box can confuse users. Therefore,
- # speak the combo box role instead. Also, only do it if the menu
- # item is not focused (if the menu item is focused, it means we're
- # navigating in the combo box)
- #
- if not obj.getState().contains(pyatspi.STATE_FOCUSED):
- comboBox = \
- self._script.getAncestor(obj,
- [pyatspi.ROLE_COMBO_BOX],
- [pyatspi.ROLE_DOCUMENT_FRAME])
- if comboBox:
- utterances.extend(self.getSpeechForObjectRole(comboBox))
-
- self._debugGenerator("Gecko._getSpeechForMenuItem",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForListItem(self, obj, already_focused):
- """Get the speech for a list item.
-
- Arguments:
- - obj: the list item
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
-
- if self._script.isAriaWidget(obj) \
- or not self._script.inDocumentContent(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForListItem(self, obj, already_focused)
-
- if not obj.getState().contains(pyatspi.STATE_SELECTABLE):
- return speechgenerator.SpeechGenerator.\
- _getDefaultSpeech(self, obj, already_focused)
-
- utterances = self._getSpeechForObjectName(obj)
-
- self._debugGenerator("Gecko._getSpeechForListItem",
- obj,
- already_focused,
- utterances)
-
- 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.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForList(self, obj, already_focused)
-
- if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForList(self, obj, already_focused)
-
- utterances = []
-
- if obj.getState().contains(pyatspi.STATE_FOCUSED):
- label = self._script.getDisplayedLabel(obj)
- if not label:
- if not self._script.inDocumentContent():
- label = obj.name
- else:
- label = self._script.guessTheLabel(obj)
-
- if not already_focused and label:
- utterances.append(label)
-
- item = None
- selection = obj.querySelection()
- for i in xrange(obj.childCount):
- if selection.isChildSelected(i):
- item = obj[i]
- break
- item = item or obj[0]
- if item:
- name = self._getSpeechForObjectName(item)
- if name != label:
- utterances.extend(name)
-
- if not already_focused:
- if obj.getState().contains(pyatspi.STATE_MULTISELECTABLE):
- # Translators: "multi-select" refers to a web form list
- # in which more than one item can be selected at a time.
- #
- utterances.append(_("multi-select"))
-
- # Translators: this represents a list in HTML.
- #
- itemString = ngettext("List with %d item",
- "List with %d items",
- obj.childCount) % obj.childCount
- utterances.append(itemString)
-
- self._debugGenerator("Gecko._getSpeechForList",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForImage(self, obj, already_focused):
- """Gets a list of utterances to be spoken for an image.
-
- The default speech will be of the following form:
-
- label name role availability
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForImage(self, obj, already_focused)
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
- if name != label:
- utterances.extend(name)
-
- # If there's no text for the image, expose the link to
- # the user if the image is in a link.
- #
- link = self._script.getAncestor(obj,
- [pyatspi.ROLE_LINK],
- [pyatspi.ROLE_DOCUMENT_FRAME])
- if not len(utterances):
- if link:
- utterances.extend(self._getSpeechForLink(link,
- already_focused))
- elif link:
- utterances.extend(self.getSpeechForObjectRole(link))
-
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- self._debugGenerator("Gecko._getSpeechForImage",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def _getSpeechForLink(self, obj, already_focused):
- """Gets a list of utterances to be spoken for a link.
-
- Arguments:
- - obj: an Accessible
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.getSpeech(obj,
- already_focused)
-
- utterances = []
-
- if not already_focused:
- label = self._getSpeechForObjectLabel(obj)
- utterances.extend(label)
- name = self._getSpeechForObjectName(obj)
-
- # Handle empty alt tags.
- #
- if name:
- lengthOfName = len(name[0].strip())
- if (lengthOfName > 0) and (name != label):
- utterances.extend(name)
-
- # If there's no text for the link, expose part of the
- # URI to the user.
- #
- if not len(utterances):
- basename = self._script.getLinkBasename(obj)
- if basename:
- utterances.append(basename)
-
- utterances.extend(self.getSpeechForObjectRole(obj))
-
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- self._debugGenerator("Gecko._getSpeechForLink",
- 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.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForTable(self, obj, already_focused)
-
- # [[[TODO: JD - We should decide if we want to provide
- # information about the table dimensions, whether or not
- # this is a layout table versus a data table, etc. For now,
- # however, if it's in HTML content let's ignore it so that
- # SayAll by sentence works. :-) ]]]
- #
- utterances = []
-
- if not self._script.inDocumentContent():
- return speechgenerator.SpeechGenerator.\
- _getSpeechForTable(self, obj, already_focused)
-
- 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 radio button
- - already_focused: False if object just received focus
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForRadioButton(self, obj, already_focused)
-
- if not self._script.inDocumentContent():
- return speechgenerator.SpeechGenerator.\
- _getSpeechForRadioButton(self, obj, already_focused)
-
- utterances = []
- if obj.getState().contains(pyatspi.STATE_CHECKED):
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
- #
- selectionState = Q_("radiobutton|selected")
- else:
- # Translators: this is in reference to a radio button being
- # selected or not.
- #
- # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
- #
- selectionState = Q_("radiobutton|not selected")
-
- if not already_focused:
- # The label is handled as a context in default.py -- assuming we
- # don't have to guess it. If we need to guess it, we need to
- # add it to utterances.
- #
- label = self._script.getDisplayedLabel(obj)
- if not label:
- label = self._script.guessTheLabel(obj)
- if label:
- utterances.append(label)
-
- utterances.append(selectionState)
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- else:
- utterances.append(selectionState)
-
- self._debugGenerator("Gecko._getSpeechForRadioButton",
- 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.
- """
-
- # Treat ARIA widgets like default.py widgets
- #
- if self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForCheckBox(self, obj, already_focused)
-
- if not self._script.inDocumentContent():
- return speechgenerator.SpeechGenerator.\
- _getSpeechForCheckBox(self, obj, already_focused)
-
- utterances = []
- state = obj.getState()
- if state.contains(pyatspi.STATE_INDETERMINATE):
- # Translators: this represents the state of a checkbox.
- #
- checkedState = _("partially checked")
- elif state.contains(pyatspi.STATE_CHECKED):
- # Translators: this represents the state of a checkbox.
- #
- checkedState = _("checked")
- else:
- # Translators: this represents the state of a checkbox.
- #
- checkedState = _("not checked")
-
- # If it's not already focused, say its label.
- #
- if not already_focused:
- label = self._script.getDisplayedLabel(obj)
- if not label:
- label = self._script.guessTheLabel(obj)
- if label:
- utterances.append(label)
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(checkedState)
- utterances.extend(self._getSpeechForObjectAvailability(obj))
- else:
- utterances.append(checkedState)
-
- self._debugGenerator("Gecko._getSpeechForCheckBox",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
- def getSpeechContext(self, obj, stopAncestor=None):
- """Get the speech 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 ancestor to stop at and not include (None
- means include all ancestors)
-
- Returns a list of utterances to be spoken.
- """
-
- utterances = []
-
- if obj is stopAncestor:
- return utterances
-
- # Skip items of unknown rolenames, menu bars, labels with
- # children, and autocompletes. (With autocompletes, we
- # wind up speaking the text object)
- #
- skipRoles = [pyatspi.ROLE_UNKNOWN,
- pyatspi.ROLE_MENU_BAR,
- pyatspi.ROLE_LABEL,
- pyatspi.ROLE_AUTOCOMPLETE]
-
- # Stop if we get to a document frame or an internal frame.
- #
- stopRoles = [pyatspi.ROLE_DOCUMENT_FRAME,
- pyatspi.ROLE_INTERNAL_FRAME]
-
- # There are some objects we want to include in the context,
- # but not add their rolenames.
- #
- dontSpeakRoles = [pyatspi.ROLE_TABLE_CELL,
- pyatspi.ROLE_FILLER]
-
- parent = obj.parent
- while parent and (parent.parent != parent):
- role = parent.getRole()
- if self._script.isSameObject(parent, stopAncestor) \
- or role in stopRoles:
- break
-
- if role in skipRoles or self._script.isLayoutOnly(parent):
- parent = parent.parent
- continue
-
- # If the parent is a menu and its parent is a combo box
- # we'll speak the object as a combo box.
- #
- if role == pyatspi.ROLE_MENU \
- and parent.parent.getRole() == pyatspi.ROLE_COMBO_BOX:
- parent = parent.parent
- continue
-
- # Also skip the parent if its accessible text is a single
- # EMBEDDED_OBJECT_CHARACTER: Script.getDisplayedText will
- # end up coming back to the child of an object for the text
- # if an object's text contains a single EOC.
- #
- parentText = self._script.queryNonEmptyText(parent)
- if parentText:
- unicodeText = parentText.getText(0, -1).decode("UTF-8")
- if unicodeText == self._script.EMBEDDED_OBJECT_CHARACTER:
- parent = parent.parent
- continue
-
- # Put in the text and label (if they exist).
- #
- text = self._script.getDisplayedText(parent)
- label = self._script.getDisplayedLabel(parent)
- newUtterances = []
- if text and (text != label) and len(text.strip()) \
- and (not text.startswith("chrome://")):
- newUtterances.append(text)
- if label and len(label.strip()):
- newUtterances.append(label)
-
- # Finally add the role if it's not among the roles we don't
- # wish to speak.
- #
- if not role in dontSpeakRoles and len(newUtterances):
- utterances.append(rolenames.getSpeechForRoleName(parent))
-
- utterances.extend(newUtterances)
-
- parent = parent.parent
-
- utterances.reverse()
-
- 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
-
- Returns a list of utterances to be spoken for the object.
- """
-
- # Let default handle non-ARIA widgets (XUL?)
- if not self._script.isAriaWidget(obj):
- return speechgenerator.SpeechGenerator.\
- _getSpeechForSlider(self, obj, already_focused)
-
- value = obj.queryValue()
-
- # OK, this craziness is all about trying to figure out the most
- # meaningful formatting string for the floating point values.
- # The number of places to the right of the decimal point should
- # be set by the minimumIncrement, but the minimumIncrement isn't
- # always set. So...we'll default the minimumIncrement to 1/100
- # of the range. But, if max == min, then we'll just go for showing
- # them off to two meaningful digits.
- #
- try:
- minimumIncrement = value.minimumIncrement
- except:
- minimumIncrement = 0.0
-
- if minimumIncrement == 0.0:
- minimumIncrement = (value.maximumValue - value.minimumValue) \
- / 100.0
-
- try:
- decimalPlaces = max(0, -math.log10(minimumIncrement))
- except:
- try:
- decimalPlaces = max(0, -math.log10(value.minimumValue))
- except:
- try:
- decimalPlaces = max(0, -math.log10(value.maximumValue))
- except:
- decimalPlaces = 0
-
- formatter = "%%.%df" % decimalPlaces
- valueString = formatter % value.currentValue
- #minString = formatter % value.minimumValue
- #maxString = formatter % value.maximumValue
-
- if already_focused:
- utterances = [valueString]
- else:
- utterances = []
- utterances.extend(self._getSpeechForObjectLabel(obj))
- utterances.extend(self.getSpeechForObjectRole(obj))
- utterances.append(valueString)
- utterances.extend(self._getSpeechForObjectAvailability(obj))
-
- self._debugGenerator("_getSpeechForSlider",
- obj,
- already_focused,
- utterances)
-
- return utterances
-
-########################################################################
-# #
-# Custom WhereAmI #
-# #
-########################################################################
-
-class GeckoWhereAmI(where_am_I.WhereAmI):
- def __init__(self, script):
- """Gecko specific WhereAmI that will be used to speak information
- about the current object of interest and will provide additional Gecko
- specific information.
- """
- where_am_I.WhereAmI.__init__(self, script)
- self._script = script
-
- def whereAmI(self, obj, basicOnly):
- """Calls the base class method for basic information and Gecko
- specific presentation methods for detailed/custom information.
- """
- if basicOnly or not self._script.inDocumentContent(obj):
- where_am_I.WhereAmI.whereAmI(self, obj, basicOnly)
- self._script.liveMngr.outputLiveRegionDescription(obj)
- else:
- if settings.useCollection:
- try:
- self._collectionPageSummary()
- except:
- debug.printException(debug.LEVEL_SEVERE)
- self._iterativePageSummary(obj)
- else:
- self._iterativePageSummary(obj)
-
- def _speakText(self, obj, basicOnly):
- """Speaks the line if the current line contains embedded object
- characters; otherwise calls the parent class.
- """
-
- line = self._script.currentLineContents
- if not self._script.inDocumentContent(obj) \
- or not line or len(line) == 1:
- return where_am_I.WhereAmI._speakText(self, obj, basicOnly)
-
- cell = self._script.getAncestor(obj,
- [pyatspi.ROLE_TABLE_CELL],
- [pyatspi.ROLE_DOCUMENT_FRAME])
- if cell:
- return self._speakTableCell(cell, basicOnly)
-
- utterances = []
- text = self._getObjLabel(obj)
- utterances.append(text)
-
- if obj.getRole() == pyatspi.ROLE_LINK:
- text = rolenames.getSpeechForRoleName(obj.parent)
- else:
- text = rolenames.getSpeechForRoleName(obj)
-
- utterances.append(text)
-
- speech.speakUtterances(utterances)
- self._script.speakContents(line)
-
- def _speakDefaultButton(self, obj):
- """Speaks the default button in a dialog.
-
- Arguments:
- - obj: the dialog box for which the default button should be obtained
- """
-
- if not (self._script.inDocumentContent(orca_state.locusOfFocus) \
- and not self._script.isAriaWidget(orca_state.locusOfFocus)):
- where_am_I.WhereAmI._speakDefaultButton(self, obj)
-
- def _collectionPageSummary(self):
- """Uses the Collection interface to get the quantity of headings,
- forms, tables, visited and unvisited links.
- """
- docframe = self._script.getDocumentFrame()
- col = docframe.queryCollection()
- # We will initialize these after the queryCollection() call in case
- # Collection is not supported
- headings = 0
- forms = 0
- tables = 0
- vlinks = 0
- uvlinks = 0
-
- stateset = pyatspi.StateSet()
- roles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK, pyatspi.ROLE_TABLE,
- pyatspi.ROLE_FORM]
- rule = col.createMatchRule(stateset.raw(), col.MATCH_NONE,
- "", col.MATCH_NONE,
- roles, col.MATCH_ANY,
- "", col.MATCH_NONE,
- False)
-
- matches = col.getMatches(rule, col.SORT_ORDER_CANONICAL, 0, True)
-
- col.freeMatchRule(rule)
- for obj in matches:
- role = obj.getRole()
- if role == pyatspi.ROLE_HEADING:
- headings += 1
- elif role == pyatspi.ROLE_FORM:
- forms += 1
- elif role == pyatspi.ROLE_TABLE \
- and not self._script.isLayoutOnly(obj):
- tables += 1
- elif role == pyatspi.ROLE_LINK:
- if obj.getState().contains(pyatspi.STATE_VISITED):
- vlinks += 1
- else:
- uvlinks += 1
-
- self._outputPageSummary(headings, forms, tables, vlinks, uvlinks, None)
-
- def _iterativePageSummary(self, obj):
- """Reads the quantity of headings, forms, tables, visited and
- unvisited links.
- """
- headings = 0
- forms = 0
- tables = 0
- vlinks = 0
- uvlinks = 0
- nodetotal = 0
- obj_index = None
- currentobj = obj
-
- # start at the first object after document frame
- obj = self._script.getDocumentFrame()[0]
- while obj:
- nodetotal += 1
- if obj == currentobj:
- obj_index = nodetotal
- role = obj.getRole()
- if role == pyatspi.ROLE_HEADING:
- headings += 1
- elif role == pyatspi.ROLE_FORM:
- forms += 1
- elif role == pyatspi.ROLE_TABLE \
- and not self._script.isLayoutOnly(obj):
- tables += 1
- elif role == pyatspi.ROLE_LINK:
- if obj.getState().contains(pyatspi.STATE_VISITED):
- vlinks += 1
- else:
- uvlinks += 1
-
- obj = self._script.findNextObject(obj)
-
- # Calculate the percentage of the document that has been read.
- if obj_index:
- percentread = int(obj_index*100/nodetotal)
- else:
- percentread = None
-
- self._outputPageSummary(headings, forms, tables,
- vlinks, uvlinks, percentread)
-
- def _outputPageSummary(self, headings, forms, tables,
- vlinks, uvlinks, percent):
-
- utterances = []
- if headings:
- # Translators: Announces the number of headings in the
- # web page that is currently being displayed.
- #
- utterances.append(ngettext \
- ('%d heading', '%d headings', headings) %headings)
- if forms:
- # Translators: Announces the number of forms in the
- # web page that is currently being displayed.
- #
- utterances.append(ngettext \
- ('%d form', '%d forms', forms) %forms)
- if tables:
- # Translators: Announces the number of non-layout tables in the
- # web page that is currently being displayed.
- #
- utterances.append(ngettext \
- ('%d table', '%d tables', tables) %tables)
- if vlinks:
- # Translators: Announces the number of visited links in the
- # web page that is currently being displayed.
- #
- utterances.append(ngettext \
- ('%d visited link', '%d visited links', vlinks) %vlinks)
- if uvlinks:
- # Translators: Announces the number of unvisited links in the
- # web page that is currently being displayed.
- #
- utterances.append(ngettext \
- ('%d unvisited link', '%d unvisited links', uvlinks) %uvlinks)
- if percent is not None:
- # Translators: Announces the percentage of the document that has
- # been read. This is calculated by knowing the index of the
- # current position divided by the total number of objects on the
- # page.
- #
- utterances.append(_('%d percent of document read') %percent)
-
- speech.speakUtterances(utterances)
-
-
-####################################################################
-# #
-# Custom bookmarks class #
-# #
-####################################################################
-class GeckoBookmarks(bookmarks.Bookmarks):
- def __init__(self, script):
- bookmarks.Bookmarks.__init__(self, script)
- self._currentbookmarkindex = {}
-
-
- def addBookmark(self, inputEvent):
- """ Add an in-page accessible object bookmark for this key and
- webpage URI. """
- # form bookmark dictionary key
- index = (inputEvent.hw_code, self.getURIKey())
- # convert the current object to a path and bookmark it
- obj, characterOffset = self._script.getCaretContext()
- path = self._objToPath()
- self._bookmarks[index] = path, characterOffset
- # Translators: this announces that a bookmark has been entered
- #
- utterances = [(_('entered bookmark'))]
- utterances.extend(self._script.speechGenerator.getSpeech \
- (obj, False))
- speech.speakUtterances(utterances)
-
- def goToBookmark(self, inputEvent, index=None):
- """ Go to the bookmark indexed at this key and this page's URI """
- index = index or (inputEvent.hw_code, self.getURIKey())
-
- try:
- path, characterOffset = self._bookmarks[index]
- except KeyError:
- self._script.systemBeep()
- return
- # convert our path to an object
- obj = self.pathToObj(path)
-
- if obj:
- # restore the location
- self._script.setCaretPosition(obj, characterOffset)
- self._script.updateBraille(obj)
- self._script.speakContents( \
- self._script.getObjectContentsAtOffset(obj, characterOffset))
- # update the currentbookmark
- self._currentbookmarkindex[index[1]] = index[0]
- else:
- self._script.systemBeep()
-
- def bookmarkCurrentWhereAmI(self, inputEvent):
- """ Report "Where am I" information for this bookmark relative to the
- current pointer location."""
- index = (inputEvent.hw_code, self.getURIKey())
- try:
- path, characterOffset = self._bookmarks[index]
- obj = self.pathToObj(path)
- except KeyError:
- self._script.systemBeep()
- return
-
- [cur_obj, cur_characterOffset] = self._script.getCaretContext()
-
- # Are they the same object?
- if self._script.isSameObject(cur_obj, obj):
- # Translators: this announces that the current object is the same
- # object pointed to by the bookmark.
- #
- speech.speak(_('bookmark is current object'))
- return
- # Are their parents the same?
- elif self._script.isSameObject(cur_obj.parent, obj.parent):
- # Translators: this announces that the current object's parent and
- # the parent of the object pointed to by the bookmark are the same.
- #
- speech.speak(_('bookmark and current object have same parent'))
- return
-
- # Do they share a common ancestor?
- # bookmark's ancestors
- bookmark_ancestors = []
- p = obj.parent
- while p:
- bookmark_ancestors.append(p)
- p = p.parent
- # look at current object's ancestors to compare to bookmark's ancestors
- p = cur_obj.parent
- while p:
- if bookmark_ancestors.count(p) > 0:
- # Translators: this announces that the bookmark and the current
- # object share a common ancestor
- #
- speech.speak(_('shared ancestor %s') %p.getRole())
- return
- p = p.parent
-
- # Translators: This announces that a comparison between the bookmark
- # and the current object can not be determined.
- #
- speech.speak(_('comparison unknown'))
-
- def saveBookmarks(self, inputEvent):
- """ Save the bookmarks for this script. """
- saved = {}
-
- # save obj as a path instead of an accessible
- for index, bookmark in self._bookmarks.iteritems():
- saved[index] = bookmark[0], bookmark[1]
-
- try:
- self.saveBookmarksToDisk(saved)
- # Translators: this announces that a bookmark has been saved to
- # disk
- #
- speech.speak(_('bookmarks saved'))
- except IOError:
- # Translators: this announces that a bookmark could not be saved to
- # disk
- #
- speech.speak(_('bookmarks could not be saved'))
-
- # Notify the observers
- for o in self._saveObservers:
- o()
-
- def goToNextBookmark(self, inputEvent):
- """ Go to the next bookmark location. If no bookmark has yet to be
- selected, the first bookmark will be used. """
- # The convenience of using a dictionary to add/goto a bookmark is
- # offset by the difficulty in finding the next bookmark. We will
- # need to sort our keys to determine the next bookmark on a page by
- # page basis.
- bm_keys = self._bookmarks.keys()
- current_uri = self.getURIKey()
-
- # mine out the hardware keys for this page and sort them
- thispage_hwkeys = []
- for bm_key in bm_keys:
- if bm_key[1] == current_uri:
- thispage_hwkeys.append(bm_key[0])
- thispage_hwkeys.sort()
-
- # no bookmarks for this page
- if len(thispage_hwkeys) == 0:
- self._script.systemBeep()
- return
- # only 1 bookmark or we are just starting out
- elif len(thispage_hwkeys) == 1 or \
- not self._currentbookmarkindex.has_key(current_uri):
- self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
- return
-
- # find current bookmark hw_code in our sorted list.
- # Go to next one if possible
- try:
- index = thispage_hwkeys.index( \
- self._currentbookmarkindex[current_uri])
- self.goToBookmark(None, index=( \
- thispage_hwkeys[index+1], current_uri))
- except (ValueError, KeyError, IndexError):
- self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
-
- def goToPrevBookmark(self, inputEvent):
- """ Go to the previous bookmark location. If no bookmark has yet to be
- selected, the first bookmark will be used. """
- bm_keys = self._bookmarks.keys()
- current_uri = self.getURIKey()
-
- # mine out the hardware keys for this page and sort them
- thispage_hwkeys = []
- for bm_key in bm_keys:
- if bm_key[1] == current_uri:
- thispage_hwkeys.append(bm_key[0])
- thispage_hwkeys.sort()
-
- # no bookmarks for this page
- if len(thispage_hwkeys) == 0:
- self._script.systemBeep()
- return
- # only 1 bookmark or we are just starting out
- elif len(thispage_hwkeys) == 1 or \
- not self._currentbookmarkindex.has_key(current_uri):
- self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
- return
-
- # find current bookmark hw_code in our sorted list.
- # Go to next one if possible
- try:
- index = thispage_hwkeys.index( \
- self._currentbookmarkindex[current_uri])
- self.goToBookmark(None,
- index=(thispage_hwkeys[index-1], current_uri))
- except (ValueError, KeyError, IndexError):
- self.goToBookmark(None, index=(thispage_hwkeys[0], current_uri))
-
- def _objToPickle(self, obj=None):
- """Given an object, return it's saving (pickleable) format. In this
- case, the obj path is determined relative to the document frame and is
- returned as a list. If obj is not provided, the current caret context
- is used. """
- return self._objToPath(start_obj=obj)
-
- def _objToPath(self, start_obj=None):
- """Given an object, return it's path from the root accessible. If obj
- is not provided, the current caret context is used. """
- if not start_obj:
- [start_obj, characterOffset] = self._script.getCaretContext()
-
- if start_obj is None \
- or start_obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
- return []
- else:
- path = []
- path.append(start_obj.getIndexInParent())
- p = start_obj.parent
- while p:
- if p.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
- path.reverse()
- return path
- path.append(p.getIndexInParent())
- p = p.parent
-
- return []
-
- def _pickleToObj(self, obj):
- """Return the s with the given path (relative to the
- document frame). """
-
- # could test for different obj types. We'll just assume it is
- # list that represents a path for now.
- return self.pathToObj(obj)
-
- def pathToObj(self, path):
- """Return the object with the given path (relative to the
- document frame). """
- returnobj = self._script.getDocumentFrame()
- for childnumber in path:
- try:
- returnobj = returnobj[childnumber]
- except IndexError:
- return None
-
- return returnobj
-
- def getURIKey(self):
- """Returns the URI key for a given page as a URI stripped of
- parameters?query#fragment as seen in urlparse."""
- uri = self._script.getDocumentFrameURI()
- if uri:
- parsed_uri = urlparse.urlparse(uri)
- return ''.join(parsed_uri[0:3])
- else:
- return None
-
+from orca.orca_i18n import _
+from orca.orca_i18n import ngettext # for ngettext support
########################################################################
# #
@@ -7610,8 +5843,8 @@
self._updateLineCache(obj, characterOffset)
def getTextLineAtCaret(self, obj):
- """Gets the line of text where the caret is. This is an override to accomodate
- the intricities of our caret navigation management.
+ """Gets the line of text where the caret is. This is an override to
+ accomodate the intricities of our caret navigation management.
Argument:
- obj: an Accessible object that implements the AccessibleText
@@ -7623,7 +5856,8 @@
contextObj, contextCaret = self.getCaretContext()
- string, caretOffset, startOffset = default.Script.getTextLineAtCaret(self, obj)
+ string, caretOffset, startOffset = \
+ default.Script.getTextLineAtCaret(self, obj)
if contextObj == obj:
if not obj.getState().contains(pyatspi.STATE_EDITABLE):
@@ -8704,7 +6938,7 @@
self.setCaretPosition(obj, characterOffset)
self.updateBraille(obj)
contents = self.getObjectContentsAtOffset(obj, characterOffset)
- self.speakContents(contents)
+ self.speakContents(contents)
else:
# Translators: this is in reference to navigating HTML content
# by heading (e.g., <h1>).
Added: trunk/src/orca/scripts/toolkits/Gecko/speech_generator.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/speech_generator.py Fri May 2 21:21:19 2008
@@ -0,0 +1,794 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Gecko toolkit.
+Please refer to the following URL for more information on the AT-SPI
+implementation in Gecko:
+http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import math
+import pyatspi
+
+import orca.rolenames as rolenames
+import orca.speechgenerator as speechgenerator
+
+from orca.orca_i18n import _
+from orca.orca_i18n import ngettext # for ngettext support
+from orca.orca_i18n import Q_ # to provide qualified translatable strings
+
+########################################################################
+# #
+# Custom SpeechGenerator #
+# #
+########################################################################
+
+class SpeechGenerator(speechgenerator.SpeechGenerator):
+ """Provides a speech generator specific to Gecko.
+ """
+
+ def __init__(self, script):
+ speechgenerator.SpeechGenerator.__init__(self, script)
+ self.speechGenerators[pyatspi.ROLE_DOCUMENT_FRAME] = \
+ self._getSpeechForDocumentFrame
+ self.speechGenerators[pyatspi.ROLE_ENTRY] = \
+ self._getSpeechForText
+ self.speechGenerators[pyatspi.ROLE_LINK] = \
+ self._getSpeechForLink
+ self.speechGenerators[pyatspi.ROLE_LIST_ITEM] = \
+ self._getSpeechForListItem
+ self.speechGenerators[pyatspi.ROLE_SLIDER] = \
+ self._getSpeechForSlider
+
+ def getSpeechForObjectRole(self, obj, role=None):
+ """Prevents some roles from being spoken."""
+ if obj.getRole() in [pyatspi.ROLE_PARAGRAPH,
+ pyatspi.ROLE_SECTION,
+ pyatspi.ROLE_LABEL,
+ pyatspi.ROLE_FORM,
+ pyatspi.ROLE_LIST_ITEM,
+ pyatspi.ROLE_MENU_ITEM,
+ pyatspi.ROLE_UNKNOWN]:
+ return []
+ else:
+ return [rolenames.getSpeechForRoleName(obj, role)]
+
+ def _getSpeechForDocumentFrame(self, obj, already_focused):
+ """Gets the speech for a document frame.
+
+ Arguments:
+ - obj: an Accessible
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ utterances = []
+
+ name = obj.name
+ if name and len(name):
+ utterances.append(name)
+ utterances.extend(self.getSpeechForObjectRole(obj))
+
+ self._debugGenerator("Gecko._getSpeechForDocumentFrame",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def _getSpeechForText(self, obj, already_focused):
+ """Gets the speech for an autocomplete box.
+
+ Arguments:
+ - obj: an Accessible
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForText(self, obj, already_focused)
+
+ utterances = []
+ parent = obj.parent
+ if parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE:
+ # This is the main difference between this class and the default
+ # class - we'll give this thing a name here, and we'll make it
+ # be the name of the autocomplete.
+ #
+ label = self._script.getDisplayedLabel(parent)
+ if not label or not len(label):
+ label = parent.name
+ utterances.append(label)
+ elif obj.getRole() in [pyatspi.ROLE_ENTRY,
+ pyatspi.ROLE_PASSWORD_TEXT] \
+ and self._script.inDocumentContent():
+ # This is a form field in web content. If we don't get a label,
+ # we'll try to guess what text on the page is functioning as
+ # the label.
+ #
+ label = self._script.getDisplayedLabel(obj)
+ if not label or not len(label):
+ label = self._script.guessTheLabel(obj)
+ if label:
+ utterances.append(label)
+ else:
+ return speechgenerator.SpeechGenerator._getSpeechForText(
+ self, obj, already_focused)
+
+ utterances.extend(self.getSpeechForObjectRole(obj))
+
+ [text, caretOffset, startOffset] = self._script.getTextLineAtCaret(obj)
+ utterances.append(text)
+
+ self._debugGenerator("Gecko._getSpeechForText",
+ 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.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForComboBox(self, obj, already_focused)
+
+ utterances = []
+
+ label = self._script.getDisplayedLabel(obj)
+ if not label:
+ if not self._script.inDocumentContent():
+ label = obj.name
+ else:
+ label = self._script.guessTheLabel(obj)
+
+ if not already_focused and label:
+ utterances.append(label)
+
+ # With Gecko, a combo box has a menu as a child. The text being
+ # displayed for the combo box can be obtained via the selected
+ # menu item.
+ #
+ menu = None
+ for child in obj:
+ if child.getRole() == pyatspi.ROLE_MENU:
+ menu = child
+ break
+ if menu:
+ child = None
+ try:
+ # This should work...
+ #
+ child = menu.querySelection().getSelectedChild(0)
+ except:
+ # But just in case, we'll fall back on this.
+ # [[[TODO - JD: Will we ever have a case where the first
+ # fails, but this will succeed???]]]
+ #
+ for item in menu:
+ if item.getState().contains(pyatspi.STATE_SELECTED):
+ child = item
+ break
+ if child:
+ utterances.append(child.name)
+
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+
+ if not already_focused:
+ utterances.extend(self.getSpeechForObjectRole(obj))
+
+ self._debugGenerator("Gecko._getSpeechForComboBox",
+ 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.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForMenuItem(self, obj, already_focused)
+
+ if not self._script.inDocumentContent():
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForMenuItem(self, obj, already_focused)
+
+ utterances = self._getSpeechForObjectName(obj)
+
+ # Saying "menu item" for a combo box can confuse users. Therefore,
+ # speak the combo box role instead. Also, only do it if the menu
+ # item is not focused (if the menu item is focused, it means we're
+ # navigating in the combo box)
+ #
+ if not obj.getState().contains(pyatspi.STATE_FOCUSED):
+ comboBox = \
+ self._script.getAncestor(obj,
+ [pyatspi.ROLE_COMBO_BOX],
+ [pyatspi.ROLE_DOCUMENT_FRAME])
+ if comboBox:
+ utterances.extend(self.getSpeechForObjectRole(comboBox))
+
+ self._debugGenerator("Gecko._getSpeechForMenuItem",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def _getSpeechForListItem(self, obj, already_focused):
+ """Get the speech for a list item.
+
+ Arguments:
+ - obj: the list item
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+
+ if self._script.isAriaWidget(obj) \
+ or not self._script.inDocumentContent(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForListItem(self, obj, already_focused)
+
+ if not obj.getState().contains(pyatspi.STATE_SELECTABLE):
+ return speechgenerator.SpeechGenerator.\
+ _getDefaultSpeech(self, obj, already_focused)
+
+ utterances = self._getSpeechForObjectName(obj)
+
+ self._debugGenerator("Gecko._getSpeechForListItem",
+ obj,
+ already_focused,
+ utterances)
+
+ 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.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForList(self, obj, already_focused)
+
+ if not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForList(self, obj, already_focused)
+
+ utterances = []
+
+ if obj.getState().contains(pyatspi.STATE_FOCUSED):
+ label = self._script.getDisplayedLabel(obj)
+ if not label:
+ if not self._script.inDocumentContent():
+ label = obj.name
+ else:
+ label = self._script.guessTheLabel(obj)
+
+ if not already_focused and label:
+ utterances.append(label)
+
+ item = None
+ selection = obj.querySelection()
+ for i in xrange(obj.childCount):
+ if selection.isChildSelected(i):
+ item = obj[i]
+ break
+ item = item or obj[0]
+ if item:
+ name = self._getSpeechForObjectName(item)
+ if name != label:
+ utterances.extend(name)
+
+ if not already_focused:
+ if obj.getState().contains(pyatspi.STATE_MULTISELECTABLE):
+ # Translators: "multi-select" refers to a web form list
+ # in which more than one item can be selected at a time.
+ #
+ utterances.append(_("multi-select"))
+
+ # Translators: this represents a list in HTML.
+ #
+ itemString = ngettext("List with %d item",
+ "List with %d items",
+ obj.childCount) % obj.childCount
+ utterances.append(itemString)
+
+ self._debugGenerator("Gecko._getSpeechForList",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def _getSpeechForImage(self, obj, already_focused):
+ """Gets a list of utterances to be spoken for an image.
+
+ The default speech will be of the following form:
+
+ label name role availability
+
+ Arguments:
+ - obj: an Accessible
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForImage(self, obj, already_focused)
+
+ utterances = []
+
+ if not already_focused:
+ label = self._getSpeechForObjectLabel(obj)
+ utterances.extend(label)
+ name = self._getSpeechForObjectName(obj)
+ if name != label:
+ utterances.extend(name)
+
+ # If there's no text for the image, expose the link to
+ # the user if the image is in a link.
+ #
+ link = self._script.getAncestor(obj,
+ [pyatspi.ROLE_LINK],
+ [pyatspi.ROLE_DOCUMENT_FRAME])
+ if not len(utterances):
+ if link:
+ utterances.extend(self._getSpeechForLink(link,
+ already_focused))
+ elif link:
+ utterances.extend(self.getSpeechForObjectRole(link))
+
+ utterances.extend(self.getSpeechForObjectRole(obj))
+
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+
+ self._debugGenerator("Gecko._getSpeechForImage",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def _getSpeechForLink(self, obj, already_focused):
+ """Gets a list of utterances to be spoken for a link.
+
+ Arguments:
+ - obj: an Accessible
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.getSpeech(obj,
+ already_focused)
+
+ utterances = []
+
+ if not already_focused:
+ label = self._getSpeechForObjectLabel(obj)
+ utterances.extend(label)
+ name = self._getSpeechForObjectName(obj)
+
+ # Handle empty alt tags.
+ #
+ if name:
+ lengthOfName = len(name[0].strip())
+ if (lengthOfName > 0) and (name != label):
+ utterances.extend(name)
+
+ # If there's no text for the link, expose part of the
+ # URI to the user.
+ #
+ if not len(utterances):
+ basename = self._script.getLinkBasename(obj)
+ if basename:
+ utterances.append(basename)
+
+ utterances.extend(self.getSpeechForObjectRole(obj))
+
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+
+ self._debugGenerator("Gecko._getSpeechForLink",
+ 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.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForTable(self, obj, already_focused)
+
+ # [[[TODO: JD - We should decide if we want to provide
+ # information about the table dimensions, whether or not
+ # this is a layout table versus a data table, etc. For now,
+ # however, if it's in HTML content let's ignore it so that
+ # SayAll by sentence works. :-) ]]]
+ #
+ utterances = []
+
+ if not self._script.inDocumentContent():
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForTable(self, obj, already_focused)
+
+ 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 radio button
+ - already_focused: False if object just received focus
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForRadioButton(self, obj, already_focused)
+
+ if not self._script.inDocumentContent():
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForRadioButton(self, obj, already_focused)
+
+ utterances = []
+ if obj.getState().contains(pyatspi.STATE_CHECKED):
+ # Translators: this is in reference to a radio button being
+ # selected or not.
+ #
+ # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+ #
+ selectionState = Q_("radiobutton|selected")
+ else:
+ # Translators: this is in reference to a radio button being
+ # selected or not.
+ #
+ # ONLY TRANSLATE THE PART AFTER THE PIPE CHARACTER |
+ #
+ selectionState = Q_("radiobutton|not selected")
+
+ if not already_focused:
+ # The label is handled as a context in default.py -- assuming we
+ # don't have to guess it. If we need to guess it, we need to
+ # add it to utterances.
+ #
+ label = self._script.getDisplayedLabel(obj)
+ if not label:
+ label = self._script.guessTheLabel(obj)
+ if label:
+ utterances.append(label)
+
+ utterances.append(selectionState)
+ utterances.extend(self.getSpeechForObjectRole(obj))
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+ else:
+ utterances.append(selectionState)
+
+ self._debugGenerator("Gecko._getSpeechForRadioButton",
+ 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.
+ """
+
+ # Treat ARIA widgets like default.py widgets
+ #
+ if self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForCheckBox(self, obj, already_focused)
+
+ if not self._script.inDocumentContent():
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForCheckBox(self, obj, already_focused)
+
+ utterances = []
+ state = obj.getState()
+ if state.contains(pyatspi.STATE_INDETERMINATE):
+ # Translators: this represents the state of a checkbox.
+ #
+ checkedState = _("partially checked")
+ elif state.contains(pyatspi.STATE_CHECKED):
+ # Translators: this represents the state of a checkbox.
+ #
+ checkedState = _("checked")
+ else:
+ # Translators: this represents the state of a checkbox.
+ #
+ checkedState = _("not checked")
+
+ # If it's not already focused, say its label.
+ #
+ if not already_focused:
+ label = self._script.getDisplayedLabel(obj)
+ if not label:
+ label = self._script.guessTheLabel(obj)
+ if label:
+ utterances.append(label)
+ utterances.extend(self.getSpeechForObjectRole(obj))
+ utterances.append(checkedState)
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+ else:
+ utterances.append(checkedState)
+
+ self._debugGenerator("Gecko._getSpeechForCheckBox",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
+ def getSpeechContext(self, obj, stopAncestor=None):
+ """Get the speech 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 ancestor to stop at and not include (None
+ means include all ancestors)
+
+ Returns a list of utterances to be spoken.
+ """
+
+ utterances = []
+
+ if obj is stopAncestor:
+ return utterances
+
+ parent = obj.parent
+ while parent and (parent.parent != parent):
+ if self._script.isSameObject(parent, stopAncestor):
+ break
+
+ # We try to omit layout things right off the bat.
+ #
+ if self._script.isLayoutOnly(parent):
+ parent = parent.parent
+ continue
+
+ # If the rolename is unknown, skip this item.
+ #
+ if parent.getRole() == pyatspi.ROLE_UNKNOWN:
+ parent = parent.parent
+ continue
+
+ # To be consistent with how we provide access to other
+ # applications, don't speak the name of menu bars.
+ #
+ if parent.getRole() == pyatspi.ROLE_MENU_BAR:
+ parent = parent.parent
+ continue
+
+ # Skip unfocusable menus. This is for earlier versions
+ # of Firefox where menus were nested in kind of an odd
+ # dual nested menu hierarchy.
+ #
+ if (parent.getRole() == pyatspi.ROLE_MENU) \
+ and not parent.getState().contains(pyatspi.STATE_FOCUSABLE):
+ parent = parent.parent
+ continue
+
+ # Now...autocompletes are weird. We'll let the handling of
+ # the entry give us the name -- unless we're in a toolbar.
+ #
+ containingToolbar = \
+ self._script.getAncestor(obj,
+ [pyatspi.ROLE_TOOL_BAR],
+ [pyatspi.ROLE_DOCUMENT_FRAME])
+ if parent.getRole() == pyatspi.ROLE_AUTOCOMPLETE and \
+ not containingToolbar:
+ parent = parent.parent
+ continue
+
+ # Labels with children should be ignored. (This is the
+ # bugzilla form bogusity bug.)
+ #
+ if parent.getRole() == pyatspi.ROLE_LABEL:
+ parent = parent.parent
+ continue
+
+ # Well...now we skip the parent if it's accessible text is
+ # a single EMBEDDED_OBJECT_CHARACTER. The reason for this
+ # is that it Script.getDisplayedText will end up coming
+ # back to the children of an object for the text in the
+ # children if an object's text contains an
+ # EMBEDDED_OBJECT_CHARACTER.
+ #
+ parentText = self._script.queryNonEmptyText(parent)
+ if parentText:
+ displayedText = parentText.getText(0, -1)
+ unicodeText = displayedText.decode("UTF-8")
+ if unicodeText \
+ and (len(unicodeText) == 1) \
+ and (unicodeText[0] == \
+ self._script.EMBEDDED_OBJECT_CHARACTER):
+ parent = parent.parent
+ continue
+
+ # Finally, put in the text and label (if they exist)
+ #
+ text = self._script.getDisplayedText(parent)
+ label = self._script.getDisplayedLabel(parent)
+ newUtterances = []
+ if text and (text != label) and len(text.strip()) \
+ and (not text.startswith("chrome://")):
+ newUtterances.append(text)
+ if label and len(label.strip()):
+ newUtterances.append(label)
+
+ # Well...if we made it this far, we will now append the
+ # role, then the text, and then the label.
+ #
+ if not parent.getRole() in [pyatspi.ROLE_TABLE_CELL,
+ pyatspi.ROLE_FILLER] \
+ and len(newUtterances):
+ utterances.append(rolenames.getSpeechForRoleName(parent))
+
+ utterances.extend(newUtterances)
+
+ parent = parent.parent
+
+ utterances.reverse()
+
+ 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
+
+ Returns a list of utterances to be spoken for the object.
+ """
+
+ # Let default handle non-ARIA widgets (XUL?)
+ if not self._script.isAriaWidget(obj):
+ return speechgenerator.SpeechGenerator.\
+ _getSpeechForSlider(self, obj, already_focused)
+
+ value = obj.queryValue()
+
+ # OK, this craziness is all about trying to figure out the most
+ # meaningful formatting string for the floating point values.
+ # The number of places to the right of the decimal point should
+ # be set by the minimumIncrement, but the minimumIncrement isn't
+ # always set. So...we'll default the minimumIncrement to 1/100
+ # of the range. But, if max == min, then we'll just go for showing
+ # them off to two meaningful digits.
+ #
+ try:
+ minimumIncrement = value.minimumIncrement
+ except:
+ minimumIncrement = 0.0
+
+ if minimumIncrement == 0.0:
+ minimumIncrement = (value.maximumValue - value.minimumValue) \
+ / 100.0
+
+ try:
+ decimalPlaces = max(0, -math.log10(minimumIncrement))
+ except:
+ try:
+ decimalPlaces = max(0, -math.log10(value.minimumValue))
+ except:
+ try:
+ decimalPlaces = max(0, -math.log10(value.maximumValue))
+ except:
+ decimalPlaces = 0
+
+ formatter = "%%.%df" % decimalPlaces
+ valueString = formatter % value.currentValue
+ #minString = formatter % value.minimumValue
+ #maxString = formatter % value.maximumValue
+
+ if already_focused:
+ utterances = [valueString]
+ else:
+ utterances = []
+ utterances.extend(self._getSpeechForObjectLabel(obj))
+ utterances.extend(self.getSpeechForObjectRole(obj))
+ utterances.append(valueString)
+ utterances.extend(self._getSpeechForObjectAvailability(obj))
+
+ self._debugGenerator("_getSpeechForSlider",
+ obj,
+ already_focused,
+ utterances)
+
+ return utterances
+
Added: trunk/src/orca/scripts/toolkits/Gecko/where_am_i.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Gecko/where_am_i.py Fri May 2 21:21:19 2008
@@ -0,0 +1,216 @@
+# Orca
+#
+# Copyright 2005-2007 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+"""Custom script for Gecko toolkit.
+Please refer to the following URL for more information on the AT-SPI
+implementation in Gecko:
+http://developer.mozilla.org/en/docs/Accessibility/ATSPI_Support
+"""
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.debug as debug
+import orca.orca_state as orca_state
+import orca.settings as settings
+import orca.speech as speech
+import orca.where_am_I as where_am_I
+
+from orca.orca_i18n import _
+from orca.orca_i18n import ngettext # for ngettext support
+
+########################################################################
+# #
+# Custom WhereAmI #
+# #
+########################################################################
+
+class GeckoWhereAmI(where_am_I.WhereAmI):
+ def __init__(self, script):
+ """Gecko specific WhereAmI that will be used to speak information
+ about the current object of interest and will provide additional Gecko
+ specific information.
+ """
+ where_am_I.WhereAmI.__init__(self, script)
+ self._script = script
+
+ def whereAmI(self, obj, basicOnly):
+ """Calls the base class method for basic information and Gecko
+ specific presentation methods for detailed/custom information.
+ """
+ if basicOnly or not self._script.inDocumentContent(obj):
+ where_am_I.WhereAmI.whereAmI(self, obj, basicOnly)
+ self._script.liveMngr.outputLiveRegionDescription(obj)
+ else:
+ if settings.useCollection:
+ try:
+ self._collectionPageSummary()
+ except:
+ debug.printException(debug.LEVEL_SEVERE)
+ self._iterativePageSummary(obj)
+ else:
+ self._iterativePageSummary(obj)
+
+ def _speakDefaultButton(self, obj):
+ """Speaks the default button in a dialog.
+
+ Arguments:
+ - obj: the dialog box for which the default button should be obtained
+ """
+
+ if not (self._script.inDocumentContent(orca_state.locusOfFocus) \
+ and not self._script.isAriaWidget(orca_state.locusOfFocus)):
+ where_am_I.WhereAmI._speakDefaultButton(self, obj)
+
+ def _collectionPageSummary(self):
+ """Uses the Collection interface to get the quantity of headings,
+ forms, tables, visited and unvisited links.
+ """
+ docframe = self._script.getDocumentFrame()
+ col = docframe.queryCollection()
+ # We will initialize these after the queryCollection() call in case
+ # Collection is not supported
+ headings = 0
+ forms = 0
+ tables = 0
+ vlinks = 0
+ uvlinks = 0
+
+ stateset = pyatspi.StateSet()
+ roles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK, pyatspi.ROLE_TABLE,
+ pyatspi.ROLE_FORM]
+ rule = col.createMatchRule(stateset.raw(), col.MATCH_NONE,
+ "", col.MATCH_NONE,
+ roles, col.MATCH_ANY,
+ "", col.MATCH_NONE,
+ False)
+
+ matches = col.getMatches(rule, col.SORT_ORDER_CANONICAL, 0, True)
+
+ col.freeMatchRule(rule)
+ for obj in matches:
+ role = obj.getRole()
+ if role == pyatspi.ROLE_HEADING:
+ headings += 1
+ elif role == pyatspi.ROLE_FORM:
+ forms += 1
+ elif role == pyatspi.ROLE_TABLE \
+ and not self._script.isLayoutOnly(obj):
+ tables += 1
+ elif role == pyatspi.ROLE_LINK:
+ if obj.getState().contains(pyatspi.STATE_VISITED):
+ vlinks += 1
+ else:
+ uvlinks += 1
+
+ self._outputPageSummary(headings, forms, tables, vlinks, uvlinks, None)
+
+ def _iterativePageSummary(self, obj):
+ """Reads the quantity of headings, forms, tables, visited and
+ unvisited links.
+ """
+ headings = 0
+ forms = 0
+ tables = 0
+ vlinks = 0
+ uvlinks = 0
+ nodetotal = 0
+ obj_index = None
+ currentobj = obj
+
+ # start at the first object after document frame
+ obj = self._script.getDocumentFrame()[0]
+ while obj:
+ nodetotal += 1
+ if obj == currentobj:
+ obj_index = nodetotal
+ role = obj.getRole()
+ if role == pyatspi.ROLE_HEADING:
+ headings += 1
+ elif role == pyatspi.ROLE_FORM:
+ forms += 1
+ elif role == pyatspi.ROLE_TABLE \
+ and not self._script.isLayoutOnly(obj):
+ tables += 1
+ elif role == pyatspi.ROLE_LINK:
+ if obj.getState().contains(pyatspi.STATE_VISITED):
+ vlinks += 1
+ else:
+ uvlinks += 1
+
+ obj = self._script.findNextObject(obj)
+
+ # Calculate the percentage of the document that has been read.
+ if obj_index:
+ percentread = int(obj_index*100/nodetotal)
+ else:
+ percentread = None
+
+ self._outputPageSummary(headings, forms, tables,
+ vlinks, uvlinks, percentread)
+
+ def _outputPageSummary(self, headings, forms, tables,
+ vlinks, uvlinks, percent):
+
+ utterances = []
+ if headings:
+ # Translators: Announces the number of headings in the
+ # web page that is currently being displayed.
+ #
+ utterances.append(ngettext \
+ ('%d heading', '%d headings', headings) %headings)
+ if forms:
+ # Translators: Announces the number of forms in the
+ # web page that is currently being displayed.
+ #
+ utterances.append(ngettext \
+ ('%d form', '%d forms', forms) %forms)
+ if tables:
+ # Translators: Announces the number of non-layout tables in the
+ # web page that is currently being displayed.
+ #
+ utterances.append(ngettext \
+ ('%d table', '%d tables', tables) %tables)
+ if vlinks:
+ # Translators: Announces the number of visited links in the
+ # web page that is currently being displayed.
+ #
+ utterances.append(ngettext \
+ ('%d visited link', '%d visited links', vlinks) %vlinks)
+ if uvlinks:
+ # Translators: Announces the number of unvisited links in the
+ # web page that is currently being displayed.
+ #
+ utterances.append(ngettext \
+ ('%d unvisited link', '%d unvisited links', uvlinks) %uvlinks)
+ if percent is not None:
+ # Translators: Announces the percentage of the document that has
+ # been read. This is calculated by knowing the index of the
+ # current position divided by the total number of objects on the
+ # page.
+ #
+ utterances.append(_('%d percent of document read') %percent)
+
+ speech.speakUtterances(utterances)
+
Copied: trunk/src/orca/scripts/toolkits/J2SE-access-bridge.py (from r3875, /trunk/src/orca/J2SE-access-bridge.py)
==============================================================================
--- /trunk/src/orca/J2SE-access-bridge.py (original)
+++ trunk/src/orca/scripts/toolkits/J2SE-access-bridge.py Fri May 2 21:21:19 2008
@@ -25,17 +25,17 @@
import pyatspi
-import default
-import debug
-import orca
-import orca_state
-import keybindings
-import speech
-import rolenames
-import speechgenerator
+import orca.default as default
+import orca.debug as debug
+import orca.orca as orca
+import orca.orca_state as orca_state
+import orca.keybindings as keybindings
+import orca.speech as speech
+import orca.rolenames as rolenames
+import orca.speechgenerator as speechgenerator
-from orca_i18n import _ # for gettext support
-from orca_i18n import Q_ # to provide qualified translatable strings
+from orca.orca_i18n import _ # for gettext support
+from orca.orca_i18n import Q_ # to provide qualified translatable strings
########################################################################
# #
Added: trunk/src/orca/scripts/toolkits/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/toolkits/Makefile.am Fri May 2 21:21:19 2008
@@ -0,0 +1,12 @@
+SUBDIRS = Gecko
+
+orca_pathdir=$(pyexecdir)
+
+orca_python_PYTHON = \
+ __init__.py \
+ GAIL.py \
+ J2SE-access-bridge.py \
+ VCL.py
+
+orca_pythondir=$(pyexecdir)/orca/scripts/toolkits
+
Copied: trunk/src/orca/scripts/toolkits/VCL.py (from r3875, /trunk/src/orca/scripts/Mozilla.py)
==============================================================================
--- /trunk/src/orca/scripts/Mozilla.py (original)
+++ trunk/src/orca/scripts/toolkits/VCL.py Fri May 2 21:21:19 2008
@@ -17,7 +17,7 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-"""Custom script for Mozilla. NOT WORKING WELL AT THE MOMENT."""
+"""Custom script for VCL toolkit (OpenOffice) applications"""
__id__ = "$Id$"
__version__ = "$Revision$"
@@ -25,12 +25,7 @@
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
__license__ = "LGPL"
-import orca.Gecko as Gecko
+import orca.default
-class Script(Gecko.Script):
- def __init__(self, app):
- Gecko.Script.__init__(self, app)
-
- # By default, don't present if Mozilla is not the active application.
- #
- self.presentIfInactive = False
+class Script(orca.default.Script):
+ pass
Added: trunk/src/orca/scripts/toolkits/__init__.py
==============================================================================
Modified: trunk/src/orca/settings.py
==============================================================================
--- trunk/src/orca/settings.py (original)
+++ trunk/src/orca/settings.py Fri May 2 21:21:19 2008
@@ -778,7 +778,8 @@
# REMEMBER: to make something a package, the directory has to
# have a __init__.py file in it.
#
-scriptPackages = ["orca-scripts", "scripts"]
+scriptPackages = ["orca-scripts", "scripts",
+ "scripts.apps", "scripts.toolkits"]
# A list that helps us map application names to script module
# names. The key is the name of an application, and the value is
@@ -836,22 +837,22 @@
# I wish the AT-SPI spec'd this out as machine readable (unlocalized)
# names, but it's what we're stuck with (unfortunately).
#
-setScriptMapping(re.compile(_('[\S\s]*StarOffice[\s\S]*')), "StarOffice")
+setScriptMapping(re.compile(_('[\S\s]*StarOffice[\s\S]*')), "soffice")
# Translators: see the regular expression note above. This is for
# OpenOffice and StarOffice.
#
-setScriptMapping(re.compile(_('soffice.bin')), "StarOffice")
+setScriptMapping(re.compile(_('soffice.bin')), "soffice")
# Translators: see the regular expression note above. This is for
# OpenOffice and StarOffice.
#
-setScriptMapping(re.compile(_('soffice')), "StarOffice")
+setScriptMapping(re.compile(_('soffice')), "soffice")
# Translators: see the regular expression note above. This is for the
# Evolution mail application.
#
-setScriptMapping(re.compile(_('[Ee]volution')), "Evolution")
+setScriptMapping(re.compile(_('[Ee]volution')), "evolution")
# Translators: see the regular expression note above. This is for the
# help application (yelp).
@@ -892,9 +893,9 @@
setScriptMapping(re.compile(_('vte')), "gnome-terminal")
# Translators: see the regular expression note above. This is for
-# supporting pidgin, which is the new name for gaim.
+# supporting gaim, which has recently be renamed to pidgin.
#
-setScriptMapping(re.compile(_('pidgin')), "gaim")
+setScriptMapping(re.compile(_('gaim')), "pidgin")
# Show deprecated messeges in debug output.
# Set this to True to help find potential pyatspi porting problems
Modified: trunk/test/harness/orca-customizations.py.in
==============================================================================
--- trunk/test/harness/orca-customizations.py.in (original)
+++ trunk/test/harness/orca-customizations.py.in Fri May 2 21:21:19 2008
@@ -16,5 +16,5 @@
orca.settings.progressBarUpdateInterval = 0
orca.settings.commFailureAttemptLimit = 0
-import orca.Gecko
-orca.Gecko.sayAllOnLoad = False
+import orca.scripts.toolkits.Gecko
+orca.scripts.toolkits.Gecko.sayAllOnLoad = False
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]