No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Yuedong Du <yuedong.du@sun.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <atk/atk.h>
28
29 #include "a11y/gal-a11y-util.h"
30 #include "table/e-table-click-to-add.h"
31 #include "table/e-table-group.h"
32 #include "table/e-table-group-leaf.h"
33 #include <glib/gi18n.h>
34
35 #include "gal-a11y-e-table-click-to-add.h"
36 #include "gal-a11y-e-table-click-to-add-factory.h"
37
38 static AtkObjectClass *parent_class;
39 static GType parent_type;
40 static gint priv_offset;
41 #define GET_PRIVATE(object) \
42 ((GalA11yETableClickToAddPrivate *) \
43 (((gchar *) object) + priv_offset))
44 #define PARENT_TYPE (parent_type)
45
46 struct _GalA11yETableClickToAddPrivate {
47 gpointer rect;
48 gpointer row;
49 };
50
51 static gint
52 etcta_get_n_actions (AtkAction *action)
53 {
54 return 1;
55 }
56
57 static const gchar *
58 etcta_get_description (AtkAction *action,
59 gint i)
60 {
61 if (i == 0)
62 return _("click to add");
63
64 return NULL;
65 }
66
67 static const gchar *
68 etcta_action_get_name (AtkAction *action,
69 gint i)
70 {
71 if (i == 0)
72 return _("click");
73
74 return NULL;
75 }
76
77 static gboolean
78 idle_do_action (gpointer data)
79 {
80 GtkLayout *layout;
81 GdkEventButton event;
82 ETableClickToAdd * etcta;
83 gint finished;
84
85 g_return_val_if_fail (data!= NULL, FALSE);
86
87 etcta = E_TABLE_CLICK_TO_ADD (
88 atk_gobject_accessible_get_object (
89 ATK_GOBJECT_ACCESSIBLE (data)));
90 g_return_val_if_fail (etcta, FALSE);
91
92 layout = GTK_LAYOUT (GNOME_CANVAS_ITEM (etcta)->canvas);
93
94 event.x = 0;
95 event.y = 0;
96 event.type = GDK_BUTTON_PRESS;
97 event.window = gtk_layout_get_bin_window (layout);
98 event.button = 1;
99 event.send_event = TRUE;
100 event.time = GDK_CURRENT_TIME;
101 event.axes = NULL;
102
103 g_signal_emit_by_name (etcta, "event", &event, &finished);
104
105 return FALSE;
106 }
107
108 static gboolean
109 etcta_do_action (AtkAction *action,
110 gint i)
111 {
112 g_return_val_if_fail (i == 0, FALSE);
113
114 g_idle_add (idle_do_action, action);
115
116 return TRUE;
117 }
118
119 static void
120 atk_action_interface_init (AtkActionIface *iface)
121 {
122 g_return_if_fail (iface != NULL);
123
124 iface->do_action = etcta_do_action;
125 iface->get_n_actions = etcta_get_n_actions;
126 iface->get_description = etcta_get_description;
127 iface->get_name = etcta_action_get_name;
128 }
129
130 static const gchar *
131 etcta_get_name (AtkObject *obj)
132 {
133 ETableClickToAdd * etcta;
134
135 g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (obj), NULL);
136
137 etcta = E_TABLE_CLICK_TO_ADD (
138 atk_gobject_accessible_get_object (
139 ATK_GOBJECT_ACCESSIBLE (obj)));
140 if (etcta && etcta->message != NULL)
141 return etcta->message;
142
143 return _("click to add");
144 }
145
146 static gint
147 etcta_get_n_children (AtkObject *accessible)
148 {
149 return 1;
150 }
151
152 static AtkObject *
153 etcta_ref_child (AtkObject *accessible,
154 gint i)
155 {
156 AtkObject * atk_obj = NULL;
157 ETableClickToAdd * etcta;
158
159 if (i != 0)
160 return NULL;
161
162 etcta = E_TABLE_CLICK_TO_ADD (
163 atk_gobject_accessible_get_object (
164 ATK_GOBJECT_ACCESSIBLE (accessible)));
165
166 g_return_val_if_fail (etcta, NULL);
167
168 if (etcta->rect) {
169 atk_obj = atk_gobject_accessible_for_object (
170 G_OBJECT (etcta->rect));
171 } else if (etcta->row) {
172 atk_obj = atk_gobject_accessible_for_object (
173 G_OBJECT (etcta->row));
174 }
175
176 g_object_ref (atk_obj);
177
178 return atk_obj;
179 }
180
181 static AtkStateSet *
182 etcta_ref_state_set (AtkObject *accessible)
183 {
184 AtkStateSet * state_set = NULL;
185
186 state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible);
187 if (state_set != NULL) {
188 atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
189 atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
190 }
191
192 return state_set;
193 }
194
195 static void
196 etcta_class_init (GalA11yETableClickToAddClass *class)
197 {
198 AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class);
199
200 parent_class = g_type_class_ref (PARENT_TYPE);
201
202 atk_object_class->get_name = etcta_get_name;
203 atk_object_class->get_n_children = etcta_get_n_children;
204 atk_object_class->ref_child = etcta_ref_child;
205 atk_object_class->ref_state_set = etcta_ref_state_set;
206 }
207
208 static void
209 etcta_init (GalA11yETableClickToAdd *a11y)
210 {
211 }
212
213 GType
214 gal_a11y_e_table_click_to_add_get_type (void)
215 {
216 static GType type = 0;
217
218 if (!type) {
219 AtkObjectFactory *factory;
220
221 GTypeInfo info = {
222 sizeof (GalA11yETableClickToAddClass),
223 (GBaseInitFunc) NULL,
224 (GBaseFinalizeFunc) NULL,
225 (GClassInitFunc) etcta_class_init,
226 (GClassFinalizeFunc) NULL,
227 NULL, /* class_data */
228 sizeof (GalA11yETableClickToAdd),
229 0,
230 (GInstanceInitFunc) etcta_init,
231 NULL /* value_table */
232 };
233
234 static const GInterfaceInfo atk_action_info = {
235 (GInterfaceInitFunc) atk_action_interface_init,
236 (GInterfaceFinalizeFunc) NULL,
237 NULL
238 };
239
240 factory = atk_registry_get_factory (
241 atk_get_default_registry (),
242 GNOME_TYPE_CANVAS_ITEM);
243
244 parent_type = atk_object_factory_get_accessible_type (factory);
245 type = gal_a11y_type_register_static_with_private (
246 PARENT_TYPE, "GalA11yETableClickToAdd", &info, 0,
247 sizeof (GalA11yETableClickToAddPrivate), &priv_offset);
248
249 g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
250
251 }
252
253 return type;
254 }
255
256 static gboolean
257 etcta_event (GnomeCanvasItem *item,
258 GdkEvent *e,
259 gpointer data)
260 {
261 ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
262 GalA11yETableClickToAdd *a11y;
263 GalA11yETableClickToAddPrivate *priv;
264
265 g_return_val_if_fail (item, TRUE);
266
267 g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (data), FALSE);
268 a11y = GAL_A11Y_E_TABLE_CLICK_TO_ADD (data);
269
270 priv = GET_PRIVATE (a11y);
271
272 /* rect replaced by row. */
273 if (etcta->rect == NULL && priv->rect != NULL) {
274 g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL);
275
276 }
277 /* row inserted, and/or replaced by a new row. */
278 if (etcta->row != NULL && priv->row == NULL) {
279 g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL);
280 } else if (etcta->row != NULL && priv->row != NULL && etcta->row != priv->row) {
281 g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL);
282 g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL);
283 }
284
285 priv->rect = etcta->rect;
286 priv->row = etcta->row;
287
288 return FALSE;
289 }
290
291 static void
292 etcta_selection_cursor_changed (ESelectionModel *esm,
293 gint row,
294 gint col,
295 GalA11yETableClickToAdd *a11y)
296 {
297 ETableClickToAdd *etcta;
298 AtkObject *row_a11y;
299
300 etcta = E_TABLE_CLICK_TO_ADD (
301 atk_gobject_accessible_get_object (
302 ATK_GOBJECT_ACCESSIBLE (a11y)));
303
304 if (etcta == NULL || etcta->row == NULL)
305 return;
306
307 row_a11y = atk_gobject_accessible_for_object (G_OBJECT (etcta->row));
308 if (row_a11y) {
309 AtkObject *cell_a11y;
310
311 cell_a11y = g_object_get_data (
312 G_OBJECT (row_a11y), "gail-focus-object");
313 if (cell_a11y) {
314 atk_focus_tracker_notify (cell_a11y);
315 }
316 }
317 }
318
319 AtkObject *
320 gal_a11y_e_table_click_to_add_new (GObject *widget)
321 {
322 GalA11yETableClickToAdd *a11y;
323 ETableClickToAdd * etcta;
324 GalA11yETableClickToAddPrivate *priv;
325
326 g_return_val_if_fail (widget != NULL, NULL);
327
328 a11y = g_object_new (gal_a11y_e_table_click_to_add_get_type (), NULL);
329 priv = GET_PRIVATE (a11y);
330
331 etcta = E_TABLE_CLICK_TO_ADD (widget);
332
333 atk_object_initialize (ATK_OBJECT (a11y), etcta);
334
335 priv->rect = etcta->rect;
336 priv->row = etcta->row;
337
338 g_signal_connect_after (
339 widget, "event",
340 G_CALLBACK (etcta_event), a11y);
341
342 g_signal_connect (
343 etcta->selection, "cursor_changed",
344 G_CALLBACK (etcta_selection_cursor_changed), a11y);
345
346 return ATK_OBJECT (a11y);
347 }
348
349 void
350 gal_a11y_e_table_click_to_add_init (void)
351 {
352 if (atk_get_root ())
353 atk_registry_set_factory_type (
354 atk_get_default_registry (),
355 E_TYPE_TABLE_CLICK_TO_ADD,
356 gal_a11y_e_table_click_to_add_factory_get_type ());
357 }