No issues found
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 |
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 }