summaryrefslogtreecommitdiff
path: root/applets/clock/calendar-client.c
diff options
context:
space:
mode:
Diffstat (limited to 'applets/clock/calendar-client.c')
-rw-r--r--applets/clock/calendar-client.c2171
1 files changed, 0 insertions, 2171 deletions
diff --git a/applets/clock/calendar-client.c b/applets/clock/calendar-client.c
deleted file mode 100644
index 8619a3b6..00000000
--- a/applets/clock/calendar-client.c
+++ /dev/null
@@ -1,2171 +0,0 @@
-/*
- * Copyright (C) 2004 Free Software Foundation, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Authors:
- * Mark McLoughlin <[email protected]>
- * William Jon McCann <[email protected]>
- * Martin Grimme <[email protected]>
- * Christian Kellner <[email protected]>
- */
-
-#include <config.h>
-
-#include "calendar-client.h"
-
-#include <mateconf/mateconf-client.h>
-
-#include <libintl.h>
-#include <string.h>
-#define HANDLE_LIBICAL_MEMORY
-#include <libecal/e-cal.h>
-#include <libecal/e-cal-time-util.h>
-#include <libecal/e-cal-recur.h>
-
-#include "calendar-sources.h"
-
-#undef CALENDAR_ENABLE_DEBUG
-#include "calendar-debug.h"
-
-#define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar"
-#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone"
-
-#ifndef _
-#define _(x) gettext(x)
-#endif
-
-#ifndef N_
-#define N_(x) x
-#endif
-
-#define CALENDAR_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CALENDAR_TYPE_CLIENT, CalendarClientPrivate))
-
-typedef struct _CalendarClientQuery CalendarClientQuery;
-typedef struct _CalendarClientSource CalendarClientSource;
-
-struct _CalendarClientQuery
-{
- ECalView *view;
- GHashTable *events;
-};
-
-struct _CalendarClientSource
-{
- CalendarClient *client;
- ECal *source;
-
- CalendarClientQuery completed_query;
- CalendarClientQuery in_progress_query;
-
- guint changed_signal_id;
-
- guint query_completed : 1;
- guint query_in_progress : 1;
-};
-
-struct _CalendarClientPrivate
-{
- CalendarSources *calendar_sources;
-
- GSList *appointment_sources;
- GSList *task_sources;
-
- icaltimezone *zone;
-
- guint zone_listener;
- MateConfClient *mateconf_client;
-
- guint day;
- guint month;
- guint year;
-};
-
-static void calendar_client_class_init (CalendarClientClass *klass);
-static void calendar_client_init (CalendarClient *client);
-static void calendar_client_finalize (GObject *object);
-static void calendar_client_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void calendar_client_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-static GSList *calendar_client_update_sources_list (CalendarClient *client,
- GSList *sources,
- GSList *esources,
- guint changed_signal_id);
-static void calendar_client_appointment_sources_changed (CalendarClient *client);
-static void calendar_client_task_sources_changed (CalendarClient *client);
-
-static void calendar_client_stop_query (CalendarClient *client,
- CalendarClientSource *source,
- CalendarClientQuery *query);
-static void calendar_client_start_query (CalendarClient *client,
- CalendarClientSource *source,
- const char *query);
-
-static void calendar_client_source_finalize (CalendarClientSource *source);
-static void calendar_client_query_finalize (CalendarClientQuery *query);
-
-static void
-calendar_client_update_appointments (CalendarClient *client);
-static void
-calendar_client_update_tasks (CalendarClient *client);
-
-enum
-{
- PROP_O,
- PROP_DAY,
- PROP_MONTH,
- PROP_YEAR
-};
-
-enum
-{
- APPOINTMENTS_CHANGED,
- TASKS_CHANGED,
- LAST_SIGNAL
-};
-
-static GObjectClass *parent_class = NULL;
-static guint signals [LAST_SIGNAL] = { 0, };
-
-GType
-calendar_client_get_type (void)
-{
- static GType client_type = 0;
-
- if (!client_type)
- {
- static const GTypeInfo client_info =
- {
- sizeof (CalendarClientClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) calendar_client_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (CalendarClient),
- 0, /* n_preallocs */
- (GInstanceInitFunc) calendar_client_init,
- };
-
- client_type = g_type_register_static (G_TYPE_OBJECT,
- "CalendarClient",
- &client_info, 0);
- }
-
- return client_type;
-}
-
-static void
-calendar_client_class_init (CalendarClientClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *) klass;
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->finalize = calendar_client_finalize;
- gobject_class->set_property = calendar_client_set_property;
- gobject_class->get_property = calendar_client_get_property;
-
- g_type_class_add_private (klass, sizeof (CalendarClientPrivate));
-
- g_object_class_install_property (gobject_class,
- PROP_DAY,
- g_param_spec_uint ("day",
- "Day",
- "The currently monitored day between 1 and 31 (0 denotes unset)",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_MONTH,
- g_param_spec_uint ("month",
- "Month",
- "The currently monitored month between 0 and 11",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_YEAR,
- g_param_spec_uint ("year",
- "Year",
- "The currently monitored year",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
-
- signals [APPOINTMENTS_CHANGED] =
- g_signal_new ("appointments-changed",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (CalendarClientClass, tasks_changed),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- signals [TASKS_CHANGED] =
- g_signal_new ("tasks-changed",
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (CalendarClientClass, tasks_changed),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-}
-
-/* Timezone code adapted from evolution/calendar/gui/calendar-config.c */
-/* The current timezone, e.g. "Europe/London". It may be NULL, in which case
- you should assume UTC. */
-static gchar *
-calendar_client_config_get_timezone (MateConfClient *mateconf_client)
-{
- char *location;
-
- location = mateconf_client_get_string (mateconf_client,
- CALENDAR_CONFIG_TIMEZONE,
- NULL);
-
- return location;
-}
-
-static icaltimezone *
-calendar_client_config_get_icaltimezone (MateConfClient *mateconf_client)
-{
- char *location;
- icaltimezone *zone = NULL;
-
- location = calendar_client_config_get_timezone (mateconf_client);
- if (!location)
- return icaltimezone_get_utc_timezone ();
-
- zone = icaltimezone_get_builtin_timezone (location);
- g_free (location);
-
- return zone;
-}
-
-static void
-calendar_client_set_timezone (CalendarClient *client)
-{
- GSList *l;
- GSList *esources;
-
- client->priv->zone = calendar_client_config_get_icaltimezone (client->priv->mateconf_client);
-
- esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
- for (l = esources; l; l = l->next) {
- ECal *source = l->data;
-
- e_cal_set_default_timezone (source, client->priv->zone, NULL);
- }
-}
-
-static void
-calendar_client_timezone_changed_cb (MateConfClient *mateconf_client,
- guint id,
- MateConfEntry *entry,
- CalendarClient *client)
-{
- calendar_client_set_timezone (client);
-}
-
-static void
-cal_opened_cb (ECal *ecal,
- ECalendarStatus status,
- CalendarClientSource *cl_source)
-{
- ECalSourceType s_type;
- CalendarClient *client = cl_source->client;
-
- s_type = e_cal_get_source_type (ecal);
-
- if (status == E_CALENDAR_STATUS_BUSY &&
- e_cal_get_load_state (ecal) == E_CAL_LOAD_NOT_LOADED)
- {
- e_cal_open_async (ecal, FALSE);
- return;
- }
-
- g_signal_handlers_disconnect_by_func (ecal, cal_opened_cb, cl_source);
-
- if (status != E_CALENDAR_STATUS_OK)
- {
- if (s_type == E_CAL_SOURCE_TYPE_EVENT)
- client->priv->appointment_sources = g_slist_remove (client->priv->appointment_sources,
- cl_source);
- else
- client->priv->task_sources = g_slist_remove (client->priv->task_sources,
- cl_source);
-
- calendar_client_source_finalize (cl_source);
- g_free (cl_source);
-
- return;
- }
-
- if (s_type == E_CAL_SOURCE_TYPE_EVENT)
- calendar_client_update_appointments (client);
- else
- calendar_client_update_tasks (client);
-}
-
-static void
-load_calendars (CalendarClient *client,
- CalendarEventType type)
-{
- GSList *l, *clients;
-
- switch (type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- clients = client->priv->appointment_sources;
- break;
- case CALENDAR_EVENT_TASK:
- clients = client->priv->task_sources;
- break;
- default:
- g_assert_not_reached ();
- }
-
- for (l = clients; l != NULL; l = l->next)
- {
- ECal *ecal;
- CalendarClientSource *cl_source = l->data;
-
- ecal = cl_source->source;
-
- if (e_cal_get_load_state (ecal) == E_CAL_LOAD_LOADED)
- continue;
-
- g_signal_connect (G_OBJECT (ecal), "cal_opened",
- G_CALLBACK (cal_opened_cb), cl_source);
- e_cal_open_async (ecal, TRUE);
- }
-}
-
-static void
-calendar_client_init (CalendarClient *client)
-{
- GSList *esources;
-
- client->priv = CALENDAR_CLIENT_GET_PRIVATE (client);
-
- client->priv->calendar_sources = calendar_sources_get ();
- client->priv->mateconf_client = mateconf_client_get_default ();
-
- esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
- client->priv->appointment_sources =
- calendar_client_update_sources_list (client, NULL, esources, signals [APPOINTMENTS_CHANGED]);
-
- esources = calendar_sources_get_task_sources (client->priv->calendar_sources);
- client->priv->task_sources =
- calendar_client_update_sources_list (client, NULL, esources, signals [TASKS_CHANGED]);
-
- /* set the timezone before loading the clients */
- calendar_client_set_timezone (client);
- load_calendars (client, CALENDAR_EVENT_APPOINTMENT);
- load_calendars (client, CALENDAR_EVENT_TASK);
-
- g_signal_connect_swapped (client->priv->calendar_sources,
- "appointment-sources-changed",
- G_CALLBACK (calendar_client_appointment_sources_changed),
- client);
- g_signal_connect_swapped (client->priv->calendar_sources,
- "task-sources-changed",
- G_CALLBACK (calendar_client_task_sources_changed),
- client);
-
- mateconf_client_add_dir (client->priv->mateconf_client,
- CALENDAR_CONFIG_PREFIX,
- MATECONF_CLIENT_PRELOAD_NONE,
- NULL);
-
- client->priv->zone_listener = mateconf_client_notify_add (client->priv->mateconf_client,
- CALENDAR_CONFIG_TIMEZONE,
- (MateConfClientNotifyFunc) calendar_client_timezone_changed_cb,
- client, NULL, NULL);
-
- client->priv->day = -1;
- client->priv->month = -1;
- client->priv->year = -1;
-}
-
-static void
-calendar_client_finalize (GObject *object)
-{
- CalendarClient *client = CALENDAR_CLIENT (object);
- GSList *l;
-
- if (client->priv->zone_listener)
- {
- mateconf_client_notify_remove (client->priv->mateconf_client,
- client->priv->zone_listener);
- client->priv->zone_listener = 0;
- }
-
- mateconf_client_remove_dir (client->priv->mateconf_client,
- CALENDAR_CONFIG_PREFIX,
- NULL);
-
- if (client->priv->mateconf_client)
- g_object_unref (client->priv->mateconf_client);
- client->priv->mateconf_client = NULL;
-
- for (l = client->priv->appointment_sources; l; l = l->next)
- {
- calendar_client_source_finalize (l->data);
- g_free (l->data);
- }
- g_slist_free (client->priv->appointment_sources);
- client->priv->appointment_sources = NULL;
-
- for (l = client->priv->task_sources; l; l = l->next)
- {
- calendar_client_source_finalize (l->data);
- g_free (l->data);
- }
- g_slist_free (client->priv->task_sources);
- client->priv->task_sources = NULL;
-
- if (client->priv->calendar_sources)
- g_object_unref (client->priv->calendar_sources);
- client->priv->calendar_sources = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-calendar_client_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- CalendarClient *client = CALENDAR_CLIENT (object);
-
- switch (prop_id)
- {
- case PROP_DAY:
- calendar_client_select_day (client, g_value_get_uint (value));
- break;
- case PROP_MONTH:
- calendar_client_select_month (client,
- g_value_get_uint (value),
- client->priv->year);
- break;
- case PROP_YEAR:
- calendar_client_select_month (client,
- client->priv->month,
- g_value_get_uint (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-calendar_client_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- CalendarClient *client = CALENDAR_CLIENT (object);
-
- switch (prop_id)
- {
- case PROP_DAY:
- g_value_set_uint (value, client->priv->day);
- break;
- case PROP_MONTH:
- g_value_set_uint (value, client->priv->month);
- break;
- case PROP_YEAR:
- g_value_set_uint (value, client->priv->year);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-CalendarClient *
-calendar_client_new (void)
-{
- return g_object_new (CALENDAR_TYPE_CLIENT, NULL);
-}
-
-/* @day and @month can happily be out of range as
- * mktime() will normalize them correctly. From mktime(3):
- *
- * "If structure members are outside their legal interval,
- * they will be normalized (so that, e.g., 40 October is
- * changed into 9 November)."
- *
- * "What?", you say, "Something useful in libc?"
- */
-static inline time_t
-make_time_for_day_begin (int day,
- int month,
- int year)
-{
- struct tm localtime_tm = { 0, };
-
- localtime_tm.tm_mday = day;
- localtime_tm.tm_mon = month;
- localtime_tm.tm_year = year - 1900;
- localtime_tm.tm_isdst = -1;
-
- return mktime (&localtime_tm);
-}
-
-static inline char *
-make_isodate_for_day_begin (int day,
- int month,
- int year)
-{
- time_t utctime;
-
- utctime = make_time_for_day_begin (day, month, year);
-
- return utctime != -1 ? isodate_from_time_t (utctime) : NULL;
-}
-
-static time_t
-get_time_from_property (icalcomponent *ical,
- icalproperty_kind prop_kind,
- struct icaltimetype (* get_prop_func) (const icalproperty *prop),
- icaltimezone *default_zone)
-{
- icalproperty *prop;
- struct icaltimetype ical_time;
- icalparameter *param;
- icaltimezone *timezone = NULL;
-
- prop = icalcomponent_get_first_property (ical, prop_kind);
- if (!prop)
- return 0;
-
- ical_time = get_prop_func (prop);
-
- param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
- if (param)
- timezone = icaltimezone_get_builtin_timezone_from_tzid (icalparameter_get_tzid (param));
- else if (icaltime_is_utc (ical_time))
- timezone = icaltimezone_get_utc_timezone ();
- else
- timezone = default_zone;
-
- return icaltime_as_timet_with_zone (ical_time, timezone);
-}
-
-static char *
-get_ical_uid (icalcomponent *ical)
-{
- return g_strdup (icalcomponent_get_uid (ical));
-}
-
-static char *
-get_ical_rid (icalcomponent *ical)
-{
- icalproperty *prop;
- struct icaltimetype ical_time;
-
- prop = icalcomponent_get_first_property (ical, ICAL_RECURRENCEID_PROPERTY);
- if (!prop)
- return NULL;
-
- ical_time = icalproperty_get_recurrenceid (prop);
-
- return icaltime_is_valid_time (ical_time) && !icaltime_is_null_time (ical_time) ?
- g_strdup (icaltime_as_ical_string (ical_time)) : NULL;
-}
-
-static char *
-get_ical_summary (icalcomponent *ical)
-{
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (ical, ICAL_SUMMARY_PROPERTY);
- if (!prop)
- return NULL;
-
- return g_strdup (icalproperty_get_summary (prop));
-}
-
-static char *
-get_ical_description (icalcomponent *ical)
-{
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (ical, ICAL_DESCRIPTION_PROPERTY);
- if (!prop)
- return NULL;
-
- return g_strdup (icalproperty_get_description (prop));
-}
-
-static inline time_t
-get_ical_start_time (icalcomponent *ical,
- icaltimezone *default_zone)
-{
- return get_time_from_property (ical,
- ICAL_DTSTART_PROPERTY,
- icalproperty_get_dtstart,
- default_zone);
-}
-
-static inline time_t
-get_ical_end_time (icalcomponent *ical,
- icaltimezone *default_zone)
-{
- return get_time_from_property (ical,
- ICAL_DTEND_PROPERTY,
- icalproperty_get_dtend,
- default_zone);
-}
-
-static gboolean
-get_ical_is_all_day (icalcomponent *ical,
- time_t start_time,
- icaltimezone *default_zone)
-{
- icalproperty *prop;
- struct tm *start_tm;
- time_t end_time;
- struct icaldurationtype duration;
- struct icaltimetype start_icaltime;
-
- start_icaltime = icalcomponent_get_dtstart (ical);
- if (start_icaltime.is_date)
- return TRUE;
-
- start_tm = gmtime (&start_time);
- if (start_tm->tm_sec != 0 ||
- start_tm->tm_min != 0 ||
- start_tm->tm_hour != 0)
- return FALSE;
-
- if ((end_time = get_ical_end_time (ical, default_zone)))
- return (end_time - start_time) % 86400 == 0;
-
- prop = icalcomponent_get_first_property (ical, ICAL_DURATION_PROPERTY);
- if (!prop)
- return FALSE;
-
- duration = icalproperty_get_duration (prop);
-
- return icaldurationtype_as_int (duration) % 86400 == 0;
-}
-
-static inline time_t
-get_ical_due_time (icalcomponent *ical,
- icaltimezone *default_zone)
-{
- return get_time_from_property (ical,
- ICAL_DUE_PROPERTY,
- icalproperty_get_due,
- default_zone);
-}
-
-static guint
-get_ical_percent_complete (icalcomponent *ical)
-{
- icalproperty *prop;
- icalproperty_status status;
- int percent_complete;
-
- status = icalcomponent_get_status (ical);
- if (status == ICAL_STATUS_COMPLETED)
- return 100;
-
- prop = icalcomponent_get_first_property (ical, ICAL_COMPLETED_PROPERTY);
- if (prop)
- return 100;
-
- prop = icalcomponent_get_first_property (ical, ICAL_PERCENTCOMPLETE_PROPERTY);
- if (!prop)
- return 0;
-
- percent_complete = icalproperty_get_percentcomplete (prop);
-
- return CLAMP (percent_complete, 0, 100);
-}
-
-static inline time_t
-get_ical_completed_time (icalcomponent *ical,
- icaltimezone *default_zone)
-{
- return get_time_from_property (ical,
- ICAL_COMPLETED_PROPERTY,
- icalproperty_get_completed,
- default_zone);
-}
-
-static int
-get_ical_priority (icalcomponent *ical)
-{
- icalproperty *prop;
-
- prop = icalcomponent_get_first_property (ical, ICAL_PRIORITY_PROPERTY);
- if (!prop)
- return -1;
-
- return icalproperty_get_priority (prop);
-}
-
-static char *
-get_source_color (ECal *esource)
-{
- ESource *source;
-
- g_return_val_if_fail (E_IS_CAL (esource), NULL);
-
- source = e_cal_get_source (esource);
-
- return g_strdup (e_source_peek_color_spec (source));
-}
-
-static gchar *
-get_source_uri (ECal *esource)
-{
- ESource *source;
- gchar *string;
- gchar **list;
-
- g_return_val_if_fail (E_IS_CAL (esource), NULL);
-
- source = e_cal_get_source (esource);
- string = g_strdup (e_source_get_uri (source));
- if (string) {
- list = g_strsplit (string, ":", 2);
- g_free (string);
-
- if (list[0]) {
- string = g_strdup (list[0]);
- g_strfreev (list);
- return string;
- }
- g_strfreev (list);
- }
- return NULL;
-}
-
-static inline int
-null_safe_strcmp (const char *a,
- const char *b)
-{
- return (!a && !b) ? 0 : (a && !b) || (!a && b) ? 1 : strcmp (a, b);
-}
-
-static inline gboolean
-calendar_appointment_equal (CalendarAppointment *a,
- CalendarAppointment *b)
-{
- GSList *la, *lb;
-
- if (g_slist_length (a->occurrences) != g_slist_length (b->occurrences))
- return FALSE;
-
- for (la = a->occurrences, lb = b->occurrences; la && lb; la = la->next, lb = lb->next)
- {
- CalendarOccurrence *oa = la->data;
- CalendarOccurrence *ob = lb->data;
-
- if (oa->start_time != ob->start_time ||
- oa->end_time != ob->end_time)
- return FALSE;
- }
-
- return
- null_safe_strcmp (a->uid, b->uid) == 0 &&
- null_safe_strcmp (a->uri, b->uri) == 0 &&
- null_safe_strcmp (a->summary, b->summary) == 0 &&
- null_safe_strcmp (a->description, b->description) == 0 &&
- null_safe_strcmp (a->color_string, b->color_string) == 0 &&
- a->start_time == b->start_time &&
- a->end_time == b->end_time &&
- a->is_all_day == b->is_all_day;
-}
-
-static void
-calendar_appointment_copy (CalendarAppointment *appointment,
- CalendarAppointment *appointment_copy)
-{
- GSList *l;
-
- g_assert (appointment != NULL);
- g_assert (appointment_copy != NULL);
-
- appointment_copy->occurrences = g_slist_copy (appointment->occurrences);
- for (l = appointment_copy->occurrences; l; l = l->next)
- {
- CalendarOccurrence *occurrence = l->data;
- CalendarOccurrence *occurrence_copy;
-
- occurrence_copy = g_new0 (CalendarOccurrence, 1);
- occurrence_copy->start_time = occurrence->start_time;
- occurrence_copy->end_time = occurrence->end_time;
-
- l->data = occurrence_copy;
- }
-
- appointment_copy->uid = g_strdup (appointment->uid);
- appointment_copy->uri = g_strdup (appointment->uri);
- appointment_copy->summary = g_strdup (appointment->summary);
- appointment_copy->description = g_strdup (appointment->description);
- appointment_copy->color_string = g_strdup (appointment->color_string);
- appointment_copy->start_time = appointment->start_time;
- appointment_copy->end_time = appointment->end_time;
- appointment_copy->is_all_day = appointment->is_all_day;
-}
-
-static void
-calendar_appointment_finalize (CalendarAppointment *appointment)
-{
- GSList *l;
-
- for (l = appointment->occurrences; l; l = l->next)
- g_free (l->data);
- g_slist_free (appointment->occurrences);
- appointment->occurrences = NULL;
-
- g_free (appointment->uid);
- appointment->uid = NULL;
-
- g_free (appointment->rid);
- appointment->rid = NULL;
-
- g_free (appointment->uri);
- appointment->uri = NULL;
-
- g_free (appointment->summary);
- appointment->summary = NULL;
-
- g_free (appointment->description);
- appointment->description = NULL;
-
- g_free (appointment->color_string);
- appointment->color_string = NULL;
-
- appointment->start_time = 0;
- appointment->is_all_day = FALSE;
-}
-
-static void
-calendar_appointment_init (CalendarAppointment *appointment,
- icalcomponent *ical,
- CalendarClientSource *source,
- icaltimezone *default_zone)
-{
- appointment->uid = get_ical_uid (ical);
- appointment->rid = get_ical_rid (ical);
- appointment->uri = get_source_uri (source->source);
- appointment->summary = get_ical_summary (ical);
- appointment->description = get_ical_description (ical);
- appointment->color_string = get_source_color (source->source);
- appointment->start_time = get_ical_start_time (ical, default_zone);
- appointment->end_time = get_ical_end_time (ical, default_zone);
- appointment->is_all_day = get_ical_is_all_day (ical,
- appointment->start_time,
- default_zone);
-}
-
-static icaltimezone *
-resolve_timezone_id (const char *tzid,
- ECal *source)
-{
- icaltimezone *retval;
-
- retval = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (!retval)
- {
- e_cal_get_timezone (source, tzid, &retval, NULL);
- }
-
- return retval;
-}
-
-static gboolean
-calendar_appointment_collect_occurrence (ECalComponent *component,
- time_t occurrence_start,
- time_t occurrence_end,
- gpointer data)
-{
- CalendarOccurrence *occurrence;
- GSList **collect_loc = data;
-
- occurrence = g_new0 (CalendarOccurrence, 1);
- occurrence->start_time = occurrence_start;
- occurrence->end_time = occurrence_end;
-
- *collect_loc = g_slist_prepend (*collect_loc, occurrence);
-
- return TRUE;
-}
-
-static void
-calendar_appointment_generate_ocurrences (CalendarAppointment *appointment,
- icalcomponent *ical,
- ECal *source,
- time_t start,
- time_t end,
- icaltimezone *default_zone)
-{
- ECalComponent *ecal;
-
- g_assert (appointment->occurrences == NULL);
-
- ecal = e_cal_component_new ();
- e_cal_component_set_icalcomponent (ecal,
- icalcomponent_new_clone (ical));
-
- e_cal_recur_generate_instances (ecal,
- start,
- end,
- calendar_appointment_collect_occurrence,
- &appointment->occurrences,
- (ECalRecurResolveTimezoneFn) resolve_timezone_id,
- source,
- default_zone);
-
- g_object_unref (ecal);
-
- appointment->occurrences = g_slist_reverse (appointment->occurrences);
-}
-
-static inline gboolean
-calendar_task_equal (CalendarTask *a,
- CalendarTask *b)
-{
- return
- null_safe_strcmp (a->uid, b->uid) == 0 &&
- null_safe_strcmp (a->summary, b->summary) == 0 &&
- null_safe_strcmp (a->description, b->description) == 0 &&
- null_safe_strcmp (a->color_string, b->color_string) == 0 &&
- a->start_time == b->start_time &&
- a->due_time == b->due_time &&
- a->percent_complete == b->percent_complete &&
- a->completed_time == b->completed_time &&
- a->priority == b->priority;
-}
-
-static void
-calendar_task_copy (CalendarTask *task,
- CalendarTask *task_copy)
-{
- g_assert (task != NULL);
- g_assert (task_copy != NULL);
-
- task_copy->uid = g_strdup (task->uid);
- task_copy->summary = g_strdup (task->summary);
- task_copy->description = g_strdup (task->description);
- task_copy->color_string = g_strdup (task->color_string);
- task_copy->start_time = task->start_time;
- task_copy->due_time = task->due_time;
- task_copy->percent_complete = task->percent_complete;
- task_copy->completed_time = task->completed_time;
- task_copy->priority = task->priority;
-}
-
-static void
-calendar_task_finalize (CalendarTask *task)
-{
- g_free (task->uid);
- task->uid = NULL;
-
- g_free (task->summary);
- task->summary = NULL;
-
- g_free (task->description);
- task->description = NULL;
-
- g_free (task->color_string);
- task->color_string = NULL;
-
- task->percent_complete = 0;
-}
-
-static void
-calendar_task_init (CalendarTask *task,
- icalcomponent *ical,
- CalendarClientSource *source,
- icaltimezone *default_zone)
-{
- task->uid = get_ical_uid (ical);
- task->summary = get_ical_summary (ical);
- task->description = get_ical_description (ical);
- task->color_string = get_source_color (source->source);
- task->start_time = get_ical_start_time (ical, default_zone);
- task->due_time = get_ical_due_time (ical, default_zone);
- task->percent_complete = get_ical_percent_complete (ical);
- task->completed_time = get_ical_completed_time (ical, default_zone);
- task->priority = get_ical_priority (ical);
-}
-
-void
-calendar_event_free (CalendarEvent *event)
-{
- switch (event->type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- calendar_appointment_finalize (CALENDAR_APPOINTMENT (event));
- break;
- case CALENDAR_EVENT_TASK:
- calendar_task_finalize (CALENDAR_TASK (event));
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- g_free (event);
-}
-
-static CalendarEvent *
-calendar_event_new (icalcomponent *ical,
- CalendarClientSource *source,
- icaltimezone *default_zone)
-{
- CalendarEvent *event;
-
- event = g_new0 (CalendarEvent, 1);
-
- switch (icalcomponent_isa (ical))
- {
- case ICAL_VEVENT_COMPONENT:
- event->type = CALENDAR_EVENT_APPOINTMENT;
- calendar_appointment_init (CALENDAR_APPOINTMENT (event),
- ical,
- source,
- default_zone);
- break;
- case ICAL_VTODO_COMPONENT:
- event->type = CALENDAR_EVENT_TASK;
- calendar_task_init (CALENDAR_TASK (event),
- ical,
- source,
- default_zone);
- break;
- default:
- g_warning ("Unknown calendar component type: %d\n",
- icalcomponent_isa (ical));
- g_free (event);
- return NULL;
- }
-
- return event;
-}
-
-static CalendarEvent *
-calendar_event_copy (CalendarEvent *event)
-{
- CalendarEvent *retval;
-
- if (!event)
- return NULL;
-
- retval = g_new0 (CalendarEvent, 1);
-
- retval->type = event->type;
-
- switch (event->type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- calendar_appointment_copy (CALENDAR_APPOINTMENT (event),
- CALENDAR_APPOINTMENT (retval));
- break;
- case CALENDAR_EVENT_TASK:
- calendar_task_copy (CALENDAR_TASK (event),
- CALENDAR_TASK (retval));
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- return retval;
-}
-
-static char *
-calendar_event_get_uid (CalendarEvent *event)
-{
- switch (event->type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- return g_strdup_printf ("%s%s", CALENDAR_APPOINTMENT (event)->uid, CALENDAR_APPOINTMENT (event)->rid ? CALENDAR_APPOINTMENT (event)->rid : "");
- break;
- case CALENDAR_EVENT_TASK:
- return g_strdup (CALENDAR_TASK (event)->uid);
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- return NULL;
-}
-
-static gboolean
-calendar_event_equal (CalendarEvent *a,
- CalendarEvent *b)
-{
- if (!a && !b)
- return TRUE;
-
- if ((a && !b) || (!a && b))
- return FALSE;
-
- if (a->type != b->type)
- return FALSE;
-
- switch (a->type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- return calendar_appointment_equal (CALENDAR_APPOINTMENT (a),
- CALENDAR_APPOINTMENT (b));
- case CALENDAR_EVENT_TASK:
- return calendar_task_equal (CALENDAR_TASK (a),
- CALENDAR_TASK (b));
- default:
- break;
- }
-
- g_assert_not_reached ();
-
- return FALSE;
-}
-
-static void
-calendar_event_generate_ocurrences (CalendarEvent *event,
- icalcomponent *ical,
- ECal *source,
- time_t start,
- time_t end,
- icaltimezone *default_zone)
-{
- if (event->type != CALENDAR_EVENT_APPOINTMENT)
- return;
-
- calendar_appointment_generate_ocurrences (CALENDAR_APPOINTMENT (event),
- ical,
- source,
- start,
- end,
- default_zone);
-}
-
-static inline void
-calendar_event_debug_dump (CalendarEvent *event)
-{
-#ifdef CALENDAR_ENABLE_DEBUG
- switch (event->type)
- {
- case CALENDAR_EVENT_APPOINTMENT:
- {
- char *start_str;
- char *end_str;
- GSList *l;
-
- start_str = CALENDAR_APPOINTMENT (event)->start_time ?
- isodate_from_time_t (CALENDAR_APPOINTMENT (event)->start_time) :
- g_strdup ("(undefined)");
- end_str = CALENDAR_APPOINTMENT (event)->end_time ?
- isodate_from_time_t (CALENDAR_APPOINTMENT (event)->end_time) :
- g_strdup ("(undefined)");
-
- dprintf ("Appointment: uid '%s', summary '%s', description '%s', "
- "start_time '%s', end_time '%s', is_all_day %s\n",
- CALENDAR_APPOINTMENT (event)->uid,
- CALENDAR_APPOINTMENT (event)->summary,
- CALENDAR_APPOINTMENT (event)->description,
- start_str,
- end_str,
- CALENDAR_APPOINTMENT (event)->is_all_day ? "(true)" : "(false)");
-
- g_free (start_str);
- g_free (end_str);
-
- dprintf (" Occurrences:\n");
- for (l = CALENDAR_APPOINTMENT (event)->occurrences; l; l = l->next)
- {
- CalendarOccurrence *occurrence = l->data;
-
- start_str = occurrence->start_time ?
- isodate_from_time_t (occurrence->start_time) :
- g_strdup ("(undefined)");
-
- end_str = occurrence->end_time ?
- isodate_from_time_t (occurrence->end_time) :
- g_strdup ("(undefined)");
-
- dprintf (" start_time '%s', end_time '%s'\n",
- start_str, end_str);
-
- g_free (start_str);
- g_free (end_str);
- }
- }
- break;
- case CALENDAR_EVENT_TASK:
- {
- char *start_str;
- char *due_str;
- char *completed_str;
-
- start_str = CALENDAR_TASK (event)->start_time ?
- isodate_from_time_t (CALENDAR_TASK (event)->start_time) :
- g_strdup ("(undefined)");
- due_str = CALENDAR_TASK (event)->due_time ?
- isodate_from_time_t (CALENDAR_TASK (event)->due_time) :
- g_strdup ("(undefined)");
- completed_str = CALENDAR_TASK (event)->completed_time ?
- isodate_from_time_t (CALENDAR_TASK (event)->completed_time) :
- g_strdup ("(undefined)");
-
- dprintf ("Task: uid '%s', summary '%s', description '%s', "
- "start_time '%s', due_time '%s', percent_complete %d, completed_time '%s'\n",
- CALENDAR_TASK (event)->uid,
- CALENDAR_TASK (event)->summary,
- CALENDAR_TASK (event)->description,
- start_str,
- due_str,
- CALENDAR_TASK (event)->percent_complete,
- completed_str);
-
- g_free (completed_str);
- }
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-#endif
-}
-
-static inline CalendarClientQuery *
-goddamn_this_is_crack (CalendarClientSource *source,
- ECalView *view,
- gboolean *emit_signal)
-{
- g_assert (view != NULL);
-
- if (source->completed_query.view == view)
- {
- if (emit_signal)
- *emit_signal = TRUE;
- return &source->completed_query;
- }
- else if (source->in_progress_query.view == view)
- {
- if (emit_signal)
- *emit_signal = FALSE;
- return &source->in_progress_query;
- }
-
- g_assert_not_reached ();
-
- return NULL;
-}
-
-static void
-calendar_client_handle_query_completed (CalendarClientSource *source,
- ECalendarStatus status,
- ECalView *view)
-{
- CalendarClientQuery *query;
-
- query = goddamn_this_is_crack (source, view, NULL);
-
- dprintf ("Query %p completed: %s\n", query, e_cal_get_error_message (status));
-
- if (status != E_CALENDAR_STATUS_OK)
- {
- g_warning ("Calendar query failed: %s\n",
- e_cal_get_error_message (status));
- calendar_client_stop_query (source->client, source, query);
- return;
- }
-
- g_assert (source->query_in_progress != FALSE);
- g_assert (query == &source->in_progress_query);
-
- calendar_client_query_finalize (&source->completed_query);
-
- source->completed_query = source->in_progress_query;
- source->query_completed = TRUE;
-
- source->query_in_progress = FALSE;
- source->in_progress_query.view = NULL;
- source->in_progress_query.events = NULL;
-
- g_signal_emit (source->client, source->changed_signal_id, 0);
-}
-
-static void
-calendar_client_handle_query_result (CalendarClientSource *source,
- GList *objects,
- ECalView *view)
-{
- CalendarClientQuery *query;
- CalendarClient *client;
- gboolean emit_signal;
- gboolean events_changed;
- GList *l;
- time_t month_begin;
- time_t month_end;
-
- client = source->client;
-
- query = goddamn_this_is_crack (source, view, &emit_signal);
-
- dprintf ("Query %p result: %d objects:\n",
- query, g_list_length (objects));
-
- month_begin = make_time_for_day_begin (1,
- client->priv->month,
- client->priv->year);
-
- month_end = make_time_for_day_begin (1,
- client->priv->month + 1,
- client->priv->year);
-
- events_changed = FALSE;
- for (l = objects; l; l = l->next)
- {
- CalendarEvent *event;
- CalendarEvent *old_event;
- icalcomponent *ical = l->data;
- char *uid;
-
- event = calendar_event_new (ical, source, client->priv->zone);
- if (!event)
- continue;
-
- calendar_event_generate_ocurrences (event,
- ical,
- source->source,
- month_begin,
- month_end,
- client->priv->zone);
-
- uid = calendar_event_get_uid (event);
-
- old_event = g_hash_table_lookup (query->events, uid);
-
- if (!calendar_event_equal (event, old_event))
- {
- dprintf ("Event %s: ", old_event ? "modified" : "added");
-
- calendar_event_debug_dump (event);
-
- g_hash_table_replace (query->events, uid, event);
-
- events_changed = TRUE;
- }
- else
- {
- g_free (uid);
- }
- }
-
- if (emit_signal && events_changed)
- {
- g_signal_emit (source->client, source->changed_signal_id, 0);
- }
-}
-
-static gboolean
-check_object_remove (gpointer key,
- gpointer value,
- gpointer data)
-{
- char *uid = data;
- ssize_t len;
-
- len = strlen (uid);
-
- if (len <= strlen (key) && strncmp (uid, key, len) == 0)
- {
- dprintf ("Event removed: ");
-
- calendar_event_debug_dump (value);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-calendar_client_handle_objects_removed (CalendarClientSource *source,
- GList *ids,
- ECalView *view)
-{
- CalendarClientQuery *query;
- gboolean emit_signal;
- gboolean events_changed;
- GList *l;
-
- query = goddamn_this_is_crack (source, view, &emit_signal);
-
- events_changed = FALSE;
- for (l = ids; l; l = l->next)
- {
- CalendarEvent *event;
- ECalComponentId *id = l->data;
- char *uid = g_strdup_printf ("%s%s", id->uid, id->rid ? id->rid : "");
-
- if (!id->rid || !(*id->rid))
- {
- int size = g_hash_table_size (query->events);
-
- g_hash_table_foreach_remove (query->events, check_object_remove, id->uid);
-
- if (size != g_hash_table_size (query->events))
- events_changed = TRUE;
- }
- else if ((event = g_hash_table_lookup (query->events, uid)))
- {
- dprintf ("Event removed: ");
-
- calendar_event_debug_dump (event);
-
- g_assert (g_hash_table_remove (query->events, uid));
-
- events_changed = TRUE;
- }
- g_free (uid);
- }
-
- if (emit_signal && events_changed)
- {
- g_signal_emit (source->client, source->changed_signal_id, 0);
- }
-}
-
-static void
-calendar_client_query_finalize (CalendarClientQuery *query)
-{
- if (query->view)
- g_object_unref (query->view);
- query->view = NULL;
-
- if (query->events)
- g_hash_table_destroy (query->events);
- query->events = NULL;
-}
-
-static void
-calendar_client_stop_query (CalendarClient *client,
- CalendarClientSource *source,
- CalendarClientQuery *query)
-{
- if (query == &source->in_progress_query)
- {
- dprintf ("Stopping in progress query %p\n", query);
-
- g_assert (source->query_in_progress != FALSE);
-
- source->query_in_progress = FALSE;
- }
- else if (query == &source->completed_query)
- {
- dprintf ("Stopping completed query %p\n", query);
-
- g_assert (source->query_completed != FALSE);
-
- source->query_completed = FALSE;
- }
- else
- g_assert_not_reached ();
-
- calendar_client_query_finalize (query);
-}
-
-static void
-calendar_client_start_query (CalendarClient *client,
- CalendarClientSource *source,
- const char *query)
-{
- ECalView *view = NULL;
- GError *error = NULL;
-
- if (!e_cal_get_query (source->source, query, &view, &error))
- {
- g_warning ("Error preparing the query: '%s': %s\n",
- query, error->message);
- g_error_free (error);
- return;
- }
-
- g_assert (view != NULL);
-
- if (source->query_in_progress)
- calendar_client_stop_query (client, source, &source->in_progress_query);
-
- dprintf ("Starting query %p: '%s'\n", &source->in_progress_query, query);
-
- source->query_in_progress = TRUE;
- source->in_progress_query.view = view;
- source->in_progress_query.events =
- g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify) calendar_event_free);
-
- g_signal_connect_swapped (view, "objects-added",
- G_CALLBACK (calendar_client_handle_query_result),
- source);
- g_signal_connect_swapped (view, "objects-modified",
- G_CALLBACK (calendar_client_handle_query_result),
- source);
- g_signal_connect_swapped (view, "objects-removed",
- G_CALLBACK (calendar_client_handle_objects_removed),
- source);
- g_signal_connect_swapped (view, "view-done",
- G_CALLBACK (calendar_client_handle_query_completed),
- source);
-
- e_cal_view_start (view);
-}
-
-static void
-calendar_client_update_appointments (CalendarClient *client)
-{
- GSList *l;
- char *query;
- char *month_begin;
- char *month_end;
-
- if (client->priv->month == -1 ||
- client->priv->year == -1)
- return;
-
- month_begin = make_isodate_for_day_begin (1,
- client->priv->month,
- client->priv->year);
-
- month_end = make_isodate_for_day_begin (1,
- client->priv->month + 1,
- client->priv->year);
-
- query = g_strdup_printf ("occur-in-time-range? (make-time \"%s\") "
- "(make-time \"%s\")",
- month_begin, month_end);
-
- for (l = client->priv->appointment_sources; l; l = l->next)
- {
- CalendarClientSource *cs = l->data;
-
- if (e_cal_get_load_state (cs->source) != E_CAL_LOAD_LOADED)
- continue;
-
- calendar_client_start_query (client, cs, query);
- }
-
- g_free (month_begin);
- g_free (month_end);
- g_free (query);
-}
-
-/* FIXME:
- * perhaps we should use evo's "hide_completed_tasks" pref?
- */
-static void
-calendar_client_update_tasks (CalendarClient *client)
-{
- GSList *l;
- char *query;
-
-#ifdef FIX_BROKEN_TASKS_QUERY
- /* FIXME: this doesn't work for tasks without a start or
- * due date
- * Look at filter_task() to see the behaviour we
- * want.
- */
-
- char *day_begin;
- char *day_end;
-
- if (client->priv->day == -1 ||
- client->priv->month == -1 ||
- client->priv->year == -1)
- return;
-
- day_begin = make_isodate_for_day_begin (client->priv->day,
- client->priv->month,
- client->priv->year);
-
- day_end = make_isodate_for_day_begin (client->priv->day + 1,
- client->priv->month,
- client->priv->year);
- if (!day_begin || !day_end)
- {
- g_warning ("Cannot run query with invalid date: %dd %dy %dm\n",
- client->priv->day,
- client->priv->month,
- client->priv->year);
- g_free (day_begin);
- g_free (day_end);
- return;
- }
-
- query = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\") "
- "(make-time \"%s\")) "
- "(or (not is-completed?) "
- "(and (is-completed?) "
- "(not (completed-before? (make-time \"%s\"))))))",
- day_begin, day_end, day_begin);
-#else
- query = g_strdup ("#t");
-#endif /* FIX_BROKEN_TASKS_QUERY */
-
- for (l = client->priv->task_sources; l; l = l->next)
- {
- CalendarClientSource *cs = l->data;
-
- if (e_cal_get_load_state (cs->source) != E_CAL_LOAD_LOADED)
- continue;
-
- calendar_client_start_query (client, cs, query);
- }
-
-#ifdef FIX_BROKEN_TASKS_QUERY
- g_free (day_begin);
- g_free (day_end);
-#endif
- g_free (query);
-}
-
-static void
-calendar_client_source_finalize (CalendarClientSource *source)
-{
- source->client = NULL;
-
- if (source->source) {
- g_signal_handlers_disconnect_by_func (source->source,
- cal_opened_cb, source);
- g_object_unref (source->source);
- }
- source->source = NULL;
-
- calendar_client_query_finalize (&source->completed_query);
- calendar_client_query_finalize (&source->in_progress_query);
-
- source->query_completed = FALSE;
- source->query_in_progress = FALSE;
-}
-
-static int
-compare_calendar_sources (CalendarClientSource *s1,
- CalendarClientSource *s2)
-{
- return (s1->source == s2->source) ? 0 : 1;
-}
-
-static GSList *
-calendar_client_update_sources_list (CalendarClient *client,
- GSList *sources,
- GSList *esources,
- guint changed_signal_id)
-{
- GSList *retval, *l;
-
- retval = NULL;
-
- for (l = esources; l; l = l->next)
- {
- CalendarClientSource dummy_source;
- CalendarClientSource *new_source;
- GSList *s;
- ECal *esource = l->data;
-
- dummy_source.source = esource;
-
- dprintf ("update_sources_list: adding client %s: ",
- e_source_peek_uid (e_cal_get_source (esource)));
-
- if ((s = g_slist_find_custom (sources,
- &dummy_source,
- (GCompareFunc) compare_calendar_sources)))
- {
- dprintf ("already on list\n");
- new_source = s->data;
- sources = g_slist_delete_link (sources, s);
- }
- else
- {
- dprintf ("added\n");
- new_source = g_new0 (CalendarClientSource, 1);
- new_source->client = client;
- new_source->source = g_object_ref (esource);
- new_source->changed_signal_id = changed_signal_id;
- }
-
- retval = g_slist_prepend (retval, new_source);
- }
-
- for (l = sources; l; l = l->next)
- {
- CalendarClientSource *source = l->data;
-
- dprintf ("Removing client %s from list\n",
- e_source_peek_uid (e_cal_get_source (source->source)));
-
- calendar_client_source_finalize (source);
- g_free (source);
- }
- g_slist_free (sources);
-
- return retval;
-}
-
-static void
-calendar_client_appointment_sources_changed (CalendarClient *client)
-{
- GSList *esources;
-
- dprintf ("appointment_sources_changed: updating ...\n");
-
- esources = calendar_sources_get_appointment_sources (client->priv->calendar_sources);
-
- client->priv->appointment_sources =
- calendar_client_update_sources_list (client,
- client->priv->appointment_sources,
- esources,
- signals [APPOINTMENTS_CHANGED]);
-
- load_calendars (client, CALENDAR_EVENT_APPOINTMENT);
- calendar_client_update_appointments (client);
-}
-
-static void
-calendar_client_task_sources_changed (CalendarClient *client)
-{
- GSList *esources;
-
- dprintf ("task_sources_changed: updating ...\n");
-
- esources = calendar_sources_get_task_sources (client->priv->calendar_sources);
-
- client->priv->task_sources =
- calendar_client_update_sources_list (client,
- client->priv->task_sources,
- esources,
- signals [TASKS_CHANGED]);
-
- load_calendars (client, CALENDAR_EVENT_TASK);
- calendar_client_update_tasks (client);
-}
-
-void
-calendar_client_get_date (CalendarClient *client,
- guint *year,
- guint *month,
- guint *day)
-{
- g_return_if_fail (CALENDAR_IS_CLIENT (client));
-
- if (year)
- *year = client->priv->year;
-
- if (month)
- *month = client->priv->month;
-
- if (day)
- *day = client->priv->day;
-}
-
-void
-calendar_client_select_month (CalendarClient *client,
- guint month,
- guint year)
-{
- g_return_if_fail (CALENDAR_IS_CLIENT (client));
- g_return_if_fail (month <= 11);
-
- if (client->priv->year != year || client->priv->month != month)
- {
- client->priv->month = month;
- client->priv->year = year;
-
- calendar_client_update_appointments (client);
- calendar_client_update_tasks (client);
-
- g_object_freeze_notify (G_OBJECT (client));
- g_object_notify (G_OBJECT (client), "month");
- g_object_notify (G_OBJECT (client), "year");
- g_object_thaw_notify (G_OBJECT (client));
- }
-}
-
-void
-calendar_client_select_day (CalendarClient *client,
- guint day)
-{
- g_return_if_fail (CALENDAR_IS_CLIENT (client));
- g_return_if_fail (day <= 31);
-
- if (client->priv->day != day)
- {
- client->priv->day = day;
-
- /* don't need to update appointments unless
- * the selected month changes
- */
-#ifdef FIX_BROKEN_TASKS_QUERY
- calendar_client_update_tasks (client);
-#endif
-
- g_object_notify (G_OBJECT (client), "day");
- }
-}
-
-typedef struct
-{
- CalendarClient *client;
- GSList *events;
- time_t start_time;
- time_t end_time;
-} FilterData;
-
-typedef void (* CalendarEventFilterFunc) (const char *uid,
- CalendarEvent *event,
- FilterData *filter_data);
-
-static void
-filter_appointment (const char *uid,
- CalendarEvent *event,
- FilterData *filter_data)
-{
- GSList *occurrences, *l;
-
- if (event->type != CALENDAR_EVENT_APPOINTMENT)
- return;
-
- occurrences = CALENDAR_APPOINTMENT (event)->occurrences;
- CALENDAR_APPOINTMENT (event)->occurrences = NULL;
-
- for (l = occurrences; l; l = l->next)
- {
- CalendarOccurrence *occurrence = l->data;
- time_t start_time = occurrence->start_time;
- time_t end_time = occurrence->end_time;
-
- if ((start_time >= filter_data->start_time &&
- start_time < filter_data->end_time) ||
- (start_time <= filter_data->start_time &&
- (end_time - 1) > filter_data->start_time))
- {
- CalendarEvent *new_event;
-
- new_event = calendar_event_copy (event);
-
- CALENDAR_APPOINTMENT (new_event)->start_time = occurrence->start_time;
- CALENDAR_APPOINTMENT (new_event)->end_time = occurrence->end_time;
-
- filter_data->events = g_slist_prepend (filter_data->events, new_event);
- }
- }
-
- CALENDAR_APPOINTMENT (event)->occurrences = occurrences;
-}
-
-static void
-filter_task (const char *uid,
- CalendarEvent *event,
- FilterData *filter_data)
-{
-#ifdef FIX_BROKEN_TASKS_QUERY
- CalendarTask *task;
-#endif
-
- if (event->type != CALENDAR_EVENT_TASK)
- return;
-
-#ifdef FIX_BROKEN_TASKS_QUERY
- task = CALENDAR_TASK (event);
-
- if (task->start_time && task->start_time > filter_data->start_time)
- return;
-
- if (task->completed_time &&
- (task->completed_time < filter_data->start_time ||
- task->completed_time > filter_data->end_time))
- return;
-#endif /* FIX_BROKEN_TASKS_QUERY */
-
- filter_data->events = g_slist_prepend (filter_data->events,
- calendar_event_copy (event));
-}
-
-static GSList *
-calendar_client_filter_events (CalendarClient *client,
- GSList *sources,
- CalendarEventFilterFunc filter_func,
- time_t start_time,
- time_t end_time)
-{
- FilterData filter_data;
- GSList *l;
- GSList *retval;
-
- if (!sources)
- return NULL;
-
- filter_data.client = client;
- filter_data.events = NULL;
- filter_data.start_time = start_time;
- filter_data.end_time = end_time;
-
- retval = NULL;
- for (l = sources; l; l = l->next)
- {
- CalendarClientSource *source = l->data;
-
- if (source->query_completed)
- {
- filter_data.events = NULL;
- g_hash_table_foreach (source->completed_query.events,
- (GHFunc) filter_func,
- &filter_data);
-
- filter_data.events = g_slist_reverse (filter_data.events);
-
- retval = g_slist_concat (retval, filter_data.events);
- }
- }
-
- return retval;
-}
-
-GSList *
-calendar_client_get_events (CalendarClient *client,
- CalendarEventType event_mask)
-{
- GSList *appointments;
- GSList *tasks;
- time_t day_begin;
- time_t day_end;
-
- g_return_val_if_fail (CALENDAR_IS_CLIENT (client), NULL);
- g_return_val_if_fail (client->priv->day != -1 &&
- client->priv->month != -1 &&
- client->priv->year != -1, NULL);
-
- day_begin = make_time_for_day_begin (client->priv->day,
- client->priv->month,
- client->priv->year);
- day_end = make_time_for_day_begin (client->priv->day + 1,
- client->priv->month,
- client->priv->year);
-
- appointments = NULL;
- if (event_mask & CALENDAR_EVENT_APPOINTMENT)
- {
- appointments = calendar_client_filter_events (client,
- client->priv->appointment_sources,
- filter_appointment,
- day_begin,
- day_end);
- }
-
- tasks = NULL;
- if (event_mask & CALENDAR_EVENT_TASK)
- {
- tasks = calendar_client_filter_events (client,
- client->priv->task_sources,
- filter_task,
- day_begin,
- day_end);
- }
-
- return g_slist_concat (appointments, tasks);
-}
-
-static inline int
-day_from_time_t (time_t t)
-{
- struct tm *tm = localtime (&t);
-
- g_assert (tm == NULL || (tm->tm_mday >=1 && tm->tm_mday <= 31));
-
- return tm ? tm->tm_mday : 0;
-}
-
-void
-calendar_client_foreach_appointment_day (CalendarClient *client,
- CalendarDayIter iter_func,
- gpointer user_data)
-{
- GSList *appointments, *l;
- gboolean marked_days [32] = { FALSE, };
- time_t month_begin;
- time_t month_end;
- int i;
-
- g_return_if_fail (CALENDAR_IS_CLIENT (client));
- g_return_if_fail (iter_func != NULL);
- g_return_if_fail (client->priv->month != -1 &&
- client->priv->year != -1);
-
- month_begin = make_time_for_day_begin (1,
- client->priv->month,
- client->priv->year);
- month_end = make_time_for_day_begin (1,
- client->priv->month + 1,
- client->priv->year);
-
- appointments = calendar_client_filter_events (client,
- client->priv->appointment_sources,
- filter_appointment,
- month_begin,
- month_end);
- for (l = appointments; l; l = l->next)
- {
- CalendarAppointment *appointment = l->data;
-
- if (appointment->start_time)
- {
- time_t day_time = appointment->start_time;
-
- if (day_time >= month_begin)
- marked_days [day_from_time_t (day_time)] = TRUE;
-
- if (appointment->end_time)
- {
- int day_offset;
- int duration = appointment->end_time - appointment->start_time;
- /* mark the days for the appointment, no need to add an extra one when duration is a multiple of 86400 */
- for (day_offset = 1; day_offset <= duration / 86400 && duration != day_offset * 86400; day_offset++)
- {
- time_t day_tm = appointment->start_time + day_offset * 86400;
-
- if (day_tm > month_end)
- break;
- if (day_tm >= month_begin)
- marked_days [day_from_time_t (day_tm)] = TRUE;
- }
- }
- }
- calendar_event_free (CALENDAR_EVENT (appointment));
- }
-
- g_slist_free (appointments);
-
- for (i = 1; i < 32; i++)
- {
- if (marked_days [i])
- iter_func (client, i, user_data);
- }
-}
-
-void
-calendar_client_set_task_completed (CalendarClient *client,
- char *task_uid,
- gboolean task_completed,
- guint percent_complete)
-{
- GSList *l;
- ECal *esource;
- icalcomponent *ical;
- icalproperty *prop;
- icalproperty_status status;
-
- g_return_if_fail (CALENDAR_IS_CLIENT (client));
- g_return_if_fail (task_uid != NULL);
- g_return_if_fail (task_completed == FALSE || percent_complete == 100);
-
- ical = NULL;
- esource = NULL;
- for (l = client->priv->task_sources; l; l = l->next)
- {
- CalendarClientSource *source = l->data;
-
- esource = source->source;
- e_cal_get_object (esource, task_uid, NULL, &ical, NULL);
- if (ical)
- break;
- }
-
- if (!ical)
- {
- g_warning ("Cannot locate task with uid = '%s'\n", task_uid);
- return;
- }
-
- g_assert (esource != NULL);
-
- /* Completed time */
- prop = icalcomponent_get_first_property (ical,
- ICAL_COMPLETED_PROPERTY);
- if (task_completed)
- {
- struct icaltimetype completed_time;
-
- completed_time = icaltime_current_time_with_zone (client->priv->zone);
- if (!prop)
- {
- icalcomponent_add_property (ical,
- icalproperty_new_completed (completed_time));
- }
- else
- {
- icalproperty_set_completed (prop, completed_time);
- }
- }
- else if (prop)
- {
- icalcomponent_remove_property (ical, prop);
- }
-
- /* Percent complete */
- prop = icalcomponent_get_first_property (ical,
- ICAL_PERCENTCOMPLETE_PROPERTY);
- if (!prop)
- {
- icalcomponent_add_property (ical,
- icalproperty_new_percentcomplete (percent_complete));
- }
- else
- {
- icalproperty_set_percentcomplete (prop, percent_complete);
- }
-
- /* Status */
- status = task_completed ? ICAL_STATUS_COMPLETED : ICAL_STATUS_NEEDSACTION;
- prop = icalcomponent_get_first_property (ical, ICAL_STATUS_PROPERTY);
- if (prop)
- {
- icalproperty_set_status (prop, status);
- }
- else
- {
- icalcomponent_add_property (ical,
- icalproperty_new_status (status));
- }
-
- e_cal_modify_object (esource, ical, CALOBJ_MOD_ALL, NULL);
-}