Bug 793125 - Crash due to popup menus left attached too long
[evolution.git] / src / calendar / gui / e-cal-model-tasks.c
blob02ce42ff56e89106353e3f2fbcd57a6ddd7ac7eb
1 /*
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
11 * for more details.
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/>.
17 * Authors:
18 * Rodrigo Moya <rodrigo@ximian.com>
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
24 #include "evolution-config.h"
26 #include <math.h>
27 #include <string.h>
28 #include <gtk/gtk.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"
34 #include "misc.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;
44 gchar *color_overdue;
47 enum {
48 PROP_0,
49 PROP_HIGHLIGHT_DUE_TODAY,
50 PROP_COLOR_DUE_TODAY,
51 PROP_HIGHLIGHT_OVERDUE,
52 PROP_COLOR_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 (
62 ECalModelTasks,
63 e_cal_model_tasks,
64 E_TYPE_CAL_MODEL,
65 G_IMPLEMENT_INTERFACE (
66 E_TYPE_TABLE_MODEL,
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. */
75 static void
76 ensure_task_complete (ECalModelComponent *comp_data,
77 time_t completed_date)
79 icalproperty *prop;
80 gboolean set_completed = TRUE;
82 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
84 /* Date Completed. */
85 if (completed_date == -1) {
86 if (prop)
87 set_completed = FALSE;
88 else
89 completed_date = time (NULL);
92 if (set_completed) {
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 (
99 completed_date,
100 FALSE,
101 utc_zone);
102 if (prop)
103 icalproperty_set_completed (prop, new_completed);
104 else {
105 prop = icalproperty_new_completed (new_completed);
106 icalcomponent_add_property (comp_data->icalcomp, prop);
110 /* Percent. */
111 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
112 if (!prop)
113 icalcomponent_add_property (comp_data->icalcomp, icalproperty_new_percentcomplete (100));
114 else
115 icalproperty_set_percentcomplete (prop, 100);
117 /* Status. */
118 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
119 if (prop)
120 icalproperty_set_status (prop, ICAL_STATUS_COMPLETED);
121 else
122 icalcomponent_add_property (comp_data->icalcomp, icalproperty_new_status (ICAL_STATUS_COMPLETED));
125 static void
126 ensure_task_partially_complete (ECalModelComponent *comp_data)
128 icalproperty *prop;
130 /* Date Completed. */
131 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
132 if (prop) {
133 icalcomponent_remove_property (comp_data->icalcomp, prop);
134 icalproperty_free (prop);
137 /* Percent. */
138 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
139 if (!prop)
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);
144 /* Status. */
145 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
146 if (prop)
147 icalproperty_set_status (prop, ICAL_STATUS_INPROCESS);
148 else
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. */
156 static void
157 ensure_task_not_complete (ECalModelComponent *comp_data)
159 icalproperty *prop;
161 /* Date Completed. */
162 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
163 if (prop) {
164 icalcomponent_remove_property (comp_data->icalcomp, prop);
165 icalproperty_free (prop);
168 /* Percent. */
169 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
170 if (prop) {
171 icalcomponent_remove_property (comp_data->icalcomp, prop);
172 icalproperty_free (prop);
175 /* Status. */
176 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
177 if (prop)
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) {
187 icaltimezone *zone;
188 icalproperty *prop;
190 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
191 if (!prop)
192 return NULL;
194 tt_completed = icalproperty_get_completed (prop);
195 if (!icaltime_is_valid_time (tt_completed) || icaltime_is_null_time (tt_completed))
196 return NULL;
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;
204 else
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) {
217 icaltimezone *zone;
218 icalproperty *prop;
220 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DUE_PROPERTY);
221 if (!prop)
222 return NULL;
224 tt_due = icalproperty_get_due (prop);
225 if (!icaltime_is_valid_time (tt_due) || icaltime_is_null_time (tt_due))
226 return NULL;
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;
234 else
235 comp_data->due->zone = NULL;
238 return e_cal_model_copy_cell_date_value (comp_data->due);
241 static gpointer
242 get_geo (ECalModelComponent *comp_data)
244 icalproperty *prop;
245 struct icalgeotype geo;
246 static gchar buf[32];
248 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_GEO_PROPERTY);
249 if (prop) {
250 geo = icalproperty_get_geo (prop);
251 g_snprintf (
252 buf, sizeof (buf), "%g %s, %g %s",
253 fabs (geo.lat),
254 geo.lat >= 0.0 ? "N" : "S",
255 fabs (geo.lon),
256 geo.lon >= 0.0 ? "E" : "W");
257 return buf;
260 return (gpointer) "";
263 static gint
264 get_percent (ECalModelComponent *comp_data)
266 icalproperty *prop;
268 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
269 if (prop)
270 return icalproperty_get_percentcomplete (prop);
272 return 0;
275 static gpointer
276 get_priority (ECalModelComponent *comp_data)
278 icalproperty *prop;
280 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PRIORITY_PROPERTY);
281 if (prop)
282 return (gpointer) e_cal_util_priority_to_string (icalproperty_get_priority (prop));
284 return (gpointer) "";
287 static gboolean
288 is_status_canceled (ECalModelComponent *comp_data)
290 icalproperty *prop;
292 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
294 return prop && icalproperty_get_status (prop) == ICAL_STATUS_CANCELLED;
297 static gpointer
298 get_status (ECalModelComponent *comp_data)
300 icalproperty *prop;
302 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
303 if (prop) {
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");
315 default:
316 return (gpointer) "";
320 return (gpointer) "";
323 static gpointer
324 get_url (ECalModelComponent *comp_data)
326 icalproperty *prop;
328 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY);
329 if (prop)
330 return (gpointer) icalproperty_get_url (prop);
332 return (gpointer) "";
335 static gboolean
336 is_complete (ECalModelComponent *comp_data)
338 icalproperty *prop;
340 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
341 if (prop)
342 return TRUE;
344 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
345 if (prop && icalproperty_get_percentcomplete (prop) == 100)
346 return TRUE;
348 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
349 if (prop && icalproperty_get_status (prop) == ICAL_STATUS_COMPLETED)
350 return TRUE;
352 return FALSE;
355 typedef enum {
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)
367 icalproperty *prop;
369 /* First, do we have a due date? */
370 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DUE_PROPERTY);
371 if (!prop)
372 return E_CAL_MODEL_TASKS_DUE_NEVER;
373 else {
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) {
384 gint cmp;
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);
389 if (cmp < 0)
390 return E_CAL_MODEL_TASKS_DUE_OVERDUE;
391 else if (cmp == 0)
392 return E_CAL_MODEL_TASKS_DUE_TODAY;
393 else
394 return E_CAL_MODEL_TASKS_DUE_FUTURE;
395 } else {
396 icalparameter *param;
397 const gchar *tzid;
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);
406 if (zone == 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;
413 else
414 if (icaltime_compare_date_only (due_tt, now_tt) == 0)
415 return E_CAL_MODEL_TASKS_DUE_TODAY;
416 else
417 return E_CAL_MODEL_TASKS_DUE_FUTURE;
422 static gboolean
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:
430 return FALSE;
431 case E_CAL_MODEL_TASKS_DUE_TODAY:
432 case E_CAL_MODEL_TASKS_DUE_OVERDUE:
433 return TRUE;
436 return FALSE;
439 static void
440 set_completed (ECalModelTasks *model,
441 ECalModelComponent *comp_data,
442 gconstpointer value)
444 ECellDateEditValue *dv = (ECellDateEditValue *) value;
446 if (!dv)
447 ensure_task_not_complete (comp_data);
448 else {
449 time_t t;
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)));
456 } else {
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);
466 static void
467 set_complete (ECalModelComponent *comp_data,
468 gconstpointer value)
470 gint state = GPOINTER_TO_INT (value);
472 if (state)
473 ensure_task_complete (comp_data, -1);
474 else
475 ensure_task_not_complete (comp_data);
478 static void
479 set_due (ECalModel *model,
480 ECalModelComponent *comp_data,
481 gconstpointer value)
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.
489 static void
490 show_geo_warning (void)
492 GtkWidget *dialog;
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);
501 static void
502 set_geo (ECalModelComponent *comp_data,
503 const gchar *value)
505 gdouble latitude, longitude;
506 gint matched;
507 struct icalgeotype geo;
508 icalproperty *prop;
510 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_GEO_PROPERTY);
512 if (string_is_empty (value)) {
513 if (prop) {
514 icalcomponent_remove_property (comp_data->icalcomp, prop);
515 icalproperty_free (prop);
517 } else {
518 matched = sscanf (value, "%lg , %lg", &latitude, &longitude);
519 if (matched != 2)
520 show_geo_warning ();
522 geo.lat = latitude;
523 geo.lon = longitude;
524 if (prop)
525 icalproperty_set_geo (prop, geo);
526 else {
527 prop = icalproperty_new_geo (geo);
528 icalcomponent_add_property (comp_data->icalcomp, prop);
534 static void
535 set_status (ECalModelComponent *comp_data,
536 const gchar *value)
538 icalproperty_status status;
539 icalproperty *prop;
541 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
543 /* an empty string is the same as 'None' */
544 if (!value[0])
545 return;
547 /* Translators: "None" for task's status */
548 if (!e_util_utf8_strcasecmp (value, C_("cal-task-status", "None")))
549 return;
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;
558 else {
559 g_warning ("Invalid status: %s\n", value);
560 return;
563 if (prop)
564 icalproperty_set_status (prop, status);
565 else {
566 prop = icalproperty_new_status (status);
567 icalcomponent_add_property (comp_data->icalcomp, prop);
570 switch (status) {
571 case ICAL_STATUS_NEEDSACTION:
572 ensure_task_not_complete (comp_data);
573 break;
575 case ICAL_STATUS_INPROCESS:
576 ensure_task_partially_complete (comp_data);
577 break;
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);
583 break;
585 case ICAL_STATUS_COMPLETED:
586 ensure_task_complete (comp_data, -1);
587 break;
589 /* to make compiler happy */
590 /* coverity[dead_error_begin] */
591 default:
592 break;
596 static void
597 set_percent (ECalModelComponent *comp_data,
598 gconstpointer value)
600 icalproperty *prop;
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 */
609 if (percent == -1) {
610 if (prop) {
611 icalcomponent_remove_property (comp_data->icalcomp, prop);
612 icalproperty_free (prop);
614 ensure_task_not_complete (comp_data);
615 } else {
616 if (prop)
617 icalproperty_set_percentcomplete (prop, percent);
618 else {
619 prop = icalproperty_new_percentcomplete (percent);
620 icalcomponent_add_property (comp_data->icalcomp, prop);
623 if (percent == 100)
624 ensure_task_complete (comp_data, -1);
625 else {
626 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
627 if (prop) {
628 icalcomponent_remove_property (comp_data->icalcomp, prop);
629 icalproperty_free (prop);
632 if (percent > 0)
633 set_status (comp_data, _("In Progress"));
639 static void
640 set_priority (ECalModelComponent *comp_data,
641 const gchar *value)
643 icalproperty *prop;
644 gint priority;
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");
651 priority = 0;
654 if (prop)
655 icalproperty_set_priority (prop, priority);
656 else {
657 prop = icalproperty_new_priority (priority);
658 icalcomponent_add_property (comp_data->icalcomp, prop);
662 static void
663 set_url (ECalModelComponent *comp_data,
664 const gchar *value)
666 icalproperty *prop;
668 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY);
670 if (string_is_empty (value)) {
671 if (prop) {
672 icalcomponent_remove_property (comp_data->icalcomp, prop);
673 icalproperty_free (prop);
675 } else {
676 if (prop)
677 icalproperty_set_url (prop, value);
678 else {
679 prop = icalproperty_new_url (value);
680 icalcomponent_add_property (comp_data->icalcomp, prop);
685 static void
686 cal_model_tasks_set_property (GObject *object,
687 guint property_id,
688 const GValue *value,
689 GParamSpec *pspec)
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));
696 return;
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));
702 return;
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));
708 return;
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));
714 return;
717 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
720 static void
721 cal_model_tasks_get_property (GObject *object,
722 guint property_id,
723 GValue *value,
724 GParamSpec *pspec)
726 switch (property_id) {
727 case PROP_HIGHLIGHT_DUE_TODAY:
728 g_value_set_boolean (
729 value,
730 e_cal_model_tasks_get_highlight_due_today (
731 E_CAL_MODEL_TASKS (object)));
732 return;
734 case PROP_COLOR_DUE_TODAY:
735 g_value_set_string (
736 value,
737 e_cal_model_tasks_get_color_due_today (
738 E_CAL_MODEL_TASKS (object)));
739 return;
741 case PROP_HIGHLIGHT_OVERDUE:
742 g_value_set_boolean (
743 value,
744 e_cal_model_tasks_get_highlight_overdue (
745 E_CAL_MODEL_TASKS (object)));
746 return;
748 case PROP_COLOR_OVERDUE:
749 g_value_set_string (
750 value,
751 e_cal_model_tasks_get_color_overdue (
752 E_CAL_MODEL_TASKS (object)));
753 return;
756 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
759 static void
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);
773 static const gchar *
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))
790 break;
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))
794 break;
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:
799 break;
802 return E_CAL_MODEL_CLASS (e_cal_model_tasks_parent_class)->
803 get_color_for_component (model, comp_data);
806 static void
807 cal_model_tasks_store_values_from_model (ECalModel *model,
808 ETableModel *source_model,
809 gint row,
810 GHashTable *values)
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);
825 static void
826 cal_model_tasks_fill_component_from_values (ECalModel *model,
827 ECalModelComponent *comp_data,
828 GHashTable *values)
830 gpointer value;
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);
841 if (!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));
854 static gint
855 cal_model_tasks_column_count (ETableModel *etm)
857 return E_CAL_MODEL_TASKS_FIELD_LAST;
860 static gpointer
861 cal_model_tasks_value_at (ETableModel *etm,
862 gint col,
863 gint row)
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);
877 if (!comp_data)
878 return (gpointer) "";
880 switch (col) {
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) "";
906 static void
907 cal_model_tasks_set_value_at (ETableModel *etm,
908 gint col,
909 gint row,
910 gconstpointer value)
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);
922 return;
925 comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
926 if (!comp_data)
927 return;
929 switch (col) {
930 case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
931 set_completed (model, comp_data, value);
932 break;
933 case E_CAL_MODEL_TASKS_FIELD_COMPLETE :
934 set_complete (comp_data, value);
935 break;
936 case E_CAL_MODEL_TASKS_FIELD_DUE :
937 set_due ((ECalModel *) model, comp_data, value);
938 break;
939 case E_CAL_MODEL_TASKS_FIELD_GEO :
940 set_geo (comp_data, value);
941 break;
942 case E_CAL_MODEL_TASKS_FIELD_PERCENT :
943 set_percent (comp_data, value);
944 break;
945 case E_CAL_MODEL_TASKS_FIELD_PRIORITY :
946 set_priority (comp_data, value);
947 break;
948 case E_CAL_MODEL_TASKS_FIELD_STATUS :
949 set_status (comp_data, value);
950 break;
951 case E_CAL_MODEL_TASKS_FIELD_URL :
952 set_url (comp_data, value);
953 break;
956 e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL);
959 static gboolean
960 cal_model_tasks_is_cell_editable (ETableModel *etm,
961 gint col,
962 gint row)
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))
975 return FALSE;
977 switch (col) {
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 :
986 return TRUE;
989 return FALSE;
992 static gpointer
993 cal_model_tasks_duplicate_value (ETableModel *etm,
994 gint col,
995 gconstpointer value)
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);
1002 switch (col) {
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;
1017 return NULL;
1020 static void
1021 cal_model_tasks_free_value (ETableModel *etm,
1022 gint col,
1023 gpointer value)
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);
1029 return;
1032 switch (col) {
1033 case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
1034 case E_CAL_MODEL_TASKS_FIELD_DUE :
1035 if (value)
1036 g_free (value);
1037 break;
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 :
1042 break;
1043 case E_CAL_MODEL_TASKS_FIELD_PERCENT :
1044 case E_CAL_MODEL_TASKS_FIELD_COMPLETE :
1045 case E_CAL_MODEL_TASKS_FIELD_OVERDUE :
1046 break;
1050 static gpointer
1051 cal_model_tasks_initialize_value (ETableModel *etm,
1052 gint col)
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);
1062 switch (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 :
1072 return NULL;
1073 case E_CAL_MODEL_TASKS_FIELD_PERCENT :
1074 return GINT_TO_POINTER (-1);
1077 return NULL;
1080 static gboolean
1081 cal_model_tasks_value_is_empty (ETableModel *etm,
1082 gint col,
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);
1093 switch (col) {
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 :
1106 return TRUE;
1109 return TRUE;
1112 static gchar *
1113 cal_model_tasks_value_to_string (ETableModel *etm,
1114 gint col,
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);
1125 switch (col) {
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");
1140 else
1141 return g_strdup_printf ("%i%%", GPOINTER_TO_INT (value));
1144 return g_strdup ("");
1147 static void
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 (
1166 object_class,
1167 PROP_HIGHLIGHT_DUE_TODAY,
1168 g_param_spec_boolean (
1169 "highlight-due-today",
1170 "Highlight Due Today",
1171 NULL,
1172 TRUE,
1173 G_PARAM_READWRITE));
1175 g_object_class_install_property (
1176 object_class,
1177 PROP_COLOR_DUE_TODAY,
1178 g_param_spec_string (
1179 "color-due-today",
1180 "Color Due Today",
1181 NULL,
1182 "#1e90ff",
1183 G_PARAM_READWRITE));
1185 g_object_class_install_property (
1186 object_class,
1187 PROP_HIGHLIGHT_OVERDUE,
1188 g_param_spec_boolean (
1189 "highlight-overdue",
1190 "Highlight Overdue",
1191 NULL,
1192 TRUE,
1193 G_PARAM_READWRITE));
1195 g_object_class_install_property (
1196 object_class,
1197 PROP_COLOR_OVERDUE,
1198 g_param_spec_string (
1199 "color-overdue",
1200 "Color Overdue",
1201 NULL,
1202 "#ff0000",
1203 G_PARAM_READWRITE));
1206 static void
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;
1225 static void
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);
1237 ECalModel *
1238 e_cal_model_tasks_new (ECalDataModel *data_model,
1239 ESourceRegistry *registry,
1240 EShell *shell)
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,
1250 "shell", shell,
1251 NULL);
1254 gboolean
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;
1262 void
1263 e_cal_model_tasks_set_highlight_due_today (ECalModelTasks *model,
1264 gboolean highlight)
1266 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model));
1268 if (model->priv->highlight_due_today == highlight)
1269 return;
1271 model->priv->highlight_due_today = highlight;
1273 g_object_notify (G_OBJECT (model), "highlight-due-today");
1276 const gchar *
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;
1284 void
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)
1292 return;
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");
1300 gboolean
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;
1308 void
1309 e_cal_model_tasks_set_highlight_overdue (ECalModelTasks *model,
1310 gboolean highlight)
1312 g_return_if_fail (E_IS_CAL_MODEL_TASKS (model));
1314 if (model->priv->highlight_overdue == highlight)
1315 return;
1317 model->priv->highlight_overdue = highlight;
1319 g_object_notify (G_OBJECT (model), "highlight-overdue");
1322 const gchar *
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;
1330 void
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)
1338 return;
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.
1353 void
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.
1377 void
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));*/
1389 /* Status */
1390 prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY);
1391 if (prop)
1392 icalproperty_set_status (prop, ICAL_STATUS_NEEDSACTION);
1393 else
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);
1398 if (prop1) {
1399 icalcomponent_remove_property (comp_data->icalcomp, prop1);
1400 icalproperty_free (prop1);
1403 /* Percent. */
1404 prop1 = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY);
1405 if (prop1) {
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);
1415 void
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);