evolution-3.6.4/widgets/table/gal-a11y-e-table-click-to-add.c

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 }