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, see <http://www.gnu.org/licenses/>.
20 #include <sys/types.h>
28 #include <glib-object.h>
29 #include <glib/gstdio.h>
31 #include "gtktextviewaccessible.h"
32 #include "gtk/gtkwidgetprivate.h"
35 static void insert_text_cb (GtkTextBuffer *buffer,
40 static void delete_range_cb (GtkTextBuffer *buffer,
44 static void mark_set_cb (GtkTextBuffer *buffer,
50 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
51 static void atk_text_interface_init (AtkTextIface *iface);
52 static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
54 G_DEFINE_TYPE_WITH_CODE (GtkTextViewAccessible, _gtk_text_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
55 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
56 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
57 G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
61 gtk_text_view_accessible_initialize (AtkObject *obj,
64 ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->initialize (obj, data);
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);
85 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_text_view_accessible_parent_class)->notify_gtk (obj, pspec);
89 gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
91 AtkStateSet *state_set;
94 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
98 state_set = ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->ref_state_set (accessible);
100 if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
101 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
102 atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
108 gtk_text_view_accessible_change_buffer (GtkTextViewAccessible *accessible,
109 GtkTextBuffer *old_buffer,
110 GtkTextBuffer *new_buffer)
114 g_signal_handlers_disconnect_matched (old_buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, accessible);
119 g_signal_connect_after (new_buffer, "insert-text", G_CALLBACK (insert_text_cb), accessible);
120 g_signal_connect (new_buffer, "delete-range", G_CALLBACK (delete_range_cb), accessible);
121 g_signal_connect_after (new_buffer, "mark-set", G_CALLBACK (mark_set_cb), accessible);
126 gtk_text_view_accessible_widget_set (GtkAccessible *accessible)
128 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
130 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))));
134 gtk_text_view_accessible_widget_unset (GtkAccessible *accessible)
136 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
137 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))),
142 _gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
144 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
145 GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
146 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
148 accessible_class->widget_set = gtk_text_view_accessible_widget_set;
149 accessible_class->widget_unset = gtk_text_view_accessible_widget_unset;
151 class->ref_state_set = gtk_text_view_accessible_ref_state_set;
152 class->initialize = gtk_text_view_accessible_initialize;
154 widget_class->notify_gtk = gtk_text_view_accessible_notify_gtk;
158 _gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
163 gtk_text_view_accessible_get_text (AtkText *text,
168 GtkTextBuffer *buffer;
169 GtkTextIter start, end;
172 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
176 view = GTK_TEXT_VIEW (widget);
177 buffer = gtk_text_view_get_buffer (view);
178 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
179 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
181 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
185 gtk_text_view_accessible_get_text_after_offset (AtkText *text,
187 AtkTextBoundary boundary_type,
193 GtkTextBuffer *buffer;
195 GtkTextIter start, end;
197 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
201 view = GTK_TEXT_VIEW (widget);
202 buffer = gtk_text_view_get_buffer (view);
203 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
205 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
207 gtk_text_view_forward_display_line (view, &end);
209 gtk_text_view_forward_display_line (view, &end);
211 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
213 gtk_text_view_forward_display_line_end (view, &end);
215 gtk_text_view_forward_display_line (view, &end);
216 gtk_text_view_forward_display_line_end (view, &end);
219 _gtk_text_buffer_get_text_after (buffer, boundary_type, &pos, &start, &end);
221 *start_offset = gtk_text_iter_get_offset (&start);
222 *end_offset = gtk_text_iter_get_offset (&end);
224 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
228 gtk_text_view_accessible_get_text_at_offset (AtkText *text,
230 AtkTextBoundary boundary_type,
236 GtkTextBuffer *buffer;
238 GtkTextIter start, end;
240 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
244 view = GTK_TEXT_VIEW (widget);
245 buffer = gtk_text_view_get_buffer (view);
246 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
248 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
250 gtk_text_view_backward_display_line_start (view, &start);
251 gtk_text_view_forward_display_line (view, &end);
253 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
255 gtk_text_view_backward_display_line_start (view, &start);
256 if (!gtk_text_iter_is_start (&start))
258 gtk_text_view_backward_display_line (view, &start);
259 gtk_text_view_forward_display_line_end (view, &start);
261 gtk_text_view_forward_display_line_end (view, &end);
264 _gtk_text_buffer_get_text_at (buffer, boundary_type, &pos, &start, &end);
266 *start_offset = gtk_text_iter_get_offset (&start);
267 *end_offset = gtk_text_iter_get_offset (&end);
269 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
273 gtk_text_view_accessible_get_text_before_offset (AtkText *text,
275 AtkTextBoundary boundary_type,
281 GtkTextBuffer *buffer;
283 GtkTextIter start, end;
285 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
289 view = GTK_TEXT_VIEW (widget);
290 buffer = gtk_text_view_get_buffer (view);
291 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
294 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
296 gtk_text_view_backward_display_line_start (view, &start);
298 gtk_text_view_backward_display_line (view, &start);
299 gtk_text_view_backward_display_line_start (view, &start);
301 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
303 gtk_text_view_backward_display_line_start (view, &start);
304 if (!gtk_text_iter_is_start (&start))
306 gtk_text_view_backward_display_line (view, &start);
308 gtk_text_view_forward_display_line_end (view, &end);
309 if (!gtk_text_iter_is_start (&start))
311 if (gtk_text_view_backward_display_line (view, &start))
312 gtk_text_view_forward_display_line_end (view, &start);
314 gtk_text_iter_set_offset (&start, 0);
321 _gtk_text_buffer_get_text_before (buffer, boundary_type, &pos, &start, &end);
323 *start_offset = gtk_text_iter_get_offset (&start);
324 *end_offset = gtk_text_iter_get_offset (&end);
326 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
330 gtk_text_view_accessible_get_character_at_offset (AtkText *text,
334 GtkTextIter start, end;
335 GtkTextBuffer *buffer;
339 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
343 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
344 if (offset >= gtk_text_buffer_get_char_count (buffer))
347 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
349 gtk_text_iter_forward_char (&end);
350 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
351 unichar = g_utf8_get_char (string);
358 gtk_text_view_accessible_get_character_count (AtkText *text)
361 GtkTextBuffer *buffer;
363 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
367 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
368 return gtk_text_buffer_get_char_count (buffer);
372 get_insert_offset (GtkTextBuffer *buffer)
377 insert = gtk_text_buffer_get_insert (buffer);
378 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
379 return gtk_text_iter_get_offset (&iter);
383 gtk_text_view_accessible_get_caret_offset (AtkText *text)
386 GtkTextBuffer *buffer;
388 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
392 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
393 return get_insert_offset (buffer);
397 gtk_text_view_accessible_set_caret_offset (AtkText *text,
402 GtkTextBuffer *buffer;
405 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
409 view = GTK_TEXT_VIEW (widget);
410 buffer = gtk_text_view_get_buffer (view);
412 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
413 gtk_text_buffer_place_cursor (buffer, &iter);
414 gtk_text_view_scroll_to_iter (view, &iter, 0, FALSE, 0, 0);
420 gtk_text_view_accessible_get_offset_at_point (AtkText *text,
427 gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
432 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
436 view = GTK_TEXT_VIEW (widget);
437 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
438 gdk_window_get_origin (window, &x_widget, &y_widget);
440 if (coords == ATK_XY_SCREEN)
445 else if (coords == ATK_XY_WINDOW)
447 window = gdk_window_get_toplevel (window);
448 gdk_window_get_origin (window, &x_window, &y_window);
450 x = x - x_widget + x_window;
451 y = y - y_widget + y_window;
456 gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
457 x, y, &buff_x, &buff_y);
458 gtk_text_view_get_visible_rect (view, &rect);
460 /* Clamp point to visible rectangle */
461 buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
462 buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
464 gtk_text_view_get_iter_at_location (view, &iter, buff_x, buff_y);
466 /* The iter at a location sometimes points to the next character.
467 * See bug 111031. We work around that
469 gtk_text_view_get_iter_location (view, &iter, &rect);
471 gtk_text_iter_backward_char (&iter);
472 return gtk_text_iter_get_offset (&iter);
476 gtk_text_view_accessible_get_character_extents (AtkText *text,
485 GtkTextBuffer *buffer;
488 GdkRectangle rectangle;
490 gint x_widget, y_widget, x_window, y_window;
492 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
496 view = GTK_TEXT_VIEW (widget);
497 buffer = gtk_text_view_get_buffer (view);
498 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
499 gtk_text_view_get_iter_location (view, &iter, &rectangle);
501 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
502 gdk_window_get_origin (window, &x_widget, &y_widget);
504 *height = rectangle.height;
505 *width = rectangle.width;
507 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
508 rectangle.x, rectangle.y, x, y);
509 if (coords == ATK_XY_WINDOW)
511 window = gdk_window_get_toplevel (window);
512 gdk_window_get_origin (window, &x_window, &y_window);
513 *x += x_widget - x_window;
514 *y += y_widget - y_window;
516 else if (coords == ATK_XY_SCREEN)
530 static AtkAttributeSet *
531 add_text_attribute (AtkAttributeSet *attributes,
532 AtkTextAttribute attr,
537 at = g_new (AtkAttribute, 1);
538 at->name = g_strdup (atk_text_attribute_get_name (attr));
541 return g_slist_prepend (attributes, at);
544 static AtkAttributeSet *
545 add_text_int_attribute (AtkAttributeSet *attributes,
546 AtkTextAttribute attr,
552 value = g_strdup (atk_text_attribute_get_value (attr, i));
554 return add_text_attribute (attributes, attr, value);
557 static AtkAttributeSet *
558 gtk_text_view_accessible_get_run_attributes (AtkText *text,
564 GtkTextBuffer *buffer;
567 AtkAttributeSet *attrib_set = NULL;
568 GSList *tags, *temp_tags;
570 gboolean val_set = FALSE;
573 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
577 view = GTK_TEXT_VIEW (widget);
578 buffer = gtk_text_view_get_buffer (view);
580 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
582 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
583 *end_offset = gtk_text_iter_get_offset (&iter);
585 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
586 *start_offset = gtk_text_iter_get_offset (&iter);
588 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
590 tags = gtk_text_iter_get_tags (&iter);
591 tags = g_slist_reverse (tags);
594 while (temp_tags && !val_set)
596 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
598 g_object_get (tag, "style-set", &val_set, NULL);
602 g_object_get (tag, "style", &style, NULL);
603 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, style);
605 temp_tags = temp_tags->next;
610 while (temp_tags && !val_set)
612 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
614 g_object_get (tag, "variant-set", &val_set, NULL);
617 PangoVariant variant;
618 g_object_get (tag, "variant", &variant, NULL);
619 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, variant);
621 temp_tags = temp_tags->next;
626 while (temp_tags && !val_set)
628 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
630 g_object_get (tag, "stretch-set", &val_set, NULL);
633 PangoStretch stretch;
634 g_object_get (tag, "stretch", &stretch, NULL);
635 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, stretch);
637 temp_tags = temp_tags->next;
642 while (temp_tags && !val_set)
644 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
646 g_object_get (tag, "justification-set", &val_set, NULL);
649 GtkJustification justification;
650 g_object_get (tag, "justification", &justification, NULL);
651 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, justification);
653 temp_tags = temp_tags->next;
658 while (temp_tags && !val_set)
660 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
661 GtkTextDirection direction;
663 g_object_get (tag, "direction", &direction, NULL);
665 if (direction != GTK_TEXT_DIR_NONE)
668 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, direction);
670 temp_tags = temp_tags->next;
675 while (temp_tags && !val_set)
677 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
679 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
682 GtkWrapMode wrap_mode;
683 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
684 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, wrap_mode);
686 temp_tags = temp_tags->next;
691 while (temp_tags && !val_set)
693 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
695 g_object_get (tag, "foreground-set", &val_set, NULL);
701 g_object_get (tag, "foreground-rgba", &rgba, NULL);
702 value = g_strdup_printf ("%u,%u,%u",
703 (guint) rgba->red * 65535,
704 (guint) rgba->green * 65535,
705 (guint) rgba->blue * 65535);
706 gdk_rgba_free (rgba);
707 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
709 temp_tags = temp_tags->next;
714 while (temp_tags && !val_set)
716 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
718 g_object_get (tag, "background-set", &val_set, NULL);
724 g_object_get (tag, "background-rgba", &rgba, NULL);
725 value = g_strdup_printf ("%u,%u,%u",
726 (guint) rgba->red * 65535,
727 (guint) rgba->green * 65535,
728 (guint) rgba->blue * 65535);
729 gdk_rgba_free (rgba);
730 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
732 temp_tags = temp_tags->next;
737 while (temp_tags && !val_set)
739 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
741 g_object_get (tag, "family-set", &val_set, NULL);
746 g_object_get (tag, "family", &value, NULL);
747 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
749 temp_tags = temp_tags->next;
754 while (temp_tags && !val_set)
756 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
758 g_object_get (tag, "language-set", &val_set, NULL);
763 g_object_get (tag, "language", &value, NULL);
764 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
766 temp_tags = temp_tags->next;
771 while (temp_tags && !val_set)
773 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
775 g_object_get (tag, "weight-set", &val_set, NULL);
781 g_object_get (tag, "weight", &weight, NULL);
782 value = g_strdup_printf ("%d", weight);
783 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
785 temp_tags = temp_tags->next;
789 /* scale is special as the effective value is the product
790 * of all specified values
795 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
798 g_object_get (tag, "scale-set", &scale_set, NULL);
802 g_object_get (tag, "scale", &font_scale, NULL);
806 temp_tags = temp_tags->next;
811 value = g_strdup_printf ("%g", scale);
812 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
817 while (temp_tags && !val_set)
819 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
821 g_object_get (tag, "size-set", &val_set, NULL);
826 g_object_get (tag, "size", &size, NULL);
827 value = g_strdup_printf ("%i", size);
828 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
830 temp_tags = temp_tags->next;
835 while (temp_tags && !val_set)
837 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
839 g_object_get (tag, "strikethrough-set", &val_set, NULL);
842 gboolean strikethrough;
843 g_object_get (tag, "strikethrough", &strikethrough, NULL);
844 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough);
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, "underline-set", &val_set, NULL);
858 PangoUnderline underline;
859 g_object_get (tag, "underline", &underline, NULL);
860 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, underline);
862 temp_tags = temp_tags->next;
867 while (temp_tags && !val_set)
869 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
871 g_object_get (tag, "rise-set", &val_set, NULL);
876 g_object_get (tag, "rise", &rise, NULL);
877 value = g_strdup_printf ("%i", rise);
878 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
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, "background-full-height-set", &val_set, NULL);
892 gboolean bg_full_height;
893 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
894 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height);
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, "pixels-inside-wrap-set", &val_set, NULL);
910 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
911 value = g_strdup_printf ("%i", pixels);
912 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, 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, "pixels-below-lines-set", &val_set, NULL);
928 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
929 value = g_strdup_printf ("%i", pixels);
930 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, 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, "pixels-above-lines-set", &val_set, NULL);
946 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
947 value = g_strdup_printf ("%i", pixels);
948 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
950 temp_tags = temp_tags->next;
955 while (temp_tags && !val_set)
957 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
959 g_object_get (tag, "editable-set", &val_set, NULL);
963 g_object_get (tag, "editable", &editable, NULL);
964 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, editable);
966 temp_tags = temp_tags->next;
971 while (temp_tags && !val_set)
973 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
975 g_object_get (tag, "invisible-set", &val_set, NULL);
979 g_object_get (tag, "invisible", &invisible, NULL);
980 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, invisible);
982 temp_tags = temp_tags->next;
987 while (temp_tags && !val_set)
989 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
991 g_object_get (tag, "indent-set", &val_set, NULL);
996 g_object_get (tag, "indent", &indent, NULL);
997 value = g_strdup_printf ("%i", indent);
998 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
1000 temp_tags = temp_tags->next;
1005 while (temp_tags && !val_set)
1007 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1009 g_object_get (tag, "right-margin-set", &val_set, NULL);
1014 g_object_get (tag, "right-margin", &margin, NULL);
1015 value = g_strdup_printf ("%i", margin);
1016 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1018 temp_tags = temp_tags->next;
1023 while (temp_tags && !val_set)
1025 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1027 g_object_get (tag, "left-margin-set", &val_set, NULL);
1032 g_object_get (tag, "left-margin", &margin, NULL);
1033 value = g_strdup_printf ("%i", margin);
1034 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1036 temp_tags = temp_tags->next;
1040 g_slist_free (tags);
1044 static AtkAttributeSet *
1045 gtk_text_view_accessible_get_default_attributes (AtkText *text)
1049 GtkTextAttributes *text_attrs;
1050 AtkAttributeSet *attributes;
1051 PangoFontDescription *font;
1054 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1058 view = GTK_TEXT_VIEW (widget);
1059 text_attrs = gtk_text_view_get_default_attributes (view);
1063 font = text_attrs->font;
1067 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STYLE,
1068 pango_font_description_get_style (font));
1070 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_VARIANT,
1071 pango_font_description_get_variant (font));
1073 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRETCH,
1074 pango_font_description_get_stretch (font));
1076 value = g_strdup (pango_font_description_get_family (font));
1077 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FAMILY_NAME, value);
1079 value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
1080 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_WEIGHT, value);
1082 value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
1083 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SIZE, value);
1086 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
1087 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
1088 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
1089 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
1090 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
1091 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
1093 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRIKETHROUGH,
1094 text_attrs->appearance.strikethrough);
1095 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_UNDERLINE,
1096 text_attrs->appearance.underline);
1098 value = g_strdup_printf ("%u,%u,%u",
1099 text_attrs->appearance.bg_color.red,
1100 text_attrs->appearance.bg_color.green,
1101 text_attrs->appearance.bg_color.blue);
1102 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_BG_COLOR, value);
1104 value = g_strdup_printf ("%u,%u,%u",
1105 text_attrs->appearance.fg_color.red,
1106 text_attrs->appearance.fg_color.green,
1107 text_attrs->appearance.fg_color.blue);
1108 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FG_COLOR, value);
1110 value = g_strdup_printf ("%g", text_attrs->font_scale);
1111 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SCALE, value);
1113 value = g_strdup ((gchar *)(text_attrs->language));
1114 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LANGUAGE, value);
1116 value = g_strdup_printf ("%i", text_attrs->appearance.rise);
1117 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RISE, value);
1119 value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
1120 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1122 value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
1123 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1125 value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
1126 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1128 value = g_strdup_printf ("%i", text_attrs->indent);
1129 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_INDENT, value);
1131 value = g_strdup_printf ("%i", text_attrs->left_margin);
1132 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1134 value = g_strdup_printf ("%i", text_attrs->right_margin);
1135 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1137 gtk_text_attributes_unref (text_attrs);
1142 gtk_text_view_accessible_get_n_selections (AtkText *text)
1145 GtkTextBuffer *buffer;
1147 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1151 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1152 if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1159 gtk_text_view_accessible_get_selection (AtkText *atk_text,
1166 GtkTextBuffer *buffer;
1167 GtkTextIter start, end;
1170 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
1174 if (selection_num != 0)
1177 view = GTK_TEXT_VIEW (widget);
1178 buffer = gtk_text_view_get_buffer (view);
1180 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1181 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1185 *start_pos = gtk_text_iter_get_offset (&start);
1186 *end_pos = gtk_text_iter_get_offset (&end);
1192 gtk_text_view_accessible_add_selection (AtkText *text,
1197 GtkTextBuffer *buffer;
1198 GtkTextIter start, end;
1200 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1204 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1206 if (!gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1208 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1209 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1210 gtk_text_buffer_select_range (buffer, &end, &start);
1219 gtk_text_view_accessible_remove_selection (AtkText *text,
1223 GtkTextBuffer *buffer;
1224 GtkTextMark *insert;
1226 GtkTextIter start, end;
1228 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1232 if (selection_num != 0)
1235 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1237 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1239 insert = gtk_text_buffer_get_insert (buffer);
1240 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
1241 gtk_text_buffer_place_cursor (buffer, &iter);
1249 gtk_text_view_accessible_set_selection (AtkText *text,
1255 GtkTextBuffer *buffer;
1256 GtkTextIter start, end;
1258 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1262 if (selection_num != 0)
1265 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1267 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1269 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1270 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1271 gtk_text_buffer_select_range (buffer, &end, &start);
1280 atk_text_interface_init (AtkTextIface *iface)
1282 iface->get_text = gtk_text_view_accessible_get_text;
1283 iface->get_text_after_offset = gtk_text_view_accessible_get_text_after_offset;
1284 iface->get_text_at_offset = gtk_text_view_accessible_get_text_at_offset;
1285 iface->get_text_before_offset = gtk_text_view_accessible_get_text_before_offset;
1286 iface->get_character_at_offset = gtk_text_view_accessible_get_character_at_offset;
1287 iface->get_character_count = gtk_text_view_accessible_get_character_count;
1288 iface->get_caret_offset = gtk_text_view_accessible_get_caret_offset;
1289 iface->set_caret_offset = gtk_text_view_accessible_set_caret_offset;
1290 iface->get_offset_at_point = gtk_text_view_accessible_get_offset_at_point;
1291 iface->get_character_extents = gtk_text_view_accessible_get_character_extents;
1292 iface->get_n_selections = gtk_text_view_accessible_get_n_selections;
1293 iface->get_selection = gtk_text_view_accessible_get_selection;
1294 iface->add_selection = gtk_text_view_accessible_add_selection;
1295 iface->remove_selection = gtk_text_view_accessible_remove_selection;
1296 iface->set_selection = gtk_text_view_accessible_set_selection;
1297 iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
1298 iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
1301 /* atkeditabletext.h */
1304 gtk_text_view_accessible_set_run_attributes (AtkEditableText *text,
1305 AtkAttributeSet *attributes,
1310 GtkTextBuffer *buffer;
1320 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1324 view = GTK_TEXT_VIEW (widget);
1325 if (!gtk_text_view_get_editable (view))
1328 buffer = gtk_text_view_get_buffer (view);
1330 if (attributes == NULL)
1333 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1334 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
1336 tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
1338 for (l = attributes; l; l = l->next)
1349 if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
1350 g_object_set (G_OBJECT (tag), "left-margin", atoi (value), NULL);
1352 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
1353 g_object_set (G_OBJECT (tag), "right-margin", atoi (value), NULL);
1355 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
1356 g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
1358 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
1359 g_object_set (G_OBJECT (tag), "pixels-above-lines", atoi (value), NULL);
1361 else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
1362 g_object_set (G_OBJECT (tag), "pixels-below-lines", atoi (value), NULL);
1364 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
1365 g_object_set (G_OBJECT (tag), "pixels-inside-wrap", atoi (value), NULL);
1367 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
1368 g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
1370 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
1371 g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
1373 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
1374 g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
1376 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
1378 g_object_set (G_OBJECT (tag), "bg-full-height",
1379 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
1383 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
1384 g_object_set (G_OBJECT (tag), "language", value, NULL);
1386 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
1387 g_object_set (G_OBJECT (tag), "family", value, NULL);
1389 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
1391 g_object_set (G_OBJECT (tag), "editable",
1392 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1396 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
1398 g_object_set (G_OBJECT (tag), "invisible",
1399 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1403 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
1405 for (j = 0; j < 3; j++)
1407 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
1409 g_object_set (G_OBJECT (tag), "underline", j, NULL);
1415 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
1417 g_object_set (G_OBJECT (tag), "strikethrough",
1418 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
1422 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
1424 RGB_vals = g_strsplit (value, ",", 3);
1425 color = g_malloc (sizeof (GdkColor));
1426 color->red = atoi (RGB_vals[0]);
1427 color->green = atoi (RGB_vals[1]);
1428 color->blue = atoi (RGB_vals[2]);
1429 g_object_set (G_OBJECT (tag), "background-gdk", color, NULL);
1432 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
1434 RGB_vals = g_strsplit (value, ",", 3);
1435 color = g_malloc (sizeof (GdkColor));
1436 color->red = atoi (RGB_vals[0]);
1437 color->green = atoi (RGB_vals[1]);
1438 color->blue = atoi (RGB_vals[2]);
1439 g_object_set (G_OBJECT (tag), "foreground-gdk", color, NULL);
1442 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
1444 for (j = 0; j < 9; j++)
1446 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
1448 g_object_set (G_OBJECT (tag), "stretch", j, NULL);
1454 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
1456 for (j = 0; j < 4; j++)
1458 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
1460 g_object_set (G_OBJECT (tag), "justification", j, NULL);
1466 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
1468 for (j = 0; j < 3; j++)
1470 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
1472 g_object_set (G_OBJECT (tag), "direction", j, NULL);
1478 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
1480 for (j = 0; j < 2; j++)
1482 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
1484 g_object_set (G_OBJECT (tag), "variant", j, NULL);
1490 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
1492 for (j = 0; j < 3; j++)
1494 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
1496 g_object_set (G_OBJECT (tag), "wrap-mode", j, NULL);
1502 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
1504 for (j = 0; j < 3; j++)
1506 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
1508 g_object_set (G_OBJECT (tag), "style", j, NULL);
1518 gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
1524 gtk_text_view_accessible_set_text_contents (AtkEditableText *text,
1525 const gchar *string)
1529 GtkTextBuffer *buffer;
1531 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1535 view = GTK_TEXT_VIEW (widget);
1536 if (!gtk_text_view_get_editable (view))
1539 buffer = gtk_text_view_get_buffer (view);
1540 gtk_text_buffer_set_text (buffer, string, -1);
1544 gtk_text_view_accessible_insert_text (AtkEditableText *text,
1545 const gchar *string,
1551 GtkTextBuffer *buffer;
1554 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1558 view = GTK_TEXT_VIEW (widget);
1559 if (!gtk_text_view_get_editable (view))
1562 buffer = gtk_text_view_get_buffer (view);
1563 gtk_text_buffer_get_iter_at_offset (buffer, &iter, *position);
1564 gtk_text_buffer_insert (buffer, &iter, string, length);
1568 gtk_text_view_accessible_copy_text (AtkEditableText *text,
1573 GtkTextBuffer *buffer;
1574 GtkTextIter start, end;
1576 GtkClipboard *clipboard;
1578 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1582 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1584 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1585 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1586 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1588 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1589 gtk_clipboard_set_text (clipboard, str, -1);
1593 gtk_text_view_accessible_cut_text (AtkEditableText *text,
1599 GtkTextBuffer *buffer;
1600 GtkTextIter start, end;
1602 GtkClipboard *clipboard;
1604 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1608 view = GTK_TEXT_VIEW (widget);
1609 if (!gtk_text_view_get_editable (view))
1611 buffer = gtk_text_view_get_buffer (view);
1613 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1614 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1615 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1616 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1617 gtk_clipboard_set_text (clipboard, str, -1);
1618 gtk_text_buffer_delete (buffer, &start, &end);
1622 gtk_text_view_accessible_delete_text (AtkEditableText *text,
1628 GtkTextBuffer *buffer;
1629 GtkTextIter start_itr;
1630 GtkTextIter end_itr;
1632 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1636 view = GTK_TEXT_VIEW (widget);
1637 if (!gtk_text_view_get_editable (view))
1639 buffer = gtk_text_view_get_buffer (view);
1641 gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
1642 gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
1643 gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
1648 GtkTextBuffer* buffer;
1653 paste_received (GtkClipboard *clipboard,
1657 PasteData* paste = data;
1658 GtkTextIter pos_itr;
1662 gtk_text_buffer_get_iter_at_offset (paste->buffer, &pos_itr, paste->position);
1663 gtk_text_buffer_insert (paste->buffer, &pos_itr, text, -1);
1666 g_object_unref (paste->buffer);
1670 gtk_text_view_accessible_paste_text (AtkEditableText *text,
1675 GtkTextBuffer *buffer;
1677 GtkClipboard *clipboard;
1679 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1683 view = GTK_TEXT_VIEW (widget);
1684 if (!gtk_text_view_get_editable (view))
1686 buffer = gtk_text_view_get_buffer (view);
1688 paste.buffer = buffer;
1689 paste.position = position;
1691 g_object_ref (paste.buffer);
1692 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1693 gtk_clipboard_request_text (clipboard, paste_received, &paste);
1697 atk_editable_text_interface_init (AtkEditableTextIface *iface)
1699 iface->set_text_contents = gtk_text_view_accessible_set_text_contents;
1700 iface->insert_text = gtk_text_view_accessible_insert_text;
1701 iface->copy_text = gtk_text_view_accessible_copy_text;
1702 iface->cut_text = gtk_text_view_accessible_cut_text;
1703 iface->delete_text = gtk_text_view_accessible_delete_text;
1704 iface->paste_text = gtk_text_view_accessible_paste_text;
1705 iface->set_run_attributes = gtk_text_view_accessible_set_run_attributes;
1711 gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
1712 GtkTextBuffer * buffer)
1714 int prev_insert_offset, prev_selection_bound;
1715 int insert_offset, selection_bound;
1718 prev_insert_offset = accessible->insert_offset;
1719 prev_selection_bound = accessible->selection_bound;
1721 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
1722 insert_offset = gtk_text_iter_get_offset (&iter);
1723 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
1724 selection_bound = gtk_text_iter_get_offset (&iter);
1726 if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
1729 accessible->insert_offset = insert_offset;
1730 accessible->selection_bound = selection_bound;
1732 if (prev_insert_offset != insert_offset)
1733 g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
1735 if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
1736 g_signal_emit_by_name (accessible, "text-selection-changed");
1740 insert_text_cb (GtkTextBuffer *buffer,
1746 GtkTextViewAccessible *accessible = data;
1750 position = gtk_text_iter_get_offset (iter);
1751 length = g_utf8_strlen (text, len);
1753 g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
1755 gtk_text_view_accessible_update_cursor (accessible, buffer);
1759 delete_range_cb (GtkTextBuffer *buffer,
1764 GtkTextViewAccessible *accessible = data;
1765 gint offset, length;
1767 offset = gtk_text_iter_get_offset (start);
1768 length = gtk_text_iter_get_offset (end) - offset;
1770 g_signal_emit_by_name (accessible,
1771 "text-changed::delete",
1775 gtk_text_view_accessible_update_cursor (accessible, buffer);
1779 mark_set_cb (GtkTextBuffer *buffer,
1780 GtkTextIter *location,
1784 GtkTextViewAccessible *accessible = data;
1787 * Only generate the signal for the "insert" mark, which
1788 * represents the cursor.
1790 if (mark == gtk_text_buffer_get_insert (buffer))
1792 gtk_text_view_accessible_update_cursor (accessible, buffer);
1794 else if (mark == gtk_text_buffer_get_selection_bound (buffer))
1796 gtk_text_view_accessible_update_cursor (accessible, buffer);
1801 gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
1804 GtkTextBuffer *buffer;
1805 gint n_mime_types = 0;
1807 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1811 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1815 gboolean advertises_plaintext = FALSE;
1818 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1819 for (i = 0; i < n_mime_types-1; ++i)
1820 if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
1821 advertises_plaintext = TRUE;
1822 if (!advertises_plaintext)
1826 return n_mime_types;
1829 static const gchar *
1830 gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
1834 GtkTextBuffer *buffer;
1836 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1840 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1843 gint n_mime_types = 0;
1846 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1847 if (i < n_mime_types)
1848 return gdk_atom_name (atoms [i]);
1849 else if (i == n_mime_types)
1850 return "text/plain";
1857 gail_streamable_content_get_stream (AtkStreamableContent *streamable,
1858 const gchar *mime_type)
1861 GtkTextBuffer *buffer;
1862 gint i, n_mime_types = 0;
1865 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1869 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1873 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1875 for (i = 0; i < n_mime_types; ++i)
1877 if (!strcmp ("text/plain", mime_type) ||
1878 !strcmp (gdk_atom_name (atoms[i]), mime_type))
1884 GtkTextIter start, end;
1885 GIOChannel *gio = NULL;
1888 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
1889 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
1890 if (!strcmp ("text/plain", mime_type))
1892 cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1893 len = strlen ((const char *) cbuf);
1897 cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
1899 g_snprintf (tname, 20, "streamXXXXXX");
1900 fd = g_mkstemp (tname);
1901 gio = g_io_channel_unix_new (fd);
1902 g_io_channel_set_encoding (gio, NULL, &err);
1904 g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
1906 g_message ("%s", err->message);
1908 g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
1910 g_message ("%s", err->message);
1912 g_io_channel_flush (gio, &err);
1914 g_message ("%s", err->message);
1917 g_message ("<error writing to stream [%s]>", tname);
1920 /* make sure the file is removed on unref of the giochannel */
1933 atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
1935 iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
1936 iface->get_mime_type = gail_streamable_content_get_mime_type;
1937 iface->get_stream = gail_streamable_content_get_stream;
1941 _gtk_text_view_accessible_set_buffer (GtkTextView *textview,
1942 GtkTextBuffer *old_buffer)
1944 GtkTextViewAccessible *accessible;
1946 g_return_if_fail (GTK_IS_TEXT_VIEW (textview));
1947 g_return_if_fail (old_buffer == NULL || GTK_IS_TEXT_BUFFER (old_buffer));
1949 accessible = GTK_TEXT_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (textview)));
1950 if (accessible == NULL)
1953 gtk_text_view_accessible_change_buffer (accessible,
1955 gtk_text_view_get_buffer (textview));