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