Пример #1
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(rolenames.getSpeechForRoleName(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': rolenames.getSpeechForRoleName(obj, role),
                        'level': level})
                else:
                    result.append(rolenames.getSpeechForRoleName(obj, role))
            else:
                result.append(rolenames.getSpeechForRoleName(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(rolenames.getSpeechForRoleName(obj[0]))
                result.extend(acss)

        return result
Пример #2
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'))
Пример #3
0
    def _generateAncestors(self, obj, **args):
        result = []
        priorObj = args.get('priorObj', None)
        commonAncestor = self._script.utilities.commonAncestor(priorObj, obj)

        if obj is commonAncestor:
            return result

        # Skip items of unknown rolenames, menu bars, labels with
        # children, and autocompletes.  (With autocompletes, we
        # wind up speaking the text object). Beginning with Firefox
        # 3.2, list items have names corresponding with their text.
        # This results in displayedText returning actual text
        # and the parent list item being spoken when it should not
        # be. So we'll take list items out of the context.
        #
        skipRoles = [pyatspi.ROLE_UNKNOWN,
                     pyatspi.ROLE_MENU_BAR,
                     pyatspi.ROLE_LABEL,
                     pyatspi.ROLE_AUTOCOMPLETE,
                     pyatspi.ROLE_LIST_ITEM]

        # Stop if we get to a document frame or an internal frame.
        #
        stopRoles = [pyatspi.ROLE_DOCUMENT_FRAME,
                     pyatspi.ROLE_INTERNAL_FRAME]

        # [[[TODO - JD: Right now we're using this method to get the
        # full context of menu items in whereAmI. It seems to work for
        # gtk-demo, but here we're getting way too much context. So for
        # now, add in a check. Later, look for better way.]]]
        #
        if args.get('formatType', 'unfocused') == 'basicWhereAmI':
            stopRoles.append(pyatspi.ROLE_MENU_BAR)

        # There are some objects we want to include in the context,
        # but not add their rolenames.
        #
        dontSpeakRoles = [pyatspi.ROLE_TABLE_CELL,
                          pyatspi.ROLE_FILLER]

        parent = obj.parent
        while parent and (parent.parent != parent):
            role = parent.getRole()
            if self._script.utilities.isSameObject(parent, commonAncestor) \
               or role in stopRoles:
                break

            if role in skipRoles or self._script.utilities.isLayoutOnly(parent):
                parent = parent.parent
                continue

            # If the parent is a menu and its parent is a combo box
            # we'll speak the object as a combo box.
            #
            if role == pyatspi.ROLE_MENU \
               and parent.parent.getRole() == pyatspi.ROLE_COMBO_BOX:
                parent = parent.parent
                continue

            # Also skip the parent if its accessible text is a single
            # EMBEDDED_OBJECT_CHARACTER: displayedText will end up
            # coming back to the child of an object for the text if
            # an object's text contains a single EOC. In addition,
            # beginning with Firefox 3.2, a table cell may derive its
            # accessible name from focusable objects it contains (e.g.
            # links, form fields). displayedText will return the
            # object's name in this case (because of the presence of
            # the EOC and other characters). This causes us to be
            # chatty. So if it's a table cell which contains an EOC,
            # we will also skip the parent.
            #
            parentText = self._script.utilities.queryNonEmptyText(parent)
            if parentText:
                unicodeText = parentText.getText(0, -1).decode("UTF-8")
                if self._script.EMBEDDED_OBJECT_CHARACTER in unicodeText \
                   and (len(unicodeText) == 1 \
                        or role == pyatspi.ROLE_TABLE_CELL):
                    parent = parent.parent
                    continue

            # Put in the text and label (if they exist).
            #
            text = self._script.utilities.displayedText(parent)
            label = self._script.utilities.displayedLabel(parent)
            newResult = []
            acss = self.voice(speech_generator.DEFAULT)
            if text and (text != label) and len(text.strip()) \
                and (not text.startswith("chrome://")):
                newResult.extend(acss)
                newResult.append(text)
            if label and len(label.strip()):
                newResult.extend(acss)
                newResult.append(label)

            # Finally add the role if it's not among the roles we don't
            # wish to speak.
            #
            if not _settingsManager.getSetting('onlySpeakDisplayedText'):
                acss = self.voice(speech_generator.SYSTEM)
                if not (role in dontSpeakRoles) and len(newResult):
                    roleInfo = rolenames.getSpeechForRoleName(parent)
                    if roleInfo:
                        result.extend(acss)
                        result.append(roleInfo)

            # If this object is an ARIA widget with STATE_REQUIRED, add
            # that. (Note that for the most part, the ARIA widget itself
            # has this state, but in the case of a group of radio buttons,
            # it is the group which has the state).
            #
            result.extend(self._generateRequired(parent, **args))

            result.extend(newResult)

            # [[[TODO - JD: Right now we're using this method to get the
            # full context of menu items in whereAmI. It seems to work for
            # gtk-demo, but here we're getting way too much context. So for
            # now, add in a check. Later, look for better way.]]]
            #
            if args.get('formatType', 'unfocused') == 'basicWhereAmI' \
               and parent.getRole() == pyatspi.ROLE_COMBO_BOX:
                break

            parent = parent.parent

        result.reverse()

        return result
Пример #4
0
    def _generateRoleName(self, obj, **args):
        """Prevents some roles from being spoken."""
        result = []
        acss = self.voice(speech_generator.SYSTEM)
        role = args.get('role', obj.getRole())
        force = args.get('force', False)

        # Saying "menu item" for a combo box can confuse users. Therefore,
        # speak the combo box role instead.  Also, only do it if the menu
        # item is not focused (if the menu item is focused, it means we're
        # navigating in the combo box)
        #
        if not obj.getState().contains(pyatspi.STATE_FOCUSED):
            comboBox = self._script.utilities.ancestorWithRole(
                obj, [pyatspi.ROLE_COMBO_BOX], [pyatspi.ROLE_DOCUMENT_FRAME])
            if comboBox:
                return self._generateRoleName(comboBox, **args)

        if not force:
            doNotSpeak = [pyatspi.ROLE_FORM,
                          pyatspi.ROLE_LABEL,
                          pyatspi.ROLE_MENU_ITEM,
                          pyatspi.ROLE_PARAGRAPH,
                          pyatspi.ROLE_SECTION,
                          pyatspi.ROLE_UNKNOWN]
        else:
            # We never ever want to speak 'unknown'
            #
            doNotSpeak = [pyatspi.ROLE_UNKNOWN]

        if not force and self._script.inDocumentContent(obj):
            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
            if not self._script.isAriaWidget(obj) \
               and args.get('formatType', 'unfocused') != 'basicWhereAmI':
                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                doNotSpeak.append(pyatspi.ROLE_LIST)

        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(rolenames.getSpeechForRoleName(link))

            if role == pyatspi.ROLE_HEADING:
                level = self._script.getHeadingLevel(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': rolenames.getSpeechForRoleName(obj, role),
                        'level': level})
                else:
                    result.append(rolenames.getSpeechForRoleName(obj, role))
            else:
                result.append(rolenames.getSpeechForRoleName(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(rolenames.getSpeechForRoleName(obj[0]))
                result.extend(acss)

        return result