orca r4173 - in trunk: . src/orca src/orca/scripts/apps src/orca/scripts/toolkits/Gecko
- From: joanied svn gnome org
- To: svn-commits-list gnome org
- Subject: orca r4173 - in trunk: . src/orca src/orca/scripts/apps src/orca/scripts/toolkits/Gecko
- Date: Mon, 8 Sep 2008 06:47:27 +0000 (UTC)
Author: joanied
Date: Mon Sep 8 06:47:27 2008
New Revision: 4173
URL: http://svn.gnome.org/viewvc/orca?rev=4173&view=rev
Log:
* src/orca/scripts/apps/yelp.py: (new)
src/orca/scripts/apps/Makefile.am:
src/orca/scripts/toolkits/Gecko/script.py:
src/orca/settings.py:
src/orca/structural_navigation.py:
Much work toward the fix for bug #356041 - GNOME Help (yelp) is
inaccessible.
Added:
trunk/src/orca/scripts/apps/yelp.py
Modified:
trunk/ChangeLog
trunk/src/orca/scripts/apps/Makefile.am
trunk/src/orca/scripts/toolkits/Gecko/script.py
trunk/src/orca/settings.py
trunk/src/orca/structural_navigation.py
Modified: trunk/src/orca/scripts/apps/Makefile.am
==============================================================================
--- trunk/src/orca/scripts/apps/Makefile.am (original)
+++ trunk/src/orca/scripts/apps/Makefile.am Mon Sep 8 06:47:27 2008
@@ -27,7 +27,8 @@
metacity.py \
Mozilla.py \
nautilus.py \
- notification-daemon.py
+ notification-daemon.py \
+ yelp.py
orca_pythondir=$(pyexecdir)/orca/scripts/apps
Added: trunk/src/orca/scripts/apps/yelp.py
==============================================================================
--- (empty file)
+++ trunk/src/orca/scripts/apps/yelp.py Mon Sep 8 06:47:27 2008
@@ -0,0 +1,144 @@
+# Orca
+#
+# Copyright 2005-2008 Sun Microsystems Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA 02110-1301 USA.
+
+"""Custom script for Yelp."""
+
+__id__ = "$Id:$"
+__version__ = "$Revision:$"
+__date__ = "$Date:$"
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__license__ = "LGPL"
+
+import pyatspi
+
+import orca.orca as orca
+import orca.orca_state as orca_state
+import orca.settings as settings
+import orca.speech as speech
+
+import orca.scripts.toolkits.Gecko as Gecko
+
+class Script(Gecko.Script):
+
+ def __init__(self, app):
+ Gecko.Script.__init__(self, app)
+
+ # By default, don't present if Yelp is not the active application.
+ #
+ self.presentIfInactive = False
+
+ def onDocumentLoadComplete(self, event):
+ """Called when a web page load is completed."""
+
+ # We can't count on this event, but often when the first Yelp
+ # window is opened, this event is emitted. If we silently set
+ # the locusOfFocus here, the frame won't be the locusOfFocus
+ # for the initial call to getDocumentFrame(). As an added
+ # bonus, when we detect this condition, we can place the user
+ # at the top of the content. Yelp seems to prefer the end,
+ # which is confusing non-visually.
+ #
+ if event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+ orca.setLocusOfFocus(event, event.source, False)
+
+ return Gecko.Script.onDocumentLoadComplete(self, event)
+
+ def getDocumentFrame(self):
+ """Returns the document frame that holds the content being shown."""
+
+ obj = orca_state.locusOfFocus
+ #print "getDocumentFrame", obj
+
+ if not obj:
+ return None
+
+ role = obj.getRole()
+ if role == pyatspi.ROLE_DOCUMENT_FRAME:
+ # We caught a lucky break.
+ #
+ return obj
+ elif role == pyatspi.ROLE_FRAME:
+ # The window was just activated. Do not look from the top down;
+ # it will cause the yelp hierarchy to become crazy, resulting in
+ # all future events having an empty name for the application.
+ # See bug 356041 for more information.
+ #
+ return None
+ else:
+ # We might be in some content. In this case, look up.
+ #
+ return self.getAncestor(obj,
+ [pyatspi.ROLE_DOCUMENT_FRAME,
+ pyatspi.ROLE_EMBEDDED],
+ [pyatspi.ROLE_FRAME])
+
+ def onCaretMoved(self, event):
+ """Called whenever the caret moves.
+
+ Arguments:
+ - event: the Event
+ """
+
+ # Unlike the unpredictable wild, wild web, odds are good that a
+ # caret-moved event from document content in Yelp is valid. But
+ # depending upon the locusOfFocus at the time this event is issued
+ # the default Gecko toolkit script might not do the right thing.
+ # Rather than risk breaking access to web content, we'll just set
+ # the locusOfFocus here before sending this event on.
+ #
+ if self.inDocumentContent(event.source):
+ orca.setLocusOfFocus(event, event.source)
+
+ return Gecko.Script.onCaretMoved(self, event)
+
+ def onChildrenChanged(self, event):
+ """Called when a child node has changed. When the user follows a
+ link in an open Yelp window, the document frame content changes,
+ but we don't get any events to tell us something has loaded.
+ STILL INVESTIGATING, but it seems like we get a reliable
+ object:children-changed:add event for detail1 == -1 for the
+ document frame. Let's go with that for now....
+ """
+
+ if event.type.startswith("object:children-changed:add") \
+ and event.detail1 == -1 and event.source \
+ and event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
+
+ #print "Yelp object:children-changed:add", obj, characterOffset
+
+ # If the frame is the locusOfFocus, getCaretContext() will fail
+ # because we don't want to look from the top down to find the
+ # document frame and cause Yelp to have an identity crisis. So
+ # let's just set it here and avoid that whole mess.
+ #
+ orca.setLocusOfFocus(event, event.source, False)
+ [obj, characterOffset] = self.getCaretContext()
+ if obj:
+ self.setCaretPosition(obj, characterOffset)
+ if obj.getState().contains(pyatspi.STATE_FOCUSED):
+ speech.speakUtterances(\
+ self.speechGenerator.getSpeech(obj, False))
+ elif not Gecko.script_settings.sayAllOnLoad:
+ self.speakContents(\
+ self.getLineContentsAtOffset(obj, characterOffset))
+ elif settings.enableSpeech:
+ self.sayAll(None)
+
+ else:
+ Gecko.Script.onChildrenChanged(self, event)
Modified: trunk/src/orca/scripts/toolkits/Gecko/script.py
==============================================================================
--- trunk/src/orca/scripts/toolkits/Gecko/script.py (original)
+++ trunk/src/orca/scripts/toolkits/Gecko/script.py Mon Sep 8 06:47:27 2008
@@ -1079,7 +1079,8 @@
if context.currentOffset == 0 and \
context.obj.getRole() in [pyatspi.ROLE_HEADING,
pyatspi.ROLE_SECTION,
- pyatspi.ROLE_PARAGRAPH]:
+ pyatspi.ROLE_PARAGRAPH] \
+ and context.obj.parent.getRole() != pyatspi.ROLE_LINK:
characterCount = context.obj.queryText().characterCount
self.setCaretPosition(context.obj, characterCount-1)
elif callbackType == speechserver.SayAllContext.INTERRUPTED:
@@ -3299,6 +3300,19 @@
if obj is None or obj.getRole() == pyatspi.ROLE_HEADING:
return -1
+ try:
+ state = obj.getState()
+ except:
+ return -1
+ else:
+ if state.contains(pyatspi.STATE_DEFUNCT):
+ # Yelp (or perhaps the work-in-progress a11y patch)
+ # seems to be guilty of this.
+ #
+ #print "getNodeLevel - obj is defunct", obj
+ debug.printException(debug.LEVEL_SEVERE)
+ return -1
+
attrs = obj.getAttributes()
if attrs is None:
return -1
@@ -3464,12 +3478,24 @@
# 2) It seems that down arrow moves us to the table, but up
# arrow moves us to the last row. Possible side effect
# of our existing caret browsing implementation??]]]
- #
- if obj[0] and obj[0].getRole == pyatspi.ROLE_CAPTION:
+ # 3) Figure out why the heck the table of contents for at
+ # least some Yelp content consists of a table whose sole
+ # child is a list!!!
+ if obj[0] and obj[0].getRole() in [pyatspi.ROLE_CAPTION,
+ pyatspi.ROLE_LIST]:
obj = obj[0]
else:
obj = obj.queryTable().getAccessibleAt(0, 0)
+ if not obj:
+ # Yelp (or perhaps the work-in-progress a11y patch) seems
+ # to be guilty of this. Although that may have been the
+ # table of contents thing (see #3 above).
+ #
+ #print "getObjectsFromEOCs - in Table, missing an accessible"
+ debug.printException(debug.LEVEL_SEVERE)
+ return []
+
objects = []
text = self.queryNonEmptyText(obj)
if text:
@@ -4407,6 +4433,9 @@
if self.isSameObject(obj, documentFrame):
[obj, characterOffset] = self.getCaretContext()
+ if not obj:
+ return None
+
index = obj.getIndexInParent() - 1
if (index < 0):
if not self.isSameObject(obj, documentFrame):
@@ -4502,6 +4531,9 @@
if self.isSameObject(obj, documentFrame):
[obj, characterOffset] = self.getCaretContext()
+ if not obj:
+ return None
+
# If the object has children, we'll choose the first one,
# unless it's a combo box or a focusable HTML list.
#
@@ -4715,7 +4747,23 @@
-1,
includeNonText)
- return self._documentFrameCaretContext[hash(documentFrame)]
+ [obj, caretOffset] = \
+ self._documentFrameCaretContext[hash(documentFrame)]
+
+ # Yelp is seemingly fond of killing children for sport. Better
+ # check for that.
+ #
+ try:
+ state = obj.getState()
+ except:
+ return [None, -1]
+ else:
+ if state.contains(pyatspi.STATE_DEFUNCT):
+ #print "getCaretContext: defunct object", obj
+ debug.printException(debug.LEVEL_SEVERE)
+ [obj, caretOffset] = [None, -1]
+
+ return [obj, caretOffset]
def getCharacterAtOffset(self, obj, characterOffset):
"""Returns the character at the given characterOffset in the
@@ -5441,7 +5489,8 @@
extents = self.getExtents(obj, characterOffset, characterOffset + 1)
nextExtents = self.getExtents(nextObj, nextOffset, nextOffset + 1)
- while self.onSameLine(extents, nextExtents):
+ while self.onSameLine(extents, nextExtents) \
+ and (extents != nextExtents):
[nextObj, nextOffset] = \
self.findNextCaretInOrder(nextObj, nextOffset)
nextExtents = self.getExtents(nextObj, nextOffset, nextOffset + 1)
Modified: trunk/src/orca/settings.py
==============================================================================
--- trunk/src/orca/settings.py (original)
+++ trunk/src/orca/settings.py Mon Sep 8 06:47:27 2008
@@ -975,11 +975,6 @@
#
setScriptMapping(re.compile(_('[Ee]volution')), "evolution")
-# Translators: see the regular expression note above. This is for the
-# help application (yelp).
-#
-setScriptMapping(re.compile(_('yelp')), "Mozilla")
-
# Translators: see the regular expression note above. This is for a
# version of Mozilla Firefox, which chooses to create strange names
# for itself at the drop of a hat.
@@ -1024,6 +1019,13 @@
#
setScriptMapping(re.compile(_('gaim')), "pidgin")
+# Translators: see the regular expression note above. This is for
+# supporting yelp, which sometimes identifies itself as gnome-help.
+# [[[TODO - JD: Not marked for translation due to string freeze.]]]
+#
+#setScriptMapping(re.compile(_('gnome-help')), "yelp")
+setScriptMapping(re.compile('gnome-help'), "yelp")
+
# Show deprecated messeges in debug output.
# Set this to True to help find potential pyatspi porting problems
#
Modified: trunk/src/orca/structural_navigation.py
==============================================================================
--- trunk/src/orca/structural_navigation.py (original)
+++ trunk/src/orca/structural_navigation.py Mon Sep 8 06:47:27 2008
@@ -783,6 +783,20 @@
"""
obj = obj or self.getCurrentObject()
+
+ # Yelp is seemingly fond of killing children for sport. Better
+ # check for that.
+ #
+ try:
+ state = obj.getState()
+ except:
+ return [None, False]
+ else:
+ if state.contains(pyatspi.STATE_DEFUNCT):
+ #print "goObject: defunct object", obj
+ debug.printException(debug.LEVEL_SEVERE)
+ return [None, False]
+
success = False
wrap = settings.wrappedStructuralNavigation
# Try to find it using Collection first. But don't do this with form
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]