1 /* ATK - The Accessibility Toolkit for GTK+
2 * Copyright 2001 Sun Microsystems Inc.
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.
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.
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.
21 #include "atkmarshal.h"
22 #include "atk-enum-types.h"
26 GPtrArray *extra_attributes = NULL;
31 TEXT_SELECTION_CHANGED,
35 static const gchar *bool[] = {"false",
37 static const gchar *style[] = {"normal",
40 static const gchar *variant[] = {"normal",
42 static const gchar *stretch[] = {"ultra_condensed",
51 static const gchar *justification[] = {"left",
56 static const gchar *direction[] = {"none",
59 static const gchar *wrap_mode[] = {"none",
62 static const gchar *underline[] = {"none",
67 static void atk_text_base_init (gpointer *g_class);
69 static guint atk_text_signals[LAST_SIGNAL] = { 0 };
74 static GType type = 0;
78 static const GTypeInfo tinfo =
80 sizeof (AtkTextIface),
81 (GBaseInitFunc) atk_text_base_init,
82 (GBaseFinalizeFunc) NULL,
83 (GClassInitFunc) NULL /* atk_text_interface_init */ ,
84 (GClassFinalizeFunc) NULL,
88 type = g_type_register_static (G_TYPE_INTERFACE, "AtkText", &tinfo, 0);
95 atk_text_base_init (gpointer *g_class)
97 static gboolean initialized = FALSE;
102 * Note that text_changed signal supports details "insert", "delete",
103 * possibly "replace".
106 atk_text_signals[TEXT_CHANGED] =
107 g_signal_new ("text_changed",
109 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
110 G_STRUCT_OFFSET (AtkTextIface, text_changed),
111 (GSignalAccumulator) NULL, NULL,
112 atk_marshal_VOID__INT_INT,
114 2, G_TYPE_INT, G_TYPE_INT);
116 atk_text_signals[CARET_MOVED] =
117 g_signal_new ("text_caret_moved",
120 G_STRUCT_OFFSET (AtkTextIface, caret_changed),
121 (GSignalAccumulator) NULL, NULL,
122 g_cclosure_marshal_VOID__INT,
125 atk_text_signals[TEXT_SELECTION_CHANGED] =
126 g_signal_new ("text_selection_changed",
129 G_STRUCT_OFFSET (AtkTextIface, text_selection_changed),
130 (GSignalAccumulator) NULL, NULL,
131 g_cclosure_marshal_VOID__VOID,
142 * @start_offset: start position
143 * @end_offset: end position
145 * Gets the specified text.
147 * Returns: the text from @start_offset up to, but not including @end_offset.
150 atk_text_get_text (AtkText *text,
156 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
158 iface = ATK_TEXT_GET_IFACE (text);
161 return (*(iface->get_text)) (text, start_offset, end_offset);
167 * atk_text_get_character_at_offset:
171 * Gets the specified text.
173 * Returns: the character at @offset.
176 atk_text_get_character_at_offset (AtkText *text,
181 g_return_val_if_fail (ATK_IS_TEXT (text), (gunichar) 0);
183 iface = ATK_TEXT_GET_IFACE (text);
185 if (iface->get_character_at_offset)
186 return (*(iface->get_character_at_offset)) (text, offset);
192 * atk_text_get_text_after_offset:
195 * @boundary_type: An #AtkTextBoundary
196 * @start_offset: the start offset of the returned string.
197 * @end_offset: the end offset of the returned string.
199 * Gets the specified text.
201 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character after the
202 * offset is returned.
204 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
205 * is from the word start after the offset to the next word start.
207 * The returned string will contain the word after the offset if the offset
208 * is inside a word or if the offset is not inside a word.
210 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
211 * is from the word end at or after the offset to the next work end.
213 * The returned string will contain the word after the offset if the offset
214 * is inside a word and will contain the word after the word after the offset
215 * if the offset is not inside a word.
217 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
218 * string is from the sentence start after the offset to the next sentence
221 * The returned string will contain the sentence after the offset if the offset
222 * is inside a sentence or if the offset is not inside a sentence.
224 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
225 * is from the sentence end at or after the offset to the next sentence end.
227 * The returned string will contain the sentence after the offset if the offset
228 * is inside a sentence and will contain the sentence after the sentence
229 * after the offset if the offset is not inside a sentence.
231 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
232 * string is from the line start after the offset to the next line start.
234 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
235 * is from the line end at or after the offset to the next line start.
237 * Returns: the text after @offset bounded by the specified @boundary_type.
240 atk_text_get_text_after_offset (AtkText *text,
242 AtkTextBoundary boundary_type,
247 gint local_start_offset, local_end_offset;
248 gint *real_start_offset, *real_end_offset;
250 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
253 real_start_offset = start_offset;
255 real_start_offset = &local_start_offset;
257 real_end_offset = end_offset;
259 real_end_offset = &local_end_offset;
261 iface = ATK_TEXT_GET_IFACE (text);
263 if (iface->get_text_after_offset)
264 return (*(iface->get_text_after_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
270 * atk_text_get_text_at_offset:
273 * @boundary_type: An #AtkTextBoundary
274 * @start_offset: the start offset of the returned string.
275 * @end_offset: the end offset of the returned string.
277 * Gets the specified text.
279 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character at the
280 * offset is returned.
282 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
283 * is from the word start at or before the offset to the word start after
286 * The returned string will contain the word at the offset if the offset
287 * is inside a word and will contain the word before the offset if the
288 * offset is not inside a word.
290 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
291 * is from the word end before the offset to the word end at or after the
294 * The returned string will contain the word at the offset if the offset
295 * is inside a word and will contain the word after to the offset if the
296 * offset is not inside a word.
298 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
299 * string is from the sentence start at or before the offset to the sentence
300 * start after the offset.
302 * The returned string will contain the sentence at the offset if the offset
303 * is inside a sentence and will contain the sentence before the offset
304 * if the offset is not inside a sentence.
306 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
307 * is from the sentence end before the offset to the sentence end at or
310 * The returned string will contain the sentence at the offset if the offset
311 * is inside a sentence and will contain the sentence after the offset
312 * if the offset is not inside a sentence.
314 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
315 * string is from the line start at or before the offset to the line
316 * start after the offset.
318 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
319 * is from the line end before the offset to the line end at or after
322 * Returns: the text at @offset bounded by the specified @boundary_type.
325 atk_text_get_text_at_offset (AtkText *text,
327 AtkTextBoundary boundary_type,
332 gint local_start_offset, local_end_offset;
333 gint *real_start_offset, *real_end_offset;
335 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
338 real_start_offset = start_offset;
340 real_start_offset = &local_start_offset;
342 real_end_offset = end_offset;
344 real_end_offset = &local_end_offset;
346 iface = ATK_TEXT_GET_IFACE (text);
348 if (iface->get_text_at_offset)
349 return (*(iface->get_text_at_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
355 * atk_text_get_text_before_offset:
358 * @boundary_type: An #AtkTextBoundary
359 * @start_offset: the start offset of the returned string.
360 * @end_offset: the end offset of the returned string.
362 * Gets the specified text.
364 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character before the
365 * offset is returned.
367 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
368 * is from the word start before the word start before the offset to
369 * the word start before the offset.
371 * The returned string will contain the word before the offset if the offset
372 * is inside a word and will contain the word before the word before the
373 * offset if the offset is not inside a word.
375 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
376 * is from the word end before the word end at or before the offset to the
377 * word end at or before the offset.
379 * The returned string will contain the word before the offset if the offset
380 * is inside a word or if the offset is not inside a word.
382 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
383 * string is from the sentence start before the sentence start before
384 * the offset to the sentence start before the offset.
386 * The returned string will contain the sentence before the offset if the
387 * offset is inside a sentence and will contain the sentence before the
388 * sentence before the offset if the offset is not inside a sentence.
390 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
391 * is from the sentence end before the sentence end at or before the offset to
392 * the sentence end at or before the offset.
394 * The returned string will contain the sentence before the offset if the
395 * offset is inside a sentence or if the offset is not inside a sentence.
397 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
398 * string is from the line start before the line start ar or before the offset
399 * to the line start ar or before the offset.
401 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
402 * is from the line end before the line end before the offset to the
403 * line end before the offset.
405 * Returns: the text before @offset bounded by the specified @boundary_type.
408 atk_text_get_text_before_offset (AtkText *text,
410 AtkTextBoundary boundary_type,
415 gint local_start_offset, local_end_offset;
416 gint *real_start_offset, *real_end_offset;
418 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
421 real_start_offset = start_offset;
423 real_start_offset = &local_start_offset;
425 real_end_offset = end_offset;
427 real_end_offset = &local_end_offset;
429 iface = ATK_TEXT_GET_IFACE (text);
431 if (iface->get_text_before_offset)
432 return (*(iface->get_text_before_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
438 * atk_text_get_caret_offset:
441 * Gets the offset position of the caret (cursor).
443 * Returns: the offset position of the caret (cursor).
446 atk_text_get_caret_offset (AtkText *text)
450 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
452 iface = ATK_TEXT_GET_IFACE (text);
454 if (iface->get_caret_offset)
455 return (*(iface->get_caret_offset)) (text);
461 * atk_text_get_character_extents:
464 * @x: x-position of character
465 * @y: y-position of character
466 * @width: width of character
467 * @height: height of character
468 * @coords: specify whether coordinates are relative to the screen or widget window
470 * Given an @offset, the @x, @y, @width, and @height values are filled
474 atk_text_get_character_extents (AtkText *text,
483 gint local_x, local_y, local_width, local_height;
484 gint *real_x, *real_y, *real_width, *real_height;
486 g_return_if_fail (ATK_IS_TEXT (text));
499 real_width = &local_width;
501 real_height = height;
503 real_height = &local_height;
505 iface = ATK_TEXT_GET_IFACE (text);
507 if (iface->get_character_extents)
508 (*(iface->get_character_extents)) (text, offset, real_x, real_y, real_width, real_height, coords);
519 *atk_text_get_run_attributes:
521 *@offset: the offset at which to get the attributes
522 *@start_offset: the address to put the start offset of the range
523 *@end_offset: the address to put the end offset of the range
525 *Creates an #AtkAttributeSet which consists of the attributes explicitly
526 *set at the position @offset in the text. @start_offset and @end_offset are
527 *set to the start and end of the range around @offset where the attributes are
528 *invariant. See the enum AtkTextAttribute for types of text attributes that
529 *can be returned. Note that other attributes may also be returned.
531 *Returns: an #AtkAttributeSet which contains the attributes explicitly set
532 *at @offset. This #AtkAttributeSet should be freed by a call to
533 *atk_attribute_set_free().
536 atk_text_get_run_attributes (AtkText *text,
542 gint local_start_offset, local_end_offset;
543 gint *real_start_offset, *real_end_offset;
545 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
548 real_start_offset = start_offset;
550 real_start_offset = &local_start_offset;
552 real_end_offset = end_offset;
554 real_end_offset = &local_end_offset;
556 iface = ATK_TEXT_GET_IFACE (text);
558 if (iface->get_run_attributes)
559 return (*(iface->get_run_attributes)) (text, offset, real_start_offset, real_end_offset);
565 *atk_text_get_default_attributes:
568 *Creates an #AtkAttributeSet which consists of the default values of
569 *attributes for the text. See the enum AtkTextAttribute for types of text
570 *attributes that can be returned. Note that other attributes may also be
573 *Returns: an #AtkAttributeSet which contains the default values of attributes.
574 *at @offset. This #AtkAttributeSet should be freed by a call to
575 *atk_attribute_set_free().
578 atk_text_get_default_attributes (AtkText *text)
582 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
584 iface = ATK_TEXT_GET_IFACE (text);
586 if (iface->get_default_attributes)
587 return (*(iface->get_default_attributes)) (text);
593 * atk_text_get_character_count:
596 * Gets the character count.
598 * Returns: the number of characters.
601 atk_text_get_character_count (AtkText *text)
605 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
607 iface = ATK_TEXT_GET_IFACE (text);
609 if (iface->get_character_count)
610 return (*(iface->get_character_count)) (text);
616 * atk_text_get_offset_at_point:
618 * @x: screen x-position of character
619 * @y: screen y-position of character
620 * @coords: specify whether coordinates are relative to the screen or
623 * Gets the offset of the character located at coordinates @x and @y. @x and @y
624 * are interpreted as being relative to the screen or this widget's window
625 * depending on @coords.
627 * Returns: the offset to the character which is located at
628 * the specified @x and @y coordinates.
631 atk_text_get_offset_at_point (AtkText *text,
638 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
640 iface = ATK_TEXT_GET_IFACE (text);
642 if (iface->get_offset_at_point)
643 return (*(iface->get_offset_at_point)) (text, x, y, coords);
649 * atk_text_get_n_selections:
652 * Gets the number of selected regions.
654 * Returns: The number of selected regions, or -1 if a failure
658 atk_text_get_n_selections (AtkText *text)
662 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
664 iface = ATK_TEXT_GET_IFACE (text);
666 if (iface->get_n_selections)
667 return (*(iface->get_n_selections)) (text);
673 * atk_text_get_selection:
675 * @selection_num: The selection number. The selected regions are
676 * assigned numbers that correspond to how far the region is from the
677 * start of the text. The selected region closest to the beginning
678 * of the text region is assigned the number 0, etc. Note that adding,
679 * moving or deleting a selected region can change the numbering.
680 * @start_offset: passes back the start position of the selected region
681 * @end_offset: passes back the end position of the selected region
683 * Gets the text from the specified selection.
685 * Returns: the selected text.
688 atk_text_get_selection (AtkText *text,
694 gint local_start_offset, local_end_offset;
695 gint *real_start_offset, *real_end_offset;
697 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
700 real_start_offset = start_offset;
702 real_start_offset = &local_start_offset;
704 real_end_offset = end_offset;
706 real_end_offset = &local_end_offset;
708 iface = ATK_TEXT_GET_IFACE (text);
710 if (iface->get_selection)
712 return (*(iface->get_selection)) (text, selection_num,
713 real_start_offset, real_end_offset);
720 * atk_text_add_selection:
722 * @start_offset: the start position of the selected region
723 * @end_offset: the end position of the selected region
725 * Adds a selection bounded by the specified offsets.
727 * Returns: %TRUE if success, %FALSE otherwise
730 atk_text_add_selection (AtkText *text,
736 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
738 iface = ATK_TEXT_GET_IFACE (text);
740 if (iface->add_selection)
741 return (*(iface->add_selection)) (text, start_offset, end_offset);
747 * atk_text_remove_selection:
749 * @selection_num: The selection number. The selected regions are
750 * assigned numbers that correspond to how far the region is from the
751 * start of the text. The selected region closest to the beginning
752 * of the text region is assigned the number 0, etc. Note that adding,
753 * moving or deleting a selected region can change the numbering.
755 * Removes the specified selection.
757 * Returns: %TRUE if success, %FALSE otherwise
760 atk_text_remove_selection (AtkText *text,
765 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
767 iface = ATK_TEXT_GET_IFACE (text);
769 if (iface->remove_selection)
770 return (*(iface->remove_selection)) (text, selection_num);
776 * atk_text_set_selection:
778 * @selection_num: The selection number. The selected regions are
779 * assigned numbers that correspond to how far the region is from the
780 * start of the text. The selected region closest to the beginning
781 * of the text region is assigned the number 0, etc. Note that adding,
782 * moving or deleting a selected region can change the numbering.
783 * @start_offset: the new start position of the selection
784 * @end_offset: the new end position of the selection
786 * Changes the start and end offset of the specified selection.
788 * Returns: %TRUE if success, %FALSE otherwise
791 atk_text_set_selection (AtkText *text,
798 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
800 iface = ATK_TEXT_GET_IFACE (text);
802 if (iface->set_selection)
804 return (*(iface->set_selection)) (text, selection_num,
805 start_offset, end_offset);
812 * atk_text_set_caret_offset:
816 * Sets the caret (cursor) position to the specified @offset.
818 * Returns: %TRUE if success, %FALSE otherwise.
821 atk_text_set_caret_offset (AtkText *text,
826 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
828 iface = ATK_TEXT_GET_IFACE (text);
830 if (iface->set_caret_offset)
832 return (*(iface->set_caret_offset)) (text, offset);
841 * atk_attribute_set_free:
842 * @attrib_set: The #AtkAttributeSet to free
844 * Frees the memory used by an #AtkAttributeSet, including all its
848 atk_attribute_set_free (AtkAttributeSet *attrib_set)
865 g_slist_free (attrib_set);
869 * atk_text_attribute_register:
870 * @name: a name string
872 * Associate @name with a new #AtkTextAttribute
874 * Returns: an #AtkTextAttribute associated with @name
877 atk_text_attribute_register (const gchar *name)
879 g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID);
881 if (!extra_attributes)
882 extra_attributes = g_ptr_array_new ();
884 g_ptr_array_add (extra_attributes, g_strdup (name));
885 return extra_attributes->len + ATK_TEXT_ATTR_LAST_DEFINED;
889 * atk_text_attribute_get_name:
890 * @attr: The #AtkTextAttribute whose name is required
892 * Gets the name corresponding to the #AtkTextAttribute
894 * Returns: a string containing the name; this string should not be freed
896 G_CONST_RETURN gchar*
897 atk_text_attribute_get_name (AtkTextAttribute attr)
899 GTypeClass *type_class;
903 type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE);
904 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
906 value = g_enum_get_value (G_ENUM_CLASS (type_class), attr);
910 name = value->value_nick;
914 if (extra_attributes)
918 n -= ATK_TEXT_ATTR_LAST_DEFINED + 1;
920 if (n < extra_attributes->len)
922 name = g_ptr_array_index (extra_attributes, n);
925 g_type_class_unref (type_class);
930 * atk_text_attribute_for_name:
931 * @name: a string which is the (non-localized) name of an ATK text attribute.
933 * Get the #AtkTextAttribute type corresponding to a text attribute name.
935 * Returns: the #AtkTextAttribute enumerated type corresponding to the specified
937 * or #ATK_TEXT_ATTRIBUTE_INVALID if no matching text attribute is found.
940 atk_text_attribute_for_name (const gchar *name)
942 GTypeClass *type_class;
944 AtkTextAttribute type = ATK_TEXT_ATTR_INVALID;
946 g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID);
948 type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE);
949 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_TEXT_ATTR_INVALID);
951 value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
961 if (extra_attributes)
963 for (i = 0; i < extra_attributes->len; i++)
965 gchar *extra_attribute = (gchar *)g_ptr_array_index (extra_attributes, i);
967 g_return_val_if_fail (extra_attribute, ATK_TEXT_ATTR_INVALID);
969 if (strcmp (name, extra_attribute) == 0)
971 type = i + 1 + ATK_TEXT_ATTR_LAST_DEFINED;
977 g_type_class_unref (type_class);
984 * atk_text_attribute_get_value:
985 * @attr: The #AtkTextAttribute for which a value is required
986 * @index: The index of the required value
988 * Gets the value for the index of the #AtkTextAttribute
990 * Returns: a string containing the value; this string should not be freed;
991 * NULL is returned if there are no values maintained for the attr value.
993 G_CONST_RETURN gchar*
994 atk_text_attribute_get_value (AtkTextAttribute attr,
999 case ATK_TEXT_ATTR_INVISIBLE:
1000 case ATK_TEXT_ATTR_EDITABLE:
1001 case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
1002 case ATK_TEXT_ATTR_STRIKETHROUGH:
1003 case ATK_TEXT_ATTR_BG_STIPPLE:
1004 case ATK_TEXT_ATTR_FG_STIPPLE:
1005 g_assert (index >= 0 && index < 2);
1007 case ATK_TEXT_ATTR_UNDERLINE:
1008 g_assert (index >= 0 && index < 4);
1009 return underline[index];
1010 case ATK_TEXT_ATTR_WRAP_MODE:
1011 g_assert (index >= 0 && index < 3);
1012 return wrap_mode[index];
1013 case ATK_TEXT_ATTR_DIRECTION:
1014 g_assert (index >= 0 && index < 3);
1015 return direction[index];
1016 case ATK_TEXT_ATTR_JUSTIFICATION:
1017 g_assert (index >= 0 && index < 3);
1018 return justification[index];
1019 case ATK_TEXT_ATTR_STRETCH:
1020 g_assert (index >= 0 && index < 9);
1021 return stretch[index];
1022 case ATK_TEXT_ATTR_VARIANT:
1023 g_assert (index >= 0 && index < 2);
1024 return variant[index];
1025 case ATK_TEXT_ATTR_STYLE:
1026 g_assert (index >= 0 && index < 3);
1027 return style[index];