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