1 /* GAIL - The GNOME Accessibility Implementation Library
2 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
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 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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.
22 #include <sys/types.h>
30 #include <glib-object.h>
31 #include <glib/gstdio.h>
33 #include "gtktextviewaccessible.h"
36 static void setup_buffer (GtkTextView *view,GtkTextViewAccessible *accessible);
37 static void insert_text_cb (GtkTextBuffer *buffer,
42 static void delete_range_cb (GtkTextBuffer *buffer,
46 static void mark_set_cb (GtkTextBuffer *buffer,
52 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
53 static void atk_text_interface_init (AtkTextIface *iface);
54 static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
56 G_DEFINE_TYPE_WITH_CODE (GtkTextViewAccessible, _gtk_text_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
57 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
58 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
59 G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
63 gtk_text_view_accessible_initialize (AtkObject *obj,
66 ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->initialize (obj, data);
68 setup_buffer (GTK_TEXT_VIEW (data), GTK_TEXT_VIEW_ACCESSIBLE (obj));
70 obj->role = ATK_ROLE_TEXT;
74 gtk_text_view_accessible_notify_gtk (GObject *obj,
79 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
81 if (!strcmp (pspec->name, "editable"))
85 editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
86 atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, editable);
88 else if (!strcmp (pspec->name, "buffer"))
90 setup_buffer (GTK_TEXT_VIEW (obj), GTK_TEXT_VIEW_ACCESSIBLE (atk_obj));
93 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_text_view_accessible_parent_class)->notify_gtk (obj, pspec);
97 gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
99 AtkStateSet *state_set;
102 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
106 state_set = ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->ref_state_set (accessible);
108 if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
109 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
110 atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
116 _gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
118 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
119 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
121 class->ref_state_set = gtk_text_view_accessible_ref_state_set;
122 class->initialize = gtk_text_view_accessible_initialize;
124 widget_class->notify_gtk = gtk_text_view_accessible_notify_gtk;
128 _gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
133 setup_buffer (GtkTextView *view,
134 GtkTextViewAccessible *accessible)
136 GtkTextBuffer *buffer;
138 buffer = gtk_text_view_get_buffer (view);
140 /* Set up signal callbacks */
141 g_signal_connect_after (buffer, "insert-text", G_CALLBACK (insert_text_cb), view);
142 g_signal_connect (buffer, "delete-range", G_CALLBACK (delete_range_cb), view);
143 g_signal_connect_after (buffer, "mark-set", G_CALLBACK (mark_set_cb), view);
147 gtk_text_view_accessible_get_text (AtkText *text,
152 GtkTextBuffer *buffer;
153 GtkTextIter start, end;
156 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
160 view = GTK_TEXT_VIEW (widget);
161 buffer = gtk_text_view_get_buffer (view);
162 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
163 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
165 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
169 gtk_text_view_accessible_get_text_after_offset (AtkText *text,
171 AtkTextBoundary boundary_type,
176 GtkTextBuffer *buffer;
178 GtkTextIter start, end;
180 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
184 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
185 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
186 _gtk_text_buffer_get_text_after (buffer, boundary_type,
188 *start_offset = gtk_text_iter_get_offset (&start);
189 *end_offset = gtk_text_iter_get_offset (&end);
190 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
194 gtk_text_view_accessible_get_text_at_offset (AtkText *text,
196 AtkTextBoundary boundary_type,
201 GtkTextBuffer *buffer;
203 GtkTextIter start, end;
205 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
209 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
210 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
211 _gtk_text_buffer_get_text_at (buffer, boundary_type,
213 *start_offset = gtk_text_iter_get_offset (&start);
214 *end_offset = gtk_text_iter_get_offset (&end);
215 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
219 gtk_text_view_accessible_get_text_before_offset (AtkText *text,
221 AtkTextBoundary boundary_type,
226 GtkTextBuffer *buffer;
228 GtkTextIter start, end;
230 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
234 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
235 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
236 _gtk_text_buffer_get_text_before (buffer, boundary_type,
238 *start_offset = gtk_text_iter_get_offset (&start);
239 *end_offset = gtk_text_iter_get_offset (&end);
240 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
244 gtk_text_view_accessible_get_character_at_offset (AtkText *text,
248 GtkTextIter start, end;
249 GtkTextBuffer *buffer;
253 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
257 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
258 if (offset >= gtk_text_buffer_get_char_count (buffer))
261 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
263 gtk_text_iter_forward_char (&end);
264 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
265 unichar = g_utf8_get_char (string);
272 gtk_text_view_accessible_get_character_count (AtkText *text)
275 GtkTextBuffer *buffer;
277 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
281 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
282 return gtk_text_buffer_get_char_count (buffer);
286 get_insert_offset (GtkTextBuffer *buffer)
291 insert = gtk_text_buffer_get_insert (buffer);
292 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
293 return gtk_text_iter_get_offset (&iter);
297 gtk_text_view_accessible_get_caret_offset (AtkText *text)
300 GtkTextBuffer *buffer;
302 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
306 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
307 return get_insert_offset (buffer);
311 gtk_text_view_accessible_set_caret_offset (AtkText *text,
316 GtkTextBuffer *buffer;
319 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
323 view = GTK_TEXT_VIEW (widget);
324 buffer = gtk_text_view_get_buffer (view);
326 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
327 gtk_text_buffer_place_cursor (buffer, &iter);
328 gtk_text_view_scroll_to_iter (view, &iter, 0, FALSE, 0, 0);
334 gtk_text_view_accessible_get_offset_at_point (AtkText *text,
341 gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
346 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
350 view = GTK_TEXT_VIEW (widget);
351 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
352 gdk_window_get_origin (window, &x_widget, &y_widget);
354 if (coords == ATK_XY_SCREEN)
359 else if (coords == ATK_XY_WINDOW)
361 window = gdk_window_get_toplevel (window);
362 gdk_window_get_origin (window, &x_window, &y_window);
364 x = x - x_widget + x_window;
365 y = y - y_widget + y_window;
370 gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
371 x, y, &buff_x, &buff_y);
372 gtk_text_view_get_visible_rect (view, &rect);
374 /* Clamp point to visible rectangle */
375 buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
376 buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
378 gtk_text_view_get_iter_at_location (view, &iter, buff_x, buff_y);
380 /* The iter at a location sometimes points to the next character.
381 * See bug 111031. We work around that
383 gtk_text_view_get_iter_location (view, &iter, &rect);
385 gtk_text_iter_backward_char (&iter);
386 return gtk_text_iter_get_offset (&iter);
390 gtk_text_view_accessible_get_character_extents (AtkText *text,
399 GtkTextBuffer *buffer;
402 GdkRectangle rectangle;
404 gint x_widget, y_widget, x_window, y_window;
406 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
410 view = GTK_TEXT_VIEW (widget);
411 buffer = gtk_text_view_get_buffer (view);
412 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
413 gtk_text_view_get_iter_location (view, &iter, &rectangle);
415 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
416 gdk_window_get_origin (window, &x_widget, &y_widget);
418 *height = rectangle.height;
419 *width = rectangle.width;
421 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
422 rectangle.x, rectangle.y, x, y);
423 if (coords == ATK_XY_WINDOW)
425 window = gdk_window_get_toplevel (window);
426 gdk_window_get_origin (window, &x_window, &y_window);
427 *x += x_widget - x_window;
428 *y += y_widget - y_window;
430 else if (coords == ATK_XY_SCREEN)
444 static AtkAttributeSet *
445 add_text_attribute (AtkAttributeSet *attributes,
446 AtkTextAttribute attr,
451 at = g_new (AtkAttribute, 1);
452 at->name = g_strdup (atk_text_attribute_get_name (attr));
455 return g_slist_prepend (attributes, at);
458 static AtkAttributeSet *
459 add_text_int_attribute (AtkAttributeSet *attributes,
460 AtkTextAttribute attr,
466 value = g_strdup (atk_text_attribute_get_value (attr, i));
468 return add_text_attribute (attributes, attr, value);
471 static AtkAttributeSet *
472 gtk_text_view_accessible_get_run_attributes (AtkText *text,
478 GtkTextBuffer *buffer;
481 AtkAttributeSet *attrib_set = NULL;
482 GSList *tags, *temp_tags;
484 gboolean val_set = FALSE;
487 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
491 view = GTK_TEXT_VIEW (widget);
492 buffer = gtk_text_view_get_buffer (view);
494 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
496 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
497 *end_offset = gtk_text_iter_get_offset (&iter);
499 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
500 *start_offset = gtk_text_iter_get_offset (&iter);
502 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
504 tags = gtk_text_iter_get_tags (&iter);
505 tags = g_slist_reverse (tags);
508 while (temp_tags && !val_set)
510 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
512 g_object_get (tag, "style-set", &val_set, NULL);
516 g_object_get (tag, "style", &style, NULL);
517 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, style);
519 temp_tags = temp_tags->next;
524 while (temp_tags && !val_set)
526 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
528 g_object_get (tag, "variant-set", &val_set, NULL);
531 PangoVariant variant;
532 g_object_get (tag, "variant", &variant, NULL);
533 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, variant);
535 temp_tags = temp_tags->next;
540 while (temp_tags && !val_set)
542 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
544 g_object_get (tag, "stretch-set", &val_set, NULL);
547 PangoStretch stretch;
548 g_object_get (tag, "stretch", &stretch, NULL);
549 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, stretch);
551 temp_tags = temp_tags->next;
556 while (temp_tags && !val_set)
558 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
560 g_object_get (tag, "justification-set", &val_set, NULL);
563 GtkJustification justification;
564 g_object_get (tag, "justification", &justification, NULL);
565 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, justification);
567 temp_tags = temp_tags->next;
572 while (temp_tags && !val_set)
574 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
575 GtkTextDirection direction;
577 g_object_get (tag, "direction", &direction, NULL);
579 if (direction != GTK_TEXT_DIR_NONE)
582 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, direction);
584 temp_tags = temp_tags->next;
589 while (temp_tags && !val_set)
591 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
593 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
596 GtkWrapMode wrap_mode;
597 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
598 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, wrap_mode);
600 temp_tags = temp_tags->next;
605 while (temp_tags && !val_set)
607 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
609 g_object_get (tag, "foreground-set", &val_set, NULL);
615 g_object_get (tag, "foreground-rgba", &rgba, NULL);
616 value = g_strdup_printf ("%u,%u,%u",
617 (guint) rgba->red * 65535,
618 (guint) rgba->green * 65535,
619 (guint) rgba->blue * 65535);
620 gdk_rgba_free (rgba);
621 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
623 temp_tags = temp_tags->next;
628 while (temp_tags && !val_set)
630 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
632 g_object_get (tag, "background-set", &val_set, NULL);
638 g_object_get (tag, "background-rgba", &rgba, NULL);
639 value = g_strdup_printf ("%u,%u,%u",
640 (guint) rgba->red * 65535,
641 (guint) rgba->green * 65535,
642 (guint) rgba->blue * 65535);
643 gdk_rgba_free (rgba);
644 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
646 temp_tags = temp_tags->next;
651 while (temp_tags && !val_set)
653 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
655 g_object_get (tag, "family-set", &val_set, NULL);
660 g_object_get (tag, "family", &value, NULL);
661 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
663 temp_tags = temp_tags->next;
668 while (temp_tags && !val_set)
670 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
672 g_object_get (tag, "language-set", &val_set, NULL);
677 g_object_get (tag, "language", &value, NULL);
678 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
680 temp_tags = temp_tags->next;
685 while (temp_tags && !val_set)
687 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
689 g_object_get (tag, "weight-set", &val_set, NULL);
695 g_object_get (tag, "weight", &weight, NULL);
696 value = g_strdup_printf ("%d", weight);
697 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
699 temp_tags = temp_tags->next;
703 /* scale is special as the effective value is the product
704 * of all specified values
709 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
712 g_object_get (tag, "scale-set", &scale_set, NULL);
716 g_object_get (tag, "scale", &font_scale, NULL);
720 temp_tags = temp_tags->next;
725 value = g_strdup_printf ("%g", scale);
726 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
731 while (temp_tags && !val_set)
733 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
735 g_object_get (tag, "size-set", &val_set, NULL);
740 g_object_get (tag, "size", &size, NULL);
741 value = g_strdup_printf ("%i", size);
742 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
744 temp_tags = temp_tags->next;
749 while (temp_tags && !val_set)
751 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
753 g_object_get (tag, "strikethrough-set", &val_set, NULL);
756 gboolean strikethrough;
757 g_object_get (tag, "strikethrough", &strikethrough, NULL);
758 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough);
760 temp_tags = temp_tags->next;
765 while (temp_tags && !val_set)
767 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
769 g_object_get (tag, "underline-set", &val_set, NULL);
772 PangoUnderline underline;
773 g_object_get (tag, "underline", &underline, NULL);
774 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, underline);
776 temp_tags = temp_tags->next;
781 while (temp_tags && !val_set)
783 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
785 g_object_get (tag, "rise-set", &val_set, NULL);
790 g_object_get (tag, "rise", &rise, NULL);
791 value = g_strdup_printf ("%i", rise);
792 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
794 temp_tags = temp_tags->next;
799 while (temp_tags && !val_set)
801 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
803 g_object_get (tag, "background-full-height-set", &val_set, NULL);
806 gboolean bg_full_height;
807 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
808 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height);
810 temp_tags = temp_tags->next;
815 while (temp_tags && !val_set)
817 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
819 g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
824 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
825 value = g_strdup_printf ("%i", pixels);
826 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
828 temp_tags = temp_tags->next;
833 while (temp_tags && !val_set)
835 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
837 g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
842 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
843 value = g_strdup_printf ("%i", pixels);
844 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
846 temp_tags = temp_tags->next;
851 while (temp_tags && !val_set)
853 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
855 g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
860 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
861 value = g_strdup_printf ("%i", pixels);
862 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
864 temp_tags = temp_tags->next;
869 while (temp_tags && !val_set)
871 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
873 g_object_get (tag, "editable-set", &val_set, NULL);
877 g_object_get (tag, "editable", &editable, NULL);
878 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, editable);
880 temp_tags = temp_tags->next;
885 while (temp_tags && !val_set)
887 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
889 g_object_get (tag, "invisible-set", &val_set, NULL);
893 g_object_get (tag, "invisible", &invisible, NULL);
894 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, invisible);
896 temp_tags = temp_tags->next;
901 while (temp_tags && !val_set)
903 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
905 g_object_get (tag, "indent-set", &val_set, NULL);
910 g_object_get (tag, "indent", &indent, NULL);
911 value = g_strdup_printf ("%i", indent);
912 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
914 temp_tags = temp_tags->next;
919 while (temp_tags && !val_set)
921 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
923 g_object_get (tag, "right-margin-set", &val_set, NULL);
928 g_object_get (tag, "right-margin", &margin, NULL);
929 value = g_strdup_printf ("%i", margin);
930 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
932 temp_tags = temp_tags->next;
937 while (temp_tags && !val_set)
939 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
941 g_object_get (tag, "left-margin-set", &val_set, NULL);
946 g_object_get (tag, "left-margin", &margin, NULL);
947 value = g_strdup_printf ("%i", margin);
948 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
950 temp_tags = temp_tags->next;
958 static AtkAttributeSet *
959 gtk_text_view_accessible_get_default_attributes (AtkText *text)
963 GtkTextAttributes *text_attrs;
964 AtkAttributeSet *attributes;
965 PangoFontDescription *font;
968 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
972 view = GTK_TEXT_VIEW (widget);
973 text_attrs = gtk_text_view_get_default_attributes (view);
977 font = text_attrs->font;
981 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STYLE,
982 pango_font_description_get_style (font));
984 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_VARIANT,
985 pango_font_description_get_variant (font));
987 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRETCH,
988 pango_font_description_get_stretch (font));
990 value = g_strdup (pango_font_description_get_family (font));
991 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FAMILY_NAME, value);
993 value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
994 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_WEIGHT, value);
996 value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
997 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SIZE, value);
1000 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
1001 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
1002 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
1003 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
1004 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
1005 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
1007 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRIKETHROUGH,
1008 text_attrs->appearance.strikethrough);
1009 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_UNDERLINE,
1010 text_attrs->appearance.underline);
1012 value = g_strdup_printf ("%u,%u,%u",
1013 text_attrs->appearance.bg_color.red,
1014 text_attrs->appearance.bg_color.green,
1015 text_attrs->appearance.bg_color.blue);
1016 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_BG_COLOR, value);
1018 value = g_strdup_printf ("%u,%u,%u",
1019 text_attrs->appearance.fg_color.red,
1020 text_attrs->appearance.fg_color.green,
1021 text_attrs->appearance.fg_color.blue);
1022 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FG_COLOR, value);
1024 value = g_strdup_printf ("%g", text_attrs->font_scale);
1025 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SCALE, value);
1027 value = g_strdup ((gchar *)(text_attrs->language));
1028 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LANGUAGE, value);
1030 value = g_strdup_printf ("%i", text_attrs->appearance.rise);
1031 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RISE, value);
1033 value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
1034 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1036 value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
1037 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1039 value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
1040 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1042 value = g_strdup_printf ("%i", text_attrs->indent);
1043 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_INDENT, value);
1045 value = g_strdup_printf ("%i", text_attrs->left_margin);
1046 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1048 value = g_strdup_printf ("%i", text_attrs->right_margin);
1049 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1051 gtk_text_attributes_unref (text_attrs);
1056 gtk_text_view_accessible_get_n_selections (AtkText *text)
1059 GtkTextBuffer *buffer;
1061 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1065 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1066 if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1073 gtk_text_view_accessible_get_selection (AtkText *atk_text,
1080 GtkTextBuffer *buffer;
1081 GtkTextIter start, end;
1084 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
1088 if (selection_num != 0)
1091 view = GTK_TEXT_VIEW (widget);
1092 buffer = gtk_text_view_get_buffer (view);
1094 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1095 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1099 *start_pos = gtk_text_iter_get_offset (&start);
1100 *end_pos = gtk_text_iter_get_offset (&end);
1106 gtk_text_view_accessible_add_selection (AtkText *text,
1111 GtkTextBuffer *buffer;
1112 GtkTextIter start, end;
1114 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1118 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1120 if (!gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1122 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1123 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1124 gtk_text_buffer_select_range (buffer, &end, &start);
1133 gtk_text_view_accessible_remove_selection (AtkText *text,
1137 GtkTextBuffer *buffer;
1138 GtkTextMark *insert;
1140 GtkTextIter start, end;
1142 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1146 if (selection_num != 0)
1149 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1151 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1153 insert = gtk_text_buffer_get_insert (buffer);
1154 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
1155 gtk_text_buffer_place_cursor (buffer, &iter);
1163 gtk_text_view_accessible_set_selection (AtkText *text,
1169 GtkTextBuffer *buffer;
1170 GtkTextIter start, end;
1172 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1176 if (selection_num != 0)
1179 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1181 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1183 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1184 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1185 gtk_text_buffer_select_range (buffer, &end, &start);
1194 atk_text_interface_init (AtkTextIface *iface)
1196 iface->get_text = gtk_text_view_accessible_get_text;
1197 iface->get_text_after_offset = gtk_text_view_accessible_get_text_after_offset;
1198 iface->get_text_at_offset = gtk_text_view_accessible_get_text_at_offset;
1199 iface->get_text_before_offset = gtk_text_view_accessible_get_text_before_offset;
1200 iface->get_character_at_offset = gtk_text_view_accessible_get_character_at_offset;
1201 iface->get_character_count = gtk_text_view_accessible_get_character_count;
1202 iface->get_caret_offset = gtk_text_view_accessible_get_caret_offset;
1203 iface->set_caret_offset = gtk_text_view_accessible_set_caret_offset;
1204 iface->get_offset_at_point = gtk_text_view_accessible_get_offset_at_point;
1205 iface->get_character_extents = gtk_text_view_accessible_get_character_extents;
1206 iface->get_n_selections = gtk_text_view_accessible_get_n_selections;
1207 iface->get_selection = gtk_text_view_accessible_get_selection;
1208 iface->add_selection = gtk_text_view_accessible_add_selection;
1209 iface->remove_selection = gtk_text_view_accessible_remove_selection;
1210 iface->set_selection = gtk_text_view_accessible_set_selection;
1211 iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
1212 iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
1215 /* atkeditabletext.h */
1218 gtk_text_view_accessible_set_run_attributes (AtkEditableText *text,
1219 AtkAttributeSet *attributes,
1224 GtkTextBuffer *buffer;
1234 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1238 view = GTK_TEXT_VIEW (widget);
1239 if (!gtk_text_view_get_editable (view))
1242 buffer = gtk_text_view_get_buffer (view);
1244 if (attributes == NULL)
1247 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1248 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
1250 tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
1252 for (l = attributes; l; l = l->next)
1263 if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
1264 g_object_set (G_OBJECT (tag), "left-margin", atoi (value), NULL);
1266 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
1267 g_object_set (G_OBJECT (tag), "right-margin", atoi (value), NULL);
1269 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
1270 g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
1272 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
1273 g_object_set (G_OBJECT (tag), "pixels-above-lines", atoi (value), NULL);
1275 else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
1276 g_object_set (G_OBJECT (tag), "pixels-below-lines", atoi (value), NULL);
1278 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
1279 g_object_set (G_OBJECT (tag), "pixels-inside-wrap", atoi (value), NULL);
1281 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
1282 g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
1284 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
1285 g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
1287 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
1288 g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
1290 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
1292 g_object_set (G_OBJECT (tag), "bg-full-height",
1293 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
1297 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
1298 g_object_set (G_OBJECT (tag), "language", value, NULL);
1300 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
1301 g_object_set (G_OBJECT (tag), "family", value, NULL);
1303 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
1305 g_object_set (G_OBJECT (tag), "editable",
1306 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1310 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
1312 g_object_set (G_OBJECT (tag), "invisible",
1313 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1317 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
1319 for (j = 0; j < 3; j++)
1321 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
1323 g_object_set (G_OBJECT (tag), "underline", j, NULL);
1329 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
1331 g_object_set (G_OBJECT (tag), "strikethrough",
1332 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
1336 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
1338 RGB_vals = g_strsplit (value, ",", 3);
1339 color = g_malloc (sizeof (GdkColor));
1340 color->red = atoi (RGB_vals[0]);
1341 color->green = atoi (RGB_vals[1]);
1342 color->blue = atoi (RGB_vals[2]);
1343 g_object_set (G_OBJECT (tag), "background-gdk", color, NULL);
1346 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
1348 RGB_vals = g_strsplit (value, ",", 3);
1349 color = g_malloc (sizeof (GdkColor));
1350 color->red = atoi (RGB_vals[0]);
1351 color->green = atoi (RGB_vals[1]);
1352 color->blue = atoi (RGB_vals[2]);
1353 g_object_set (G_OBJECT (tag), "foreground-gdk", color, NULL);
1356 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
1358 for (j = 0; j < 9; j++)
1360 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
1362 g_object_set (G_OBJECT (tag), "stretch", j, NULL);
1368 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
1370 for (j = 0; j < 4; j++)
1372 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
1374 g_object_set (G_OBJECT (tag), "justification", j, NULL);
1380 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
1382 for (j = 0; j < 3; j++)
1384 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
1386 g_object_set (G_OBJECT (tag), "direction", j, NULL);
1392 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
1394 for (j = 0; j < 2; j++)
1396 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
1398 g_object_set (G_OBJECT (tag), "variant", j, NULL);
1404 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
1406 for (j = 0; j < 3; j++)
1408 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
1410 g_object_set (G_OBJECT (tag), "wrap-mode", j, NULL);
1416 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
1418 for (j = 0; j < 3; j++)
1420 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
1422 g_object_set (G_OBJECT (tag), "style", j, NULL);
1432 gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
1438 gtk_text_view_accessible_set_text_contents (AtkEditableText *text,
1439 const gchar *string)
1443 GtkTextBuffer *buffer;
1445 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1449 view = GTK_TEXT_VIEW (widget);
1450 if (!gtk_text_view_get_editable (view))
1453 buffer = gtk_text_view_get_buffer (view);
1454 gtk_text_buffer_set_text (buffer, string, -1);
1458 gtk_text_view_accessible_insert_text (AtkEditableText *text,
1459 const gchar *string,
1465 GtkTextBuffer *buffer;
1468 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1472 view = GTK_TEXT_VIEW (widget);
1473 if (!gtk_text_view_get_editable (view))
1476 buffer = gtk_text_view_get_buffer (view);
1477 gtk_text_buffer_get_iter_at_offset (buffer, &iter, *position);
1478 gtk_text_buffer_insert (buffer, &iter, string, length);
1482 gtk_text_view_accessible_copy_text (AtkEditableText *text,
1487 GtkTextBuffer *buffer;
1488 GtkTextIter start, end;
1490 GtkClipboard *clipboard;
1492 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1496 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1498 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1499 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1500 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1502 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1503 gtk_clipboard_set_text (clipboard, str, -1);
1507 gtk_text_view_accessible_cut_text (AtkEditableText *text,
1513 GtkTextBuffer *buffer;
1514 GtkTextIter start, end;
1516 GtkClipboard *clipboard;
1518 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1522 view = GTK_TEXT_VIEW (widget);
1523 if (!gtk_text_view_get_editable (view))
1525 buffer = gtk_text_view_get_buffer (view);
1527 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1528 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1529 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1530 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1531 gtk_clipboard_set_text (clipboard, str, -1);
1532 gtk_text_buffer_delete (buffer, &start, &end);
1536 gtk_text_view_accessible_delete_text (AtkEditableText *text,
1542 GtkTextBuffer *buffer;
1543 GtkTextIter start_itr;
1544 GtkTextIter end_itr;
1546 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1550 view = GTK_TEXT_VIEW (widget);
1551 if (!gtk_text_view_get_editable (view))
1553 buffer = gtk_text_view_get_buffer (view);
1555 gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
1556 gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
1557 gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
1562 GtkTextBuffer* buffer;
1567 paste_received (GtkClipboard *clipboard,
1571 PasteData* paste = data;
1572 GtkTextIter pos_itr;
1576 gtk_text_buffer_get_iter_at_offset (paste->buffer, &pos_itr, paste->position);
1577 gtk_text_buffer_insert (paste->buffer, &pos_itr, text, -1);
1580 g_object_unref (paste->buffer);
1584 gtk_text_view_accessible_paste_text (AtkEditableText *text,
1589 GtkTextBuffer *buffer;
1591 GtkClipboard *clipboard;
1593 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1597 view = GTK_TEXT_VIEW (widget);
1598 if (!gtk_text_view_get_editable (view))
1600 buffer = gtk_text_view_get_buffer (view);
1602 paste.buffer = buffer;
1603 paste.position = position;
1605 g_object_ref (paste.buffer);
1606 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1607 gtk_clipboard_request_text (clipboard, paste_received, &paste);
1611 atk_editable_text_interface_init (AtkEditableTextIface *iface)
1613 iface->set_text_contents = gtk_text_view_accessible_set_text_contents;
1614 iface->insert_text = gtk_text_view_accessible_insert_text;
1615 iface->copy_text = gtk_text_view_accessible_copy_text;
1616 iface->cut_text = gtk_text_view_accessible_cut_text;
1617 iface->delete_text = gtk_text_view_accessible_delete_text;
1618 iface->paste_text = gtk_text_view_accessible_paste_text;
1619 iface->set_run_attributes = gtk_text_view_accessible_set_run_attributes;
1625 gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
1626 GtkTextBuffer * buffer)
1628 int prev_insert_offset, prev_selection_bound;
1629 int insert_offset, selection_bound;
1632 prev_insert_offset = accessible->insert_offset;
1633 prev_selection_bound = accessible->selection_bound;
1635 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
1636 insert_offset = gtk_text_iter_get_offset (&iter);
1637 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
1638 selection_bound = gtk_text_iter_get_offset (&iter);
1640 if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
1643 accessible->insert_offset = insert_offset;
1644 accessible->selection_bound = selection_bound;
1646 if (prev_insert_offset != insert_offset)
1647 g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
1649 if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
1650 g_signal_emit_by_name (accessible, "text-selection-changed");
1654 insert_text_cb (GtkTextBuffer *buffer,
1660 GtkTextView *view = data;
1661 GtkTextViewAccessible *accessible;
1665 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
1667 position = gtk_text_iter_get_offset (iter);
1668 length = g_utf8_strlen (text, len);
1670 g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
1672 gtk_text_view_accessible_update_cursor (accessible, buffer);
1676 delete_range_cb (GtkTextBuffer *buffer,
1681 GtkTextView *view = data;
1682 GtkTextViewAccessible *accessible;
1683 gint offset, length;
1685 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
1687 offset = gtk_text_iter_get_offset (start);
1688 length = gtk_text_iter_get_offset (end) - offset;
1690 g_signal_emit_by_name (accessible,
1691 "text-changed::delete",
1695 gtk_text_view_accessible_update_cursor (accessible, buffer);
1699 mark_set_cb (GtkTextBuffer *buffer,
1700 GtkTextIter *location,
1704 GtkTextView *text = data;
1705 GtkTextViewAccessible *accessible;
1707 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (text)));
1710 * Only generate the signal for the "insert" mark, which
1711 * represents the cursor.
1713 if (mark == gtk_text_buffer_get_insert (buffer))
1715 gtk_text_view_accessible_update_cursor (accessible, buffer);
1717 else if (mark == gtk_text_buffer_get_selection_bound (buffer))
1719 gtk_text_view_accessible_update_cursor (accessible, buffer);
1724 gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
1727 GtkTextBuffer *buffer;
1728 gint n_mime_types = 0;
1730 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1734 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1738 gboolean advertises_plaintext = FALSE;
1741 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1742 for (i = 0; i < n_mime_types-1; ++i)
1743 if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
1744 advertises_plaintext = TRUE;
1745 if (!advertises_plaintext)
1749 return n_mime_types;
1752 static const gchar *
1753 gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
1757 GtkTextBuffer *buffer;
1759 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1763 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1766 gint n_mime_types = 0;
1769 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1770 if (i < n_mime_types)
1771 return gdk_atom_name (atoms [i]);
1772 else if (i == n_mime_types)
1773 return "text/plain";
1780 gail_streamable_content_get_stream (AtkStreamableContent *streamable,
1781 const gchar *mime_type)
1784 GtkTextBuffer *buffer;
1785 gint i, n_mime_types = 0;
1788 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1792 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1796 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1798 for (i = 0; i < n_mime_types; ++i)
1800 if (!strcmp ("text/plain", mime_type) ||
1801 !strcmp (gdk_atom_name (atoms[i]), mime_type))
1807 GtkTextIter start, end;
1808 GIOChannel *gio = NULL;
1811 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
1812 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
1813 if (!strcmp ("text/plain", mime_type))
1815 cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1816 len = strlen ((const char *) cbuf);
1820 cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
1822 g_snprintf (tname, 20, "streamXXXXXX");
1823 fd = g_mkstemp (tname);
1824 gio = g_io_channel_unix_new (fd);
1825 g_io_channel_set_encoding (gio, NULL, &err);
1827 g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
1829 g_message ("%s", err->message);
1831 g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
1833 g_message ("%s", err->message);
1835 g_io_channel_flush (gio, &err);
1837 g_message ("%s", err->message);
1840 g_message ("<error writing to stream [%s]>", tname);
1843 /* make sure the file is removed on unref of the giochannel */
1856 atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
1858 iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
1859 iface->get_mime_type = gail_streamable_content_get_mime_type;
1860 iface->get_stream = gail_streamable_content_get_stream;