1#Copyright (C) 2008 Codethink Ltd
2#Copyright (C) 2010 Novell, Inc.
3
4#This library is free software; you can redistribute it and/or
5#modify it under the terms of the GNU Lesser General Public
6#License version 2 as published by the Free Software Foundation.
7
8#This program is distributed in the hope that it will be useful,
9#but WITHOUT ANY WARRANTY; without even the implied warranty of
10#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#GNU General Public License for more details.
12#You should have received a copy of the GNU Lesser General Public License
13#along with this program; if not, write to the Free Software
14#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
16from gi.repository import Atspi
17from pyatspi.atspienum import *
18from pyatspi.utils import *
19from pyatspi.interface import *
20
21
22__all__ = [
23           "Text",
24           "TEXT_BOUNDARY_TYPE",
25           "TEXT_BOUNDARY_CHAR",
26           "TEXT_BOUNDARY_WORD_START",
27           "TEXT_BOUNDARY_WORD_END",
28           "TEXT_BOUNDARY_SENTENCE_START",
29           "TEXT_BOUNDARY_SENTENCE_END",
30           "TEXT_BOUNDARY_LINE_START",
31           "TEXT_BOUNDARY_LINE_END",
32           "TEXT_CLIP_TYPE",
33           "TEXT_CLIP_NONE",
34           "TEXT_CLIP_MIN",
35           "TEXT_CLIP_MAX",
36           "TEXT_CLIP_BOTH",
37           "TEXT_GRANULARITY_CHAR",
38           "TEXT_GRANULARITY_WORD",
39           "TEXT_GRANULARITY_SENTENCE",
40           "TEXT_GRANULARITY_LINE",
41           "TEXT_GRANULARITY_PARAGRAPH",
42          ]
43
44#------------------------------------------------------------------------------
45
46class TEXT_BOUNDARY_TYPE(AtspiEnum):
47        _enum_lookup = {
48                0:'TEXT_BOUNDARY_CHAR',
49                1:'TEXT_BOUNDARY_WORD_START',
50                2:'TEXT_BOUNDARY_WORD_END',
51                3:'TEXT_BOUNDARY_SENTENCE_START',
52                4:'TEXT_BOUNDARY_SENTENCE_END',
53                5:'TEXT_BOUNDARY_LINE_START',
54                6:'TEXT_BOUNDARY_LINE_END',
55        }
56
57TEXT_BOUNDARY_CHAR = TEXT_BOUNDARY_TYPE(0)
58TEXT_BOUNDARY_LINE_END = TEXT_BOUNDARY_TYPE(6)
59TEXT_BOUNDARY_LINE_START = TEXT_BOUNDARY_TYPE(5)
60TEXT_BOUNDARY_SENTENCE_END = TEXT_BOUNDARY_TYPE(4)
61TEXT_BOUNDARY_SENTENCE_START = TEXT_BOUNDARY_TYPE(3)
62TEXT_BOUNDARY_WORD_END = TEXT_BOUNDARY_TYPE(2)
63TEXT_BOUNDARY_WORD_START = TEXT_BOUNDARY_TYPE(1)
64
65#------------------------------------------------------------------------------
66
67class TEXT_CLIP_TYPE(AtspiEnum):
68        _enum_lookup = {
69                0:'TEXT_CLIP_NONE',
70                1:'TEXT_CLIP_MIN',
71                2:'TEXT_CLIP_MAX',
72                3:'TEXT_CLIP_BOTH',
73        }
74
75TEXT_CLIP_BOTH = TEXT_CLIP_TYPE(3)
76TEXT_CLIP_MAX = TEXT_CLIP_TYPE(2)
77TEXT_CLIP_MIN = TEXT_CLIP_TYPE(1)
78TEXT_CLIP_NONE = TEXT_CLIP_TYPE(0)
79
80#------------------------------------------------------------------------------
81
82class TEXT_GRANULARITY_TYPE(AtspiEnum):
83        _enum_lookup = {
84                0:'TEXT_GRANULARITY_CHAR',
85                1:'TEXT_GRANULARITY_WORD',
86                2:'TEXT_GRANULARITY_SENTENCE',
87                3:'TEXT_GRANULARITY_LINE',
88                4:'TEXT_GRANULARITY_PARAGRAPH',
89        }
90
91TEXT_GRANULARITY_CHAR = TEXT_GRANULARITY_TYPE(0)
92TEXT_GRANULARITY_WORD = TEXT_GRANULARITY_TYPE(1)
93TEXT_GRANULARITY_SENTENCE = TEXT_GRANULARITY_TYPE(2)
94TEXT_GRANULARITY_LINE = TEXT_GRANULARITY_TYPE(3)
95TEXT_GRANULARITY_PARAGRAPH = TEXT_GRANULARITY_TYPE(4)
96
97#------------------------------------------------------------------------------
98
99class Text(interface):
100        """
101        The text interface should be implemented by objects which place
102        textual information onscreen as character strings or glyphs.
103        The text interface allows access to textual content, including
104        display attributes and semantic hints associated with runs of
105        text, and access to bounding box information for glyphs and substrings.
106        It also allows portions of textual content to be selected, if
107        the object's StateSet includes STATE_SELECTABLE_TEXT.
108        In some cases a Text object may have, as its content, an empty
109        string. In particular this can occur in the case of Hypertext
110        objects which do not display explicitly textual information onscreen,
111        as Hypertext is derived from the Text interface.
112        Typographic and semantic attributes of onscreen textual content,
113        for instance typeface, weight, language, and such qualities as
114        'emphasis' or 'blockquote', are represented as text attributes.
115        Contiguous sequences of characters over which these attributes
116        are unchanged are referred to as "attribute runs", and are available
117        via Text::getAttributeRun. Where possible, implementing clients
118        will report textual attributes which are the same over the entire
119        text object, for instance those inherited from a default or document-scope
120        style, via getDefaultAttributes instead of reporting them explicitly
121        for each character. Therefore, for any span of text, the attributes
122        in effect are the union of the set returned by Text::getDefaultAttributes,
123        and the set returned at a particular character offset via Text::getAttributeRun.
124        """
125
126        def addSelection(self, startOffset, endOffset):
127                """
128                The result of calling addSelection on objects which already have
129                one selection present, and which do not include STATE_MULTISELECTABLE,
130                is undefined, other than the return value.
131                @return True of the selection was successfully added, False otherwise.
132                Selection may fail if the object does not support selection of
133                text (see STATE_SELECTABLE_TEXT), if the object does not support
134                multiple selections and a selection is already defined, or for
135                other reasons (for instance if the user does not have permission
136                to copy the text into the relevant selection buffer).
137                """
138                return Atspi.Text.add_selection(self.obj, startOffset, endOffset)
139
140        def getAttributeRun(self, offset, includeDefaults=True):
141                """
142                Query a particular text object for the text attributes defined
143                at a given offset, obtaining the start and end of the "attribute
144                run" over which these attributes are currently invariant. Text
145                attributes are those presentational, typographic, or semantic
146                attributes or qualitites which apply to a range of text specifyable
147                by starting and ending offsets. Attributes relevant to localization
148                should be provided in accordance with the w3c "Internationalization
149                and Localization Markup Requirements", http://www.w3.org/TR/2005/WD-itsreq-20051122/
150                Other text attributes should choose their names and value semantics
151                in accordance with relevant standards such as CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512),
152                XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and
153                WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). Those attributes
154                from the aforementioned specifications and recommendations which
155                do not concern typographic, presentational, or semantic aspects
156                of text should be exposed via the more general Accessible::getAttributes()
157                API (if at all).
158                For example, CSS attributes which should be exposed on text (either
159                as default attributes, or as explicitly-set attributes when non-default
160                values are specified in the content view) include the Font attributes
161                (i.e. "css2:font-weight", "css2:font-style"), the "css2:color"
162                and "css2:background-color" attributes, and "css2:text-decoration"
163                attribute.
164                If includeDefaults is TRUE, then this AttributeSet should include
165                the default attributes as well as those which are explicitly
166                assigned to the attribute run in question. startOffset and endOffset
167                will be back-filled to indicate the start and end of the attribute
168                run which contains 'offset' - an attribute run is a contiguous
169                section of text whose attributes are homogeneous.
170                @param : offset
171                the offset of the character whose attributes will be reported.
172                @param : startOffset
173                backfilled with the starting offset of the character range over
174                which all text attributes match those of offset, i.e. the start
175                of the homogeneous attribute run including offset.
176                @param : endOffset
177                backfilled with the offset of the first character past the character
178                range over which all text attributes match those of offset, i.e.
179                the character immediately after the homogeneous attribute run
180                including offset.
181                @param : includeDefaults
182                if False, the call should only return those attributes which
183                are explicitly set on the current attribute run, omitting any
184                attributes which are inherited from the default values. See also
185                Text::getDefaultAttributes.
186                @return the AttributeSet defined at offset, optionally including
187                the 'default' attributes.
188                """
189                [attrs, startOffset, endOffset] = Atspi.Text.get_attribute_run(self.obj, offset, includeDefaults)
190                dict = [key + ':' + value for key, value in attrs.items()]
191                return [dict, startOffset, endOffset]
192
193        def getAttributeValue(self, offset, attributeName):
194                """
195                Get the string value of a named attribute at a given offset,
196                if defined.
197                @param : offset
198                the offset of the character for which the attribute run is to
199                be obtained.
200                @param : attributeName
201                the name of the attribute for which the value is to be returned,
202                if defined.
203                @param : startOffset
204                back-filled with the offset of the first character in the attribute
205                run containing the character at offset.
206                @param : endOffset
207                back-filled with the offset of the first character past the end
208                of the attribute run containing the character at offset.
209                @param : defined
210                back-filled with True if the attributeName has a defined value
211                at offset, False otherwise.
212                @return the value of attribute (name-value pair) corresponding
213                to "name", if defined.
214                """
215                return Atspi.Text.get_text_attribute_value(self.obj, offset, attributeName)
216
217        def getAttributes(self, offset):
218                """
219                getAttributes is deprecated in favor of getAttributeRun.
220                @return the attributes at offset, as a semicolon-delimited set
221                of colon-delimited name-value pairs.
222                """
223                [attrs, startOffset, endOffset] = Atspi.Text.get_text_attributes(self.obj, offset)
224                arr = [key + ':' + value for key, value in attrs.items()]
225                str = ';'.join (arr)
226                return [str, startOffset, endOffset]
227
228        def getBoundedRanges(self, x, y, width, height, coordType, xClipType, yClipType):
229                """
230                Return the text content within a bounding box, as a list of Range
231                structures. Depending on the TEXT_CLIP_TYPE parameters, glyphs
232                which are clipped by the bounding box (i.e. which lie partially
233                inside and partially outside it) may or may not be included in
234                the ranges returned.
235                @param : x
236                the minimum x ( i.e. leftmost) coordinate of the bounding box.
237                @param : y
238                the minimum y coordinate of the bounding box.
239                @param : width
240                the horizontal size of the bounding box. The rightmost bound
241                of the bounding box is (x + width);
242                @param : height
243                the vertical size of the bounding box. The maximum y value of
244                the bounding box is (y + height);
245                @param : coordType
246                If 0, the above coordinates are interpreted as pixels relative
247                to corner of the screen; if 1, the coordinates are interpreted
248                as pixels relative to the corner of the containing toplevel window.
249                @param : xClipType
250                determines whether text which intersects the bounding box in
251                the x direction is included.
252                @param : yClipType
253                determines whether text which intersects the bounding box in
254                the y direction is included.
255                """
256                return Atspi.Text.get_bounded_ranges(self.obj, x, y, width, height, coordType, xClipType, yClipType)
257
258        def getCharacterAtOffset(self, offset):
259                """
260                @param : offset
261                position
262                @return an unsigned long integer whose value corresponds to the
263                UCS-4 representation of the character at the specified text offset,
264                or 0 if offset is out of range.
265                """
266                return Atspi.Text.get_character_at_offset(self.obj, offset)
267
268        def getCharacterExtents(self, offset, coordType):
269                """
270                Obtain a the bounding box, as x, y, width, and height, of the
271                character or glyph at a particular character offset in this object's
272                text content. The coordinate system in which the results are
273                reported is specified by coordType. If an onscreen glyph corresponds
274                to multiple character offsets, for instance if the glyph is a
275                ligature, the bounding box reported will include the entire glyph
276                and therefore may apply to more than one character offset.
277                The returned values are meaningful only if the Text has
278                both STATE_VISIBLE and STATE_SHOWING.
279                @param : offset
280                the character offset of the character or glyph being queried.
281                @param : coordType
282                If 0, the results will be reported in screen coordinates, i.e.
283                in pixels relative to the upper-left corner of the screen, with
284                the x axis pointing right and the y axis pointing down. If 1,
285                the results will be reported relative to the containing toplevel
286                window, with the x axis pointing right and the y axis pointing
287                down.
288                """
289                ret = Atspi.Text.get_character_extents(self.obj, offset, coordType)
290                return rectToList(ret)
291
292        def getDefaultAttributeSet(self):
293                """
294                Return an AttributeSet containing the text attributes which apply
295                to all text in the object by virtue of the default settings of
296                the document, view, or user agent; e.g. those attributes which
297                are implied rather than explicitly applied to the text object.
298                For instance, an object whose entire text content has been explicitly
299                marked as 'bold' will report the 'bold' attribute via getAttributeRun(),
300                whereas an object whose text weight is inspecified may report
301                the default or implied text weight in the default AttributeSet.
302                """
303                return Atspi.Text.get_default_attributes(self.obj)
304
305                ret = Atspi.Text.get_default_attribute_set(self.obj)
306                return [key + ':' + value for key, value in ret.values()]
307
308        def getDefaultAttributes(self):
309                """
310                Deprecated in favor of getDefaultAttributeSet.
311                @return the attributes which apply to the entire text content,
312                but which were not explicitly specified by the content creator.
313                """
314                ret = Atspi.Text.get_default_attributes(self.obj)
315                return ';'.join([key + ':' + value for key, value in ret.items()])
316
317        def getNSelections(self):
318                """
319                Obtain the number of separate, contiguous selections in the current
320                Text object. Text objects which do not implement selection of
321                discontiguous text regions will always return '0' or '1'. Note
322                that "contiguous" is defined by continuity of the offsets, i.e.
323                a text 'selection' is defined by a start/end offset pair. In
324                the case of bidirectional text, this means that a continguous
325                selection may appear visually discontiguous, and vice-versa.
326                @return the number of contiguous selections in the current Text
327                object.
328                """
329                return Atspi.Text.get_n_selections(self.obj)
330
331        def getOffsetAtPoint(self, x, y, coordType):
332                """
333                Get the offset of the character at a given onscreen coordinate.
334                The coordinate system used to interpret x and y is determined
335                by parameter coordType.
336                @param : x
337                @param : y
338                @param : coordType
339                if 0, the input coordinates are interpreted relative to the entire
340                screen, if 1, they are relative to the toplevel window containing
341                this Text object.
342                @return the text offset (as an offset into the character array)
343                of the glyph whose onscreen bounds contain the point x,y, or
344                -1 if the point is outside the bounds of any glyph.
345                """
346                return Atspi.Text.get_offset_at_point(self.obj, x, y, coordType)
347
348        def getRangeExtents(self, startOffset, endOffset, coordType):
349                """
350                Obtain the bounding box which entirely contains a given text
351                range. Negative values may be returned for the bounding box parameters
352                in the event that all or part of the text range is offscreen
353                or not mapped to the screen.
354                The returned values are meaningful only if the Text has
355                both STATE_VISIBLE and STATE_SHOWING.
356                @param : startOffset
357                the offset of the first character in the specified range.
358                @param : endOffset
359                the offset of the character immediately after the last character
360                in the specified range.
361                @param : x
362                an integer parameter which is back-filled with the minimum horizontal
363                coordinate of the resulting bounding box.
364                @param : y
365                an integer parameter which is back-filled with the minimum vertical
366                coordinate of the resulting bounding box.
367                @param : width
368                an integer parameter which is back-filled with the horizontal
369                extent of the bounding box.
370                @param : height
371                an integer parameter which is back-filled with the vertical extent
372                of the bounding box.
373                @param : coordType
374                If 0, the above coordinates are reported in pixels relative to
375                corner of the screen; if 1, the coordinates are reported relative
376                to the corner of the containing toplevel window.
377                """
378                ret = Atspi.Text.get_range_extents(self.obj, startOffset, endOffset, coordType)
379                return rectToList(ret)
380
381        def getSelection(self, selectionNum):
382                """
383                The result of calling getSelection with an out-of-range selectionNum
384                (i.e. for a selection which does not exist) is not strictly defined,
385                but should set endOffset equal to startOffset.
386                @param : selectionNum
387                indicates which of a set of non-contiguous selections to modify.
388                @param : startOffset
389                back-filled with the starting offset of the resulting substring,
390                if one exists.
391                @param : endOffset
392                back-filled with the offset of the character immediately following
393                the resulting substring, if one exists.
394                """
395                ret = Atspi.Text.get_selection(self.obj, selectionNum)
396                return rangeToList(ret)
397
398        def getText(self, startOffset, endOffset):
399                """
400                Obtain all or part of the onscreen textual content of a Text
401                object. If endOffset is specified as "-1", then this method will
402                return the entire onscreen textual contents of the Text object.
403                @param : startOffset
404                back-filled with the starting offset of the resulting substring,
405                if one exists.
406                @param : endOffset
407                back-filled with the offset of the character immediately following
408                the resulting substring, if one exists.
409                @return the textual content of the current Text object beginning
410                startOffset (inclusive) up to but not including the character
411                at endOffset.
412                """
413                return Atspi.Text.get_text(self.obj, startOffset, endOffset)
414
415        def getTextAfterOffset(self, offset, type):
416                """
417                Deprecated in favor of getStringAtOffset.
418                Obtain a subset of the text content of an object which entirely
419                follows offset, delimited by character, word, line, or sentence
420                boundaries as specified by type. The starting and ending offsets
421                of the resulting substring are returned in startOffset and endOffset.
422                By definition, if such a substring exists, startOffset must be
423                greater than offset.
424                @param : offset
425                the offset from which the substring search begins, and which
426                must lie before the returned substring.
427                @param : type
428                the text-boundary delimiter which determines whether the returned
429                text constitures a character, word, line, or sentence (and possibly
430                attendant whitespace), and whether the start or ending of such
431                a substring forms the boundary condition.
432                @param : startOffset
433                back-filled with the starting offset of the resulting substring,
434                if one exists.
435                @param : endOffset
436                back-filled with the offset of the character immediately following
437                the resulting substring, if one exists.
438                @return a string which is a substring of the text content of
439                the object, delimited by the specified boundary condition.
440                """
441                ret = Atspi.Text.get_text_after_offset(self.obj, offset, type)
442                return textRangeToList(ret)
443
444        def getTextAtOffset(self, offset, type):
445                """
446                Deprecated in favor of getStringAtOffset.
447                Obtain a subset of the text content of an object which includes
448                the specified offset, delimited by character, word, line, or
449                sentence boundaries as specified by type. The starting and ending
450                offsets of the resulting substring are returned in startOffset
451                and endOffset.
452                @param : offset
453                the offset from which the substring search begins, and which
454                must lie within the returned substring.
455                @param : type
456                the text-boundary delimiter which determines whether the returned
457                text constitures a character, word, line, or sentence (and possibly
458                attendant whitespace), and whether the start or ending of such
459                a substring forms the boundary condition.
460                @param : startOffset
461                back-filled with the starting offset of the resulting substring,
462                if one exists.
463                @param : endOffset
464                back-filled with the offset of the character immediately following
465                the resulting substring, if one exists.
466                @return a string which is a substring of the text content of
467                the object, delimited by the specified boundary condition.
468                """
469                ret = Atspi.Text.get_text_at_offset(self.obj, offset, type)
470                return textRangeToList(ret)
471
472        def getTextBeforeOffset(self, offset, type):
473                """
474                Deprecated in favor of getStringAtOffset.
475                Obtain a subset of the text content of an object which entirely
476                precedes offset, delimited by character, word, line, or sentence
477                boundaries as specified by type. The starting and ending offsets
478                of the resulting substring are returned in startOffset and endOffset.
479                By definition, if such a substring exists, endOffset is less
480                than or equal to offset.
481                @param : offset
482                the offset from which the substring search begins.
483                @param : type
484                the text-boundary delimiter which determines whether the returned
485                text constitures a character, word, line, or sentence (and possibly
486                attendant whitespace), and whether the start or ending of such
487                a substring forms the boundary condition.
488                @param : startOffset
489                back-filled with the starting offset of the resulting substring,
490                if one exists.
491                @param : endOffset
492                back-filled with the offset of the character immediately following
493                the resulting substring, if one exists.
494                @return a string which is a substring of the text content of
495                the object, delimited by the specified boundary condition.
496                """
497                ret = Atspi.Text.get_text_before_offset(self.obj, offset, type)
498                return textRangeToList(ret)
499
500        def getStringAtOffset(self, offset, type):
501                """
502                Obtain a subset of the text content of an object which includes
503                the specified offset, delimited by character, word, line, sentence
504                or paragraph granularity as specified by type. The starting and ending
505                offsets of the resulting substring are returned in startOffset
506                and endOffset.
507                @param : offset
508                the offset from which the substring search begins, and which
509                must lie within the returned substring.
510                @param : type
511                the text granularity which determines whether the  returned text
512                constitures a character, word, line, sentence or paragraph (and
513                possibly attendant  whitespace). For all of those cases, boundaries
514                will always be defined from the start of the current substring to
515                the start of the following one for the same granularity.
516                @param : startOffset
517                back-filled with the starting offset of the resulting substring,
518                if one exists.
519                @param : endOffset
520                back-filled with the offset of the character immediately following
521                the resulting substring, if one exists.
522                @return a string which is a substring of the text content of
523                the object, delimited by the specified text granularity.
524                """
525                ret = Atspi.Text.get_string_at_offset(self.obj, offset, type)
526                return textRangeToList(ret)
527
528        def removeSelection(self, selectionNum):
529                """
530                Deselect the text contained in the specified selectionNum, if
531                such a selection exists, otherwise do nothing. Removal of a non-existant
532                selectionNum has no effect.
533                @param : selectionNum
534                indicates which of a set of non-contiguous selections to modify.
535                @return True if the selection was successfully removed, False
536                otherwise.
537                """
538                return Atspi.Text.remove_selection(self.obj, selectionNum)
539
540        def setCaretOffset(self, offset):
541                """
542                Programmatically move the text caret (visible or virtual, as
543                above) to a given position.
544                @param : offset
545                a long int indicating the desired character offset. Not all implementations
546                of Text will honor setCaretOffset requests, so the return value
547                below should be checked by the client.
548                @return TRUE if the request was carried out, or FALSE if the
549                caret could not be moved to the requested position.
550                """
551                return Atspi.Text.set_caret_offset(self.obj, offset)
552
553        def setSelection(self, selectionNum, startOffset, endOffset):
554                """
555                Modify an existing selection's start or ending offset.
556                Calling setSelection for a selectionNum that is not already defined
557                has no effect. The result of calling setSelection with a selectionNum
558                greater than 0 for objects that do not include STATE_MULTISELECTABLE
559                is undefined.
560                @param : selectionNum
561                indicates which of a set of non-contiguous selections to modify.
562                @param : startOffset
563                the new starting offset for the selection
564                @param : endOffset
565                the new ending offset for the selection
566                @return True if the selection corresponding to selectionNum is
567                successfully modified, False otherwise.
568                """
569                return Atspi.Text.set_selection(self.obj, selectionNum, startOffset, endOffset)
570
571        def get_caretOffset(self):
572                return Atspi.Text.get_caret_offset(self.obj)
573        _caretOffsetDoc = \
574                """
575                The current offset of the text caret in the Text object. This
576                caret may be virtual, e.g. non-visual and notional-only, but
577                if an onscreen representation of the caret position is visible,
578                it will correspond to this offset. The caret offset is given
579                as a character offset, as opposed to a byte offset into a text
580                buffer or a column offset.
581                """
582        caretOffset = property(fget=get_caretOffset, doc=_caretOffsetDoc)
583
584        def get_characterCount(self):
585                return Atspi.Text.get_character_count(self.obj)
586        _characterCountDoc = \
587                """
588                The total current number of characters in the Text object, including
589                whitespace and non-spacing characters.
590                """
591        characterCount = property(fget=get_characterCount, doc=_characterCountDoc)
592
593        def scrollSubstringTo(self, startOffset, endOffset, scroll_type):
594                """
595                Makes the text range visible on the screen at a given position by
596                scrolling all necessary parents.
597                @return True if scrolling was successful.
598                """
599                return Atspi.Text.scroll_substring_to(self.obj, startOffset, endOffset, scroll_type)
600
601        def scrollSubstringToPoint(self, startOffset, endOffset, coord_type, x, y):
602                """
603                Makes the text range visible on the screen at a given position by
604                scrolling all necessary parents.
605                @return True if scrolling was successful.
606                """
607                return Atspi.Text.scroll_substring_to_point(self.obj, startOffset, endOffset, coord_type, x, y)
608
609def rangeToList(r):
610        return (r.start_offset, r.end_offset)
611
612def textRangeToList(r):
613        return (r.content, r.start_offset, r.end_offset)
614