evolution-3.6.4/widgets/misc/ea-calendar-cell.c

No issues found

  1 /*
  2  *
  3  * This program is free software; you can redistribute it and/or
  4  * modify it under the terms of the GNU Lesser General Public
  5  * License as published by the Free Software Foundation; either
  6  * version 2 of the License, or (at your option) version 3.
  7  *
  8  * This program is distributed in the hope that it will be useful,
  9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 11  * Lesser General Public License for more details.
 12  *
 13  * You should have received a copy of the GNU Lesser General Public
 14  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 15  *
 16  *
 17  * Authors:
 18  *		Bolian Yin <bolian.yin@sun.com>
 19  *
 20  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 21  *
 22  */
 23 
 24 #ifdef HAVE_CONFIG_H
 25 #include <config.h>
 26 #endif
 27 
 28 #include <gtk/gtk.h>
 29 #include <e-util/e-util.h>
 30 #include "ea-calendar-cell.h"
 31 #include "ea-calendar-item.h"
 32 #include "a11y/ea-factory.h"
 33 
 34 /* ECalendarCell */
 35 
 36 static void e_calendar_cell_class_init (ECalendarCellClass *class);
 37 
 38 EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new)
 39 
 40 GType
 41 e_calendar_cell_get_type (void)
 42 {
 43 	static GType type = 0;
 44 
 45 	if (!type) {
 46 		static GTypeInfo tinfo = {
 47 			sizeof (ECalendarCellClass),
 48 			(GBaseInitFunc) NULL, /* base init */
 49 			(GBaseFinalizeFunc) NULL, /* base finalize */
 50 			(GClassInitFunc) e_calendar_cell_class_init, /* class init */
 51 			(GClassFinalizeFunc) NULL, /* class finalize */
 52 			NULL, /* class data */
 53 			sizeof (ECalendarCell), /* instance size */
 54 			0, /* nb preallocs */
 55 			(GInstanceInitFunc) NULL, /* instance init */
 56 			NULL /* value table */
 57 		};
 58 
 59 		type = g_type_register_static (
 60 			G_TYPE_OBJECT,
 61 			"ECalendarCell", &tinfo, 0);
 62 	}
 63 
 64 	return type;
 65 }
 66 
 67 static void
 68 e_calendar_cell_class_init (ECalendarCellClass *class)
 69 {
 70     EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell);
 71 }
 72 
 73 ECalendarCell *
 74 e_calendar_cell_new (ECalendarItem *calitem,
 75                      gint row,
 76                      gint column)
 77 {
 78 	GObject *object;
 79 	ECalendarCell *cell;
 80 
 81 	g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL);
 82 
 83 	object = g_object_new (E_TYPE_CALENDAR_CELL, NULL);
 84 	cell = E_CALENDAR_CELL (object);
 85 	cell->calitem = calitem;
 86 	cell->row = row;
 87 	cell->column = column;
 88 
 89 #ifdef ACC_DEBUG
 90 	g_print ("EvoAcc: e_calendar_cell created %p\n", (gpointer) cell);
 91 #endif
 92 
 93 	return cell;
 94 }
 95 
 96 /* EaCalendarCell */
 97 
 98 static void ea_calendar_cell_class_init (EaCalendarCellClass *klass);
 99 static void ea_calendar_cell_init (EaCalendarCell *a11y);
100 
101 static const gchar * ea_calendar_cell_get_name (AtkObject *accessible);
102 static const gchar * ea_calendar_cell_get_description (AtkObject *accessible);
103 static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible);
104 static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible);
105 static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible);
106 
107 /* component interface */
108 static void atk_component_interface_init (AtkComponentIface *iface);
109 static void component_interface_get_extents (AtkComponent *component,
110 					     gint *x, gint *y,
111 					     gint *width, gint *height,
112 					     AtkCoordType coord_type);
113 static gboolean component_interface_grab_focus (AtkComponent *component);
114 
115 static gpointer parent_class = NULL;
116 
117 #ifdef ACC_DEBUG
118 static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0;
119 static void ea_calendar_cell_finalize (GObject *object);
120 #endif
121 
122 GType
123 ea_calendar_cell_get_type (void)
124 {
125 	static GType type = 0;
126 
127 	if (!type) {
128 		static GTypeInfo tinfo = {
129 			sizeof (EaCalendarCellClass),
130 			(GBaseInitFunc) NULL, /* base init */
131 			(GBaseFinalizeFunc) NULL, /* base finalize */
132 			(GClassInitFunc) ea_calendar_cell_class_init, /* class init */
133 			(GClassFinalizeFunc) NULL, /* class finalize */
134 			NULL, /* class data */
135 			sizeof (EaCalendarCell), /* instance size */
136 			0, /* nb preallocs */
137 			(GInstanceInitFunc) ea_calendar_cell_init, /* instance init */
138 			NULL /* value table */
139 		};
140 
141 		static const GInterfaceInfo atk_component_info = {
142 			(GInterfaceInitFunc) atk_component_interface_init,
143 			(GInterfaceFinalizeFunc) NULL,
144 			NULL
145 		};
146 
147 		type = g_type_register_static (
148 			ATK_TYPE_GOBJECT_ACCESSIBLE,
149 			"EaCalendarCell", &tinfo, 0);
150 		g_type_add_interface_static (
151 			type, ATK_TYPE_COMPONENT,
152 			&atk_component_info);
153 	}
154 
155 	return type;
156 }
157 
158 static void
159 ea_calendar_cell_class_init (EaCalendarCellClass *klass)
160 {
161 	AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
162 
163 #ifdef ACC_DEBUG
164 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
165 	gobject_class->finalize = ea_calendar_cell_finalize;
166 #endif
167 
168 	parent_class = g_type_class_peek_parent (klass);
169 
170 	class->get_name = ea_calendar_cell_get_name;
171 	class->get_description = ea_calendar_cell_get_description;
172 
173 	class->get_parent = ea_calendar_cell_get_parent;
174 	class->get_index_in_parent = ea_calendar_cell_get_index_in_parent;
175 	class->ref_state_set = ea_calendar_cell_ref_state_set;
176 }
177 
178 static void
179 ea_calendar_cell_init (EaCalendarCell *a11y)
180 {
181 	a11y->state_set = atk_state_set_new ();
182 	atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT);
183 	atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED);
184 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE);
185 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE);
186 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING);
187 	atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE);
188 }
189 
190 AtkObject *
191 ea_calendar_cell_new (GObject *obj)
192 {
193 	gpointer object;
194 	AtkObject *atk_object;
195 
196 	g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL);
197 	object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL);
198 	atk_object = ATK_OBJECT (object);
199 	atk_object_initialize (atk_object, obj);
200 	atk_object->role = ATK_ROLE_TABLE_CELL;
201 
202 #ifdef ACC_DEBUG
203 	++n_ea_calendar_cell_created;
204 	g_print (
205 		"ACC_DEBUG: n_ea_calendar_cell_created = %d\n",
206 		n_ea_calendar_cell_created);
207 #endif
208 	return atk_object;
209 }
210 
211 #ifdef ACC_DEBUG
212 static void ea_calendar_cell_finalize (GObject *object)
213 {
214 	G_OBJECT_CLASS (parent_class)->finalize (object);
215 
216 	++n_ea_calendar_cell_destroyed;
217 	g_print (
218 		"ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n",
219 		n_ea_calendar_cell_destroyed);
220 }
221 #endif
222 
223 static const gchar *
224 ea_calendar_cell_get_name (AtkObject *accessible)
225 {
226 	GObject *g_obj;
227 
228 	g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL);
229 
230 	g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
231 	if (!g_obj)
232 		/* defunct object*/
233 		return NULL;
234 
235 	if (!accessible->name) {
236 		AtkObject *atk_obj;
237 		EaCalendarItem *ea_calitem;
238 		ECalendarCell *cell;
239 		gint day_index;
240 		gint year, month, day;
241 		gchar buffer[128];
242 
243 		cell = E_CALENDAR_CELL (g_obj);
244 		atk_obj = ea_calendar_cell_get_parent (accessible);
245 		ea_calitem = EA_CALENDAR_ITEM (atk_obj);
246 		day_index = atk_table_get_index_at (
247 			ATK_TABLE (ea_calitem),
248 			cell->row, cell->column);
249 		e_calendar_item_get_date_for_offset (cell->calitem, day_index,
250 						     &year, &month, &day);
251 
252 		g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day);
253 		ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer);
254 	}
255 	return accessible->name;
256 }
257 
258 static const gchar *
259 ea_calendar_cell_get_description (AtkObject *accessible)
260 {
261 	return ea_calendar_cell_get_name (accessible);
262 }
263 
264 static AtkObject *
265 ea_calendar_cell_get_parent (AtkObject *accessible)
266 {
267 	GObject *g_obj;
268 	ECalendarCell *cell;
269 	ECalendarItem *calitem;
270 
271 	g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL);
272 
273 	g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
274 	if (!g_obj)
275 		/* defunct object*/
276 		return NULL;
277 
278 	cell = E_CALENDAR_CELL (g_obj);
279 	calitem = cell->calitem;
280 	return atk_gobject_accessible_for_object (G_OBJECT (calitem));
281 }
282 
283 static gint
284 ea_calendar_cell_get_index_in_parent (AtkObject *accessible)
285 {
286 	GObject *g_obj;
287 	ECalendarCell *cell;
288 	AtkObject *parent;
289 
290 	g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1);
291 
292 	g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
293 	if (!g_obj)
294 		return -1;
295 	cell = E_CALENDAR_CELL (g_obj);
296 	parent = atk_object_get_parent (accessible);
297 	return atk_table_get_index_at (
298 		ATK_TABLE (parent),
299 		cell->row, cell->column);
300 }
301 
302 static AtkStateSet *
303 ea_calendar_cell_ref_state_set (AtkObject *accessible)
304 {
305 	EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible);
306 
307 	g_return_val_if_fail (atk_cell->state_set, NULL);
308 
309 	g_object_ref (atk_cell->state_set);
310 
311 	return atk_cell->state_set;
312 
313 }
314 
315 /* Atk Component Interface */
316 
317 static void
318 atk_component_interface_init (AtkComponentIface *iface)
319 {
320 	g_return_if_fail (iface != NULL);
321 
322 	iface->get_extents = component_interface_get_extents;
323 	iface->grab_focus  = component_interface_grab_focus;
324 }
325 
326 static void
327 component_interface_get_extents (AtkComponent *component,
328                                  gint *x,
329                                  gint *y,
330                                  gint *width,
331                                  gint *height,
332                                  AtkCoordType coord_type)
333 {
334 	GObject *g_obj;
335 	AtkObject *atk_obj, *atk_canvas;
336 	ECalendarCell *cell;
337 	ECalendarItem *calitem;
338 	EaCalendarItem *ea_calitem;
339 	gint day_index;
340 	gint year, month, day;
341 	gint canvas_x, canvas_y, canvas_width, canvas_height;
342 
343 	*x = *y = *width = *height = 0;
344 
345 	g_return_if_fail (EA_IS_CALENDAR_CELL (component));
346 
347 	g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component));
348 	if (!g_obj)
349 		/* defunct object*/
350 		return;
351 
352 	cell = E_CALENDAR_CELL (g_obj);
353 	calitem = cell->calitem;
354 	atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
355 	ea_calitem = EA_CALENDAR_ITEM (atk_obj);
356 	day_index = atk_table_get_index_at (
357 		ATK_TABLE (ea_calitem),
358 		cell->row, cell->column);
359 	e_calendar_item_get_date_for_offset (calitem, day_index,
360 					     &year, &month, &day);
361 
362 	if (!e_calendar_item_get_day_extents (calitem,
363 					      year, month, day,
364 					      x, y, width, height))
365 	    return;
366 	atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem));
367 	atk_component_get_extents (
368 		ATK_COMPONENT (atk_canvas),
369 		&canvas_x, &canvas_y,
370 		&canvas_width, &canvas_height,
371 		coord_type);
372 	*x += canvas_x;
373 	*y += canvas_y;
374 }
375 
376 static gboolean
377 component_interface_grab_focus (AtkComponent *component)
378 {
379 	GObject *g_obj;
380 	GtkWidget *toplevel;
381 	AtkObject *ea_calitem;
382 	ECalendarItem *calitem;
383 	EaCalendarCell *a11y;
384 	gint index;
385 
386 	a11y = EA_CALENDAR_CELL (component);
387 	ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y));
388 
389 	g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem));
390 	calitem = E_CALENDAR_ITEM (g_obj);
391 
392 	index = atk_object_get_index_in_parent (ATK_OBJECT (a11y));
393 
394 	atk_selection_clear_selection (ATK_SELECTION (ea_calitem));
395 	atk_selection_add_selection (ATK_SELECTION (ea_calitem), index);
396 
397 	gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
398 	toplevel = gtk_widget_get_toplevel (
399 		GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
400 	if (toplevel && gtk_widget_is_toplevel (toplevel))
401 		gtk_window_present (GTK_WINDOW (toplevel));
402 
403 	return TRUE;
404 
405 }