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.
25 #include "gtkentryaccessible.h"
26 #include "gtkcomboboxaccessible.h"
30 static void insert_text_cb (GtkEditable *editable,
34 static void delete_text_cb (GtkEditable *editable,
37 static void changed_cb (GtkEditable *editable);
39 static gboolean check_for_selection_change (GtkEntryAccessible *entry,
43 static void atk_editable_text_interface_init (AtkEditableTextIface *iface);
44 static void atk_text_interface_init (AtkTextIface *iface);
45 static void atk_action_interface_init (AtkActionIface *iface);
48 G_DEFINE_TYPE_WITH_CODE (GtkEntryAccessible, gtk_entry_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
49 G_IMPLEMENT_INTERFACE (ATK_TYPE_EDITABLE_TEXT, atk_editable_text_interface_init)
50 G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init)
51 G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
55 gtk_entry_accessible_finalize (GObject *object)
57 GtkEntryAccessible *entry = GTK_ENTRY_ACCESSIBLE (object);
59 if (entry->action_idle_handler)
61 g_source_remove (entry->action_idle_handler);
62 entry->action_idle_handler = 0;
64 G_OBJECT_CLASS (gtk_entry_accessible_parent_class)->finalize (object);
68 gtk_entry_accessible_ref_state_set (AtkObject *accessible)
70 AtkStateSet *state_set;
74 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
78 state_set = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->ref_state_set (accessible);
80 g_object_get (G_OBJECT (widget), "editable", &value, NULL);
82 atk_state_set_add_state (state_set, ATK_STATE_EDITABLE);
83 atk_state_set_add_state (state_set, ATK_STATE_SINGLE_LINE);
88 static AtkAttributeSet *
89 gtk_entry_accessible_get_attributes (AtkObject *accessible)
92 AtkAttributeSet *attributes;
93 AtkAttribute *placeholder_text;
96 attributes = ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->get_attributes (accessible);
98 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
102 text = gtk_entry_get_placeholder_text (GTK_ENTRY (widget));
106 placeholder_text = g_malloc (sizeof (AtkAttribute));
107 placeholder_text->name = g_strdup ("placeholder-text");
108 placeholder_text->value = g_strdup (text);
110 attributes = g_slist_append (attributes, placeholder_text);
116 gtk_entry_accessible_initialize (AtkObject *obj,
120 GtkEntryAccessible *gtk_entry_accessible;
121 gint start_pos, end_pos;
123 ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->initialize (obj, data);
125 gtk_entry_accessible = GTK_ENTRY_ACCESSIBLE (obj);
127 entry = GTK_ENTRY (data);
128 gtk_editable_get_selection_bounds (GTK_EDITABLE (entry),
129 &start_pos, &end_pos);
130 gtk_entry_accessible->cursor_position = end_pos;
131 gtk_entry_accessible->selection_bound = start_pos;
133 /* Set up signal callbacks */
134 g_signal_connect (entry, "insert-text", G_CALLBACK (insert_text_cb), NULL);
135 g_signal_connect (entry, "delete-text", G_CALLBACK (delete_text_cb), NULL);
136 g_signal_connect (entry, "changed", G_CALLBACK (changed_cb), NULL);
138 if (gtk_entry_get_visibility (entry))
139 obj->role = ATK_ROLE_TEXT;
141 obj->role = ATK_ROLE_PASSWORD_TEXT;
145 gtk_entry_accessible_notify_gtk (GObject *obj,
151 GtkEntryAccessible* entry;
153 widget = GTK_WIDGET (obj);
154 atk_obj = gtk_widget_get_accessible (widget);
155 gtk_entry = GTK_ENTRY (widget);
156 entry = GTK_ENTRY_ACCESSIBLE (atk_obj);
158 if (strcmp (pspec->name, "cursor-position") == 0)
160 if (check_for_selection_change (entry, gtk_entry))
161 g_signal_emit_by_name (atk_obj, "text_selection_changed");
163 * The entry cursor position has moved so generate the signal.
165 g_signal_emit_by_name (atk_obj, "text_caret_moved",
166 entry->cursor_position);
168 else if (strcmp (pspec->name, "selection-bound") == 0)
170 if (check_for_selection_change (entry, gtk_entry))
171 g_signal_emit_by_name (atk_obj, "text_selection_changed");
173 else if (strcmp (pspec->name, "editable") == 0)
177 g_object_get (obj, "editable", &value, NULL);
178 atk_object_notify_state_change (atk_obj, ATK_STATE_EDITABLE, value);
180 else if (strcmp (pspec->name, "visibility") == 0)
185 visibility = gtk_entry_get_visibility (gtk_entry);
186 new_role = visibility ? ATK_ROLE_TEXT : ATK_ROLE_PASSWORD_TEXT;
187 atk_object_set_role (atk_obj, new_role);
190 GTK_WIDGET_ACCESSIBLE_CLASS (gtk_entry_accessible_parent_class)->notify_gtk (obj, pspec);
194 gtk_entry_accessible_get_index_in_parent (AtkObject *accessible)
197 * If the parent widget is a combo box then the index is 1
198 * otherwise do the normal thing.
200 if (accessible->accessible_parent)
201 if (GTK_IS_COMBO_BOX_ACCESSIBLE (accessible->accessible_parent))
204 return ATK_OBJECT_CLASS (gtk_entry_accessible_parent_class)->get_index_in_parent (accessible);
208 gtk_entry_accessible_class_init (GtkEntryAccessibleClass *klass)
210 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
211 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
212 GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
214 gobject_class->finalize = gtk_entry_accessible_finalize;
216 class->ref_state_set = gtk_entry_accessible_ref_state_set;
217 class->get_index_in_parent = gtk_entry_accessible_get_index_in_parent;
218 class->initialize = gtk_entry_accessible_initialize;
219 class->get_attributes = gtk_entry_accessible_get_attributes;
221 widget_class->notify_gtk = gtk_entry_accessible_notify_gtk;
225 gtk_entry_accessible_init (GtkEntryAccessible *entry)
227 entry->length_insert = 0;
228 entry->length_delete = 0;
229 entry->cursor_position = 0;
230 entry->selection_bound = 0;
234 gtk_entry_accessible_get_text (AtkText *atk_text,
241 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
245 /* FIXME: is this acceptable ? */
246 if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
247 return g_strdup ("");
249 text = gtk_entry_get_text (GTK_ENTRY (widget));
252 return g_utf8_substring (text, start_pos, end_pos > -1 ? end_pos : g_utf8_strlen (text, -1));
258 gtk_entry_accessible_get_text_before_offset (AtkText *text,
260 AtkTextBoundary boundary_type,
266 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
270 /* FIXME: is this acceptable ? */
271 if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
272 return g_strdup ("");
274 return _gtk_pango_get_text_before (gtk_entry_get_layout (GTK_ENTRY (widget)),
275 boundary_type, offset,
276 start_offset, end_offset);
280 gtk_entry_accessible_get_text_at_offset (AtkText *text,
282 AtkTextBoundary boundary_type,
288 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
292 /* FIXME: is this acceptable ? */
293 if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
294 return g_strdup ("");
296 return _gtk_pango_get_text_at (gtk_entry_get_layout (GTK_ENTRY (widget)),
297 boundary_type, offset,
298 start_offset, end_offset);
302 gtk_entry_accessible_get_text_after_offset (AtkText *text,
304 AtkTextBoundary boundary_type,
310 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
314 /* FIXME: is this acceptable ? */
315 if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
316 return g_strdup ("");
318 return _gtk_pango_get_text_after (gtk_entry_get_layout (GTK_ENTRY (widget)),
319 boundary_type, offset,
320 start_offset, end_offset);
324 gtk_entry_accessible_get_character_count (AtkText *atk_text)
329 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
333 text = gtk_entry_get_text (GTK_ENTRY (widget));
336 return g_utf8_strlen (text, -1);
342 gtk_entry_accessible_get_caret_offset (AtkText *text)
346 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
350 return gtk_editable_get_position (GTK_EDITABLE (widget));
354 gtk_entry_accessible_set_caret_offset (AtkText *text,
359 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
363 gtk_editable_set_position (GTK_EDITABLE (widget), offset);
368 static AtkAttributeSet *
369 add_text_attribute (AtkAttributeSet *attributes,
370 AtkTextAttribute attr,
375 at = g_new (AtkAttribute, 1);
376 at->name = g_strdup (atk_text_attribute_get_name (attr));
377 at->value = g_strdup (atk_text_attribute_get_value (attr, i));
379 return g_slist_prepend (attributes, at);
382 static AtkAttributeSet *
383 gtk_entry_accessible_get_run_attributes (AtkText *text,
389 AtkAttributeSet *attributes;
391 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
396 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
397 gtk_widget_get_direction (widget));
398 attributes = _gtk_pango_get_run_attributes (attributes,
399 gtk_entry_get_layout (GTK_ENTRY (widget)),
407 static AtkAttributeSet *
408 gtk_entry_accessible_get_default_attributes (AtkText *text)
411 AtkAttributeSet *attributes;
413 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
418 attributes = add_text_attribute (attributes, ATK_TEXT_ATTR_DIRECTION,
419 gtk_widget_get_direction (widget));
420 attributes = _gtk_pango_get_default_attributes (attributes,
421 gtk_entry_get_layout (GTK_ENTRY (widget)));
422 attributes = _gtk_style_context_get_attributes (attributes,
423 gtk_widget_get_style_context (widget),
424 gtk_widget_get_state_flags (widget));
430 gtk_entry_accessible_get_character_extents (AtkText *text,
440 PangoRectangle char_rect;
441 const gchar *entry_text;
442 gint index, x_layout, y_layout;
444 gint x_window, y_window;
446 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
450 entry = GTK_ENTRY (widget);
452 gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
453 entry_text = gtk_entry_get_text (entry);
454 index = g_utf8_offset_to_pointer (entry_text, offset) - entry_text;
455 pango_layout_index_to_pos (gtk_entry_get_layout (entry), index, &char_rect);
456 pango_extents_to_pixels (&char_rect, NULL);
458 window = gtk_widget_get_window (widget);
459 gdk_window_get_origin (window, &x_window, &y_window);
461 *x = x_window + x_layout + char_rect.x;
462 *y = x_window + y_layout + char_rect.y;
463 *width = char_rect.width;
464 *height = char_rect.height;
466 if (coords == ATK_XY_WINDOW)
468 window = gdk_window_get_toplevel (window);
469 gdk_window_get_origin (window, &x_window, &y_window);
477 gtk_entry_accessible_get_offset_at_point (AtkText *atk_text,
485 gint index, x_layout, y_layout;
486 gint x_window, y_window;
487 gint x_local, y_local;
490 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
494 entry = GTK_ENTRY (widget);
496 gtk_entry_get_layout_offsets (entry, &x_layout, &y_layout);
498 window = gtk_widget_get_window (widget);
499 gdk_window_get_origin (window, &x_window, &y_window);
501 x_local = x - x_layout - x_window;
502 y_local = y - y_layout - y_window;
504 if (coords == ATK_XY_WINDOW)
506 window = gdk_window_get_toplevel (window);
507 gdk_window_get_origin (window, &x_window, &y_window);
512 if (!pango_layout_xy_to_index (gtk_entry_get_layout (entry),
513 x_local * PANGO_SCALE,
514 y_local * PANGO_SCALE,
517 if (x_local < 0 || y_local < 0)
525 text = gtk_entry_get_text (entry);
526 return g_utf8_pointer_to_offset (text, text + index);
533 gtk_entry_accessible_get_n_selections (AtkText *text)
538 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
542 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start, &end))
549 gtk_entry_accessible_get_selection (AtkText *text,
556 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
560 if (selection_num != 0)
563 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), start_pos, end_pos))
564 return gtk_editable_get_chars (GTK_EDITABLE (widget), *start_pos, *end_pos);
570 gtk_entry_accessible_add_selection (AtkText *text,
578 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
582 entry = GTK_ENTRY (widget);
584 if (!gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
586 gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
594 gtk_entry_accessible_remove_selection (AtkText *text,
600 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
604 if (selection_num != 0)
607 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start, &end))
609 gtk_editable_select_region (GTK_EDITABLE (widget), end, end);
617 gtk_entry_accessible_set_selection (AtkText *text,
625 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
629 if (selection_num != 0)
632 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), &start, &end))
634 gtk_editable_select_region (GTK_EDITABLE (widget), start_pos, end_pos);
642 gtk_entry_accessible_get_character_at_offset (AtkText *atk_text,
649 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text));
653 if (!gtk_entry_get_visibility (GTK_ENTRY (widget)))
656 text = gtk_entry_get_text (GTK_ENTRY (widget));
657 if (offset >= g_utf8_strlen (text, -1))
660 index = g_utf8_offset_to_pointer (text, offset);
662 return g_utf8_get_char (index);
666 atk_text_interface_init (AtkTextIface *iface)
668 iface->get_text = gtk_entry_accessible_get_text;
669 iface->get_character_at_offset = gtk_entry_accessible_get_character_at_offset;
670 iface->get_text_before_offset = gtk_entry_accessible_get_text_before_offset;
671 iface->get_text_at_offset = gtk_entry_accessible_get_text_at_offset;
672 iface->get_text_after_offset = gtk_entry_accessible_get_text_after_offset;
673 iface->get_caret_offset = gtk_entry_accessible_get_caret_offset;
674 iface->set_caret_offset = gtk_entry_accessible_set_caret_offset;
675 iface->get_character_count = gtk_entry_accessible_get_character_count;
676 iface->get_n_selections = gtk_entry_accessible_get_n_selections;
677 iface->get_selection = gtk_entry_accessible_get_selection;
678 iface->add_selection = gtk_entry_accessible_add_selection;
679 iface->remove_selection = gtk_entry_accessible_remove_selection;
680 iface->set_selection = gtk_entry_accessible_set_selection;
681 iface->get_run_attributes = gtk_entry_accessible_get_run_attributes;
682 iface->get_default_attributes = gtk_entry_accessible_get_default_attributes;
683 iface->get_character_extents = gtk_entry_accessible_get_character_extents;
684 iface->get_offset_at_point = gtk_entry_accessible_get_offset_at_point;
688 gtk_entry_accessible_set_text_contents (AtkEditableText *text,
693 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
697 if (!gtk_editable_get_editable (GTK_EDITABLE (widget)))
700 gtk_entry_set_text (GTK_ENTRY (widget), string);
704 gtk_entry_accessible_insert_text (AtkEditableText *text,
710 GtkEditable *editable;
712 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
716 editable = GTK_EDITABLE (widget);
717 if (!gtk_editable_get_editable (editable))
720 gtk_editable_insert_text (editable, string, length, position);
721 gtk_editable_set_position (editable, *position);
725 gtk_entry_accessible_copy_text (AtkEditableText *text,
730 GtkEditable *editable;
732 GtkClipboard *clipboard;
734 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
738 if (!gtk_widget_has_screen (widget))
741 editable = GTK_EDITABLE (widget);
742 str = gtk_editable_get_chars (editable, start_pos, end_pos);
743 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
744 gtk_clipboard_set_text (clipboard, str, -1);
749 gtk_entry_accessible_cut_text (AtkEditableText *text,
754 GtkEditable *editable;
756 GtkClipboard *clipboard;
758 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
762 if (!gtk_widget_has_screen (widget))
765 editable = GTK_EDITABLE (widget);
766 if (!gtk_editable_get_editable (editable))
769 str = gtk_editable_get_chars (editable, start_pos, end_pos);
770 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
771 gtk_clipboard_set_text (clipboard, str, -1);
772 gtk_editable_delete_text (editable, start_pos, end_pos);
776 gtk_entry_accessible_delete_text (AtkEditableText *text,
781 GtkEditable *editable;
783 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
787 editable = GTK_EDITABLE (widget);
788 if (!gtk_editable_get_editable (editable))
791 gtk_editable_delete_text (editable, start_pos, end_pos);
801 paste_received_cb (GtkClipboard *clipboard,
805 PasteData *paste = data;
808 gtk_editable_insert_text (GTK_EDITABLE (paste->entry), text, -1,
811 g_object_unref (paste->entry);
816 gtk_entry_accessible_paste_text (AtkEditableText *text,
820 GtkEditable *editable;
822 GtkClipboard *clipboard;
824 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
828 if (!gtk_widget_has_screen (widget))
831 editable = GTK_EDITABLE (widget);
832 if (!gtk_editable_get_editable (editable))
835 paste = g_new0 (PasteData, 1);
836 paste->entry = GTK_ENTRY (widget);
837 paste->position = position;
839 g_object_ref (paste->entry);
840 clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
841 gtk_clipboard_request_text (clipboard, paste_received_cb, paste);
845 atk_editable_text_interface_init (AtkEditableTextIface *iface)
847 iface->set_text_contents = gtk_entry_accessible_set_text_contents;
848 iface->insert_text = gtk_entry_accessible_insert_text;
849 iface->copy_text = gtk_entry_accessible_copy_text;
850 iface->cut_text = gtk_entry_accessible_cut_text;
851 iface->delete_text = gtk_entry_accessible_delete_text;
852 iface->paste_text = gtk_entry_accessible_paste_text;
853 iface->set_run_attributes = NULL;
856 /* We connect to GtkEditable::insert-text, since it carries
857 * the information we need. But we delay emitting our own
858 * text_changed::insert signal until the entry has update
859 * all its internal state and emits GtkEntry::changed.
862 insert_text_cb (GtkEditable *editable,
864 gint new_text_length,
867 GtkEntryAccessible *accessible;
869 if (new_text_length == 0)
872 accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
873 if (accessible->length_insert == 0)
875 accessible->position_insert = *position;
876 accessible->length_insert = g_utf8_strlen (new_text, new_text_length);
880 /* We connect to GtkEditable::delete-text, since it carries
881 * the information we need. But we delay emitting our own
882 * text_changed::delete signal until the entry has update
883 * all its internal state and emits GtkEntry::changed.
886 delete_text_cb (GtkEditable *editable,
890 GtkEntryAccessible *accessible;
896 text = gtk_entry_get_text (GTK_ENTRY (editable));
897 end = g_utf8_strlen (text, -1);
903 accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
904 if (accessible->length_delete == 0)
906 accessible->position_delete = start;
907 accessible->length_delete = end - start;
911 /* Note the assumption here: A single ::changed emission
912 * will only collect a single deletion/insertion, and there
913 * won't be multiple insertions or deletions in a single
917 changed_cb (GtkEditable *editable)
919 GtkEntryAccessible *accessible;
921 accessible = GTK_ENTRY_ACCESSIBLE (gtk_widget_get_accessible (GTK_WIDGET (editable)));
923 if (accessible->length_delete > 0)
925 g_signal_emit_by_name (accessible,
926 "text_changed::delete",
927 accessible->position_delete,
928 accessible->length_delete);
929 accessible->length_delete = 0;
931 if (accessible->length_insert > 0)
933 g_signal_emit_by_name (accessible,
934 "text_changed::insert",
935 accessible->position_insert,
936 accessible->length_insert);
937 accessible->length_insert = 0;
942 check_for_selection_change (GtkEntryAccessible *accessible,
945 gboolean ret_val = FALSE;
948 if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
950 if (end != accessible->cursor_position ||
951 start != accessible->selection_bound)
953 * This check is here as this function can be called
954 * for notification of selection_bound and current_pos.
955 * The values of current_pos and selection_bound may be the same
956 * for both notifications and we only want to generate one
957 * text_selection_changed signal.
963 /* We had a selection */
964 ret_val = (accessible->cursor_position != accessible->selection_bound);
967 accessible->cursor_position = end;
968 accessible->selection_bound = start;
974 idle_do_action (gpointer data)
976 GtkEntryAccessible *entry;
979 entry = GTK_ENTRY_ACCESSIBLE (data);
980 entry->action_idle_handler = 0;
981 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (entry));
982 if (widget == NULL /* State is defunct */ ||
983 !gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
986 gtk_widget_activate (widget);
992 gtk_entry_accessible_do_action (AtkAction *action,
995 GtkEntryAccessible *entry;
998 entry = GTK_ENTRY_ACCESSIBLE (action);
999 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
1003 if (!gtk_widget_get_sensitive (widget) || !gtk_widget_get_visible (widget))
1009 if (entry->action_idle_handler)
1012 entry->action_idle_handler = gdk_threads_add_idle (idle_do_action, entry);
1018 gtk_entry_accessible_get_n_actions (AtkAction *action)
1023 static const gchar *
1024 gtk_entry_accessible_get_keybinding (AtkAction *action,
1029 AtkRelationSet *set;
1030 AtkRelation *relation;
1032 gpointer target_object;
1038 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
1042 set = atk_object_ref_relation_set (ATK_OBJECT (action));
1047 relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_LABELLED_BY);
1050 target = atk_relation_get_target (relation);
1052 target_object = g_ptr_array_index (target, 0);
1053 label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
1056 g_object_unref (set);
1058 if (GTK_IS_LABEL (label))
1060 key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
1061 if (key_val != GDK_KEY_VoidSymbol)
1062 return gtk_accelerator_name (key_val, GDK_MOD1_MASK);
1069 gtk_entry_accessible_action_get_name (AtkAction *action,
1079 atk_action_interface_init (AtkActionIface *iface)
1081 iface->do_action = gtk_entry_accessible_do_action;
1082 iface->get_n_actions = gtk_entry_accessible_get_n_actions;
1083 iface->get_keybinding = gtk_entry_accessible_get_keybinding;
1084 iface->get_name = gtk_entry_accessible_action_get_name;