evolution-3.6.4/widgets/table/gal-a11y-e-table.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  *		Christopher James Lahey <clahey@ximian.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 "a11y/gal-a11y-util.h"
 28 #include "table/e-table.h"
 29 #include "table/e-table-click-to-add.h"
 30 #include "table/e-table-group.h"
 31 #include "table/e-table-group-container.h"
 32 #include "table/e-table-group-leaf.h"
 33 
 34 #include "gal-a11y-e-table.h"
 35 #include "gal-a11y-e-table-factory.h"
 36 #include "gal-a11y-e-table-item.h"
 37 
 38 #define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETableClass))
 39 static AtkObjectClass *parent_class;
 40 static GType parent_type;
 41 static gint priv_offset;
 42 #define GET_PRIVATE(object) ((GalA11yETablePrivate *) (((gchar *) object) + priv_offset))
 43 #define PARENT_TYPE (parent_type)
 44 
 45 struct _GalA11yETablePrivate {
 46 	AtkObject *child_item;
 47 };
 48 
 49 /* Static functions */
 50 static ETableItem *
 51 find_first_table_item (ETableGroup *group)
 52 {
 53 	GnomeCanvasGroup *cgroup;
 54 	GList *l;
 55 
 56 	cgroup = GNOME_CANVAS_GROUP (group);
 57 
 58 	for (l = cgroup->item_list; l; l = l->next) {
 59 		GnomeCanvasItem *i;
 60 
 61 		i = GNOME_CANVAS_ITEM (l->data);
 62 
 63 		if (E_IS_TABLE_GROUP (i))
 64 			return find_first_table_item (E_TABLE_GROUP (i));
 65 		else if (E_IS_TABLE_ITEM (i)) {
 66 			return E_TABLE_ITEM (i);
 67 		}
 68 	}
 69 
 70 	return NULL;
 71 }
 72 
 73 static AtkObject *
 74 eti_get_accessible (ETableItem *eti,
 75                     AtkObject *parent)
 76 {
 77 	AtkObject *a11y = NULL;
 78 
 79 	g_return_val_if_fail (eti, NULL);
 80 
 81 	a11y = atk_gobject_accessible_for_object (G_OBJECT (eti));
 82 	g_return_val_if_fail (a11y, NULL);
 83 
 84 	return a11y;
 85 }
 86 
 87 static gboolean
 88 init_child_item (GalA11yETable *a11y)
 89 {
 90 	ETable *table;
 91 
 92 	if (!a11y || !GTK_IS_ACCESSIBLE (a11y))
 93 		return FALSE;
 94 
 95 	table = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y)));
 96 	if (table && gtk_widget_get_mapped (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) {
 97 		ETableGroupContainer *etgc =  (ETableGroupContainer *) table->group;
 98 		GList *list;
 99 
100 		for (list = etgc->children; list; list = g_list_next (list)) {
101 			ETableGroupContainerChildNode *child_node = list->data;
102 			ETableGroup *child = child_node->child;
103 			ETableItem *eti = find_first_table_item (child);
104 
105 			eti_get_accessible (eti, ATK_OBJECT (a11y));
106 		}
107 	}
108 	g_object_unref (a11y);
109 	g_object_unref (table);
110 
111 	return FALSE;
112 }
113 
114 static AtkObject *
115 et_ref_accessible_at_point (AtkComponent *component,
116                             gint x,
117                             gint y,
118                             AtkCoordType coord_type)
119 {
120 	GalA11yETable *a11y = GAL_A11Y_E_TABLE (component);
121 	if (GET_PRIVATE (a11y)->child_item)
122 		g_object_ref (GET_PRIVATE (a11y)->child_item);
123 	return GET_PRIVATE (a11y)->child_item;
124 }
125 
126 static gint
127 et_get_n_children (AtkObject *accessible)
128 {
129 	GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
130 	ETable * et;
131 	gint n = 0;
132 
133 	et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y)));
134 
135 	if (et && et->group) {
136 		if (E_IS_TABLE_GROUP_LEAF (et->group))
137 			n = 1;
138 		else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
139 			ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
140 			n = g_list_length (etgc->children);
141 		}
142 	}
143 
144 	if (et && et->use_click_to_add && et->click_to_add) {
145 		n++;
146 	}
147 	return n;
148 }
149 
150 static AtkObject *
151 et_ref_child (AtkObject *accessible,
152               gint i)
153 {
154 	GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
155 	ETable * et;
156 	gint child_no;
157 
158 	et = E_TABLE (gtk_accessible_get_widget (GTK_ACCESSIBLE (a11y)));
159 	if (!et)
160 		return NULL;
161 
162 	child_no = et_get_n_children (accessible);
163 	if (i == 0 || i < child_no - 1) {
164 		if (E_IS_TABLE_GROUP_LEAF (et->group)) {
165 			ETableItem *eti = find_first_table_item (et->group);
166 			AtkObject *aeti = eti_get_accessible (eti, accessible);
167 			if (aeti)
168 				g_object_ref (aeti);
169 			return aeti;
170 
171 		} else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
172 			ETableGroupContainer *etgc =  (ETableGroupContainer *) et->group;
173 			ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i);
174 			if (child_node) {
175 				ETableGroup *child = child_node->child;
176 				ETableItem * eti = find_first_table_item (child);
177 				AtkObject *aeti =  eti_get_accessible (eti, accessible);
178 				if (aeti)
179 					g_object_ref (aeti);
180 				return aeti;
181 			}
182 		}
183 	} else if (i == child_no -1) {
184 		ETableClickToAdd * etcta;
185 
186 		if (et && et->use_click_to_add && et->click_to_add) {
187 			etcta = E_TABLE_CLICK_TO_ADD (et->click_to_add);
188 			accessible = atk_gobject_accessible_for_object (G_OBJECT (etcta));
189 			if (accessible)
190 				g_object_ref (accessible);
191 			return accessible;
192 		}
193 	}
194 
195 	return NULL;
196 }
197 
198 static AtkLayer
199 et_get_layer (AtkComponent *component)
200 {
201 	return ATK_LAYER_WIDGET;
202 }
203 
204 static void
205 et_class_init (GalA11yETableClass *class)
206 {
207 	AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (class);
208 
209 	parent_class                              = g_type_class_ref (PARENT_TYPE);
210 
211 	atk_object_class->get_n_children          = et_get_n_children;
212 	atk_object_class->ref_child               = et_ref_child;
213 }
214 
215 static void
216 et_atk_component_iface_init (AtkComponentIface *iface)
217 {
218 	iface->ref_accessible_at_point = et_ref_accessible_at_point;
219 	iface->get_layer = et_get_layer;
220 }
221 
222 static void
223 et_init (GalA11yETable *a11y)
224 {
225 	GalA11yETablePrivate *priv;
226 
227 	priv = GET_PRIVATE (a11y);
228 
229 	priv->child_item = NULL;
230 }
231 
232 /**
233  * gal_a11y_e_table_get_type:
234  * @void:
235  *
236  * Registers the &GalA11yETable class if necessary, and returns the type ID
237  * associated to it.
238  *
239  * Return value: The type ID of the &GalA11yETable class.
240  **/
241 GType
242 gal_a11y_e_table_get_type (void)
243 {
244 	static GType type = 0;
245 
246 	if (!type) {
247 		AtkObjectFactory *factory;
248 
249 		GTypeInfo info = {
250 			sizeof (GalA11yETableClass),
251 			(GBaseInitFunc) NULL,
252 			(GBaseFinalizeFunc) NULL,
253 			(GClassInitFunc) et_class_init,
254 			(GClassFinalizeFunc) NULL,
255 			NULL, /* class_data */
256 			sizeof (GalA11yETable),
257 			0,
258 			(GInstanceInitFunc) et_init,
259 			NULL /* value_table */
260 		};
261 
262 		static const GInterfaceInfo atk_component_info = {
263 			(GInterfaceInitFunc) et_atk_component_iface_init,
264 			(GInterfaceFinalizeFunc) NULL,
265 			NULL
266 		};
267 
268 		factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET);
269 		parent_type = atk_object_factory_get_accessible_type (factory);
270 
271 		type = gal_a11y_type_register_static_with_private (
272 			PARENT_TYPE, "GalA11yETable", &info, 0,
273 			sizeof (GalA11yETablePrivate), &priv_offset);
274 		g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
275 	}
276 
277 	return type;
278 }
279 
280 AtkObject *
281 gal_a11y_e_table_new (GObject *widget)
282 {
283 	GalA11yETable *a11y;
284 	ETable *table;
285 
286 	table = E_TABLE (widget);
287 
288 	a11y = g_object_new (gal_a11y_e_table_get_type (), NULL);
289 
290 	gtk_accessible_set_widget (GTK_ACCESSIBLE (a11y), GTK_WIDGET (widget));
291 
292 	/* we need to init all the children for multiple table items */
293 	if (table && gtk_widget_get_mapped (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) {
294 		/* Ref it here so that it is still valid in the idle function */
295 		/* It will be unrefed in the idle function */
296 		g_object_ref (a11y);
297 		g_object_ref (widget);
298 
299 		g_idle_add ((GSourceFunc) init_child_item, a11y);
300 	}
301 
302 	return ATK_OBJECT (a11y);
303 }
304 
305 void
306 gal_a11y_e_table_init (void)
307 {
308 	if (atk_get_root ())
309 		atk_registry_set_factory_type (
310 			atk_get_default_registry (),
311 						E_TYPE_TABLE,
312 						gal_a11y_e_table_factory_get_type ());
313 
314 }