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>
26 #include <glib-object.h>
27 #include <glib/gstdio.h>
29 #include "gtktextviewaccessible.h"
32 static void setup_buffer (GtkTextView *view,GtkTextViewAccessible *accessible);
33 static void insert_text_cb (GtkTextBuffer *buffer,
38 static void delete_range_cb (GtkTextBuffer *buffer,
42 static void mark_set_cb (GtkTextBuffer *buffer,
48 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
49 static void atk_text_interface_init (AtkTextIface *iface);
50 static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
52 G_DEFINE_TYPE_WITH_CODE (GtkTextViewAccessible, gtk_text_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
53 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
54 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
55 G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
59 gtk_text_view_accessible_initialize (AtkObject *obj,
62 ATK_OBJECT_CLASS (gtk_text_view_accessible_parent_class)->initialize (obj, data);
64 setup_buffer (GTK_TEXT_VIEW (data), GTK_TEXT_VIEW_ACCESSIBLE (obj));
66 obj->role = ATK_ROLE_TEXT;
70 gtk_text_view_accessible_notify_gtk (GObject *obj,
75 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
77 if (!strcmp (pspec->name, "editable"))
81 editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
82 atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, editable);
84 else if (!strcmp (pspec->name, "buffer"))
86 setup_buffer (GTK_TEXT_VIEW (obj), GTK_TEXT_VIEW_ACCESSIBLE (atk_obj));
89 GTK_WIDGET_ACCESSIBLE_CLASS (gtk_text_view_accessible_parent_class)->notify_gtk (obj, pspec);
93 gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
95 AtkStateSet *state_set;
98 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
102 state_set = ATK_OBJECT_CLASS (gtk_text_view_accessible_parent_class)->ref_state_set (accessible);
104 if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
105 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
106 atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
112 gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
114 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
115 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
117 class->ref_state_set = gtk_text_view_accessible_ref_state_set;
118 class->initialize = gtk_text_view_accessible_initialize;
120 widget_class->notify_gtk = gtk_text_view_accessible_notify_gtk;
124 gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
129 setup_buffer (GtkTextView *view,
130 GtkTextViewAccessible *accessible)
132 GtkTextBuffer *buffer;
134 buffer = gtk_text_view_get_buffer (view);
136 /* Set up signal callbacks */
137 g_signal_connect_after (buffer, "insert-text", G_CALLBACK (insert_text_cb), view);
138 g_signal_connect (buffer, "delete-range", G_CALLBACK (delete_range_cb), view);
139 g_signal_connect_after (buffer, "mark-set", G_CALLBACK (mark_set_cb), view);
143 gtk_text_view_accessible_get_text (AtkText *text,
148 GtkTextBuffer *buffer;
149 GtkTextIter start, end;
152 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
156 view = GTK_TEXT_VIEW (widget);
157 buffer = gtk_text_view_get_buffer (view);
158 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
159 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
161 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
165 gtk_text_view_accessible_get_text_after_offset (AtkText *text,
167 AtkTextBoundary boundary_type,
172 GtkTextBuffer *buffer;
174 GtkTextIter start, end;
176 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
180 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
181 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
182 _gtk_text_buffer_get_text_after (buffer, boundary_type,
184 *start_offset = gtk_text_iter_get_offset (&start);
185 *end_offset = gtk_text_iter_get_offset (&end);
186 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
190 gtk_text_view_accessible_get_text_at_offset (AtkText *text,
192 AtkTextBoundary boundary_type,
197 GtkTextBuffer *buffer;
199 GtkTextIter start, end;
201 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
205 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
206 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
207 _gtk_text_buffer_get_text_at (buffer, boundary_type,
209 *start_offset = gtk_text_iter_get_offset (&start);
210 *end_offset = gtk_text_iter_get_offset (&end);
211 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
215 gtk_text_view_accessible_get_text_before_offset (AtkText *text,
217 AtkTextBoundary boundary_type,
222 GtkTextBuffer *buffer;
224 GtkTextIter start, end;
226 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
230 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
231 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
232 _gtk_text_buffer_get_text_before (buffer, boundary_type,
234 *start_offset = gtk_text_iter_get_offset (&start);
235 *end_offset = gtk_text_iter_get_offset (&end);
236 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
240 gtk_text_view_accessible_get_character_at_offset (AtkText *text,
244 GtkTextIter start, end;
245 GtkTextBuffer *buffer;
249 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
253 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
254 if (offset >= gtk_text_buffer_get_char_count (buffer))
257 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
259 gtk_text_iter_forward_char (&end);
260 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
261 unichar = g_utf8_get_char (string);
268 gtk_text_view_accessible_get_character_count (AtkText *text)
271 GtkTextBuffer *buffer;
273 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
277 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
278 return gtk_text_buffer_get_char_count (buffer);
282 get_insert_offset (GtkTextBuffer *buffer)
287 insert = gtk_text_buffer_get_insert (buffer);
288 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
289 return gtk_text_iter_get_offset (&iter);
293 gtk_text_view_accessible_get_caret_offset (AtkText *text)
296 GtkTextBuffer *buffer;
298 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
302 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
303 return get_insert_offset (buffer);
307 gtk_text_view_accessible_set_caret_offset (AtkText *text,
312 GtkTextBuffer *buffer;
315 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
319 view = GTK_TEXT_VIEW (widget);
320 buffer = gtk_text_view_get_buffer (view);
322 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
323 gtk_text_buffer_place_cursor (buffer, &iter);
324 gtk_text_view_scroll_to_iter (view, &iter, 0, FALSE, 0, 0);
330 gtk_text_view_accessible_get_offset_at_point (AtkText *text,
337 gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
342 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
346 view = GTK_TEXT_VIEW (widget);
347 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
348 gdk_window_get_origin (window, &x_widget, &y_widget);
350 if (coords == ATK_XY_SCREEN)
355 else if (coords == ATK_XY_WINDOW)
357 window = gdk_window_get_toplevel (window);
358 gdk_window_get_origin (window, &x_window, &y_window);
360 x = x - x_widget + x_window;
361 y = y - y_widget + y_window;
366 gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
367 x, y, &buff_x, &buff_y);
368 gtk_text_view_get_visible_rect (view, &rect);
370 /* Clamp point to visible rectangle */
371 buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
372 buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
374 gtk_text_view_get_iter_at_location (view, &iter, buff_x, buff_y);
376 /* The iter at a location sometimes points to the next character.
377 * See bug 111031. We work around that
379 gtk_text_view_get_iter_location (view, &iter, &rect);
381 gtk_text_iter_backward_char (&iter);
382 return gtk_text_iter_get_offset (&iter);
386 gtk_text_view_accessible_get_character_extents (AtkText *text,
395 GtkTextBuffer *buffer;
398 GdkRectangle rectangle;
400 gint x_widget, y_widget, x_window, y_window;
402 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
406 view = GTK_TEXT_VIEW (widget);
407 buffer = gtk_text_view_get_buffer (view);
408 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
409 gtk_text_view_get_iter_location (view, &iter, &rectangle);
411 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
412 gdk_window_get_origin (window, &x_widget, &y_widget);
414 *height = rectangle.height;
415 *width = rectangle.width;
417 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
418 rectangle.x, rectangle.y, x, y);
419 if (coords == ATK_XY_WINDOW)
421 window = gdk_window_get_toplevel (window);
422 gdk_window_get_origin (window, &x_window, &y_window);
423 *x += x_widget - x_window;
424 *y += y_widget - y_window;
426 else if (coords == ATK_XY_SCREEN)
440 static AtkAttributeSet *
441 add_text_attribute (AtkAttributeSet *attributes,
442 AtkTextAttribute attr,
447 at = g_new (AtkAttribute, 1);
448 at->name = g_strdup (atk_text_attribute_get_name (attr));
451 return g_slist_prepend (attributes, at);
454 static AtkAttributeSet *
455 add_text_int_attribute (AtkAttributeSet *attributes,
456 AtkTextAttribute attr,
462 value = g_strdup (atk_text_attribute_get_value (attr, i));
464 return add_text_attribute (attributes, attr, value);
467 static AtkAttributeSet *
468 gtk_text_view_accessible_get_run_attributes (AtkText *text,
474 GtkTextBuffer *buffer;
477 AtkAttributeSet *attrib_set = NULL;
478 GSList *tags, *temp_tags;
480 gboolean val_set = FALSE;
483 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
487 view = GTK_TEXT_VIEW (widget);
488 buffer = gtk_text_view_get_buffer (view);
490 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
492 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
493 *end_offset = gtk_text_iter_get_offset (&iter);
495 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
496 *start_offset = gtk_text_iter_get_offset (&iter);
498 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
500 tags = gtk_text_iter_get_tags (&iter);
501 tags = g_slist_reverse (tags);
504 while (temp_tags && !val_set)
506 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
508 g_object_get (tag, "style-set", &val_set, NULL);
512 g_object_get (tag, "style", &style, NULL);
513 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, style);
515 temp_tags = temp_tags->next;
520 while (temp_tags && !val_set)
522 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
524 g_object_get (tag, "variant-set", &val_set, NULL);
527 PangoVariant variant;
528 g_object_get (tag, "variant", &variant, NULL);
529 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, variant);
531 temp_tags = temp_tags->next;
536 while (temp_tags && !val_set)
538 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
540 g_object_get (tag, "stretch-set", &val_set, NULL);
543 PangoStretch stretch;
544 g_object_get (tag, "stretch", &stretch, NULL);
545 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, stretch);
547 temp_tags = temp_tags->next;
552 while (temp_tags && !val_set)
554 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
556 g_object_get (tag, "justification-set", &val_set, NULL);
559 GtkJustification justification;
560 g_object_get (tag, "justification", &justification, NULL);
561 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, justification);
563 temp_tags = temp_tags->next;
568 while (temp_tags && !val_set)
570 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
571 GtkTextDirection direction;
573 g_object_get (tag, "direction", &direction, NULL);
575 if (direction != GTK_TEXT_DIR_NONE)
578 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, direction);
580 temp_tags = temp_tags->next;
585 while (temp_tags && !val_set)
587 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
589 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
592 GtkWrapMode wrap_mode;
593 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
594 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, wrap_mode);
596 temp_tags = temp_tags->next;
601 while (temp_tags && !val_set)
603 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
605 g_object_get (tag, "foreground-set", &val_set, NULL);
611 g_object_get (tag, "foreground-rgba", &rgba, NULL);
612 value = g_strdup_printf ("%u,%u,%u",
613 (guint) rgba->red * 65535,
614 (guint) rgba->green * 65535,
615 (guint) rgba->blue * 65535);
616 gdk_rgba_free (rgba);
617 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
619 temp_tags = temp_tags->next;
624 while (temp_tags && !val_set)
626 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
628 g_object_get (tag, "background-set", &val_set, NULL);
634 g_object_get (tag, "background-rgba", &rgba, NULL);
635 value = g_strdup_printf ("%u,%u,%u",
636 (guint) rgba->red * 65535,
637 (guint) rgba->green * 65535,
638 (guint) rgba->blue * 65535);
639 gdk_rgba_free (rgba);
640 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
642 temp_tags = temp_tags->next;
647 while (temp_tags && !val_set)
649 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
651 g_object_get (tag, "family-set", &val_set, NULL);
656 g_object_get (tag, "family", &value, NULL);
657 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
659 temp_tags = temp_tags->next;
664 while (temp_tags && !val_set)
666 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
668 g_object_get (tag, "language-set", &val_set, NULL);
673 g_object_get (tag, "language", &value, NULL);
674 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
676 temp_tags = temp_tags->next;
681 while (temp_tags && !val_set)
683 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
685 g_object_get (tag, "weight-set", &val_set, NULL);
691 g_object_get (tag, "weight", &weight, NULL);
692 value = g_strdup_printf ("%d", weight);
693 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
695 temp_tags = temp_tags->next;
699 /* scale is special as the effective value is the product
700 * of all specified values
705 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
708 g_object_get (tag, "scale-set", &scale_set, NULL);
712 g_object_get (tag, "scale", &font_scale, NULL);
716 temp_tags = temp_tags->next;
721 value = g_strdup_printf ("%g", scale);
722 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
727 while (temp_tags && !val_set)
729 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
731 g_object_get (tag, "size-set", &val_set, NULL);
736 g_object_get (tag, "size", &size, NULL);
737 value = g_strdup_printf ("%i", size);
738 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
740 temp_tags = temp_tags->next;
745 while (temp_tags && !val_set)
747 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
749 g_object_get (tag, "strikethrough-set", &val_set, NULL);
752 gboolean strikethrough;
753 g_object_get (tag, "strikethrough", &strikethrough, NULL);
754 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough);
756 temp_tags = temp_tags->next;
761 while (temp_tags && !val_set)
763 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
765 g_object_get (tag, "underline-set", &val_set, NULL);
768 PangoUnderline underline;
769 g_object_get (tag, "underline", &underline, NULL);
770 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, underline);
772 temp_tags = temp_tags->next;
777 while (temp_tags && !val_set)
779 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
781 g_object_get (tag, "rise-set", &val_set, NULL);
786 g_object_get (tag, "rise", &rise, NULL);
787 value = g_strdup_printf ("%i", rise);
788 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
790 temp_tags = temp_tags->next;
795 while (temp_tags && !val_set)
797 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
799 g_object_get (tag, "background-full-height-set", &val_set, NULL);
802 gboolean bg_full_height;
803 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
804 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height);
806 temp_tags = temp_tags->next;
811 while (temp_tags && !val_set)
813 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
815 g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
820 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
821 value = g_strdup_printf ("%i", pixels);
822 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
824 temp_tags = temp_tags->next;
829 while (temp_tags && !val_set)
831 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
833 g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
838 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
839 value = g_strdup_printf ("%i", pixels);
840 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
842 temp_tags = temp_tags->next;
847 while (temp_tags && !val_set)
849 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
851 g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
856 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
857 value = g_strdup_printf ("%i", pixels);
858 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
860 temp_tags = temp_tags->next;
865 while (temp_tags && !val_set)
867 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
869 g_object_get (tag, "editable-set", &val_set, NULL);
873 g_object_get (tag, "editable", &editable, NULL);
874 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, editable);
876 temp_tags = temp_tags->next;
881 while (temp_tags && !val_set)
883 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
885 g_object_get (tag, "invisible-set", &val_set, NULL);
889 g_object_get (tag, "invisible", &invisible, NULL);
890 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, invisible);
892 temp_tags = temp_tags->next;
897 while (temp_tags && !val_set)
899 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
901 g_object_get (tag, "indent-set", &val_set, NULL);
906 g_object_get (tag, "indent", &indent, NULL);
907 value = g_strdup_printf ("%i", indent);
908 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
910 temp_tags = temp_tags->next;
915 while (temp_tags && !val_set)
917 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
919 g_object_get (tag, "right-margin-set", &val_set, NULL);
924 g_object_get (tag, "right-margin", &margin, NULL);
925 value = g_strdup_printf ("%i", margin);
926 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
928 temp_tags = temp_tags->next;
933 while (temp_tags && !val_set)
935 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
937 g_object_get (tag, "left-margin-set", &val_set, NULL);
942 g_object_get (tag, "left-margin", &margin, NULL);
943 value = g_strdup_printf ("%i", margin);
944 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
946 temp_tags = temp_tags->next;
954 static AtkAttributeSet *
955 gtk_text_view_accessible_get_default_attributes (AtkText *text)
959 GtkTextAttributes *text_attrs;
960 AtkAttributeSet *attributes;
961 PangoFontDescription *font;
964 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
968 view = GTK_TEXT_VIEW (widget);
969 text_attrs = gtk_text_view_get_default_attributes (view);
973 font = text_attrs->font;
977 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STYLE,
978 pango_font_description_get_style (font));
980 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_VARIANT,
981 pango_font_description_get_variant (font));
983 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRETCH,
984 pango_font_description_get_stretch (font));
986 value = g_strdup (pango_font_description_get_family (font));
987 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FAMILY_NAME, value);
989 value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
990 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_WEIGHT, value);
992 value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
993 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SIZE, value);
996 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
997 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
998 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
999 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
1000 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
1001 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
1003 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRIKETHROUGH,
1004 text_attrs->appearance.strikethrough);
1005 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_UNDERLINE,
1006 text_attrs->appearance.underline);
1008 value = g_strdup_printf ("%u,%u,%u",
1009 text_attrs->appearance.bg_color.red,
1010 text_attrs->appearance.bg_color.green,
1011 text_attrs->appearance.bg_color.blue);
1012 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_BG_COLOR, value);
1014 value = g_strdup_printf ("%u,%u,%u",
1015 text_attrs->appearance.fg_color.red,
1016 text_attrs->appearance.fg_color.green,
1017 text_attrs->appearance.fg_color.blue);
1018 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FG_COLOR, value);
1020 value = g_strdup_printf ("%g", text_attrs->font_scale);
1021 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SCALE, value);
1023 value = g_strdup ((gchar *)(text_attrs->language));
1024 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LANGUAGE, value);
1026 value = g_strdup_printf ("%i", text_attrs->appearance.rise);
1027 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RISE, value);
1029 value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
1030 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1032 value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
1033 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1035 value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
1036 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1038 value = g_strdup_printf ("%i", text_attrs->indent);
1039 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_INDENT, value);
1041 value = g_strdup_printf ("%i", text_attrs->left_margin);
1042 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1044 value = g_strdup_printf ("%i", text_attrs->right_margin);
1045 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1047 gtk_text_attributes_unref (text_attrs);
1052 gtk_text_view_accessible_get_n_selections (AtkText *text)
1055 GtkTextBuffer *buffer;
1057 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1061 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1062 if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1069 gtk_text_view_accessible_get_selection (AtkText *atk_text,
1076 GtkTextBuffer *buffer;
1077 GtkTextIter start, end;
1080 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
1084 if (selection_num != 0)
1087 view = GTK_TEXT_VIEW (widget);
1088 buffer = gtk_text_view_get_buffer (view);
1090 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1091 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1095 *start_pos = gtk_text_iter_get_offset (&start);
1096 *end_pos = gtk_text_iter_get_offset (&end);
1102 gtk_text_view_accessible_add_selection (AtkText *text,
1107 GtkTextBuffer *buffer;
1108 GtkTextIter start, end;
1110 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1114 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1116 if (!gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1118 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1119 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1120 gtk_text_buffer_select_range (buffer, &end, &start);
1129 gtk_text_view_accessible_remove_selection (AtkText *text,
1133 GtkTextBuffer *buffer;
1134 GtkTextMark *insert;
1136 GtkTextIter start, end;
1138 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1142 if (selection_num != 0)
1145 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1147 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1149 insert = gtk_text_buffer_get_insert (buffer);
1150 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
1151 gtk_text_buffer_place_cursor (buffer, &iter);
1159 gtk_text_view_accessible_set_selection (AtkText *text,
1165 GtkTextBuffer *buffer;
1166 GtkTextIter start, end;
1168 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1172 if (selection_num != 0)
1175 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1177 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1179 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1180 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1181 gtk_text_buffer_select_range (buffer, &end, &start);
1190 atk_text_interface_init (AtkTextIface *iface)
1192 iface->get_text = gtk_text_view_accessible_get_text;
1193 iface->get_text_after_offset = gtk_text_view_accessible_get_text_after_offset;
1194 iface->get_text_at_offset = gtk_text_view_accessible_get_text_at_offset;
1195 iface->get_text_before_offset = gtk_text_view_accessible_get_text_before_offset;
1196 iface->get_character_at_offset = gtk_text_view_accessible_get_character_at_offset;
1197 iface->get_character_count = gtk_text_view_accessible_get_character_count;
1198 iface->get_caret_offset = gtk_text_view_accessible_get_caret_offset;
1199 iface->set_caret_offset = gtk_text_view_accessible_set_caret_offset;
1200 iface->get_offset_at_point = gtk_text_view_accessible_get_offset_at_point;
1201 iface->get_character_extents = gtk_text_view_accessible_get_character_extents;
1202 iface->get_n_selections = gtk_text_view_accessible_get_n_selections;
1203 iface->get_selection = gtk_text_view_accessible_get_selection;
1204 iface->add_selection = gtk_text_view_accessible_add_selection;
1205 iface->remove_selection = gtk_text_view_accessible_remove_selection;
1206 iface->set_selection = gtk_text_view_accessible_set_selection;
1207 iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
1208 iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
1211 /* atkeditabletext.h */
1214 gtk_text_view_accessible_set_run_attributes (AtkEditableText *text,
1215 AtkAttributeSet *attributes,
1220 GtkTextBuffer *buffer;
1230 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1234 view = GTK_TEXT_VIEW (widget);
1235 if (!gtk_text_view_get_editable (view))
1238 buffer = gtk_text_view_get_buffer (view);
1240 if (attributes == NULL)
1243 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1244 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
1246 tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
1248 for (l = attributes; l; l = l->next)
1259 if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
1260 g_object_set (G_OBJECT (tag), "left_margin", atoi (value), NULL);
1262 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
1263 g_object_set (G_OBJECT (tag), "right_margin", atoi (value), NULL);
1265 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
1266 g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
1268 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
1269 g_object_set (G_OBJECT (tag), "pixels_above_lines", atoi (value), NULL);
1271 else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
1272 g_object_set (G_OBJECT (tag), "pixels_below_lines", atoi (value), NULL);
1274 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
1275 g_object_set (G_OBJECT (tag), "pixels_inside_wrap", atoi (value), NULL);
1277 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
1278 g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
1280 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
1281 g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
1283 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
1284 g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
1286 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
1288 g_object_set (G_OBJECT (tag), "bg_full_height",
1289 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
1293 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
1294 g_object_set (G_OBJECT (tag), "language", value, NULL);
1296 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
1297 g_object_set (G_OBJECT (tag), "family", value, NULL);
1299 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
1301 g_object_set (G_OBJECT (tag), "editable",
1302 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1306 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
1308 g_object_set (G_OBJECT (tag), "invisible",
1309 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1313 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
1315 for (j = 0; j < 3; j++)
1317 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
1319 g_object_set (G_OBJECT (tag), "underline", j, NULL);
1325 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
1327 g_object_set (G_OBJECT (tag), "strikethrough",
1328 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
1332 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
1334 RGB_vals = g_strsplit (value, ",", 3);
1335 color = g_malloc (sizeof (GdkColor));
1336 color->red = atoi (RGB_vals[0]);
1337 color->green = atoi (RGB_vals[1]);
1338 color->blue = atoi (RGB_vals[2]);
1339 g_object_set (G_OBJECT (tag), "background_gdk", color, NULL);
1342 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
1344 RGB_vals = g_strsplit (value, ",", 3);
1345 color = g_malloc (sizeof (GdkColor));
1346 color->red = atoi (RGB_vals[0]);
1347 color->green = atoi (RGB_vals[1]);
1348 color->blue = atoi (RGB_vals[2]);
1349 g_object_set (G_OBJECT (tag), "foreground_gdk", color, NULL);
1352 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
1354 for (j = 0; j < 9; j++)
1356 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
1358 g_object_set (G_OBJECT (tag), "stretch", j, NULL);
1364 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
1366 for (j = 0; j < 4; j++)
1368 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
1370 g_object_set (G_OBJECT (tag), "justification", j, NULL);
1376 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
1378 for (j = 0; j < 3; j++)
1380 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
1382 g_object_set (G_OBJECT (tag), "direction", j, NULL);
1388 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
1390 for (j = 0; j < 2; j++)
1392 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
1394 g_object_set (G_OBJECT (tag), "variant", j, NULL);
1400 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
1402 for (j = 0; j < 3; j++)
1404 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
1406 g_object_set (G_OBJECT (tag), "wrap_mode", j, NULL);
1412 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
1414 for (j = 0; j < 3; j++)
1416 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
1418 g_object_set (G_OBJECT (tag), "style", j, NULL);
1428 gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
1434 gtk_text_view_accessible_set_text_contents (AtkEditableText *text,
1435 const gchar *string)
1439 GtkTextBuffer *buffer;
1441 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1445 view = GTK_TEXT_VIEW (widget);
1446 if (!gtk_text_view_get_editable (view))
1449 buffer = gtk_text_view_get_buffer (view);
1450 gtk_text_buffer_set_text (buffer, string, -1);
1454 gtk_text_view_accessible_insert_text (AtkEditableText *text,
1455 const gchar *string,
1461 GtkTextBuffer *buffer;
1464 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1468 view = GTK_TEXT_VIEW (widget);
1469 if (!gtk_text_view_get_editable (view))
1472 buffer = gtk_text_view_get_buffer (view);
1473 gtk_text_buffer_get_iter_at_offset (buffer, &iter, *position);
1474 gtk_text_buffer_insert (buffer, &iter, string, length);
1478 gtk_text_view_accessible_copy_text (AtkEditableText *text,
1483 GtkTextBuffer *buffer;
1484 GtkTextIter start, end;
1486 GtkClipboard *clipboard;
1488 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1492 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1494 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1495 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1496 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1498 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1499 gtk_clipboard_set_text (clipboard, str, -1);
1503 gtk_text_view_accessible_cut_text (AtkEditableText *text,
1509 GtkTextBuffer *buffer;
1510 GtkTextIter start, end;
1512 GtkClipboard *clipboard;
1514 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1518 view = GTK_TEXT_VIEW (widget);
1519 if (!gtk_text_view_get_editable (view))
1521 buffer = gtk_text_view_get_buffer (view);
1523 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1524 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1525 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1526 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1527 gtk_clipboard_set_text (clipboard, str, -1);
1528 gtk_text_buffer_delete (buffer, &start, &end);
1532 gtk_text_view_accessible_delete_text (AtkEditableText *text,
1538 GtkTextBuffer *buffer;
1539 GtkTextIter start_itr;
1540 GtkTextIter end_itr;
1542 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1546 view = GTK_TEXT_VIEW (widget);
1547 if (!gtk_text_view_get_editable (view))
1549 buffer = gtk_text_view_get_buffer (view);
1551 gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
1552 gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
1553 gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
1558 GtkTextBuffer* buffer;
1563 paste_received (GtkClipboard *clipboard,
1567 PasteData* paste = data;
1568 GtkTextIter pos_itr;
1572 gtk_text_buffer_get_iter_at_offset (paste->buffer, &pos_itr, paste->position);
1573 gtk_text_buffer_insert (paste->buffer, &pos_itr, text, -1);
1576 g_object_unref (paste->buffer);
1580 gtk_text_view_accessible_paste_text (AtkEditableText *text,
1585 GtkTextBuffer *buffer;
1587 GtkClipboard *clipboard;
1589 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1593 view = GTK_TEXT_VIEW (widget);
1594 if (!gtk_text_view_get_editable (view))
1596 buffer = gtk_text_view_get_buffer (view);
1598 paste.buffer = buffer;
1599 paste.position = position;
1601 g_object_ref (paste.buffer);
1602 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1603 gtk_clipboard_request_text (clipboard, paste_received, &paste);
1607 atk_editable_text_interface_init (AtkEditableTextIface *iface)
1609 iface->set_text_contents = gtk_text_view_accessible_set_text_contents;
1610 iface->insert_text = gtk_text_view_accessible_insert_text;
1611 iface->copy_text = gtk_text_view_accessible_copy_text;
1612 iface->cut_text = gtk_text_view_accessible_cut_text;
1613 iface->delete_text = gtk_text_view_accessible_delete_text;
1614 iface->paste_text = gtk_text_view_accessible_paste_text;
1615 iface->set_run_attributes = gtk_text_view_accessible_set_run_attributes;
1621 gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
1622 GtkTextBuffer * buffer)
1624 int prev_insert_offset, prev_selection_bound;
1625 int insert_offset, selection_bound;
1628 prev_insert_offset = accessible->insert_offset;
1629 prev_selection_bound = accessible->selection_bound;
1631 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
1632 insert_offset = gtk_text_iter_get_offset (&iter);
1633 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
1634 selection_bound = gtk_text_iter_get_offset (&iter);
1636 if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
1639 accessible->insert_offset = insert_offset;
1640 accessible->selection_bound = selection_bound;
1642 if (prev_insert_offset != insert_offset)
1643 g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
1645 if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
1646 g_signal_emit_by_name (accessible, "text-selection-changed");
1650 insert_text_cb (GtkTextBuffer *buffer,
1656 GtkTextView *view = data;
1657 GtkTextViewAccessible *accessible;
1661 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
1663 position = gtk_text_iter_get_offset (iter);
1664 length = g_utf8_strlen (text, len);
1666 g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
1668 gtk_text_view_accessible_update_cursor (accessible, buffer);
1672 delete_range_cb (GtkTextBuffer *buffer,
1677 GtkTextView *view = data;
1678 GtkTextViewAccessible *accessible;
1679 gint offset, length;
1681 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (view)));
1683 offset = gtk_text_iter_get_offset (start);
1684 length = gtk_text_iter_get_offset (end) - offset;
1686 g_signal_emit_by_name (accessible,
1687 "text_changed::delete",
1691 gtk_text_view_accessible_update_cursor (accessible, buffer);
1695 mark_set_cb (GtkTextBuffer *buffer,
1696 GtkTextIter *location,
1700 GtkTextView *text = data;
1701 GtkTextViewAccessible *accessible;
1703 accessible = GTK_TEXT_VIEW_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (text)));
1706 * Only generate the signal for the "insert" mark, which
1707 * represents the cursor.
1709 if (mark == gtk_text_buffer_get_insert (buffer))
1711 gtk_text_view_accessible_update_cursor (accessible, buffer);
1713 else if (mark == gtk_text_buffer_get_selection_bound (buffer))
1715 gtk_text_view_accessible_update_cursor (accessible, buffer);
1720 gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
1723 GtkTextBuffer *buffer;
1724 gint n_mime_types = 0;
1726 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1730 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1734 gboolean advertises_plaintext = FALSE;
1737 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1738 for (i = 0; i < n_mime_types-1; ++i)
1739 if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
1740 advertises_plaintext = TRUE;
1741 if (!advertises_plaintext)
1745 return n_mime_types;
1748 static const gchar *
1749 gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
1753 GtkTextBuffer *buffer;
1755 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1759 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1762 gint n_mime_types = 0;
1765 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1766 if (i < n_mime_types)
1767 return gdk_atom_name (atoms [i]);
1768 else if (i == n_mime_types)
1769 return "text/plain";
1776 gail_streamable_content_get_stream (AtkStreamableContent *streamable,
1777 const gchar *mime_type)
1780 GtkTextBuffer *buffer;
1781 gint i, n_mime_types = 0;
1784 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1788 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1792 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1794 for (i = 0; i < n_mime_types; ++i)
1796 if (!strcmp ("text/plain", mime_type) ||
1797 !strcmp (gdk_atom_name (atoms[i]), mime_type))
1803 GtkTextIter start, end;
1804 GIOChannel *gio = NULL;
1807 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
1808 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
1809 if (!strcmp ("text/plain", mime_type))
1811 cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1812 len = strlen ((const char *) cbuf);
1816 cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
1818 g_snprintf (tname, 20, "streamXXXXXX");
1819 fd = g_mkstemp (tname);
1820 gio = g_io_channel_unix_new (fd);
1821 g_io_channel_set_encoding (gio, NULL, &err);
1823 g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
1825 g_message ("%s", err->message);
1827 g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
1829 g_message ("%s", err->message);
1831 g_io_channel_flush (gio, &err);
1833 g_message ("%s", err->message);
1836 g_message ("<error writing to stream [%s]>", tname);
1839 /* make sure the file is removed on unref of the giochannel */
1852 atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
1854 iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
1855 iface->get_mime_type = gail_streamable_content_get_mime_type;
1856 iface->get_stream = gail_streamable_content_get_stream;