2 * Evolution calendar - Data model for ETable
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.
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
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/>.
18 * Rodrigo Moya <rodrigo@ximian.com>
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
24 #include "evolution-config.h"
29 #include <glib/gi18n.h>
31 #include "calendar-config.h"
32 #include "e-cal-model-tasks.h"
33 #include "e-cell-date-edit-text.h"
36 #define E_CAL_MODEL_TASKS_GET_PRIVATE(obj) \
37 (G_TYPE_INSTANCE_GET_PRIVATE \
38 ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksPrivate))
40 struct _ECalModelTasksPrivate
{
41 gboolean highlight_due_today
;
42 gchar
*color_due_today
;
43 gboolean highlight_overdue
;
49 PROP_HIGHLIGHT_DUE_TODAY
,
51 PROP_HIGHLIGHT_OVERDUE
,
55 /* Forward Declarations */
56 static void e_cal_model_tasks_table_model_init
57 (ETableModelInterface
*iface
);
59 static ETableModelInterface
*table_model_parent_interface
;
61 G_DEFINE_TYPE_WITH_CODE (
65 G_IMPLEMENT_INTERFACE (
67 e_cal_model_tasks_table_model_init
))
69 /* This makes sure a task is marked as complete.
70 * It makes sure the "Date Completed" property is set. If the completed_date
71 * is not -1, then that is used, otherwise if the "Date Completed" property
72 * is not already set it is set to the current time.
73 * It makes sure the percent is set to 100, and that the status is "Completed".
74 * Note that this doesn't update the component on the server. */
76 ensure_task_complete (ECalModelComponent
*comp_data
,
77 time_t completed_date
)
80 gboolean set_completed
= TRUE
;
82 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
85 if (completed_date
== -1) {
87 set_completed
= FALSE
;
89 completed_date
= time (NULL
);
93 icaltimezone
*utc_zone
;
94 struct icaltimetype new_completed
;
96 /* COMPLETED is stored in UTC. */
97 utc_zone
= icaltimezone_get_utc_timezone ();
98 new_completed
= icaltime_from_timet_with_zone (
103 icalproperty_set_completed (prop
, new_completed
);
105 prop
= icalproperty_new_completed (new_completed
);
106 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
111 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
113 icalcomponent_add_property (comp_data
->icalcomp
, icalproperty_new_percentcomplete (100));
115 icalproperty_set_percentcomplete (prop
, 100);
118 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
120 icalproperty_set_status (prop
, ICAL_STATUS_COMPLETED
);
122 icalcomponent_add_property (comp_data
->icalcomp
, icalproperty_new_status (ICAL_STATUS_COMPLETED
));
126 ensure_task_partially_complete (ECalModelComponent
*comp_data
)
130 /* Date Completed. */
131 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
133 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
134 icalproperty_free (prop
);
138 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
140 icalcomponent_add_property (comp_data
->icalcomp
, icalproperty_new_percentcomplete (50));
141 else if (icalproperty_get_percentcomplete (prop
) == 0 || icalproperty_get_percentcomplete (prop
) == 100)
142 icalproperty_set_percentcomplete (prop
, 50);
145 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
147 icalproperty_set_status (prop
, ICAL_STATUS_INPROCESS
);
149 icalcomponent_add_property (comp_data
->icalcomp
, icalproperty_new_status (ICAL_STATUS_INPROCESS
));
152 /* This makes sure a task is marked as incomplete. It clears the
153 * "Date Completed" property. If the percent is set to 100 it removes it,
154 * and if the status is "Completed" it sets it to "Needs Action".
155 * Note that this doesn't update the component on the client. */
157 ensure_task_not_complete (ECalModelComponent
*comp_data
)
161 /* Date Completed. */
162 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
164 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
165 icalproperty_free (prop
);
169 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
171 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
172 icalproperty_free (prop
);
176 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
178 icalproperty_set_status (prop
, ICAL_STATUS_NEEDSACTION
);
181 static ECellDateEditValue
*
182 get_completed (ECalModelComponent
*comp_data
)
184 struct icaltimetype tt_completed
;
186 if (!comp_data
->completed
) {
190 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
194 tt_completed
= icalproperty_get_completed (prop
);
195 if (!icaltime_is_valid_time (tt_completed
) || icaltime_is_null_time (tt_completed
))
198 comp_data
->completed
= g_new0 (ECellDateEditValue
, 1);
199 comp_data
->completed
->tt
= tt_completed
;
201 if (icaltime_get_tzid (tt_completed
)
202 && e_cal_client_get_timezone_sync (comp_data
->client
, icaltime_get_tzid (tt_completed
), &zone
, NULL
, NULL
))
203 comp_data
->completed
->zone
= zone
;
205 comp_data
->completed
->zone
= NULL
;
208 return e_cal_model_copy_cell_date_value (comp_data
->completed
);
211 static ECellDateEditValue
*
212 get_due (ECalModelComponent
*comp_data
)
214 struct icaltimetype tt_due
;
216 if (!comp_data
->due
) {
220 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_DUE_PROPERTY
);
224 tt_due
= icalproperty_get_due (prop
);
225 if (!icaltime_is_valid_time (tt_due
) || icaltime_is_null_time (tt_due
))
228 comp_data
->due
= g_new0 (ECellDateEditValue
, 1);
229 comp_data
->due
->tt
= tt_due
;
231 if (icaltime_get_tzid (tt_due
)
232 && e_cal_client_get_timezone_sync (comp_data
->client
, icaltime_get_tzid (tt_due
), &zone
, NULL
, NULL
))
233 comp_data
->due
->zone
= zone
;
235 comp_data
->due
->zone
= NULL
;
238 return e_cal_model_copy_cell_date_value (comp_data
->due
);
242 get_geo (ECalModelComponent
*comp_data
)
245 struct icalgeotype geo
;
246 static gchar buf
[32];
248 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_GEO_PROPERTY
);
250 geo
= icalproperty_get_geo (prop
);
252 buf
, sizeof (buf
), "%g %s, %g %s",
254 geo
.lat
>= 0.0 ? "N" : "S",
256 geo
.lon
>= 0.0 ? "E" : "W");
260 return (gpointer
) "";
264 get_percent (ECalModelComponent
*comp_data
)
268 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
270 return icalproperty_get_percentcomplete (prop
);
276 get_priority (ECalModelComponent
*comp_data
)
280 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PRIORITY_PROPERTY
);
282 return (gpointer
) e_cal_util_priority_to_string (icalproperty_get_priority (prop
));
284 return (gpointer
) "";
288 is_status_canceled (ECalModelComponent
*comp_data
)
292 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
294 return prop
&& icalproperty_get_status (prop
) == ICAL_STATUS_CANCELLED
;
298 get_status (ECalModelComponent
*comp_data
)
302 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
304 switch (icalproperty_get_status (prop
)) {
305 case ICAL_STATUS_NONE
:
306 return (gpointer
) "";
307 case ICAL_STATUS_NEEDSACTION
:
308 return (gpointer
) _("Not Started");
309 case ICAL_STATUS_INPROCESS
:
310 return (gpointer
) _("In Progress");
311 case ICAL_STATUS_COMPLETED
:
312 return (gpointer
) _("Completed");
313 case ICAL_STATUS_CANCELLED
:
314 return (gpointer
) _("Cancelled");
316 return (gpointer
) "";
320 return (gpointer
) "";
324 get_url (ECalModelComponent
*comp_data
)
328 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_URL_PROPERTY
);
330 return (gpointer
) icalproperty_get_url (prop
);
332 return (gpointer
) "";
336 is_complete (ECalModelComponent
*comp_data
)
340 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
344 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
345 if (prop
&& icalproperty_get_percentcomplete (prop
) == 100)
348 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
349 if (prop
&& icalproperty_get_status (prop
) == ICAL_STATUS_COMPLETED
)
356 E_CAL_MODEL_TASKS_DUE_NEVER
,
357 E_CAL_MODEL_TASKS_DUE_FUTURE
,
358 E_CAL_MODEL_TASKS_DUE_TODAY
,
359 E_CAL_MODEL_TASKS_DUE_OVERDUE
,
360 E_CAL_MODEL_TASKS_DUE_COMPLETE
361 } ECalModelTasksDueStatus
;
363 static ECalModelTasksDueStatus
364 get_due_status (ECalModelTasks
*model
,
365 ECalModelComponent
*comp_data
)
369 /* First, do we have a due date? */
370 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_DUE_PROPERTY
);
372 return E_CAL_MODEL_TASKS_DUE_NEVER
;
374 struct icaltimetype now_tt
, due_tt
;
375 icaltimezone
*zone
= NULL
;
377 /* Second, is it already completed? */
378 if (is_complete (comp_data
))
379 return E_CAL_MODEL_TASKS_DUE_COMPLETE
;
381 /* Third, are we overdue as of right now? */
382 due_tt
= icalproperty_get_due (prop
);
383 if (due_tt
.is_date
) {
386 now_tt
= icaltime_current_time_with_zone (e_cal_model_get_timezone (E_CAL_MODEL (model
)));
387 cmp
= icaltime_compare_date_only (due_tt
, now_tt
);
390 return E_CAL_MODEL_TASKS_DUE_OVERDUE
;
392 return E_CAL_MODEL_TASKS_DUE_TODAY
;
394 return E_CAL_MODEL_TASKS_DUE_FUTURE
;
396 icalparameter
*param
;
399 if (!(param
= icalproperty_get_first_parameter (prop
, ICAL_TZID_PARAMETER
)))
400 return E_CAL_MODEL_TASKS_DUE_FUTURE
;
402 /* Get the current time in the same timezone as the DUE date.*/
403 tzid
= icalparameter_get_tzid (param
);
404 e_cal_client_get_timezone_sync (
405 comp_data
->client
, tzid
, &zone
, NULL
, NULL
);
407 return E_CAL_MODEL_TASKS_DUE_FUTURE
;
409 now_tt
= icaltime_current_time_with_zone (zone
);
411 if (icaltime_compare (due_tt
, now_tt
) <= 0)
412 return E_CAL_MODEL_TASKS_DUE_OVERDUE
;
414 if (icaltime_compare_date_only (due_tt
, now_tt
) == 0)
415 return E_CAL_MODEL_TASKS_DUE_TODAY
;
417 return E_CAL_MODEL_TASKS_DUE_FUTURE
;
423 is_overdue (ECalModelTasks
*model
,
424 ECalModelComponent
*comp_data
)
426 switch (get_due_status (model
, comp_data
)) {
427 case E_CAL_MODEL_TASKS_DUE_NEVER
:
428 case E_CAL_MODEL_TASKS_DUE_FUTURE
:
429 case E_CAL_MODEL_TASKS_DUE_COMPLETE
:
431 case E_CAL_MODEL_TASKS_DUE_TODAY
:
432 case E_CAL_MODEL_TASKS_DUE_OVERDUE
:
440 set_completed (ECalModelTasks
*model
,
441 ECalModelComponent
*comp_data
,
444 ECellDateEditValue
*dv
= (ECellDateEditValue
*) value
;
447 ensure_task_not_complete (comp_data
);
451 if (dv
->tt
.is_date
) {
452 /* if it's a date, it will be floating,
453 * but completed needs a date time value */
454 dv
->tt
.is_date
= FALSE
;
455 t
= icaltime_as_timet_with_zone (dv
->tt
, e_cal_model_get_timezone (E_CAL_MODEL (model
)));
457 /* we assume that COMPLETED is entered in the current timezone,
458 * even though it gets stored in UTC */
459 t
= icaltime_as_timet_with_zone (dv
->tt
, dv
->zone
);
462 ensure_task_complete (comp_data
, t
);
467 set_complete (ECalModelComponent
*comp_data
,
470 gint state
= GPOINTER_TO_INT (value
);
473 ensure_task_complete (comp_data
, -1);
475 ensure_task_not_complete (comp_data
);
479 set_due (ECalModel
*model
,
480 ECalModelComponent
*comp_data
,
483 e_cal_model_update_comp_time (model
, comp_data
, value
, ICAL_DUE_PROPERTY
, icalproperty_set_due
, icalproperty_new_due
);
486 /* FIXME: We need to set the "transient_for" property for the dialog, but the
487 * model doesn't know anything about the windows.
490 show_geo_warning (void)
494 dialog
= gtk_message_dialog_new (
495 NULL
, 0, GTK_MESSAGE_ERROR
, GTK_BUTTONS_OK
,
496 "%s", _("The geographical position must be entered "
497 "in the format: \n\n45.436845,125.862501"));
498 gtk_widget_show (dialog
);
502 set_geo (ECalModelComponent
*comp_data
,
505 gdouble latitude
, longitude
;
507 struct icalgeotype geo
;
510 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_GEO_PROPERTY
);
512 if (string_is_empty (value
)) {
514 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
515 icalproperty_free (prop
);
518 matched
= sscanf (value
, "%lg , %lg", &latitude
, &longitude
);
525 icalproperty_set_geo (prop
, geo
);
527 prop
= icalproperty_new_geo (geo
);
528 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
535 set_status (ECalModelComponent
*comp_data
,
538 icalproperty_status status
;
541 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
543 /* an empty string is the same as 'None' */
547 /* Translators: "None" for task's status */
548 if (!e_util_utf8_strcasecmp (value
, C_("cal-task-status", "None")))
550 else if (!e_util_utf8_strcasecmp (value
, _("Not Started")))
551 status
= ICAL_STATUS_NEEDSACTION
;
552 else if (!e_util_utf8_strcasecmp (value
, _("In Progress")))
553 status
= ICAL_STATUS_INPROCESS
;
554 else if (!e_util_utf8_strcasecmp (value
, _("Completed")))
555 status
= ICAL_STATUS_COMPLETED
;
556 else if (!e_util_utf8_strcasecmp (value
, _("Cancelled")))
557 status
= ICAL_STATUS_CANCELLED
;
559 g_warning ("Invalid status: %s\n", value
);
564 icalproperty_set_status (prop
, status
);
566 prop
= icalproperty_new_status (status
);
567 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
571 case ICAL_STATUS_NEEDSACTION
:
572 ensure_task_not_complete (comp_data
);
575 case ICAL_STATUS_INPROCESS
:
576 ensure_task_partially_complete (comp_data
);
579 case ICAL_STATUS_CANCELLED
:
580 ensure_task_not_complete (comp_data
);
581 /* do this again, because the previous function changed status to NEEDSACTION */
582 icalproperty_set_status (prop
, status
);
585 case ICAL_STATUS_COMPLETED
:
586 ensure_task_complete (comp_data
, -1);
589 /* to make compiler happy */
590 /* coverity[dead_error_begin] */
597 set_percent (ECalModelComponent
*comp_data
,
601 gint percent
= GPOINTER_TO_INT (value
);
603 g_return_if_fail (percent
>= -1);
604 g_return_if_fail (percent
<= 100);
606 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
608 /* A value of -1 means it isn't set */
611 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
612 icalproperty_free (prop
);
614 ensure_task_not_complete (comp_data
);
617 icalproperty_set_percentcomplete (prop
, percent
);
619 prop
= icalproperty_new_percentcomplete (percent
);
620 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
624 ensure_task_complete (comp_data
, -1);
626 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
628 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
629 icalproperty_free (prop
);
633 set_status (comp_data
, _("In Progress"));
640 set_priority (ECalModelComponent
*comp_data
,
646 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PRIORITY_PROPERTY
);
648 priority
= e_cal_util_priority_from_string (value
);
649 if (priority
== -1) {
650 g_warning ("Invalid priority");
655 icalproperty_set_priority (prop
, priority
);
657 prop
= icalproperty_new_priority (priority
);
658 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
663 set_url (ECalModelComponent
*comp_data
,
668 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_URL_PROPERTY
);
670 if (string_is_empty (value
)) {
672 icalcomponent_remove_property (comp_data
->icalcomp
, prop
);
673 icalproperty_free (prop
);
677 icalproperty_set_url (prop
, value
);
679 prop
= icalproperty_new_url (value
);
680 icalcomponent_add_property (comp_data
->icalcomp
, prop
);
686 cal_model_tasks_set_property (GObject
*object
,
691 switch (property_id
) {
692 case PROP_HIGHLIGHT_DUE_TODAY
:
693 e_cal_model_tasks_set_highlight_due_today (
694 E_CAL_MODEL_TASKS (object
),
695 g_value_get_boolean (value
));
698 case PROP_COLOR_DUE_TODAY
:
699 e_cal_model_tasks_set_color_due_today (
700 E_CAL_MODEL_TASKS (object
),
701 g_value_get_string (value
));
704 case PROP_HIGHLIGHT_OVERDUE
:
705 e_cal_model_tasks_set_highlight_overdue (
706 E_CAL_MODEL_TASKS (object
),
707 g_value_get_boolean (value
));
710 case PROP_COLOR_OVERDUE
:
711 e_cal_model_tasks_set_color_overdue (
712 E_CAL_MODEL_TASKS (object
),
713 g_value_get_string (value
));
717 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
721 cal_model_tasks_get_property (GObject
*object
,
726 switch (property_id
) {
727 case PROP_HIGHLIGHT_DUE_TODAY
:
728 g_value_set_boolean (
730 e_cal_model_tasks_get_highlight_due_today (
731 E_CAL_MODEL_TASKS (object
)));
734 case PROP_COLOR_DUE_TODAY
:
737 e_cal_model_tasks_get_color_due_today (
738 E_CAL_MODEL_TASKS (object
)));
741 case PROP_HIGHLIGHT_OVERDUE
:
742 g_value_set_boolean (
744 e_cal_model_tasks_get_highlight_overdue (
745 E_CAL_MODEL_TASKS (object
)));
748 case PROP_COLOR_OVERDUE
:
751 e_cal_model_tasks_get_color_overdue (
752 E_CAL_MODEL_TASKS (object
)));
756 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
760 cal_model_tasks_finalize (GObject
*object
)
762 ECalModelTasksPrivate
*priv
;
764 priv
= E_CAL_MODEL_TASKS_GET_PRIVATE (object
);
766 g_free (priv
->color_due_today
);
767 g_free (priv
->color_overdue
);
769 /* Chain up to parent's finalize() method. */
770 G_OBJECT_CLASS (e_cal_model_tasks_parent_class
)->finalize (object
);
774 cal_model_tasks_get_color_for_component (ECalModel
*model
,
775 ECalModelComponent
*comp_data
)
777 ECalModelTasks
*tasks
;
779 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), NULL
);
780 g_return_val_if_fail (comp_data
!= NULL
, NULL
);
782 tasks
= E_CAL_MODEL_TASKS (model
);
784 /* XXX ECalModel's get_color_for_component() method should really
785 * get a GdkColor instead of a color specification string. */
787 switch (get_due_status (tasks
, comp_data
)) {
788 case E_CAL_MODEL_TASKS_DUE_TODAY
:
789 if (!e_cal_model_tasks_get_highlight_due_today (tasks
))
791 return e_cal_model_tasks_get_color_due_today (tasks
);
792 case E_CAL_MODEL_TASKS_DUE_OVERDUE
:
793 if (!e_cal_model_tasks_get_highlight_overdue (tasks
))
795 return e_cal_model_tasks_get_color_overdue (tasks
);
796 case E_CAL_MODEL_TASKS_DUE_NEVER
:
797 case E_CAL_MODEL_TASKS_DUE_FUTURE
:
798 case E_CAL_MODEL_TASKS_DUE_COMPLETE
:
802 return E_CAL_MODEL_CLASS (e_cal_model_tasks_parent_class
)->
803 get_color_for_component (model
, comp_data
);
807 cal_model_tasks_store_values_from_model (ECalModel
*model
,
808 ETableModel
*source_model
,
812 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
813 g_return_if_fail (E_IS_TABLE_MODEL (source_model
));
814 g_return_if_fail (values
!= NULL
);
816 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_COMPLETED
, row
);
817 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_PERCENT
, row
);
818 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_STATUS
, row
);
819 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_DUE
, row
);
820 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_GEO
, row
);
821 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_PRIORITY
, row
);
822 e_cal_model_util_set_value (values
, source_model
, E_CAL_MODEL_TASKS_FIELD_URL
, row
);
826 cal_model_tasks_fill_component_from_values (ECalModel
*model
,
827 ECalModelComponent
*comp_data
,
832 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
833 g_return_if_fail (comp_data
!= NULL
);
834 g_return_if_fail (values
!= NULL
);
836 /* This just makes sure if anything indicates completion, all
837 * three fields do or if percent is 0, status is sane */
839 value
= e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_COMPLETED
);
840 set_completed ((ECalModelTasks
*) model
, comp_data
, value
);
842 value
= e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_PERCENT
);
843 set_percent (comp_data
, value
);
844 if (GPOINTER_TO_INT (value
) != 100 && GPOINTER_TO_INT (value
) != 0)
845 set_status (comp_data
, e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_STATUS
));
848 set_due (model
, comp_data
, e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_DUE
));
849 set_geo (comp_data
, e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_GEO
));
850 set_priority (comp_data
, e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_PRIORITY
));
851 set_url (comp_data
, e_cal_model_util_get_value (values
, E_CAL_MODEL_TASKS_FIELD_URL
));
855 cal_model_tasks_column_count (ETableModel
*etm
)
857 return E_CAL_MODEL_TASKS_FIELD_LAST
;
861 cal_model_tasks_value_at (ETableModel
*etm
,
865 ECalModelComponent
*comp_data
;
866 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
868 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), NULL
);
870 g_return_val_if_fail (col
>= 0 && (col
< E_CAL_MODEL_TASKS_FIELD_LAST
|| col
== E_CAL_MODEL_TASKS_FIELD_STRIKEOUT
), NULL
);
871 g_return_val_if_fail (row
>= 0 && row
< e_table_model_row_count (etm
), NULL
);
873 if (col
< E_CAL_MODEL_FIELD_LAST
)
874 return table_model_parent_interface
->value_at (etm
, col
, row
);
876 comp_data
= e_cal_model_get_component_at (E_CAL_MODEL (model
), row
);
878 return (gpointer
) "";
881 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
882 return get_completed (comp_data
);
883 case E_CAL_MODEL_TASKS_FIELD_STRIKEOUT
:
884 return GINT_TO_POINTER (is_status_canceled (comp_data
) || is_complete (comp_data
));
885 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
886 return GINT_TO_POINTER (is_complete (comp_data
));
887 case E_CAL_MODEL_TASKS_FIELD_DUE
:
888 return get_due (comp_data
);
889 case E_CAL_MODEL_TASKS_FIELD_GEO
:
890 return get_geo (comp_data
);
891 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
892 return GINT_TO_POINTER (is_overdue (model
, comp_data
));
893 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
894 return GINT_TO_POINTER (get_percent (comp_data
));
895 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
896 return get_priority (comp_data
);
897 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
898 return get_status (comp_data
);
899 case E_CAL_MODEL_TASKS_FIELD_URL
:
900 return get_url (comp_data
);
903 return (gpointer
) "";
907 cal_model_tasks_set_value_at (ETableModel
*etm
,
912 ECalModelComponent
*comp_data
;
913 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
915 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
917 g_return_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
);
918 g_return_if_fail (row
>= 0 && row
< e_table_model_row_count (etm
));
920 if (col
< E_CAL_MODEL_FIELD_LAST
) {
921 table_model_parent_interface
->set_value_at (etm
, col
, row
, value
);
925 comp_data
= e_cal_model_get_component_at (E_CAL_MODEL (model
), row
);
930 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
931 set_completed (model
, comp_data
, value
);
933 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
934 set_complete (comp_data
, value
);
936 case E_CAL_MODEL_TASKS_FIELD_DUE
:
937 set_due ((ECalModel
*) model
, comp_data
, value
);
939 case E_CAL_MODEL_TASKS_FIELD_GEO
:
940 set_geo (comp_data
, value
);
942 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
943 set_percent (comp_data
, value
);
945 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
946 set_priority (comp_data
, value
);
948 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
949 set_status (comp_data
, value
);
951 case E_CAL_MODEL_TASKS_FIELD_URL
:
952 set_url (comp_data
, value
);
956 e_cal_model_modify_component (E_CAL_MODEL (model
), comp_data
, E_CAL_OBJ_MOD_ALL
);
960 cal_model_tasks_is_cell_editable (ETableModel
*etm
,
964 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
966 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), FALSE
);
968 g_return_val_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
, FALSE
);
969 g_return_val_if_fail (row
>= -1 || (row
>= 0 && row
< e_table_model_row_count (etm
)), FALSE
);
971 if (col
< E_CAL_MODEL_FIELD_LAST
)
972 return table_model_parent_interface
->is_cell_editable (etm
, col
, row
);
974 if (!e_cal_model_test_row_editable (E_CAL_MODEL (etm
), row
))
978 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
979 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
980 case E_CAL_MODEL_TASKS_FIELD_DUE
:
981 case E_CAL_MODEL_TASKS_FIELD_GEO
:
982 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
983 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
984 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
985 case E_CAL_MODEL_TASKS_FIELD_URL
:
993 cal_model_tasks_duplicate_value (ETableModel
*etm
,
997 g_return_val_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
, NULL
);
999 if (col
< E_CAL_MODEL_FIELD_LAST
)
1000 return table_model_parent_interface
->duplicate_value (etm
, col
, value
);
1003 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
1004 case E_CAL_MODEL_TASKS_FIELD_DUE
:
1005 return e_cal_model_copy_cell_date_value (value
);
1007 case E_CAL_MODEL_TASKS_FIELD_GEO
:
1008 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
1009 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
1010 case E_CAL_MODEL_TASKS_FIELD_URL
:
1011 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
1012 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
1013 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
1014 return (gpointer
) value
;
1021 cal_model_tasks_free_value (ETableModel
*etm
,
1025 g_return_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
);
1027 if (col
< E_CAL_MODEL_FIELD_LAST
) {
1028 table_model_parent_interface
->free_value (etm
, col
, value
);
1033 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
1034 case E_CAL_MODEL_TASKS_FIELD_DUE
:
1038 case E_CAL_MODEL_TASKS_FIELD_GEO
:
1039 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
1040 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
1041 case E_CAL_MODEL_TASKS_FIELD_URL
:
1043 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
1044 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
1045 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
1051 cal_model_tasks_initialize_value (ETableModel
*etm
,
1054 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
1056 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), NULL
);
1057 g_return_val_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
, NULL
);
1059 if (col
< E_CAL_MODEL_FIELD_LAST
)
1060 return table_model_parent_interface
->initialize_value (etm
, col
);
1063 case E_CAL_MODEL_TASKS_FIELD_GEO
:
1064 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
1065 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
1066 case E_CAL_MODEL_TASKS_FIELD_URL
:
1067 return (gpointer
) "";
1068 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
1069 case E_CAL_MODEL_TASKS_FIELD_DUE
:
1070 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
1071 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
1073 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
1074 return GINT_TO_POINTER (-1);
1081 cal_model_tasks_value_is_empty (ETableModel
*etm
,
1083 gconstpointer value
)
1085 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
1087 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), TRUE
);
1088 g_return_val_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
, TRUE
);
1090 if (col
< E_CAL_MODEL_FIELD_LAST
)
1091 return table_model_parent_interface
->value_is_empty (etm
, col
, value
);
1094 case E_CAL_MODEL_TASKS_FIELD_GEO
:
1095 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
1096 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
1097 case E_CAL_MODEL_TASKS_FIELD_URL
:
1098 return string_is_empty (value
);
1099 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
1100 case E_CAL_MODEL_TASKS_FIELD_DUE
:
1101 return value
? FALSE
: TRUE
;
1102 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
1103 return (GPOINTER_TO_INT (value
) < 0) ? TRUE
: FALSE
;
1104 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
1105 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
1113 cal_model_tasks_value_to_string (ETableModel
*etm
,
1115 gconstpointer value
)
1117 ECalModelTasks
*model
= (ECalModelTasks
*) etm
;
1119 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), g_strdup (""));
1120 g_return_val_if_fail (col
>= 0 && col
< E_CAL_MODEL_TASKS_FIELD_LAST
, g_strdup (""));
1122 if (col
< E_CAL_MODEL_FIELD_LAST
)
1123 return table_model_parent_interface
->value_to_string (etm
, col
, value
);
1126 case E_CAL_MODEL_TASKS_FIELD_GEO
:
1127 case E_CAL_MODEL_TASKS_FIELD_PRIORITY
:
1128 case E_CAL_MODEL_TASKS_FIELD_STATUS
:
1129 case E_CAL_MODEL_TASKS_FIELD_URL
:
1130 return g_strdup (value
);
1131 case E_CAL_MODEL_TASKS_FIELD_COMPLETED
:
1132 case E_CAL_MODEL_TASKS_FIELD_DUE
:
1133 return e_cal_model_date_value_to_string (E_CAL_MODEL (model
), value
);
1134 case E_CAL_MODEL_TASKS_FIELD_COMPLETE
:
1135 case E_CAL_MODEL_TASKS_FIELD_OVERDUE
:
1136 return g_strdup (value
? _("Yes") : _("No"));
1137 case E_CAL_MODEL_TASKS_FIELD_PERCENT
:
1138 if (GPOINTER_TO_INT (value
) < 0)
1139 return g_strdup ("N/A");
1141 return g_strdup_printf ("%i%%", GPOINTER_TO_INT (value
));
1144 return g_strdup ("");
1148 e_cal_model_tasks_class_init (ECalModelTasksClass
*class)
1150 GObjectClass
*object_class
;
1151 ECalModelClass
*cal_model_class
;
1153 g_type_class_add_private (class, sizeof (ECalModelTasksPrivate
));
1155 object_class
= G_OBJECT_CLASS (class);
1156 object_class
->set_property
= cal_model_tasks_set_property
;
1157 object_class
->get_property
= cal_model_tasks_get_property
;
1158 object_class
->finalize
= cal_model_tasks_finalize
;
1160 cal_model_class
= E_CAL_MODEL_CLASS (class);
1161 cal_model_class
->get_color_for_component
= cal_model_tasks_get_color_for_component
;
1162 cal_model_class
->store_values_from_model
= cal_model_tasks_store_values_from_model
;
1163 cal_model_class
->fill_component_from_values
= cal_model_tasks_fill_component_from_values
;
1165 g_object_class_install_property (
1167 PROP_HIGHLIGHT_DUE_TODAY
,
1168 g_param_spec_boolean (
1169 "highlight-due-today",
1170 "Highlight Due Today",
1173 G_PARAM_READWRITE
));
1175 g_object_class_install_property (
1177 PROP_COLOR_DUE_TODAY
,
1178 g_param_spec_string (
1183 G_PARAM_READWRITE
));
1185 g_object_class_install_property (
1187 PROP_HIGHLIGHT_OVERDUE
,
1188 g_param_spec_boolean (
1189 "highlight-overdue",
1190 "Highlight Overdue",
1193 G_PARAM_READWRITE
));
1195 g_object_class_install_property (
1198 g_param_spec_string (
1203 G_PARAM_READWRITE
));
1207 e_cal_model_tasks_table_model_init (ETableModelInterface
*iface
)
1209 table_model_parent_interface
=
1210 g_type_interface_peek_parent (iface
);
1212 iface
->column_count
= cal_model_tasks_column_count
;
1214 iface
->value_at
= cal_model_tasks_value_at
;
1215 iface
->set_value_at
= cal_model_tasks_set_value_at
;
1216 iface
->is_cell_editable
= cal_model_tasks_is_cell_editable
;
1218 iface
->duplicate_value
= cal_model_tasks_duplicate_value
;
1219 iface
->free_value
= cal_model_tasks_free_value
;
1220 iface
->initialize_value
= cal_model_tasks_initialize_value
;
1221 iface
->value_is_empty
= cal_model_tasks_value_is_empty
;
1222 iface
->value_to_string
= cal_model_tasks_value_to_string
;
1226 e_cal_model_tasks_init (ECalModelTasks
*model
)
1228 model
->priv
= E_CAL_MODEL_TASKS_GET_PRIVATE (model
);
1230 model
->priv
->highlight_due_today
= TRUE
;
1231 model
->priv
->highlight_overdue
= TRUE
;
1233 e_cal_model_set_component_kind (
1234 E_CAL_MODEL (model
), ICAL_VTODO_COMPONENT
);
1238 e_cal_model_tasks_new (ECalDataModel
*data_model
,
1239 ESourceRegistry
*registry
,
1242 g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model
), NULL
);
1243 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry
), NULL
);
1244 g_return_val_if_fail (E_IS_SHELL (shell
), NULL
);
1246 return g_object_new (
1247 E_TYPE_CAL_MODEL_TASKS
,
1248 "data-model", data_model
,
1249 "registry", registry
,
1255 e_cal_model_tasks_get_highlight_due_today (ECalModelTasks
*model
)
1257 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), FALSE
);
1259 return model
->priv
->highlight_due_today
;
1263 e_cal_model_tasks_set_highlight_due_today (ECalModelTasks
*model
,
1266 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
1268 if (model
->priv
->highlight_due_today
== highlight
)
1271 model
->priv
->highlight_due_today
= highlight
;
1273 g_object_notify (G_OBJECT (model
), "highlight-due-today");
1277 e_cal_model_tasks_get_color_due_today (ECalModelTasks
*model
)
1279 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), NULL
);
1281 return model
->priv
->color_due_today
;
1285 e_cal_model_tasks_set_color_due_today (ECalModelTasks
*model
,
1286 const gchar
*color_due_today
)
1288 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
1289 g_return_if_fail (color_due_today
!= NULL
);
1291 if (g_strcmp0 (model
->priv
->color_due_today
, color_due_today
) == 0)
1294 g_free (model
->priv
->color_due_today
);
1295 model
->priv
->color_due_today
= g_strdup (color_due_today
);
1297 g_object_notify (G_OBJECT (model
), "color-due-today");
1301 e_cal_model_tasks_get_highlight_overdue (ECalModelTasks
*model
)
1303 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), FALSE
);
1305 return model
->priv
->highlight_overdue
;
1309 e_cal_model_tasks_set_highlight_overdue (ECalModelTasks
*model
,
1312 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
1314 if (model
->priv
->highlight_overdue
== highlight
)
1317 model
->priv
->highlight_overdue
= highlight
;
1319 g_object_notify (G_OBJECT (model
), "highlight-overdue");
1323 e_cal_model_tasks_get_color_overdue (ECalModelTasks
*model
)
1325 g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model
), NULL
);
1327 return model
->priv
->color_overdue
;
1331 e_cal_model_tasks_set_color_overdue (ECalModelTasks
*model
,
1332 const gchar
*color_overdue
)
1334 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
1335 g_return_if_fail (color_overdue
!= NULL
);
1337 if (g_strcmp0 (model
->priv
->color_overdue
, color_overdue
) == 0)
1340 g_free (model
->priv
->color_overdue
);
1341 model
->priv
->color_overdue
= g_strdup (color_overdue
);
1343 g_object_notify (G_OBJECT (model
), "color-overdue");
1347 * e_cal_model_tasks_mark_comp_complete
1348 * @model: Currently not used...
1349 * @comp_data: Component of our interest
1351 * Marks component as complete and commits changes to the calendar backend.
1354 e_cal_model_tasks_mark_comp_complete (ECalModelTasks
*model
,
1355 ECalModelComponent
*comp_data
)
1357 g_return_if_fail (model
!= NULL
);
1358 g_return_if_fail (comp_data
!= NULL
);
1360 /* we will receive changes when committed, so don't do this */
1361 /*e_table_model_pre_change (E_TABLE_MODEL (model));*/
1363 ensure_task_complete (comp_data
, -1);
1365 /*e_table_model_row_changed (E_TABLE_MODEL (model), model_row);*/
1367 e_cal_model_modify_component (E_CAL_MODEL (model
), comp_data
, E_CAL_OBJ_MOD_ALL
);
1371 * e_cal_model_tasks_mark_comp_incomplete
1372 * @model: Currently not used...
1373 * @comp_data: Component of our interest
1375 * Marks component as incomplete and commits changes to the calendar backend.
1378 e_cal_model_tasks_mark_comp_incomplete (ECalModelTasks
*model
,
1379 ECalModelComponent
*comp_data
)
1381 icalproperty
*prop
,*prop1
;
1383 g_return_if_fail (model
!= NULL
);
1384 g_return_if_fail (comp_data
!= NULL
);
1386 /* we will receive changes when committed, so don't do this */
1387 /*e_table_model_pre_change (E_TABLE_MODEL (model));*/
1390 prop
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_STATUS_PROPERTY
);
1392 icalproperty_set_status (prop
, ICAL_STATUS_NEEDSACTION
);
1394 icalcomponent_add_property (comp_data
->icalcomp
, icalproperty_new_status (ICAL_STATUS_NEEDSACTION
));
1396 /*complete property*/
1397 prop1
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_COMPLETED_PROPERTY
);
1399 icalcomponent_remove_property (comp_data
->icalcomp
, prop1
);
1400 icalproperty_free (prop1
);
1404 prop1
= icalcomponent_get_first_property (comp_data
->icalcomp
, ICAL_PERCENTCOMPLETE_PROPERTY
);
1406 icalcomponent_remove_property (comp_data
->icalcomp
, prop1
);
1407 icalproperty_free (prop1
);
1410 /*e_table_model_row_changed (E_TABLE_MODEL (model), model_row);*/
1412 e_cal_model_modify_component (E_CAL_MODEL (model
), comp_data
, E_CAL_OBJ_MOD_ALL
);
1416 e_cal_model_tasks_update_due_tasks (ECalModelTasks
*model
)
1418 gint row
, row_count
;
1419 ECalModelComponent
*comp_data
;
1420 ECalModelTasksDueStatus status
;
1422 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model
));
1424 row_count
= e_table_model_row_count (E_TABLE_MODEL (model
));
1426 for (row
= 0; row
< row_count
; row
++)
1428 comp_data
= e_cal_model_get_component_at (E_CAL_MODEL (model
), row
);
1429 status
= get_due_status (E_CAL_MODEL_TASKS (model
), comp_data
);
1430 if ((status
== E_CAL_MODEL_TASKS_DUE_TODAY
) || (status
== E_CAL_MODEL_TASKS_DUE_OVERDUE
))
1432 e_table_model_pre_change (E_TABLE_MODEL (model
));
1433 e_table_model_row_changed (E_TABLE_MODEL (model
), row
);