evolution-3.6.4/calendar/gui/e-cal-model-calendar.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-cal-model-calendar.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-cal-model-calendar.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * Evolution calendar - Data model for ETable
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  *
 18  * Authors:
 19  *		Rodrigo Moya <rodrigo@ximian.com>
 20  *
 21  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 22  *
 23  */
 24 
 25 #ifdef HAVE_CONFIG_H
 26 #include <config.h>
 27 #endif
 28 
 29 #include <string.h>
 30 #include <glib/gi18n.h>
 31 #include "e-cal-model-calendar.h"
 32 #include "e-cell-date-edit-text.h"
 33 #include "itip-utils.h"
 34 #include "misc.h"
 35 #include "dialogs/recur-comp.h"
 36 #include "dialogs/send-comp.h"
 37 
 38 static gint ecmc_column_count (ETableModel *etm);
 39 static gpointer ecmc_value_at (ETableModel *etm, gint col, gint row);
 40 static void ecmc_set_value_at (ETableModel *etm, gint col, gint row, gconstpointer value);
 41 static gboolean ecmc_is_cell_editable (ETableModel *etm, gint col, gint row);
 42 static gpointer ecmc_duplicate_value (ETableModel *etm, gint col, gconstpointer value);
 43 static void ecmc_free_value (ETableModel *etm, gint col, gpointer value);
 44 static gpointer ecmc_initialize_value (ETableModel *etm, gint col);
 45 static gboolean ecmc_value_is_empty (ETableModel *etm, gint col, gconstpointer value);
 46 static gchar *ecmc_value_to_string (ETableModel *etm, gint col, gconstpointer value);
 47 
 48 static void ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
 49 					    ETableModel *source_model, gint row);
 50 
 51 G_DEFINE_TYPE (ECalModelCalendar, e_cal_model_calendar, E_TYPE_CAL_MODEL)
 52 
 53 static void
 54 e_cal_model_calendar_class_init (ECalModelCalendarClass *class)
 55 {
 56 	ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (class);
 57 	ECalModelClass *model_class = E_CAL_MODEL_CLASS (class);
 58 
 59 	etm_class->column_count = ecmc_column_count;
 60 	etm_class->value_at = ecmc_value_at;
 61 	etm_class->set_value_at = ecmc_set_value_at;
 62 	etm_class->is_cell_editable = ecmc_is_cell_editable;
 63 	etm_class->duplicate_value = ecmc_duplicate_value;
 64 	etm_class->free_value = ecmc_free_value;
 65 	etm_class->initialize_value = ecmc_initialize_value;
 66 	etm_class->value_is_empty = ecmc_value_is_empty;
 67 	etm_class->value_to_string = ecmc_value_to_string;
 68 
 69 	model_class->fill_component_from_model = ecmc_fill_component_from_model;
 70 }
 71 
 72 static void
 73 e_cal_model_calendar_init (ECalModelCalendar *model)
 74 {
 75 	e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VEVENT_COMPONENT);
 76 }
 77 
 78 /* ETableModel methods */
 79 static gint
 80 ecmc_column_count (ETableModel *etm)
 81 {
 82 	return E_CAL_MODEL_CALENDAR_FIELD_LAST;
 83 }
 84 
 85 static ECellDateEditValue *
 86 get_dtend (ECalModelCalendar *model,
 87            ECalModelComponent *comp_data)
 88 {
 89 	struct icaltimetype tt_end;
 90 
 91 	if (!comp_data->dtend) {
 92 		icalproperty *prop;
 93 		icaltimezone *zone = NULL, *model_zone = NULL;
 94 		gboolean got_zone = FALSE;
 95 
 96 		prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTEND_PROPERTY);
 97 		if (!prop)
 98 			return NULL;
 99 
100 		tt_end = icalproperty_get_dtend (prop);
101 
102 		if (icaltime_get_tzid (tt_end)
103 		    && e_cal_client_get_timezone_sync (comp_data->client, icaltime_get_tzid (tt_end), &zone, NULL, NULL))
104 			got_zone = TRUE;
105 
106 		model_zone = e_cal_model_get_timezone (E_CAL_MODEL (model));
107 
108 		if (e_cal_model_get_flags (E_CAL_MODEL (model)) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) {
109 			if (got_zone) {
110 				tt_end = icaltime_from_timet_with_zone (comp_data->instance_end, tt_end.is_date, zone);
111 				if (model_zone)
112 					icaltimezone_convert_time (&tt_end, zone, model_zone);
113 			} else
114 				tt_end = icaltime_from_timet_with_zone (
115 					comp_data->instance_end,
116 					tt_end.is_date, model_zone);
117 		}
118 
119 		if (!icaltime_is_valid_time (tt_end) || icaltime_is_null_time (tt_end))
120 			return NULL;
121 
122 		comp_data->dtend = g_new0 (ECellDateEditValue, 1);
123 		comp_data->dtend->tt = tt_end;
124 
125 		if (got_zone)
126 			comp_data->dtend->zone = zone;
127 		else
128 			comp_data->dtend->zone = NULL;
129 	}
130 
131 	return comp_data->dtend;
132 }
133 
134 static gpointer
135 get_location (ECalModelComponent *comp_data)
136 {
137 	icalproperty *prop;
138 
139 	prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY);
140 	if (prop)
141 		return (gpointer) icalproperty_get_location (prop);
142 
143 	return (gpointer) "";
144 }
145 
146 static gpointer
147 get_transparency (ECalModelComponent *comp_data)
148 {
149 	icalproperty *prop;
150 
151 	prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY);
152 	if (prop) {
153 		icalproperty_transp transp;
154 
155 		transp = icalproperty_get_transp (prop);
156 		if (transp == ICAL_TRANSP_TRANSPARENT ||
157 		    transp == ICAL_TRANSP_TRANSPARENTNOCONFLICT)
158 			return _("Free");
159 		else if (transp == ICAL_TRANSP_OPAQUE ||
160 			 transp == ICAL_TRANSP_OPAQUENOCONFLICT)
161 			return _("Busy");
162 	}
163 
164 	return NULL;
165 }
166 
167 static gpointer
168 ecmc_value_at (ETableModel *etm,
169                gint col,
170                gint row)
171 {
172 	ECalModelComponent *comp_data;
173 	ECalModelCalendar *model = (ECalModelCalendar *) etm;
174 
175 	g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), NULL);
176 
177 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
178 	g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL);
179 
180 	if (col < E_CAL_MODEL_FIELD_LAST)
181 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->value_at (etm, col, row);
182 
183 	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
184 	if (!comp_data)
185 		return (gpointer) "";
186 
187 	switch (col) {
188 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
189 		return get_dtend (model, comp_data);
190 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
191 		return get_location (comp_data);
192 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
193 		return get_transparency (comp_data);
194 	}
195 
196 	return (gpointer) "";
197 }
198 
199 static void
200 set_dtend (ECalModel *model,
201            ECalModelComponent *comp_data,
202            gconstpointer value)
203 {
204 	e_cal_model_update_comp_time (model, comp_data, value, ICAL_DTEND_PROPERTY, icalproperty_set_dtend, icalproperty_new_dtend);
205 }
206 
207 static void
208 set_location (ECalModelComponent *comp_data,
209               gconstpointer value)
210 {
211 	icalproperty *prop;
212 
213 	prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY);
214 
215 	if (string_is_empty (value)) {
216 		if (prop) {
217 			icalcomponent_remove_property (comp_data->icalcomp, prop);
218 			icalproperty_free (prop);
219 		}
220 	} else {
221 		if (prop)
222 			icalproperty_set_location (prop, (const gchar *) value);
223 		else {
224 			prop = icalproperty_new_location ((const gchar *) value);
225 			icalcomponent_add_property (comp_data->icalcomp, prop);
226 		}
227 	}
228 }
229 
230 static void
231 set_transparency (ECalModelComponent *comp_data,
232                   gconstpointer value)
233 {
234 	icalproperty *prop;
235 
236 	prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY);
237 
238 	if (string_is_empty (value)) {
239 		if (prop) {
240 			icalcomponent_remove_property (comp_data->icalcomp, prop);
241 			icalproperty_free (prop);
242 		}
243 	} else {
244 		icalproperty_transp transp;
245 
246 		if (!g_ascii_strcasecmp (value, "FREE"))
247 			transp = ICAL_TRANSP_TRANSPARENT;
248 		else if (!g_ascii_strcasecmp (value, "OPAQUE"))
249 			transp = ICAL_TRANSP_OPAQUE;
250 		else {
251 			if (prop) {
252 				icalcomponent_remove_property (comp_data->icalcomp, prop);
253 				icalproperty_free (prop);
254 			}
255 
256 			return;
257 		}
258 
259 		if (prop)
260 			icalproperty_set_transp (prop, transp);
261 		else {
262 			prop = icalproperty_new_transp (transp);
263 			icalcomponent_add_property (comp_data->icalcomp, prop);
264 		}
265 	}
266 }
267 
268 static void
269 ecmc_set_value_at (ETableModel *etm,
270                    gint col,
271                    gint row,
272                    gconstpointer value)
273 {
274 	ECalModelComponent *comp_data;
275 	CalObjModType mod = CALOBJ_MOD_ALL;
276 	ECalComponent *comp;
277 	ECalModelCalendar *model = (ECalModelCalendar *) etm;
278 	ESourceRegistry *registry;
279 	GError *error = NULL;
280 
281 	g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
282 	g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
283 	g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm));
284 
285 	registry = e_cal_model_get_registry (E_CAL_MODEL (model));
286 
287 	if (col < E_CAL_MODEL_FIELD_LAST) {
288 		E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->set_value_at (etm, col, row, value);
289 		return;
290 	}
291 
292 	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
293 	if (!comp_data)
294 		return;
295 
296 	comp = e_cal_component_new ();
297 	if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) {
298 		g_object_unref (comp);
299 		return;
300 	}
301 
302 	/* ask about mod type */
303 	if (e_cal_component_is_instance (comp)) {
304 		if (!recur_component_dialog (comp_data->client, comp, &mod, NULL, FALSE)) {
305 			g_object_unref (comp);
306 			return;
307 		}
308 	}
309 
310 	switch (col) {
311 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
312 		set_dtend ((ECalModel *) model, comp_data, value);
313 		break;
314 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
315 		set_location (comp_data, value);
316 		break;
317 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
318 		set_transparency (comp_data, value);
319 		break;
320 	}
321 
322 	e_cal_client_modify_object_sync (
323 		comp_data->client, comp_data->icalcomp, mod, NULL, &error);
324 
325 	if (error == NULL) {
326 		gboolean strip_alarms = TRUE;
327 
328 		if (itip_organizer_is_user (registry, comp, comp_data->client) &&
329 		    send_component_dialog (NULL, comp_data->client, comp, FALSE, &strip_alarms, NULL)) {
330 			ECalComponent *send_comp = NULL;
331 
332 			if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) {
333 				/* Ensure we send the master object, not the instance only */
334 				icalcomponent *icalcomp = NULL;
335 				const gchar *uid = NULL;
336 
337 				e_cal_component_get_uid (comp, &uid);
338 				if (e_cal_client_get_object_sync (comp_data->client, uid, NULL, &icalcomp, NULL, NULL) && icalcomp) {
339 					send_comp = e_cal_component_new ();
340 					if (!e_cal_component_set_icalcomponent (send_comp, icalcomp)) {
341 						icalcomponent_free (icalcomp);
342 						g_object_unref (send_comp);
343 						send_comp = NULL;
344 					}
345 				}
346 			}
347 
348 			itip_send_comp (
349 				registry, E_CAL_COMPONENT_METHOD_REQUEST,
350 				send_comp ? send_comp : comp, comp_data->client,
351 				NULL, NULL, NULL, strip_alarms, FALSE);
352 
353 			if (send_comp)
354 				g_object_unref (send_comp);
355 		}
356 	} else {
357 		g_warning (
358 			G_STRLOC ": Could not modify the object! %s",
359 			error->message);
360 
361 		/* FIXME Show error dialog */
362 		g_error_free (error);
363 	}
364 
365 	g_object_unref (comp);
366 }
367 
368 static gboolean
369 ecmc_is_cell_editable (ETableModel *etm,
370                        gint col,
371                        gint row)
372 {
373 	ECalModelCalendar *model = (ECalModelCalendar *) etm;
374 
375 	g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), FALSE);
376 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, FALSE);
377 	g_return_val_if_fail (row >= -1 || (row >= 0 && row < e_table_model_row_count (etm)), FALSE);
378 
379 	if (col < E_CAL_MODEL_FIELD_LAST)
380 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->is_cell_editable (etm, col, row);
381 
382 	if (!e_cal_model_test_row_editable (E_CAL_MODEL (etm), row))
383 		return FALSE;
384 
385 	switch (col) {
386 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
387 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
388 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
389 		return TRUE;
390 	}
391 
392 	return FALSE;
393 }
394 
395 static gpointer
396 ecmc_duplicate_value (ETableModel *etm,
397                       gint col,
398                       gconstpointer value)
399 {
400 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
401 
402 	if (col < E_CAL_MODEL_FIELD_LAST)
403 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->duplicate_value (etm, col, value);
404 
405 	switch (col) {
406 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
407 		if (value) {
408 			ECellDateEditValue *dv, *orig_dv;
409 
410 			orig_dv = (ECellDateEditValue *) value;
411 			dv = g_new0 (ECellDateEditValue, 1);
412 			*dv = *orig_dv;
413 
414 			return dv;
415 		}
416 		break;
417 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
418 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
419 		return g_strdup (value);
420 	}
421 
422 	return NULL;
423 }
424 
425 static void
426 ecmc_free_value (ETableModel *etm,
427                  gint col,
428                  gpointer value)
429 {
430 	g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
431 
432 	if (col < E_CAL_MODEL_FIELD_LAST) {
433 		E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->free_value (etm, col, value);
434 		return;
435 	}
436 
437 	switch (col) {
438 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
439 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
440 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
441 		if (value)
442 			g_free (value);
443 		break;
444 	}
445 }
446 
447 static gpointer
448 ecmc_initialize_value (ETableModel *etm,
449                        gint col)
450 {
451 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
452 
453 	if (col < E_CAL_MODEL_FIELD_LAST)
454 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->initialize_value (etm, col);
455 
456 	switch (col) {
457 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
458 		return NULL;
459 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
460 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
461 		return g_strdup ("");
462 	}
463 
464 	return NULL;
465 }
466 
467 static gboolean
468 ecmc_value_is_empty (ETableModel *etm,
469                      gint col,
470                      gconstpointer value)
471 {
472 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, TRUE);
473 
474 	if (col < E_CAL_MODEL_FIELD_LAST)
475 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->value_is_empty (etm, col, value);
476 
477 	switch (col) {
478 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
479 		return value ? FALSE : TRUE;
480 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
481 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
482 		return string_is_empty (value);
483 	}
484 
485 	return TRUE;
486 }
487 
488 static gchar *
489 ecmc_value_to_string (ETableModel *etm,
490                       gint col,
491                       gconstpointer value)
492 {
493 	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, g_strdup (""));
494 
495 	if (col < E_CAL_MODEL_FIELD_LAST)
496 		return E_TABLE_MODEL_CLASS (e_cal_model_calendar_parent_class)->value_to_string (etm, col, value);
497 
498 	switch (col) {
499 	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
500 		return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value);
501 	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
502 	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
503 		return g_strdup (value);
504 	}
505 
506 	return g_strdup ("");
507 }
508 
509 /* ECalModel class methods */
510 
511 static void
512 ecmc_fill_component_from_model (ECalModel *model,
513                                 ECalModelComponent *comp_data,
514                                 ETableModel *source_model,
515                                 gint row)
516 {
517 	g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
518 	g_return_if_fail (comp_data != NULL);
519 	g_return_if_fail (E_IS_TABLE_MODEL (source_model));
520 
521 	set_dtend (
522 		model, comp_data,
523 		e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row));
524 	set_location (
525 		comp_data,
526 		e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row));
527 	set_transparency (
528 		comp_data,
529 		e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row));
530 }
531 
532 /**
533  * e_cal_model_calendar_new
534  */
535 ECalModel *
536 e_cal_model_calendar_new (ESourceRegistry *registry)
537 {
538 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
539 
540 	return g_object_new (
541 		E_TYPE_CAL_MODEL_CALENDAR,
542 		"registry", registry, NULL);
543 }