Re: Start to scripting Orca
- From: Rich Burridge <Rich Burridge Sun COM>
- To: Orca screen reader developers <orca-list gnome org>, wvdwalt csir co za
- Cc:
- Subject: Re: Start to scripting Orca
- Date: Wed, 05 Apr 2006 08:27:23 -0700
Willem van der Walt wrote:
I have just now tried to use planner, a project management tool. It
sounds like it should be usable with some scripting.
Yes.
The problem is that I am new to gnome and orca of course. What is
happening is that the thing says "toggel button pressed" or not
pressed when arrowing up and down.
I see/hear this too. Visually there is a column of toggle buttons with
graphical images down the left side of the main planner window.
They have text below them:
Gantt Chart
Tasks
Resources
Resource Usage
Unfortunately that text is not currently available to Orca to read.
Now if I look at the component hierarchy with at-poke, I can see
that that panel on the left is filled with a load of fillers each containing
a toggle button and a label. This will be enough to allow us to get to the
text describing each toggle button.
Above the line, a description occurs according to the 7 key on the
numpad. As I understand it, one can now write a script to
automaticly speak the description together with the status of the button.
Unfortunately it's not going to be as simple as that. The person(s)
that wrote planner should have used a LABEL_FOR relationship
to associated the label with the toggle button. I've filed bug #337382
(http://bugzilla.gnome.org/show_bug.cgi?id=337382) against planner on this.
Having said that, we can easily workaround this with an Orca script for
planner.
Is this correct and is there an example script which might already
handle this situation?
Not exactly, but there are one that would make a good starting point.
Evolution
has similar code in it. For something like this, I would start with
that. More on this below.
Can one copy an existing script to the name of a new application to
have orca call it when the new application is opened?
Yes. To do a proper job (i.e. so that others can take advantage of this
work),
one would need to create a new script in the .../orca/src/orca/scripts
directory
called planner.py It could start off as a copy of one of the other
scripts in
that directory. You would also need to modify the Makefile.am file in that
directory, to make sure that the new script name was added to the
orca_python_PYTHON definition. This means that it would automatically
get installed in a location where Python can find it.
So here's what needs to be done to get this to work. I'll create an initial
planner.py script with the following in it.
class Script(default.Script):
def __init__(self, app):
default.Script.__init__(self, app)
Note that the real planner.py will have a load of extra things in it
like the initial copyright message, plus comments, debug messages
and import lines, but in order to try to keep it simple, I'll leave that
out here.
Now what we are interested in is when the focus is on one of those four
toggle buttons. To do this from within the planner.py script, we need to
subclass
the onFocus() method. When that method is called, we check the hierarchy of
the component that currently has focus to see if it matches what we want.
To find out what we want, I would have previously run Planner with Orca and
hit Insert-F7 when the focus was at one of the toggle buttons in
Planner. Doing
that I determined that the component hierarchy I needed to be looking
for is:
toggle button
filler
filler
panel
panel
filler
filler
frame
application
I only need to use enough of these to make it unique.
Also, if it's a focus event for planner but it isn't this kind, then we
just want to pass
it off to the parent class.
This gives the following code:
def onFocus(self, event):
rolesList = [rolenames.ROLE_TOGGLE_BUTTON, \
rolenames.ROLE_FILLER, \
rolenames.ROLE_FILLER, \
rolenames.ROLE_PANEL, \
rolenames.ROLE_PANEL]
if util.isDesiredFocusedItem(event.source, rolesList):
... handle this focus event ...
return
default.Script.onFocus(self, event)
Now we need to fill in the ".. handle this focus event ..." part.
What we want to do is use the filler component that is the parent of the
toggle button that current has focus. It's other child will be the label
that describes this toggle button. We want to get a handle to that,
extract the label and speak it. Here's the code that does that:
filler = event.source.parent
allLabels = atspi.findByRole(filler, rolenames.ROLE_LABEL)
speech.speak(allLabels[0].name)
return
We just use allLabels[0] because we know that there is only going to be one
label found.
I've checked in the full version of this script in CVS HEAD for Orca.
I've also attached it to this message. If you place this in the installed
location for your Orca scripts, then it should work for you. Or just
check out the very latest version of Orca from CVS HEAD and
configure, build and install it.
As you navigate Planner with Orca, I expect you to find other places
where it's not providing enough information. Hopefully we'll be able
to file bugs against Planner so that they properly fix up these problems.
We should also hopefully be able to provide script workarounds to
improve the usability as well.
ps. Where does user questions for orca go?
This is a great place to ask questions like this. The mailing list is
archived.
We can now point people back to this email.
# Orca
#
# Copyright 2005 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.
import orca.debug as debug
import orca.default as default
import orca.atspi as atspi
import orca.rolenames as rolenames
import orca.orca as orca
import orca.braille as braille
import orca.speech as speech
import orca.settings as settings
import orca.util as util
from orca.orca_i18n import _ # for gettext support
########################################################################
# #
# The planner script class. #
# #
########################################################################
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 walkComponentHierarchy(self, obj):
"""Debug routine to print out the hierarchy of components for the
given object.
Arguments:
- obj: the component to start from
"""
print "<<<<---- Component Hierachy ---->>>>"
print "START: Obj:", obj.name, obj.role
parent = obj
while parent:
if parent != obj:
if not parent.parent:
print "TOP: Parent:", parent.name, parent.role
else:
print "Parent:", parent.name, parent.role
parent = parent.parent
print "<<<<============================>>>>"
# This method tries to detect and handle the following cases:
# 1) Main window: one of the four graphic toggle buttons.
def onFocus(self, event):
"""Called whenever an object gets focus.
Arguments:
- event: the Event
"""
brailleGen = self.brailleGenerator
speechGen = self.speechGenerator
debug.printObjectEvent(debug.LEVEL_FINEST,
event,
event.source.toString())
# self.walkComponentHierarchy(event.source)
# 1) Main window: one of the four graphic toggle buttons.
#
# If the focus is on one of the four graphic toggle buttons on
# the left side of the main window, then get the label associated
# with it, and speak it.
rolesList = [rolenames.ROLE_TOGGLE_BUTTON, \
rolenames.ROLE_FILLER, \
rolenames.ROLE_FILLER, \
rolenames.ROLE_PANEL, \
rolenames.ROLE_PANEL]
if util.isDesiredFocusedItem(event.source, rolesList):
debug.println(debug.LEVEL_FINEST,
"planner.onFocus - main window: " \
+ "one of the four graphic toggle buttons.")
filler = event.source.parent
allLabels = atspi.findByRole(filler, rolenames.ROLE_LABEL)
speech.speak(allLabels[0].name)
return
# For everything else, pass the focus event onto the parent class
# to be handled in the default way.
default.Script.onFocus(self, event)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]