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 * Bolian Yin <bolian.yin@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 <stdio.h>
28 #include <time.h>
29 #include <string.h>
30 #include <libgnomecanvas/gnome-canvas.h>
31 #include <e-util/e-util.h>
32 #include <glib/gi18n.h>
33
34 #include <libedataserver/libedataserver.h>
35
36 #include "ea-calendar-item.h"
37 #include "ea-calendar-cell.h"
38 #include "ea-cell-table.h"
39
40 #define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH
41
42 /* EaCalendarItem */
43 static void ea_calendar_item_class_init (EaCalendarItemClass *class);
44 static void ea_calendar_item_finalize (GObject *object);
45
46 static const gchar * ea_calendar_item_get_name (AtkObject *accessible);
47 static const gchar * ea_calendar_item_get_description (AtkObject *accessible);
48 static gint ea_calendar_item_get_n_children (AtkObject *accessible);
49 static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index);
50 static AtkStateSet * ea_calendar_item_ref_state_set (AtkObject *accessible);
51
52 /* atk table interface */
53 static void atk_table_interface_init (AtkTableIface *iface);
54 static gint table_interface_get_index_at (AtkTable *table,
55 gint row,
56 gint column);
57 static gint table_interface_get_column_at_index (AtkTable *table,
58 gint index);
59 static gint table_interface_get_row_at_index (AtkTable *table,
60 gint index);
61 static AtkObject * table_interface_ref_at (AtkTable *table,
62 gint row,
63 gint column);
64 static gint table_interface_get_n_rows (AtkTable *table);
65 static gint table_interface_get_n_columns (AtkTable *table);
66 static gint table_interface_get_column_extent_at (AtkTable *table,
67 gint row,
68 gint column);
69 static gint table_interface_get_row_extent_at (AtkTable *table,
70 gint row,
71 gint column);
72
73 static gboolean table_interface_is_row_selected (AtkTable *table,
74 gint row);
75 static gboolean table_interface_is_column_selected (AtkTable *table,
76 gint row);
77 static gboolean table_interface_is_selected (AtkTable *table,
78 gint row,
79 gint column);
80 static gint table_interface_get_selected_rows (AtkTable *table,
81 gint **rows_selected);
82 static gint table_interface_get_selected_columns (AtkTable *table,
83 gint **columns_selected);
84 static gboolean table_interface_add_row_selection (AtkTable *table, gint row);
85 static gboolean table_interface_remove_row_selection (AtkTable *table,
86 gint row);
87 static gboolean table_interface_add_column_selection (AtkTable *table,
88 gint column);
89 static gboolean table_interface_remove_column_selection (AtkTable *table,
90 gint column);
91 static AtkObject * table_interface_get_row_header (AtkTable *table, gint row);
92 static AtkObject * table_interface_get_column_header (AtkTable *table,
93 gint in_col);
94 static AtkObject * table_interface_get_caption (AtkTable *table);
95
96 static const gchar *
97 table_interface_get_column_description (AtkTable *table,
98 gint in_col);
99
100 static const gchar *
101 table_interface_get_row_description (AtkTable *table,
102 gint row);
103
104 static AtkObject *table_interface_get_summary (AtkTable *table);
105
106 /* atk selection interface */
107 static void atk_selection_interface_init (AtkSelectionIface *iface);
108 static gboolean selection_interface_add_selection (AtkSelection *selection,
109 gint i);
110 static gboolean selection_interface_clear_selection (AtkSelection *selection);
111 static AtkObject *selection_interface_ref_selection (AtkSelection *selection,
112 gint i);
113 static gint selection_interface_get_selection_count (AtkSelection *selection);
114 static gboolean selection_interface_is_child_selected (AtkSelection *selection,
115 gint i);
116
117 /* callbacks */
118 static void selection_preview_change_cb (ECalendarItem *calitem);
119 static void date_range_changed_cb (ECalendarItem *calitem);
120
121 /* helpers */
122 static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem);
123 static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem);
124 static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem,
125 gint column,
126 gchar *buffer,
127 gint buffer_size);
128 static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem,
129 gint row,
130 gchar *buffer,
131 gint buffer_size);
132 static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem,
133 gint year,
134 gint month,
135 gint day,
136 gint *offset);
137 static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem,
138 AtkObject *item_cell);
139
140 #ifdef ACC_DEBUG
141 static gint n_ea_calendar_item_created = 0;
142 static gint n_ea_calendar_item_destroyed = 0;
143 #endif
144
145 static gpointer parent_class = NULL;
146
147 GType
148 ea_calendar_item_get_type (void)
149 {
150 static GType type = 0;
151 AtkObjectFactory *factory;
152 GTypeQuery query;
153 GType derived_atk_type;
154
155 if (!type) {
156 static GTypeInfo tinfo = {
157 sizeof (EaCalendarItemClass),
158 (GBaseInitFunc) NULL, /* base init */
159 (GBaseFinalizeFunc) NULL, /* base finalize */
160 (GClassInitFunc) ea_calendar_item_class_init, /* class init */
161 (GClassFinalizeFunc) NULL, /* class finalize */
162 NULL, /* class data */
163 sizeof (EaCalendarItem), /* instance size */
164 0, /* nb preallocs */
165 (GInstanceInitFunc) NULL, /* instance init */
166 NULL /* value table */
167 };
168
169 static const GInterfaceInfo atk_table_info = {
170 (GInterfaceInitFunc) atk_table_interface_init,
171 (GInterfaceFinalizeFunc) NULL,
172 NULL
173 };
174 static const GInterfaceInfo atk_selection_info = {
175 (GInterfaceInitFunc) atk_selection_interface_init,
176 (GInterfaceFinalizeFunc) NULL,
177 NULL
178 };
179
180 /*
181 * Figure out the size of the class and instance
182 * we are run-time deriving from (GailCanvasItem, in this case)
183 */
184
185 factory = atk_registry_get_factory (
186 atk_get_default_registry (),
187 GNOME_TYPE_CANVAS_ITEM);
188 derived_atk_type = atk_object_factory_get_accessible_type (factory);
189 g_type_query (derived_atk_type, &query);
190
191 tinfo.class_size = query.class_size;
192 tinfo.instance_size = query.instance_size;
193
194 type = g_type_register_static (
195 derived_atk_type,
196 "EaCalendarItem", &tinfo, 0);
197 g_type_add_interface_static (
198 type, ATK_TYPE_TABLE,
199 &atk_table_info);
200 g_type_add_interface_static (
201 type, ATK_TYPE_SELECTION,
202 &atk_selection_info);
203 }
204
205 return type;
206 }
207
208 static void
209 ea_calendar_item_class_init (EaCalendarItemClass *klass)
210 {
211 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
212 AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
213
214 gobject_class->finalize = ea_calendar_item_finalize;
215 parent_class = g_type_class_peek_parent (klass);
216
217 class->get_name = ea_calendar_item_get_name;
218 class->get_description = ea_calendar_item_get_description;
219 class->ref_state_set = ea_calendar_item_ref_state_set;
220
221 class->get_n_children = ea_calendar_item_get_n_children;
222 class->ref_child = ea_calendar_item_ref_child;
223 }
224
225 AtkObject *
226 ea_calendar_item_new (GObject *obj)
227 {
228 gpointer object;
229 AtkObject *atk_object;
230 AtkObject *item_cell;
231
232 g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL);
233 object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL);
234 atk_object = ATK_OBJECT (object);
235 atk_object_initialize (atk_object, obj);
236 atk_object->role = ATK_ROLE_CALENDAR;
237
238 item_cell = atk_selection_ref_selection (
239 ATK_SELECTION (atk_object), 0);
240 if (item_cell)
241 ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell);
242
243 #ifdef ACC_DEBUG
244 ++n_ea_calendar_item_created;
245 g_print (
246 "ACC_DEBUG: n_ea_calendar_item_created = %d\n",
247 n_ea_calendar_item_created);
248 #endif
249 /* connect signal handlers */
250 g_signal_connect (
251 obj, "selection_preview_changed",
252 G_CALLBACK (selection_preview_change_cb), atk_object);
253 g_signal_connect (
254 obj, "date_range_changed",
255 G_CALLBACK (date_range_changed_cb), atk_object);
256
257 return atk_object;
258 }
259
260 static void
261 ea_calendar_item_finalize (GObject *object)
262 {
263 EaCalendarItem *ea_calitem;
264
265 g_return_if_fail (EA_IS_CALENDAR_ITEM (object));
266
267 ea_calitem = EA_CALENDAR_ITEM (object);
268
269 /* Free the allocated cell data */
270 ea_calendar_item_destory_cell_data (ea_calitem);
271
272 G_OBJECT_CLASS (parent_class)->finalize (object);
273 #ifdef ACC_DEBUG
274 ++n_ea_calendar_item_destroyed;
275 printf (
276 "ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n",
277 n_ea_calendar_item_destroyed);
278 #endif
279 }
280
281 static const gchar *
282 ea_calendar_item_get_name (AtkObject *accessible)
283 {
284 GObject *g_obj;
285 ECalendarItem *calitem;
286 gint start_year, start_month, start_day;
287 gint end_year, end_month, end_day;
288 gchar *name_str = NULL;
289 gchar buffer_start[128] = "";
290 gchar buffer_end[128] = "";
291 struct tm day_start = { 0 };
292 struct tm day_end = { 0 };
293
294 g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL);
295
296 g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
297 if (!g_obj)
298 return NULL;
299 g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL);
300
301 calitem = E_CALENDAR_ITEM (g_obj);
302 if (e_calendar_item_get_date_range (
303 calitem,
304 &start_year, &start_month, &start_day,
305 &end_year, &end_month, &end_day)) {
306
307 day_start.tm_year = start_year - 1900;
308 day_start.tm_mon = start_month;
309 day_start.tm_mday = start_day;
310 day_start.tm_isdst = -1;
311
312 e_utf8_strftime (
313 buffer_start, sizeof (buffer_start),
314 _("%d %B %Y"), &day_start);
315
316 day_end.tm_year = end_year - 1900;
317 day_end.tm_mon = end_month;
318 day_end.tm_mday = end_day;
319 day_end.tm_isdst = -1;
320
321 e_utf8_strftime (
322 buffer_end, sizeof (buffer_end),
323 _("%d %B %Y"), &day_end);
324
325 name_str = g_strdup_printf (
326 _("Calendar: from %s to %s"),
327 buffer_start, buffer_end);
328 }
329
330 #if 0
331 if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) {
332 GDate select_start, select_end;
333 gint year1, year2, month1, month2, day1, day2;
334
335 year1 = g_date_get_year (&select_start);
336 month1 = g_date_get_month (&select_start);
337 day1 = g_date_get_day (&select_start);
338
339 year2 = g_date_get_year (&select_end);
340 month2 = g_date_get_month (&select_end);
341 day2 = g_date_get_day (&select_end);
342
343 sprintf (
344 new_name + strlen (new_name),
345 " : current selection: from %d-%d-%d to %d-%d-%d.",
346 year1, month1, day1,
347 year2, month2, day2);
348 }
349 #endif
350
351 ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str);
352 g_free (name_str);
353
354 return accessible->name;
355 }
356
357 static const gchar *
358 ea_calendar_item_get_description (AtkObject *accessible)
359 {
360 if (accessible->description)
361 return accessible->description;
362
363 return _("evolution calendar item");
364 }
365
366 static AtkStateSet *
367 ea_calendar_item_ref_state_set (AtkObject *accessible)
368 {
369 AtkStateSet *state_set;
370 GObject *g_obj;
371
372 state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible);
373 g_obj = atk_gobject_accessible_get_object (
374 ATK_GOBJECT_ACCESSIBLE (accessible));
375 if (!g_obj)
376 return state_set;
377
378 atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
379 atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
380
381 return state_set;
382 }
383
384 static gint
385 ea_calendar_item_get_n_children (AtkObject *accessible)
386 {
387 AtkGObjectAccessible *atk_gobj;
388 GObject *g_obj;
389 ECalendarItem *calitem;
390 gint n_children = 0;
391 gint start_year, start_month, start_day;
392 gint end_year, end_month, end_day;
393 GDate *start_date, *end_date;
394
395 g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1);
396
397 atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
398 g_obj = atk_gobject_accessible_get_object (atk_gobj);
399 if (!g_obj)
400 return -1;
401
402 calitem = E_CALENDAR_ITEM (g_obj);
403 if (!e_calendar_item_get_date_range (calitem, &start_year,
404 &start_month, &start_day,
405 &end_year, &end_month,
406 &end_day))
407 return 0;
408
409 start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
410 end_date = g_date_new_dmy (end_day, end_month + 1, end_year);
411
412 n_children = g_date_days_between (start_date, end_date) + 1;
413 g_free (start_date);
414 g_free (end_date);
415 return n_children;
416 }
417
418 static AtkObject *
419 ea_calendar_item_ref_child (AtkObject *accessible,
420 gint index)
421 {
422 AtkGObjectAccessible *atk_gobj;
423 GObject *g_obj;
424 ECalendarItem *calitem;
425 gint n_children;
426 ECalendarCell *cell;
427 EaCellTable *cell_data;
428 EaCalendarItem *ea_calitem;
429
430 g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL);
431
432 atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
433 g_obj = atk_gobject_accessible_get_object (atk_gobj);
434 if (!g_obj)
435 return NULL;
436
437 calitem = E_CALENDAR_ITEM (g_obj);
438
439 n_children = ea_calendar_item_get_n_children (accessible);
440 if (index < 0 || index >= n_children)
441 return NULL;
442
443 ea_calitem = EA_CALENDAR_ITEM (accessible);
444 cell_data = ea_calendar_item_get_cell_data (ea_calitem);
445 if (!cell_data)
446 return NULL;
447
448 cell = ea_cell_table_get_cell_at_index (cell_data, index);
449 if (!cell) {
450 cell = e_calendar_cell_new (
451 calitem,
452 index / EA_CALENDAR_COLUMN_NUM,
453 index % EA_CALENDAR_COLUMN_NUM);
454 ea_cell_table_set_cell_at_index (cell_data, index, cell);
455 g_object_unref (cell);
456 }
457
458 #ifdef ACC_DEBUG
459 g_print (
460 "AccDebug: ea_calendar_item children[%d]=%p\n", index,
461 (gpointer) cell);
462 #endif
463 return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT (cell)));
464 }
465
466 /* atk table interface */
467
468 static void
469 atk_table_interface_init (AtkTableIface *iface)
470 {
471 g_return_if_fail (iface != NULL);
472
473 iface->ref_at = table_interface_ref_at;
474
475 iface->get_n_rows = table_interface_get_n_rows;
476 iface->get_n_columns = table_interface_get_n_columns;
477 iface->get_index_at = table_interface_get_index_at;
478 iface->get_column_at_index = table_interface_get_column_at_index;
479 iface->get_row_at_index = table_interface_get_row_at_index;
480 iface->get_column_extent_at = table_interface_get_column_extent_at;
481 iface->get_row_extent_at = table_interface_get_row_extent_at;
482
483 iface->is_selected = table_interface_is_selected;
484 iface->get_selected_rows = table_interface_get_selected_rows;
485 iface->get_selected_columns = table_interface_get_selected_columns;
486 iface->is_row_selected = table_interface_is_row_selected;
487 iface->is_column_selected = table_interface_is_column_selected;
488 iface->add_row_selection = table_interface_add_row_selection;
489 iface->remove_row_selection = table_interface_remove_row_selection;
490 iface->add_column_selection = table_interface_add_column_selection;
491 iface->remove_column_selection = table_interface_remove_column_selection;
492
493 iface->get_row_header = table_interface_get_row_header;
494 iface->get_column_header = table_interface_get_column_header;
495 iface->get_caption = table_interface_get_caption;
496 iface->get_summary = table_interface_get_summary;
497 iface->get_row_description = table_interface_get_row_description;
498 iface->get_column_description = table_interface_get_column_description;
499 }
500
501 static AtkObject *
502 table_interface_ref_at (AtkTable *table,
503 gint row,
504 gint column)
505 {
506 gint index;
507
508 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
509 index = EA_CALENDAR_COLUMN_NUM * row + column;
510 return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index);
511 }
512
513 static gint
514 table_interface_get_n_rows (AtkTable *table)
515 {
516 AtkGObjectAccessible *atk_gobj;
517 GObject *g_obj;
518 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
519 gint n_children;
520
521 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
522 g_obj = atk_gobject_accessible_get_object (atk_gobj);
523 if (!g_obj)
524 return -1;
525
526 n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
527 return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1;
528 }
529
530 static gint
531 table_interface_get_n_columns (AtkTable *table)
532 {
533 AtkGObjectAccessible *atk_gobj;
534 GObject *g_obj;
535 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
536
537 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
538 g_obj = atk_gobject_accessible_get_object (atk_gobj);
539 if (!g_obj)
540 return -1;
541
542 return EA_CALENDAR_COLUMN_NUM;
543 }
544
545 static gint
546 table_interface_get_index_at (AtkTable *table,
547 gint row,
548 gint column)
549 {
550 AtkGObjectAccessible *atk_gobj;
551 GObject *g_obj;
552 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
553
554 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
555 g_obj = atk_gobject_accessible_get_object (atk_gobj);
556 if (!g_obj)
557 return -1;
558
559 return row * EA_CALENDAR_COLUMN_NUM + column;
560 }
561
562 static gint
563 table_interface_get_column_at_index (AtkTable *table,
564 gint index)
565 {
566 AtkGObjectAccessible *atk_gobj;
567 GObject *g_obj;
568 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
569 gint n_children;
570
571 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
572 g_obj = atk_gobject_accessible_get_object (atk_gobj);
573 if (!g_obj)
574 return -1;
575
576 n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
577 if (index >= 0 && index < n_children)
578 return index % EA_CALENDAR_COLUMN_NUM;
579 return -1;
580 }
581
582 static gint
583 table_interface_get_row_at_index (AtkTable *table,
584 gint index)
585 {
586 AtkGObjectAccessible *atk_gobj;
587 GObject *g_obj;
588 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
589 gint n_children;
590
591 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
592 g_obj = atk_gobject_accessible_get_object (atk_gobj);
593 if (!g_obj)
594 return -1;
595
596 n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
597 if (index >= 0 && index < n_children)
598 return index / EA_CALENDAR_COLUMN_NUM;
599 return -1;
600 }
601
602 static gint
603 table_interface_get_column_extent_at (AtkTable *table,
604 gint row,
605 gint column)
606 {
607 AtkGObjectAccessible *atk_gobj;
608 GObject *g_obj;
609 ECalendarItem *calitem;
610 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
611
612 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
613 g_obj = atk_gobject_accessible_get_object (atk_gobj);
614 if (!g_obj)
615 return FALSE;
616
617 calitem = E_CALENDAR_ITEM (g_obj);
618 return calitem->cell_width;
619 }
620
621 static gint
622 table_interface_get_row_extent_at (AtkTable *table,
623 gint row,
624 gint column)
625 {
626 AtkGObjectAccessible *atk_gobj;
627 GObject *g_obj;
628 ECalendarItem *calitem;
629 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
630
631 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
632 g_obj = atk_gobject_accessible_get_object (atk_gobj);
633 if (!g_obj)
634 return FALSE;
635
636 calitem = E_CALENDAR_ITEM (g_obj);
637 return calitem->cell_height;
638 }
639
640 /* any day in the row is selected, the row is selected */
641 static gboolean
642 table_interface_is_row_selected (AtkTable *table,
643 gint row)
644 {
645 AtkGObjectAccessible *atk_gobj;
646 GObject *g_obj;
647 gint n_rows;
648 ECalendarItem *calitem;
649 gint row_index_start, row_index_end;
650 gint sel_index_start, sel_index_end;
651
652 GDate start_date, end_date;
653
654 g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE);
655
656 atk_gobj = ATK_GOBJECT_ACCESSIBLE (table);
657 g_obj = atk_gobject_accessible_get_object (atk_gobj);
658 if (!g_obj)
659 return FALSE;
660
661 n_rows = table_interface_get_n_rows (table);
662 if (row < 0 || row >= n_rows)
663 return FALSE;
664
665 row_index_start = row * EA_CALENDAR_COLUMN_NUM;
666 row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1;
667
668 calitem = E_CALENDAR_ITEM (g_obj);
669 if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
670 return FALSE;
671
672 e_calendar_item_get_offset_for_date (calitem,
673 g_date_get_year (&start_date),
674 g_date_get_month (&start_date),
675 g_date_get_day (&start_date),
676 &sel_index_start);
677 e_calendar_item_get_offset_for_date (calitem,
678 g_date_get_year (&end_date),
679 g_date_get_month (&end_date),
680 g_date_get_day (&end_date),
681 &sel_index_end);
682
683 if ((sel_index_start < row_index_start &&
684 sel_index_end >= row_index_start) ||
685 (sel_index_start >= row_index_start &&
686 sel_index_start <= row_index_end))
687 return TRUE;
688 return FALSE;
689 }
690
691 static gboolean
692 table_interface_is_selected (AtkTable *table,
693 gint row,
694 gint column)
695 {
696 AtkGObjectAccessible *atk_gobj;
697 GObject *g_obj;
698 gint n_rows, n_columns;
699 ECalendarItem *calitem;
700 gint index;
701 gint sel_index_start, sel_index_end;
702
703 GDate start_date, end_date;
704
705 g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE);
706
707 atk_gobj = ATK_GOBJECT_ACCESSIBLE (table);
708 g_obj = atk_gobject_accessible_get_object (atk_gobj);
709 if (!g_obj)
710 return FALSE;
711
712 n_rows = table_interface_get_n_rows (table);
713 if (row < 0 || row >= n_rows)
714 return FALSE;
715 n_columns = table_interface_get_n_columns (table);
716 if (column < 0 || column >= n_columns)
717 return FALSE;
718
719 index = table_interface_get_index_at (table, row, column);
720
721 calitem = E_CALENDAR_ITEM (g_obj);
722 if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
723 return FALSE;
724
725 e_calendar_item_get_offset_for_date (calitem,
726 g_date_get_year (&start_date),
727 g_date_get_month (&start_date),
728 g_date_get_day (&start_date),
729 &sel_index_start);
730 e_calendar_item_get_offset_for_date (calitem,
731 g_date_get_year (&end_date),
732 g_date_get_month (&end_date),
733 g_date_get_day (&end_date), &sel_index_end);
734
735 if (sel_index_start <= index && sel_index_end >= index)
736 return TRUE;
737 return FALSE;
738 }
739
740 static gboolean
741 table_interface_is_column_selected (AtkTable *table,
742 gint column)
743 {
744 return FALSE;
745 }
746
747 static gint
748 table_interface_get_selected_rows (AtkTable *table,
749 gint **rows_selected)
750 {
751 *rows_selected = NULL;
752 return -1;
753 }
754
755 static gint
756 table_interface_get_selected_columns (AtkTable *table,
757 gint **columns_selected)
758 {
759 *columns_selected = NULL;
760 return -1;
761 }
762
763 static gboolean
764 table_interface_add_row_selection (AtkTable *table,
765 gint row)
766 {
767 return FALSE;
768 }
769
770 static gboolean
771 table_interface_remove_row_selection (AtkTable *table,
772 gint row)
773 {
774 return FALSE;
775 }
776
777 static gboolean
778 table_interface_add_column_selection (AtkTable *table,
779 gint column)
780 {
781 return FALSE;
782 }
783
784 static gboolean
785 table_interface_remove_column_selection (AtkTable *table,
786 gint column)
787 {
788 /* FIXME: NOT IMPLEMENTED */
789 return FALSE;
790 }
791
792 static AtkObject *
793 table_interface_get_row_header (AtkTable *table,
794 gint row)
795 {
796 /* FIXME: NOT IMPLEMENTED */
797 return NULL;
798 }
799
800 static AtkObject *
801 table_interface_get_column_header (AtkTable *table,
802 gint in_col)
803 {
804 /* FIXME: NOT IMPLEMENTED */
805 return NULL;
806 }
807
808 static AtkObject *
809 table_interface_get_caption (AtkTable *table)
810 {
811 /* FIXME: NOT IMPLEMENTED */
812 return NULL;
813 }
814
815 static const gchar *
816 table_interface_get_column_description (AtkTable *table,
817 gint in_col)
818 {
819 AtkGObjectAccessible *atk_gobj;
820 GObject *g_obj;
821 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
822 const gchar *description = NULL;
823 EaCellTable *cell_data;
824 gint n_columns;
825
826 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
827 g_obj = atk_gobject_accessible_get_object (atk_gobj);
828 if (!g_obj)
829 return NULL;
830
831 n_columns = table_interface_get_n_columns (table);
832 if (in_col < 0 || in_col >= n_columns)
833 return NULL;
834 cell_data = ea_calendar_item_get_cell_data (ea_calitem);
835 if (!cell_data)
836 return NULL;
837
838 description = ea_cell_table_get_column_label (cell_data, in_col);
839 if (!description) {
840 gchar buffer[128] = "column description";
841 ea_calendar_item_get_column_label (
842 ea_calitem, in_col,
843 buffer, sizeof (buffer));
844 ea_cell_table_set_column_label (cell_data, in_col, buffer);
845 description = ea_cell_table_get_column_label (
846 cell_data, in_col);
847 }
848 return description;
849 }
850
851 static const gchar *
852 table_interface_get_row_description (AtkTable *table,
853 gint row)
854 {
855 AtkGObjectAccessible *atk_gobj;
856 GObject *g_obj;
857 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (table);
858 const gchar *description = NULL;
859 EaCellTable *cell_data;
860 gint n_rows;
861
862 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
863 g_obj = atk_gobject_accessible_get_object (atk_gobj);
864 if (!g_obj)
865 return NULL;
866
867 n_rows = table_interface_get_n_rows (table);
868 if (row < 0 || row >= n_rows)
869 return NULL;
870 cell_data = ea_calendar_item_get_cell_data (ea_calitem);
871 if (!cell_data)
872 return NULL;
873
874 description = ea_cell_table_get_row_label (cell_data, row);
875 if (!description) {
876 gchar buffer[128] = "row description";
877 ea_calendar_item_get_row_label (
878 ea_calitem, row,
879 buffer, sizeof (buffer));
880 ea_cell_table_set_row_label (cell_data, row, buffer);
881 description = ea_cell_table_get_row_label (
882 cell_data,
883 row);
884 }
885 return description;
886 }
887
888 static AtkObject *
889 table_interface_get_summary (AtkTable *table)
890 {
891 /* FIXME: NOT IMPLEMENTED */
892 return NULL;
893 }
894
895 /* atkselection interface */
896
897 static void
898 atk_selection_interface_init (AtkSelectionIface *iface)
899 {
900 g_return_if_fail (iface != NULL);
901
902 iface->add_selection = selection_interface_add_selection;
903 iface->clear_selection = selection_interface_clear_selection;
904 iface->ref_selection = selection_interface_ref_selection;
905 iface->get_selection_count = selection_interface_get_selection_count;
906 iface->is_child_selected = selection_interface_is_child_selected;
907 }
908
909 static gboolean
910 selection_interface_add_selection (AtkSelection *selection,
911 gint index)
912 {
913 AtkGObjectAccessible *atk_gobj;
914 GObject *g_obj;
915 ECalendarItem *calitem;
916 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection);
917 gint year, month, day;
918 GDate start_date, end_date;
919
920 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
921 g_obj = atk_gobject_accessible_get_object (atk_gobj);
922 if (!g_obj)
923 return FALSE;
924
925 calitem = E_CALENDAR_ITEM (g_obj);
926 if (!e_calendar_item_get_date_for_offset (calitem, index,
927 &year, &month, &day))
928 return FALSE;
929
930 /* FIXME: not support mulit-selection */
931 g_date_set_dmy (&start_date, day, month + 1, year);
932 end_date = start_date;
933 e_calendar_item_set_selection (calitem, &start_date, &end_date);
934 return TRUE;
935 }
936
937 static gboolean
938 selection_interface_clear_selection (AtkSelection *selection)
939 {
940 AtkGObjectAccessible *atk_gobj;
941 GObject *g_obj;
942 ECalendarItem *calitem;
943 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection);
944
945 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
946 g_obj = atk_gobject_accessible_get_object (atk_gobj);
947 if (!g_obj)
948 return FALSE;
949
950 calitem = E_CALENDAR_ITEM (g_obj);
951 e_calendar_item_set_selection (calitem, NULL, NULL);
952
953 return TRUE;
954 }
955
956 static AtkObject *
957 selection_interface_ref_selection (AtkSelection *selection,
958 gint i)
959 {
960 GObject *g_obj;
961 ECalendarItem *calitem;
962 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection);
963 gint count, sel_offset;
964 GDate start_date, end_date;
965
966 count = selection_interface_get_selection_count (selection);
967 if (i < 0 || i >= count)
968 return NULL;
969
970 g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem));
971
972 calitem = E_CALENDAR_ITEM (g_obj);
973 if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
974 return NULL;
975 if (!e_calendar_item_get_offset_for_date (calitem,
976 g_date_get_year (&start_date),
977 g_date_get_month (&start_date) - 1,
978 g_date_get_day (&start_date),
979 &sel_offset))
980 return NULL;
981
982 return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i);
983 }
984
985 static gint
986 selection_interface_get_selection_count (AtkSelection *selection)
987 {
988 AtkGObjectAccessible *atk_gobj;
989 GObject *g_obj;
990 ECalendarItem *calitem;
991 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection);
992 GDate start_date, end_date;
993
994 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
995 g_obj = atk_gobject_accessible_get_object (atk_gobj);
996 if (!g_obj)
997 return 0;
998
999 calitem = E_CALENDAR_ITEM (g_obj);
1000 if (e_calendar_item_get_selection (calitem, &start_date, &end_date))
1001 return g_date_days_between (&start_date, &end_date) + 1;
1002 else
1003 return 0;
1004 }
1005
1006 static gboolean
1007 selection_interface_is_child_selected (AtkSelection *selection,
1008 gint index)
1009 {
1010 AtkGObjectAccessible *atk_gobj;
1011 GObject *g_obj;
1012 EaCalendarItem * ea_calitem = EA_CALENDAR_ITEM (selection);
1013 gint row, column, n_children;
1014
1015 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
1016 g_obj = atk_gobject_accessible_get_object (atk_gobj);
1017 if (!g_obj)
1018 return FALSE;
1019
1020 n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
1021 if (index < 0 || index >= n_children)
1022 return FALSE;
1023
1024 row = index / EA_CALENDAR_COLUMN_NUM;
1025 column = index % EA_CALENDAR_COLUMN_NUM;
1026
1027 return table_interface_is_selected (ATK_TABLE (selection), row, column);
1028 }
1029
1030 /* callbacks */
1031
1032 static void
1033 selection_preview_change_cb (ECalendarItem *calitem)
1034 {
1035 AtkObject *atk_obj;
1036 AtkObject *item_cell;
1037
1038 g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
1039 atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
1040 ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj));
1041
1042 /* only deal with the first selected child, for now */
1043 item_cell = atk_selection_ref_selection (
1044 ATK_SELECTION (atk_obj), 0);
1045
1046 if (item_cell)
1047 ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell);
1048
1049 g_signal_emit_by_name (
1050 atk_obj,
1051 "active-descendant-changed",
1052 item_cell);
1053 g_signal_emit_by_name (atk_obj, "selection_changed");
1054 }
1055
1056 static void
1057 date_range_changed_cb (ECalendarItem *calitem)
1058 {
1059 AtkObject *atk_obj;
1060 AtkObject *item_cell;
1061
1062 g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
1063 atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
1064 ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj));
1065
1066 item_cell = atk_selection_ref_selection (
1067 ATK_SELECTION (atk_obj), 0);
1068 if (item_cell)
1069 ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell);
1070
1071 g_signal_emit_by_name (atk_obj, "model_changed");
1072 }
1073
1074 /* helpers */
1075
1076 static EaCellTable *
1077 ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem)
1078 {
1079 AtkGObjectAccessible *atk_gobj;
1080 GObject *g_obj;
1081 EaCellTable *cell_data;
1082
1083 g_return_val_if_fail (ea_calitem, NULL);
1084
1085 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
1086 g_obj = atk_gobject_accessible_get_object (atk_gobj);
1087 if (!g_obj)
1088 return NULL;
1089
1090 cell_data = g_object_get_data (
1091 G_OBJECT (ea_calitem),
1092 "ea-calendar-cell-table");
1093
1094 if (!cell_data) {
1095 gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
1096 cell_data = ea_cell_table_create (
1097 n_cells / EA_CALENDAR_COLUMN_NUM,
1098 EA_CALENDAR_COLUMN_NUM,
1099 FALSE);
1100 g_object_set_data (
1101 G_OBJECT (ea_calitem),
1102 "ea-calendar-cell-table", cell_data);
1103 }
1104 return cell_data;
1105 }
1106
1107 static void
1108 ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem)
1109 {
1110 EaCellTable *cell_data;
1111
1112 g_return_if_fail (ea_calitem);
1113
1114 cell_data = g_object_get_data (
1115 G_OBJECT (ea_calitem),
1116 "ea-calendar-cell-table");
1117 if (cell_data) {
1118 g_object_set_data (
1119 G_OBJECT (ea_calitem),
1120 "ea-calendar-cell-table", NULL);
1121 ea_cell_table_destroy (cell_data);
1122 }
1123 }
1124
1125 static gboolean
1126 ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem,
1127 gint row,
1128 gchar *buffer,
1129 gint buffer_size)
1130 {
1131 AtkGObjectAccessible *atk_gobj;
1132 GObject *g_obj;
1133 ECalendarItem *calitem;
1134 gint index, week_num;
1135 gint year, month, day;
1136
1137 g_return_val_if_fail (ea_calitem, FALSE);
1138
1139 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
1140 g_obj = atk_gobject_accessible_get_object (atk_gobj);
1141 if (!g_obj)
1142 return FALSE;
1143
1144 calitem = E_CALENDAR_ITEM (g_obj);
1145
1146 index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0);
1147 if (!e_calendar_item_get_date_for_offset (calitem, index,
1148 &year, &month, &day))
1149 return FALSE;
1150
1151 week_num = e_calendar_item_get_week_number (
1152 calitem, day, month, year);
1153
1154 g_snprintf (buffer, buffer_size, "week number : %d", week_num);
1155 return TRUE;
1156 }
1157
1158 static gboolean
1159 ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem,
1160 gint column,
1161 gchar *buffer,
1162 gint buffer_size)
1163 {
1164 AtkGObjectAccessible *atk_gobj;
1165 GObject *g_obj;
1166 const gchar *abbr_name;
1167
1168 g_return_val_if_fail (ea_calitem, FALSE);
1169
1170 atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
1171 g_obj = atk_gobject_accessible_get_object (atk_gobj);
1172 if (!g_obj)
1173 return FALSE;
1174
1175 /* Columns are 0 = Monday ... 6 = Sunday */
1176 abbr_name = e_get_weekday_name (column + 1, TRUE);
1177 g_strlcpy (buffer, abbr_name, buffer_size);
1178
1179 return TRUE;
1180 }
1181
1182 /* the coordinate the e-calendar canvas coord */
1183 gboolean
1184 e_calendar_item_get_day_extents (ECalendarItem *calitem,
1185 gint year,
1186 gint month,
1187 gint date,
1188 gint *x,
1189 gint *y,
1190 gint *width,
1191 gint *height)
1192 {
1193 GnomeCanvasItem *item;
1194 GtkWidget *widget;
1195 GtkStyle *style;
1196 PangoFontDescription *font_desc;
1197 PangoContext *pango_context;
1198 PangoFontMetrics *font_metrics;
1199 gint char_height, xthickness, ythickness, text_y;
1200 gint new_year, new_month, num_months, months_offset;
1201 gint month_x, month_y, month_cell_x, month_cell_y;
1202 gint month_row, month_col;
1203 gint day_row, day_col;
1204 gint days_from_week_start;
1205
1206 g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
1207
1208 item = GNOME_CANVAS_ITEM (calitem);
1209 widget = GTK_WIDGET (item->canvas);
1210 style = gtk_widget_get_style (widget);
1211
1212 /* Set up Pango prerequisites */
1213 font_desc = calitem->font_desc;
1214 if (!font_desc)
1215 font_desc = style->font_desc;
1216 pango_context = gtk_widget_get_pango_context (widget);
1217 font_metrics = pango_context_get_metrics (
1218 pango_context, font_desc,
1219 pango_context_get_language (pango_context));
1220
1221 char_height =
1222 PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
1223 PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics));
1224
1225 xthickness = style->xthickness;
1226 ythickness = style->ythickness;
1227
1228 new_year = year;
1229 new_month = month;
1230 e_calendar_item_normalize_date (calitem, &new_year, &new_month);
1231 num_months = calitem->rows * calitem->cols;
1232 months_offset = (new_year - calitem->year) * 12
1233 + new_month - calitem->month;
1234
1235 if (months_offset > num_months || months_offset < 0)
1236 return FALSE;
1237
1238 month_row = months_offset / calitem->cols;
1239 month_col = months_offset % calitem->cols;
1240
1241 month_x = item->x1 + xthickness + calitem->x_offset
1242 + month_col * calitem->month_width;
1243 month_y = item->y1 + ythickness + month_row * calitem->month_height;
1244
1245 month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS
1246 + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS;
1247 text_y = month_y + ythickness * 2
1248 + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME
1249 + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME
1250 + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad;
1251
1252 month_cell_y = text_y + char_height
1253 + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1
1254 + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS;
1255
1256 days_from_week_start = e_calendar_item_get_n_days_from_week_start (
1257 calitem, new_year, new_month);
1258 day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM;
1259 day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM;
1260
1261 *x = month_cell_x + day_col * calitem->cell_width;
1262 *y = month_cell_y + day_row * calitem->cell_height;
1263 *width = calitem->cell_width;
1264 *height = calitem->cell_height;
1265
1266 return TRUE;
1267 }
1268
1269 /* month is from 0 to 11 */
1270 gboolean
1271 e_calendar_item_get_date_for_offset (ECalendarItem *calitem,
1272 gint day_offset,
1273 gint *year,
1274 gint *month,
1275 gint *day)
1276 {
1277 gint start_year, start_month, start_day;
1278 gint end_year, end_month, end_day;
1279 GDate *start_date;
1280
1281 g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
1282
1283 if (!e_calendar_item_get_date_range (calitem, &start_year,
1284 &start_month, &start_day,
1285 &end_year, &end_month,
1286 &end_day))
1287 return FALSE;
1288
1289 start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
1290
1291 g_date_add_days (start_date, day_offset);
1292
1293 *year = g_date_get_year (start_date);
1294 *month = g_date_get_month (start_date) - 1;
1295 *day = g_date_get_day (start_date);
1296
1297 return TRUE;
1298 }
1299
1300 /* the arg month is from 0 to 11 */
1301 static gboolean
1302 e_calendar_item_get_offset_for_date (ECalendarItem *calitem,
1303 gint year,
1304 gint month,
1305 gint day,
1306 gint *offset)
1307 {
1308 gint start_year, start_month, start_day;
1309 gint end_year, end_month, end_day;
1310 GDate *start_date, *end_date;
1311
1312 *offset = 0;
1313 g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
1314
1315 if (!e_calendar_item_get_date_range (calitem, &start_year,
1316 &start_month, &start_day,
1317 &end_year, &end_month,
1318 &end_day))
1319 return FALSE;
1320
1321 start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
1322 end_date = g_date_new_dmy (day, month + 1, year);
1323
1324 *offset = g_date_days_between (start_date, end_date);
1325 g_free (start_date);
1326 g_free (end_date);
1327
1328 return TRUE;
1329 }
1330
1331 gint
1332 e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem,
1333 gint year,
1334 gint month)
1335 {
1336 struct tm tmp_tm;
1337 gint start_weekday, days_from_week_start;
1338
1339 memset (&tmp_tm, 0, sizeof (tmp_tm));
1340 tmp_tm.tm_year = year - 1900;
1341 tmp_tm.tm_mon = month;
1342 tmp_tm.tm_mday = 1;
1343 tmp_tm.tm_isdst = -1;
1344 mktime (&tmp_tm);
1345 start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */
1346 days_from_week_start = (start_weekday + 7 - calitem->week_start_day)
1347 % 7;
1348 return days_from_week_start;
1349 }
1350
1351 static void
1352 ea_calendar_set_focus_object (EaCalendarItem *ea_calitem,
1353 AtkObject *item_cell)
1354 {
1355 AtkStateSet *state_set, *old_state_set;
1356 AtkObject *old_cell;
1357
1358 old_cell = (AtkObject *) g_object_get_data (
1359 G_OBJECT (ea_calitem), "gail-focus-object");
1360 if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) {
1361 old_state_set = atk_object_ref_state_set (old_cell);
1362 atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED);
1363 g_object_unref (old_state_set);
1364 }
1365 if (old_cell)
1366 g_object_unref (old_cell);
1367
1368 state_set = atk_object_ref_state_set (item_cell);
1369 atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
1370 g_object_set_data (G_OBJECT (ea_calitem), "gail-focus-object", item_cell);
1371 g_object_unref (state_set);
1372 }