Viewing file: script.py (8.24 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Orca # # Copyright 2004-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.
"""Provides a custom script for gcalctool."""
__id__ = "$Id$" __version__ = "$Revision$" __date__ = "$Date$" __copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." __license__ = "LGPL"
import orca.braille as braille import orca.default as default import orca.input_event as input_event import orca.orca_state as orca_state import orca.speech as speech import pyatspi
from speech_generator import SpeechGenerator
from orca.orca_i18n import _ # for gettext support
######################################################################## # # # The GCalcTool script class. # # # ########################################################################
class Script(default.Script):
def __init__(self, app): """Creates a new script for the given application. Callers should use the getScript factory method instead of calling this constructor directly.
Arguments: - app: the application to create a script for. """
default.Script.__init__(self, app)
self._lastProcessedKeyEvent = None self._lastSpokenContents = None self._resultsDisplay = None self._statusLine = None
def getSpeechGenerator(self): """Returns the speech generator for this script. """ return SpeechGenerator(self)
def onWindowActivated(self, event): """Called whenever one of gcalctool's toplevel windows is activated.
Arguments: - event: the window activated Event """
# Locate the results display and the status line if we've not yet # done so. # if not (self._resultsDisplay and self._statusLine) \ and event.source.getRole() == pyatspi.ROLE_FRAME: objs = self.findByRole(event.source, pyatspi.ROLE_EDITBAR) if len(objs) == 0: # Translators: this is an indication that Orca is unable to # obtain the display of the gcalctool calculator, which is # the area where calculation results are presented. # contents = _("Unable to get calculator display") speech.speak(contents) braille.displayMessage(contents) else: self._resultsDisplay = objs[0] contents = self.getText(self._resultsDisplay, 0, -1) braille.displayMessage(contents) # The status line in gcalctool 5.29 is a sibling of the # edit bar. # objs = self.findByRole(self._resultsDisplay.parent, pyatspi.ROLE_TEXT) for obj in objs: if not obj.getState().contains(pyatspi.STATE_EDITABLE): self._statusLine = obj break else: # The status line in gcalctool 5.28 is a label in the # status bar in which text is inserted as need be. # statusBar = self.findStatusBar(event.source) if statusBar: objs = self.findByRole(statusBar, pyatspi.ROLE_LABEL) if len(objs): self._statusLine = objs[0]
default.Script.onWindowActivated(self, event)
def onTextInserted(self, event): """Called whenever text is inserted into gcalctool's text display.
Arguments: - event: the text inserted Event """
# Always update the Braille display but only speak if the last # key pressed was Return, space, or equals. # if self.isSameObject(event.source, self._resultsDisplay): contents = self.getText(self._resultsDisplay, 0, -1) braille.displayMessage(contents)
if (orca_state.lastInputEvent is None) \ or \ (not isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent)): return
if (orca_state.lastNonModifierKeyEvent.event_string == "space") \ or (orca_state.lastNonModifierKeyEvent.event_string \ == "Return") \ or (orca_state.lastNonModifierKeyEvent.event_string == "="):
# gcalctool issues several identical text inserted events # for a single press of keys such as enter, space, or equals. # In fact, it's usually about 4, but we cannot depend upon # that. In addition, keyboard events are decoupled from # text insertion events, so we may get key press/release # events before an insertion occurs, or we might get a # press, an insertion, and then a release. # # So, what we do is try to infer that an insertion event # was the cause of a single key event. # speakIt = True if self._lastProcessedKeyEvent: # This catches text insertion events where the last # keyboard event we looked at was the key release event. # if self._lastProcessedKeyEvent.timestamp \ == orca_state.lastNonModifierKeyEvent.timestamp: speakIt = False # This catches text insertion events where the last # keyboard event we looked at was the key press event, # but the current one is now the associated key release # event. We infer they are the same by looking at the # hardware code, the time delta between the press and # the release, and that we are on the verge of repeating # something we just spoke. # # It would be tempting to look at just the contents that # we previous spoke, but a use case we need to handle is # when the user enters a number (e.g., "666") and then # presses Return several times. In this case, we get # the text insertion events and they are all "666". # elif (self._lastProcessedKeyEvent.type \ == pyatspi.KEY_PRESSED_EVENT) \ and (orca_state.lastNonModifierKeyEvent.type \ == pyatspi.KEY_RELEASED_EVENT) \ and (orca_state.lastNonModifierKeyEvent.hw_code \ == self._lastProcessedKeyEvent.hw_code) \ and (orca_state.lastNonModifierKeyEvent.timestamp \ - self._lastProcessedKeyEvent.timestamp) < 1000 \ and (contents == self._lastSpokenContents): speakIt = False if speakIt: speech.speak(contents) self._lastSpokenContents = contents
self._lastProcessedKeyEvent = \ input_event.KeyboardEvent(orca_state.lastNonModifierKeyEvent)
elif self.isSameObject(event.source, self._statusLine): contents = self.getText(self._statusLine, 0, -1) speech.speak(contents) return
|