1 /*
2 * Evolution calendar - Data model for ETable
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 *
17 * Authors:
18 * Rodrigo Moya <rodrigo@ximian.com>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 #include "evolution-config.h"
25
26 #include <string.h>
27 #include <glib/gi18n.h>
28 #include "e-cal-model-calendar.h"
29 #include "e-cell-date-edit-text.h"
30 #include "itip-utils.h"
31 #include "misc.h"
32 #include "e-cal-dialogs.h"
33
34 /* Forward Declarations */
35 static void e_cal_model_calendar_table_model_init
36 (ETableModelInterface *iface);
37
38 static ETableModelInterface *table_model_parent_interface;
39
G_DEFINE_TYPE_WITH_CODE(ECalModelCalendar,e_cal_model_calendar,E_TYPE_CAL_MODEL,G_IMPLEMENT_INTERFACE (E_TYPE_TABLE_MODEL,e_cal_model_calendar_table_model_init))40 G_DEFINE_TYPE_WITH_CODE (
41 ECalModelCalendar,
42 e_cal_model_calendar,
43 E_TYPE_CAL_MODEL,
44 G_IMPLEMENT_INTERFACE (
45 E_TYPE_TABLE_MODEL,
46 e_cal_model_calendar_table_model_init))
47
48 static ECellDateEditValue *
49 get_dtend (ECalModelCalendar *model,
50 ECalModelComponent *comp_data)
51 {
52 if (!comp_data->dtend) {
53 comp_data->dtend = e_cal_model_util_get_datetime_value (E_CAL_MODEL (model), comp_data,
54 I_CAL_DTEND_PROPERTY, i_cal_property_get_dtend);
55 }
56
57 return e_cell_date_edit_value_copy (comp_data->dtend);
58 }
59
60 static gpointer
get_location(ECalModelComponent * comp_data)61 get_location (ECalModelComponent *comp_data)
62 {
63 ICalProperty *prop;
64 const gchar *res = NULL;
65
66 prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_LOCATION_PROPERTY);
67 if (prop) {
68 res = i_cal_property_get_location (prop);
69 g_clear_object (&prop);
70 }
71
72 if (!res)
73 res = "";
74
75 return (gpointer) res;
76 }
77
78 static gpointer
get_transparency(ECalModelComponent * comp_data)79 get_transparency (ECalModelComponent *comp_data)
80 {
81 ICalProperty *prop;
82
83 prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_TRANSP_PROPERTY);
84 if (prop) {
85 ICalPropertyTransp transp;
86 const gchar *res = NULL;
87
88 transp = i_cal_property_get_transp (prop);
89 if (transp == I_CAL_TRANSP_TRANSPARENT ||
90 transp == I_CAL_TRANSP_TRANSPARENTNOCONFLICT)
91 res = _("Free");
92 else if (transp == I_CAL_TRANSP_OPAQUE ||
93 transp == I_CAL_TRANSP_OPAQUENOCONFLICT)
94 res = _("Busy");
95
96 g_clear_object (&prop);
97
98 return (gpointer) res;
99 }
100
101 return NULL;
102 }
103
104 static void
set_dtend(ECalModel * model,ECalModelComponent * comp_data,gconstpointer value)105 set_dtend (ECalModel *model,
106 ECalModelComponent *comp_data,
107 gconstpointer value)
108 {
109 e_cal_model_update_comp_time (model, comp_data, value, I_CAL_DTEND_PROPERTY, i_cal_property_set_dtend, i_cal_property_new_dtend);
110 }
111
112 static void
set_location(ECalModelComponent * comp_data,gconstpointer value)113 set_location (ECalModelComponent *comp_data,
114 gconstpointer value)
115 {
116 ICalProperty *prop;
117
118 prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_LOCATION_PROPERTY);
119
120 if (string_is_empty (value)) {
121 if (prop) {
122 i_cal_component_remove_property (comp_data->icalcomp, prop);
123 g_object_unref (prop);
124 }
125 } else {
126 if (prop) {
127 i_cal_property_set_location (prop, (const gchar *) value);
128 g_object_unref (prop);
129 } else {
130 prop = i_cal_property_new_location ((const gchar *) value);
131 i_cal_component_take_property (comp_data->icalcomp, prop);
132 }
133 }
134 }
135
136 static void
set_transparency(ECalModelComponent * comp_data,gconstpointer value)137 set_transparency (ECalModelComponent *comp_data,
138 gconstpointer value)
139 {
140 ICalProperty *prop;
141
142 prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_TRANSP_PROPERTY);
143
144 if (string_is_empty (value)) {
145 if (prop) {
146 i_cal_component_remove_property (comp_data->icalcomp, prop);
147 g_object_unref (prop);
148 }
149 } else {
150 ICalPropertyTransp transp;
151
152 if (!g_ascii_strcasecmp (value, "FREE"))
153 transp = I_CAL_TRANSP_TRANSPARENT;
154 else if (!g_ascii_strcasecmp (value, "OPAQUE"))
155 transp = I_CAL_TRANSP_OPAQUE;
156 else {
157 if (prop) {
158 i_cal_component_remove_property (comp_data->icalcomp, prop);
159 g_object_unref (prop);
160 }
161
162 return;
163 }
164
165 if (prop) {
166 i_cal_property_set_transp (prop, transp);
167 g_object_unref (prop);
168 } else {
169 prop = i_cal_property_new_transp (transp);
170 i_cal_component_take_property (comp_data->icalcomp, prop);
171 }
172 }
173 }
174
175 static void
cal_model_calendar_store_values_from_model(ECalModel * model,ETableModel * source_model,gint row,GHashTable * values)176 cal_model_calendar_store_values_from_model (ECalModel *model,
177 ETableModel *source_model,
178 gint row,
179 GHashTable *values)
180 {
181 g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
182 g_return_if_fail (E_IS_TABLE_MODEL (source_model));
183 g_return_if_fail (values != NULL);
184
185 e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row);
186 e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row);
187 e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row);
188 e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_STATUS, row);
189 }
190
191 static void
cal_model_calendar_fill_component_from_values(ECalModel * model,ECalModelComponent * comp_data,GHashTable * values)192 cal_model_calendar_fill_component_from_values (ECalModel *model,
193 ECalModelComponent *comp_data,
194 GHashTable *values)
195 {
196 g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
197 g_return_if_fail (comp_data != NULL);
198 g_return_if_fail (values != NULL);
199
200 set_dtend (model, comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_DTEND));
201 set_location (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_LOCATION));
202 set_transparency (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY));
203 e_cal_model_util_set_status (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_STATUS));
204 }
205
206 static gint
cal_model_calendar_column_count(ETableModel * etm)207 cal_model_calendar_column_count (ETableModel *etm)
208 {
209 return E_CAL_MODEL_CALENDAR_FIELD_LAST;
210 }
211
212 static gpointer
cal_model_calendar_value_at(ETableModel * etm,gint col,gint row)213 cal_model_calendar_value_at (ETableModel *etm,
214 gint col,
215 gint row)
216 {
217 ECalModelComponent *comp_data;
218 ECalModelCalendar *model = (ECalModelCalendar *) etm;
219
220 g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), NULL);
221
222 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
223 g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL);
224
225 if (col < E_CAL_MODEL_FIELD_LAST)
226 return table_model_parent_interface->value_at (etm, col, row);
227
228 comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
229 if (!comp_data)
230 return (gpointer) "";
231
232 switch (col) {
233 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
234 return get_dtend (model, comp_data);
235 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
236 return get_location (comp_data);
237 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
238 return get_transparency (comp_data);
239 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
240 return e_cal_model_util_get_status (comp_data);
241 }
242
243 return (gpointer) "";
244 }
245
246 static void
cal_model_calendar_set_value_at(ETableModel * etm,gint col,gint row,gconstpointer value)247 cal_model_calendar_set_value_at (ETableModel *etm,
248 gint col,
249 gint row,
250 gconstpointer value)
251 {
252 ECalModelComponent *comp_data;
253 ECalObjModType mod = E_CAL_OBJ_MOD_ALL;
254 ECalComponent *comp;
255 ECalModelCalendar *model = (ECalModelCalendar *) etm;
256
257 g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
258 g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
259 g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm));
260
261 if (col < E_CAL_MODEL_FIELD_LAST) {
262 table_model_parent_interface->set_value_at (etm, col, row, value);
263 return;
264 }
265
266 comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
267 if (!comp_data)
268 return;
269
270 comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone (comp_data->icalcomp));
271 if (!comp) {
272 return;
273 }
274
275 /* ask about mod type */
276 if (e_cal_component_is_instance (comp)) {
277 if (!e_cal_dialogs_recur_component (comp_data->client, comp, &mod, NULL, FALSE)) {
278 g_object_unref (comp);
279 return;
280 }
281 }
282
283 switch (col) {
284 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
285 set_dtend ((ECalModel *) model, comp_data, value);
286 break;
287 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
288 set_location (comp_data, value);
289 break;
290 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
291 set_transparency (comp_data, value);
292 break;
293 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
294 e_cal_model_util_set_status (comp_data, value);
295 break;
296 }
297
298 e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, mod);
299
300 g_object_unref (comp);
301 }
302
303 static gboolean
cal_model_calendar_is_cell_editable(ETableModel * etm,gint col,gint row)304 cal_model_calendar_is_cell_editable (ETableModel *etm,
305 gint col,
306 gint row)
307 {
308 ECalModelCalendar *model = (ECalModelCalendar *) etm;
309
310 g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), FALSE);
311 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, FALSE);
312 g_return_val_if_fail (row >= -1 || (row >= 0 && row < e_table_model_row_count (etm)), FALSE);
313
314 if (col < E_CAL_MODEL_FIELD_LAST)
315 return table_model_parent_interface->is_cell_editable (etm, col, row);
316
317 if (!e_cal_model_test_row_editable (E_CAL_MODEL (etm), row))
318 return FALSE;
319
320 switch (col) {
321 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
322 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
323 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
324 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
325 return TRUE;
326 }
327
328 return FALSE;
329 }
330
331 static gpointer
cal_model_calendar_duplicate_value(ETableModel * etm,gint col,gconstpointer value)332 cal_model_calendar_duplicate_value (ETableModel *etm,
333 gint col,
334 gconstpointer value)
335 {
336 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
337
338 if (col < E_CAL_MODEL_FIELD_LAST)
339 return table_model_parent_interface->duplicate_value (etm, col, value);
340
341 switch (col) {
342 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
343 return e_cell_date_edit_value_copy (value);
344 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
345 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
346 return g_strdup (value);
347 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
348 return (gpointer) value;
349 }
350
351 return NULL;
352 }
353
354 static void
cal_model_calendar_free_value(ETableModel * etm,gint col,gpointer value)355 cal_model_calendar_free_value (ETableModel *etm,
356 gint col,
357 gpointer value)
358 {
359 g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
360
361 if (col < E_CAL_MODEL_FIELD_LAST) {
362 table_model_parent_interface->free_value (etm, col, value);
363 return;
364 }
365
366 switch (col) {
367 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
368 e_cell_date_edit_value_free (value);
369 break;
370 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
371 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
372 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
373 break;
374 }
375 }
376
377 static gpointer
cal_model_calendar_initialize_value(ETableModel * etm,gint col)378 cal_model_calendar_initialize_value (ETableModel *etm,
379 gint col)
380 {
381 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
382
383 if (col < E_CAL_MODEL_FIELD_LAST)
384 return table_model_parent_interface->initialize_value (etm, col);
385
386 switch (col) {
387 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
388 return NULL;
389 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
390 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
391 return g_strdup ("");
392 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
393 return (gpointer) "";
394 }
395
396 return NULL;
397 }
398
399 static gboolean
cal_model_calendar_value_is_empty(ETableModel * etm,gint col,gconstpointer value)400 cal_model_calendar_value_is_empty (ETableModel *etm,
401 gint col,
402 gconstpointer value)
403 {
404 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, TRUE);
405
406 if (col < E_CAL_MODEL_FIELD_LAST)
407 return table_model_parent_interface->value_is_empty (etm, col, value);
408
409 switch (col) {
410 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
411 return value ? FALSE : TRUE;
412 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
413 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
414 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
415 return string_is_empty (value);
416 }
417
418 return TRUE;
419 }
420
421 static gchar *
cal_model_calendar_value_to_string(ETableModel * etm,gint col,gconstpointer value)422 cal_model_calendar_value_to_string (ETableModel *etm,
423 gint col,
424 gconstpointer value)
425 {
426 g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, g_strdup (""));
427
428 if (col < E_CAL_MODEL_FIELD_LAST)
429 return table_model_parent_interface->value_to_string (etm, col, value);
430
431 switch (col) {
432 case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
433 return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value);
434 case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
435 case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
436 case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
437 return g_strdup (value);
438 }
439
440 return g_strdup ("");
441 }
442
443 static void
e_cal_model_calendar_class_init(ECalModelCalendarClass * class)444 e_cal_model_calendar_class_init (ECalModelCalendarClass *class)
445 {
446 ECalModelClass *model_class;
447
448 model_class = E_CAL_MODEL_CLASS (class);
449 model_class->store_values_from_model = cal_model_calendar_store_values_from_model;
450 model_class->fill_component_from_values = cal_model_calendar_fill_component_from_values;
451 }
452
453 static void
e_cal_model_calendar_table_model_init(ETableModelInterface * iface)454 e_cal_model_calendar_table_model_init (ETableModelInterface *iface)
455 {
456 table_model_parent_interface =
457 g_type_interface_peek_parent (iface);
458
459 iface->column_count = cal_model_calendar_column_count;
460 iface->value_at = cal_model_calendar_value_at;
461 iface->set_value_at = cal_model_calendar_set_value_at;
462 iface->is_cell_editable = cal_model_calendar_is_cell_editable;
463 iface->duplicate_value = cal_model_calendar_duplicate_value;
464 iface->free_value = cal_model_calendar_free_value;
465 iface->initialize_value = cal_model_calendar_initialize_value;
466 iface->value_is_empty = cal_model_calendar_value_is_empty;
467 iface->value_to_string = cal_model_calendar_value_to_string;
468 }
469
470 static void
e_cal_model_calendar_init(ECalModelCalendar * model)471 e_cal_model_calendar_init (ECalModelCalendar *model)
472 {
473 e_cal_model_set_component_kind (
474 E_CAL_MODEL (model), I_CAL_VEVENT_COMPONENT);
475 }
476
477 ECalModel *
e_cal_model_calendar_new(ECalDataModel * data_model,ESourceRegistry * registry,EShell * shell)478 e_cal_model_calendar_new (ECalDataModel *data_model,
479 ESourceRegistry *registry,
480 EShell *shell)
481 {
482 g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL);
483 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
484 g_return_val_if_fail (E_IS_SHELL (shell), NULL);
485
486 return g_object_new (
487 E_TYPE_CAL_MODEL_CALENDAR,
488 "data-model", data_model,
489 "registry", registry,
490 "shell", shell,
491 NULL);
492 }
493
494