Beispiel #1
0
    def isFocusOnFindDialog(self):
        """Return an indication of whether the current locus of focus is on
        the Find button or the combo box in the Find dialog.
        """

        obj = orca_state.locusOfFocus
        rolesList1 = [
            rolenames.ROLE_PUSH_BUTTON, rolenames.ROLE_FILLER,
            rolenames.ROLE_FILLER, rolenames.ROLE_DIALOG,
            rolenames.ROLE_APPLICATION
        ]

        rolesList2 = [
            rolenames.ROLE_COMBO_BOX, rolenames.ROLE_PANEL,
            rolenames.ROLE_FILLER, rolenames.ROLE_FILLER,
            rolenames.ROLE_DIALOG, rolenames.ROLE_APPLICATION
        ]

        # Translators: this is used to tell us if the focus is on the
        # "Find" button in gedit's Find dialog.  It must match what
        # gedit is using.  We hate keying off stuff like this, but
        # we're forced to do so in this case.
        #
        if (self.isDesiredFocusedItem(obj, rolesList1) \
            and obj.name == _("Find")) \
            or (self.isDesiredFocusedItem(obj, rolesList2) \
                and obj.parent.parent.parent.parent.name == _("Find")):
            return True
        else:
            return False
    def isFocusOnFindDialog(self):
        """Return an indication of whether the current locus of focus is on
        the Find button or the combo box in the Find dialog.
        """

        obj = orca_state.locusOfFocus
        rolesList1 = [rolenames.ROLE_PUSH_BUTTON,
                     rolenames.ROLE_FILLER,
                     rolenames.ROLE_FILLER,
                     rolenames.ROLE_DIALOG,
                     rolenames.ROLE_APPLICATION]

        rolesList2 = [rolenames.ROLE_COMBO_BOX,
                     rolenames.ROLE_PANEL,
                     rolenames.ROLE_FILLER,
                     rolenames.ROLE_FILLER,
                     rolenames.ROLE_DIALOG,
                     rolenames.ROLE_APPLICATION]

        # Translators: this is used to tell us if the focus is on the
        # "Find" button in gedit's Find dialog.  It must match what
        # gedit is using.  We hate keying off stuff like this, but
        # we're forced to do so in this case.
        #
        if (self.isDesiredFocusedItem(obj, rolesList1) \
            and obj.name == _("Find")) \
            or (self.isDesiredFocusedItem(obj, rolesList2) \
                and obj.parent.parent.parent.parent.name == _("Find")):
            return True
        else:
            return False
Beispiel #3
0
    def onStateChanged(self, event):
        """Called whenever an object's state changes.

        Arguments:
        - event: the Event
        """

        if not event.type.startswith("object:state-changed:busy"):
            default.Script.onStateChanged(self, event)
            return

        if not event.source or event.source.getRole() != pyatspi.ROLE_DOCUMENT_FRAME or not self._isBrowser:
            return

        if event.detail1:
            # Translators: this is in reference to loading a web page
            # or some other content.
            #
            self.presentMessage(_("Loading.  Please wait."))
        elif event.source.name:
            # Translators: this is in reference to loading a web page
            # or some other content.
            #
            self.presentMessage(_("Finished loading %s.") % event.source.name)
        else:
            # Translators: this is in reference to loading a web page
            # or some other content.
            #
            self.presentMessage(_("Finished loading."))
Beispiel #4
0
    def presentStatusBar(self, obj):
        """Presents information about the metacity status bar."""

        # We have to stop speech, as Metacity has a key grab and we're not
        # getting keys
        #
        speech.stop()

        # If the window was iconified, then obj.name will be surronded by
        # brackets. If this is the case, remove them before comparing the
        # name against the various window names. See bug #522797 for more
        # details.
        #
        objName = obj.name
        if objName and len(objName):
            if objName[0] == "[" and objName[-1] == "]":
                objName = objName[1:-1]

        # Do we know about this window?  Traverse through our list of apps
        # and go through the toplevel windows in each to see if we know
        # about this one.  If we do, it's accessible.  If we don't, it is
        # not.
        #
        found = False
        for app in self.utilities.knownApplications():
            i = 0
            try:
                childCount = app.childCount
            except:
                continue
            while i < childCount:
                try:
                    win = app.getChildAtIndex(i)
                except:
                    win = None
                if win is None:
                    print("app error " + app.name)
                elif win.name == objName:
                    found = True
                i = i + 1

        try:
            text = obj.name
        except:
            text = objName

        # Translators: the "Workspace " and "Desk " strings are
        # the prefix of what metacity shows when you press
        # Ctrl+Alt and the left or right arrow keys to switch
        # between workspaces.  The goal here is to find a match
        # with that prefix.
        #
        if text.startswith(_("Workspace ")) or text.startswith(_("Desk ")):
            pass
        elif not found:
            text += ". " + messages.INACCESSIBLE

        self.displayBrailleMessage(text)
        speech.speak(text)
Beispiel #5
0
    def onStateChanged(self, event):
        """Called whenever an object's state changes.

        Arguments:
        - event: the Event
        """

        if event.source.getRole() == pyatspi.ROLE_FRAME \
           and event.type.startswith("object:state-changed:busy"):
            # The busy cursor gets set/unset frequently. It's only worth
            # presenting if we're in the Search entry (handles both search
            # and catalog refreshes).
            #
            if not self.isSearchEntry(orca_state.locusOfFocus):
                return

            if event.detail1 == 1 and not self._isBusy:
                # Translators: this is in reference to loading a web page
                # or some other content.
                #
                msg = _("Loading.  Please wait.")
                speech.speak(msg)
                self.displayBrailleMessage(
                    msg, flashTime=settings.brailleFlashTime)
                self._isBusy = True
            elif event.detail1 == 0 and self._isBusy:
                # Translators: this is in reference to loading a web page
                # or some other content.
                #
                msg = _("Finished loading.")
                speech.speak(msg)
                self.displayBrailleMessage(
                    msg, flashTime=settings.brailleFlashTime)
                self._isBusy = False
            return

        if script_settings.presentLoggedErrors \
           and not self._presentedStatusBarIcon \
           and event.source.getRole() == pyatspi.ROLE_PANEL \
           and event.type.startswith("object:state-changed:showing") \
           and event.detail1:
            obj = self.findStatusBarIcon()
            while obj and not self.utilities.isSameObject(obj, event.source):
                obj = obj.parent
            if obj:
                # Translators: The Package Manager application notifies the
                # user of minor errors by displaying an icon in the status
                # bar and adding them to an error log rather than displaying
                # the error in a dialog box. This is the message Orca will
                # present to inform the user that this has occurred.
                #
                msg = _("An error occurred. View the error log for details.")
                speech.speak(msg)
                self.displayBrailleMessage(
                    msg, flashTime=settings.brailleFlashTime)
                self._presentedStatusBarIcon = True

        default.Script.onStateChanged(self, event)
Beispiel #6
0
    def checkForTableBoundary(self, oldFocus, newFocus):
        """Check to see if we've crossed any table boundaries,
        speaking the appropriate details when we have.

        Arguments:
        - oldFocus: Accessible that is the old locus of focus
        - newFocus: Accessible that is the new locus of focus
        """

        if oldFocus == None or newFocus == None:
            return

        [oldFocusIsTable, oldFocusRows, oldFocusColumns] = \
                   self.getTableAndDimensions(oldFocus)
        [newFocusIsTable, newFocusRows, newFocusColumns] = \
                   self.getTableAndDimensions(newFocus)

        # [[[TODO: JD - It is possible to move focus into the object
        # that contains the object that contains the text object. We
        # need to detect this and adjust accordingly.]]]

        if not oldFocusIsTable and newFocusIsTable:
            # We've entered a table.  Announce the dimensions.
            #
            line = _("table with %d rows and %d columns.") % \
                    (newFocusRows, newFocusColumns)
            speech.speak(line)

        elif oldFocusIsTable and not newFocusIsTable:
            # We've left a table.  Announce this fact.
            #
            speech.speak(_("leaving table."))

        elif oldFocusIsTable and newFocusIsTable:
            # See if we've crossed a cell boundary.  If so, speak
            # what has changed (per Mike).
            #
            [oldRow, oldCol] = \
                   self.getCellCoordinates(oldFocusIsTable, oldFocus)
            [newRow, newCol] = \
                   self.getCellCoordinates(newFocusIsTable, newFocus)
            # We can't count on being in the first/last cell
            # of the new row -- only the first/last cell of
            # the new row that contains data.
            #
            if newRow != oldRow:
                # Translators: this represents the row and column we're
                # on in a table.
                #
                line = _("row %d, column %d") % (newRow, newCol)
                speech.speak(line)
            elif newCol != oldCol:
                # Translators: this represents the column we're
                # on in a table.
                #
                line = _("column %d") % newCol
                speech.speak(line)
    def checkForTableBoundary (self, oldFocus, newFocus):
        """Check to see if we've crossed any table boundaries,
        speaking the appropriate details when we have.

        Arguments:
        - oldFocus: Accessible that is the old locus of focus
        - newFocus: Accessible that is the new locus of focus
        """

        if oldFocus == None or newFocus == None:
            return

        [oldFocusIsTable, oldFocusRows, oldFocusColumns] = \
                   self.getTableAndDimensions(oldFocus)
        [newFocusIsTable, newFocusRows, newFocusColumns] = \
                   self.getTableAndDimensions(newFocus)

        # [[[TODO: JD - It is possible to move focus into the object
        # that contains the object that contains the text object. We
        # need to detect this and adjust accordingly.]]]

        if not oldFocusIsTable and newFocusIsTable:
            # We've entered a table.  Announce the dimensions.
            #
            line = _("table with %d rows and %d columns.") % \
                    (newFocusRows, newFocusColumns)
            speech.speak(line)

        elif oldFocusIsTable and not newFocusIsTable:
            # We've left a table.  Announce this fact.
            #
            speech.speak(_("leaving table."))

        elif oldFocusIsTable and newFocusIsTable:
            # See if we've crossed a cell boundary.  If so, speak
            # what has changed (per Mike).
            #
            [oldRow, oldCol] = \
                   self.getCellCoordinates(oldFocusIsTable, oldFocus)
            [newRow, newCol] = \
                   self.getCellCoordinates(newFocusIsTable, newFocus)
            # We can't count on being in the first/last cell
            # of the new row -- only the first/last cell of
            # the new row that contains data.
            #
            if newRow != oldRow:
                # Translators: this represents the row and column we're
                # on in a table.
                #
                line = _("row %d, column %d") % (newRow, newCol)
                speech.speak(line)
            elif newCol != oldCol:
                # Translators: this represents the column we're
                # on in a table.
                #
                line = _("column %d") % newCol
                speech.speak(line)
Beispiel #8
0
 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.utilities.isSameObject(cur_obj, obj):
         # Translators: this announces that the current object is the same
         # object pointed to by the bookmark.
         #
         self._script.presentMessage(_('bookmark is current object'))
         return
     # Are their parents the same?
     elif self._script.utilities.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.
         #
         self._script.presentMessage(
             _('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:
             rolename = rolenames.getSpeechForRoleName(p)
             # Translators: this announces that the bookmark and the current
             # object share a common ancestor
             #
             self._script.presentMessage(_('shared ancestor %s') % rolename)
             return
         p = p.parent
     
     # Translators: This announces that a comparison between the bookmark
     # and the current object can not be determined.
     #
     self._script.presentMessage(_('comparison unknown'))
    def __init__(self, app):
        """Creates a new script for the given application.

        Arguments:
        - app: the application to create a script for.
        """

        self.debugLevel = debug.LEVEL_FINEST
        default.Script.__init__(self, app)

        # Acroread documents are contained in an object whose rolename
        # is "Document".  "Link" is also capitalized in acroread.  We
        # need to make these known to Orca for speech and braille output.
        #
        self.ROLE_DOCUMENT = "Document"
        rolenames.rolenames[self.ROLE_DOCUMENT] = \
            rolenames.Rolename(self.ROLE_DOCUMENT,
                               # Translators: short braille for the
                               # rolename of a document.
                               #
                               _("doc"),
                               # Translators: long braille for the
                               # rolename of a document.
                               #
                               _("Document"),
                               # Translators: spoken words for the
                               # rolename of a document.
                               #
                               _("document"))

        self.ROLE_LINK = "Link"
        rolenames.rolenames[self.ROLE_LINK] = \
            rolenames.rolenames[rolenames.ROLE_LINK]

        # To handle the multiple, identical object:text-caret-moved events
        # and possible focus events that result from a single key press
        #
        self.currentInputEvent = None

        # To handle the case when we get an object:text-caret-moved event
        # for some text we just left, but which is still showing on the
        # screen.
        #
        self.lastCaretMovedLine = None

        # To minimize chattiness related to focused events when the Find
        # toolbar is active.
        #
        self.findToolbarActive = False
        self.findToolbarName = None
        self.preFindLine = None
Beispiel #10
0
    def __init__(self, app):
        """Creates a new script for the given application.

        Arguments:
        - app: the application to create a script for.
        """

        self.debugLevel = debug.LEVEL_FINEST
        default.Script.__init__(self, app)

        # Acroread documents are contained in an object whose rolename
        # is "Document".  "Link" is also capitalized in acroread.  We
        # need to make these known to Orca for speech and braille output.
        #
        self.ROLE_DOCUMENT = "Document"
        rolenames.rolenames[self.ROLE_DOCUMENT] = \
            rolenames.Rolename(self.ROLE_DOCUMENT,
                               # Translators: short braille for the
                               # rolename of a document.
                               #
                               _("doc"),
                               # Translators: long braille for the
                               # rolename of a document.
                               #
                               _("Document"),
                               # Translators: spoken words for the
                               # rolename of a document.
                               #
                               _("document"))

        self.ROLE_LINK = "Link"
        rolenames.rolenames[self.ROLE_LINK] = \
            rolenames.rolenames[rolenames.ROLE_LINK]

        # To handle the multiple, identical object:text-caret-moved events
        # and possible focus events that result from a single key press
        #
        self.currentInputEvent = None

        # To handle the case when we get an object:text-caret-moved event
        # for some text we just left, but which is still showing on the
        # screen.
        #
        self.lastCaretMovedLine = None

        # To minimize chattiness related to focused events when the Find
        # toolbar is active.
        #
        self.findToolbarActive = False
        self.findToolbarName = None
        self.preFindLine = None
    def _getTutorialForText(self, obj, alreadyFocused, forceTutorial):
        """Get the tutorial string for a text object.

        Arguments:
        - obj: the text component
        - alreadyFocused: False if object just received focus
        - forceTutorial: used for when whereAmI really needs the tutorial
          string

        Returns a list of tutorial utterances to be spoken for the object.
        """

        utterances = tutorialgenerator.TutorialGenerator.\
            _getTutorialForText(self, obj, alreadyFocused, forceTutorial)
        if utterances and self._script.isSearchEntry(obj):
            # Translators: This is the tutorial string associated with a
            # specific search field in the Packagemanager application.
            # It is designed to inform the user how to move directly to
            # the search results after the search has been completed.
            #
            utterances.append(_("Use Ctrl+L to move focus to the results."))
        self._debugGenerator("_getTutorialForText",
                             obj,
                             alreadyFocused,
                             utterances)

        return utterances
Beispiel #12
0
    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 = [rolenames.ROLE_TOGGLE_BUTTON, rolenames.ROLE_TOOL_BAR]

        if self._script.isDesiredFocusedItem(obj, roleList) and not obj.name:
            text += _("Display more options")

        # Second special case is each one of the four graphics toggle
        # buttons in the main window Application should implement an
        # accessible relationship between the button and the label,
        # but until this is made we append for each one the button the
        # label that should be associated and its state (checked or
        # not)
        #
        rolesList = [rolenames.ROLE_TOGGLE_BUTTON,\
                     rolenames.ROLE_FILLER,\
                     rolenames.ROLE_FILLER,\
                     rolenames.ROLE_PANEL,\
                     rolenames.ROLE_PANEL]
        if self._script.isDesiredFocusedItem(obj, rolesList):
            debug.println(debug.LEVEL_FINEST,
                          "planner.onFocus - main window: " \
                          + "one of the four graphic toggle buttons.")
            filler = obj.parent
            allLabels = self._script.findByRole(filler, rolenames.ROLE_LABEL)
            text += allLabels[0].name

        text = self._script.appendString(
            settings.brailleRadioButtonIndicators[
                obj.state.count(atspi.Accessibility.STATE_CHECKED)],
            text)

        text = self._script.appendString(text, self._getTextForRole(obj))

        regions = []
        componentRegion = braille.Component(obj, text)
        regions.append(componentRegion)

        return [regions, componentRegion]
Beispiel #13
0
    def _isSpellCheckListItemFocus(self, event):
        """Check if this event is for a list item in the spell checking
        dialog and whether it has a FOCUSED state.

        Arguments:
        - event: the Event

        Return True is this event is for a list item in the spell checking 
        dialog and it doesn't have a FOCUSED state, Otherwise return False.
        """

        rolesList = [pyatspi.ROLE_LIST_ITEM, \
                     pyatspi.ROLE_LIST, \
                     pyatspi.ROLE_DIALOG, \
                     pyatspi.ROLE_APPLICATION]
        if self.utilities.hasMatchingHierarchy(event.source, rolesList):
            dialog = event.source.parent.parent

            # Translators: this is what the name of the spell checking
            # dialog in Thunderbird begins with. The translated form
            # has to match what Thunderbird is using.  We hate keying
            # off stuff like this, but we're forced to do so in this case.
            #
            if dialog.name.startswith(_("Check Spelling")):
                state = event.source.getState()
                if not state.contains(pyatspi.STATE_FOCUSED):
                    return True

        return False
Beispiel #14
0
    def _generateDisplayedText(self, obj, **args):
        """Returns an array of strings for use by braille that represents all
        the text being displayed by the object. [[[WDW - consider
        returning an empty array if this is not a text object.]]]
        """
        result = []

        # This is the black triangle at the far right of the toolbar.
        #
        handleRibbonButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR

        # This is one of the Gantt, Tasks, Resources, etc., buttons on the
        # left hand side of the main window.
        #
        handleTabButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_FILLER \
            and len(obj.parent) == 2

        if handleRibbonButton:
            result.append(_("Display more options"))
        elif handleTabButton:
            result.append(self._script.utilities.displayedText(obj.parent[1]))
        else:
            result.extend(
                braille_generator.BrailleGenerator._generateDisplayedText(
                    self, obj, **args))

        return result
Beispiel #15
0
    def onChildrenChanged(self, event):
        """Called whenever a child object changes in some way.

        Arguments:
        - event: the text inserted Event
        """

        # Check to see if a new chat room tab has been created and if it
        # has, then announce its name. See bug #469098 for more details.
        #
        if event.type.startswith("object:children-changed:add"):
            rolesList = [pyatspi.ROLE_PAGE_TAB_LIST,
                         pyatspi.ROLE_FILLER,
                         pyatspi.ROLE_FRAME]
            if self.utilities.hasMatchingHierarchy(event.source, rolesList):
                # As it's possible to get this component hierarchy in other
                # places than the chat room (i.e. the Preferences dialog),
                # we check to see if the name of the frame is the same as one
                # of its children. If it is, then it's a chat room tab event.
                # For a final check, we only announce the new chat tab if the
                # last child has a name.
                #
                nameFound = False
                frameName = event.source.parent.parent.name
                for child in event.source:
                    if frameName and (frameName == child.name):
                        nameFound = True
                if nameFound:
                    child = event.source[-1]
                    if child.name:
                        line = _("New chat tab %s") % child.name
                        speech.speak(line)
    def _generateLabelAndName(self, obj, **args):
        """Gets the label and the name if the name is different from the label.
        """
        result = []

        # This is the black triangle at the far right of the toolbar.
        #
        handleRibbonButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR

        # This is one of the Gantt, Tasks, Resources, etc., buttons on the
        # left hand side of the main window.
        #
        handleTabButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_FILLER \
            and len(obj.parent) == 2

        if handleRibbonButton:
            result.append(_("Display more options"))
        elif handleTabButton:
            result.append(self._script.utilities.displayedText(obj.parent[1]))
        else:
            result.extend(
                speech_generator.SpeechGenerator._generateLabelAndName(
                    self, obj, **args))

        return result
Beispiel #17
0
    def onWindowCreate(self, event):
        """Called whenever a window is created in the notify-osd
        application.

        Arguments:
        - event: the Event.
        """
        try:
            ivalue = event.source.queryValue()
            value = ivalue.currentValue
        except NotImplementedError:
            value = -1
            
        utterances = []
        message = ""
        if value < 0:
            # Translators: This denotes a notification to the user of some sort.
            #
            utterances.append(_('Notification'))
            utterances.append(self.voices.get(settings.SYSTEM_VOICE))
            message = '%s %s' % (event.source.name, event.source.description)
            utterances.append(message)
            utterances.append(self.voices.get(settings.DEFAULT_VOICE))
        else:
            # A gauge notification, e.g. the Ubuntu volume notification that
            # appears when you press the multimedia keys.
            #
            message = '%s %d' % (event.source.name, value)
            utterances.append(message)
            utterances.append(self.voices.get(settings.SYSTEM_VOICE))

        speech.speak(utterances, None, True)
        self.displayBrailleMessage(message, flashTime=settings.brailleFlashTime)
        notification_messages.saveMessage(message)
Beispiel #18
0
    def _generateDisplayedText(self, obj, **args):
        """Returns an array of strings for use by braille that represents all
        the text being displayed by the object. [[[WDW - consider
        returning an empty array if this is not a text object.]]]
        """
        result = []

        # This is the black triangle at the far right of the toolbar.
        #
        handleRibbonButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR

        # This is one of the Gantt, Tasks, Resources, etc., buttons on the
        # left hand side of the main window.
        #
        handleTabButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_FILLER \
            and len(obj.parent) == 2

        if handleRibbonButton:
            result.append(_("Display more options"))
        elif handleTabButton:
            result.append(self._script.utilities.displayedText(obj.parent[1]))
        else:
            result.extend(
                braille_generator.BrailleGenerator._generateDisplayedText(
                    self, obj, **args))

        return result
Beispiel #19
0
    def _generateLabelAndName(self, obj, **args):
        """Gets the label and the name if the name is different from the label.
        """
        result = []

        # This is the black triangle at the far right of the toolbar.
        #
        handleRibbonButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR

        # This is one of the Gantt, Tasks, Resources, etc., buttons on the
        # left hand side of the main window.
        #
        handleTabButton = \
            obj and not obj.name \
            and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON \
            and obj.parent.getRole() == pyatspi.ROLE_FILLER \
            and len(obj.parent) == 2

        if handleRibbonButton:
            result.append(_("Display more options"))
        elif handleTabButton:
            result.append(self._script.utilities.displayedText(obj.parent[1]))
        else:
            result.extend(
                speech_generator.SpeechGenerator._generateLabelAndName(
                    self, obj, **args))

        return result
Beispiel #20
0
    def onChildrenChanged(self, event):
        """Called whenever a child object changes in some way.

        Arguments:
        - event: the text inserted Event
        """

        # Check to see if a new chat room tab has been created and if it
        # has, then announce its name. See bug #469098 for more details.
        #
        if event.type.startswith("object:children-changed:add"):
            rolesList = [rolenames.ROLE_PAGE_TAB_LIST, \
                         rolenames.ROLE_FILLER, \
                         rolenames.ROLE_FRAME]
            if self.isDesiredFocusedItem(event.source, rolesList):
                childCount = event.source.childCount

                # As it's possible to get this component hierarchy in other
                # places than the chat room (i.e. the Preferences dialog),
                # we check to see if the name of the frame is the same as one
                # of its children. If it is, then it's a chat room tab event.
                # For a final check, we only announce the new chat tab if the
                # last child has a name.
                #
                nameFound = False
                frameName = event.source.parent.parent.name
                for i in range(0, childCount):
                    child = event.source.child(i)
                    if frameName and (frameName == child.name):
                        nameFound = True
                if nameFound:
                    child = event.source.child(childCount - 1)
                    if child.name:
                        line = _("New chat tab %s") % child.name
                        speech.speak(line)
    def _tableCellPresentation(self, cell, arg):
        """Presents the table cell or indicates that one was not found.
        Overridden here to avoid the double-speaking of the dynamic
        headers.

        Arguments:
        - obj: the accessible object under consideration.
        - arg: an optional argument which may need to be included in
          the criteria (e.g. the level of a heading).
        """

        # TODO - JD: This really should be dealt with via a formatting
        # string, once we work out how to implement formatting strings
        # throughout the Gecko code. In the meantime, this method will
        # result in a consistent user experience between applications.
        #
        if not cell:
            return

        if settings.speakCellHeaders:
            self._presentCellHeaders(cell, arg)

        [obj, characterOffset] = self._getCaretPosition(cell)
        self._setCaretPosition(obj, characterOffset)
        self._script.updateBraille(obj)

        blank = self._isBlankCell(cell)
        if not blank:
            for child in cell:
                speech.speak(self._script.utilities.displayedText(child))
        else:
            # Translators: "blank" is a short word to mean the
            # user has navigated to an empty line.
            #
            speech.speak(_("blank"))

        if settings.speakCellCoordinates:
            [row, col] = self.getCellCoordinates(cell)
            # Translators: this represents the (row, col) position of
            # a cell in a table.
            #
            self._script.presentMessage(_("Row %(row)d, column %(column)d.") \
                                       % {"row" : row + 1, "column" : col + 1})

        spanString = self._getCellSpanInfo(cell)
        if spanString and settings.speakCellSpan:
            self._script.presentMessage(spanString)
Beispiel #22
0
    def onNameChanged(self, event):
        """Called whenever a property on an object changes.

        Arguments:
        - event: the Event
        """

        obj = event.source

        # If the user has just deleted an open mail message, then we want to
        # try to speak the new name of the open mail message frame and also
        # present the first line of that message to be consistent with what
        # we do when a new message window is opened. See bug #540039 for more
        # details.
        #
        rolesList = [pyatspi.ROLE_DOCUMENT_FRAME,
                     pyatspi.ROLE_INTERNAL_FRAME,
                     pyatspi.ROLE_FRAME,
                     pyatspi.ROLE_APPLICATION]
        if self.utilities.hasMatchingHierarchy(event.source, rolesList):
            lastKey, mods = self.utilities.lastKeyAndModifiers()
            if lastKey == "Delete":
                speech.speak(obj.name)
                [obj, offset] = self.findFirstCaretContext(obj, 0)
                self.setCaretPosition(obj, offset)
                return

        # If we get a "object:property-change:accessible-name" event for 
        # the first item in the Suggestions lists for the spell checking
        # dialog, then speak the first two labels in that dialog. These
        # will by the "Misspelled word:" label and the currently misspelled
        # word. See bug #535192 for more details.
        #
        rolesList = [pyatspi.ROLE_LIST_ITEM,
                     pyatspi.ROLE_LIST,
                     pyatspi.ROLE_DIALOG,
                     pyatspi.ROLE_APPLICATION]
        if self.utilities.hasMatchingHierarchy(obj, rolesList):
            dialog = obj.parent.parent

            # Translators: this is what the name of the spell checking 
            # dialog in Thunderbird begins with. The translated form
            # has to match what Thunderbird is using.  We hate keying
            # off stuff like this, but we're forced to do so in this case.
            #
            if dialog.name.startswith(_("Check Spelling")):
                if obj.getIndexInParent() == 0:
                    badWord = self.utilities.displayedText(dialog[1])

                    if self.textArea != None:
                        # If we have a handle to the Thunderbird message text
                        # area, then extract out all the text objects, and
                        # create a list of all the words found in them.
                        #
                        allTokens = []
                        text = self.utilities.substring(self.textArea, 0, -1)
                        tokens = text.split()
                        allTokens += tokens
                        self.speakMisspeltWord(allTokens, badWord)
Beispiel #23
0
    def setupInputEventHandlers(self):
        debug.println(self.debugLevel, "gnome-mud.setupInputEventHandlers.")

        default.Script.setupInputEventHandlers(self)
        self.inputEventHandlers["readPreviousMessageHandler"] = \
            input_event.InputEventHandler(
                Script.readPreviousMessage,
                _("Read the latest n messages in the incoming messages text \
                    area."))
    def _generateTableCellRow(self, obj, **args):
        """Get the speech for a table cell row or a single table cell
        if _settingsManager.getSetting('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

        Returns a list of utterances to be spoken for the object.
        """
        result = []
        if self._script.isSpreadSheetCell(obj):
            if _settingsManager.getSetting('readTableCellRow'):
                parent = obj.parent
                parentTable = parent.queryTable()
                index = self._script.utilities.cellIndex(obj)
                row = parentTable.getRowAtIndex(index)
                column = parentTable.getColumnAtIndex(index)
                # 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 "lastRow" in self._script.pointOfReference and \
                    "lastColumn" in self._script.pointOfReference:
                    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:
                            result.extend(self._generateRealTableCell(
                                              cell, **args))
                else:
                    result.extend(self._generateRealTableCell(obj, **args))
            else:
                result.extend(self._generateRealTableCell(obj, **args))
        else:
            result.extend(
                speech_generator.SpeechGenerator._generateTableCellRow(
                    self, obj, **args))
            if not len(result) \
               and _settingsManager.getSetting('speakBlankLines'):
                # Translators: "blank" is a short word to mean the
                # user has navigated to an empty line.
                #
                result.append(_("blank"))
        return result
Beispiel #25
0
    def _speakEnclosingPanel(self, obj):
        """Speak the enclosing panel for the object, if it is
        named. Going two containers up the hierarchy appears to be far
        enough to find a named panel, if there is one.  Don't speak
        panels whose name begins with 'chrome://'"""

        self._debug("_speakEnclosingPanel")

        parent = obj.parent
        if not parent:
            return

        if parent.name != "" \
            and (not parent.name.startswith("chrome://")) \
            and (parent.role == rolenames.ROLE_PANEL):

            # Speak the parent panel name, but only once.
            #
            if parent.name != self._containingPanelName:
                self._containingPanelName = parent.name
                utterances = []
                # Translators: this is the name of a panel in Thunderbird.
                #
                text = _("%s panel") % parent.name
                utterances.append(text)
                speech.speakUtterances(utterances)
        else:
            grandparent = parent.parent
            if grandparent \
                and (grandparent.name != "") \
                and (not grandparent.name.startswith("chrome://")) \
                and (grandparent.role == rolenames.ROLE_PANEL):

                # Speak the grandparent panel name, but only once.
                #
                if grandparent.name != self._containingPanelName:
                    self._containingPanelName = grandparent.name
                    utterances = []
                    # Translators: this is the name of a panel in Thunderbird.
                    #
                    text = _("%s panel") % grandparent.name
                    utterances.append(text)
                    speech.speakUtterances(utterances)
Beispiel #26
0
    def presentStatusBar(self, obj):
        """Presents information about the metacity status bar."""

        # We have to stop speech, as Metacity has a key grab and we're not
        # getting keys
        #
        speech.stop()

        # Do we know about this window?  Traverse through our list of apps
        # and go through the toplevel windows in each to see if we know
        # about this one.  If we do, it's accessible.  If we don't, it is
        # not.
        #
        found = False
        for app in self.getKnownApplications():
            i = 0
            while i < app.childCount:
                win = app.child(i)
                if win is None:
                    print "app error " + app.name
                elif win.name == obj.name:
                    found = True
                i = i + 1

        text = obj.name

        # Translators: the "Workspace " and "Desk " strings are
        # the prefix of what metacity shows when you press
        # Ctrl+Alt and the left or right arrow keys to switch
        # between workspaces.  The goal here is to find a match
        # with that prefix.
        #
        if text.startswith(_("Workspace ")) or text.startswith(_("Desk ")):
            pass
        elif not found:
            # Translators: inaccessible means that the application cannot
            # be read by Orca.  This usually means the application is not
            # friendly to the assistive technology infrastructure.
            #
            text += ". " + _("inaccessible")

        braille.displayMessage(text)
        speech.speak(text)
Beispiel #27
0
    def _speakEnclosingPanel(self, obj):
        """Speak the enclosing panel for the object, if it is
        named. Going two containers up the hierarchy appears to be far
        enough to find a named panel, if there is one.  Don't speak
        panels whose name begins with 'chrome://'"""

        self._debug("_speakEnclosingPanel")

        parent = obj.parent
        if not parent:
            return

        if parent.name != "" \
            and (not parent.name.startswith("chrome://")) \
            and (parent.getRole() == pyatspi.ROLE_PANEL):

            # Speak the parent panel name, but only once.
            #
            if parent.name != self._containingPanelName:
                self._containingPanelName = parent.name
                utterances = []
                # Translators: this is the name of a panel in Thunderbird.
                #
                text = _("%s panel") % parent.name
                utterances.append(text)
                speech.speak(utterances)
        else:
            grandparent = parent.parent
            if grandparent \
                and (grandparent.name != "") \
                and (not grandparent.name.startswith("chrome://")) \
                and (grandparent.getRole() == pyatspi.ROLE_PANEL):

                # Speak the grandparent panel name, but only once.
                #
                if grandparent.name != self._containingPanelName:
                    self._containingPanelName = grandparent.name
                    utterances = []
                    # Translators: this is the name of a panel in Thunderbird.
                    #
                    text = _("%s panel") % grandparent.name
                    utterances.append(text)
                    speech.speak(utterances)
Beispiel #28
0
    def _generateRoleName(self, obj, **args):
        if _settingsManager.getSetting('onlySpeakDisplayedText'):
            return []

        result = []
        acss = self.voice(speech_generator.SYSTEM)
        role = args.get('role', obj.getRole())
        force = args.get('force', False)

        doNotSpeak = [pyatspi.ROLE_UNKNOWN]
        if not force:
            doNotSpeak.extend([pyatspi.ROLE_FORM,
                               pyatspi.ROLE_LABEL,
                               pyatspi.ROLE_MENU_ITEM,
                               pyatspi.ROLE_LIST_ITEM,
                               pyatspi.ROLE_PARAGRAPH,
                               pyatspi.ROLE_SECTION,
                               pyatspi.ROLE_TABLE_CELL])

        if not (role in doNotSpeak):
            if role == pyatspi.ROLE_IMAGE:
                link = self._script.utilities.ancestorWithRole(
                    obj, [pyatspi.ROLE_LINK], [pyatspi.ROLE_DOCUMENT_FRAME])
                if link:
                    result.append(self.getLocalizedRoleName(link))

            if role == pyatspi.ROLE_HEADING:
                level = self._script.utilities.headingLevel(obj)
                if level:
                    # Translators: the %(level)d is in reference to a heading
                    # level in HTML (e.g., For <h3>, the level is 3)
                    # and the %(role)s is in reference to a previously
                    # translated rolename for the heading.
                    #
                    result.append(_("%(role)s level %(level)d") % {
                        'role': self.getLocalizedRoleName(obj, role),
                        'level': level})
                else:
                    result.append(self.getLocalizedRoleName(obj, role))
            else:
                result.append(self.getLocalizedRoleName(obj, role))

            if result:
                result.extend(acss)

            if role == pyatspi.ROLE_LINK \
               and obj.childCount and obj[0].getRole() == pyatspi.ROLE_IMAGE:
                # If this is a link with a child which is an image, we
                # want to indicate that.
                #
                acss = self.voice(speech_generator.HYPERLINK)
                result.append(self.getLocalizedRoleName(obj[0]))
                result.extend(acss)

        return result
    def setupInputEventHandlers(self):
        """Defines InputEventHandler fields for this script that can be
        called by the key and braille bindings. In this particular case,
        we just want to be able to add a handler to toggle whether we
        prefix chat room messages with the name of the chat room.
        """

        debug.println(self.debugLevel, "gaim.setupInputEventHandlers.")

        default.Script.setupInputEventHandlers(self)
        self.inputEventHandlers["togglePrefixHandler"] = input_event.InputEventHandler(
            Script.togglePrefix, _("Toggle whether we prefix chat room messages with the name of the chat room.")
        )

        # In gaim/pidgin, we are overriding the default script's bookmark
        # feature and keybindings to provide chat room message history.
        #
        self.inputEventHandlers["goToBookmark"] = input_event.InputEventHandler(
            Script.readPreviousMessage, _("Speak and braille a previous chat room message.")
        )
Beispiel #30
0
    def togglePrefix(self, inputEvent):
        """ Toggle whether we prefix chat room messages with the name of
        the chat room.

        Arguments:
        - inputEvent: if not None, the input event that caused this action.
        """

        global prefixChatMessage

        debug.println(self.debugLevel, "gaim.togglePrefix.")

        line = _("speak chat room name.")
        prefixChatMessage = not prefixChatMessage
        if not prefixChatMessage:
            line = _("Do not speak chat room name.")

        speech.speak(line)

        return True
    def togglePrefix(self, inputEvent):
        """ Toggle whether we prefix chat room messages with the name of
        the chat room.

        Arguments:
        - inputEvent: if not None, the input event that caused this action.
        """

        global prefixChatMessage

        debug.println(self.debugLevel, "gaim.togglePrefix.")

        line = _("speak chat room name.")
        prefixChatMessage = not prefixChatMessage
        if not prefixChatMessage:
            line = _("Do not speak chat room name.")

        speech.speak(line)

        return True
Beispiel #32
0
    def setupInputEventHandlers(self):
        """Defines InputEventHandler fields for this script that can be
        called by the key and braille bindings. In this particular case,
        we just want to be able to define our own sayAll() method.
        """

        default.Script.setupInputEventHandlers(self)

        self.inputEventHandlers["sayAllHandler"] = \
            input_event.InputEventHandler(
                Script.sayAll,
                _("Speaks entire document."))
    def setupInputEventHandlers(self):
        """Defines InputEventHandler fields for this script that can be
        called by the key and braille bindings. In this particular case,
        we just want to be able to define our own sayAll() method.
        """

        default.Script.setupInputEventHandlers(self)

        self.inputEventHandlers["sayAllHandler"] = \
            input_event.InputEventHandler(
                Script.sayAll,
                _("Speaks entire document."))
Beispiel #34
0
    def onWindowCreate(self, event):
        """Called whenever a window is created in the notification-daemon
        application.

        Arguments:
        - event: the Event.
        """
        a = self.findByRole(event.source, rolenames.ROLE_LABEL)
        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)
Beispiel #35
0
    def setupInputEventHandlers(self):
        """Defines InputEventHandler fields for this script that can be
        called by the key and braille bindings. In this particular case,
        we just want to be able to add a handler to toggle whether we
        prefix chat room messages with the name of the chat room.
        """

        debug.println(self.debugLevel, "gaim.setupInputEventHandlers.")

        default.Script.setupInputEventHandlers(self)
        self.inputEventHandlers["togglePrefixHandler"] = \
            input_event.InputEventHandler(
                Script.togglePrefix,
                _("Toggle whether we prefix chat room messages with the name of the chat room."))

        # In gaim/pidgin, we are overriding the default script's bookmark
        # feature and keybindings to provide chat room message history.
        #
        self.inputEventHandlers["goToBookmark"] = \
            input_event.InputEventHandler(
                Script.readPreviousMessage,
                _("Speak and braille a previous chat room message."))
 def _generateToggleState(self, obj, **args):
     """Treat push buttons (which act like toggle buttons) and toggle
     buttons in the toolbar specially.  This is so we can have more
     natural sounding speech such as "bold on", "bold off", etc."""
     acss = self.voice(speech_generator.SYSTEM)
     result = []
     role = args.get('role', obj.getRole())
     if role in [pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_TOGGLE_BUTTON] \
        and obj.parent.getRole() == pyatspi.ROLE_TOOL_BAR:
         if obj.getState().contains(pyatspi.STATE_CHECKED):
             # Translators: this represents the state of a check box
             #
             result.append(_("on"))
         else:
             # Translators: this represents the state of a check box
             #
             result.append(_("off"))
         result.extend(acss)
     elif role == pyatspi.ROLE_TOGGLE_BUTTON:
         result.extend(speech_generator.SpeechGenerator._generateToggleState(
             self, obj, **args))
     return result
    def onWindowCreate(self, event):
        """Called whenever a window is created in the notification-daemon
        application.

        Arguments:
        - event: the Event.
        """
        a = self.findByRole(event.source, rolenames.ROLE_LABEL)
        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)
Beispiel #38
0
 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.generateSpeech(obj))
     speech.speak(utterances)
Beispiel #39
0
    def onWindowCreate(self, event):
        """Called whenever a window is created in the notification-daemon
        application.

        Arguments:
        - event: the Event.
        """
        a = self.utilities.descendantsWithRole(event.source, pyatspi.ROLE_LABEL)
        print a
        texts = [self.utilities.displayedText(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)
Beispiel #40
0
    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
            #
            self._script.presentMessage(_('bookmarks saved'))
        except IOError:
            # Translators: this announces that a bookmark could not be saved to 
            # disk
            #
            self._script.presentMessage(_('bookmarks could not be saved'))

        # Notify the observers
        for o in self._saveObservers:
            o()
Beispiel #41
0
    def onShowingChanged(self, event):
        """Callback for object:state-changed:showing accessibility events."""

        obj = event.source
        if obj.getRole() != pyatspi.ROLE_PUSH_BUTTON \
           or not obj.getState().contains(pyatspi.STATE_VISIBLE):
            return default.Script.onShowingChanged(self, event)

        # Translators: the "Stop" string must match what gnome-search-tool
        # is using.  We hate keying off stuff like this, but we're forced
        # to do so in this case.
        if obj.name == _("Stop"):
            self.searching = True
            if not self.fileTable:
                frame = self.utilities.topLevelObject(obj)
                allTables = self.utilities.descendantsWithRole(
                    frame, pyatspi.ROLE_TABLE)
                self.fileTable = allTables[0]

            GLib.idle_add(self._speakSearching)
            return

        # Translators: the "Find" string must match what gnome-search-tool
        # is using.  We hate keying off stuff like this, but we're forced
        # to do so in this case.
        if obj.name == _("Find") and self.searching:
            self.searching = False
            self.presentMessage(messages.SEARCH_COMPLETE)
            if self.fileTable.getState().contains(pyatspi.STATE_SENSITIVE):
                try:
                    fileCount = self.fileTable.queryTable().nRows
                    self.presentMessage(messages.filesFound(fileCount))
                except NotImplementedError:
                    self.presentMessage(messages.FILES_NOT_FOUND)
            return

        default.Script.onShowingChanged(self, event)
Beispiel #42
0
    def _speakSearching(self):
        """If we are still searching, let the user know. Then start another
        timer to go off again and repeat this process.
        """

        if not self.searching:
            return False

        currentTime = time.time()
        if not self.startTime or \
           (currentTime > (self.startTime + self.searchInterval)):
            speech.speak(_("Searching."))
            self.startTime = time.time()

        return True
Beispiel #43
0
    def getAppPreferencesGUI(self):
        """Return a GtkVBox contain the application unique configuration
        GUI items for the current application.
        """

        global prefixChatMessage

        vbox = gtk.VBox(False, 0)
        vbox.set_border_width(12)
        gtk.Widget.show(vbox)
        # Translators: If this checkbox is checked, then Orca will speak
        # the name of the chat room.
        #
        label = _("Speak Chat Room name")
        self.speakNameCheckButton = gtk.CheckButton(label)
        gtk.Widget.show(self.speakNameCheckButton)
        gtk.Box.pack_start(vbox, self.speakNameCheckButton, False, False, 0)
        gtk.ToggleButton.set_active(self.speakNameCheckButton,
                                    prefixChatMessage)

        return vbox
Beispiel #44
0
    def utterMessage(self, chatRoomName, message):
        """ Speak/braille a chat room message.
        messages are kept.

        Arguments:
        - chatRoomName: name of the chat room this message came from.
        - message: the chat room message.
        """

        global prefixChatMessage

        text = ""
        if prefixChatMessage:
            if chatRoomName and chatRoomName != "":
                text += _("Message from chat room %s") % chatRoomName + " "
        if message and message != "":
            text += message

        if text != "":
            braille.displayMessage(text)
            speech.speak(text)
Beispiel #45
0
    def onCaretMoved(self, event):
        """Called whenever the caret moves.

        Arguments:
        - event: the Event
        """

        debug.printObjectEvent(self.debugLevel, event, event.source.toString())

        # self.printAncestry(event.source)

        # If we've received a text caret moved event and the current locus
        # of focus is on the Find button on the Find dialog or the combo
        # box in the Find dialog and the last input event was a Return,
        # and if the current line contains the phrase we were looking for,
        # then speak the current text line, to give an indication of what
        # we've just found.
        #
        if self.isFocusOnFindDialog() \
           and orca_state.lastNonModifierKeyEvent.event_string == "Return":
            debug.println(self.debugLevel, "gedit.onCaretMoved - find dialog.")

            allComboBoxes = self.findByRole(orca_state.locusOfFocus.app,
                                            rolenames.ROLE_COMBO_BOX)
            phrase = self.getDisplayedText(allComboBoxes[0])
            [text, caretOffset, startOffset] = \
                self.getTextLineAtCaret(event.source)
            if text.lower().find(phrase) != -1:
                # Translators: this indicates a find command succeeded in
                # finding something.
                #
                speech.speak(_("Phrase found."))
                utterances = self.speechGenerator.getSpeech(event.source, True)
                speech.speakUtterances(utterances)

        # For everything else, pass the caret moved event onto the parent
        # class to be handled in the default way.

        default.Script.onCaretMoved(self, event)
Beispiel #46
0
    def onStateChanged(self, event):
        """Called whenever an object's state changes.

        Arguments:
        - event: the Event
        """

        debug.printObjectEvent(self.debugLevel, event, event.source.toString())

        # self.printAncestry(event.source)

        rolesList = [rolenames.ROLE_PUSH_BUTTON, \
                    rolenames.ROLE_FILLER, \
                    rolenames.ROLE_FILLER, \
                    rolenames.ROLE_FILLER, \
                    rolenames.ROLE_FRAME, \
                    rolenames.ROLE_APPLICATION]
        visible = event.source.state.count( \
                               atspi.Accessibility.STATE_VISIBLE)

        # Check to see if we have just had an "object:state-changed:showing"
        # event for the Stop button. If the name is "Stop", and one of its
        # states is VISIBLE, that means we have started a search. As the
        # search progresses, regularly inform the user of this by speaking
        # "Searching" (assuming the search tool has focus).
        #
        # Translators: the "Stop" string must match what gnome-search-tool
        # is using.  We hate keying off stuff like this, but we're forced
        # to do so in this case.
        #
        if self.isDesiredFocusedItem(event.source, rolesList) and \
           event.source.name == _("Stop") and visible:
            debug.println(self.debugLevel,
                          "gnome-search-tool.onNameChanged - " \
                          + "search started.")

            self.searching = True

            # If we don't already have a handle to the table containing the
            # list of files found, then get it now.
            #
            if not self.fileTable:
                frame = self.getTopLevel(event.source)
                allTables = self.findByRole(frame, rolenames.ROLE_TABLE)
                self.fileTable = allTables[0]

            gobject.idle_add(self._speakSearching)

        # Check to see if we have just had an "object:state-changed:showing"
        # event for the Find button. If the name is "Find", and one of its
        # states is VISIBLE and we are currently searching, that means we
        # have just stopped a search. Inform the user that the search is
        # complete and tell them how many files were found.
        #
        # Translators: the "Find" string must match what gnome-search-tool
        # is using.  We hate keying off stuff like this, but we're forced
        # to do so in this case.
        #
        if self.isDesiredFocusedItem(event.source, rolesList) and \
           event.source.name == _("Find") and visible and self.searching:
            debug.println(self.debugLevel,
                          "gnome-search-tool.onNameChanged - " \
                          + "search completed.")

            self.searching = False
            speech.speak(_("Search complete."))
            sensitive = self.fileTable.state.count( \
                               atspi.Accessibility.STATE_SENSITIVE)
            if sensitive:
                fileCount = self.fileTable.table.nRows
                noFilesString = ngettext("%d file found", "%d files found",
                                         fileCount) % fileCount
                speech.speak(noFilesString)
            else:
                speech.speak(_("No files found."))

        # Pass the event onto the parent class to be handled in the default way.
        #
        default.Script.onStateChanged(self, event)
Beispiel #47
0
    def onNameChanged(self, event):
        """Called whenever a property on an object changes.

        Arguments:
        - event: the Event
        """

        brailleGen = self.brailleGenerator
        speechGen = self.speechGenerator

        debug.printObjectEvent(self.debugLevel, event, event.source.toString())

        # self.printAncestry(event.source)

        # 1) check spelling dialog.
        #
        # Check to see if if we've had a property-change event for the
        # accessible name for the label containing the current misspelt
        # word in the check spelling dialog.
        # This (hopefully) means that the user has just corrected a
        # spelling mistake, in which case, speak/braille the current
        # misspelt word plus its context.
        #
        # Note that in order to make sure that this event is for the
        # check spelling dialog, a check is made of the localized name of the
        # frame. Translators for other locales will need to ensure that
        # their translation of this string matches what gedit uses in
        # that locale.

        rolesList = [
            rolenames.ROLE_LABEL, rolenames.ROLE_PANEL, rolenames.ROLE_FILLER,
            rolenames.ROLE_FRAME
        ]
        if self.isDesiredFocusedItem(event.source, rolesList):
            frame = event.source.parent.parent.parent
            # Translators: this is the name of the "Check Spelling" window
            # in gedit and must be the same as what gedit uses.  We hate
            # keying off stuff like this, but we're forced to do so in this
            # case.
            #
            if frame.name.startswith(_("Check Spelling")):
                debug.println(self.debugLevel,
                              "gedit.onNameChanged - check spelling dialog.")

                self.readMisspeltWord(event, event.source.parent)
                # Fall-thru to process the event with the default handler.

        # 2) find dialog - phrase not found.
        #
        # If we've received an "object:property-change:accessible-name" for
        # the status bar and the current locus of focus is on the Find
        # button on the Find dialog or the combo box in the Find dialog
        # and the last input event was a Return and the name for the current
        # event source is "Phrase not found", then speak it.
        #
        # [[[TODO: richb - "Phrase not found" is spoken twice because we
        # apparently get two identical "object:property-change:accessible-name"
        # events.]]]

        # Translators: the "Phrase not found" is the result of a failed
        # find command.  It must be the same as what gedit uses.  We hate
        # keying off stuff like this, but we're forced to do so in this
        # case.
        #
        if event.source.role == rolenames.ROLE_STATUSBAR \
           and self.isFocusOnFindDialog() \
           and orca_state.lastNonModifierKeyEvent.event_string == "Return" \
           and event.source.name == _("Phrase not found"):
            debug.println(self.debugLevel,
                          "gedit.onNameChanged - phrase not found.")

            speech.speak(event.source.name)

        # Pass the event onto the parent class to be handled in the default way.
        default.Script.onNameChanged(self, event)
Beispiel #48
0
    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
        """

        brailleGen = self.brailleGenerator
        speechGen = self.speechGenerator

        debug.printObjectEvent(self.debugLevel, event, event.source.toString())

        # self.printAncestry(event.source)

        # 1) Text area (for caching handle for spell checking purposes).
        #
        # This works in conjunction with code in section 2). Check to see if
        # focus is currently in the gedit text area. If it is, then, if this
        # is the first time, save a pointer to the scroll pane which contains
        # the text being editted.
        #
        # Note that this drops through to then use the default event
        # processing in the parent class for this "focus:" event.

        rolesList = [
            rolenames.ROLE_TEXT, rolenames.ROLE_SCROLL_PANE,
            rolenames.ROLE_FILLER, rolenames.ROLE_PAGE_TAB,
            rolenames.ROLE_PAGE_TAB_LIST, rolenames.ROLE_SPLIT_PANE
        ]
        if self.isDesiredFocusedItem(event.source, rolesList):
            debug.println(self.debugLevel,
                          "gedit.locusOfFocusChanged - text area.")

            self.textArea = event.source.parent
            # Fall-thru to process the event with the default handler.

        # 2) check spelling dialog.
        #
        # Check to see if the Spell Check dialog has just appeared and got
        # focus. If it has, then speak/braille the current misspelt word
        # plus its context.
        #
        # Note that in order to make sure that this focus event is for the
        # check spelling dialog, a check is made of the localized name of the
        # option pane. Translators for other locales will need to ensure that
        # their translation of this string matches what gedit uses in
        # that locale.

        rolesList = [
            rolenames.ROLE_TEXT, rolenames.ROLE_FILLER, rolenames.ROLE_PANEL,
            rolenames.ROLE_FILLER, rolenames.ROLE_FRAME
        ]
        if self.isDesiredFocusedItem(event.source, rolesList):
            frame = event.source.parent.parent.parent.parent
            # Translators: this is the name of the "Check Spelling" window
            # in gedit and must be the same as what gedit uses.  We hate
            # keying off stuff like this, but we're forced to do so in this
            # case.
            #
            if frame.name.startswith(_("Check Spelling")):
                debug.println(
                    self.debugLevel,
                    "gedit.locusOfFocusChanged - check spelling dialog.")

                self.readMisspeltWord(event, event.source.parent.parent)
                # Fall-thru to process the event with the default handler.

        # For everything else, pass the focus event onto the parent class
        # to be handled in the default way.

        default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus,
                                           newLocusOfFocus)
Beispiel #49
0
    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
        """

        brailleGen = self.brailleGenerator
        speechGen = self.speechGenerator

        details = debug.getAccessibleDetails(self.debugLevel, event.source)
        debug.printObjectEvent(self.debugLevel, event, details)

        # [[[TODO - JD: what follows here should be replaced with methods
        # in this script's speech and braille generators. That will require
        # making each generator, moving this script into a new directory,
        # etc.]]]
        #

        # Here we handle the case when focus is in the "Work online/offline"
        # button near the status bar that has an image without a description.
        # We speak and braille "Online/Offline button" here, until the
        # developer of the application adds a description to the images
        # associated with the button, which shows the online or offline
        # work mode.
        #
        rolesList = [
            pyatspi.ROLE_PUSH_BUTTON, pyatspi.ROLE_FILLER, pyatspi.ROLE_FILLER,
            pyatspi.ROLE_FRAME
        ]

        # We are checking if the button with the focus is the button to
        # turn on/off the work mode in liferea. This push button is
        # hierarchically located in the main window of the application
        # (frame), inside a filler and inside another filler.
        #
        if self.utilities.hasMatchingHierarchy(event.source, rolesList):
            # If we are focusing this button we construct a utterance and
            # a braille region to speak/braille "online/offline button".
            # Here we declare utterances and add the localized string
            # "online/offline".
            #
            utterances = []
            utterances.append(_("Work online / offline"))

            # Here we extend the utterances with the speech generator for
            # the object with focus (the push button).
            #
            utterances.extend(speechGen.generateSpeech(event.source))

            # Finally we speak/braille the utterances/regions.
            #
            speech.speak(utterances)

            regions = brailleGen.generateBraille(event.source)
            regions[0].insert(0, self.getNewBrailleRegion(utterances[0] + " "))
            self.displayBrailleRegions(regions)

            return

        # Here we handle the case when the focus is in the headlines table.
        # See comment #3 of bug #350233.
        # http://bugzilla.gnome.org/show_bug.cgi?id=350233
        #
        if orca_state.locusOfFocus.getRole() == \
                                        pyatspi.ROLE_TABLE_COLUMN_HEADER:
            table = event.source.parent
            hasRole = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_CELL
            cells = pyatspi.findAllDescendants(event.source, hasRole)
            eventsynthesizer.clickObject(cells[1], 1)

        default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus,
                                           newLocusOfFocus)
Beispiel #50
0
    def readMisspeltWord(self, event, panel):
        """Speak/braille the current misspelt word plus its context.
           The spell check dialog contains a "paragraph" which shows the
           context for the current spelling mistake. After speaking/brailling
           the default action for this component, that a selection of the
           surronding text from that paragraph with the misspelt word is also
           spoken.

        Arguments:
        - event: the event.
        - panel: the panel in the check spelling dialog containing the label
                 with the misspelt word.
        """

        # Braille the default action for this component.
        #
        self.updateBraille(orca_state.locusOfFocus)

        # Look for the label containing the misspelled word.
        # There will be three labels in the top panel in the Check
        # Spelling dialog. Look for the one that isn't a label to
        # another component.
        #
        allLabels = self.findByRole(panel, rolenames.ROLE_LABEL)
        for label in allLabels:
            # Translators: these are labels from the gedit spell checking
            # dialog and must be the same strings gedit uses.  We hate
            # keying off stuff like this, but we're forced to do so in
            # in this case.
            #
            if label.name.startswith(_("Change to:")) or \
               label.name.startswith(_("Misspelled word:")):
                continue
            else:
                badWord = label.name
                break

        # Note that we often get two or more of these focus or property-change
        # events each time there is a new misspelt word. We extract the
        # current text caret position and the misspelt word and compare
        # them against the values saved from the last time this routine
        # was called. If they are the same then we ignore it.

        if self.textArea != None:
            allText = self.findByRole(self.textArea, rolenames.ROLE_TEXT)
            caretPosition = allText[0].text.caretOffset

            debug.println(self.debugLevel, \
                "gedit.readMisspeltWord: type=%s  word=%s caret position=%d" \
                % (event.type, badWord, caretPosition))

            if (caretPosition == self.lastCaretPosition) and \
               (badWord == self.lastBadWord) and \
               (event.type == self.lastEventType):
                return

            # The indication that spell checking is complete is when the
            # "misspelt" word is set to "Completed spell checking". Ugh!
            # Try to detect this and let the user know.
            #
            # Translators: this string must be the same that is used by
            # gedit.  We hate keying off stuff like this, but we're
            # forced to do so in this case.
            #
            if badWord == _("Completed spell checking"):
                utterance = _("Spell checking is complete.")
                speech.speak(utterance)
                utterance = _("Press Tab and Return to terminate.")
                speech.speak(utterance)
                return

            # If we have a handle to the gedit text area, then extract out
            # all the text objects, and create a list of all the words found
            # in them.
            #
            allTokens = []
            for i in range(0, len(allText)):
                text = self.getText(allText[i], 0, -1)
                tokens = text.split()
                allTokens += tokens

            self.speakMisspeltWord(allTokens, badWord)

            # Save misspelt word information for comparison purposes
            # next time around.
            #
            self.lastCaretPosition = caretPosition
            self.lastBadWord = badWord
            self.lastEventType = event.type
Beispiel #51
0
    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
        """

        brailleGen = self.brailleGenerator
        speechGen = self.speechGenerator

        debug.printObjectEvent(self.debugLevel, event, event.source.toString())

        # Here we handle the case when focus is in the "Work online/offline"
        # button near the status bar that has an image without a description.
        # We speak and braille "Online/Offline button" here, until the
        # developer of the application adds a description to the images
        # associated with the button, which shows the online or offline
        # work mode.
        #
        rolesList = [
            rolenames.ROLE_PUSH_BUTTON, rolenames.ROLE_FILLER,
            rolenames.ROLE_FILLER, rolenames.ROLE_FRAME
        ]

        # We are checking if the button with the focus is the button to
        # turn on/off the work mode in liferea. This push button is
        # hierarchically located in the main window of the application
        # (frame), inside a filler and inside another filler.
        #
        if self.isDesiredFocusedItem(event.source, rolesList):
            # If we are focusing this button we construct a utterance and
            # a braille region to speak/braille "online/offline button".
            # Here we declare utterances and add the localized string
            # "online/offline".
            #
            utterances = []
            utterances.append(_("Work online / offline"))

            # Here we extend the utterances with the speech generator for
            # the object with focus (the push button).
            #
            utterances.extend(speechGen.getSpeech(event.source, False))

            # Finally we speak/braille the utterances/regions.
            #
            speech.speakUtterances(utterances)

            regions = brailleGen.getBrailleRegions(event.source)
            regions[0].insert(0, braille.Region(utterances[0] + " "))
            braille.displayRegions(regions)

            return

        # Here we handle the case when the focus is in the headlines table.
        # See comment #3 of bug #350233.
        # http://bugzilla.gnome.org/show_bug.cgi?id=350233
        #
        if orca_state.locusOfFocus.role == rolenames.ROLE_TABLE_COLUMN_HEADER:
            table = event.source.parent
            cells = self.findByRole(table, rolenames.ROLE_TABLE_CELL)
            eventsynthesizer.clickObject(cells[1], 1)

        default.Script.locusOfFocusChanged(self, event, oldLocusOfFocus,
                                           newLocusOfFocus)
Beispiel #52
0
    speech.speak(f.read())
    f = os.popen("acpi")
    braille.displayMessage(f.read(80))
    f.close()
    return True


def decirHoraYFecha(script, inputEvent=None):
    speech.speak(strftime("Son las %H y %M, %A, %d de %B de %Y", localtime()))
    braille.displayMessage(strftime("%H:%M | %d/%m/%Y", localtime()))

    return True


decirInfoBateriaHandler = input_event.InputEventHandler(
    decirInfoBateria, _("Lee el estado de la batería"))
decirHoraYFechaHandler = input_event.InputEventHandler(
    decirHoraYFecha, _("Dicela hora y fecha"))

teclas = keybindings.KeyBindings()

teclas.add(
    keybindings.KeyBinding("h", 1 << settings.MODIFIER_ORCA,
                           1 << settings.MODIFIER_ORCA,
                           decirHoraYFechaHandler))
teclas.add(
    keybindings.KeyBinding("e", 1 << settings.MODIFIER_ORCA,
                           1 << settings.MODIFIER_ORCA,
                           decirInfoBateriaHandler))
settings.keyBindingsMap = {}
settings.keyBindingsMap["default"] = teclas
Beispiel #53
0
    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=[rolenames.ROLE_TOGGLE_BUTTON,\
                  rolenames.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.state.count(atspi.Accessibility.STATE_CHECKED):
                    tmp.append(_("pressed"))
                else:
                    tmp.append(_("not pressed"))

                utterances.extend(tmp)
                utterances.extend(self._getSpeechForObjectAvailability(obj))
            else:
                if obj.state.count(atspi.Accessibility.STATE_CHECKED):
                    utterances.append(_("pressed"))
                else:
                    utterances.append(_("not pressed"))

            return utterances

        # Application should implement an accessible relationship
        # between the button and the label, but until this is made we
        # append for each one the button the label that should be
        # associated and its state (checked or not)
        #
        roleList = [rolenames.ROLE_TOGGLE_BUTTON,\
                    rolenames.ROLE_FILLER,\
                    rolenames.ROLE_FILLER,\
                    rolenames.ROLE_PANEL,\
                    rolenames.ROLE_PANEL]
        if self._script.isDesiredFocusedItem(obj, roleList):
            debug.println(debug.LEVEL_FINEST,
                          "planner.onFocus - main window: " \
                          + "one of the four graphic toggle buttons.")
            if not already_focused:
                filler = obj.parent
                allLabels = self._script.findByRole(filler, rolenames.ROLE_LABEL)
                tmp.append(allLabels[0].name)
                tmp.extend(self._getDefaultSpeech(obj, already_focused))
                if obj.state.count(atspi.Accessibility.STATE_CHECKED):
                    tmp.append(_("pressed"))
                else:
                    tmp.append(_("not pressed"))

                utterances.extend(tmp)
                utterances.extend(self._getSpeechForObjectAvailability(obj))
            else:
                if obj.state.count(atspi.Accessibility.STATE_CHECKED):
                    utterances.append(_("pressed"))
                else:
                    utterances.append(_("not pressed"))

            return utterances

        return self._getSpeechForLabel(obj, already_focused)