Improved atk docs for atktext.c
[platform/upstream/atk.git] / atk / atktext.c
1 /* ATK - The Accessibility Toolkit for GTK+
2  * Copyright 2001 Sun Microsystems Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "atktext.h"
21
22 enum {
23   TEXT_CHANGED,
24   CARET_MOVED,
25   LAST_SIGNAL
26 };
27
28 struct _AtkTextIfaceClass
29 {
30   GObjectClass parent;
31 };
32
33 typedef struct _AtkTextIfaceClass AtkTextIfaceClass;
34
35 static void atk_text_base_init (gpointer *g_class);
36
37 static guint atk_text_signals[LAST_SIGNAL] = { 0 };
38
39 GType
40 atk_text_get_type ()
41 {
42   static GType type = 0;
43
44   if (!type) 
45     {
46       static const GTypeInfo tinfo =
47       {
48         sizeof (AtkTextIface),
49         (GBaseInitFunc) atk_text_base_init,
50         (GBaseFinalizeFunc) NULL,
51         (GClassInitFunc) NULL /* atk_text_interface_init */ ,
52         (GClassFinalizeFunc) NULL,
53
54       };
55
56       type = g_type_register_static (G_TYPE_INTERFACE, "AtkText", &tinfo, 0);
57     }
58
59   return type;
60 }
61
62 static void
63 atk_text_base_init (gpointer *g_class)
64 {
65   static gboolean initialized = FALSE;
66
67   if (! initialized)
68     {
69    /* 
70     * Note that text_changed signal supports details "insert", "delete", 
71     * possibly "replace". 
72     */
73
74     atk_text_signals[TEXT_CHANGED] =
75       g_signal_newc ("text_changed",
76                      ATK_TYPE_TEXT,
77                      G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
78                      G_STRUCT_OFFSET (AtkTextIface, text_changed), 
79                      (GSignalAccumulator) NULL, NULL,
80                      g_cclosure_marshal_VOID__VOID,
81                      G_TYPE_NONE,
82                      0, G_TYPE_NONE);
83
84     atk_text_signals[CARET_MOVED] =
85       g_signal_newc ("text_caret_moved",
86                      ATK_TYPE_TEXT,
87                      G_SIGNAL_RUN_LAST,
88                      G_STRUCT_OFFSET (AtkTextIface, caret_changed),
89                      (GSignalAccumulator) NULL, NULL,
90                      g_cclosure_marshal_VOID__INT,
91                      G_TYPE_NONE,
92                      1, G_TYPE_INT);
93
94   initialized = TRUE;
95   }
96 }
97
98 /**
99  * atk_text_get_text:
100  * @text: an #AtkText
101  * @start_offset: start position
102  * @end_offset: end position
103  *
104  * Gets the specified text.
105  *
106  * Returns: the text from @start_offset up to, but not including @end_offset.
107  **/
108 gchar*
109 atk_text_get_text (AtkText      *text,
110                    gint         start_offset,
111                    gint         end_offset)
112 {
113   AtkTextIface *iface;
114
115   g_return_val_if_fail (text != NULL, NULL);
116   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
117
118   iface = ATK_TEXT_GET_IFACE (text);
119
120   if (iface->get_text)
121     return (*(iface->get_text)) (text, start_offset, end_offset);
122   else
123     return NULL;
124 }
125
126 /**
127  * atk_text_get_character_at_offset
128  * @text: an #AtkText
129  * @offset: position
130  *
131  * Gets the specified text.
132  *
133  * Returns: the character at @offset.
134  **/
135 gunichar
136 atk_text_get_character_at_offset (AtkText      *text,
137                                   gint         offset)
138 {
139   AtkTextIface *iface;
140
141   g_return_val_if_fail (text != NULL, (gunichar) 0);
142   g_return_val_if_fail (ATK_IS_TEXT (text), (gunichar) 0);
143
144   iface = ATK_TEXT_GET_IFACE (text);
145
146   if (iface->get_character_at_offset)
147     return (*(iface->get_character_at_offset)) (text, offset);
148   else
149     return (gunichar) 0;
150 }
151
152 /**
153  * atk_text_get_text_after_offset
154  * @text: an #AtkText
155  * @offset: position
156  * @boundary_type: An #AtkTextBoundary
157  *
158  * Gets the specified text.
159  * If the boundary type is ATK_TEXT_BOUNDARY_WORD_START or
160  * ATK_TEXT_BOUNDARY_WORD_END part of a word may be returned.
161  * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the start point 
162  * will be the offset and will continue to the start of the next sentence. 
163  * The first word may not be a complete word. Similarly for 
164  * ATK_TEXT_BOUNDARY_SENTENCE_END, ATK_TEXT_BOUNDARY_LINE_START and
165  * ATK_TEXT_BOUNDARY_LINE_END
166  *
167  * Returns: the text after @offset up to the specified @boundary_type.
168  **/
169 gchar*
170 atk_text_get_text_after_offset (AtkText          *text,
171                                 gint             offset,
172                                 AtkTextBoundary  boundary_type)
173 {
174   AtkTextIface *iface;
175
176   g_return_val_if_fail (text != NULL, NULL);
177   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
178
179   iface = ATK_TEXT_GET_IFACE (text);
180
181   if (iface->get_text_after_offset)
182     return (*(iface->get_text_after_offset)) (text, offset, boundary_type);
183   else
184     return NULL;
185 }
186
187 /**
188  * atk_text_get_text_at_offset
189  * @text: an #AtkText
190  * @offset: position
191  * @boundary_type: An #AtkTextBoundary
192  *
193  * Gets the specified text.
194  * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START or 
195  * ATK_TEXT_BOUNDARY_WORD_END a complete word is returned; 
196  * if the boundary type is  ATK_TEXT_BOUNDARY_SENTENCE_START or 
197  * ATK_TEXT_BOUNDARY_SENTENCE_END a complete sentence
198  * is returned; if the boundary type is ATK_TEXT_BOUNDARY_LINE_START or
199  * ATK_TEXT_BOUNDARY_LINE_END a complete line is returned.
200  *
201  * Returns: the text at @offset up to the specified @boundary_type.
202  **/
203 gchar*
204 atk_text_get_text_at_offset (AtkText          *text,
205                              gint             offset,
206                              AtkTextBoundary  boundary_type)
207 {
208   AtkTextIface *iface;
209
210   g_return_val_if_fail (text != NULL, NULL);
211   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
212
213   iface = ATK_TEXT_GET_IFACE (text);
214
215   if (iface->get_text_at_offset)
216     return (*(iface->get_text_at_offset)) (text, offset, boundary_type);
217   else
218     return NULL;
219 }
220
221 /**
222  * atk_text_get_text_before_offset
223  * @text: an #AtkText
224  * @offset: position
225  * @boundary_type: An #AtkTextBoundary
226  *
227  * Gets the specified text.
228  * If the boundary type is ATK_TEXT_BOUNDARY_WORD_START or
229  * ATK_TEXT_BOUNDARY_WORD_END part of a word may be returned.
230  * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the start point 
231  * will be at the start of the sentence, and will continue to the offset. 
232  * The last word may not be a complete word. Similarly for 
233  * ATK_TEXT_BOUNDARY_SENTENCE_END, ATK_TEXT_BOUNDARY_LINE_START and
234  * ATK_TEXT_BOUNDARY_LINE_END
235  *
236  * Returns: the text before @offset starting from the specified @boundary_type.
237  **/
238 gchar*
239 atk_text_get_text_before_offset (AtkText          *text,
240                                  gint             offset,
241                                  AtkTextBoundary  boundary_type)
242 {
243   AtkTextIface *iface;
244
245   g_return_val_if_fail (text != NULL, NULL);
246   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
247
248   iface = ATK_TEXT_GET_IFACE (text);
249
250   if (iface->get_text_before_offset)
251     return (*(iface->get_text_before_offset)) (text, offset, boundary_type);
252   else
253     return NULL;
254 }
255
256 /**
257  * atk_text_get_caret_offset
258  * @text: an #AtkText
259  *
260  * Gets the offset position of the caret (cursor).
261  *
262  * Returns: the offset position of the caret (cursor).
263  **/
264 gint
265 atk_text_get_caret_offset (AtkText *text)
266 {
267   AtkTextIface *iface;
268
269   g_return_val_if_fail (text != NULL, -1);
270   g_return_val_if_fail (ATK_IS_TEXT (text), -1);
271
272   iface = ATK_TEXT_GET_IFACE (text);
273
274   if (iface->get_caret_offset)
275     return (*(iface->get_caret_offset)) (text);
276   else
277     return -1;
278 }
279
280 /**
281  * atk_text_get_row_col_at_offset
282  * @text: an #AtkText
283  * @offset: position
284  * @row: row number
285  * @col: column number
286  *
287  * Given an @offset, the @row and @col arguments are filled appropriately.
288  **/
289 void
290 atk_text_get_row_col_at_offset (AtkText *text,
291                                 gint offset,
292                                 gint *row,
293                                 gint *col)
294 {
295   AtkTextIface *iface;
296
297   g_return_if_fail (text != NULL);
298   g_return_if_fail (ATK_IS_TEXT (text));
299
300   iface = ATK_TEXT_GET_IFACE (text);
301
302   if (iface->get_row_col_at_offset)
303     (*(iface->get_row_col_at_offset)) (text, offset, row, col);
304   else
305     {
306       *row = 0;
307       *col = 0;
308     }
309 }
310
311 /**
312  * atk_text_get_range_attributes
313  * @text: an #AtkText
314  * @start_offset: start position
315  * @end_offset: end position
316  *
317  * Gets attributes over the specified range.
318  *
319  * Returns: a #PangoAttrList with the text attributes between the
320  * @start_offset and the @end_offset.
321  **/
322 PangoAttrList*
323 atk_text_get_range_attributes (AtkText *text,
324                                gint start_offset,
325                                gint end_offset)
326 {
327   AtkTextIface *iface;
328
329   g_return_val_if_fail (text != NULL, NULL);
330   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
331
332   iface = ATK_TEXT_GET_IFACE (text);
333
334   if (iface->get_range_attributes)
335     return (*(iface->get_range_attributes)) (text, start_offset, end_offset);
336   else
337     return NULL;
338 }
339
340 /**
341  * atk_text_get_character_extents
342  * @text: an #AtkText
343  * @offset: position
344  * @x: x-position of character
345  * @y: y-position of character
346  * @length: length of character
347  * @width: width of character
348  *
349  * Given an @offset, the @x, @y, @length, and @width values are filled
350  * appropriately.
351  **/
352 void
353 atk_text_get_character_extents (AtkText *text,
354                                 gint offset,
355                                 gint *x,
356                                 gint *y,
357                                 gint *length,
358                                 gint *width)
359 {
360   AtkTextIface *iface;
361
362   g_return_if_fail (text != NULL);
363   g_return_if_fail (ATK_IS_TEXT (text));
364
365   iface = ATK_TEXT_GET_IFACE (text);
366
367   if (iface->get_character_extents)
368     (*(iface->get_character_extents)) (text, offset, x, y, length, width);
369   else
370     {
371       *x = 0;
372       *x = 0;
373       *length = 0;
374       *width = 0;
375     }
376 }
377
378 /**
379  * atk_text_get_character_count
380  * @text: an #AtkText
381  *
382  * Gets the character count.
383  *
384  * Returns: the number of characters.
385  **/
386 gint
387 atk_text_get_character_count (AtkText *text)
388 {
389   AtkTextIface *iface;
390
391   g_return_val_if_fail (text != NULL, -1);
392   g_return_val_if_fail (ATK_IS_TEXT (text), -1);
393
394   iface = ATK_TEXT_GET_IFACE (text);
395
396   if (iface->get_character_count)
397     return (*(iface->get_character_count)) (text);
398   else
399     return -1;
400 }
401
402 /**
403  * atk_text_get_offset_at_point
404  * @text: an #AtkText
405  * @x: screen x-position of character
406  * @y: screen y-position of character
407  *
408  * Gets the x,y screen coordinates of the specified character.
409  *
410  * Returns: the offset to the character which is located at
411  * the specified @x and @y coordinates.
412  **/
413 gint
414 atk_text_get_offset_at_point (AtkText *text,
415                               gint x,
416                               gint y)
417 {
418   AtkTextIface *iface;
419
420   g_return_val_if_fail (text != NULL, -1);
421   g_return_val_if_fail (ATK_IS_TEXT (text), -1);
422
423   iface = ATK_TEXT_GET_IFACE (text);
424
425   if (iface->get_offset_at_point)
426     return (*(iface->get_offset_at_point)) (text, x, y);
427   else
428     return -1;
429 }
430
431 /**
432  * atk_text_get_selected_text
433  * @text: an #AtkText
434  *
435  * Gets the selected text.
436  *
437  * Returns: the selected text.
438  **/
439 gchar*
440 atk_text_get_selected_text (AtkText *text)
441 {
442   AtkTextIface *iface;
443
444   g_return_val_if_fail (text != NULL, NULL);
445   g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
446
447   iface = ATK_TEXT_GET_IFACE (text);
448
449   if (iface->get_selected_text)
450     return (*(iface->get_selected_text)) (text);
451   else
452     return NULL;
453 }
454
455 /**
456  * atk_text_get_selection_bounds
457  * @text: an #AtkText
458  * @start_offset: start position
459  * @end_offset: end position
460  *
461  * @start_offset and @end_offset are filled with the
462  * current selection bounds.
463  **/
464 void
465 atk_text_get_selection_bounds (AtkText *text,
466                                gint    *start_offset,
467                                gint    *end_offset)
468 {
469   AtkTextIface *iface;
470
471   g_return_if_fail (text != NULL);
472   g_return_if_fail (ATK_IS_TEXT (text));
473
474   iface = ATK_TEXT_GET_IFACE (text);
475
476   if (iface->get_selection_bounds)
477     (*(iface->get_selection_bounds)) (text, start_offset, end_offset);
478   else
479   {
480     *start_offset = 0;
481     *end_offset = 0;
482   }
483 }
484
485 /**
486  * atk_text_set_selection_bounds
487  * @text: an #AtkText
488  * @start_offset: start position
489  * @end_offset: end position
490  *
491  * The selection bounds are set to the specified @start_offset
492  * and @end_offset values.
493  * 
494  * Returns: %TRUE if success, %FALSE otherwise.
495  **/
496 gboolean
497 atk_text_set_selection_bounds (AtkText *text,
498                                gint    start_offset,
499                                gint    end_offset)
500 {
501   AtkTextIface *iface;
502
503   g_return_val_if_fail (text != NULL, FALSE);
504   g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
505
506   iface = ATK_TEXT_GET_IFACE (text);
507
508   if (iface->set_selection_bounds)
509     {
510       return (*(iface->set_selection_bounds)) (text, start_offset, end_offset);
511     }
512   else
513     {
514       return FALSE;
515     }
516 }
517
518 /**
519  * atk_text_set_caret_offset
520  * @text: an #AtkText
521  * @offset: position
522  *
523  * Sets the caret (cursor) position to the specified @offset.
524  *
525  * Returns: %TRUE if success, %FALSE otherwise.
526  **/
527 gboolean
528 atk_text_set_caret_offset (AtkText *text,
529                            gint    offset)
530 {
531   AtkTextIface *iface;
532
533   g_return_val_if_fail (text != NULL, FALSE);
534   g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
535
536   iface = ATK_TEXT_GET_IFACE (text);
537
538   if (iface->set_caret_offset)
539     {
540       return (*(iface->set_caret_offset)) (text, offset);
541     }
542   else
543     {
544       return FALSE;
545     }
546 }