Beispiel #1
0
    def onFocus(self, event):
        """Callback for focus: accessibility events."""

        # NOTE: This event type is deprecated and Orca should no longer use it.
        # This callback remains just to handle bugs in applications and toolkits
        # that fail to reliably emit object:state-changed:focused events.
        if self.utilities.isLayoutOnly(event.source):
            return

        if self.utilities.isTypeahead(orca_state.locusOfFocus) \
           and "Table" in pyatspi.listInterfaces(event.source) \
           and not event.source.getState().contains(pyatspi.STATE_FOCUSED):
            return

        ancestor = pyatspi.findAncestor(orca_state.locusOfFocus, lambda x: x == event.source)
        if not ancestor:
            orca.setLocusOfFocus(event, event.source)
            return

        if ancestor and "Table" in pyatspi.listInterfaces(ancestor):
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if isMenu(ancestor) and not pyatspi.findAncestor(ancestor, isMenu):
            return

        orca.setLocusOfFocus(event, event.source)
Beispiel #2
0
    def onFocus(self, event):
        """Callback for focus: accessibility events."""

        # NOTE: This event type is deprecated and Orca should no longer use it.
        # This callback remains just to handle bugs in applications and toolkits
        # that fail to reliably emit object:state-changed:focused events.

        if self.utilities.eventIsCanvasNoise(event):
            return

        if self.utilities.isLayoutOnly(event.source):
            return

        if self.utilities.isTypeahead(orca_state.locusOfFocus) \
           and "Table" in pyatspi.listInterfaces(event.source) \
           and not event.source.getState().contains(pyatspi.STATE_FOCUSED):
            return

        ancestor = pyatspi.findAncestor(orca_state.locusOfFocus,
                                        lambda x: x == event.source)
        if not ancestor:
            orca.setLocusOfFocus(event, event.source)
            return

        if ancestor and "Table" in pyatspi.listInterfaces(ancestor):
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if isMenu(ancestor) and not pyatspi.findAncestor(ancestor, isMenu):
            return

        orca.setLocusOfFocus(event, event.source)
Beispiel #3
0
    def isDocumentCell(self, cell):
        isCell = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_CELL
        if not isCell(cell):
            cell = pyatspi.findAncestor(cell, isCell)

        if not cell or self.isSpreadSheetCell(cell):
            return False

        isDocument = lambda x: x and x.getRole() == pyatspi.ROLE_DOCUMENT_FRAME
        return pyatspi.findAncestor(cell, isDocument) != None
Beispiel #4
0
    def isDocumentCell(self, cell):
        isCell = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_CELL
        if not isCell(cell):
            cell = pyatspi.findAncestor(cell, isCell)

        if not cell or self.isSpreadSheetCell(cell):
            return False

        isDocument = lambda x: x and x.getRole() == pyatspi.ROLE_DOCUMENT_FRAME
        return pyatspi.findAncestor(cell, isDocument) != None
Beispiel #5
0
    def _on_mouse_moved(self, event):
        """Callback for mouse:abs events."""

        screen, pX, pY = self._pointer.get_position()
        window = self._accessible_window_at_point(pX, pY)
        msg = "MOUSE REVIEW: Window at (%i, %i) is %s" % (pX, pY, window)
        debug.println(debug.LEVEL_INFO, msg, True)
        if not window:
            return

        script = orca_state.activeScript
        if not script:
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if isMenu(orca_state.locusOfFocus):
            menu = orca_state.locusOfFocus
        else:
            menu = pyatspi.findAncestor(orca_state.locusOfFocus, isMenu)

        obj = script.utilities.descendantAtPoint(menu, pX, pY) \
            or script.utilities.descendantAtPoint(window, pX, pY)
        msg = "MOUSE REVIEW: Object at (%i, %i) is %s" % (pX, pY, obj)
        debug.println(debug.LEVEL_INFO, msg, True)

        script = _scriptManager.getScript(window.getApplication(), obj)
        new = _ItemContext(pX, pY, obj, window, script)
        new.present(self._currentMouseOver)
        self._currentMouseOver = new
Beispiel #6
0
    def locateInputLine(self, obj):
        """Return the spread sheet input line. This only needs to be found
        the very first time a spread sheet table cell gets focus. We use the
        table cell to work back up the component hierarchy until we have found
        the common panel that both it and the input line reside in. We then
        use that as the base component to search for a component which has a
        paragraph role. This will be the input line.

        Arguments:
        - obj: the spread sheet table cell that has just got focus.

        Returns the spread sheet input line component.
        """

        if self._script.inputLineForCell:
            return self._script.inputLineForCell

        isScrollPane = lambda x: x and x.getRole() == pyatspi.ROLE_SCROLL_PANE
        scrollPane = pyatspi.findAncestor(obj, isScrollPane)
        if not scrollPane:
            return None

        toolbar = None
        for child in scrollPane.parent:
            if child and child.getRole() == pyatspi.ROLE_TOOL_BAR:
                toolbar = child
                break

        isParagraph = lambda x: x and x.getRole() == pyatspi.ROLE_PARAGRAPH
        allParagraphs = pyatspi.findAllDescendants(toolbar, isParagraph)
        if len(allParagraphs) == 1:
            self._script.inputLineForCell = allParagraphs[0]

        return self._script.inputLineForCell
Beispiel #7
0
    def _generateName(self, obj, **args):
        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateName(obj, **args)

        brailleLabel = self._script.utilities.objectAttributes(obj).get(
            "braillelabel")
        if brailleLabel:
            return [brailleLabel]

        if self._script.utilities.preferDescriptionOverName(obj):
            return [obj.description]

        if obj.name and not self._script.utilities.hasValidName(obj):
            return []

        result = super()._generateName(obj, **args)
        if result and result[0] and not self._script.utilities.hasExplicitName(
                obj):
            result[0] = result[0].strip()
        elif not result and obj.getRole() == pyatspi.ROLE_CHECK_BOX:
            gridCell = pyatspi.findAncestor(obj,
                                            self._script.utilities.isGridCell)
            if gridCell:
                return super()._generateName(gridCell, **args)

        return result
Beispiel #8
0
def _containingDocument(obj):
    roles = [pyatspi.ROLE_DOCUMENT_EMAIL,
             pyatspi.ROLE_DOCUMENT_FRAME,
             pyatspi.ROLE_DOCUMENT_PRESENTATION,
             pyatspi.ROLE_DOCUMENT_SPREADSHEET,
             pyatspi.ROLE_DOCUMENT_TEXT,
             pyatspi.ROLE_DOCUMENT_WEB]
    isDocument = lambda x: x and x.getRole() in roles
    document = pyatspi.findAncestor(obj, isDocument)
    while document:
        ancestor = pyatspi.findAncestor(document, isDocument)
        if not ancestor or ancestor == document:
            break
        document = ancestor

    return document
Beispiel #9
0
    def _on_mouse_moved(self, event):
        """Callback for mouse:abs events."""

        screen, pX, pY = self._pointer.get_position()
        window = self._accessible_window_at_point(pX, pY)
        msg = "MOUSE REVIEW: Window at (%i, %i) is %s" % (pX, pY, window)
        debug.println(debug.LEVEL_INFO, msg, True)
        if not window:
            return

        script = orca_state.activeScript
        if not script:
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if isMenu(orca_state.locusOfFocus):
            menu = orca_state.locusOfFocus
        else:
            menu = pyatspi.findAncestor(orca_state.locusOfFocus, isMenu)

        obj = script.utilities.descendantAtPoint(menu, pX, pY) \
            or script.utilities.descendantAtPoint(window, pX, pY)
        msg = "MOUSE REVIEW: Object at (%i, %i) is %s" % (pX, pY, obj)
        debug.println(debug.LEVEL_INFO, msg, True)

        script = _scriptManager.getScript(window.getApplication(), obj)
        new = _ItemContext(pX, pY, obj, window, script)
        new.present(self._currentMouseOver)
        self._currentMouseOver = new
Beispiel #10
0
    def locusOfFocusChanged(self, event, oldFocus, newFocus):
        """Handles changes of focus of interest to the script."""

        if self.utilities.isToggleDescendantOfComboBox(newFocus):
            isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
            newFocus = pyatspi.findAncestor(newFocus, isComboBox) or newFocus

        super().locusOfFocusChanged(event, oldFocus, newFocus)
Beispiel #11
0
 def _getContainer(self):
     roles = [
         pyatspi.ROLE_DIALOG, pyatspi.ROLE_FRAME, pyatspi.ROLE_LAYERED_PANE,
         pyatspi.ROLE_MENU, pyatspi.ROLE_PAGE_TAB, pyatspi.ROLE_TOOL_BAR,
         pyatspi.ROLE_WINDOW
     ]
     isContainer = lambda x: x and x.getRole() in roles
     return pyatspi.findAncestor(self._obj, isContainer)
Beispiel #12
0
    def _isOrIsIn(self, child, parent):
        if not (child and parent):
            return False

        if child == parent:
            return True

        return pyatspi.findAncestor(child, lambda x: x == parent)
Beispiel #13
0
    def isEntryCompletionPopupItem(self, obj):
        if obj.getRole() == pyatspi.ROLE_TABLE_CELL:
            isWindow = lambda x: x and x.getRole() == pyatspi.ROLE_WINDOW
            window = pyatspi.findAncestor(obj, isWindow)
            if window:
                return True

        return False
Beispiel #14
0
    def isEntryCompletionPopupItem(self, obj):
        if obj.getRole() == pyatspi.ROLE_TABLE_CELL:
            isWindow = lambda x: x and x.getRole() == pyatspi.ROLE_WINDOW
            window = pyatspi.findAncestor(obj, isWindow)
            if window:
                return True

        return False
Beispiel #15
0
    def locusOfFocusChanged(self, event, oldFocus, newFocus):
        """Handles changes of focus of interest to the script."""

        if self.utilities.isToggleDescendantOfComboBox(newFocus):
            isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
            newFocus = pyatspi.findAncestor(newFocus, isComboBox) or newFocus
            orca.setLocusOfFocus(event, newFocus, False)

        super().locusOfFocusChanged(event, oldFocus, newFocus)
Beispiel #16
0
    def _generateRoleName(self, obj, **args):
        """Prevents some roles from being displayed."""

        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateRoleName(obj, **args)

        roledescription = self._script.utilities.getRoleDescription(obj, True)
        if roledescription:
            return [roledescription]

        doNotDisplay = [
            pyatspi.ROLE_FORM, pyatspi.ROLE_PARAGRAPH, pyatspi.ROLE_STATIC,
            pyatspi.ROLE_SECTION, pyatspi.ROLE_REDUNDANT_OBJECT,
            pyatspi.ROLE_UNKNOWN
        ]

        state = obj.getState()
        if not state.contains(pyatspi.STATE_FOCUSABLE):
            doNotDisplay.extend([
                pyatspi.ROLE_LIST, pyatspi.ROLE_LIST_ITEM,
                pyatspi.ROLE_COLUMN_HEADER, pyatspi.ROLE_ROW_HEADER,
                pyatspi.ROLE_TABLE_CELL, pyatspi.ROLE_PANEL
            ])

        if args.get('startOffset') is not None and args.get(
                'endOffset') is not None:
            doNotDisplay.append(pyatspi.ROLE_ALERT)

        result = []
        role = args.get('role', obj.getRole())

        if role == pyatspi.ROLE_HEADING:
            level = self._script.utilities.headingLevel(obj)
            result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level)

        elif self._script.utilities.isLink(
                obj) and obj == orca_state.locusOfFocus:
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)

        elif role not in doNotDisplay:
            label = self._script.utilities.labelForCellCoordinates(obj)
            if label:
                result.append(label)
            else:
                result = super()._generateRoleName(obj, **args)

        index = args.get('index', 0)
        total = args.get('total', 1)
        if index == total - 1 and role != pyatspi.ROLE_HEADING \
           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
            isHeading = lambda x: x and x.getRole() == pyatspi.ROLE_HEADING
            heading = pyatspi.findAncestor(obj, isHeading)
            if heading:
                result.extend(self._generateRoleName(heading))

        return result
Beispiel #17
0
    def isFocusedChat(self, obj):
        """Returns True if we plan to treat this chat as focused."""

        isPageTab = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
        pageTab = pyatspi.findAncestor(obj, isPageTab)
        if pageTab is None:
            return super().isFocusedChat(obj)

        return pageTab.getState().contains(pyatspi.STATE_SHOWING)
Beispiel #18
0
    def _generateListBoxItemWidgets(self, obj, **args):
        # The list which descends from a combobox should be a menu, and its children
        # menuitems. We can remove this once that change is made in Chromium.
        if pyatspi.findAncestor(obj, lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX):
            msg = "CHROMIUM: Not generating listbox item widgets for combobox child %s" % obj
            debug.println(debug.LEVEL_INFO, msg, True)
            return []

        return super()._generateListBoxItemWidgets(obj, **args)
Beispiel #19
0
    def _findErrorWidget(self, root):
        isPanel = lambda x: x and x.getRole() == pyatspi.ROLE_PANEL
        panel = pyatspi.findAncestor(self._changeToEntry, isPanel)
        if not panel:
            return None

        isError = lambda x: x and x.getRole() == pyatspi.ROLE_LABEL \
                  and not ":" in x.name and not x.getRelationSet()
        return pyatspi.findDescendant(panel, isError)
Beispiel #20
0
    def _findErrorWidget(self, root):
        isPanel = lambda x: x and x.getRole() == pyatspi.ROLE_PANEL
        panel = pyatspi.findAncestor(self._changeToEntry, isPanel)
        if not panel:
            return None

        isError = lambda x: x and x.getRole() == pyatspi.ROLE_LABEL \
                  and not ":" in x.name and not x.getRelationSet()
        return pyatspi.findDescendant(panel, isError)
Beispiel #21
0
    def isFocusedChat(self, obj):
        """Returns True if we plan to treat this chat as focused."""

        isPageTab = lambda x: x and x.getRole() == pyatspi.ROLE_PAGE_TAB
        pageTab = pyatspi.findAncestor(obj, isPageTab)
        if pageTab is None:
            return super().isFocusedChat(obj)

        return pageTab.getState().contains(pyatspi.STATE_SHOWING)
Beispiel #22
0
    def onFocus(self, event):
        """Callback for focus: accessibility events."""

        # NOTE: This event type is deprecated and Orca should no longer use it.
        # This callback remains just to handle bugs in applications and toolkits
        # that fail to reliably emit object:state-changed:focused events.

        if self.utilities.eventIsCanvasNoise(event):
            return

        if self.utilities.isLayoutOnly(event.source):
            return

        if event.source == mouse_review.reviewer.getCurrentItem():
            msg = "GTK: Event source is current mouse review item"
            debug.println(debug.LEVEL_INFO, msg, True)
            return

        if self.utilities.isTypeahead(orca_state.locusOfFocus) \
           and "Table" in pyatspi.listInterfaces(event.source) \
           and not event.source.getState().contains(pyatspi.STATE_FOCUSED):
            return

        if "Table" in pyatspi.listInterfaces(event.source):
            selectedChildren = self.utilities.selectedChildren(event.source)
            if selectedChildren:
                orca.setLocusOfFocus(event, selectedChildren[0])
                return

        ancestor = pyatspi.findAncestor(orca_state.locusOfFocus,
                                        lambda x: x == event.source)
        if not ancestor:
            orca.setLocusOfFocus(event, event.source)
            return

        if ancestor and "Table" in pyatspi.listInterfaces(ancestor):
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if isMenu(ancestor) and not pyatspi.findAncestor(ancestor, isMenu):
            return

        orca.setLocusOfFocus(event, event.source)
Beispiel #23
0
 def _getContainer(self):
     roles = [pyatspi.ROLE_DIALOG,
              pyatspi.ROLE_FRAME,
              pyatspi.ROLE_LAYERED_PANE,
              pyatspi.ROLE_MENU,
              pyatspi.ROLE_PAGE_TAB,
              pyatspi.ROLE_TOOL_BAR,
              pyatspi.ROLE_WINDOW]
     isContainer = lambda x: x and x.getRole() in roles
     return pyatspi.findAncestor(self._obj, isContainer)
Beispiel #24
0
 def _get_win(self, event):
     if 'selenium-server/core/Blank.html' in event.source.name:
         frame = pyatspi.findAncestor(
             event.source,
             lambda x: x.getRole() == pyatspi.ROLE_FRAME)
         if frame:
             print 'TOP FRAME:', frame
             pyatspi.Registry.deregisterEventListener(
                 self._get_win, 'document:load-complete')
             self._top_frame = frame
Beispiel #25
0
    def _adjustObject(self, obj):
        """We want to treat text objects inside list items and table cells as
        list items and table cells.
        """

        if obj.getState().contains(pyatspi.STATE_FOCUSED):
            return obj

        roles = [pyatspi.ROLE_TABLE_CELL, pyatspi.ROLE_LIST_ITEM]
        ancestor = pyatspi.findAncestor(obj, lambda x: x and x.getRole() in roles)
        if ancestor and not self._script.utilities.isLayoutOnly(ancestor.parent):
            obj = ancestor
        return obj
Beispiel #26
0
    def _generateTableCellRow(self, obj, **args):
        if not self._script.inFocusMode():
            return super()._generateTableCellRow(obj, **args)

        if not self._script.utilities.shouldReadFullRow(obj):
            return self._generateRealTableCell(obj, **args)

        isRow = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_ROW
        row = pyatspi.findAncestor(obj, isRow)
        if row and row.name:
            return self.generate(row)

        return super()._generateTableCellRow(obj, **args)
    def _generateTableCellRow(self, obj, **args):
        if not self._script.inFocusMode():
            return super()._generateTableCellRow(obj, **args)

        if not self._script.utilities.shouldReadFullRow(obj):
            return self._generateRealTableCell(obj, **args)

        isRow = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_ROW
        row = pyatspi.findAncestor(obj, isRow)
        if row and row.name and not self._script.utilities.isLayoutOnly(row):
            return self.generate(row)

        return super()._generateTableCellRow(obj, **args)
Beispiel #28
0
    def __init__(self, script):
        """Create a new Context for script."""

        self.script = script
        self.zones = []
        self.lines = []
        self.lineIndex = 0
        self.zoneIndex = 0
        self.wordIndex = 0
        self.charIndex = 0
        self.targetCharInfo = None
        self.focusZone = None
        self.container = None
        self.focusObj = orca_state.locusOfFocus
        self.topLevel = script.utilities.topLevelObject(self.focusObj)
        self.bounds = 0, 0, 0, 0

        try:
            component = self.topLevel.queryComponent()
            self.bounds = component.getExtents(pyatspi.DESKTOP_COORDS)
        except:
            msg = "ERROR: Exception getting extents of %s" % self.topLevel
            debug.println(debug.LEVEL_INFO, msg, True)

        containerRoles = [pyatspi.ROLE_MENU]
        isContainer = lambda x: x and x.getRole() in containerRoles
        container = pyatspi.findAncestor(self.focusObj, isContainer)
        if not container and isContainer(self.focusObj):
            container = self.focusObj

        self.container = container or self.topLevel

        self.zones, self.focusZone = self.getShowingZones(self.container)
        self.lines = self.clusterZonesByLine(self.zones)
        if not (self.lines and self.focusZone):
            return

        for i, line in enumerate(self.lines):
            if self.focusZone in line.zones:
                self.lineIndex = i
                self.zoneIndex = line.zones.index(self.focusZone)
                word, offset = self.focusZone.wordWithCaret()
                if word:
                    self.wordIndex = word.index
                    self.charIndex = offset
                break

        msg = "FLAT REVIEW: On line %i, zone %i, word %i, char %i" % \
              (self.lineIndex, self.zoneIndex, self.wordIndex, self.charIndex)
        debug.println(debug.LEVEL_INFO, msg, True)
Beispiel #29
0
    def _generateRoleName(self, obj, **args):
        """Prevents some roles from being displayed."""

        roledescription = self._script.utilities.getRoleDescription(obj)
        if roledescription:
            return [roledescription]

        doNotDisplay = [pyatspi.ROLE_FORM,
                        pyatspi.ROLE_PARAGRAPH,
                        pyatspi.ROLE_STATIC,
                        pyatspi.ROLE_SECTION,
                        pyatspi.ROLE_REDUNDANT_OBJECT,
                        pyatspi.ROLE_UNKNOWN]

        state = obj.getState()
        if not state.contains(pyatspi.STATE_FOCUSABLE):
            doNotDisplay.extend([pyatspi.ROLE_LIST,
                                 pyatspi.ROLE_LIST_ITEM,
                                 pyatspi.ROLE_COLUMN_HEADER,
                                 pyatspi.ROLE_ROW_HEADER,
                                 pyatspi.ROLE_TABLE_CELL,
                                 pyatspi.ROLE_PANEL])

        if args.get('startOffset') is not None and args.get('endOffset') is not None:
            doNotDisplay.append(pyatspi.ROLE_ALERT)

        result = []
        role = args.get('role', obj.getRole())

        if role == pyatspi.ROLE_HEADING:
            level = self._script.utilities.headingLevel(obj)
            result.append(object_properties.ROLE_HEADING_LEVEL_BRAILLE % level)

        elif self._script.utilities.isLink(obj) and obj == orca_state.locusOfFocus:
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)

        elif role not in doNotDisplay:
            result = super()._generateRoleName(obj, **args)

        index = args.get('index', 0)
        total = args.get('total', 1)
        if index == total - 1 and role != pyatspi.ROLE_HEADING \
           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
            isHeading = lambda x: x and x.getRole() == pyatspi.ROLE_HEADING
            heading = pyatspi.findAncestor(obj, isHeading)
            if heading:
                result.extend(self._generateRoleName(heading))

        return result
Beispiel #30
0
    def _adjustObject(self, obj):
        """We want to treat text objects inside list items and table cells as
        list items and table cells.
        """

        if obj.getState().contains(pyatspi.STATE_FOCUSED):
            return obj

        roles = [pyatspi.ROLE_TABLE_CELL, pyatspi.ROLE_LIST_ITEM]
        ancestor = pyatspi.findAncestor(obj,
                                        lambda x: x and x.getRole() in roles)
        if ancestor and not self._script.utilities.isLayoutOnly(
                ancestor.parent):
            obj = ancestor
        return obj
Beispiel #31
0
    def locusOfFocusChanged(self, event, oldFocus, newFocus):
        """Handles changes of focus of interest to the script."""

        if self.utilities.isToggleDescendantOfComboBox(newFocus):
            isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
            newFocus = pyatspi.findAncestor(newFocus, isComboBox) or newFocus
            orca.setLocusOfFocus(event, newFocus, False)
        elif self.utilities.isInOpenMenuBarMenu(newFocus):
            window = self.utilities.topLevelObject(newFocus)
            windowChanged = window and orca_state.activeWindow != window
            if windowChanged:
                orca_state.activeWindow = window
                self.windowActivateTime = time.time()

        super().locusOfFocusChanged(event, oldFocus, newFocus)
Beispiel #32
0
    def onCheckedChanged(self, event):
        """Callback for object:state-changed:checked accessibility events."""

        obj = event.source
        if self.utilities.isSameObject(obj, orca_state.locusOfFocus):
            default.Script.onCheckedChanged(self, event)
            return

        # Present changes of child widgets of GtkListBox items
        isListBox = lambda x: x and x.getRole() == pyatspi.ROLE_LIST_BOX
        if not pyatspi.findAncestor(obj, isListBox):
            return

        self.updateBraille(obj)
        speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
Beispiel #33
0
    def onCheckedChanged(self, event):
        """Callback for object:state-changed:checked accessibility events."""

        obj = event.source
        if self.utilities.isSameObject(obj, orca_state.locusOfFocus):
            default.Script.onCheckedChanged(self, event)
            return

        # Present changes of child widgets of GtkListBox items
        isListBox = lambda x: x and x.getRole() == pyatspi.ROLE_LIST_BOX
        if not pyatspi.findAncestor(obj, isListBox):
            return

        self.updateBraille(obj)
        speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
Beispiel #34
0
    def isToggleDescendantOfComboBox(self, obj):
        if not (obj and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON):
            return False

        rv = self._isToggleDescendantOfComboBox.get(hash(obj))
        if rv is not None:
            return rv

        isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
        comboBox = pyatspi.findAncestor(obj, isComboBox)
        if comboBox:
            self._isComboBoxWithToggleDescendant[hash(comboBox)] = True

        rv = comboBox is not None
        self._isToggleDescendantOfComboBox[hash(obj)] = rv
        return rv
Beispiel #35
0
    def isToggleDescendantOfComboBox(self, obj):
        if not (obj and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON):
            return False

        rv = self._isToggleDescendantOfComboBox.get(hash(obj))
        if rv is not None:
            return rv

        isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
        comboBox = pyatspi.findAncestor(obj, isComboBox)
        if comboBox:
            self._isComboBoxWithToggleDescendant[hash(comboBox)] = True

        rv = comboBox is not None
        self._isToggleDescendantOfComboBox[hash(obj)] = rv
        return rv
Beispiel #36
0
    def unrelatedLabels(self, root, onlyShowing=True, minimumWords=3):
        if not root:
            return []

        roles = [
            pyatspi.ROLE_DIALOG, pyatspi.ROLE_NOTIFICATION,
            pyatspi.ROLE_MENU_ITEM
        ]

        hasRole = lambda x: x and x.getRole() in roles
        if not hasRole(root) and pyatspi.findAncestor(root, hasRole) is None:
            msg = "GNOME SHELL: Not seeking unrelated labels for %s" % root
            debug.println(debug.LEVEL_INFO, msg, True)
            return []

        return super().unrelatedLabels(root, onlyShowing, minimumWords)
Beispiel #37
0
    def locateInputLine(self, obj):
        """Return the spread sheet input line. This only needs to be found
        the very first time a spread sheet table cell gets focus. We use the
        table cell to work back up the component hierarchy until we have found
        the common panel that both it and the input line reside in. We then
        use that as the base component to search for a component which has a
        paragraph role. This will be the input line.

        Arguments:
        - obj: the spread sheet table cell that has just got focus.

        Returns the spread sheet input line component.
        """

        if self._script.inputLineForCell:
            try:
                topLevel = self.topLevelObject(self._script.inputLineForCell)
            except:
                msg = "ERROR: Exception getting topLevelObject for inputline"
                debug.println(debug.LEVEL_INFO, msg, True)
                self._script.inputLineForCell = None
            else:
                if self.isSameObject(orca_state.activeWindow, topLevel):
                    return self._script.inputLineForCell

        isScrollPane = lambda x: x and x.getRole() == pyatspi.ROLE_SCROLL_PANE
        scrollPane = pyatspi.findAncestor(obj, isScrollPane)
        if not scrollPane:
            return None

        toolbar = None
        for child in scrollPane.parent:
            if child and child.getRole() == pyatspi.ROLE_TOOL_BAR:
                toolbar = child
                break

        if not toolbar:
            msg = "ERROR: Calc inputline toolbar not found."
            debug.println(debug.LEVEL_INFO, msg, True)
            return None

        isParagraph = lambda x: x and x.getRole() == pyatspi.ROLE_PARAGRAPH
        allParagraphs = pyatspi.findAllDescendants(toolbar, isParagraph)
        if len(allParagraphs) == 1:
            self._script.inputLineForCell = allParagraphs[0]

        return self._script.inputLineForCell
Beispiel #38
0
    def locateInputLine(self, obj):
        """Return the spread sheet input line. This only needs to be found
        the very first time a spread sheet table cell gets focus. We use the
        table cell to work back up the component hierarchy until we have found
        the common panel that both it and the input line reside in. We then
        use that as the base component to search for a component which has a
        paragraph role. This will be the input line.

        Arguments:
        - obj: the spread sheet table cell that has just got focus.

        Returns the spread sheet input line component.
        """

        if self._script.inputLineForCell:
            try:
                topLevel = self.topLevelObject(self._script.inputLineForCell)
            except:
                msg = "ERROR: Exception getting topLevelObject for inputline"
                debug.println(debug.LEVEL_INFO, msg, True)
                self._script.inputLineForCell = None
            else:
                if self.isSameObject(orca_state.activeWindow, topLevel):
                    return self._script.inputLineForCell

        isScrollPane = lambda x: x and x.getRole() == pyatspi.ROLE_SCROLL_PANE
        scrollPane = pyatspi.findAncestor(obj, isScrollPane)
        if not scrollPane:
            return None

        toolbar = None
        for child in scrollPane.parent:
            if child and child.getRole() == pyatspi.ROLE_TOOL_BAR:
                toolbar = child
                break

        if not toolbar:
            msg = "ERROR: Calc inputline toolbar not found."
            debug.println(debug.LEVEL_INFO, msg, True)
            return None

        isParagraph = lambda x: x and x.getRole() == pyatspi.ROLE_PARAGRAPH
        allParagraphs = pyatspi.findAllDescendants(toolbar, isParagraph)
        if len(allParagraphs) == 1:
            self._script.inputLineForCell = allParagraphs[0]

        return self._script.inputLineForCell
Beispiel #39
0
    def inFindContainer(self, obj=None):
        if not obj:
            obj = orca_state.locusOfFocus

        if not obj or self.inDocumentContent(obj):
            return False

        if obj.getRole() not in [pyatspi.ROLE_ENTRY, pyatspi.ROLE_PUSH_BUTTON]:
            return False

        isDialog = lambda x: x and x.getRole() == pyatspi.ROLE_DIALOG
        result = self.isFindContainer(pyatspi.findAncestor(obj, isDialog))
        if result:
            msg = "CHROMIUM: %s believed to be find-in-page widget" % obj
            debug.println(debug.LEVEL_INFO, msg, True)

        return result
Beispiel #40
0
    def containingComboBox(self, obj):
        isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
        if isComboBox(obj):
            comboBox = obj
        else:
            comboBox = pyatspi.findAncestor(obj, isComboBox)

        if not comboBox:
            return None

        if not self.isZombie(comboBox):
            return comboBox

        try:
            parent = comboBox.parent
        except:
            pass
        else:
            replicant = self.findReplicant(parent, comboBox)
            if replicant and not self.isZombie(replicant):
                comboBox = replicant

        return comboBox
Beispiel #41
0
    def containingComboBox(self, obj):
        isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
        if isComboBox(obj):
            comboBox = obj
        else:
            comboBox = pyatspi.findAncestor(obj, isComboBox)

        if not comboBox:
            return None

        if not self.isZombie(comboBox):
            return comboBox

        try:
            parent = comboBox.parent
        except:
            pass
        else:
            replicant = self.findReplicant(parent, comboBox)
            if replicant and not self.isZombie(replicant):
                comboBox = replicant

        return comboBox
Beispiel #42
0
    def _generateOldAncestors(self, obj, **args):
        """Returns an array of strings (and possibly voice and audio
        specifications) that represent the text of the ancestors for
        the object being left."""

        priorObj = args.get('priorObj', None)
        if not priorObj:
            return []

        if self._script.utilities.isSpreadSheetCell(priorObj):
            return []

        isTable = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE
        oldTable = pyatspi.findAncestor(priorObj, isTable)
        if oldTable:
            ancestor = self._script.utilities.commonAncestor(oldTable, obj)
            if ancestor and ancestor.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
                result = [messages.TABLE_LEAVING]
                result.extend(self.voice(speech_generator.SYSTEM))
                result.extend(self._generatePause(obj, **args))
                return result

        return speech_generator.SpeechGenerator._generateOldAncestors(
            self, obj, **args)
Beispiel #43
0
    def _generateOldAncestors(self, obj, **args):
        """Returns an array of strings (and possibly voice and audio
        specifications) that represent the text of the ancestors for
        the object being left."""

        priorObj = args.get('priorObj', None)
        if not priorObj:
            return []

        if self._script.utilities.isSpreadSheetCell(priorObj):
            return []

        isTable = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE
        oldTable = pyatspi.findAncestor(priorObj, isTable)
        if oldTable:
            ancestor = self._script.utilities.commonAncestor(oldTable, obj)
            if ancestor and ancestor.getRole() == pyatspi.ROLE_DOCUMENT_FRAME:
                result = [messages.TABLE_LEAVING]
                result.extend(self.voice(speech_generator.SYSTEM))
                result.extend(self._generatePause(obj, **args))
                return result

        return speech_generator.SpeechGenerator._generateOldAncestors(
            self, obj, **args)
Beispiel #44
0
    def inFindContainer(self, obj=None):
        if not obj:
            obj = orca_state.locusOfFocus

        if not obj or self.inDocumentContent(obj):
            return False

        if obj.getRole() not in [pyatspi.ROLE_ENTRY, pyatspi.ROLE_PUSH_BUTTON]:
            return False

        isToolbar = lambda x: x and x.getRole() == pyatspi.ROLE_TOOL_BAR
        toolbar = pyatspi.findAncestor(obj, isToolbar)
        result = self.isFindContainer(toolbar)
        if result:
            msg = "GECKO: %s believed to be find-in-page widget (toolbar)" % obj
            debug.println(debug.LEVEL_INFO, msg, True)
            return True

        if self._isQuickFind(toolbar):
            msg = "GECKO: %s believed to be find-in-page widget (quick find)" % obj
            debug.println(debug.LEVEL_INFO, msg, True)
            return True

        return False
Beispiel #45
0
    def inferFromTable(self, obj, proximityForRight=50):
        """Attempt to infer the functional/displayed label of obj by looking
        at the contents of the surrounding table cells. Note that this approach
        assumes a simple table in which the widget is the sole occupant of its
        cell.

        Arguments
        - obj: the unlabeled widget

        Returns the text which we think is the label, or None.
        """

        cell = pyatspi.findAncestor(obj, self._isCell)
        if not self._isSimpleObject(cell):
            return None, []

        if not cell in [obj.parent, obj.parent.parent]:
            return None, []

        grid = pyatspi.findAncestor(cell, self._isTable)
        if not grid:
            return None, []

        cellLeft = cellRight = cellAbove = cellBelow = None
        gridrow = pyatspi.findAncestor(cell, self._isRow)
        rowindex, colindex = self._script.utilities.coordinatesForCell(cell)
        if colindex > -1:
            cellLeft = self._getCellFromTable(grid, rowindex, colindex - 1)
            cellRight = self._getCellFromTable(grid, rowindex, colindex + 1)
            cellAbove = self._getCellFromTable(grid, rowindex - 1, colindex)
            cellBelow = self._getCellFromTable(grid, rowindex + 1, colindex)
        elif gridrow and cell.parent == gridrow:
            cellindex = cell.getIndexInParent()
            cellLeft = self._getCellFromRow(gridrow, cellindex - 1)
            cellRight = self._getCellFromRow(gridrow, cellindex + 1)
            rowindex = gridrow.getIndexInParent()
            if rowindex > 0:
                cellAbove = self._getCellFromRow(gridrow.parent[rowindex - 1],
                                                 cellindex)
            if rowindex + 1 < grid.childCount:
                cellBelow = self._getCellFromRow(gridrow.parent[rowindex + 1],
                                                 cellindex)

        if cellLeft and not self._preferRight(obj):
            label, sources = self._createLabelFromContents(cellLeft)
            if label:
                return label.strip(), sources

        objX, objY, objWidth, objHeight = self._getExtents(obj)

        if cellRight and not self._preventRight(obj):
            x, y, width, height = self._getExtents(cellRight)
            distance = x - (objX + objWidth)
            if distance <= proximityForRight or self._preferRight(obj):
                label, sources = self._createLabelFromContents(cellRight)
                if label:
                    return label.strip(), sources

        labelAbove = labelBelow = None
        if cellAbove:
            labelAbove, sourcesAbove = self._createLabelFromContents(cellAbove)
            if labelAbove and self._preferTop(obj):
                return labelAbove.strip(), sourcesAbove

        if cellBelow and not self._preventBelow(obj):
            labelBelow, sourcesBelow = self._createLabelFromContents(cellBelow)

        if labelAbove and labelBelow:
            aboveX, aboveY, aboveWidth, aboveHeight = self._getExtents(
                cellAbove)
            belowX, belowY, belowWidth, belowHeight = self._getExtents(
                cellBelow)
            dAbove = objY - (aboveY + aboveHeight)
            dBelow = belowY - (objY + objHeight)
            if dAbove <= dBelow:
                return labelAbove.strip(), sourcesAbove
            return labelBelow.strip(), sourcesBelow

        if labelAbove:
            return labelAbove.strip(), sourcesAbove
        if labelBelow:
            return labelBelow.strip(), sourcesBelow

        # None of the cells immediately surrounding this cell seem to be serving
        # as a functional label. Therefore, see if this table looks like a grid
        # of widgets with the functional labels in the first row.

        try:
            table = grid.queryTable()
        except NotImplementedError:
            return None, []

        firstRow = [table.getAccessibleAt(0, i) for i in range(table.nColumns)]
        if not firstRow or list(filter(self._isWidget, firstRow)):
            return None, []

        if colindex < 0:
            return None, []

        cells = [
            table.getAccessibleAt(i, colindex) for i in range(1, table.nRows)
        ]
        cells = [x for x in cells if x is not None]
        if [
                x for x in cells
                if x.childCount and x[0].getRole() != obj.getRole()
        ]:
            return None, []

        label, sources = self._createLabelFromContents(firstRow[colindex])
        if label:
            return label.strip(), sources

        return None, []
Beispiel #46
0
    def _generateRoleName(self, obj, **args):
        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateRoleName(obj, **args)

        result = []
        acss = self.voice(speech_generator.SYSTEM)

        roledescription = self._script.utilities.getRoleDescription(obj)
        if roledescription:
            result = [roledescription]
            result.extend(acss)
            return result

        role = args.get("role", obj.getRole())
        force = args.get("force", False)

        start = args.get("startOffset")
        end = args.get("endOffset")

        if not force:
            doNotSpeak = [
                pyatspi.ROLE_FOOTER,
                pyatspi.ROLE_FORM,
                pyatspi.ROLE_LABEL,
                pyatspi.ROLE_MENU_ITEM,
                pyatspi.ROLE_PARAGRAPH,
                pyatspi.ROLE_SECTION,
                pyatspi.ROLE_UNKNOWN,
            ]
        else:
            doNotSpeak = [pyatspi.ROLE_UNKNOWN]

        if not force:
            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
            doNotSpeak.append(pyatspi.ROLE_TEXT)
            doNotSpeak.append("ROLE_STATIC")
            if args.get("formatType", "unfocused") != "basicWhereAmI":
                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                doNotSpeak.append(pyatspi.ROLE_LIST)
            if start or end:
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_FRAME)
                doNotSpeak.append(pyatspi.ROLE_ALERT)
            if self._script.utilities.isAnchor(obj):
                doNotSpeak.append(obj.getRole())

        if obj.getState().contains(pyatspi.STATE_EDITABLE):
            lastKey, mods = self._script.utilities.lastKeyAndModifiers()
            if ((lastKey in ["Down", "Right"] and not mods) or self._script.inSayAll()) and start:
                return []
            if lastKey in ["Up", "Left"] and not mods:
                text = self._script.utilities.queryNonEmptyText(obj)
                if text and end not in [None, text.characterCount]:
                    return []
            if role not in doNotSpeak:
                result.append(self.getLocalizedRoleName(obj, **args))
                result.extend(acss)

        elif role == pyatspi.ROLE_HEADING:
            level = self._script.utilities.headingLevel(obj)
            if level:
                result.append(
                    object_properties.ROLE_HEADING_LEVEL_SPEECH
                    % {"role": self.getLocalizedRoleName(obj, **args), "level": level}
                )
                result.extend(acss)
            else:
                result.append(self.getLocalizedRoleName(obj, **args))
                result.extend(acss)

        elif self._script.utilities.isLink(obj):
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)
                result.extend(acss)
            else:
                if self._script.utilities.hasUselessCanvasDescendant(obj):
                    result.append(self.getLocalizedRoleName(obj, role=pyatspi.ROLE_IMAGE))
                    result.extend(acss)
                result.append(self.getLocalizedRoleName(obj, **args))
                result.extend(acss)

        elif role not in doNotSpeak:
            result.append(self.getLocalizedRoleName(obj, **args))
            result.extend(acss)

        index = args.get("index", 0)
        total = args.get("total", 1)
        ancestorRoles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK]
        if index == total - 1 and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
            speakRoles = lambda x: x and x.getRole() in ancestorRoles
            ancestor = pyatspi.findAncestor(obj, speakRoles)
            if ancestor and ancestor.getRole() != role:
                result.extend(self._generateRoleName(ancestor))

        return result
    def _generateRoleName(self, obj, **args):
        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateRoleName(obj, **args)

        result = []
        acss = self.voice(speech_generator.SYSTEM)

        roledescription = self._script.utilities.getRoleDescription(obj)
        if roledescription:
            result = [roledescription]
            result.extend(acss)
            return result

        role = args.get('role', obj.getRole())
        enabled, disabled = self._getEnabledAndDisabledContextRoles()
        if role in disabled:
            return []

        force = args.get('force', False)
        start = args.get('startOffset')
        end = args.get('endOffset')
        index = args.get('index', 0)
        total = args.get('total', 1)

        if not force:
            doNotSpeak = [
                pyatspi.ROLE_FOOTER, pyatspi.ROLE_FORM, pyatspi.ROLE_LABEL,
                pyatspi.ROLE_MENU_ITEM, pyatspi.ROLE_PARAGRAPH,
                pyatspi.ROLE_SECTION, pyatspi.ROLE_REDUNDANT_OBJECT,
                pyatspi.ROLE_UNKNOWN
            ]
        else:
            doNotSpeak = [pyatspi.ROLE_UNKNOWN]

        if not force:
            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
            doNotSpeak.append(pyatspi.ROLE_TEXT)
            doNotSpeak.append(pyatspi.ROLE_STATIC)
            if args.get('formatType', 'unfocused') != 'basicWhereAmI':
                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                doNotSpeak.append(pyatspi.ROLE_LIST)
            if (start or end):
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_FRAME)
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_WEB)
                doNotSpeak.append(pyatspi.ROLE_ALERT)
            if self._script.utilities.isAnchor(obj):
                doNotSpeak.append(obj.getRole())
            if total > 1:
                doNotSpeak.append(pyatspi.ROLE_ROW_HEADER)
            if self._script.utilities.isMenuInCollapsedSelectElement(obj):
                doNotSpeak.append(pyatspi.ROLE_MENU)

        if obj.getState().contains(pyatspi.STATE_EDITABLE):
            lastKey, mods = self._script.utilities.lastKeyAndModifiers()
            if ((lastKey in ["Down", "Right"] and not mods)
                    or self._script.inSayAll()) and start:
                return []
            if lastKey in ["Up", "Left"] and not mods:
                text = self._script.utilities.queryNonEmptyText(obj)
                if text and end not in [None, text.characterCount]:
                    return []
            if role in [
                    pyatspi.ROLE_ENTRY, pyatspi.ROLE_PASSWORD_TEXT,
                    pyatspi.ROLE_SPIN_BUTTON
            ]:
                result.append(self.getLocalizedRoleName(obj, **args))
            elif obj.parent and not obj.parent.getState().contains(
                    pyatspi.STATE_EDITABLE):
                if lastKey not in [
                        "Home", "End", "Up", "Down", "Left", "Right",
                        "Page_Up", "Page_Down"
                ]:
                    result.append(object_properties.ROLE_EDITABLE_CONTENT)
            elif role not in doNotSpeak:
                result.append(self.getLocalizedRoleName(obj, **args))
            if result:
                result.extend(acss)

        elif role == pyatspi.ROLE_HEADING:
            if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(
                    obj):
                level = self._script.utilities.headingLevel(obj)
                if level:
                    result.append(
                        object_properties.ROLE_HEADING_LEVEL_SPEECH % {
                            'role': self.getLocalizedRoleName(obj, **args),
                            'level': level
                        })
                    result.extend(acss)
                else:
                    result.append(self.getLocalizedRoleName(obj, **args))
                    result.extend(acss)

        elif self._script.utilities.isLink(obj):
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)
                result.extend(acss)
            else:
                if self._script.utilities.hasUselessCanvasDescendant(obj):
                    result.append(
                        self.getLocalizedRoleName(obj,
                                                  role=pyatspi.ROLE_IMAGE))
                    result.extend(acss)
                if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(
                        obj):
                    result.append(self.getLocalizedRoleName(obj, **args))
                    result.extend(acss)

        elif role == pyatspi.ROLE_COMMENT:
            if index == 0:
                result.append(self.getLocalizedRoleName(obj, **args))
                result.extend(acss)

        elif role not in doNotSpeak and args.get('priorObj') != obj:
            result.append(self.getLocalizedRoleName(obj, **args))
            result.extend(acss)

        if self._script.utilities.isMath(
                obj) and not self._script.utilities.isMathTopLevel(obj):
            return result

        ancestorRoles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK]
        speakRoles = lambda x: x and x.getRole() in ancestorRoles
        ancestor = pyatspi.findAncestor(obj, speakRoles)
        if ancestor and ancestor.getRole() != role and (
                index == total - 1 or obj.name == ancestor.name):
            result.extend(self._generateRoleName(ancestor))

        return result
Beispiel #48
0
    def _generateRoleName(self, obj, **args):
        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateRoleName(obj, **args)

        result = []
        acss = self.voice(speech_generator.SYSTEM)

        roledescription = self._script.utilities.getRoleDescription(obj)
        if roledescription:
            result = [roledescription]
            result.extend(acss)
            return result

        role = args.get('role', obj.getRole())
        enabled, disabled = self._getEnabledAndDisabledContextRoles()
        if role in disabled:
            return []

        force = args.get('force', False)
        start = args.get('startOffset')
        end = args.get('endOffset')
        index = args.get('index', 0)
        total = args.get('total', 1)

        if not force:
            doNotSpeak = [pyatspi.ROLE_FOOTER,
                          pyatspi.ROLE_FORM,
                          pyatspi.ROLE_LABEL,
                          pyatspi.ROLE_MENU_ITEM,
                          pyatspi.ROLE_PARAGRAPH,
                          pyatspi.ROLE_SECTION,
                          pyatspi.ROLE_REDUNDANT_OBJECT,
                          pyatspi.ROLE_UNKNOWN]
        else:
            doNotSpeak = [pyatspi.ROLE_UNKNOWN]

        if not force:
            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
            doNotSpeak.append(pyatspi.ROLE_TEXT)
            doNotSpeak.append(pyatspi.ROLE_STATIC)
            if args.get('formatType', 'unfocused') != 'basicWhereAmI':
                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                doNotSpeak.append(pyatspi.ROLE_LIST)
            if (start or end):
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_FRAME)
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_WEB)
                doNotSpeak.append(pyatspi.ROLE_ALERT)
            if self._script.utilities.isAnchor(obj):
                doNotSpeak.append(obj.getRole())
            if total > 1:
                doNotSpeak.append(pyatspi.ROLE_ROW_HEADER)

        if obj.getState().contains(pyatspi.STATE_EDITABLE):
            lastKey, mods = self._script.utilities.lastKeyAndModifiers()
            if ((lastKey in ["Down", "Right"] and not mods) or self._script.inSayAll()) and start:
                return []
            if lastKey in ["Up", "Left"] and not mods:
                text = self._script.utilities.queryNonEmptyText(obj)
                if text and end not in [None, text.characterCount]:
                    return []
            if role in [pyatspi.ROLE_ENTRY, pyatspi.ROLE_PASSWORD_TEXT, pyatspi.ROLE_SPIN_BUTTON]:
                result.append(self.getLocalizedRoleName(obj, **args))
            elif obj.parent and not obj.parent.getState().contains(pyatspi.STATE_EDITABLE):
                if lastKey not in ["Home", "End", "Up", "Down", "Left", "Right", "Page_Up", "Page_Down"]:
                    result.append(object_properties.ROLE_EDITABLE_CONTENT)
            elif role not in doNotSpeak:
                result.append(self.getLocalizedRoleName(obj, **args))
            if result:
                result.extend(acss)

        elif role == pyatspi.ROLE_HEADING:
            if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(obj):
                level = self._script.utilities.headingLevel(obj)
                if level:
                    result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % {
                        'role': self.getLocalizedRoleName(obj, **args),
                        'level': level})
                    result.extend(acss)
                else:
                    result.append(self.getLocalizedRoleName(obj, **args))
                    result.extend(acss)

        elif self._script.utilities.isLink(obj):
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)
                result.extend(acss)
            else:
                if self._script.utilities.hasUselessCanvasDescendant(obj):
                    result.append(self.getLocalizedRoleName(obj, role=pyatspi.ROLE_IMAGE))
                    result.extend(acss)
                if index == total - 1 or not self._script.utilities.isFocusableWithMathChild(obj):
                    result.append(self.getLocalizedRoleName(obj, **args))
                    result.extend(acss)

        elif role == pyatspi.ROLE_COMMENT:
            if index == 0:
                result.append(self.getLocalizedRoleName(obj, **args))
                result.extend(acss)

        elif role not in doNotSpeak and args.get('priorObj') != obj:
            result.append(self.getLocalizedRoleName(obj, **args))
            result.extend(acss)

        if self._script.utilities.isMath(obj) and not self._script.utilities.isMathTopLevel(obj):
            return result

        ancestorRoles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK]
        if index == total - 1 \
           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
            speakRoles = lambda x: x and x.getRole() in ancestorRoles
            ancestor = pyatspi.findAncestor(obj, speakRoles)
            if ancestor and ancestor.getRole() != role:
                result.extend(self._generateRoleName(ancestor))

        return result
Beispiel #49
0
    def _on_mouse_moved(self, event):
        """Callback for mouse:abs events."""

        screen, pX, pY = self._pointer.get_position()
        window = self._accessible_window_at_point(pX, pY)
        msg = "MOUSE REVIEW: Window at (%i, %i) is %s" % (pX, pY, window)
        debug.println(debug.LEVEL_INFO, msg, True)
        if not window:
            return

        script = orca_state.activeScript
        if not script:
            return

        isMenu = lambda x: x and x.getRole() == pyatspi.ROLE_MENU
        if script.utilities.isDead(orca_state.locusOfFocus):
            menu = None
        elif isMenu(orca_state.locusOfFocus):
            menu = orca_state.locusOfFocus
        else:
            try:
                menu = pyatspi.findAncestor(orca_state.locusOfFocus, isMenu)
            except:
                msg = "ERROR: Exception getting ancestor of %s" % orca_state.locusOfFocus
                debug.println(debug.LEVEL_INFO, msg, True)
                menu = None

        document = None
        if script.utilities.inDocumentContent():
            document = script.utilities.activeDocument()

        obj = script.utilities.descendantAtPoint(menu, pX, pY) \
            or script.utilities.descendantAtPoint(document, pX, pY) \
            or script.utilities.descendantAtPoint(window, pX, pY)
        msg = "MOUSE REVIEW: Object at (%i, %i) is %s" % (pX, pY, obj)
        debug.println(debug.LEVEL_INFO, msg, True)

        script = _scriptManager.getScript(window.getApplication(), obj)
        if menu and obj and not pyatspi.findAncestor(obj, isMenu):
            if script.utilities.intersectingRegion(obj, menu) != (0, 0, 0, 0):
                msg = "MOUSE REVIEW: %s believed to be under %s" % (obj, menu)
                debug.println(debug.LEVEL_INFO, msg, True)
                return

        if document and obj and document != script.utilities.getContainingDocument(
                obj):
            msg = "MOUSE REVIEW: %s is not in active document %s" % (obj,
                                                                     document)
            debug.println(debug.LEVEL_INFO, msg, True)
            return

        if obj and obj.getRole() in script.utilities.getCellRoles() \
           and script.utilities.shouldReadFullRow(obj):
            isRow = lambda x: x and x.getRole() == pyatspi.ROLE_TABLE_ROW
            obj = pyatspi.findAncestor(obj, isRow) or obj

        screen, nowX, nowY = self._pointer.get_position()
        if (pX, pY) != (nowX, nowY):
            msg = "MOUSE REVIEW: Pointer moved again: (%i, %i)" % (nowX, nowY)
            debug.println(debug.LEVEL_INFO, msg, True)
            return

        boundary = None
        x, y, width, height = self._currentMouseOver.getBoundingBox()
        if y <= pY <= y + height and self._currentMouseOver.getString():
            boundary = pyatspi.TEXT_BOUNDARY_WORD_START
        elif obj == self._currentMouseOver.getObject():
            boundary = pyatspi.TEXT_BOUNDARY_LINE_START
        elif obj and obj.getState().contains(pyatspi.STATE_SELECTABLE):
            boundary = pyatspi.TEXT_BOUNDARY_LINE_START

        new = _ItemContext(pX, pY, obj, boundary, window, script)
        if new.present(self._currentMouseOver):
            self._currentMouseOver = new
Beispiel #50
0
 def _is_in_frame(self, event):
     try:
         return pyatspi.findAncestor(
             event.source, lambda x: x == self._top_frame)
     except:
         return None
Beispiel #51
0
    def _generateRoleName(self, obj, **args):
        if not self._script.utilities.inDocumentContent(obj):
            return super()._generateRoleName(obj, **args)

        result = []
        acss = self.voice(speech_generator.SYSTEM)

        roledescription = self._script.utilities.getRoleDescription(obj)
        if roledescription:
            result = [roledescription]
            result.extend(acss)
            return result

        role = args.get('role', obj.getRole())
        force = args.get('force', False)

        start = args.get('startOffset')
        end = args.get('endOffset')

        if not force:
            doNotSpeak = [pyatspi.ROLE_FOOTER,
                          pyatspi.ROLE_FORM,
                          pyatspi.ROLE_LABEL,
                          pyatspi.ROLE_MENU_ITEM,
                          pyatspi.ROLE_PARAGRAPH,
                          pyatspi.ROLE_SECTION,
                          pyatspi.ROLE_UNKNOWN]
        else:
            doNotSpeak = [pyatspi.ROLE_UNKNOWN]

        if not force:
            doNotSpeak.append(pyatspi.ROLE_TABLE_CELL)
            doNotSpeak.append(pyatspi.ROLE_TEXT)
            doNotSpeak.append('ROLE_STATIC')
            if args.get('formatType', 'unfocused') != 'basicWhereAmI':
                doNotSpeak.append(pyatspi.ROLE_LIST_ITEM)
                doNotSpeak.append(pyatspi.ROLE_LIST)
            if (start or end):
                doNotSpeak.append(pyatspi.ROLE_DOCUMENT_FRAME)
                doNotSpeak.append(pyatspi.ROLE_ALERT)

        if obj.getState().contains(pyatspi.STATE_EDITABLE):
            lastKey, mods = self._script.utilities.lastKeyAndModifiers()
            if ((lastKey in ["Down", "Right"] and not mods) or self._script.inSayAll()) and start:
                return []
            if lastKey in ["Up", "Left"] and not mods:
                text = self._script.utilities.queryNonEmptyText(obj)
                if text and end not in [None, text.characterCount]:
                    return []
            if role not in doNotSpeak:
                result.append(self.getLocalizedRoleName(obj, role))
                result.extend(acss)

        elif role == pyatspi.ROLE_HEADING:
            level = self._script.utilities.headingLevel(obj)
            if level:
                result.append(object_properties.ROLE_HEADING_LEVEL_SPEECH % {
                    'role': self.getLocalizedRoleName(obj, role),
                    'level': level})
                result.extend(acss)
            else:
                result.append(self.getLocalizedRoleName(obj, role))
                result.extend(acss)

        elif role == pyatspi.ROLE_LINK:
            if obj.parent.getRole() == pyatspi.ROLE_IMAGE:
                result.append(messages.IMAGE_MAP_LINK)
                result.extend(acss)
            else:
                if self._script.utilities.hasUselessCanvasDescendant(obj):
                    result.append(self.getLocalizedRoleName(obj, pyatspi.ROLE_IMAGE))
                    result.extend(acss)
                result.append(self.getLocalizedRoleName(obj, role))
                result.extend(acss)

        elif role not in doNotSpeak:
            result.append(self.getLocalizedRoleName(obj, role))
            result.extend(acss)

        index = args.get('index', 0)
        total = args.get('total', 1)
        ancestorRoles = [pyatspi.ROLE_HEADING, pyatspi.ROLE_LINK]
        if index == total - 1 \
           and (role == pyatspi.ROLE_IMAGE or self._script.utilities.queryNonEmptyText(obj)):
            speakRoles = lambda x: x and x.getRole() in ancestorRoles
            ancestor = pyatspi.findAncestor(obj, speakRoles)
            if ancestor and ancestor.getRole() != role:
                result.extend(self._generateRoleName(ancestor))

        return result
 def isSeekSlider(self, obj):
     return bool(pyatspi.findAncestor(
             obj, lambda x: x.getRole() == pyatspi.ROLE_TOOL_BAR))