]> Pileus Git - ~andy/gtk/blob - gtk/a11y/gtkexpanderaccessible.c
b9697f9afc09336045f6c234cec3b20dea965266
[~andy/gtk] / gtk / a11y / gtkexpanderaccessible.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2003 Sun Microsystems Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include "config.h"
21
22 #include <gtk/gtk.h>
23 #include "gtkexpanderaccessible.h"
24
25 static void atk_action_interface_init (AtkActionIface *iface);
26
27 G_DEFINE_TYPE_WITH_CODE (GtkExpanderAccessible, _gtk_expander_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE,
28                          G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
29
30 static const gchar *
31 gtk_expander_accessible_get_full_text (GtkExpander *widget)
32 {
33   GtkWidget *label_widget;
34
35   label_widget = gtk_expander_get_label_widget (widget);
36
37   if (!GTK_IS_LABEL (label_widget))
38     return NULL;
39
40   return gtk_label_get_text (GTK_LABEL (label_widget));
41 }
42
43 static const gchar *
44 gtk_expander_accessible_get_name (AtkObject *obj)
45 {
46   GtkWidget *widget;
47   const gchar *name;
48
49   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
50   if (widget == NULL)
51     return NULL;
52
53   name = ATK_OBJECT_CLASS (_gtk_expander_accessible_parent_class)->get_name (obj);
54   if (name != NULL)
55     return name;
56
57   return gtk_expander_accessible_get_full_text (GTK_EXPANDER (widget));
58 }
59
60 static gint
61 gtk_expander_accessible_get_n_children (AtkObject *obj)
62 {
63   GtkWidget *widget;
64   GList *children;
65   gint count = 0;
66
67   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
68   if (widget == NULL)
69     return 0;
70
71   children = gtk_container_get_children (GTK_CONTAINER(widget));
72   count = g_list_length (children);
73   g_list_free (children);
74
75   /* See if there is a label - if there is, reduce our count by 1
76    * since we don't want the label included with the children.
77    */
78   if (gtk_expander_get_label_widget (GTK_EXPANDER (widget)))
79     count -= 1;
80
81   return count;
82 }
83
84 static AtkObject *
85 gtk_expander_accessible_ref_child (AtkObject *obj,
86                                    gint       i)
87 {
88   GList *children, *tmp_list;
89   AtkObject *accessible;
90   GtkWidget *widget;
91   GtkWidget *label;
92   gint index;
93
94   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
95   if (widget == NULL)
96     return NULL;
97
98   children = gtk_container_get_children (GTK_CONTAINER (widget));
99
100   /* See if there is a label - if there is, we need to skip it
101    * since we don't want the label included with the children.
102    */
103   label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
104   if (label)
105     {
106       for (index = 0; index <= i; index++)
107         {
108           tmp_list = g_list_nth (children, index);
109           if (label == GTK_WIDGET (tmp_list->data))
110             {
111               i += 1;
112               break;
113             }
114         }
115     }
116
117   tmp_list = g_list_nth (children, i);
118   if (!tmp_list)
119     {
120       g_list_free (children);
121       return NULL;
122     }
123   accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data));
124
125   g_list_free (children);
126   g_object_ref (accessible);
127   return accessible;
128 }
129
130 static void
131 gtk_expander_accessible_initialize (AtkObject *obj,
132                                     gpointer   data)
133 {
134   ATK_OBJECT_CLASS (_gtk_expander_accessible_parent_class)->initialize (obj, data);
135
136   obj->role = ATK_ROLE_TOGGLE_BUTTON;
137 }
138
139 static void
140 gtk_expander_accessible_notify_gtk (GObject    *obj,
141                                     GParamSpec *pspec)
142 {
143   AtkObject* atk_obj;
144   GtkExpander *expander;
145
146   expander = GTK_EXPANDER (obj);
147   atk_obj = gtk_widget_get_accessible (GTK_WIDGET (expander));
148 ;
149   if (g_strcmp0 (pspec->name, "label") == 0)
150     {
151       if (atk_obj->name == NULL)
152         g_object_notify (G_OBJECT (atk_obj), "accessible-name");
153       g_signal_emit_by_name (atk_obj, "visible-data-changed");
154     }
155   else if (g_strcmp0 (pspec->name, "expanded") == 0)
156     {
157       atk_object_notify_state_change (atk_obj, ATK_STATE_CHECKED,
158                                       gtk_expander_get_expanded (expander));
159       atk_object_notify_state_change (atk_obj, ATK_STATE_EXPANDED,
160                                       gtk_expander_get_expanded (expander));
161       g_signal_emit_by_name (atk_obj, "visible-data-changed");
162     }
163   else
164     GTK_WIDGET_ACCESSIBLE_CLASS (_gtk_expander_accessible_parent_class)->notify_gtk (obj, pspec);
165 }
166
167 static AtkStateSet *
168 gtk_expander_accessible_ref_state_set (AtkObject *obj)
169 {
170   AtkStateSet *state_set;
171   GtkWidget *widget;
172   GtkExpander *expander;
173
174   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
175   if (widget == NULL)
176     return NULL;
177
178   state_set = ATK_OBJECT_CLASS (_gtk_expander_accessible_parent_class)->ref_state_set (obj);
179
180   expander = GTK_EXPANDER (widget);
181
182   atk_state_set_add_state (state_set, ATK_STATE_EXPANDABLE);
183
184   if (gtk_expander_get_expanded (expander))
185     {
186       atk_state_set_add_state (state_set, ATK_STATE_CHECKED);
187       atk_state_set_add_state (state_set, ATK_STATE_EXPANDED);
188     }
189
190   return state_set;
191 }
192
193 static void
194 _gtk_expander_accessible_class_init (GtkExpanderAccessibleClass *klass)
195 {
196   AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
197   GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass;
198
199   widget_class->notify_gtk = gtk_expander_accessible_notify_gtk;
200
201   class->get_name = gtk_expander_accessible_get_name;
202   class->get_n_children = gtk_expander_accessible_get_n_children;
203   class->ref_child = gtk_expander_accessible_ref_child;
204   class->ref_state_set = gtk_expander_accessible_ref_state_set;
205
206   class->initialize = gtk_expander_accessible_initialize;
207 }
208
209 static void
210 _gtk_expander_accessible_init (GtkExpanderAccessible *expander)
211 {
212 }
213
214 static gboolean
215 gtk_expander_accessible_do_action (AtkAction *action,
216                                    gint       i)
217 {
218   GtkWidget *widget;
219
220   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
221   if (widget == NULL)
222     return FALSE;
223
224   if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
225     return FALSE;
226
227   if (i != 0)
228     return FALSE;
229
230   gtk_widget_activate (widget);
231   return TRUE;
232 }
233
234 static gint
235 gtk_expander_accessible_get_n_actions (AtkAction *action)
236 {
237   return 1;
238 }
239
240 static const gchar *
241 gtk_expander_accessible_get_keybinding (AtkAction *action,
242                                         gint       i)
243 {
244   gchar *return_value = NULL;
245   GtkWidget *widget;
246   GtkWidget *label;
247
248   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
249   if (widget == NULL)
250     return NULL;
251
252   if (i != 0)
253     return NULL;
254
255   label = gtk_expander_get_label_widget (GTK_EXPANDER (widget));
256   if (GTK_IS_LABEL (label))
257     {
258       guint key_val;
259
260       key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label));
261       if (key_val != GDK_KEY_VoidSymbol)
262         return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
263     }
264
265   return return_value;
266 }
267
268 static const gchar *
269 gtk_expander_accessible_action_get_name (AtkAction *action,
270                                          gint       i)
271 {
272   if (i != 0)
273     return NULL;
274
275   return "activate";
276 }
277
278 static void
279 atk_action_interface_init (AtkActionIface *iface)
280 {
281   iface->do_action = gtk_expander_accessible_do_action;
282   iface->get_n_actions = gtk_expander_accessible_get_n_actions;
283   iface->get_keybinding = gtk_expander_accessible_get_keybinding;
284   iface->get_name = gtk_expander_accessible_action_get_name;
285 }