evolution-3.6.4/calendar/gui/ea-cal-view-event.c

Location Tool Test ID Function Issue
ea-cal-view-event.c:308:39 clang-analyzer Access to field 'icalcomp' results in a dereference of a null pointer (loaded from field 'comp_data')
ea-cal-view-event.c:308:39 clang-analyzer Access to field 'comp_data' results in a dereference of a null pointer (loaded from variable 'event')
ea-cal-view-event.c:308:39 clang-analyzer Access to field 'comp_data' results in a dereference of a null pointer (loaded from variable 'event')
ea-cal-view-event.c:308:39 clang-analyzer Access to field 'icalcomp' results in a dereference of a null pointer (loaded from field 'comp_data')
  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 "ea-cal-view-event.h"
 28 #include "ea-calendar-helpers.h"
 29 #include "ea-day-view.h"
 30 #include "ea-week-view.h"
 31 #include <text/e-text.h>
 32 #include <glib/gi18n.h>
 33 
 34 static void	ea_cal_view_event_class_init	(EaCalViewEventClass *klass);
 35 static void	ea_cal_view_event_init		(EaCalViewEvent *a11y);
 36 static void	ea_cal_view_event_dispose	(GObject *object);
 37 static const gchar *
 38 		ea_cal_view_event_get_name	(AtkObject *accessible);
 39 static const gchar *
 40 		ea_cal_view_event_get_description
 41 						(AtkObject *accessible);
 42 static AtkObject *
 43 		ea_cal_view_event_get_parent	(AtkObject *accessible);
 44 static gint	ea_cal_view_event_get_index_in_parent
 45 						(AtkObject *accessible);
 46 static AtkStateSet *
 47 		ea_cal_view_event_ref_state_set	(AtkObject *accessible);
 48 
 49 /* component interface */
 50 static void	atk_component_interface_init	(AtkComponentIface *iface);
 51 static void	ea_cal_view_get_extents		(AtkComponent *component,
 52 						 gint *x,
 53 						 gint *y,
 54 						 gint *width,
 55 						 gint *height,
 56 						 AtkCoordType coord_type);
 57 /* action interface */
 58 static void	atk_action_interface_init	(AtkActionIface *iface);
 59 static gboolean	ea_cal_view_event_do_action	(AtkAction *action,
 60 						 gint i);
 61 static gint	ea_cal_view_event_get_n_actions	(AtkAction *action);
 62 static const gchar *
 63 		ea_cal_view_event_action_get_name
 64 						(AtkAction *action,
 65 						 gint i);
 66 
 67 #ifdef ACC_DEBUG
 68 static gint n_ea_cal_view_event_created = 0;
 69 static gint n_ea_cal_view_event_destroyed = 0;
 70 static void ea_cal_view_finalize (GObject *object);
 71 #endif
 72 
 73 static gpointer parent_class = NULL;
 74 
 75 GType
 76 ea_cal_view_event_get_type (void)
 77 {
 78 	static GType type = 0;
 79 	AtkObjectFactory *factory;
 80 	GTypeQuery query;
 81 	GType derived_atk_type;
 82 
 83 	if (!type) {
 84 		static GTypeInfo tinfo = {
 85 			sizeof (EaCalViewEventClass),
 86 			(GBaseInitFunc) NULL, /* base init */
 87 			(GBaseFinalizeFunc) NULL, /* base finalize */
 88 			(GClassInitFunc) ea_cal_view_event_class_init, /* class init */
 89 			(GClassFinalizeFunc) NULL, /* class finalize */
 90 			NULL, /* class data */
 91 			sizeof (EaCalViewEvent), /* instance size */
 92 			0, /* nb preallocs */
 93 			(GInstanceInitFunc) ea_cal_view_event_init, /* instance init */
 94 			NULL /* value table */
 95 		};
 96 
 97 		static const GInterfaceInfo atk_component_info = {
 98 			(GInterfaceInitFunc) atk_component_interface_init,
 99 			(GInterfaceFinalizeFunc) NULL,
100 			NULL
101 		};
102 
103 		static const GInterfaceInfo atk_action_info = {
104 			(GInterfaceInitFunc) atk_action_interface_init,
105 			(GInterfaceFinalizeFunc) NULL,
106 			NULL
107 		};
108 
109 		/*
110 		 * Figure out the size of the class and instance
111 		 * we are run-time deriving from (atk object for E_TEXT, in this case)
112 		 */
113 
114 		factory = atk_registry_get_factory (
115 			atk_get_default_registry (),
116 			E_TYPE_TEXT);
117 		derived_atk_type = atk_object_factory_get_accessible_type (factory);
118 		g_type_query (derived_atk_type, &query);
119 
120 		tinfo.class_size = query.class_size;
121 		tinfo.instance_size = query.instance_size;
122 
123 		/* we inherit the component, text and other interfaces from E_TEXT */
124 		type = g_type_register_static (
125 			derived_atk_type,
126 			"EaCalViewEvent", &tinfo, 0);
127 		g_type_add_interface_static (
128 			type, ATK_TYPE_COMPONENT,
129 			&atk_component_info);
130 		g_type_add_interface_static (
131 			type, ATK_TYPE_ACTION,
132 			&atk_action_info);
133 
134 	}
135 
136 	return type;
137 }
138 
139 static void
140 ea_cal_view_event_class_init (EaCalViewEventClass *klass)
141 {
142 	AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
143 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
144 #ifdef ACC_DEBUG
145 	gobject_class->finalize = ea_cal_view_finalize;
146 #endif
147 
148 	parent_class = g_type_class_peek_parent (klass);
149 
150 	gobject_class->dispose = ea_cal_view_event_dispose;
151 
152 	class->get_name = ea_cal_view_event_get_name;
153 	class->get_description = ea_cal_view_event_get_description;
154 	class->get_parent = ea_cal_view_event_get_parent;
155 	class->get_index_in_parent = ea_cal_view_event_get_index_in_parent;
156 	class->ref_state_set = ea_cal_view_event_ref_state_set;
157 
158 }
159 
160 static void
161 ea_cal_view_event_init (EaCalViewEvent *a11y)
162 {
163 	a11y->state_set = atk_state_set_new ();
164 	atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT);
165 	atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED);
166 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE);
167 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE);
168 	atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING);
169 	atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE);
170 }
171 
172 #ifdef ACC_DEBUG
173 static void ea_cal_view_finalize (GObject *object)
174 {
175 	G_OBJECT_CLASS (parent_class)->finalize (object);
176 
177 	++n_ea_cal_view_event_destroyed;
178 	printf (
179 		"ACC_DEBUG: n_ea_cal_view_event_destroyed = %d\n",
180 		n_ea_cal_view_event_destroyed);
181 }
182 #endif
183 
184 AtkObject *
185 ea_cal_view_event_new (GObject *obj)
186 {
187 	AtkObject *atk_obj = NULL;
188 	GObject *target_obj;
189 	ECalendarView *cal_view;
190 
191 	g_return_val_if_fail (E_IS_TEXT (obj), NULL);
192 	cal_view = ea_calendar_helpers_get_cal_view_from (GNOME_CANVAS_ITEM (obj));
193 	if (!cal_view)
194 		return NULL;
195 
196 	if (E_IS_WEEK_VIEW (cal_view)) {
197 		gint event_num, span_num;
198 		EWeekViewEvent *week_view_event;
199 		EWeekViewEventSpan *event_span;
200 		EWeekView *week_view = E_WEEK_VIEW (cal_view);
201 
202 		/* for week view, we need to check if a atkobject exists for
203 		 * the first span of the same event
204 		 */
205 		if (!e_week_view_find_event_from_item (week_view,
206 						       GNOME_CANVAS_ITEM (obj),
207 						       &event_num,
208 						       &span_num))
209 			return NULL;
210 
211 		if (!is_array_index_in_bounds (week_view->events, event_num))
212 			return NULL;
213 
214 		week_view_event = &g_array_index (week_view->events,
215 						  EWeekViewEvent,
216 						  event_num);
217 
218 		if (!is_array_index_in_bounds (
219 			week_view->spans, week_view_event->spans_index))
220 			return NULL;
221 
222 		/* get the first span */
223 		event_span = &g_array_index (week_view->spans,
224 					     EWeekViewEventSpan,
225 					     week_view_event->spans_index);
226 		target_obj = G_OBJECT (event_span->text_item);
227 		atk_obj = g_object_get_data (target_obj, "accessible-object");
228 
229 	}
230 	else
231 		target_obj = obj;
232 
233 	if (!atk_obj) {
234 		static AtkRole event_role = ATK_ROLE_INVALID;
235 		atk_obj = ATK_OBJECT (
236 			g_object_new (EA_TYPE_CAL_VIEW_EVENT,
237 			NULL));
238 		atk_object_initialize (atk_obj, target_obj);
239 		if (event_role == ATK_ROLE_INVALID)
240 			event_role = atk_role_register ("Calendar Event");
241 		atk_obj->role = event_role;
242 #ifdef ACC_DEBUG
243 		++n_ea_cal_view_event_created;
244 		printf (
245 			"ACC_DEBUG: n_ea_cal_view_event_created = %d\n",
246 			n_ea_cal_view_event_created);
247 #endif
248 	}
249 
250 	/* the registered factory for E_TEXT is cannot create a EaCalViewEvent,
251 	 * we should save the EaCalViewEvent object in it.
252 	 */
253 	g_object_set_data (obj, "accessible-object", atk_obj);
254 
255 	return atk_obj;
256 }
257 
258 static void
259 ea_cal_view_event_dispose (GObject *object)
260 {
261 	EaCalViewEvent *a11y = EA_CAL_VIEW_EVENT (object);
262 
263 	if (a11y->state_set) {
264 		g_object_unref (a11y->state_set);
265 		a11y->state_set = NULL;
266 	}
267 
268 	/* Chain up to parent's dispose() method. */
269 	G_OBJECT_CLASS (parent_class)->dispose (object);
270 }
271 
272 static const gchar *
273 ea_cal_view_event_get_name (AtkObject *accessible)
274 {
275 	AtkGObjectAccessible *atk_gobj;
276 	GObject *g_obj;
277 	ECalendarViewEvent *event;
278 	gchar *name_string;
279 	const gchar *alarm_string;
280 	const gchar *recur_string;
281 	const gchar *meeting_string;
282 	gchar *summary_string;
283 	const gchar *summary;
284 
285 	g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL);
286 
287 	atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
288 	g_obj = atk_gobject_accessible_get_object (atk_gobj);
289 	if (!g_obj || !E_IS_TEXT (g_obj))
290 		return NULL;
291 	event = ea_calendar_helpers_get_cal_view_event_from (GNOME_CANVAS_ITEM (g_obj));
292 	if (!is_comp_data_valid (event))
293 		return NULL;
294 
295 	alarm_string = recur_string = meeting_string = "";
296 	if (event && event->comp_data) {
297 		if (e_cal_util_component_has_alarms (event->comp_data->icalcomp))
298 			alarm_string = _("It has reminders.");
299 
300 		if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp))
301 			recur_string = _("It has recurrences.");
302 
303 		if (e_cal_util_component_has_organizer (event->comp_data->icalcomp))
304 			meeting_string = _("It is a meeting.");
305 
306 	}
307 
308 	summary = icalcomponent_get_summary (event->comp_data->icalcomp);
Access to field 'icalcomp' results in a dereference of a null pointer (loaded from field 'comp_data')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'comp_data' results in a dereference of a null pointer (loaded from variable 'event')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'comp_data' results in a dereference of a null pointer (loaded from variable 'event')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

Access to field 'icalcomp' results in a dereference of a null pointer (loaded from field 'comp_data')
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

309 if (summary) 310 summary_string = g_strdup_printf ( 311 _("Calendar Event: Summary is %s."), summary); 312 else 313 summary_string = g_strdup ( 314 _("Calendar Event: It has no summary.")); 315 316 name_string = g_strdup_printf ( 317 "%s %s %s %s", summary_string, 318 alarm_string, recur_string, meeting_string); 319 g_free (summary_string); 320 321 ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_string); 322 #ifdef ACC_DEBUG 323 printf ( 324 "EvoAcc: name for event accobj=%p, is %s\n", 325 (gpointer) accessible, new_name); 326 #endif 327 g_free (name_string); 328 return accessible->name; 329 } 330 331 static const gchar * 332 ea_cal_view_event_get_description (AtkObject *accessible) 333 { 334 if (accessible->description) 335 return accessible->description; 336 337 return _("calendar view event"); 338 } 339 340 static AtkObject * 341 ea_cal_view_event_get_parent (AtkObject *accessible) 342 { 343 AtkGObjectAccessible *atk_gobj; 344 GObject *g_obj; 345 GnomeCanvasItem *canvas_item; 346 ECalendarView *cal_view; 347 348 g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL); 349 atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); 350 351 g_obj = atk_gobject_accessible_get_object (atk_gobj); 352 if (g_obj == NULL) 353 /* Object is defunct */ 354 return NULL; 355 canvas_item = GNOME_CANVAS_ITEM (g_obj); 356 357 cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); 358 359 if (!cal_view) 360 return NULL; 361 362 return gtk_widget_get_accessible (GTK_WIDGET (cal_view)); 363 } 364 365 static gint 366 ea_cal_view_event_get_index_in_parent (AtkObject *accessible) 367 { 368 GObject *g_obj; 369 GnomeCanvasItem *canvas_item; 370 ECalendarView *cal_view; 371 ECalendarViewEvent *cal_view_event; 372 373 g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), -1); 374 g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)); 375 if (!g_obj) 376 /* defunct object*/ 377 return -1; 378 379 canvas_item = GNOME_CANVAS_ITEM (g_obj); 380 cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); 381 if (!cal_view) 382 return -1; 383 384 cal_view_event = ea_calendar_helpers_get_cal_view_event_from (canvas_item); 385 if (!cal_view_event) 386 return -1; 387 388 if (E_IS_DAY_VIEW (cal_view)) { 389 gint day, event_num, num_before; 390 EDayViewEvent *day_view_event; 391 EDayView *day_view = E_DAY_VIEW (cal_view); 392 393 /* the long event comes first in the order */ 394 for (event_num = day_view->long_events->len - 1; event_num >= 0; 395 --event_num) { 396 day_view_event = &g_array_index (day_view->long_events, 397 EDayViewEvent, event_num); 398 if (cal_view_event == (ECalendarViewEvent *) day_view_event) 399 return event_num; 400 401 } 402 num_before = day_view->long_events->len; 403 404 for (day = 0; day < day_view->days_shown; ++day) { 405 for (event_num = day_view->events[day]->len - 1; event_num >= 0; 406 --event_num) { 407 day_view_event = &g_array_index (day_view->events[day], 408 EDayViewEvent, event_num); 409 if (cal_view_event == (ECalendarViewEvent *) day_view_event) 410 return num_before + event_num; 411 } 412 num_before += day_view->events[day]->len; 413 } 414 } 415 else if (E_IS_WEEK_VIEW (cal_view)) { 416 AtkObject *atk_parent, *atk_child; 417 gint index = 0; 418 419 atk_parent = atk_object_get_parent (accessible); 420 while ((atk_child = atk_object_ref_accessible_child (atk_parent, 421 index)) != NULL) { 422 if (atk_child == accessible) { 423 g_object_unref (atk_child); 424 return index; 425 } 426 g_object_unref (atk_child); 427 ++index; 428 } 429 } 430 else { 431 g_return_val_if_reached (-1); 432 } 433 return -1; 434 } 435 436 static AtkStateSet * 437 ea_cal_view_event_ref_state_set (AtkObject *accessible) 438 { 439 EaCalViewEvent *atk_event = EA_CAL_VIEW_EVENT (accessible); 440 441 g_return_val_if_fail (atk_event->state_set, NULL); 442 443 g_object_ref (atk_event->state_set); 444 445 return atk_event->state_set; 446 } 447 448 /* Atk Component Interface */ 449 450 static void 451 atk_component_interface_init (AtkComponentIface *iface) 452 { 453 g_return_if_fail (iface != NULL); 454 455 iface->get_extents = ea_cal_view_get_extents; 456 } 457 458 static void 459 ea_cal_view_get_extents (AtkComponent *component, 460 gint *x, 461 gint *y, 462 gint *width, 463 gint *height, 464 AtkCoordType coord_type) 465 { 466 GObject *g_obj; 467 GnomeCanvasItem *canvas_item; 468 gint x_window, y_window; 469 gint scroll_x, scroll_y; 470 ECalendarView *cal_view; 471 gint item_x, item_y, item_w, item_h; 472 GtkWidget *canvas = NULL; 473 GdkWindow *window; 474 475 g_return_if_fail (EA_IS_CAL_VIEW_EVENT (component)); 476 477 g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component)); 478 if (!g_obj) 479 /* defunct object*/ 480 return; 481 g_return_if_fail (E_IS_TEXT (g_obj)); 482 483 canvas_item = GNOME_CANVAS_ITEM (g_obj); 484 cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); 485 if (!cal_view) 486 return; 487 488 if (E_IS_DAY_VIEW (cal_view)) { 489 gint day, event_num; 490 491 if (!e_day_view_find_event_from_item (E_DAY_VIEW (cal_view), 492 canvas_item, 493 &day, &event_num)) 494 return; 495 if (day == E_DAY_VIEW_LONG_EVENT) { 496 gint start_day, end_day; 497 if (!e_day_view_get_long_event_position (E_DAY_VIEW (cal_view), 498 event_num, 499 &start_day, 500 &end_day, 501 &item_x, 502 &item_y, 503 &item_w, 504 &item_h)) 505 return; 506 canvas = E_DAY_VIEW (cal_view)->top_canvas; 507 } 508 else { 509 if (!e_day_view_get_event_position (E_DAY_VIEW (cal_view), day, 510 event_num, 511 &item_x, &item_y, 512 &item_w, &item_h)) 513 514 return; 515 canvas = E_DAY_VIEW (cal_view)->main_canvas; 516 } 517 } 518 else if (E_IS_WEEK_VIEW (cal_view)) { 519 gint event_num, span_num; 520 if (!e_week_view_find_event_from_item (E_WEEK_VIEW (cal_view), 521 canvas_item, &event_num, 522 &span_num)) 523 return; 524 525 if (!e_week_view_get_span_position (E_WEEK_VIEW (cal_view), 526 event_num, span_num, 527 &item_x, &item_y, &item_w)) 528 return; 529 item_h = E_WEEK_VIEW_ICON_HEIGHT; 530 canvas = E_WEEK_VIEW (cal_view)->main_canvas; 531 } 532 else 533 return; 534 535 if (!canvas) 536 return; 537 538 window = gtk_widget_get_window (canvas); 539 gdk_window_get_origin (window, &x_window, &y_window); 540 gnome_canvas_get_scroll_offsets (GNOME_CANVAS (canvas), &scroll_x, &scroll_y); 541 542 *x = item_x + x_window - scroll_x; 543 *y = item_y + y_window - scroll_y; 544 *width = item_w; 545 *height = item_h; 546 547 if (coord_type == ATK_XY_WINDOW) { 548 gint x_toplevel, y_toplevel; 549 550 window = gtk_widget_get_window (GTK_WIDGET (cal_view)); 551 window = gdk_window_get_toplevel (window); 552 gdk_window_get_origin (window, &x_toplevel, &y_toplevel); 553 554 *x -= x_toplevel; 555 *y -= y_toplevel; 556 } 557 558 #ifdef ACC_DEBUG 559 printf ("Event Bounds (%d, %d, %d, %d)\n", *x, *y, *width, *height); 560 #endif 561 } 562 563 #define CAL_VIEW_EVENT_ACTION_NUM 1 564 565 static const gchar * action_name[CAL_VIEW_EVENT_ACTION_NUM] = { 566 N_("Grab Focus") 567 }; 568 569 static void 570 atk_action_interface_init (AtkActionIface *iface) 571 { 572 g_return_if_fail (iface != NULL); 573 574 iface->do_action = ea_cal_view_event_do_action; 575 iface->get_n_actions = ea_cal_view_event_get_n_actions; 576 iface->get_name = ea_cal_view_event_action_get_name; 577 } 578 579 static gboolean 580 ea_cal_view_event_do_action (AtkAction *action, 581 gint i) 582 { 583 AtkGObjectAccessible *atk_gobj; 584 AtkComponent *atk_comp; 585 586 atk_gobj = ATK_GOBJECT_ACCESSIBLE (action); 587 588 if (i == 0) { 589 atk_comp = (AtkComponent *) atk_gobj; 590 return atk_component_grab_focus (atk_comp); 591 } 592 593 return FALSE; 594 595 } 596 597 static gint 598 ea_cal_view_event_get_n_actions (AtkAction *action) 599 { 600 return CAL_VIEW_EVENT_ACTION_NUM; 601 } 602 603 static const gchar * 604 ea_cal_view_event_action_get_name (AtkAction *action, 605 gint i) 606 { 607 if (i >= 0 && i < CAL_VIEW_EVENT_ACTION_NUM) 608 return action_name[i]; 609 return NULL; 610 }