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"
34 struct _GtkTextViewAccessiblePrivate
40 static void insert_text_cb (GtkTextBuffer *buffer,
45 static void delete_range_cb (GtkTextBuffer *buffer,
49 static void mark_set_cb (GtkTextBuffer *buffer,
55 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
56 static void atk_text_interface_init (AtkTextIface *iface);
57 static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
59 G_DEFINE_TYPE_WITH_CODE (GtkTextViewAccessible, _gtk_text_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
60 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
61 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
62 G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
66 gtk_text_view_accessible_initialize (AtkObject *obj,
69 ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->initialize (obj, data);
71 obj->role = ATK_ROLE_TEXT;
75 gtk_text_view_accessible_notify_gtk (GObject *obj,
80 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
82 if (!strcmp (pspec->name, "editable"))
86 editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
87 atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, editable);
90 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_text_view_accessible_parent_class)->notify_gtk (obj, pspec);
94 gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
96 AtkStateSet *state_set;
99 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
103 state_set = ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->ref_state_set (accessible);
105 if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
106 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
107 atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
113 gtk_text_view_accessible_change_buffer (GtkTextViewAccessible *accessible,
114 GtkTextBuffer *old_buffer,
115 GtkTextBuffer *new_buffer)
119 g_signal_handlers_disconnect_matched (old_buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, accessible);
124 g_signal_connect_after (new_buffer, "insert-text", G_CALLBACK (insert_text_cb), accessible);
125 g_signal_connect (new_buffer, "delete-range", G_CALLBACK (delete_range_cb), accessible);
126 g_signal_connect_after (new_buffer, "mark-set", G_CALLBACK (mark_set_cb), accessible);
131 gtk_text_view_accessible_widget_set (GtkAccessible *accessible)
133 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
135 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))));
139 gtk_text_view_accessible_widget_unset (GtkAccessible *accessible)
141 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
142 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))),
147 _gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
149 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
150 GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
151 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
153 accessible_class->widget_set = gtk_text_view_accessible_widget_set;
154 accessible_class->widget_unset = gtk_text_view_accessible_widget_unset;
156 class->ref_state_set = gtk_text_view_accessible_ref_state_set;
157 class->initialize = gtk_text_view_accessible_initialize;
159 widget_class->notify_gtk = gtk_text_view_accessible_notify_gtk;
161 g_type_class_add_private (klass, sizeof (GtkTextViewAccessiblePrivate));
165 _gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
167 accessible->priv = G_TYPE_INSTANCE_GET_PRIVATE (accessible,
168 GTK_TYPE_TEXT_VIEW_ACCESSIBLE,
169 GtkTextViewAccessiblePrivate);
173 gtk_text_view_accessible_get_text (AtkText *text,
178 GtkTextBuffer *buffer;
179 GtkTextIter start, end;
182 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
186 view = GTK_TEXT_VIEW (widget);
187 buffer = gtk_text_view_get_buffer (view);
188 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
189 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
191 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
195 gtk_text_view_accessible_get_text_after_offset (AtkText *text,
197 AtkTextBoundary boundary_type,
203 GtkTextBuffer *buffer;
205 GtkTextIter start, end;
207 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
211 view = GTK_TEXT_VIEW (widget);
212 buffer = gtk_text_view_get_buffer (view);
213 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
215 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
217 gtk_text_view_forward_display_line (view, &end);
219 gtk_text_view_forward_display_line (view, &end);
221 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
223 gtk_text_view_forward_display_line_end (view, &end);
225 gtk_text_view_forward_display_line (view, &end);
226 gtk_text_view_forward_display_line_end (view, &end);
229 _gtk_text_buffer_get_text_after (buffer, boundary_type, &pos, &start, &end);
231 *start_offset = gtk_text_iter_get_offset (&start);
232 *end_offset = gtk_text_iter_get_offset (&end);
234 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
238 gtk_text_view_accessible_get_text_at_offset (AtkText *text,
240 AtkTextBoundary boundary_type,
246 GtkTextBuffer *buffer;
248 GtkTextIter start, end;
250 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
254 view = GTK_TEXT_VIEW (widget);
255 buffer = gtk_text_view_get_buffer (view);
256 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
258 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
260 gtk_text_view_backward_display_line_start (view, &start);
261 gtk_text_view_forward_display_line (view, &end);
263 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
265 gtk_text_view_backward_display_line_start (view, &start);
266 if (!gtk_text_iter_is_start (&start))
268 gtk_text_view_backward_display_line (view, &start);
269 gtk_text_view_forward_display_line_end (view, &start);
271 gtk_text_view_forward_display_line_end (view, &end);
274 _gtk_text_buffer_get_text_at (buffer, boundary_type, &pos, &start, &end);
276 *start_offset = gtk_text_iter_get_offset (&start);
277 *end_offset = gtk_text_iter_get_offset (&end);
279 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
283 gtk_text_view_accessible_get_text_before_offset (AtkText *text,
285 AtkTextBoundary boundary_type,
291 GtkTextBuffer *buffer;
293 GtkTextIter start, end;
295 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
299 view = GTK_TEXT_VIEW (widget);
300 buffer = gtk_text_view_get_buffer (view);
301 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
304 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
306 gtk_text_view_backward_display_line_start (view, &start);
308 gtk_text_view_backward_display_line (view, &start);
309 gtk_text_view_backward_display_line_start (view, &start);
311 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
313 gtk_text_view_backward_display_line_start (view, &start);
314 if (!gtk_text_iter_is_start (&start))
316 gtk_text_view_backward_display_line (view, &start);
318 gtk_text_view_forward_display_line_end (view, &end);
319 if (!gtk_text_iter_is_start (&start))
321 if (gtk_text_view_backward_display_line (view, &start))
322 gtk_text_view_forward_display_line_end (view, &start);
324 gtk_text_iter_set_offset (&start, 0);
331 _gtk_text_buffer_get_text_before (buffer, boundary_type, &pos, &start, &end);
333 *start_offset = gtk_text_iter_get_offset (&start);
334 *end_offset = gtk_text_iter_get_offset (&end);
336 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
340 gtk_text_view_accessible_get_character_at_offset (AtkText *text,
344 GtkTextIter start, end;
345 GtkTextBuffer *buffer;
349 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
353 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
354 if (offset >= gtk_text_buffer_get_char_count (buffer))
357 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
359 gtk_text_iter_forward_char (&end);
360 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
361 unichar = g_utf8_get_char (string);
368 gtk_text_view_accessible_get_character_count (AtkText *text)
371 GtkTextBuffer *buffer;
373 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
377 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
378 return gtk_text_buffer_get_char_count (buffer);
382 get_insert_offset (GtkTextBuffer *buffer)
387 insert = gtk_text_buffer_get_insert (buffer);
388 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
389 return gtk_text_iter_get_offset (&iter);
393 gtk_text_view_accessible_get_caret_offset (AtkText *text)
396 GtkTextBuffer *buffer;
398 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
402 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
403 return get_insert_offset (buffer);
407 gtk_text_view_accessible_set_caret_offset (AtkText *text,
412 GtkTextBuffer *buffer;
415 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
419 view = GTK_TEXT_VIEW (widget);
420 buffer = gtk_text_view_get_buffer (view);
422 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
423 gtk_text_buffer_place_cursor (buffer, &iter);
424 gtk_text_view_scroll_to_iter (view, &iter, 0, FALSE, 0, 0);
430 gtk_text_view_accessible_get_offset_at_point (AtkText *text,
437 gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
442 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
446 view = GTK_TEXT_VIEW (widget);
447 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
448 gdk_window_get_origin (window, &x_widget, &y_widget);
450 if (coords == ATK_XY_SCREEN)
455 else if (coords == ATK_XY_WINDOW)
457 window = gdk_window_get_toplevel (window);
458 gdk_window_get_origin (window, &x_window, &y_window);
460 x = x - x_widget + x_window;
461 y = y - y_widget + y_window;
466 gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
467 x, y, &buff_x, &buff_y);
468 gtk_text_view_get_visible_rect (view, &rect);
470 /* Clamp point to visible rectangle */
471 buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
472 buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
474 gtk_text_view_get_iter_at_location (view, &iter, buff_x, buff_y);
476 /* The iter at a location sometimes points to the next character.
477 * See bug 111031. We work around that
479 gtk_text_view_get_iter_location (view, &iter, &rect);
481 gtk_text_iter_backward_char (&iter);
482 return gtk_text_iter_get_offset (&iter);
486 gtk_text_view_accessible_get_character_extents (AtkText *text,
495 GtkTextBuffer *buffer;
498 GdkRectangle rectangle;
500 gint x_widget, y_widget, x_window, y_window;
502 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
506 view = GTK_TEXT_VIEW (widget);
507 buffer = gtk_text_view_get_buffer (view);
508 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
509 gtk_text_view_get_iter_location (view, &iter, &rectangle);
511 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
512 gdk_window_get_origin (window, &x_widget, &y_widget);
514 *height = rectangle.height;
515 *width = rectangle.width;
517 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
518 rectangle.x, rectangle.y, x, y);
519 if (coords == ATK_XY_WINDOW)
521 window = gdk_window_get_toplevel (window);
522 gdk_window_get_origin (window, &x_window, &y_window);
523 *x += x_widget - x_window;
524 *y += y_widget - y_window;
526 else if (coords == ATK_XY_SCREEN)
540 static AtkAttributeSet *
541 add_text_attribute (AtkAttributeSet *attributes,
542 AtkTextAttribute attr,
547 at = g_new (AtkAttribute, 1);
548 at->name = g_strdup (atk_text_attribute_get_name (attr));
551 return g_slist_prepend (attributes, at);
554 static AtkAttributeSet *
555 add_text_int_attribute (AtkAttributeSet *attributes,
556 AtkTextAttribute attr,
562 value = g_strdup (atk_text_attribute_get_value (attr, i));
564 return add_text_attribute (attributes, attr, value);
567 static AtkAttributeSet *
568 gtk_text_view_accessible_get_run_attributes (AtkText *text,
574 GtkTextBuffer *buffer;
577 AtkAttributeSet *attrib_set = NULL;
578 GSList *tags, *temp_tags;
580 gboolean val_set = FALSE;
582 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
586 view = GTK_TEXT_VIEW (widget);
587 buffer = gtk_text_view_get_buffer (view);
589 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
591 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
592 *end_offset = gtk_text_iter_get_offset (&iter);
594 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
595 *start_offset = gtk_text_iter_get_offset (&iter);
597 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
599 tags = gtk_text_iter_get_tags (&iter);
600 tags = g_slist_reverse (tags);
603 while (temp_tags && !val_set)
605 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
607 g_object_get (tag, "style-set", &val_set, NULL);
611 g_object_get (tag, "style", &style, NULL);
612 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, style);
614 temp_tags = temp_tags->next;
619 while (temp_tags && !val_set)
621 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
623 g_object_get (tag, "variant-set", &val_set, NULL);
626 PangoVariant variant;
627 g_object_get (tag, "variant", &variant, NULL);
628 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, variant);
630 temp_tags = temp_tags->next;
635 while (temp_tags && !val_set)
637 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
639 g_object_get (tag, "stretch-set", &val_set, NULL);
642 PangoStretch stretch;
643 g_object_get (tag, "stretch", &stretch, NULL);
644 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, stretch);
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, "justification-set", &val_set, NULL);
658 GtkJustification justification;
659 g_object_get (tag, "justification", &justification, NULL);
660 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, justification);
662 temp_tags = temp_tags->next;
667 while (temp_tags && !val_set)
669 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
670 GtkTextDirection direction;
672 g_object_get (tag, "direction", &direction, NULL);
674 if (direction != GTK_TEXT_DIR_NONE)
677 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, direction);
679 temp_tags = temp_tags->next;
684 while (temp_tags && !val_set)
686 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
688 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
691 GtkWrapMode wrap_mode;
692 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
693 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, wrap_mode);
695 temp_tags = temp_tags->next;
700 while (temp_tags && !val_set)
702 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
704 g_object_get (tag, "foreground-set", &val_set, NULL);
710 g_object_get (tag, "foreground-rgba", &rgba, NULL);
711 value = g_strdup_printf ("%u,%u,%u",
712 (guint) rgba->red * 65535,
713 (guint) rgba->green * 65535,
714 (guint) rgba->blue * 65535);
715 gdk_rgba_free (rgba);
716 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
718 temp_tags = temp_tags->next;
723 while (temp_tags && !val_set)
725 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
727 g_object_get (tag, "background-set", &val_set, NULL);
733 g_object_get (tag, "background-rgba", &rgba, NULL);
734 value = g_strdup_printf ("%u,%u,%u",
735 (guint) rgba->red * 65535,
736 (guint) rgba->green * 65535,
737 (guint) rgba->blue * 65535);
738 gdk_rgba_free (rgba);
739 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
741 temp_tags = temp_tags->next;
746 while (temp_tags && !val_set)
748 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
750 g_object_get (tag, "family-set", &val_set, NULL);
755 g_object_get (tag, "family", &value, NULL);
756 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
758 temp_tags = temp_tags->next;
763 while (temp_tags && !val_set)
765 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
767 g_object_get (tag, "language-set", &val_set, NULL);
772 g_object_get (tag, "language", &value, NULL);
773 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
775 temp_tags = temp_tags->next;
780 while (temp_tags && !val_set)
782 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
784 g_object_get (tag, "weight-set", &val_set, NULL);
790 g_object_get (tag, "weight", &weight, NULL);
791 value = g_strdup_printf ("%d", weight);
792 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
794 temp_tags = temp_tags->next;
798 /* scale is special as the effective value is the product
799 * of all specified values
804 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
807 g_object_get (tag, "scale-set", &scale_set, NULL);
811 g_object_get (tag, "scale", &font_scale, NULL);
815 temp_tags = temp_tags->next;
820 value = g_strdup_printf ("%g", scale);
821 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
826 while (temp_tags && !val_set)
828 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
830 g_object_get (tag, "size-set", &val_set, NULL);
835 g_object_get (tag, "size", &size, NULL);
836 value = g_strdup_printf ("%i", size);
837 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
839 temp_tags = temp_tags->next;
844 while (temp_tags && !val_set)
846 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
848 g_object_get (tag, "strikethrough-set", &val_set, NULL);
851 gboolean strikethrough;
852 g_object_get (tag, "strikethrough", &strikethrough, NULL);
853 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough);
855 temp_tags = temp_tags->next;
860 while (temp_tags && !val_set)
862 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
864 g_object_get (tag, "underline-set", &val_set, NULL);
867 PangoUnderline underline;
868 g_object_get (tag, "underline", &underline, NULL);
869 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, underline);
871 temp_tags = temp_tags->next;
876 while (temp_tags && !val_set)
878 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
880 g_object_get (tag, "rise-set", &val_set, NULL);
885 g_object_get (tag, "rise", &rise, NULL);
886 value = g_strdup_printf ("%i", rise);
887 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
889 temp_tags = temp_tags->next;
894 while (temp_tags && !val_set)
896 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
898 g_object_get (tag, "background-full-height-set", &val_set, NULL);
901 gboolean bg_full_height;
902 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
903 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height);
905 temp_tags = temp_tags->next;
910 while (temp_tags && !val_set)
912 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
914 g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
919 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
920 value = g_strdup_printf ("%i", pixels);
921 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
923 temp_tags = temp_tags->next;
928 while (temp_tags && !val_set)
930 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
932 g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
937 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
938 value = g_strdup_printf ("%i", pixels);
939 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
941 temp_tags = temp_tags->next;
946 while (temp_tags && !val_set)
948 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
950 g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
955 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
956 value = g_strdup_printf ("%i", pixels);
957 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
959 temp_tags = temp_tags->next;
964 while (temp_tags && !val_set)
966 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
968 g_object_get (tag, "editable-set", &val_set, NULL);
972 g_object_get (tag, "editable", &editable, NULL);
973 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, editable);
975 temp_tags = temp_tags->next;
980 while (temp_tags && !val_set)
982 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
984 g_object_get (tag, "invisible-set", &val_set, NULL);
988 g_object_get (tag, "invisible", &invisible, NULL);
989 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, invisible);
991 temp_tags = temp_tags->next;
996 while (temp_tags && !val_set)
998 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1000 g_object_get (tag, "indent-set", &val_set, NULL);
1005 g_object_get (tag, "indent", &indent, NULL);
1006 value = g_strdup_printf ("%i", indent);
1007 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
1009 temp_tags = temp_tags->next;
1014 while (temp_tags && !val_set)
1016 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1018 g_object_get (tag, "right-margin-set", &val_set, NULL);
1023 g_object_get (tag, "right-margin", &margin, NULL);
1024 value = g_strdup_printf ("%i", margin);
1025 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1027 temp_tags = temp_tags->next;
1032 while (temp_tags && !val_set)
1034 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1036 g_object_get (tag, "left-margin-set", &val_set, NULL);
1041 g_object_get (tag, "left-margin", &margin, NULL);
1042 value = g_strdup_printf ("%i", margin);
1043 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1045 temp_tags = temp_tags->next;
1049 g_slist_free (tags);
1053 static AtkAttributeSet *
1054 gtk_text_view_accessible_get_default_attributes (AtkText *text)
1058 GtkTextAttributes *text_attrs;
1059 AtkAttributeSet *attributes;
1060 PangoFontDescription *font;
1063 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1067 view = GTK_TEXT_VIEW (widget);
1068 text_attrs = gtk_text_view_get_default_attributes (view);
1072 font = text_attrs->font;
1076 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STYLE,
1077 pango_font_description_get_style (font));
1079 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_VARIANT,
1080 pango_font_description_get_variant (font));
1082 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRETCH,
1083 pango_font_description_get_stretch (font));
1085 value = g_strdup (pango_font_description_get_family (font));
1086 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FAMILY_NAME, value);
1088 value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
1089 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_WEIGHT, value);
1091 value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
1092 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SIZE, value);
1095 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
1096 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
1097 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
1098 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
1099 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
1100 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
1102 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRIKETHROUGH,
1103 text_attrs->appearance.strikethrough);
1104 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_UNDERLINE,
1105 text_attrs->appearance.underline);
1107 value = g_strdup_printf ("%u,%u,%u",
1108 text_attrs->appearance.bg_color.red,
1109 text_attrs->appearance.bg_color.green,
1110 text_attrs->appearance.bg_color.blue);
1111 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_BG_COLOR, value);
1113 value = g_strdup_printf ("%u,%u,%u",
1114 text_attrs->appearance.fg_color.red,
1115 text_attrs->appearance.fg_color.green,
1116 text_attrs->appearance.fg_color.blue);
1117 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FG_COLOR, value);
1119 value = g_strdup_printf ("%g", text_attrs->font_scale);
1120 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SCALE, value);
1122 value = g_strdup ((gchar *)(text_attrs->language));
1123 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LANGUAGE, value);
1125 value = g_strdup_printf ("%i", text_attrs->appearance.rise);
1126 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RISE, value);
1128 value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
1129 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1131 value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
1132 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1134 value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
1135 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1137 value = g_strdup_printf ("%i", text_attrs->indent);
1138 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_INDENT, value);
1140 value = g_strdup_printf ("%i", text_attrs->left_margin);
1141 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1143 value = g_strdup_printf ("%i", text_attrs->right_margin);
1144 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1146 gtk_text_attributes_unref (text_attrs);
1151 gtk_text_view_accessible_get_n_selections (AtkText *text)
1154 GtkTextBuffer *buffer;
1156 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1160 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1161 if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1168 gtk_text_view_accessible_get_selection (AtkText *atk_text,
1175 GtkTextBuffer *buffer;
1176 GtkTextIter start, end;
1179 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
1183 if (selection_num != 0)
1186 view = GTK_TEXT_VIEW (widget);
1187 buffer = gtk_text_view_get_buffer (view);
1189 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1190 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1194 *start_pos = gtk_text_iter_get_offset (&start);
1195 *end_pos = gtk_text_iter_get_offset (&end);
1201 gtk_text_view_accessible_add_selection (AtkText *text,
1206 GtkTextBuffer *buffer;
1207 GtkTextIter start, end;
1209 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1213 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1215 if (!gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1217 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1218 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1219 gtk_text_buffer_select_range (buffer, &end, &start);
1228 gtk_text_view_accessible_remove_selection (AtkText *text,
1232 GtkTextBuffer *buffer;
1233 GtkTextMark *insert;
1235 GtkTextIter start, end;
1237 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1241 if (selection_num != 0)
1244 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1246 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1248 insert = gtk_text_buffer_get_insert (buffer);
1249 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
1250 gtk_text_buffer_place_cursor (buffer, &iter);
1258 gtk_text_view_accessible_set_selection (AtkText *text,
1264 GtkTextBuffer *buffer;
1265 GtkTextIter start, end;
1267 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1271 if (selection_num != 0)
1274 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1276 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1278 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1279 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1280 gtk_text_buffer_select_range (buffer, &end, &start);
1289 atk_text_interface_init (AtkTextIface *iface)
1291 iface->get_text = gtk_text_view_accessible_get_text;
1292 iface->get_text_after_offset = gtk_text_view_accessible_get_text_after_offset;
1293 iface->get_text_at_offset = gtk_text_view_accessible_get_text_at_offset;
1294 iface->get_text_before_offset = gtk_text_view_accessible_get_text_before_offset;
1295 iface->get_character_at_offset = gtk_text_view_accessible_get_character_at_offset;
1296 iface->get_character_count = gtk_text_view_accessible_get_character_count;
1297 iface->get_caret_offset = gtk_text_view_accessible_get_caret_offset;
1298 iface->set_caret_offset = gtk_text_view_accessible_set_caret_offset;
1299 iface->get_offset_at_point = gtk_text_view_accessible_get_offset_at_point;
1300 iface->get_character_extents = gtk_text_view_accessible_get_character_extents;
1301 iface->get_n_selections = gtk_text_view_accessible_get_n_selections;
1302 iface->get_selection = gtk_text_view_accessible_get_selection;
1303 iface->add_selection = gtk_text_view_accessible_add_selection;
1304 iface->remove_selection = gtk_text_view_accessible_remove_selection;
1305 iface->set_selection = gtk_text_view_accessible_set_selection;
1306 iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
1307 iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
1310 /* atkeditabletext.h */
1313 gtk_text_view_accessible_set_run_attributes (AtkEditableText *text,
1314 AtkAttributeSet *attributes,
1319 GtkTextBuffer *buffer;
1329 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1333 view = GTK_TEXT_VIEW (widget);
1334 if (!gtk_text_view_get_editable (view))
1337 buffer = gtk_text_view_get_buffer (view);
1339 if (attributes == NULL)
1342 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1343 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
1345 tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
1347 for (l = attributes; l; l = l->next)
1358 if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
1359 g_object_set (G_OBJECT (tag), "left-margin", atoi (value), NULL);
1361 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
1362 g_object_set (G_OBJECT (tag), "right-margin", atoi (value), NULL);
1364 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
1365 g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
1367 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
1368 g_object_set (G_OBJECT (tag), "pixels-above-lines", atoi (value), NULL);
1370 else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
1371 g_object_set (G_OBJECT (tag), "pixels-below-lines", atoi (value), NULL);
1373 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
1374 g_object_set (G_OBJECT (tag), "pixels-inside-wrap", atoi (value), NULL);
1376 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
1377 g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
1379 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
1380 g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
1382 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
1383 g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
1385 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
1387 g_object_set (G_OBJECT (tag), "bg-full-height",
1388 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
1392 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
1393 g_object_set (G_OBJECT (tag), "language", value, NULL);
1395 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
1396 g_object_set (G_OBJECT (tag), "family", value, NULL);
1398 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
1400 g_object_set (G_OBJECT (tag), "editable",
1401 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1405 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
1407 g_object_set (G_OBJECT (tag), "invisible",
1408 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1412 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_UNDERLINE)))
1414 for (j = 0; j < 3; j++)
1416 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
1418 g_object_set (G_OBJECT (tag), "underline", j, NULL);
1424 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
1426 g_object_set (G_OBJECT (tag), "strikethrough",
1427 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
1431 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
1433 RGB_vals = g_strsplit (value, ",", 3);
1434 color = g_malloc (sizeof (GdkColor));
1435 color->red = atoi (RGB_vals[0]);
1436 color->green = atoi (RGB_vals[1]);
1437 color->blue = atoi (RGB_vals[2]);
1438 g_object_set (G_OBJECT (tag), "background-gdk", color, NULL);
1441 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
1443 RGB_vals = g_strsplit (value, ",", 3);
1444 color = g_malloc (sizeof (GdkColor));
1445 color->red = atoi (RGB_vals[0]);
1446 color->green = atoi (RGB_vals[1]);
1447 color->blue = atoi (RGB_vals[2]);
1448 g_object_set (G_OBJECT (tag), "foreground-gdk", color, NULL);
1451 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
1453 for (j = 0; j < 9; j++)
1455 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
1457 g_object_set (G_OBJECT (tag), "stretch", j, NULL);
1463 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
1465 for (j = 0; j < 4; j++)
1467 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
1469 g_object_set (G_OBJECT (tag), "justification", j, NULL);
1475 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
1477 for (j = 0; j < 3; j++)
1479 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
1481 g_object_set (G_OBJECT (tag), "direction", j, NULL);
1487 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
1489 for (j = 0; j < 2; j++)
1491 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
1493 g_object_set (G_OBJECT (tag), "variant", j, NULL);
1499 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
1501 for (j = 0; j < 3; j++)
1503 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
1505 g_object_set (G_OBJECT (tag), "wrap-mode", j, NULL);
1511 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
1513 for (j = 0; j < 3; j++)
1515 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
1517 g_object_set (G_OBJECT (tag), "style", j, NULL);
1527 gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
1533 gtk_text_view_accessible_set_text_contents (AtkEditableText *text,
1534 const gchar *string)
1538 GtkTextBuffer *buffer;
1540 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1544 view = GTK_TEXT_VIEW (widget);
1545 if (!gtk_text_view_get_editable (view))
1548 buffer = gtk_text_view_get_buffer (view);
1549 gtk_text_buffer_set_text (buffer, string, -1);
1553 gtk_text_view_accessible_insert_text (AtkEditableText *text,
1554 const gchar *string,
1560 GtkTextBuffer *buffer;
1563 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1567 view = GTK_TEXT_VIEW (widget);
1568 if (!gtk_text_view_get_editable (view))
1571 buffer = gtk_text_view_get_buffer (view);
1572 gtk_text_buffer_get_iter_at_offset (buffer, &iter, *position);
1573 gtk_text_buffer_insert (buffer, &iter, string, length);
1577 gtk_text_view_accessible_copy_text (AtkEditableText *text,
1582 GtkTextBuffer *buffer;
1583 GtkTextIter start, end;
1585 GtkClipboard *clipboard;
1587 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1591 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1593 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1594 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1595 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1597 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1598 gtk_clipboard_set_text (clipboard, str, -1);
1602 gtk_text_view_accessible_cut_text (AtkEditableText *text,
1608 GtkTextBuffer *buffer;
1609 GtkTextIter start, end;
1611 GtkClipboard *clipboard;
1613 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1617 view = GTK_TEXT_VIEW (widget);
1618 if (!gtk_text_view_get_editable (view))
1620 buffer = gtk_text_view_get_buffer (view);
1622 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1623 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1624 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1625 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1626 gtk_clipboard_set_text (clipboard, str, -1);
1627 gtk_text_buffer_delete (buffer, &start, &end);
1631 gtk_text_view_accessible_delete_text (AtkEditableText *text,
1637 GtkTextBuffer *buffer;
1638 GtkTextIter start_itr;
1639 GtkTextIter end_itr;
1641 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1645 view = GTK_TEXT_VIEW (widget);
1646 if (!gtk_text_view_get_editable (view))
1648 buffer = gtk_text_view_get_buffer (view);
1650 gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
1651 gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
1652 gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
1657 GtkTextBuffer* buffer;
1662 paste_received (GtkClipboard *clipboard,
1666 PasteData* paste = data;
1667 GtkTextIter pos_itr;
1671 gtk_text_buffer_get_iter_at_offset (paste->buffer, &pos_itr, paste->position);
1672 gtk_text_buffer_insert (paste->buffer, &pos_itr, text, -1);
1675 g_object_unref (paste->buffer);
1679 gtk_text_view_accessible_paste_text (AtkEditableText *text,
1684 GtkTextBuffer *buffer;
1686 GtkClipboard *clipboard;
1688 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1692 view = GTK_TEXT_VIEW (widget);
1693 if (!gtk_text_view_get_editable (view))
1695 buffer = gtk_text_view_get_buffer (view);
1697 paste.buffer = buffer;
1698 paste.position = position;
1700 g_object_ref (paste.buffer);
1701 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1702 gtk_clipboard_request_text (clipboard, paste_received, &paste);
1706 atk_editable_text_interface_init (AtkEditableTextIface *iface)
1708 iface->set_text_contents = gtk_text_view_accessible_set_text_contents;
1709 iface->insert_text = gtk_text_view_accessible_insert_text;
1710 iface->copy_text = gtk_text_view_accessible_copy_text;
1711 iface->cut_text = gtk_text_view_accessible_cut_text;
1712 iface->delete_text = gtk_text_view_accessible_delete_text;
1713 iface->paste_text = gtk_text_view_accessible_paste_text;
1714 iface->set_run_attributes = gtk_text_view_accessible_set_run_attributes;
1720 gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
1721 GtkTextBuffer * buffer)
1723 int prev_insert_offset, prev_selection_bound;
1724 int insert_offset, selection_bound;
1727 prev_insert_offset = accessible->priv->insert_offset;
1728 prev_selection_bound = accessible->priv->selection_bound;
1730 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
1731 insert_offset = gtk_text_iter_get_offset (&iter);
1732 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
1733 selection_bound = gtk_text_iter_get_offset (&iter);
1735 if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
1738 accessible->priv->insert_offset = insert_offset;
1739 accessible->priv->selection_bound = selection_bound;
1741 if (prev_insert_offset != insert_offset)
1742 g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
1744 if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
1745 g_signal_emit_by_name (accessible, "text-selection-changed");
1749 insert_text_cb (GtkTextBuffer *buffer,
1755 GtkTextViewAccessible *accessible = data;
1759 position = gtk_text_iter_get_offset (iter);
1760 length = g_utf8_strlen (text, len);
1762 g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
1764 gtk_text_view_accessible_update_cursor (accessible, buffer);
1768 delete_range_cb (GtkTextBuffer *buffer,
1773 GtkTextViewAccessible *accessible = data;
1774 gint offset, length;
1776 offset = gtk_text_iter_get_offset (start);
1777 length = gtk_text_iter_get_offset (end) - offset;
1779 g_signal_emit_by_name (accessible,
1780 "text-changed::delete",
1784 gtk_text_view_accessible_update_cursor (accessible, buffer);
1788 mark_set_cb (GtkTextBuffer *buffer,
1789 GtkTextIter *location,
1793 GtkTextViewAccessible *accessible = data;
1796 * Only generate the signal for the "insert" mark, which
1797 * represents the cursor.
1799 if (mark == gtk_text_buffer_get_insert (buffer))
1801 gtk_text_view_accessible_update_cursor (accessible, buffer);
1803 else if (mark == gtk_text_buffer_get_selection_bound (buffer))
1805 gtk_text_view_accessible_update_cursor (accessible, buffer);
1810 gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
1813 GtkTextBuffer *buffer;
1814 gint n_mime_types = 0;
1816 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1820 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1824 gboolean advertises_plaintext = FALSE;
1827 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1828 for (i = 0; i < n_mime_types-1; ++i)
1829 if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
1830 advertises_plaintext = TRUE;
1831 if (!advertises_plaintext)
1835 return n_mime_types;
1838 static const gchar *
1839 gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
1843 GtkTextBuffer *buffer;
1845 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1849 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1852 gint n_mime_types = 0;
1855 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1856 if (i < n_mime_types)
1857 return gdk_atom_name (atoms [i]);
1858 else if (i == n_mime_types)
1859 return "text/plain";
1866 gail_streamable_content_get_stream (AtkStreamableContent *streamable,
1867 const gchar *mime_type)
1870 GtkTextBuffer *buffer;
1871 gint i, n_mime_types = 0;
1874 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1878 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1882 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1884 for (i = 0; i < n_mime_types; ++i)
1886 if (!strcmp ("text/plain", mime_type) ||
1887 !strcmp (gdk_atom_name (atoms[i]), mime_type))
1893 GtkTextIter start, end;
1894 GIOChannel *gio = NULL;
1897 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
1898 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
1899 if (!strcmp ("text/plain", mime_type))
1901 cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1902 len = strlen ((const char *) cbuf);
1906 cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
1908 g_snprintf (tname, 20, "streamXXXXXX");
1909 fd = g_mkstemp (tname);
1910 gio = g_io_channel_unix_new (fd);
1911 g_io_channel_set_encoding (gio, NULL, &err);
1913 g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
1915 g_message ("%s", err->message);
1917 g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
1919 g_message ("%s", err->message);
1921 g_io_channel_flush (gio, &err);
1923 g_message ("%s", err->message);
1926 g_message ("<error writing to stream [%s]>", tname);
1929 /* make sure the file is removed on unref of the giochannel */
1942 atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
1944 iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
1945 iface->get_mime_type = gail_streamable_content_get_mime_type;
1946 iface->get_stream = gail_streamable_content_get_stream;
1950 _gtk_text_view_accessible_set_buffer (GtkTextView *textview,
1951 GtkTextBuffer *old_buffer)
1953 GtkTextViewAccessible *accessible;
1955 g_return_if_fail (GTK_IS_TEXT_VIEW (textview));
1956 g_return_if_fail (old_buffer == NULL || GTK_IS_TEXT_BUFFER (old_buffer));
1958 accessible = GTK_TEXT_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (textview)));
1959 if (accessible == NULL)
1962 gtk_text_view_accessible_change_buffer (accessible,
1964 gtk_text_view_get_buffer (textview));