コード例 #1
0
ファイル: script.py プロジェクト: GNOME/orca
    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)
コード例 #2
0
ファイル: script.py プロジェクト: hgneng/orca
    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)
コード例 #3
0
ファイル: script.py プロジェクト: RKelson93/orca
    def onSelectedChanged(self, event):
        """Callback for object:state-changed:selected accessibility events."""

        if event.source.getRole() == pyatspi.ROLE_PAGE_TAB and event.detail1:
            oldName = event.source.name
            event.source.clearCache()
            newName = event.source.name
            if oldName != newName:
                msg = "CHROMIUM: NO NAME CHANGE HACK: (name should be: '%s')" % newName
                debug.println(debug.LEVEL_INFO, msg, True)

        # Other apps and toolkits implement the selection interface, which is
        # what we use to present active-descendanty selection changes, leaving
        # state-changed:selected for notifications related to toggling the
        # selected state of the currently-focused item (e.g. pressing ctrl+space
        # in a file explorer). While handling active-descendanty changes here is
        # not technically a HACK, once Chromium implements the selection interface,
        # we should remove this code and defer to Orca's default handling.
        if event.detail1 and not self.utilities.isLayoutOnly(event.source) \
           and not "Selection" in pyatspi.listInterfaces(event.source.parent) \
           and self.utilities.canBeActiveWindow(self.utilities.topLevelObject(event.source)):
            msg = "CHROMIUM: NO SELECTION IFACE HACK: Setting %s to locusOfFocus" % event.source
            debug.println(debug.LEVEL_INFO, msg, True)
            orca.setLocusOfFocus(event, event.source)
            return

        if super().onSelectedChanged(event):
            return

        msg = "CHROMIUM: Passing along event to default script"
        debug.println(debug.LEVEL_INFO, msg, True)
        default.Script.onSelectedChanged(self, event)
コード例 #4
0
    def selectedChildren(self, obj):
        if not obj:
            return []

        role = obj.getRole()
        isSelection = lambda x: x and 'Selection' in pyatspi.listInterfaces(x)
        if not isSelection(obj) and role == pyatspi.ROLE_COMBO_BOX:
            child = pyatspi.findDescendant(obj, isSelection)
            if child:
                return super().selectedChildren(child)

        # Things only seem broken for certain tables, e.g. the Paths table.
        # TODO - JD: File the LibreOffice bugs and reference them here.
        if role != pyatspi.ROLE_TABLE or self.isSpreadSheetTable(obj):
            return super().selectedChildren(obj)

        try:
            selection = obj.querySelection()
        except:
            return []

        children = []
        for i, child in enumerate(obj):
            if selection.isChildSelected(i):
                children.append(obj[i])

        return children
コード例 #5
0
ファイル: generic.py プロジェクト: eeejay/ldtp2
    def imagecapture(self, winName = None, resolution1 = None,
                     resolution2 = None, x = 0, y = 0):
        if winName:
            acc = None
            for gui in self._list_guis():
                if self._match_name_to_acc(winName, gui):
                    if 'Component' in pyatspi.listInterfaces(gui):
                        acc = gui
                        break
            if not acc:
                raise LdtpServerException('No window matches %s' % winName)
            icomponent = acc.queryComponent()
            bb = icomponent.getExtents(pyatspi.DESKTOP_COORDS)
            x, y, resolution2, resolution1 = bb.x, bb.y, bb.height, bb.width

        window = gtk.gdk.get_default_root_window ()
        size = window.get_size ()
        pb = gtk.gdk.Pixbuf (gtk.gdk.COLORSPACE_RGB, False, 8, 
                             resolution1 or size [0], 
                             resolution2 or size [1])
        pb = pb.get_from_drawable (window, window.get_colormap (),
                                   x, y, 0, 0, 
                                   resolution1 or size [0], 
                                   resolution2 or size [1])

        if pb:
            tmpFile = tempfile.mktemp('.png', 'ldtpd_')
            pb.save(tmpFile, 'png')
            del pb
            gc.collect()
        rv = b64encode(open(tmpFile).read())
        os.remove(tmpFile)
        return rv
コード例 #6
0
ファイル: script_utilities.py プロジェクト: GNOME/orca
    def handleRowAndColumnSelectionChange(self, obj):
        interfaces = pyatspi.listInterfaces(obj)
        if not ("Table" in interfaces and "Selection" in interfaces):
            return True

        table = obj.queryTable()
        cols = set(table.getSelectedColumns())
        rows = set(table.getSelectedRows())

        selectedCols = sorted(cols.difference(set(self._calcSelectedColumns)))
        unselectedCols = sorted(set(self._calcSelectedColumns).difference(cols))
        convert = lambda x: self.columnConvert(x+1)
        selectedCols = list(map(convert, selectedCols))
        unselectedCols = list(map(convert, unselectedCols))

        selectedRows = sorted(rows.difference(set(self._calcSelectedRows)))
        unselectedRows = sorted(set(self._calcSelectedRows).difference(rows))
        convert = lambda x: x + 1
        selectedRows = list(map(convert, selectedRows))
        unselectedRows = list(map(convert, unselectedRows))

        self._calcSelectedColumns = list(cols)
        self._calcSelectedRows = list(rows)

        if len(cols) == table.nColumns:
            self._script.speakMessage(messages.DOCUMENT_SELECTED_ALL)
            return True

        if not len(cols) and len(unselectedCols) == table.nColumns:
            self._script.speakMessage(messages.DOCUMENT_UNSELECTED_ALL)
            return True

        msgs = []
        if len(unselectedCols) == 1:
            msgs.append(messages.TABLE_COLUMN_UNSELECTED % unselectedCols[0])
        elif len(unselectedCols) > 1:
            msgs.append(messages.TABLE_COLUMN_RANGE_UNSELECTED % (unselectedCols[0], unselectedCols[-1]))

        if len(unselectedRows) == 1:
            msgs.append(messages.TABLE_ROW_UNSELECTED % unselectedRows[0])
        elif len(unselectedRows) > 1:
            msgs.append(messages.TABLE_ROW_RANGE_UNSELECTED % (unselectedRows[0], unselectedRows[-1]))

        if len(selectedCols) == 1:
            msgs.append(messages.TABLE_COLUMN_SELECTED % selectedCols[0])
        elif len(selectedCols) > 1:
            msgs.append(messages.TABLE_COLUMN_RANGE_SELECTED % (selectedCols[0], selectedCols[-1]))

        if len(selectedRows) == 1:
            msgs.append(messages.TABLE_ROW_SELECTED % selectedRows[0])
        elif len(selectedRows) > 1:
            msgs.append(messages.TABLE_ROW_RANGE_SELECTED % (selectedRows[0], selectedRows[-1]))

        if msgs:
            self._script.presentationInterrupt()

        for msg in msgs:
            self._script.speakMessage(msg, interrupt=False)

        return bool(len(msgs))
コード例 #7
0
    def selectedChildren(self, obj):
        if not obj:
            return []

        role = obj.getRole()
        isSelection = lambda x: x and 'Selection' in pyatspi.listInterfaces(x)
        if not isSelection(obj) and role == pyatspi.ROLE_COMBO_BOX:
            child = pyatspi.findDescendant(obj, isSelection)
            if child:
                return super().selectedChildren(child)

        # Things only seem broken for certain tables, e.g. the Paths table.
        # TODO - JD: File the LibreOffice bugs and reference them here.
        if role != pyatspi.ROLE_TABLE or self.isSpreadSheetCell(obj):
            return super().selectedChildren(obj)

        try:
            selection = obj.querySelection()
        except:
            return []

        children = []
        for i, child in enumerate(obj):
            if selection.isChildSelected(i):
                children.append(obj[i])

        return children
コード例 #8
0
    def treatAsEntry(self, obj):
        if not obj or self.inDocumentContent(obj):
            return super().treatAsEntry(obj)

        # Firefox seems to have turned its accessible location widget into a
        # childless editable combobox.

        try:
            role = obj.getRole()
            state = obj.getState()
            childCount = obj.childCount
        except:
            msg = "GECKO: Exception getting role, state, and child count for %s" % obj
            debug.println(debug.LEVEL_INFO, msg, True)
            return False

        if role != pyatspi.ROLE_COMBO_BOX:
            return False

        if not state.contains(pyatspi.STATE_FOCUSED):
            return False

        if childCount:
            return False

        if not "EditableText" in pyatspi.listInterfaces(obj):
            return False

        msg = "GECKO: Treating %s as entry" % obj
        debug.println(debug.LEVEL_INFO, msg, True)
        return True
コード例 #9
0
def _obscuringBanner(obj):
    document = _containingDocument(obj)
    if not document:
        msg = "EVENT SYNTHESIZER: No obscuring banner found for %s. No document." % obj
        debug.println(debug.LEVEL_INFO, msg, True)
        return None

    if not "Component" in pyatspi.listInterfaces(document):
        msg = "EVENT SYNTHESIZER: No obscuring banner found for %s. No doc iface." % obj
        debug.println(debug.LEVEL_INFO, msg, True)
        return None

    objX, objY, objWidth, objHeight = _objectExtents(obj)
    docX, docY, docWidth, docHeight = _objectExtents(document)

    left = _getAccessibleAtPoint(document, docX, objY)
    right = _getAccessibleAtPoint(document, docX + docWidth, objY)
    if not (left and right and left == right != document):
        msg = "EVENT SYNTHESIZER: No obscuring banner found for %s" % obj
        debug.println(debug.LEVEL_INFO, msg, True)
        return None

    msg = "EVENT SYNTHESIZER: %s believed to be obscured by banner %s" % (obj, left)
    debug.println(debug.LEVEL_INFO, msg, True)
    return left
コード例 #10
0
    def selectedChildren(self, obj):
        if not obj:
            return []

        role = obj.getRole()
        isSelection = lambda x: x and 'Selection' in pyatspi.listInterfaces(x)
        if not isSelection(obj) and role == pyatspi.ROLE_COMBO_BOX:
            child = pyatspi.findDescendant(obj, isSelection)
            if child:
                return super().selectedChildren(child)

        # Things only seem broken for certain tables, e.g. the Paths table.
        # TODO - JD: File the LibreOffice bugs and reference them here.
        if role != pyatspi.ROLE_TABLE:
            return super().selectedChildren(obj)

        # We will need to special case this due to the possibility of there
        # being lots of children (which may also prove to be zombie objects).
        # This is why we can't have nice things.
        if self.isSpreadSheetTable(obj):
            return []

        try:
            selection = obj.querySelection()
        except:
            return []

        children = []
        for i, child in enumerate(obj):
            if selection.isChildSelected(i):
                children.append(obj[i])

        return children
コード例 #11
0
ファイル: mouse_review.py プロジェクト: GNOME/orca
    def _treatAsSingleObject(self):
        interfaces = pyatspi.listInterfaces(self._obj)
        if "Text" not in interfaces:
            return True

        roles = [pyatspi.ROLE_ENTRY,
                 pyatspi.ROLE_LABEL,
                 pyatspi.ROLE_PASSWORD_TEXT]

        if self._obj.getRole() in roles:
            return True

        if self._obj.name and not "EditableText" in pyatspi.listInterfaces(self._obj):
            return True

        return False
コード例 #12
0
    def _treatAsSingleObject(self):
        interfaces = pyatspi.listInterfaces(self._obj)
        if "Text" not in interfaces:
            return True

        roles = [
            pyatspi.ROLE_ENTRY, pyatspi.ROLE_LABEL, pyatspi.ROLE_PASSWORD_TEXT
        ]

        if self._obj.getRole() in roles:
            return True

        if self._obj.name and not "EditableText" in pyatspi.listInterfaces(
                self._obj):
            return True

        return False
コード例 #13
0
    def _getCoordinatesForSelectedRange(self, obj):
        interfaces = pyatspi.listInterfaces(obj)
        if not ("Table" in interfaces and "Selection" in interfaces):
            return (-1, -1), (-1, -1)

        first, last = self.firstAndLastSelectedChildren(obj)
        firstCoords = self.coordinatesForCell(first)
        lastCoords = self.coordinatesForCell(last)
        return firstCoords, lastCoords
コード例 #14
0
ファイル: braille_generator.py プロジェクト: GNOME/orca
    def _generateLabelAndName(self, obj, **args):
        if self._script.utilities.isTextBlockElement(obj):
            return []

        role = args.get('role', obj.getRole())
        if role == pyatspi.ROLE_LABEL and 'Text' in pyatspi.listInterfaces(obj):
            return []

        return super()._generateLabelAndName(obj, **args)
コード例 #15
0
ファイル: mouse_review.py プロジェクト: aminba90/PythonCourse
    def _treatAsSingleObject(self):
        interfaces = pyatspi.listInterfaces(self._obj)
        if "Text" not in interfaces:
            return True

        if not self._obj.queryText().characterCount:
            return True

        return False
コード例 #16
0
    def _generateLabelAndName(self, obj, **args):
        if self._script.utilities.isTextBlockElement(obj):
            return []

        role = args.get('role', obj.getRole())
        if role == pyatspi.ROLE_LABEL and 'Text' in pyatspi.listInterfaces(obj):
            return []

        return super()._generateLabelAndName(obj, **args)
コード例 #17
0
ファイル: script_utilities.py プロジェクト: GNOME/orca
    def _getCoordinatesForSelectedRange(self, obj):
        interfaces = pyatspi.listInterfaces(obj)
        if not ("Table" in interfaces and "Selection" in interfaces):
            return (-1, -1), (-1, -1)

        first, last = self.firstAndLastSelectedChildren(obj)
        firstCoords = self.coordinatesForCell(first)
        lastCoords = self.coordinatesForCell(last)
        return firstCoords, lastCoords
コード例 #18
0
ファイル: script.py プロジェクト: isabella232/orca-1
    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)
コード例 #19
0
    def _getCellFromTable(self, table, rowindex, colindex):
        if "Table" not in pyatspi.listInterfaces(table):
            return NOne

        if rowindex < 0 or colindex < 0:
            return None

        iface = table.queryTable()
        if rowindex >= iface.nRows or colindex >= iface.nColumns:
            return None

        return table.queryTable().getAccessibleAt(rowindex, colindex)
コード例 #20
0
    def selectedChildren(self, obj):
        result = super().selectedChildren(obj)
        if result or "Selection" in pyatspi.listInterfaces(obj):
            return result

        # HACK: Ideally, we'd use the selection interface to get the selected
        # children. But that interface is not implemented yet. This hackaround
        # is extremely non-performant.
        for child in obj:
            if child.getState().contains(pyatspi.STATE_SELECTED):
                result.append(child)

        return result
コード例 #21
0
 def onAccChanged(self, acc):
     '''
 Update the UI when the selected accessible changes.
 
 @param acc: The applications-wide selected accessible.
 @type acc: Accessibility.Accessible
 '''
     self.acc = acc
     ints = pyatspi.listInterfaces(acc)
     model = self.iface_combo.get_model()
     model.clear()
     for iface in ints:
         self.iface_combo.append_text(iface)
     self.iface_combo.set_active(0)
コード例 #22
0
ファイル: api_view.py プロジェクト: alibezz/accerciser-mirror
 def onAccChanged(self, acc):
   '''
   Update the UI when the selected accessible changes.
   
   @param acc: The applications-wide selected accessible.
   @type acc: Accessibility.Accessible
   '''
   self.acc = acc
   ints = pyatspi.listInterfaces(acc)
   model = self.iface_combo.get_model()
   model.clear()
   for iface in ints:
     self.iface_combo.append_text(iface)
   self.iface_combo.set_active(0)
コード例 #23
0
    def selectedChildCount(self, obj):
        count = super().selectedChildCount(obj)
        if count or "Selection" in pyatspi.listInterfaces(obj):
            return count

        # HACK: Ideally, we'd use the selection interface to get the selected
        # child count. But that interface is not implemented yet. This hackaround
        # is extremely non-performant.
        for child in obj:
            if child.getState().contains(pyatspi.STATE_SELECTED):
                count += 1

        msg = "CHROMIUM: NO SELECTION INTERFACE HACK: Selected children: %i" % count
        debug.println(debug.LEVEL_INFO, msg, True)
        return count
コード例 #24
0
    def assertInterfaces(self, control, expected_ifaces):
        """
        Ensure that only the expected interfaces are present.  Fail otherwise.
        """
        ifaces = pyatspi.listInterfaces(control._accessible)

        ifaces = map(unicode.lower, ifaces)
        expected_ifaces = map(str.lower, expected_ifaces)

        for iface in ifaces:
            if iface in expected_ifaces:
                expected_ifaces.remove(iface)
            else:
                self.fail("Unexpected interface: %s" % iface)
        self.assertEqual(0, len(expected_ifaces), \
                         "Some interfaces are not implemented: %s" % expected_ifaces)
コード例 #25
0
ファイル: braille_generator.py プロジェクト: rathovarun/orca
    def _generateFocusedItem(self, obj, **args):
        result = []
        role = args.get('role', obj.getRole())
        if role not in [pyatspi.ROLE_LIST, pyatspi.ROLE_LIST_BOX]:
            return result

        if 'Selection' in pyatspi.listInterfaces(obj):
            items = self._script.utilities.selectedChildren(obj)
        else:
            items = [self._script.utilities.focusedChild(obj)]
        if not (items and items[0]):
            return result

        for item in map(self._generateName, items):
            result.extend(item)

        return result
コード例 #26
0
ファイル: tests_mapping.py プロジェクト: loleksak/eail-its
def test_widget_interfaces(obj, interfaces):
    """
    Verifies whether the interfaces implemented by the widget
    are consistent with those declared in the ATK-EAIL mapping.

    The mapping is provided in parameters.ini.

    :param obj: widget object in test application.
    :param interfaces: list of interfaces expected in ATK-EAIL mapping.
    """

    assert obj, "No application or no ATK object has been found"

    implemented_interfaces = pyatspi.listInterfaces(obj)
    assert sorted(implemented_interfaces) == sorted(interfaces),\
        "Implemented interfaces different then expected: [%s] != [%s]" % \
        (str(implemented_interfaces), str(interfaces))
コード例 #27
0
    def _generateFocusedItem(self, obj, **args):
        result = []
        role = args.get('role', obj.getRole())
        if role not in [pyatspi.ROLE_LIST, pyatspi.ROLE_LIST_BOX]:
            return result

        if 'Selection' in pyatspi.listInterfaces(obj):
            items = self._script.utilities.selectedChildren(obj)
        else:
            items = [self._script.utilities.focusedChild(obj)]
        if not (items and items[0]):
            return result

        for item in map(self._generateName, items):
            result.extend(item)

        return result
コード例 #28
0
    def _adjustPointForObj(self, obj, x, y, coordType):
        try:
            singleLine = obj.getState().contains(pyatspi.STATE_SINGLE_LINE)
        except:
            singleLine = False

        if not singleLine or "EditableText" not in pyatspi.listInterfaces(obj):
            return x, y

        text = self.queryNonEmptyText(obj)
        if not text:
            return x, y

        objBox = obj.queryComponent().getExtents(coordType)
        stringBox = text.getRangeExtents(0, text.characterCount, coordType)
        if self.intersection(objBox, stringBox) != (0, 0, 0, 0):
            return x, y

        msg = "ERROR: text bounds %s not in obj bounds %s" % (stringBox,
                                                              objBox)
        debug.println(debug.LEVEL_INFO, msg, True)

        # This is where the string starts; not the widget.
        boxX, boxY = stringBox[0], stringBox[1]

        # Window Coordinates should be relative to the window; not the widget.
        # But broken interface is broken, and this appears to be what is being
        # exposed. And we need this information to get the widget's x and y.
        charExtents = text.getCharacterExtents(0, pyatspi.WINDOW_COORDS)
        if 0 < charExtents[0] < charExtents[2]:
            boxX -= charExtents[0]
        if 0 < charExtents[1] < charExtents[3]:
            boxY -= charExtents[1]

        # The point relative to the widget:
        relX = x - objBox[0]
        relY = y - objBox[1]

        # The point relative to our adjusted bounding box:
        newX = boxX + relX
        newY = boxY + relY

        msg = "INFO: Adjusted (%i, %i) to (%i, %i)" % (x, y, newX, newY)
        debug.println(debug.LEVEL_INFO, msg, True)
        return newX, newY
コード例 #29
0
ファイル: script_utilities.py プロジェクト: GNOME/orca
    def _adjustPointForObj(self, obj, x, y, coordType):
        try:
            singleLine = obj.getState().contains(pyatspi.STATE_SINGLE_LINE)
        except:
            singleLine = False

        if not singleLine or "EditableText" not in pyatspi.listInterfaces(obj):
            return x, y

        text = self.queryNonEmptyText(obj)
        if not text:
            return x, y

        objBox = obj.queryComponent().getExtents(coordType)
        stringBox = text.getRangeExtents(0, text.characterCount, coordType)
        if self.intersection(objBox, stringBox) != (0, 0, 0, 0):
            return x, y

        msg = "ERROR: text bounds %s not in obj bounds %s" % (stringBox, objBox)
        debug.println(debug.LEVEL_INFO, msg, True)

        # This is where the string starts; not the widget.
        boxX, boxY = stringBox[0], stringBox[1]

        # Window Coordinates should be relative to the window; not the widget.
        # But broken interface is broken, and this appears to be what is being
        # exposed. And we need this information to get the widget's x and y.
        charExtents = text.getCharacterExtents(0, pyatspi.WINDOW_COORDS)
        if 0 < charExtents[0] < charExtents[2]:
            boxX -= charExtents[0]
        if 0 < charExtents[1] < charExtents[3]:
            boxY -= charExtents[1]

        # The point relative to the widget:
        relX = x - objBox[0]
        relY = y - objBox[1]

        # The point relative to our adjusted bounding box:
        newX = boxX + relX
        newY = boxY + relY

        msg = "INFO: Adjusted (%i, %i) to (%i, %i)" % (x, y, newX, newY)
        debug.println(debug.LEVEL_INFO, msg, True)
        return newX, newY
コード例 #30
0
ファイル: script_utilities.py プロジェクト: GNOME/orca
    def isUselessPanel(self, obj):
        if not (obj and obj.getRole() == pyatspi.ROLE_PANEL):
            return False

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

        try:
            name = obj.name
            childCount = obj.childCount
            supportsText = "Text" in pyatspi.listInterfaces(obj)
        except:
            rv = True
        else:
            rv = not (name or childCount or supportsText)

        self._isUselessPanel[hash(obj)] = rv
        return rv
コード例 #31
0
    def isUselessPanel(self, obj):
        if not (obj and obj.getRole() == pyatspi.ROLE_PANEL):
            return False

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

        try:
            name = obj.name
            childCount = obj.childCount
            supportsText = "Text" in pyatspi.listInterfaces(obj)
        except:
            rv = True
        else:
            rv = not (name or childCount or supportsText)

        self._isUselessPanel[hash(obj)] = rv
        return rv
コード例 #32
0
    def selectedChildren(self, obj):
        result = super().selectedChildren(obj)
        if result or "Selection" in pyatspi.listInterfaces(obj):
            return result

        try:
            childCount = obj.childCount
        except:
            msg = "CHROMIUM: Exception getting child count of %s" % obj
            debug.println(debug.LEVEL_INFO, msg, True)
            return result

        # HACK: Ideally, we'd use the selection interface to get the selected
        # children. But that interface is not implemented yet. This hackaround
        # is extremely non-performant.
        for i in range(childCount):
            child = obj[i]
            if child and child.getState().contains(pyatspi.STATE_SELECTED):
                result.append(child)

        return result
コード例 #33
0
    def _getStringContext(self):
        """Returns the _StringContext associated with the specified point."""

        if not (self._script and self._obj):
            return _StringContext(self._obj)

        interfaces = pyatspi.listInterfaces(self._obj)
        if "Text" not in interfaces:
            return _StringContext(self._obj, self._script)

        state = self._obj.getState()
        if not state.contains(pyatspi.STATE_SELECTABLE):
            boundary = pyatspi.TEXT_BOUNDARY_WORD_START
        else:
            boundary = pyatspi.TEXT_BOUNDARY_LINE_START

        string, start, end = self._script.utilities.textAtPoint(
            self._obj, self._x, self._y, boundary=boundary)
        if not string and self._script.utilities.isTextArea(self._obj):
            string = self._script.speechGenerator.getRoleName(self._obj)

        return _StringContext(self._obj, self._script, string, start, end)
コード例 #34
0
    def _getStringContext(self):
        """Returns the _StringContext associated with the specified point."""

        if not (self._script and self._obj):
            return _StringContext(self._obj)

        interfaces = pyatspi.listInterfaces(self._obj)
        if "Text" not in interfaces:
            return _StringContext(self._obj, self._script)

        state = self._obj.getState()
        if not state.contains(pyatspi.STATE_SELECTABLE):
            boundary = pyatspi.TEXT_BOUNDARY_WORD_START
        else:
            boundary = pyatspi.TEXT_BOUNDARY_LINE_START

        string, start, end = self._script.utilities.textAtPoint(
            self._obj, self._x, self._y, boundary=boundary)
        if not string and self._script.utilities.isTextArea(self._obj):
            string = self._script.speechGenerator.getRoleName(self._obj)

        return _StringContext(self._obj, self._script, string, start, end)
コード例 #35
0
    def imagecapture(self, window_name = None, x = 0, y = 0,
                     width = None, height = None):
        """
        Captures screenshot of the whole desktop or given window
        
        @param window_name: Window name to look for, either full name,
        LDTP's name convention, or a Unix glob.
        @type window_name: string
        @param x: x co-ordinate value
        @type x: int
        @param y: y co-ordinate value
        @type y: int
        @param width: width co-ordinate value
        @type width: int
        @param height: height co-ordinate value
        @type height: int

        @return: screenshot with base64 encoded for the client
        @rtype: string
        """
        if window_name:
            acc = None
            for gui in self._list_guis():
                if self._match_name_to_acc(window_name, gui):
                    if 'Component' in pyatspi.listInterfaces(gui):
                        acc = gui
                        for obj in self._list_objects(gui):
                            role = obj.getRole()
                            if role == pyatspi.ROLE_CHECK_BOX or \
                                    role == pyatspi.ROLE_PUSH_BUTTON or \
                                    role == pyatspi.ROLE_RADIO_BUTTON:
                                try:
                                    # Try to grab focus
                                    self._grab_focus(obj)
                                except:
                                    pass
                                # Inner for loop
                                break
                        # Outer for loop
                        break
            if not acc:
                raise LdtpServerException('No window matches %s' % window_name)
            icomponent = acc.queryComponent()
            bb = icomponent.getExtents(pyatspi.DESKTOP_COORDS)
            x, y, height, width = bb.x, bb.y, bb.height, bb.width

        tmpFile = tempfile.mktemp('.png', 'ldtpd_')
        if gtk3:
           window = gdk.get_default_root_window()
           tmp_size = window.get_geometry()
           size = []
           # Width
           size.append(tmp_size[2])
           # Height
           size.append(tmp_size[3])
           pb = gdk.pixbuf_get_from_window(window, x, y, width or size[0],
                                           height or size[1])
           pb.savev(tmpFile, 'png', [], [])
           del pb
           gc.collect()
        else:
           window = gtk.gdk.get_default_root_window()
           size = window.get_size()
           pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 
                               width or size [0], 
                               height or size [1])
           pb = pb.get_from_drawable(window, window.get_colormap(),
                                      x, y, 0, 0, 
                                      width or size [0], 
                                      height or size [1])

           if pb:
              pb.save(tmpFile, 'png')
              del pb
              gc.collect()
        rv = b64encode(open(tmpFile).read())
        os.remove(tmpFile)
        return rv
コード例 #36
0
    def handleRowAndColumnSelectionChange(self, obj):
        interfaces = pyatspi.listInterfaces(obj)
        if not ("Table" in interfaces and "Selection" in interfaces):
            return True

        table = obj.queryTable()
        cols = set(table.getSelectedColumns())
        rows = set(table.getSelectedRows())

        selectedCols = sorted(cols.difference(set(self._calcSelectedColumns)))
        unselectedCols = sorted(
            set(self._calcSelectedColumns).difference(cols))
        convert = lambda x: self.columnConvert(x + 1)
        selectedCols = list(map(convert, selectedCols))
        unselectedCols = list(map(convert, unselectedCols))

        selectedRows = sorted(rows.difference(set(self._calcSelectedRows)))
        unselectedRows = sorted(set(self._calcSelectedRows).difference(rows))
        convert = lambda x: x + 1
        selectedRows = list(map(convert, selectedRows))
        unselectedRows = list(map(convert, unselectedRows))

        self._calcSelectedColumns = list(cols)
        self._calcSelectedRows = list(rows)

        if len(cols) == table.nColumns:
            self._script.speakMessage(messages.DOCUMENT_SELECTED_ALL)
            return True

        if not len(cols) and len(unselectedCols) == table.nColumns:
            self._script.speakMessage(messages.DOCUMENT_UNSELECTED_ALL)
            return True

        msgs = []
        if len(unselectedCols) == 1:
            msgs.append(messages.TABLE_COLUMN_UNSELECTED % unselectedCols[0])
        elif len(unselectedCols) > 1:
            msgs.append(messages.TABLE_COLUMN_RANGE_UNSELECTED %
                        (unselectedCols[0], unselectedCols[-1]))

        if len(unselectedRows) == 1:
            msgs.append(messages.TABLE_ROW_UNSELECTED % unselectedRows[0])
        elif len(unselectedRows) > 1:
            msgs.append(messages.TABLE_ROW_RANGE_UNSELECTED %
                        (unselectedRows[0], unselectedRows[-1]))

        if len(selectedCols) == 1:
            msgs.append(messages.TABLE_COLUMN_SELECTED % selectedCols[0])
        elif len(selectedCols) > 1:
            msgs.append(messages.TABLE_COLUMN_RANGE_SELECTED %
                        (selectedCols[0], selectedCols[-1]))

        if len(selectedRows) == 1:
            msgs.append(messages.TABLE_ROW_SELECTED % selectedRows[0])
        elif len(selectedRows) > 1:
            msgs.append(messages.TABLE_ROW_RANGE_SELECTED %
                        (selectedRows[0], selectedRows[-1]))

        if msgs:
            self._script.presentationInterrupt()

        for msg in msgs:
            self._script.speakMessage(msg, interrupt=False)

        return bool(len(msgs))
コード例 #37
0
ファイル: generic.py プロジェクト: zhyh329/ldtp2
    def imagecapture(self,
                     window_name=None,
                     x=0,
                     y=0,
                     width=None,
                     height=None):
        """
        Captures screenshot of the whole desktop or given window
        
        @param window_name: Window name to look for, either full name,
        LDTP's name convention, or a Unix glob.
        @type window_name: string
        @param x: x co-ordinate value
        @type x: int
        @param y: y co-ordinate value
        @type y: int
        @param width: width co-ordinate value
        @type width: int
        @param height: height co-ordinate value
        @type height: int

        @return: screenshot with base64 encoded for the client
        @rtype: string
        """
        # Validate the parameters
        # x and y offsets cannot be nagative
        x = max(0, x)
        y = max(0, y)

        # height and width cannot be less than 1
        # set to None if nagative value is given
        if width < 1:
            width = None
        if height < 1:
            height = None

        if window_name:
            acc = None
            for gui in self._list_guis():
                if self._match_name_to_acc(window_name, gui):
                    if 'Component' in pyatspi.listInterfaces(gui):
                        acc = gui
                        for obj in self._list_objects(gui):
                            role = obj.getRole()
                            if role == pyatspi.ROLE_CHECK_BOX or \
                                    role == pyatspi.ROLE_PUSH_BUTTON or \
                                    role == pyatspi.ROLE_RADIO_BUTTON:
                                try:
                                    # Try to grab focus
                                    self._grab_focus(obj)
                                except:
                                    pass
                                # Inner for loop
                                break
                        # Outer for loop
                        break
            if not acc:
                raise LdtpServerException('No window matches %s' % window_name)
            icomponent = acc.queryComponent()
            bb = icomponent.getExtents(pyatspi.DESKTOP_COORDS)
            # If co-ordinates are provided, use it
            # offsets cannot be greater than or equal to the window size
            # we want to capture at least one pixel
            x = min(x, bb.width - 1)
            y = min(y, bb.height - 1)

            # adjust the width and height parameters
            # so that the captured image is contained
            # within the visible window area
            # Take into account that window may be only
            # partially on the screen then the reported
            # width and height are not the same as the area of the window
            # that can actually be captured.

            # if bb.x is negative then the actual width
            # is smaller than the bb.width
            leftClippedWidth = min(bb.width, bb.width + bb.x)

            # if bb.y is negative then the actual height
            # is smaller than the bb.height
            topClippedHeight = min(bb.height, bb.height + bb.y)

            # Clipping from the right and bottom is done later
            # when the desktop size is known
            if width == None:
                width = leftClippedWidth - x
            else:
                width = min(width, leftClippedWidth - x)
            if height == None:
                height = topClippedHeight - y
            else:
                height = min(height, topClippedHeight - y)

            # take the window position into account
            # use 0 as the window co-oridinate
            # if it is negative
            x = x + max(0, bb.x)
            y = y + max(0, bb.y)

        tmpFile = tempfile.mktemp('.png', 'ldtpd_')
        if gtk3:
            window = gdk.get_default_root_window()
            tmp_size = window.get_geometry()
            size = []
            # Width
            size.append(tmp_size[2])
            # Height
            size.append(tmp_size[3])
            # offsets cannot be greater than or equal to the desktop size
            # we want to capture at least one pixel
            x = min(x, size[0] - 1)
            y = min(y, size[1] - 1)

            # adjust the width and height parameters
            # so that the captured image is contained
            # within the desktop area
            if width == None:
                width = size[0] - x
            else:
                width = min(width, size[0] - x)
            if height == None:
                height = size[1] - y
            else:
                height = min(height, size[1] - y)
            pb = gdk.pixbuf_get_from_window(window, x, y, width, height)
            pb.savev(tmpFile, 'png', [], [])
            del pb
            gc.collect()
        else:
            window = gtk.gdk.get_default_root_window()
            size = window.get_size()
            # offsets cannot be greater than or equal to the desktop size
            # we want to capture at least one pixel
            x = min(x, size[0] - 1)
            y = min(y, size[1] - 1)

            # adjust the width and height parameters
            # so that the captured image is contained
            # within the desktop area
            if width == None:
                width = size[0] - x
            else:
                width = min(width, size[0] - x)
            if height == None:
                height = size[1] - y
            else:
                height = min(height, size[1] - y)
            pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width,
                                height)
            pb = pb.get_from_drawable(window, window.get_colormap(), x, y, 0,
                                      0, width, height)

            if pb:
                pb.save(tmpFile, 'png')
                del pb
                gc.collect()
        rv = b64encode(open(tmpFile).read())
        os.remove(tmpFile)
        return rv
コード例 #38
0
ファイル: generic.py プロジェクト: IsSuEat/ldtp2
    def imagecapture(self, window_name = None, x = 0, y = 0,
                     width = None, height = None):
        """
        Captures screenshot of the whole desktop or given window
        
        @param window_name: Window name to look for, either full name,
        LDTP's name convention, or a Unix glob.
        @type window_name: string
        @param x: x co-ordinate value
        @type x: int
        @param y: y co-ordinate value
        @type y: int
        @param width: width co-ordinate value
        @type width: int
        @param height: height co-ordinate value
        @type height: int

        @return: screenshot with base64 encoded for the client
        @rtype: string
        """	
        # Validate the parameters
        # x and y offsets cannot be nagative
        x = max(0, x)
        y = max(0, y)

        # height and width cannot be less than 1
        # set to None if nagative value is given
        if width < 1:
            width = None
        if height < 1:
            height = None
	
        if window_name:
            acc = None
            for gui in self._list_guis():
                if self._match_name_to_acc(window_name, gui):
                    if 'Component' in pyatspi.listInterfaces(gui):
                        acc = gui
                        for obj in self._list_objects(gui):
                            role = obj.getRole()
                            if role == pyatspi.ROLE_CHECK_BOX or \
                                    role == pyatspi.ROLE_PUSH_BUTTON or \
                                    role == pyatspi.ROLE_RADIO_BUTTON:
                                try:
                                    # Try to grab focus
                                    self._grab_focus(obj)
                                except:
                                    pass
                                # Inner for loop
                                break
                        # Outer for loop
                        break
            if not acc:
                raise LdtpServerException('No window matches %s' % window_name)
            icomponent = acc.queryComponent()
            bb = icomponent.getExtents(pyatspi.DESKTOP_COORDS)
            # If co-ordinates are provided, use it
            # offsets cannot be greater than or equal to the window size
            # we want to capture at least one pixel
            x = min(x, bb.width - 1)
            y = min(y, bb.height - 1)

            # adjust the width and height parameters
            # so that the captured image is contained
            # within the visible window area
            # Take into account that window may be only
            # partially on the screen then the reported
            # width and height are not the same as the area of the window
            # that can actually be captured.
            
            # if bb.x is negative then the actual width 
            # is smaller than the bb.width
            leftClippedWidth = min(bb.width, bb.width + bb.x)
            
            # if bb.y is negative then the actual height
            # is smaller than the bb.height
            topClippedHeight = min(bb.height, bb.height + bb.y)
            
            # Clipping from the right and bottom is done later
            # when the desktop size is known            
            if width == None:                
                width = leftClippedWidth - x
            else:
                width = min(width, leftClippedWidth - x)
            if height == None:
                height = topClippedHeight - y
            else:
                height = min(height, topClippedHeight - y)

            # take the window position into account
            # use 0 as the window co-oridinate
            # if it is negative
            x = x + max(0, bb.x)
            y = y + max(0, bb.y)

        tmpFile = tempfile.mktemp('.png', 'ldtpd_')
        if gtk3:
           window = gdk.get_default_root_window()
           tmp_size = window.get_geometry()
           size = []
           # Width
           size.append(tmp_size[2])
           # Height
           size.append(tmp_size[3])
           # offsets cannot be greater than or equal to the desktop size
           # we want to capture at least one pixel
           x = min(x, size[0] - 1)
           y = min(y, size[1] - 1)
	   
           # adjust the width and height parameters
           # so that the captured image is contained
           # within the desktop area
           if width == None:
               width = size[0] - x
           else:
               width = min(width, size[0] - x)
           if height == None:
               height = size[1] - y
           else:
               height = min(height, size[1] - y)
           pb = gdk.pixbuf_get_from_window(window, x, y, width,
                                           height)
           pb.savev(tmpFile, 'png', [], [])
           del pb
           gc.collect()
        else:
           window = gtk.gdk.get_default_root_window()
           size = window.get_size()
           # offsets cannot be greater than or equal to the desktop size
           # we want to capture at least one pixel
           x = min(x, size[0] - 1)
           y = min(y, size[1] - 1)
	   
           # adjust the width and height parameters
           # so that the captured image is contained
           # within the desktop area
           if width == None:
               width = size[0] - x
           else:
               width = min(width, size[0] - x)
           if height == None:
               height = size[1] - y
           else:
               height = min(height, size[1] - y)
           pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 
                               width, 
                               height)
           pb = pb.get_from_drawable(window, window.get_colormap(),
                                      x, y, 0, 0, 
                                      width, 
                                      height)

           if pb:
              pb.save(tmpFile, 'png')
              del pb
              gc.collect()
        rv = b64encode(open(tmpFile).read())
        os.remove(tmpFile)
        return rv
コード例 #39
0
ファイル: flat_review.py プロジェクト: isabella232/orca-1
    def getZonesFromText(self, accessible, cliprect):
        """Gets a list of Zones from an object that implements the
        AccessibleText specialization.

        Arguments:
        - accessible: the accessible
        - cliprect: the extents that the Zones must fit inside.

        Returns a list of Zones.
        """

        if not self.script.utilities.hasPresentableText(accessible):
            return []

        zones = []
        text = accessible.queryText()

        # TODO - JD: This is here temporarily whilst I sort out the rest
        # of the text-related mess.
        if "EditableText" in pyatspi.listInterfaces(accessible) \
           and accessible.getState().contains(pyatspi.STATE_SINGLE_LINE):
            extents = accessible.queryComponent().getExtents(0)
            return [TextZone(accessible, 0, text.getText(0, -1), *extents)]

        offset = 0
        lastEndOffset = -1
        upperMax = lowerMax = text.characterCount
        upperMid = lowerMid = int(upperMax / 2)
        upperMin = lowerMin = 0
        upperY = lowerY = 0
        oldMid = 0

        # performing binary search to locate first line inside clipped area
        while oldMid != upperMid:
            oldMid = upperMid
            [x, y, width,
             height] = text.getRangeExtents(upperMid, upperMid + 1, 0)
            upperY = y
            if y > cliprect.y:
                upperMax = upperMid
            else:
                upperMin = upperMid
            upperMid = int((upperMax - upperMin) / 2) + upperMin

        # performing binary search to locate last line inside clipped area
        oldMid = 0
        limit = cliprect.y + cliprect.height
        while oldMid != lowerMid:
            oldMid = lowerMid
            [x, y, width,
             height] = text.getRangeExtents(lowerMid, lowerMid + 1, 0)
            lowerY = y
            if y > limit:
                lowerMax = lowerMid
            else:
                lowerMin = lowerMid
            lowerMid = int((lowerMax - lowerMin) / 2) + lowerMin

        msg = "FLAT REVIEW: Getting lines for %s offsets %i-%i" % (
            accessible, upperMin, lowerMax)
        debug.println(debug.LEVEL_INFO, msg, True)

        lines = self._getLines(accessible, upperMin, lowerMax)
        msg = "FLAT REVIEW: %i lines found for %s" % (len(lines), accessible)
        debug.println(debug.LEVEL_INFO, msg, True)

        for string, startOffset, endOffset in lines:
            zones.extend(
                self.splitTextIntoZones(accessible, string, startOffset,
                                        cliprect))

        return zones
コード例 #40
-2
ファイル: script_utilities.py プロジェクト: GNOME/orca
    def selectedChildren(self, obj):
        if not obj:
            return []

        role = obj.getRole()
        isSelection = lambda x: x and 'Selection' in pyatspi.listInterfaces(x)
        if not isSelection(obj) and role == pyatspi.ROLE_COMBO_BOX:
            child = pyatspi.findDescendant(obj, isSelection)
            if child:
                return super().selectedChildren(child)

        # Things only seem broken for certain tables, e.g. the Paths table.
        # TODO - JD: File the LibreOffice bugs and reference them here.
        if role != pyatspi.ROLE_TABLE:
            return super().selectedChildren(obj)

        # We will need to special case this due to the possibility of there
        # being lots of children (which may also prove to be zombie objects).
        # This is why we can't have nice things.
        if self.isSpreadSheetTable(obj):
            return []

        try:
            selection = obj.querySelection()
        except:
            return []

        children = []
        for i, child in enumerate(obj):
            if selection.isChildSelected(i):
                children.append(obj[i])

        return children