1 /* GAIL - The GNOME Accessibility Implementation Library
2 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include <sys/types.h>
30 #include <glib-object.h>
31 #include <glib/gstdio.h>
33 #include "gtktextviewaccessible.h"
34 #include "gtk/gtkwidgetprivate.h"
37 static void insert_text_cb (GtkTextBuffer *buffer,
42 static void delete_range_cb (GtkTextBuffer *buffer,
46 static void mark_set_cb (GtkTextBuffer *buffer,
52 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
53 static void atk_text_interface_init (AtkTextIface *iface);
54 static void atk_streamable_content_interface_init (AtkStreamableContentIface *iface);
56 G_DEFINE_TYPE_WITH_CODE (GtkTextViewAccessible, _gtk_text_view_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
57 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
58 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
59 G_IMPLEMENT_INTERFACE (ATK_TYPE_STREAMABLE_CONTENT, atk_streamable_content_interface_init))
63 gtk_text_view_accessible_initialize (AtkObject *obj,
66 ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->initialize (obj, data);
68 obj->role = ATK_ROLE_TEXT;
72 gtk_text_view_accessible_notify_gtk (GObject *obj,
77 atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj));
79 if (!strcmp (pspec->name, "editable"))
83 editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (obj));
84 atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, editable);
87 GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_text_view_accessible_parent_class)->notify_gtk (obj, pspec);
91 gtk_text_view_accessible_ref_state_set (AtkObject *accessible)
93 AtkStateSet *state_set;
96 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
100 state_set = ATK_OBJECT_CLASS (_gtk_text_view_accessible_parent_class)->ref_state_set (accessible);
102 if (gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)))
103 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
104 atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE);
110 gtk_text_view_accessible_change_buffer (GtkTextViewAccessible *accessible,
111 GtkTextBuffer *old_buffer,
112 GtkTextBuffer *new_buffer)
116 g_signal_handlers_disconnect_matched (old_buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, accessible);
121 g_signal_connect_after (new_buffer, "insert-text", G_CALLBACK (insert_text_cb), accessible);
122 g_signal_connect (new_buffer, "delete-range", G_CALLBACK (delete_range_cb), accessible);
123 g_signal_connect_after (new_buffer, "mark-set", G_CALLBACK (mark_set_cb), accessible);
128 gtk_text_view_accessible_widget_set (GtkAccessible *accessible)
130 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
132 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))));
136 gtk_text_view_accessible_widget_unset (GtkAccessible *accessible)
138 gtk_text_view_accessible_change_buffer (GTK_TEXT_VIEW_ACCESSIBLE (accessible),
139 gtk_text_view_get_buffer (GTK_TEXT_VIEW (gtk_accessible_get_widget (accessible))),
144 _gtk_text_view_accessible_class_init (GtkTextViewAccessibleClass *klass)
146 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
147 GtkAccessibleClass *accessible_class = GTK_ACCESSIBLE_CLASS (klass);
148 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
150 accessible_class->widget_set = gtk_text_view_accessible_widget_set;
151 accessible_class->widget_unset = gtk_text_view_accessible_widget_unset;
153 class->ref_state_set = gtk_text_view_accessible_ref_state_set;
154 class->initialize = gtk_text_view_accessible_initialize;
156 widget_class->notify_gtk = gtk_text_view_accessible_notify_gtk;
160 _gtk_text_view_accessible_init (GtkTextViewAccessible *accessible)
165 gtk_text_view_accessible_get_text (AtkText *text,
170 GtkTextBuffer *buffer;
171 GtkTextIter start, end;
174 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
178 view = GTK_TEXT_VIEW (widget);
179 buffer = gtk_text_view_get_buffer (view);
180 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
181 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
183 return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
187 gtk_text_view_accessible_get_text_after_offset (AtkText *text,
189 AtkTextBoundary boundary_type,
195 GtkTextBuffer *buffer;
197 GtkTextIter start, end;
199 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
203 view = GTK_TEXT_VIEW (widget);
204 buffer = gtk_text_view_get_buffer (view);
205 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
207 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
209 gtk_text_view_forward_display_line (view, &end);
211 gtk_text_view_forward_display_line (view, &end);
213 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
215 gtk_text_view_forward_display_line_end (view, &end);
217 gtk_text_view_forward_display_line (view, &end);
218 gtk_text_view_forward_display_line_end (view, &end);
221 _gtk_text_buffer_get_text_after (buffer, boundary_type, &pos, &start, &end);
223 *start_offset = gtk_text_iter_get_offset (&start);
224 *end_offset = gtk_text_iter_get_offset (&end);
226 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
230 gtk_text_view_accessible_get_text_at_offset (AtkText *text,
232 AtkTextBoundary boundary_type,
238 GtkTextBuffer *buffer;
240 GtkTextIter start, end;
242 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
246 view = GTK_TEXT_VIEW (widget);
247 buffer = gtk_text_view_get_buffer (view);
248 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
250 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
252 gtk_text_view_backward_display_line_start (view, &start);
253 gtk_text_view_forward_display_line (view, &end);
255 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
257 gtk_text_view_backward_display_line_start (view, &start);
258 if (!gtk_text_iter_is_start (&start))
260 gtk_text_view_backward_display_line (view, &start);
261 gtk_text_view_forward_display_line_end (view, &start);
263 gtk_text_view_forward_display_line_end (view, &end);
266 _gtk_text_buffer_get_text_at (buffer, boundary_type, &pos, &start, &end);
268 *start_offset = gtk_text_iter_get_offset (&start);
269 *end_offset = gtk_text_iter_get_offset (&end);
271 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
275 gtk_text_view_accessible_get_text_before_offset (AtkText *text,
277 AtkTextBoundary boundary_type,
283 GtkTextBuffer *buffer;
285 GtkTextIter start, end;
287 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
291 view = GTK_TEXT_VIEW (widget);
292 buffer = gtk_text_view_get_buffer (view);
293 gtk_text_buffer_get_iter_at_offset (buffer, &pos, offset);
296 if (boundary_type == ATK_TEXT_BOUNDARY_LINE_START)
298 gtk_text_view_backward_display_line_start (view, &start);
300 gtk_text_view_backward_display_line (view, &start);
301 gtk_text_view_backward_display_line_start (view, &start);
303 else if (boundary_type == ATK_TEXT_BOUNDARY_LINE_END)
305 gtk_text_view_backward_display_line_start (view, &start);
306 if (!gtk_text_iter_is_start (&start))
308 gtk_text_view_backward_display_line (view, &start);
310 gtk_text_view_forward_display_line_end (view, &end);
311 if (!gtk_text_iter_is_start (&start))
313 if (gtk_text_view_backward_display_line (view, &start))
314 gtk_text_view_forward_display_line_end (view, &start);
316 gtk_text_iter_set_offset (&start, 0);
323 _gtk_text_buffer_get_text_before (buffer, boundary_type, &pos, &start, &end);
325 *start_offset = gtk_text_iter_get_offset (&start);
326 *end_offset = gtk_text_iter_get_offset (&end);
328 return gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
332 gtk_text_view_accessible_get_character_at_offset (AtkText *text,
336 GtkTextIter start, end;
337 GtkTextBuffer *buffer;
341 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
345 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
346 if (offset >= gtk_text_buffer_get_char_count (buffer))
349 gtk_text_buffer_get_iter_at_offset (buffer, &start, offset);
351 gtk_text_iter_forward_char (&end);
352 string = gtk_text_buffer_get_slice (buffer, &start, &end, FALSE);
353 unichar = g_utf8_get_char (string);
360 gtk_text_view_accessible_get_character_count (AtkText *text)
363 GtkTextBuffer *buffer;
365 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
369 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
370 return gtk_text_buffer_get_char_count (buffer);
374 get_insert_offset (GtkTextBuffer *buffer)
379 insert = gtk_text_buffer_get_insert (buffer);
380 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
381 return gtk_text_iter_get_offset (&iter);
385 gtk_text_view_accessible_get_caret_offset (AtkText *text)
388 GtkTextBuffer *buffer;
390 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
394 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
395 return get_insert_offset (buffer);
399 gtk_text_view_accessible_set_caret_offset (AtkText *text,
404 GtkTextBuffer *buffer;
407 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
411 view = GTK_TEXT_VIEW (widget);
412 buffer = gtk_text_view_get_buffer (view);
414 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
415 gtk_text_buffer_place_cursor (buffer, &iter);
416 gtk_text_view_scroll_to_iter (view, &iter, 0, FALSE, 0, 0);
422 gtk_text_view_accessible_get_offset_at_point (AtkText *text,
429 gint x_widget, y_widget, x_window, y_window, buff_x, buff_y;
434 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
438 view = GTK_TEXT_VIEW (widget);
439 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
440 gdk_window_get_origin (window, &x_widget, &y_widget);
442 if (coords == ATK_XY_SCREEN)
447 else if (coords == ATK_XY_WINDOW)
449 window = gdk_window_get_toplevel (window);
450 gdk_window_get_origin (window, &x_window, &y_window);
452 x = x - x_widget + x_window;
453 y = y - y_widget + y_window;
458 gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_WIDGET,
459 x, y, &buff_x, &buff_y);
460 gtk_text_view_get_visible_rect (view, &rect);
462 /* Clamp point to visible rectangle */
463 buff_x = CLAMP (buff_x, rect.x, rect.x + rect.width - 1);
464 buff_y = CLAMP (buff_y, rect.y, rect.y + rect.height - 1);
466 gtk_text_view_get_iter_at_location (view, &iter, buff_x, buff_y);
468 /* The iter at a location sometimes points to the next character.
469 * See bug 111031. We work around that
471 gtk_text_view_get_iter_location (view, &iter, &rect);
473 gtk_text_iter_backward_char (&iter);
474 return gtk_text_iter_get_offset (&iter);
478 gtk_text_view_accessible_get_character_extents (AtkText *text,
487 GtkTextBuffer *buffer;
490 GdkRectangle rectangle;
492 gint x_widget, y_widget, x_window, y_window;
494 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
498 view = GTK_TEXT_VIEW (widget);
499 buffer = gtk_text_view_get_buffer (view);
500 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
501 gtk_text_view_get_iter_location (view, &iter, &rectangle);
503 window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_WIDGET);
504 gdk_window_get_origin (window, &x_widget, &y_widget);
506 *height = rectangle.height;
507 *width = rectangle.width;
509 gtk_text_view_buffer_to_window_coords (view, GTK_TEXT_WINDOW_WIDGET,
510 rectangle.x, rectangle.y, x, y);
511 if (coords == ATK_XY_WINDOW)
513 window = gdk_window_get_toplevel (window);
514 gdk_window_get_origin (window, &x_window, &y_window);
515 *x += x_widget - x_window;
516 *y += y_widget - y_window;
518 else if (coords == ATK_XY_SCREEN)
532 static AtkAttributeSet *
533 add_text_attribute (AtkAttributeSet *attributes,
534 AtkTextAttribute attr,
539 at = g_new (AtkAttribute, 1);
540 at->name = g_strdup (atk_text_attribute_get_name (attr));
543 return g_slist_prepend (attributes, at);
546 static AtkAttributeSet *
547 add_text_int_attribute (AtkAttributeSet *attributes,
548 AtkTextAttribute attr,
554 value = g_strdup (atk_text_attribute_get_value (attr, i));
556 return add_text_attribute (attributes, attr, value);
559 static AtkAttributeSet *
560 gtk_text_view_accessible_get_run_attributes (AtkText *text,
566 GtkTextBuffer *buffer;
569 AtkAttributeSet *attrib_set = NULL;
570 GSList *tags, *temp_tags;
572 gboolean val_set = FALSE;
575 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
579 view = GTK_TEXT_VIEW (widget);
580 buffer = gtk_text_view_get_buffer (view);
582 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
584 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
585 *end_offset = gtk_text_iter_get_offset (&iter);
587 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
588 *start_offset = gtk_text_iter_get_offset (&iter);
590 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
592 tags = gtk_text_iter_get_tags (&iter);
593 tags = g_slist_reverse (tags);
596 while (temp_tags && !val_set)
598 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
600 g_object_get (tag, "style-set", &val_set, NULL);
604 g_object_get (tag, "style", &style, NULL);
605 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, style);
607 temp_tags = temp_tags->next;
612 while (temp_tags && !val_set)
614 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
616 g_object_get (tag, "variant-set", &val_set, NULL);
619 PangoVariant variant;
620 g_object_get (tag, "variant", &variant, NULL);
621 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, variant);
623 temp_tags = temp_tags->next;
628 while (temp_tags && !val_set)
630 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
632 g_object_get (tag, "stretch-set", &val_set, NULL);
635 PangoStretch stretch;
636 g_object_get (tag, "stretch", &stretch, NULL);
637 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, stretch);
639 temp_tags = temp_tags->next;
644 while (temp_tags && !val_set)
646 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
648 g_object_get (tag, "justification-set", &val_set, NULL);
651 GtkJustification justification;
652 g_object_get (tag, "justification", &justification, NULL);
653 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, justification);
655 temp_tags = temp_tags->next;
660 while (temp_tags && !val_set)
662 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
663 GtkTextDirection direction;
665 g_object_get (tag, "direction", &direction, NULL);
667 if (direction != GTK_TEXT_DIR_NONE)
670 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, direction);
672 temp_tags = temp_tags->next;
677 while (temp_tags && !val_set)
679 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
681 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
684 GtkWrapMode wrap_mode;
685 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
686 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, wrap_mode);
688 temp_tags = temp_tags->next;
693 while (temp_tags && !val_set)
695 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
697 g_object_get (tag, "foreground-set", &val_set, NULL);
703 g_object_get (tag, "foreground-rgba", &rgba, NULL);
704 value = g_strdup_printf ("%u,%u,%u",
705 (guint) rgba->red * 65535,
706 (guint) rgba->green * 65535,
707 (guint) rgba->blue * 65535);
708 gdk_rgba_free (rgba);
709 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
711 temp_tags = temp_tags->next;
716 while (temp_tags && !val_set)
718 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
720 g_object_get (tag, "background-set", &val_set, NULL);
726 g_object_get (tag, "background-rgba", &rgba, NULL);
727 value = g_strdup_printf ("%u,%u,%u",
728 (guint) rgba->red * 65535,
729 (guint) rgba->green * 65535,
730 (guint) rgba->blue * 65535);
731 gdk_rgba_free (rgba);
732 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
734 temp_tags = temp_tags->next;
739 while (temp_tags && !val_set)
741 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
743 g_object_get (tag, "family-set", &val_set, NULL);
748 g_object_get (tag, "family", &value, NULL);
749 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
751 temp_tags = temp_tags->next;
756 while (temp_tags && !val_set)
758 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
760 g_object_get (tag, "language-set", &val_set, NULL);
765 g_object_get (tag, "language", &value, NULL);
766 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
768 temp_tags = temp_tags->next;
773 while (temp_tags && !val_set)
775 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
777 g_object_get (tag, "weight-set", &val_set, NULL);
783 g_object_get (tag, "weight", &weight, NULL);
784 value = g_strdup_printf ("%d", weight);
785 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
787 temp_tags = temp_tags->next;
791 /* scale is special as the effective value is the product
792 * of all specified values
797 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
800 g_object_get (tag, "scale-set", &scale_set, NULL);
804 g_object_get (tag, "scale", &font_scale, NULL);
808 temp_tags = temp_tags->next;
813 value = g_strdup_printf ("%g", scale);
814 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SCALE, value);
819 while (temp_tags && !val_set)
821 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
823 g_object_get (tag, "size-set", &val_set, NULL);
828 g_object_get (tag, "size", &size, NULL);
829 value = g_strdup_printf ("%i", size);
830 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
832 temp_tags = temp_tags->next;
837 while (temp_tags && !val_set)
839 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
841 g_object_get (tag, "strikethrough-set", &val_set, NULL);
844 gboolean strikethrough;
845 g_object_get (tag, "strikethrough", &strikethrough, NULL);
846 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough);
848 temp_tags = temp_tags->next;
853 while (temp_tags && !val_set)
855 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
857 g_object_get (tag, "underline-set", &val_set, NULL);
860 PangoUnderline underline;
861 g_object_get (tag, "underline", &underline, NULL);
862 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, underline);
864 temp_tags = temp_tags->next;
869 while (temp_tags && !val_set)
871 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
873 g_object_get (tag, "rise-set", &val_set, NULL);
878 g_object_get (tag, "rise", &rise, NULL);
879 value = g_strdup_printf ("%i", rise);
880 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
882 temp_tags = temp_tags->next;
887 while (temp_tags && !val_set)
889 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
891 g_object_get (tag, "background-full-height-set", &val_set, NULL);
894 gboolean bg_full_height;
895 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
896 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height);
898 temp_tags = temp_tags->next;
903 while (temp_tags && !val_set)
905 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
907 g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
912 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
913 value = g_strdup_printf ("%i", pixels);
914 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
916 temp_tags = temp_tags->next;
921 while (temp_tags && !val_set)
923 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
925 g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
930 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
931 value = g_strdup_printf ("%i", pixels);
932 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
934 temp_tags = temp_tags->next;
939 while (temp_tags && !val_set)
941 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
943 g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
948 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
949 value = g_strdup_printf ("%i", pixels);
950 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
952 temp_tags = temp_tags->next;
957 while (temp_tags && !val_set)
959 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
961 g_object_get (tag, "editable-set", &val_set, NULL);
965 g_object_get (tag, "editable", &editable, NULL);
966 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, editable);
968 temp_tags = temp_tags->next;
973 while (temp_tags && !val_set)
975 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
977 g_object_get (tag, "invisible-set", &val_set, NULL);
981 g_object_get (tag, "invisible", &invisible, NULL);
982 attrib_set = add_text_int_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, invisible);
984 temp_tags = temp_tags->next;
989 while (temp_tags && !val_set)
991 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
993 g_object_get (tag, "indent-set", &val_set, NULL);
998 g_object_get (tag, "indent", &indent, NULL);
999 value = g_strdup_printf ("%i", indent);
1000 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
1002 temp_tags = temp_tags->next;
1007 while (temp_tags && !val_set)
1009 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1011 g_object_get (tag, "right-margin-set", &val_set, NULL);
1016 g_object_get (tag, "right-margin", &margin, NULL);
1017 value = g_strdup_printf ("%i", margin);
1018 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1020 temp_tags = temp_tags->next;
1025 while (temp_tags && !val_set)
1027 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1029 g_object_get (tag, "left-margin-set", &val_set, NULL);
1034 g_object_get (tag, "left-margin", &margin, NULL);
1035 value = g_strdup_printf ("%i", margin);
1036 attrib_set = add_text_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1038 temp_tags = temp_tags->next;
1042 g_slist_free (tags);
1046 static AtkAttributeSet *
1047 gtk_text_view_accessible_get_default_attributes (AtkText *text)
1051 GtkTextAttributes *text_attrs;
1052 AtkAttributeSet *attributes;
1053 PangoFontDescription *font;
1056 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1060 view = GTK_TEXT_VIEW (widget);
1061 text_attrs = gtk_text_view_get_default_attributes (view);
1065 font = text_attrs->font;
1069 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STYLE,
1070 pango_font_description_get_style (font));
1072 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_VARIANT,
1073 pango_font_description_get_variant (font));
1075 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRETCH,
1076 pango_font_description_get_stretch (font));
1078 value = g_strdup (pango_font_description_get_family (font));
1079 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FAMILY_NAME, value);
1081 value = g_strdup_printf ("%d", pango_font_description_get_weight (font));
1082 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_WEIGHT, value);
1084 value = g_strdup_printf ("%i", pango_font_description_get_size (font) / PANGO_SCALE);
1085 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SIZE, value);
1088 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_JUSTIFICATION, text_attrs->justification);
1089 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, text_attrs->direction);
1090 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_WRAP_MODE, text_attrs->wrap_mode);
1091 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_EDITABLE, text_attrs->editable);
1092 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_INVISIBLE, text_attrs->invisible);
1093 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_BG_FULL_HEIGHT, text_attrs->bg_full_height);
1095 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_STRIKETHROUGH,
1096 text_attrs->appearance.strikethrough);
1097 attributes = add_text_int_attribute (attributes, ATK_TEXT_ATTR_UNDERLINE,
1098 text_attrs->appearance.underline);
1100 value = g_strdup_printf ("%u,%u,%u",
1101 text_attrs->appearance.bg_color.red,
1102 text_attrs->appearance.bg_color.green,
1103 text_attrs->appearance.bg_color.blue);
1104 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_BG_COLOR, value);
1106 value = g_strdup_printf ("%u,%u,%u",
1107 text_attrs->appearance.fg_color.red,
1108 text_attrs->appearance.fg_color.green,
1109 text_attrs->appearance.fg_color.blue);
1110 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_FG_COLOR, value);
1112 value = g_strdup_printf ("%g", text_attrs->font_scale);
1113 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_SCALE, value);
1115 value = g_strdup ((gchar *)(text_attrs->language));
1116 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LANGUAGE, value);
1118 value = g_strdup_printf ("%i", text_attrs->appearance.rise);
1119 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RISE, value);
1121 value = g_strdup_printf ("%i", text_attrs->pixels_inside_wrap);
1122 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1124 value = g_strdup_printf ("%i", text_attrs->pixels_below_lines);
1125 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1127 value = g_strdup_printf ("%i", text_attrs->pixels_above_lines);
1128 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1130 value = g_strdup_printf ("%i", text_attrs->indent);
1131 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_INDENT, value);
1133 value = g_strdup_printf ("%i", text_attrs->left_margin);
1134 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1136 value = g_strdup_printf ("%i", text_attrs->right_margin);
1137 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1139 gtk_text_attributes_unref (text_attrs);
1144 gtk_text_view_accessible_get_n_selections (AtkText *text)
1147 GtkTextBuffer *buffer;
1149 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1153 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1154 if (gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1161 gtk_text_view_accessible_get_selection (AtkText *atk_text,
1168 GtkTextBuffer *buffer;
1169 GtkTextIter start, end;
1172 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
1176 if (selection_num != 0)
1179 view = GTK_TEXT_VIEW (widget);
1180 buffer = gtk_text_view_get_buffer (view);
1182 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1183 text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1187 *start_pos = gtk_text_iter_get_offset (&start);
1188 *end_pos = gtk_text_iter_get_offset (&end);
1194 gtk_text_view_accessible_add_selection (AtkText *text,
1199 GtkTextBuffer *buffer;
1200 GtkTextIter start, end;
1202 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1206 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1208 if (!gtk_text_buffer_get_selection_bounds (buffer, NULL, NULL))
1210 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1211 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1212 gtk_text_buffer_select_range (buffer, &end, &start);
1221 gtk_text_view_accessible_remove_selection (AtkText *text,
1225 GtkTextBuffer *buffer;
1226 GtkTextMark *insert;
1228 GtkTextIter start, end;
1230 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1234 if (selection_num != 0)
1237 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1239 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1241 insert = gtk_text_buffer_get_insert (buffer);
1242 gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
1243 gtk_text_buffer_place_cursor (buffer, &iter);
1251 gtk_text_view_accessible_set_selection (AtkText *text,
1257 GtkTextBuffer *buffer;
1258 GtkTextIter start, end;
1260 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1264 if (selection_num != 0)
1267 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1269 if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
1271 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1272 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1273 gtk_text_buffer_select_range (buffer, &end, &start);
1282 atk_text_interface_init (AtkTextIface *iface)
1284 iface->get_text = gtk_text_view_accessible_get_text;
1285 iface->get_text_after_offset = gtk_text_view_accessible_get_text_after_offset;
1286 iface->get_text_at_offset = gtk_text_view_accessible_get_text_at_offset;
1287 iface->get_text_before_offset = gtk_text_view_accessible_get_text_before_offset;
1288 iface->get_character_at_offset = gtk_text_view_accessible_get_character_at_offset;
1289 iface->get_character_count = gtk_text_view_accessible_get_character_count;
1290 iface->get_caret_offset = gtk_text_view_accessible_get_caret_offset;
1291 iface->set_caret_offset = gtk_text_view_accessible_set_caret_offset;
1292 iface->get_offset_at_point = gtk_text_view_accessible_get_offset_at_point;
1293 iface->get_character_extents = gtk_text_view_accessible_get_character_extents;
1294 iface->get_n_selections = gtk_text_view_accessible_get_n_selections;
1295 iface->get_selection = gtk_text_view_accessible_get_selection;
1296 iface->add_selection = gtk_text_view_accessible_add_selection;
1297 iface->remove_selection = gtk_text_view_accessible_remove_selection;
1298 iface->set_selection = gtk_text_view_accessible_set_selection;
1299 iface->get_run_attributes = gtk_text_view_accessible_get_run_attributes;
1300 iface->get_default_attributes = gtk_text_view_accessible_get_default_attributes;
1303 /* atkeditabletext.h */
1306 gtk_text_view_accessible_set_run_attributes (AtkEditableText *text,
1307 AtkAttributeSet *attributes,
1312 GtkTextBuffer *buffer;
1322 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1326 view = GTK_TEXT_VIEW (widget);
1327 if (!gtk_text_view_get_editable (view))
1330 buffer = gtk_text_view_get_buffer (view);
1332 if (attributes == NULL)
1335 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
1336 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_offset);
1338 tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
1340 for (l = attributes; l; l = l->next)
1351 if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LEFT_MARGIN)))
1352 g_object_set (G_OBJECT (tag), "left-margin", atoi (value), NULL);
1354 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RIGHT_MARGIN)))
1355 g_object_set (G_OBJECT (tag), "right-margin", atoi (value), NULL);
1357 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INDENT)))
1358 g_object_set (G_OBJECT (tag), "indent", atoi (value), NULL);
1360 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_ABOVE_LINES)))
1361 g_object_set (G_OBJECT (tag), "pixels-above-lines", atoi (value), NULL);
1363 else if (!strcmp(name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_BELOW_LINES)))
1364 g_object_set (G_OBJECT (tag), "pixels-below-lines", atoi (value), NULL);
1366 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP)))
1367 g_object_set (G_OBJECT (tag), "pixels-inside-wrap", atoi (value), NULL);
1369 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_SIZE)))
1370 g_object_set (G_OBJECT (tag), "size", atoi (value), NULL);
1372 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_RISE)))
1373 g_object_set (G_OBJECT (tag), "rise", atoi (value), NULL);
1375 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WEIGHT)))
1376 g_object_set (G_OBJECT (tag), "weight", atoi (value), NULL);
1378 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_FULL_HEIGHT)))
1380 g_object_set (G_OBJECT (tag), "bg-full-height",
1381 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, 0))),
1385 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_LANGUAGE)))
1386 g_object_set (G_OBJECT (tag), "language", value, NULL);
1388 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FAMILY_NAME)))
1389 g_object_set (G_OBJECT (tag), "family", value, NULL);
1391 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_EDITABLE)))
1393 g_object_set (G_OBJECT (tag), "editable",
1394 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, 0))),
1398 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_INVISIBLE)))
1400 g_object_set (G_OBJECT (tag), "invisible",
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_UNDERLINE)))
1407 for (j = 0; j < 3; j++)
1409 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, j)))
1411 g_object_set (G_OBJECT (tag), "underline", j, NULL);
1417 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRIKETHROUGH)))
1419 g_object_set (G_OBJECT (tag), "strikethrough",
1420 (strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, 0))),
1424 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_BG_COLOR)))
1426 RGB_vals = g_strsplit (value, ",", 3);
1427 color = g_malloc (sizeof (GdkColor));
1428 color->red = atoi (RGB_vals[0]);
1429 color->green = atoi (RGB_vals[1]);
1430 color->blue = atoi (RGB_vals[2]);
1431 g_object_set (G_OBJECT (tag), "background-gdk", color, NULL);
1434 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_FG_COLOR)))
1436 RGB_vals = g_strsplit (value, ",", 3);
1437 color = g_malloc (sizeof (GdkColor));
1438 color->red = atoi (RGB_vals[0]);
1439 color->green = atoi (RGB_vals[1]);
1440 color->blue = atoi (RGB_vals[2]);
1441 g_object_set (G_OBJECT (tag), "foreground-gdk", color, NULL);
1444 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STRETCH)))
1446 for (j = 0; j < 9; j++)
1448 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, j)))
1450 g_object_set (G_OBJECT (tag), "stretch", j, NULL);
1456 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_JUSTIFICATION)))
1458 for (j = 0; j < 4; j++)
1460 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, j)))
1462 g_object_set (G_OBJECT (tag), "justification", j, NULL);
1468 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_DIRECTION)))
1470 for (j = 0; j < 3; j++)
1472 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, j)))
1474 g_object_set (G_OBJECT (tag), "direction", j, NULL);
1480 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_VARIANT)))
1482 for (j = 0; j < 2; j++)
1484 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, j)))
1486 g_object_set (G_OBJECT (tag), "variant", j, NULL);
1492 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_WRAP_MODE)))
1494 for (j = 0; j < 3; j++)
1496 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, j)))
1498 g_object_set (G_OBJECT (tag), "wrap-mode", j, NULL);
1504 else if (!strcmp (name, atk_text_attribute_get_name (ATK_TEXT_ATTR_STYLE)))
1506 for (j = 0; j < 3; j++)
1508 if (!strcmp (value, atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, j)))
1510 g_object_set (G_OBJECT (tag), "style", j, NULL);
1520 gtk_text_buffer_apply_tag (buffer, tag, &start, &end);
1526 gtk_text_view_accessible_set_text_contents (AtkEditableText *text,
1527 const gchar *string)
1531 GtkTextBuffer *buffer;
1533 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1537 view = GTK_TEXT_VIEW (widget);
1538 if (!gtk_text_view_get_editable (view))
1541 buffer = gtk_text_view_get_buffer (view);
1542 gtk_text_buffer_set_text (buffer, string, -1);
1546 gtk_text_view_accessible_insert_text (AtkEditableText *text,
1547 const gchar *string,
1553 GtkTextBuffer *buffer;
1556 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1560 view = GTK_TEXT_VIEW (widget);
1561 if (!gtk_text_view_get_editable (view))
1564 buffer = gtk_text_view_get_buffer (view);
1565 gtk_text_buffer_get_iter_at_offset (buffer, &iter, *position);
1566 gtk_text_buffer_insert (buffer, &iter, string, length);
1570 gtk_text_view_accessible_copy_text (AtkEditableText *text,
1575 GtkTextBuffer *buffer;
1576 GtkTextIter start, end;
1578 GtkClipboard *clipboard;
1580 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1584 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1586 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1587 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1588 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1590 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1591 gtk_clipboard_set_text (clipboard, str, -1);
1595 gtk_text_view_accessible_cut_text (AtkEditableText *text,
1601 GtkTextBuffer *buffer;
1602 GtkTextIter start, end;
1604 GtkClipboard *clipboard;
1606 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1610 view = GTK_TEXT_VIEW (widget);
1611 if (!gtk_text_view_get_editable (view))
1613 buffer = gtk_text_view_get_buffer (view);
1615 gtk_text_buffer_get_iter_at_offset (buffer, &start, start_pos);
1616 gtk_text_buffer_get_iter_at_offset (buffer, &end, end_pos);
1617 str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1618 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1619 gtk_clipboard_set_text (clipboard, str, -1);
1620 gtk_text_buffer_delete (buffer, &start, &end);
1624 gtk_text_view_accessible_delete_text (AtkEditableText *text,
1630 GtkTextBuffer *buffer;
1631 GtkTextIter start_itr;
1632 GtkTextIter end_itr;
1634 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1638 view = GTK_TEXT_VIEW (widget);
1639 if (!gtk_text_view_get_editable (view))
1641 buffer = gtk_text_view_get_buffer (view);
1643 gtk_text_buffer_get_iter_at_offset (buffer, &start_itr, start_pos);
1644 gtk_text_buffer_get_iter_at_offset (buffer, &end_itr, end_pos);
1645 gtk_text_buffer_delete (buffer, &start_itr, &end_itr);
1650 GtkTextBuffer* buffer;
1655 paste_received (GtkClipboard *clipboard,
1659 PasteData* paste = data;
1660 GtkTextIter pos_itr;
1664 gtk_text_buffer_get_iter_at_offset (paste->buffer, &pos_itr, paste->position);
1665 gtk_text_buffer_insert (paste->buffer, &pos_itr, text, -1);
1668 g_object_unref (paste->buffer);
1672 gtk_text_view_accessible_paste_text (AtkEditableText *text,
1677 GtkTextBuffer *buffer;
1679 GtkClipboard *clipboard;
1681 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
1685 view = GTK_TEXT_VIEW (widget);
1686 if (!gtk_text_view_get_editable (view))
1688 buffer = gtk_text_view_get_buffer (view);
1690 paste.buffer = buffer;
1691 paste.position = position;
1693 g_object_ref (paste.buffer);
1694 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
1695 gtk_clipboard_request_text (clipboard, paste_received, &paste);
1699 atk_editable_text_interface_init (AtkEditableTextIface *iface)
1701 iface->set_text_contents = gtk_text_view_accessible_set_text_contents;
1702 iface->insert_text = gtk_text_view_accessible_insert_text;
1703 iface->copy_text = gtk_text_view_accessible_copy_text;
1704 iface->cut_text = gtk_text_view_accessible_cut_text;
1705 iface->delete_text = gtk_text_view_accessible_delete_text;
1706 iface->paste_text = gtk_text_view_accessible_paste_text;
1707 iface->set_run_attributes = gtk_text_view_accessible_set_run_attributes;
1713 gtk_text_view_accessible_update_cursor (GtkTextViewAccessible *accessible,
1714 GtkTextBuffer * buffer)
1716 int prev_insert_offset, prev_selection_bound;
1717 int insert_offset, selection_bound;
1720 prev_insert_offset = accessible->insert_offset;
1721 prev_selection_bound = accessible->selection_bound;
1723 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
1724 insert_offset = gtk_text_iter_get_offset (&iter);
1725 gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_selection_bound (buffer));
1726 selection_bound = gtk_text_iter_get_offset (&iter);
1728 if (prev_insert_offset == insert_offset && prev_selection_bound == selection_bound)
1731 accessible->insert_offset = insert_offset;
1732 accessible->selection_bound = selection_bound;
1734 if (prev_insert_offset != insert_offset)
1735 g_signal_emit_by_name (accessible, "text-caret-moved", insert_offset);
1737 if (prev_insert_offset != prev_selection_bound || insert_offset != selection_bound)
1738 g_signal_emit_by_name (accessible, "text-selection-changed");
1742 insert_text_cb (GtkTextBuffer *buffer,
1748 GtkTextViewAccessible *accessible = data;
1752 position = gtk_text_iter_get_offset (iter);
1753 length = g_utf8_strlen (text, len);
1755 g_signal_emit_by_name (accessible, "text-changed::insert", position - length, length);
1757 gtk_text_view_accessible_update_cursor (accessible, buffer);
1761 delete_range_cb (GtkTextBuffer *buffer,
1766 GtkTextViewAccessible *accessible = data;
1767 gint offset, length;
1769 offset = gtk_text_iter_get_offset (start);
1770 length = gtk_text_iter_get_offset (end) - offset;
1772 g_signal_emit_by_name (accessible,
1773 "text-changed::delete",
1777 gtk_text_view_accessible_update_cursor (accessible, buffer);
1781 mark_set_cb (GtkTextBuffer *buffer,
1782 GtkTextIter *location,
1786 GtkTextViewAccessible *accessible = data;
1789 * Only generate the signal for the "insert" mark, which
1790 * represents the cursor.
1792 if (mark == gtk_text_buffer_get_insert (buffer))
1794 gtk_text_view_accessible_update_cursor (accessible, buffer);
1796 else if (mark == gtk_text_buffer_get_selection_bound (buffer))
1798 gtk_text_view_accessible_update_cursor (accessible, buffer);
1803 gail_streamable_content_get_n_mime_types (AtkStreamableContent *streamable)
1806 GtkTextBuffer *buffer;
1807 gint n_mime_types = 0;
1809 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1813 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1817 gboolean advertises_plaintext = FALSE;
1820 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1821 for (i = 0; i < n_mime_types-1; ++i)
1822 if (!strcmp ("text/plain", gdk_atom_name (atoms[i])))
1823 advertises_plaintext = TRUE;
1824 if (!advertises_plaintext)
1828 return n_mime_types;
1831 static const gchar *
1832 gail_streamable_content_get_mime_type (AtkStreamableContent *streamable,
1836 GtkTextBuffer *buffer;
1838 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1842 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1845 gint n_mime_types = 0;
1848 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1849 if (i < n_mime_types)
1850 return gdk_atom_name (atoms [i]);
1851 else if (i == n_mime_types)
1852 return "text/plain";
1859 gail_streamable_content_get_stream (AtkStreamableContent *streamable,
1860 const gchar *mime_type)
1863 GtkTextBuffer *buffer;
1864 gint i, n_mime_types = 0;
1867 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (streamable));
1871 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
1875 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_mime_types);
1877 for (i = 0; i < n_mime_types; ++i)
1879 if (!strcmp ("text/plain", mime_type) ||
1880 !strcmp (gdk_atom_name (atoms[i]), mime_type))
1886 GtkTextIter start, end;
1887 GIOChannel *gio = NULL;
1890 gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
1891 gtk_text_buffer_get_iter_at_offset (buffer, &end, -1);
1892 if (!strcmp ("text/plain", mime_type))
1894 cbuf = (guint8*) gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
1895 len = strlen ((const char *) cbuf);
1899 cbuf = gtk_text_buffer_serialize (buffer, buffer, atoms[i], &start, &end, &len);
1901 g_snprintf (tname, 20, "streamXXXXXX");
1902 fd = g_mkstemp (tname);
1903 gio = g_io_channel_unix_new (fd);
1904 g_io_channel_set_encoding (gio, NULL, &err);
1906 g_io_channel_write_chars (gio, (const char *) cbuf, (gssize) len, &written, &err);
1908 g_message ("%s", err->message);
1910 g_io_channel_seek_position (gio, 0, G_SEEK_SET, &err);
1912 g_message ("%s", err->message);
1914 g_io_channel_flush (gio, &err);
1916 g_message ("%s", err->message);
1919 g_message ("<error writing to stream [%s]>", tname);
1922 /* make sure the file is removed on unref of the giochannel */
1935 atk_streamable_content_interface_init (AtkStreamableContentIface *iface)
1937 iface->get_n_mime_types = gail_streamable_content_get_n_mime_types;
1938 iface->get_mime_type = gail_streamable_content_get_mime_type;
1939 iface->get_stream = gail_streamable_content_get_stream;
1943 _gtk_text_view_accessible_set_buffer (GtkTextView *textview,
1944 GtkTextBuffer *old_buffer)
1946 GtkTextViewAccessible *accessible;
1948 g_return_if_fail (GTK_IS_TEXT_VIEW (textview));
1949 g_return_if_fail (old_buffer == NULL || GTK_IS_TEXT_BUFFER (old_buffer));
1951 accessible = GTK_TEXT_VIEW_ACCESSIBLE (_gtk_widget_peek_accessible (GTK_WIDGET (textview)));
1952 if (accessible == NULL)
1955 gtk_text_view_accessible_change_buffer (accessible,
1957 gtk_text_view_get_buffer (textview));