1 #Copyright (C) 2008 Codethink Ltd
3 #This library is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU Lesser General Public
5 #License version 2 as published by the Free Software Foundation.
7 #This program is distributed in the hope that it will be useful,
8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 #GNU General Public License for more details.
11 #You should have received a copy of the GNU Lesser General Public License
12 #along with this program; if not, write to the Free Software
13 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 from base import BaseProxy, Enum
19 from factory import add_accessible_class
25 "TEXT_BOUNDARY_WORD_START",
26 "TEXT_BOUNDARY_WORD_END",
27 "TEXT_BOUNDARY_SENTENCE_START",
28 "TEXT_BOUNDARY_SENTENCE_END",
29 "TEXT_BOUNDARY_LINE_START",
30 "TEXT_BOUNDARY_LINE_END",
38 #------------------------------------------------------------------------------
40 class TEXT_BOUNDARY_TYPE(Enum):
42 0:'TEXT_BOUNDARY_CHAR',
43 1:'TEXT_BOUNDARY_WORD_START',
44 2:'TEXT_BOUNDARY_WORD_END',
45 3:'TEXT_BOUNDARY_SENTENCE_START',
46 4:'TEXT_BOUNDARY_SENTENCE_END',
47 5:'TEXT_BOUNDARY_LINE_START',
48 6:'TEXT_BOUNDARY_LINE_END',
51 TEXT_BOUNDARY_CHAR = TEXT_BOUNDARY_TYPE(0)
52 TEXT_BOUNDARY_LINE_END = TEXT_BOUNDARY_TYPE(6)
53 TEXT_BOUNDARY_LINE_START = TEXT_BOUNDARY_TYPE(5)
54 TEXT_BOUNDARY_SENTENCE_END = TEXT_BOUNDARY_TYPE(4)
55 TEXT_BOUNDARY_SENTENCE_START = TEXT_BOUNDARY_TYPE(3)
56 TEXT_BOUNDARY_WORD_END = TEXT_BOUNDARY_TYPE(2)
57 TEXT_BOUNDARY_WORD_START = TEXT_BOUNDARY_TYPE(1)
59 #------------------------------------------------------------------------------
61 class TEXT_CLIP_TYPE(Enum):
69 TEXT_CLIP_BOTH = TEXT_CLIP_TYPE(3)
70 TEXT_CLIP_MAX = TEXT_CLIP_TYPE(2)
71 TEXT_CLIP_MIN = TEXT_CLIP_TYPE(1)
72 TEXT_CLIP_NONE = TEXT_CLIP_TYPE(0)
74 #------------------------------------------------------------------------------
76 class Text(BaseProxy):
78 The text interface should be implemented by objects which place
79 textual information onscreen as character strings or glyphs.
80 The text interface allows access to textual content, including
81 display attributes and semantic hints associated with runs of
82 text, and access to bounding box information for glyphs and substrings.
83 It also allows portions of textual content to be selected, if
84 the object's StateSet includes STATE_SELECTABLE_TEXT.
85 In some cases a Text object may have, as its content, an empty
86 string. In particular this can occur in the case of Hypertext
87 objects which do not display explicitly textual information onscreen,
88 as Hypertext is derived from the Text interface.
89 Typographic and semantic attributes of onscreen textual content,
90 for instance typeface, weight, language, and such qualities as
91 'emphasis' or 'blockquote', are represented as text attributes.
92 Contiguous sequences of characters over which these attributes
93 are unchanged are referred to as "attribute runs", and are available
94 via Text::getAttributeRun. Where possible, implementing clients
95 will report textual attributes which are the same over the entire
96 text object, for instance those inherited from a default or document-scope
97 style, via getDefaultAttributes instead of reporting them explicitly
98 for each character. Therefore, for any span of text, the attributes
99 in effect are the union of the set returned by Text::getDefaultAttributes,
100 and the set returned at a particular character offset via Text::getAttributeRun.
103 def addSelection(self, *args, **kwargs):
105 The result of calling addSelection on objects which already have
106 one selection present, and which do not include STATE_MULTISELECTABLE,
107 is undefined, other than the return value.
108 @return True of the selection was successfully added, False otherwise.
109 Selection may fail if the object does not support selection of
110 text (see STATE_SELECTABLE_TEXT), if the object does not support
111 multiple selections and a selection is already defined, or for
112 other reasons (for instance if the user does not have permission
113 to copy the text into the relevant selection buffer).
115 func = self.get_dbus_method("addSelection")
116 return func(*args, **kwargs)
118 def getAttributeRun(self, *args, **kwargs):
120 Query a particular text object for the text attributes defined
121 at a given offset, obtaining the start and end of the "attribute
122 run" over which these attributes are currently invariant. Text
123 attributes are those presentational, typographic, or semantic
124 attributes or qualitites which apply to a range of text specifyable
125 by starting and ending offsets. Attributes relevant to localization
126 should be provided in accordance with the w3c "Internationalization
127 and Localization Markup Requirements", http://www.w3.org/TR/2005/WD-itsreq-20051122/
128 Other text attributes should choose their names and value semantics
129 in accordance with relevant standards such as CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512),
130 XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and
131 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). Those attributes
132 from the aforementioned specifications and recommendations which
133 do not concern typographic, presentational, or semantic aspects
134 of text should be exposed via the more general Accessible::getAttributes()
136 For example, CSS attributes which should be exposed on text (either
137 as default attributes, or as explicitly-set attributes when non-default
138 values are specified in the content view) include the Font attributes
139 (i.e. "css2:font-weight", "css2:font-style"), the "css2:color"
140 and "css2:background-color" attributes, and "css2:text-decoration"
142 If includeDefaults is TRUE, then this AttributeSet should include
143 the default attributes as well as those which are explicitly
144 assigned to the attribute run in question. startOffset and endOffset
145 will be back-filled to indicate the start and end of the attribute
146 run which contains 'offset' - an attribute run is a contiguous
147 section of text whose attributes are homogeneous.
149 the offset of the character whose attributes will be reported.
151 backfilled with the starting offset of the character range over
152 which all text attributes match those of offset, i.e. the start
153 of the homogeneous attribute run including offset.
155 backfilled with the offset of the first character past the character
156 range over which all text attributes match those of offset, i.e.
157 the character immediately after the homogeneous attribute run
159 @param : includeDefaults
160 if False, the call should only return those attributes which
161 are explicitly set on the current attribute run, omitting any
162 attributes which are inherited from the default values. See also
163 Text::getDefaultAttributes.
164 @return the AttributeSet defined at offset, optionally including
165 the 'default' attributes.
167 func = self.get_dbus_method("getAttributeRun")
168 return func(*args, **kwargs)
170 def getAttributeValue(self, *args, **kwargs):
172 Get the string value of a named attribute at a given offset,
175 the offset of the character for which the attribute run is to
177 @param : attributeName
178 the name of the attribute for which the value is to be returned,
181 back-filled with the offset of the first character in the attribute
182 run containing the character at offset.
184 back-filled with the offset of the first character past the end
185 of the attribute run containing the character at offset.
187 back-filled with True if the attributeName has a defined value
188 at offset, False otherwise.
189 @return the value of attribute (name-value pair) corresponding
190 to "name", if defined.
192 func = self.get_dbus_method("getAttributeValue")
193 return func(*args, **kwargs)
195 def getAttributes(self, offset):
197 getAttributes is deprecated in favor of getAttributeRun.
198 @return the attributes at offset, as a semicolon-delimited set
199 of colon-delimited name-value pairs.
201 func = self.get_dbus_method("getAttributes")
202 return func(dbus.Int32(offset))
204 def getBoundedRanges(self, *args, **kwargs):
206 Return the text content within a bounding box, as a list of Range
207 structures. Depending on the TEXT_CLIP_TYPE parameters, glyphs
208 which are clipped by the bounding box (i.e. which lie partially
209 inside and partially outside it) may or may not be included in
212 the minimum x ( i.e. leftmost) coordinate of the bounding box.
214 the minimum y coordinate of the bounding box.
216 the horizontal size of the bounding box. The rightmost bound
217 of the bounding box is (x + width);
219 the vertical size of the bounding box. The maximum y value of
220 the bounding box is (y + height);
222 If 0, the above coordinates are interpreted as pixels relative
223 to corner of the screen; if 1, the coordinates are interpreted
224 as pixels relative to the corner of the containing toplevel window.
226 determines whether text which intersects the bounding box in
227 the x direction is included.
229 determines whether text which intersects the bounding box in
230 the y direction is included.
232 func = self.get_dbus_method("getBoundedRanges")
233 return func(*args, **kwargs)
235 def getCharacterAtOffset(self, *args, **kwargs):
237 @return an unsigned long integer whose value corresponds to the
238 UCS-4 representation of the character at the specified text offset,
239 or 0 if offset is out of range.
241 func = self.get_dbus_method("getCharacterAtOffset")
242 return func(*args, **kwargs)
244 def getCharacterExtents(self, *args, **kwargs):
246 Obtain a the bounding box, as x, y, width, and height, of the
247 character or glyph at a particular character offset in this object's
248 text content. The coordinate system in which the results are
249 reported is specified by coordType. If an onscreen glyph corresponds
250 to multiple character offsets, for instance if the glyph is a
251 ligature, the bounding box reported will include the entire glyph
252 and therefore may apply to more than one character offset.
254 the character offset of the character or glyph being queried.
256 the minimum horizontal coordinate of the bounding box of the
257 glyph representing the character at offset.
259 the minimum vertical coordinate of the bounding box of the glyph
260 representing the character at offset.
262 the horizontal extent of the bounding box of the glyph representing
263 the character at offset.
265 the vertical extent of the bounding box of the glyph representing
266 the character at offset.
268 If 0, the results will be reported in screen coordinates, i.e.
269 in pixels relative to the upper-left corner of the screen, with
270 the x axis pointing right and the y axis pointing down. If 1,
271 the results will be reported relative to the containing toplevel
272 window, with the x axis pointing right and the y axis pointing
275 func = self.get_dbus_method("getCharacterExtents")
276 return func(*args, **kwargs)
278 def getDefaultAttributeSet(self, *args, **kwargs):
280 Return an AttributeSet containing the text attributes which apply
281 to all text in the object by virtue of the default settings of
282 the document, view, or user agent; e.g. those attributes which
283 are implied rather than explicitly applied to the text object.
284 For instance, an object whose entire text content has been explicitly
285 marked as 'bold' will report the 'bold' attribute via getAttributeRun(),
286 whereas an object whose text weight is inspecified may report
287 the default or implied text weight in the default AttributeSet.
289 func = self.get_dbus_method("getDefaultAttributeSet")
290 return func(*args, **kwargs)
292 def getDefaultAttributes(self, *args, **kwargs):
294 Deprecated in favor of getDefaultAttributeSet.
295 @return the attributes which apply to the entire text content,
296 but which were not explicitly specified by the content creator.
298 func = self.get_dbus_method("getDefaultAttributes")
299 return func(*args, **kwargs)
301 def getNSelections(self, *args, **kwargs):
303 Obtain the number of separate, contiguous selections in the current
304 Text object. Text objects which do not implement selection of
305 discontiguous text regions will always return '0' or '1'. Note
306 that "contiguous" is defined by continuity of the offsets, i.e.
307 a text 'selection' is defined by a start/end offset pair. In
308 the case of bidirectional text, this means that a continguous
309 selection may appear visually discontiguous, and vice-versa.
310 @return the number of contiguous selections in the current Text
313 func = self.get_dbus_method("getNSelections")
314 return func(*args, **kwargs)
316 def getOffsetAtPoint(self, *args, **kwargs):
318 Get the offset of the character at a given onscreen coordinate.
319 The coordinate system used to interpret x and y is determined
320 by parameter coordType.
324 if 0, the input coordinates are interpreted relative to the entire
325 screen, if 1, they are relative to the toplevel window containing
327 @return the text offset (as an offset into the character array)
328 of the glyph whose onscreen bounds contain the point x,y, or
329 -1 if the point is outside the bounds of any glyph.
331 func = self.get_dbus_method("getOffsetAtPoint")
332 return func(*args, **kwargs)
334 def getRangeExtents(self, *args, **kwargs):
336 Obtain the bounding box which entirely contains a given text
337 range. Negative values may be returned for the bounding box parameters
338 in the event that all or part of the text range is offscreen
339 or not mapped to the screen.
341 the offset of the first character in the specified range.
343 the offset of the character immediately after the last character
344 in the specified range.
346 an integer parameter which is back-filled with the minimum horizontal
347 coordinate of the resulting bounding box.
349 an integer parameter which is back-filled with the minimum vertical
350 coordinate of the resulting bounding box.
352 an integer parameter which is back-filled with the horizontal
353 extent of the bounding box.
355 an integer parameter which is back-filled with the vertical extent
358 If 0, the above coordinates are reported in pixels relative to
359 corner of the screen; if 1, the coordinates are reported relative
360 to the corner of the containing toplevel window.
362 func = self.get_dbus_method("getRangeExtents")
363 return func(*args, **kwargs)
365 def getSelection(self, *args, **kwargs):
367 The result of calling getSelection with an out-of-range selectionNum
368 (i.e. for a selection which does not exist) is not strictly defined,
369 but should set endOffset equal to startOffset.
371 func = self.get_dbus_method("getSelection")
372 return func(*args, **kwargs)
374 def getText(self, startOffset, endOffset):
376 Obtain all or part of the onscreen textual content of a Text
377 object. If endOffset is specified as "-1", then this method will
378 return the entire onscreen textual contents of the Text object.
379 @return the textual content of the current Text object beginning
380 startOffset (inclusive) up to but not including the character
383 func = self.get_dbus_method("getText")
386 return func(dbus.Int32(startOffset), dbus.Int32(endOffset))
388 def getTextAfterOffset(self, *args, **kwargs):
390 Obtain a subset of the text content of an object which entirely
391 follows offset, delimited by character, word, line, or sentence
392 boundaries as specified by type. The starting and ending offsets
393 of the resulting substring are returned in startOffset and endOffset.
394 By definition, if such a substring exists, startOffset must be
397 the offset from which the substring search begins, and which
398 must lie before the returned substring.
400 the text-boundary delimiter which determines whether the returned
401 text constitures a character, word, line, or sentence (and possibly
402 attendant whitespace), and whether the start or ending of such
403 a substring forms the boundary condition.
405 back-filled with the starting offset of the resulting substring,
408 back-filled with the offset of the character immediately following
409 the resulting substring, if one exists.
410 @return a string which is a substring of the text content of
411 the object, delimited by the specified boundary condition.
413 func = self.get_dbus_method("getTextAfterOffset")
414 return func(*args, **kwargs)
416 def getTextAtOffset(self, *args, **kwargs):
418 Obtain a subset of the text content of an object which includes
419 the specified offset, delimited by character, word, line, or
420 sentence boundaries as specified by type. The starting and ending
421 offsets of the resulting substring are returned in startOffset
424 the offset from which the substring search begins, and which
425 must lie within the returned substring.
427 the text-boundary delimiter which determines whether the returned
428 text constitures a character, word, line, or sentence (and possibly
429 attendant whitespace), and whether the start or ending of such
430 a substring forms the boundary condition.
432 back-filled with the starting offset of the resulting substring,
435 back-filled with the offset of the character immediately following
436 the resulting substring, if one exists.
437 @return a string which is a substring of the text content of
438 the object, delimited by the specified boundary condition.
440 func = self.get_dbus_method("getTextAtOffset")
441 return func(*args, **kwargs)
443 def getTextBeforeOffset(self, *args, **kwargs):
445 Obtain a subset of the text content of an object which entirely
446 precedes offset, delimited by character, word, line, or sentence
447 boundaries as specified by type. The starting and ending offsets
448 of the resulting substring are returned in startOffset and endOffset.
449 By definition, if such a substring exists, endOffset is less
450 than or equal to offset.
452 the offset from which the substring search begins.
454 the text-boundary delimiter which determines whether the returned
455 text constitures a character, word, line, or sentence (and possibly
456 attendant whitespace), and whether the start or ending of such
457 a substring forms the boundary condition.
459 back-filled with the starting offset of the resulting substring,
462 back-filled with the offset of the character immediately following
463 the resulting substring, if one exists.
464 @return a string which is a substring of the text content of
465 the object, delimited by the specified boundary condition.
467 func = self.get_dbus_method("getTextBeforeOffset")
468 return func(*args, **kwargs)
470 def removeSelection(self, *args, **kwargs):
472 Deselect the text contained in the specified selectionNum, if
473 such a selection exists, otherwise do nothing. Removal of a non-existant
474 selectionNum has no effect.
475 @return True if the selection was successfully removed, False
478 func = self.get_dbus_method("removeSelection")
479 return func(*args, **kwargs)
481 def setCaretOffset(self, *args, **kwargs):
483 Programmatically move the text caret (visible or virtual, as
484 above) to a given position.
486 a long int indicating the desired character offset. Not all implementations
487 of Text will honor setCaretOffset requests, so the return value
488 below should be checked by the client.
489 @return TRUE if the request was carried out, or FALSE if the
490 caret could not be moved to the requested position.
492 func = self.get_dbus_method("setCaretOffset")
493 return func(*args, **kwargs)
495 def setSelection(self, *args, **kwargs):
497 Modify an existing selection's start or ending offset.
498 Calling setSelection for a selectionNum that is not already defined
499 has no effect. The result of calling setSelection with a selectionNum
500 greater than 0 for objects that do not include STATE_MULTISELECTABLE
502 @param : selectionNum
503 indicates which of a set of non-contiguous selections to modify.
505 the new starting offset for the selection
507 the new ending offset for the selection
508 @return True if the selection corresponding to selectionNum is
509 successfully modified, False otherwise.
511 func = self.get_dbus_method("setSelection")
512 return func(*args, **kwargs)
514 def get_caretOffset(self):
515 return self._pgetter(self._dbus_interface, "caretOffset")
516 def set_caretOffset(self, value):
517 self._psetter(self._dbus_interface, "caretOffset", value)
520 The current offset of the text caret in the Text object. This
521 caret may be virtual, e.g. non-visual and notional-only, but
522 if an onscreen representation of the caret position is visible,
523 it will correspond to this offset. The caret offset is given
524 as a character offset, as opposed to a byte offset into a text
525 buffer or a column offset.
527 caretOffset = property(fget=get_caretOffset, fset=set_caretOffset, doc=_caretOffsetDoc)
529 def get_characterCount(self):
530 return self._pgetter(self._dbus_interface, "characterCount")
531 def set_characterCount(self, value):
532 self._psetter(self._dbus_interface, "characterCount", value)
533 _characterCountDoc = \
535 The total current number of characters in the Text object, including
536 whitespace and non-spacing characters.
538 characterCount = property(fget=get_characterCount, fset=set_characterCount, doc=_characterCountDoc)
541 def __new__(cls, startOffset, endOffset, content, data):
542 list.__new__(cls, (startOffset, endOffset, content, data))
543 def __init__(self, startOffset, endOffset, content, data):
544 list.__init__(self, (startOffset, endOffset, content, data))
546 def _get_startOffset(self):
548 def _set_startOffset(self, val):
550 startOffset = property(fget=_get_startOffset, fset=_set_startOffset)
551 def _get_endOffset(self):
553 def _set_endOffset(self, val):
555 endOffset = property(fget=_get_endOffset, fset=_set_endOffset)
556 def _get_content(self):
558 def _set_content(self, val):
560 content = property(fget=_get_content, fset=_set_content)
563 def _set_data(self, val):
565 data = property(fget=_get_data, fset=_set_data)
567 # ATTENTION - Register the Application class with the accessible factory.
568 add_accessible_class(interfaces.ATSPI_TEXT, Text)
570 #END----------------------------------------------------------------------------