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 }