[pyatspi2] Some refactoring to fix text and document attributes



commit 41fb85401ab93aacf27dfb66bec9599b64c5cf5f
Author: Mike Gorse <mgorse novell com>
Date:   Thu Dec 9 16:14:11 2010 -0500

    Some refactoring to fix text and document attributes
    
    Wrap Text and Document interfaces to avoid namespace conflicts with
    getAttributes, as the objects returned by get_text and get_document are
    really AtspiAccessibles, and so Pygi treats them as such, so interface
    information is not preserved.

 pyatspi/Accessibility.py |   41 +----
 pyatspi/Makefile.am      |    2 +
 pyatspi/document.py      |   71 ++++++
 pyatspi/text.py          |  540 ++++++++++++++++++++++++++++++++++++++++++++++
 pyatspi/utils.py         |    6 +
 5 files changed, 623 insertions(+), 37 deletions(-)
---
diff --git a/pyatspi/Accessibility.py b/pyatspi/Accessibility.py
index 59ce222..0a2245b 100644
--- a/pyatspi/Accessibility.py
+++ b/pyatspi/Accessibility.py
@@ -20,6 +20,8 @@ Registry = Registry()
 from constants import *
 from role import *
 from state import *
+from text import *
+from document import *
 from utils import *
 
 def Accessible_getitem(self, i):
@@ -36,15 +38,6 @@ def pointToList(point):
 def rectToList(rect):
 	return (rect.x, rect.y, rect.width, rect.height)
 
-def textAttrToList(ta):
-	return (ta.start_offset, ta.end_offset, ta.text)
-
-def rangeToList(r):
-	return (r.start_offset, r.end_offset, r.text)
-
-def textRangeToList(r):
-	return (r.text, r.start_offset, r.end_offset)
-
 # TODO: Figure out how to override Atspi.Rect constructor and remove this class
 class BoundingBox(list):
         def __new__(cls, x, y, width, height):
@@ -166,11 +159,7 @@ Atspi.Component.getSize = lambda x: pointToList(Atspi.Component.get_size(x))
 Atspi.Component.grabFocus = Atspi.Component.grab_focus
 
 ### document ###
-Document = Atspi.Document
-Atspi.Accessible.queryDocument = lambda x: getInterface(Atspi.Accessible.get_document, x)
-Atspi.Document.getAttributevalue = Atspi.Document.get_attribute_value
-Atspi.Document.getAttributes = lambda x: [key + ":" + value for key, value in Atspi.Document.get_attributes (x)]
-Atspi.Document.getLocale = Atspi.Document.get_locale
+Atspi.Accessible.queryDocument = lambda x: Document(getInterface(Atspi.Accessible.get_document, x))
 
 ### editable text ###
 EditableText = Atspi.EditableText
@@ -249,29 +238,7 @@ Atspi.Table.get_nSelectedColumns = Atspi.Table.get_n_selected_columns
 Atspi.Table.get_nSelectedRows = Atspi.Table.get_n_selected_rows
 
 ### text ###
-Text = Atspi.Text
-Atspi.Accessible.queryText = lambda x: getInterface(Atspi.Accessible.get_text, x)
-Atspi.Text.addSelection = Atspi.Text.add_selection
-Atspi.Text.getAttributeRun = lambda x,o,i: textAttrToList (Atspi.Text.get_attribute_run (x,o,i))
-Atspi.Text.getAttributevalue = Atspi.Text.get_attribute_value
-Atspi.Text.getAttributes = lambda x,o: textAttrToList (Atspi.Text.get_attributes (x, o))
-Atspi.Text.getBoundedRanges = Atspi.Text.get_bounded_ranges
-Atspi.Text.getcharacterAtOffset = Atspi.Text.get_character_at_offset
-Atspi.Text.getCharacterExtents = lambda x,c: rectToList(Atspi.Text.get_character_extents(x,c))
-Atspi.Text.getDefaultAttributes = lambda x: hashToAttributeList (Atspi.Text.get_default_attributes (x))
-Atspi.Text.getNSelections = Atspi.Text.get_n_selections
-Atspi.Text.getOffsetAtPoint = Atspi.Text.get_offset_at_point
-Atspi.Text.getRangeExtents = lambda x,s,e,c: rectToList(Atspi.Text.get_range_extents(x,s,e,c))
-Atspi.Text.getSelection = lambda x,n: rangeToList (Atspi.Text.get_selection (x,n))
-Atspi.Text.getText = Atspi.Text.get_text
-Atspi.Text.getTextAfterOffset = lambda x,o,b: textRangeToList(Atspi.Text.get_text_after_offset (x,o,b))
-Atspi.Text.getTextAtOffset = lambda x,o,b: textRangeToList(Atspi.Text.get_text_at_offset (x,o,b))
-Atspi.Text.getTextBeforeOffset = lambda x,o,b: textRangeToList(Atspi.Text.get_text_before_offset (x,o,b))
-Atspi.Text.removeSelection = Atspi.Text.remove_selection
-Atspi.Text.setCaretOffset = Atspi.Text.set_caret_offset
-Atspi.Text.setSelection = Atspi.Text.set_selection
-Atspi.Text.caretOffset = property(fget=Atspi.Text.get_caret_offset, fset=Atspi.Text.set_caret_offset)
-Atspi.Text.characterCount = property(fget=Atspi.Text.get_character_count)
+Atspi.Accessible.queryText = lambda x: Text(getInterface(Atspi.Accessible.get_text, x))
 
 TEXT_BOUNDARY_CHAR = Atspi.TextBoundaryType.CHAR
 TEXT_BOUNDARY_WORD_START = Atspi.TextBoundaryType.WORD_START
diff --git a/pyatspi/Makefile.am b/pyatspi/Makefile.am
index cb127be..7fc96f2 100644
--- a/pyatspi/Makefile.am
+++ b/pyatspi/Makefile.am
@@ -17,10 +17,12 @@ pyatspi_PYTHON = \
                 exceptions.py           \
 		factory.py		\
 		__init__.py		\
+	document.py \
 		interfaces.py		\
 		registry.py		\
 		role.py			\
 		state.py		\
+	text.py \
 		utils.py
 
 CLEANFILES = *.pyc
diff --git a/pyatspi/document.py b/pyatspi/document.py
new file mode 100644
index 0000000..36284ce
--- /dev/null
+++ b/pyatspi/document.py
@@ -0,0 +1,71 @@
+#Copyright (C) 2008 Codethink Ltd
+#Copyright (C) 2010 Novell, Inc.
+
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License version 2 as published by the Free Software Foundation.
+
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#GNU General Public License for more details.
+#You should have received a copy of the GNU Lesser General Public License
+#along with this program; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from gi.repository import Atspi
+
+__all__ = [
+           "Document",
+          ]
+
+#------------------------------------------------------------------------------
+
+class Document:
+        """
+        Primarily a 'tagging' interface which indicates the start of
+        document content in the Accessibility hierarchy. Accessible objects
+        below the node implementing Document are normally assumed to
+        be part of the document content. Attributes of Document are those
+        attributes associated with the document as a whole. Objects that
+        implement Document are normally expected to implement Collection
+        as well.
+        """
+
+        def __init__(self, obj):
+                self.obj = obj
+
+        def getAttributeValue(self, key):
+                """
+                Gets the value of a single attribute, if specified for the document
+                as a whole.
+                @param : attributename
+                a string indicating the name of a specific attribute (name-value
+                pair) being queried.
+                @return a string corresponding to the value of the specified
+                attribute, or an empty string if the attribute is unspecified
+                for the object.
+                """
+                return Atspi.Document.get_attribute_value(self.obj, key)
+
+        def getAttributes(self):
+                """
+                Gets all attributes specified for a document as a whole. For
+                attributes which change within the document content, see Accessibility::Text::getAttributes
+                instead.
+                @return an AttributeSet containing the attributes of the document,
+                as name-value pairs.
+                """
+                ret = Atspi.Document.get_attributes(self.obj)
+                return [key + ':' + value for key, value in ret.iteritems()]
+
+        def getLocale(self):
+                """
+                Gets the locale associated with the document's content. e.g.
+                the locale for LOCALE_TYPE_MESSAGES.
+                @return a string compliant with the POSIX standard for locale
+                description.
+                """
+                return Atspi.Document.get_locale(self.obj)
+
+#END----------------------------------------------------------------------------
diff --git a/pyatspi/text.py b/pyatspi/text.py
new file mode 100644
index 0000000..a906534
--- /dev/null
+++ b/pyatspi/text.py
@@ -0,0 +1,540 @@
+#Copyright (C) 2008 Codethink Ltd
+#Copyright (C) 2010 Novell, Inc.
+
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License version 2 as published by the Free Software Foundation.
+
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#GNU General Public License for more details.
+#You should have received a copy of the GNU Lesser General Public License
+#along with this program; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from gi.repository import Atspi
+from enum import *
+import utils
+
+
+__all__ = [
+           "Text",
+           "TEXT_BOUNDARY_TYPE",
+           "TEXT_BOUNDARY_CHAR",
+           "TEXT_BOUNDARY_WORD_START",
+           "TEXT_BOUNDARY_WORD_END",
+           "TEXT_BOUNDARY_SENTENCE_START",
+           "TEXT_BOUNDARY_SENTENCE_END",
+           "TEXT_BOUNDARY_LINE_START",
+           "TEXT_BOUNDARY_LINE_END",
+           "TEXT_CLIP_TYPE",
+           "TEXT_CLIP_NONE",
+           "TEXT_CLIP_MIN",
+           "TEXT_CLIP_MAX",
+           "TEXT_CLIP_BOTH",
+          ]
+
+#------------------------------------------------------------------------------
+
+class TEXT_BOUNDARY_TYPE(Enum):
+        _enum_lookup = {
+                0:'TEXT_BOUNDARY_CHAR',
+                1:'TEXT_BOUNDARY_WORD_START',
+                2:'TEXT_BOUNDARY_WORD_END',
+                3:'TEXT_BOUNDARY_SENTENCE_START',
+                4:'TEXT_BOUNDARY_SENTENCE_END',
+                5:'TEXT_BOUNDARY_LINE_START',
+                6:'TEXT_BOUNDARY_LINE_END',
+        }
+
+TEXT_BOUNDARY_CHAR = TEXT_BOUNDARY_TYPE(0)
+TEXT_BOUNDARY_LINE_END = TEXT_BOUNDARY_TYPE(6)
+TEXT_BOUNDARY_LINE_START = TEXT_BOUNDARY_TYPE(5)
+TEXT_BOUNDARY_SENTENCE_END = TEXT_BOUNDARY_TYPE(4)
+TEXT_BOUNDARY_SENTENCE_START = TEXT_BOUNDARY_TYPE(3)
+TEXT_BOUNDARY_WORD_END = TEXT_BOUNDARY_TYPE(2)
+TEXT_BOUNDARY_WORD_START = TEXT_BOUNDARY_TYPE(1)
+
+#------------------------------------------------------------------------------
+
+class TEXT_CLIP_TYPE(Enum):
+        _enum_lookup = {
+                0:'TEXT_CLIP_NONE',
+                1:'TEXT_CLIP_MIN',
+                2:'TEXT_CLIP_MAX',
+                3:'TEXT_CLIP_BOTH',
+        }
+
+TEXT_CLIP_BOTH = TEXT_CLIP_TYPE(3)
+TEXT_CLIP_MAX = TEXT_CLIP_TYPE(2)
+TEXT_CLIP_MIN = TEXT_CLIP_TYPE(1)
+TEXT_CLIP_NONE = TEXT_CLIP_TYPE(0)
+
+#------------------------------------------------------------------------------
+
+class Text:
+        """
+        The text interface should be implemented by objects which place
+        textual information onscreen as character strings or glyphs.
+        The text interface allows access to textual content, including
+        display attributes and semantic hints associated with runs of
+        text, and access to bounding box information for glyphs and substrings.
+        It also allows portions of textual content to be selected, if
+        the object's StateSet includes STATE_SELECTABLE_TEXT.
+        In some cases a Text object may have, as its content, an empty
+        string. In particular this can occur in the case of Hypertext
+        objects which do not display explicitly textual information onscreen,
+        as Hypertext is derived from the Text interface. 
+        Typographic and semantic attributes of onscreen textual content,
+        for instance typeface, weight, language, and such qualities as
+        'emphasis' or 'blockquote', are represented as text attributes.
+        Contiguous sequences of characters over which these attributes
+        are unchanged are referred to as "attribute runs", and are available
+        via Text::getAttributeRun. Where possible, implementing clients
+        will report textual attributes which are the same over the entire
+        text object, for instance those inherited from a default or document-scope
+        style, via getDefaultAttributes instead of reporting them explicitly
+        for each character. Therefore, for any span of text, the attributes
+        in effect are the union of the set returned by Text::getDefaultAttributes,
+        and the set returned at a particular character offset via Text::getAttributeRun.
+        """
+
+        def __init__(self, obj):
+                self.obj = obj
+
+        def addSelection(self, index):
+                """
+                The result of calling addSelection on objects which already have
+                one selection present, and which do not include STATE_MULTISELECTABLE,
+                is undefined, other than the return value. 
+                @return True of the selection was successfully added, False otherwise.
+                Selection may fail if the object does not support selection of
+                text (see STATE_SELECTABLE_TEXT), if the object does not support
+                multiple selections and a selection is already defined, or for
+                other reasons (for instance if the user does not have permission
+                to copy the text into the relevant selection buffer).
+                """
+                return Atspi.Text.add_selection(self.obj, index)
+
+        def getAttributeRun(self, offset):
+                """
+                Query a particular text object for the text attributes defined
+                at a given offset, obtaining the start and end of the "attribute
+                run" over which these attributes are currently invariant. Text
+                attributes are those presentational, typographic, or semantic
+                attributes or qualitites which apply to a range of text specifyable
+                by starting and ending offsets. Attributes relevant to localization
+                should be provided in accordance with the w3c "Internationalization
+                and Localization Markup Requirements", http://www.w3.org/TR/2005/WD-itsreq-20051122/
+                Other text attributes should choose their names and value semantics
+                in accordance with relevant standards such as CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512),
+                XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and
+                WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). Those attributes
+                from the aforementioned specifications and recommendations which
+                do not concern typographic, presentational, or semantic aspects
+                of text should be exposed via the more general Accessible::getAttributes()
+                API (if at all).
+                For example, CSS attributes which should be exposed on text (either
+                as default attributes, or as explicitly-set attributes when non-default
+                values are specified in the content view) include the Font attributes
+                (i.e. "css2:font-weight", "css2:font-style"), the "css2:color"
+                and "css2:background-color" attributes, and "css2:text-decoration"
+                attribute.
+                If includeDefaults is TRUE, then this AttributeSet should include
+                the default attributes as well as those which are explicitly
+                assigned to the attribute run in question. startOffset and endOffset
+                will be back-filled to indicate the start and end of the attribute
+                run which contains 'offset' - an attribute run is a contiguous
+                section of text whose attributes are homogeneous. 
+                @param : offset
+                the offset of the character whose attributes will be reported.
+                @param : startOffset
+                backfilled with the starting offset of the character range over
+                which all text attributes match those of offset, i.e. the start
+                of the homogeneous attribute run including offset. 
+                @param : endOffset
+                backfilled with the offset of the first character past the character
+                range over which all text attributes match those of offset, i.e.
+                the character immediately after the homogeneous attribute run
+                including offset. 
+                @param : includeDefaults
+                if False, the call should only return those attributes which
+                are explicitly set on the current attribute run, omitting any
+                attributes which are inherited from the default values. See also
+                Text::getDefaultAttributes.
+                @return the AttributeSet defined at offset, optionally including
+                the 'default' attributes.
+                """
+                [attrs, startOffset, endOffset] = Atspi.Text.get_attribute_run(self.obj, offset)
+                dict = [key + ':' + value for key, value in attrs.values()]
+                return [dict, startOffset, endOffset]
+
+        def getAttributeValue(self, offset, attributeName):
+                """
+                Get the string value of a named attribute at a given offset,
+                if defined. 
+                @param : offset
+                the offset of the character for which the attribute run is to
+                be obtained. 
+                @param : attributeName
+                the name of the attribute for which the value is to be returned,
+                if defined. 
+                @param : startOffset
+                back-filled with the offset of the first character in the attribute
+                run containing the character at offset. 
+                @param : endOffset
+                back-filled with the offset of the first character past the end
+                of the attribute run containing the character at offset. 
+                @param : defined
+                back-filled with True if the attributeName has a defined value
+                at offset, False otherwise. 
+                @return the value of attribute (name-value pair) corresponding
+                to "name", if defined.
+                """
+                return Atspi.Text.get_attribute_value(self.obj, offset, attributeName)
+
+        def getAttributes(self, offset):
+                """
+                getAttributes is deprecated in favor of getAttributeRun. 
+                @return the attributes at offset, as a semicolon-delimited set
+                of colon-delimited name-value pairs.
+                """
+                [attrs, startOffset, endOffset] = Atspi.Text.get_attributes(self.obj, offset)
+                arr = [key + ':' + value for key, value in attrs.items()]
+		str = ';'.join (arr)
+                return [str, startOffset, endOffset]
+
+        def getBoundedRanges(self, x, y, width, height, coordType, xClipType, yClipType):
+                """
+                Return the text content within a bounding box, as a list of Range
+                structures. Depending on the TEXT_CLIP_TYPE parameters, glyphs
+                which are clipped by the bounding box (i.e. which lie partially
+                inside and partially outside it) may or may not be included in
+                the ranges returned. 
+                @param : x
+                the minimum x ( i.e. leftmost) coordinate of the bounding box.
+                @param : y
+                the minimum y coordinate of the bounding box. 
+                @param : width
+                the horizontal size of the bounding box. The rightmost bound
+                of the bounding box is (x + width); 
+                @param : height
+                the vertical size of the bounding box. The maximum y value of
+                the bounding box is (y + height); 
+                @param : coordType
+                If 0, the above coordinates are interpreted as pixels relative
+                to corner of the screen; if 1, the coordinates are interpreted
+                as pixels relative to the corner of the containing toplevel window.
+                @param : xClipType
+                determines whether text which intersects the bounding box in
+                the x direction is included. 
+                @param : yClipType
+                determines whether text which intersects the bounding box in
+                the y direction is included.
+                """
+                return Atspi.Text.get_bounded_ranges(self.obj, x, y, width, height, coordType, xClipType, yClipType)
+
+        def getCharacterAtOffset(self, offset):
+                """
+                @param : offset
+                position
+                @return an unsigned long integer whose value corresponds to the
+                UCS-4 representation of the character at the specified text offset,
+                or 0 if offset is out of range.
+                """
+                return Atspi.Text.get_character_offset(self.obj, offset)
+
+        def getCharacterExtents(self, offset, coordType):
+                """
+                Obtain a the bounding box, as x, y, width, and height, of the
+                character or glyph at a particular character offset in this object's
+                text content. The coordinate system in which the results are
+                reported is specified by coordType. If an onscreen glyph corresponds
+                to multiple character offsets, for instance if the glyph is a
+                ligature, the bounding box reported will include the entire glyph
+                and therefore may apply to more than one character offset. 
+                @param : offset
+                the character offset of the character or glyph being queried.
+                @param : coordType
+                If 0, the results will be reported in screen coordinates, i.e.
+                in pixels relative to the upper-left corner of the screen, with
+                the x axis pointing right and the y axis pointing down. If 1,
+                the results will be reported relative to the containing toplevel
+                window, with the x axis pointing right and the y axis pointing
+                down.
+                """
+                ret = Atspi.Text.get_character_extents(self.obj, offset, coordType)
+                return utils.rectToList(ret)
+
+        def getDefaultAttributeSet(self):
+                """
+                Return an AttributeSet containing the text attributes which apply
+                to all text in the object by virtue of the default settings of
+                the document, view, or user agent; e.g. those attributes which
+                are implied rather than explicitly applied to the text object.
+                For instance, an object whose entire text content has been explicitly
+                marked as 'bold' will report the 'bold' attribute via getAttributeRun(),
+                whereas an object whose text weight is inspecified may report
+                the default or implied text weight in the default AttributeSet.
+                """
+                ret = Atspi.Text.get_default_attribute_set(self.obj)
+                return [key + ':' + value for key, value in ret.values()]
+
+        def getDefaultAttributes(self):
+                """
+                Deprecated in favor of getDefaultAttributeSet. 
+                @return the attributes which apply to the entire text content,
+                but which were not explicitly specified by the content creator.
+                """
+                ret = Atspi.Text.get_default_attributes(self.obj)
+                return ';'.join([key + ':' + value for key, value in ret.iteritems()])
+
+        def getNSelections(self):
+                """
+                Obtain the number of separate, contiguous selections in the current
+                Text object. Text objects which do not implement selection of
+                discontiguous text regions will always return '0' or '1'. Note
+                that "contiguous" is defined by continuity of the offsets, i.e.
+                a text 'selection' is defined by a start/end offset pair. In
+                the case of bidirectional text, this means that a continguous
+                selection may appear visually discontiguous, and vice-versa.
+                @return the number of contiguous selections in the current Text
+                object.
+                """
+                return Atspi.Text.get_n_selections(self.obj)
+
+        def getOffsetAtPoint(self, x, y, coordType):
+                """
+                Get the offset of the character at a given onscreen coordinate.
+                The coordinate system used to interpret x and y is determined
+                by parameter coordType. 
+                @param : x
+                @param : y
+                @param : coordType
+                if 0, the input coordinates are interpreted relative to the entire
+                screen, if 1, they are relative to the toplevel window containing
+                this Text object. 
+                @return the text offset (as an offset into the character array)
+                of the glyph whose onscreen bounds contain the point x,y, or
+                -1 if the point is outside the bounds of any glyph.
+                """
+                return Atspi.Text.get_offset_at_point(self.obj, x, y, UInt32(coordType))
+
+        def getRangeExtents(self, startOffset, endOffset, coordType):
+                """
+                Obtain the bounding box which entirely contains a given text
+                range. Negative values may be returned for the bounding box parameters
+                in the event that all or part of the text range is offscreen
+                or not mapped to the screen. 
+                @param : startOffset
+                the offset of the first character in the specified range. 
+                @param : endOffset
+                the offset of the character immediately after the last character
+                in the specified range. 
+                @param : x
+                an integer parameter which is back-filled with the minimum horizontal
+                coordinate of the resulting bounding box. 
+                @param : y
+                an integer parameter which is back-filled with the minimum vertical
+                coordinate of the resulting bounding box. 
+                @param : width
+                an integer parameter which is back-filled with the horizontal
+                extent of the bounding box. 
+                @param : height
+                an integer parameter which is back-filled with the vertical extent
+                of the bounding box. 
+                @param : coordType
+                If 0, the above coordinates are reported in pixels relative to
+                corner of the screen; if 1, the coordinates are reported relative
+                to the corner of the containing toplevel window.
+                """
+                ret = Atspi.Text.get_range_extents(self.obj, startOffset, endOffset, coordType)
+                return utils.rectToList(ret)
+
+        def getSelection(self, selectionNum):
+                """
+                The result of calling getSelection with an out-of-range selectionNum
+                (i.e. for a selection which does not exist) is not strictly defined,
+                but should set endOffset equal to startOffset.
+                @param : selectionNum
+                indicates which of a set of non-contiguous selections to modify.
+                @param : startOffset
+                back-filled with the starting offset of the resulting substring,
+                if one exists. 
+                @param : endOffset
+                back-filled with the offset of the character immediately following
+                the resulting substring, if one exists. 
+                """
+                ret = Atspi.Text.get_selection(self.obj, selectionNum)
+                return rangeToList(ret)
+
+        def getText(self, startOffset, endOffset):
+                """
+                Obtain all or part of the onscreen textual content of a Text
+                object. If endOffset is specified as "-1", then this method will
+                return the entire onscreen textual contents of the Text object.
+                @param : startOffset
+                back-filled with the starting offset of the resulting substring,
+                if one exists. 
+                @param : endOffset
+                back-filled with the offset of the character immediately following
+                the resulting substring, if one exists. 
+                @return the textual content of the current Text object beginning
+                startOffset (inclusive) up to but not including the character
+                at endOffset.
+                """
+                if not endOffset:
+                        endOffset = -1
+                return Atspi.Text.get_text(self.obj, startOffset, endOffset)
+
+        def getTextAfterOffset(self, offset, type):
+                """
+                Obtain a subset of the text content of an object which entirely
+                follows offset, delimited by character, word, line, or sentence
+                boundaries as specified by type. The starting and ending offsets
+                of the resulting substring are returned in startOffset and endOffset.
+                By definition, if such a substring exists, startOffset must be
+                greater than offset. 
+                @param : offset
+                the offset from which the substring search begins, and which
+                must lie before the returned substring. 
+                @param : type
+                the text-boundary delimiter which determines whether the returned
+                text constitures a character, word, line, or sentence (and possibly
+                attendant whitespace), and whether the start or ending of such
+                a substring forms the boundary condition. 
+                @param : startOffset
+                back-filled with the starting offset of the resulting substring,
+                if one exists. 
+                @param : endOffset
+                back-filled with the offset of the character immediately following
+                the resulting substring, if one exists. 
+                @return a string which is a substring of the text content of
+                the object, delimited by the specified boundary condition.
+                """
+                ret = Atspi.Text.get_text_after_offset(self.obj, offset, type)
+                return textRangeToList(ret)
+
+        def getTextAtOffset(self, offset, type):
+                """
+                Obtain a subset of the text content of an object which includes
+                the specified offset, delimited by character, word, line, or
+                sentence boundaries as specified by type. The starting and ending
+                offsets of the resulting substring are returned in startOffset
+                and endOffset. 
+                @param : offset
+                the offset from which the substring search begins, and which
+                must lie within the returned substring. 
+                @param : type
+                the text-boundary delimiter which determines whether the returned
+                text constitures a character, word, line, or sentence (and possibly
+                attendant whitespace), and whether the start or ending of such
+                a substring forms the boundary condition. 
+                @param : startOffset
+                back-filled with the starting offset of the resulting substring,
+                if one exists. 
+                @param : endOffset
+                back-filled with the offset of the character immediately following
+                the resulting substring, if one exists. 
+                @return a string which is a substring of the text content of
+                the object, delimited by the specified boundary condition.
+                """
+                ret = Atspi.Text.get_text_at_offset(self.obj, offset, type)
+                return textRangeToList(ret)
+
+        def getTextBeforeOffset(self, offset, type):
+                """
+                Obtain a subset of the text content of an object which entirely
+                precedes offset, delimited by character, word, line, or sentence
+                boundaries as specified by type. The starting and ending offsets
+                of the resulting substring are returned in startOffset and endOffset.
+                By definition, if such a substring exists, endOffset is less
+                than or equal to offset. 
+                @param : offset
+                the offset from which the substring search begins. 
+                @param : type
+                the text-boundary delimiter which determines whether the returned
+                text constitures a character, word, line, or sentence (and possibly
+                attendant whitespace), and whether the start or ending of such
+                a substring forms the boundary condition. 
+                @param : startOffset
+                back-filled with the starting offset of the resulting substring,
+                if one exists. 
+                @param : endOffset
+                back-filled with the offset of the character immediately following
+                the resulting substring, if one exists. 
+                @return a string which is a substring of the text content of
+                the object, delimited by the specified boundary condition.
+                """
+                func = self.get_dbus_method("GetTextBeforeOffset", dbus_interface=ATSPI_TEXT)
+                ret = Atspi.Text.get_text_before_offset(self.obj, offset, type)
+                return textRangeToList(ret)
+
+        def removeSelection(self, selectionNum):
+                """
+                Deselect the text contained in the specified selectionNum, if
+                such a selection exists, otherwise do nothing. Removal of a non-existant
+                selectionNum has no effect. 
+                @param : selectionNum
+                indicates which of a set of non-contiguous selections to modify.
+                @return True if the selection was successfully removed, False
+                otherwise.
+                """
+                return Atspi.Text.remove_selection(self.obj, index)
+
+        def setCaretOffset(self, offset):
+                """
+                Programmatically move the text caret (visible or virtual, as
+                above) to a given position. 
+                @param : offset
+                a long int indicating the desired character offset. Not all implementations
+                of Text will honor setCaretOffset requests, so the return value
+                below should be checked by the client. 
+                @return TRUE if the request was carried out, or FALSE if the
+                caret could not be moved to the requested position.
+                """
+                return Atspi.Text.set_caret_offset(self.obj, offset)
+
+        def setSelection(self, selectionNum, startOffset, endOffset):
+                """
+                Modify an existing selection's start or ending offset.
+                Calling setSelection for a selectionNum that is not already defined
+                has no effect. The result of calling setSelection with a selectionNum
+                greater than 0 for objects that do not include STATE_MULTISELECTABLE
+                is undefined. 
+                @param : selectionNum
+                indicates which of a set of non-contiguous selections to modify.
+                @param : startOffset
+                the new starting offset for the selection 
+                @param : endOffset
+                the new ending offset for the selection 
+                @return True if the selection corresponding to selectionNum is
+                successfully modified, False otherwise.
+                """
+                return Atspi.Text.set_selection(self.obj, selectionNum, startOffset, endOffset)
+
+        def get_caretOffset(self):
+                return Atspi.Text.get_caret_offset(self.obj)
+        _caretOffsetDoc = \
+                """
+                The current offset of the text caret in the Text object. This
+                caret may be virtual, e.g. non-visual and notional-only, but
+                if an onscreen representation of the caret position is visible,
+                it will correspond to this offset. The caret offset is given
+                as a character offset, as opposed to a byte offset into a text
+                buffer or a column offset.
+                """
+        caretOffset = property(fget=get_caretOffset, doc=_caretOffsetDoc)
+
+        def get_characterCount(self):
+                return Atspi.Text.get_character_count(self.obj)
+        _characterCountDoc = \
+                """
+                The total current number of characters in the Text object, including
+                whitespace and non-spacing characters.
+                """
+        characterCount = property(fget=get_characterCount, doc=_characterCountDoc)
+
+def textRangeToList(r):
+        return (r.content, r.start_offset, r.end_offset)
diff --git a/pyatspi/utils.py b/pyatspi/utils.py
index d505125..adea61a 100644
--- a/pyatspi/utils.py
+++ b/pyatspi/utils.py
@@ -322,3 +322,9 @@ def getPath(acc):
                 except Exception:
                         raise LookupError
                 acc = acc.parent
+
+def pointToList(point):
+	return (point.x, point.y)
+
+def rectToList(rect):
+	return (rect.x, rect.y, rect.width, rect.height)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]