From 25317085c402d37406b4ecbd4a13289a09c9385e Mon Sep 17 00:00:00 2001 From: Chenthill Palanisamy Date: Tue, 11 Oct 2005 09:07:24 +0000 Subject: fixes #266144, #317575. svn path=/trunk/; revision=30503 --- calendar/ChangeLog | 21 +++++++ calendar/gui/alarm-notify/alarm-queue.c | 103 +++++++++++++++++++------------- calendar/gui/e-cal-model.c | 69 +++++++++++---------- calendar/gui/e-cal-model.h | 2 +- calendar/gui/e-calendar-table.c | 18 +++++- calendar/gui/e-calendar-view.c | 10 +++- calendar/gui/gnome-cal.c | 2 +- 7 files changed, 140 insertions(+), 85 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 7e8b09867b..1c471f51d4 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,24 @@ +2005-10-10 Chenthill Palanisamy + + Fixes #266144, 317575. + * gui/alarm-notify/alarm-queue.c: (remove_queued_alarm), + (add_component_alarms), (lookup_comp_queued_alarms), (remove_comp), + (query_objects_changed_cb), (compare_ids), + (alarm_queue_add_client), (add_id_cb), (remove_client_alarms), + (update_cqa): + * gui/e-cal-model.c (search_by_id_and_client):Use ECalComponentId. + (e_cal_view_objects_added_cb), (e_cal_view_objects_modified_cb), + (e_cal_view_objects_removed_cb), + (e_cal_model_get_component_for_uid), + (e_cal_model_set_instance_times): set the proper timezone. + * gui/e-cal-model.h: + * gui/e-calendar-view.c: (delete_event): Do not remove the + recurrence id. + * gui/e-calendar-table.c (hide_completed_rows), + (show_completed_rows): Use ECalComponentId to get a component + for model. + * gui/gnome-cal.c: (dn_e_cal_view_objects_removed_cb): + 2005-10-06 Srinivasa Ragavan * calendar.error.xml: Added accels to the Disard new event/ diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c index e9f7b76c5a..f8df860487 100644 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ b/calendar/gui/alarm-notify/alarm-queue.c @@ -98,7 +98,7 @@ typedef struct { ClientAlarms *parent_client; /* The component's UID */ - char *uid; + ECalComponentId *id; /* The actual component and its alarm instances */ ECalComponentAlarms *alarms; @@ -268,9 +268,9 @@ remove_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id, return; if (free_object) { - g_hash_table_remove (cqa->parent_client->uid_alarms_hash, cqa->uid); - g_free (cqa->uid); - cqa->uid = NULL; + g_hash_table_remove (cqa->parent_client->uid_alarms_hash, cqa->id); + e_cal_component_free_id (cqa->id); + cqa->id = NULL; cqa->parent_client = NULL; e_cal_component_alarms_free (cqa->alarms); g_free (cqa); @@ -341,7 +341,7 @@ alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) static void add_component_alarms (ClientAlarms *ca, ECalComponentAlarms *alarms) { - const char *uid; + ECalComponentId *id; CompQueuedAlarms *cqa; GSList *l; @@ -384,13 +384,10 @@ add_component_alarms (ClientAlarms *ca, ECalComponentAlarms *alarms) cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa); } - e_cal_component_get_uid (alarms->comp, &uid); + id = e_cal_component_get_id (alarms->comp); /* If we failed to add all the alarms, then we should get rid of the cqa */ if (cqa->queued_alarms == NULL) { - g_message ("add_component_alarms(): Could not add any of the alarms " - "for the component `%s'; discarding it...", uid); - e_cal_component_alarms_free (cqa->alarms); cqa->alarms = NULL; @@ -399,8 +396,8 @@ add_component_alarms (ClientAlarms *ca, ECalComponentAlarms *alarms) } cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - cqa->uid = g_strdup (uid); - g_hash_table_insert (ca->uid_alarms_hash, cqa->uid, cqa); + cqa->id = id; + g_hash_table_insert (ca->uid_alarms_hash, cqa->id, cqa); } /* Loads the alarms of a client for a given range of time */ @@ -486,9 +483,9 @@ cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data) /* Looks up a component's queued alarm structure in a client alarms structure */ static CompQueuedAlarms * -lookup_comp_queued_alarms (ClientAlarms *ca, const char *uid) +lookup_comp_queued_alarms (ClientAlarms *ca, const ECalComponentId *id) { - return g_hash_table_lookup (ca->uid_alarms_hash, uid); + return g_hash_table_lookup (ca->uid_alarms_hash, id); } static void @@ -515,11 +512,11 @@ remove_alarms (CompQueuedAlarms *cqa, gboolean free_object) /* Removes a component an its alarms */ static void -remove_comp (ClientAlarms *ca, const char *uid) +remove_comp (ClientAlarms *ca, const ECalComponentId *id) { CompQueuedAlarms *cqa; - cqa = lookup_comp_queued_alarms (ca, uid); + cqa = lookup_comp_queued_alarms (ca, id); if (!cqa) return; @@ -533,7 +530,7 @@ remove_comp (ClientAlarms *ca, const char *uid) /* The list should be empty now, and thus the queued component alarms * structure should have been freed and removed from the hash table. */ - g_assert (lookup_comp_queued_alarms (ca, uid) == NULL); + g_assert (lookup_comp_queued_alarms (ca, id) == NULL); } /* Called when a calendar component changes; we must reload its corresponding @@ -563,22 +560,30 @@ query_objects_changed_cb (ECal *client, GList *objects, gpointer data) day_end = time_day_end_with_zone (time (NULL), zone); g_message ("Query response for alarms"); for (l = objects; l != NULL; l = l->next) { - const char *uid; + ECalComponentId *id; GSList *sl; + ECalComponent *comp = e_cal_component_new (); + + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data)); - uid = icalcomponent_get_uid (l->data); - found = e_cal_get_alarms_for_object (ca->client, uid, from, day_end, &alarms); + id = e_cal_component_get_id (comp); + found = e_cal_get_alarms_for_object (ca->client, id, from, day_end, &alarms); if (!found) { g_message ("No alarms found on object"); - remove_comp (ca, uid); + remove_comp (ca, id); + e_cal_component_free_id (id); + g_object_unref (comp); + comp = NULL; continue; } - cqa = lookup_comp_queued_alarms (ca, uid); + cqa = lookup_comp_queued_alarms (ca, id); if (!cqa) { g_message ("No currently queue alarms"); add_component_alarms (ca, alarms); + g_object_unref (comp); + comp = NULL; continue; } @@ -588,11 +593,7 @@ query_objects_changed_cb (ECal *client, GList *objects, gpointer data) if (alarms == NULL || alarms->alarms == NULL) { /* update the cqa and its queued alarms for changes in summary and alarm_uid */ - ECalComponent *newcomp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (newcomp, icalcomponent_new_clone (l->data))) - g_warning ("couldn't update calendar component with modified data from backend\n"); - - update_cqa (cqa, newcomp); + update_cqa (cqa, comp); if (alarms) e_cal_component_alarms_free (alarms); @@ -628,6 +629,8 @@ query_objects_changed_cb (ECal *client, GList *objects, gpointer data) } cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); + g_object_unref (comp); + comp = NULL; } } @@ -1407,6 +1410,23 @@ alarm_queue_done (void) alarm_queue_inited = FALSE; } +static gboolean +compare_ids (gpointer a, gpointer b) +{ + ECalComponentId *id, *id1; + + id = a; + id1 = b; + + if (g_str_equal (id->uid, id1->uid)) { + if (id->rid && id1->rid) + return g_str_equal (id->rid, id1->rid); + else if (!(id->rid && id1->rid)) + return TRUE; + } + return FALSE; +} + /** * alarm_queue_add_client: * @client: A calendar client. @@ -1443,7 +1463,7 @@ alarm_queue_add_client (ECal *client) g_hash_table_insert (client_alarms_hash, client, ca); - ca->uid_alarms_hash = g_hash_table_new (g_str_hash, g_str_equal); + ca->uid_alarms_hash = g_hash_table_new (g_str_hash, (GEqualFunc) compare_ids); if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) { load_alarms_for_today (ca); @@ -1456,38 +1476,37 @@ alarm_queue_add_client (ECal *client) /* Called from g_hash_table_foreach(); adds a component UID to a list */ static void -add_uid_cb (gpointer key, gpointer value, gpointer data) +add_id_cb (gpointer key, gpointer value, gpointer data) { - GSList **uids; - const char *uid; + GSList **ids; + const ECalComponentId *id; - uids = data; - uid = key; + ids = data; + id = key; - *uids = g_slist_prepend (*uids, (char *) uid); + *ids = g_slist_prepend (*ids, (ECalComponentId *) id); } /* Removes all the alarms queued for a particular calendar client */ static void remove_client_alarms (ClientAlarms *ca) { - GSList *uids; + GSList *ids = NULL; GSList *l; /* First we build a list of UIDs so that we can remove them one by one */ - uids = NULL; - g_hash_table_foreach (ca->uid_alarms_hash, add_uid_cb, &uids); + g_hash_table_foreach (ca->uid_alarms_hash, add_id_cb, &ids); - for (l = uids; l; l = l->next) { - const char *uid; + for (l = ids; l; l = l->next) { + const ECalComponentId *id; - uid = l->data; + id = l->data; - remove_comp (ca, uid); + remove_comp (ca, id); } - g_slist_free (uids); + g_slist_free (ids); /* The hash table should be empty now */ @@ -1548,11 +1567,9 @@ update_cqa (CompQueuedAlarms *cqa, ECalComponent *newcomp) GSList *qa_list; /* List of current QueuedAlarms corresponding to cqa */ time_t from, to; icaltimezone *zone; - char *uid; ECalComponentAlarmAction omit[] = {-1}; oldcomp = cqa->alarms->comp; - e_cal_component_get_uid (newcomp, (const char **)&uid); zone = config_data_get_timezone (); from = time_day_begin_with_zone (time (NULL), zone); diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index d20793f9ae..02acdd7411 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -1244,10 +1244,9 @@ find_client_data (ECalModel *model, ECal *client) return NULL; } -/* Pass NULL for the client if we just want to find based on uid */ /* FIXME how do we prevent the same UID is different calendars? */ static ECalModelComponent * -search_by_uid_and_client (ECalModelPrivate *priv, ECal *client, const char *uid) +search_by_id_and_client (ECalModelPrivate *priv, ECal *client, const ECalComponentId *id) { gint i; @@ -1255,19 +1254,27 @@ search_by_uid_and_client (ECalModelPrivate *priv, ECal *client, const char *uid) ECalModelComponent *comp_data = g_ptr_array_index (priv->objects, i); if (comp_data) { - const char *tmp_uid; + const char *uid, *rid; + gboolean has_rid = (id->rid && *id->rid); - tmp_uid = icalcomponent_get_uid (comp_data->icalcomp); - if (tmp_uid && *tmp_uid) { - if ((!client || comp_data->client == client) && !strcmp (uid, tmp_uid)) + uid = icalcomponent_get_uid (comp_data->icalcomp); + rid = icaltime_as_ical_string (icalcomponent_get_recurrenceid (comp_data->icalcomp)); + + if (uid && *uid) { + if ((!client || comp_data->client == client) && !strcmp (id->uid, uid)) { + if (has_rid) { + if (!(rid && *rid && !strcmp (rid, id->rid))) + continue; + } return comp_data; + } } } } return NULL; } - + typedef struct { ECal *client; ECalView *query; @@ -1335,10 +1342,15 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data for (l = objects; l; l = l->next) { ECalModelComponent *comp_data; + ECalComponentId *id; + ECalComponent *comp = e_cal_component_new (); + + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data)); + id = e_cal_component_get_id (comp); /* remove the components if they are already present and re-add them */ - while ((comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), - icalcomponent_get_uid (l->data)))) { + while ((comp_data = search_by_id_and_client (priv, NULL, + id))) { int pos; pos = get_position_in_array (priv->objects, comp_data); @@ -1348,9 +1360,11 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data e_cal_model_free_component_data (comp_data); } + e_cal_component_free_id (id); + g_object_unref (comp); ensure_dates_are_in_default_zone (l->data); - if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) { + if (e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) { RecurrenceExpansionData rdata; rdata.client = e_cal_view_get_client (query); @@ -1386,28 +1400,12 @@ e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer user_d priv = model->priv; - for (l = objects; l; l = l->next) { - ECalModelComponent *comp_data; - - /* remove all recurrences and re-add them after generating them */ - while ((comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), - icalcomponent_get_uid (l->data)))) { - int pos; - - pos = get_position_in_array (priv->objects, comp_data); - e_table_model_row_deleted (E_TABLE_MODEL (model), pos); - - g_ptr_array_remove (priv->objects, comp_data); - e_cal_model_free_component_data (comp_data); - } - } - /* now re-add all objects */ e_cal_view_objects_added_cb (query, objects, model); } static void -e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer user_data) +e_cal_view_objects_removed_cb (ECalView *query, GList *ids, gpointer user_data) { ECalModelPrivate *priv; ECalModel *model = (ECalModel *) user_data; @@ -1415,14 +1413,15 @@ e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer user_data) priv = model->priv; - for (l = uids; l; l = l->next) { - ECalModelComponent *comp_data; + for (l = ids; l; l = l->next) { + ECalModelComponent *comp_data = NULL; + ECalComponentId *id = l->data; int pos; e_table_model_pre_change (E_TABLE_MODEL (model)); /* make sure we remove all objects with this UID */ - while ((comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), l->data))) { + while ((comp_data = search_by_id_and_client (priv, e_cal_view_get_client (query), id))) { pos = get_position_in_array (priv->objects, comp_data); e_table_model_row_deleted (E_TABLE_MODEL (model), pos); @@ -1911,7 +1910,7 @@ e_cal_model_get_component_at (ECalModel *model, gint row) } ECalModelComponent * -e_cal_model_get_component_for_uid (ECalModel *model, const char *uid) +e_cal_model_get_component_for_uid (ECalModel *model, const ECalComponentId *id) { ECalModelPrivate *priv; @@ -1919,8 +1918,8 @@ e_cal_model_get_component_for_uid (ECalModel *model, const char *uid) priv = model->priv; - return search_by_uid_and_client (priv, NULL, uid); -} + return search_by_id_and_client (priv, NULL, id); +} /** * e_cal_model_date_value_to_string @@ -2088,8 +2087,8 @@ e_cal_model_set_instance_times (ECalModelComponent *comp_data, icaltimezone *zon start_time = icalcomponent_get_dtstart (comp_data->icalcomp); end_time = icalcomponent_get_dtend (comp_data->icalcomp); - comp_data->instance_start = icaltime_as_timet (start_time); + comp_data->instance_start = icaltime_as_timet_with_zone (start_time, zone); comp_data->instance_end = comp_data->instance_start + - (icaltime_as_timet (end_time) - icaltime_as_timet (start_time)); + (icaltime_as_timet_with_zone (end_time, zone) - icaltime_as_timet_with_zone (start_time, zone)); } diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h index cc8ea4d648..d98d81bbfc 100644 --- a/calendar/gui/e-cal-model.h +++ b/calendar/gui/e-cal-model.h @@ -142,7 +142,7 @@ gboolean e_cal_model_get_rgb_color_for_component (ECalModel ECalModelComponent *e_cal_model_get_component_at (ECalModel *model, gint row); ECalModelComponent *e_cal_model_get_component_for_uid (ECalModel *model, - const char *uid); + const ECalComponentId *id); gchar *e_cal_model_date_value_to_string (ECalModel *model, const void *value); ECalModelComponent *e_cal_model_copy_component_data (ECalModelComponent *comp_data); diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index d339ccaf8b..943a84f533 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -1296,14 +1296,21 @@ hide_completed_rows (ECalModel *model, GList *clients_list, char *hide_sexp, GPt for (m = objects; m; m = m->next) { ECalModelComponent *comp_data; + ECalComponentId *id; + ECalComponent *comp = e_cal_component_new (); - if ((comp_data = e_cal_model_get_component_for_uid (model, icalcomponent_get_uid (m->data)))) { + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (m->data)); + id = e_cal_component_get_id (comp); + + if ((comp_data = e_cal_model_get_component_for_uid (model, id))) { e_table_model_pre_change (E_TABLE_MODEL (model)); pos = get_position_in_array (comp_objects, comp_data); e_table_model_row_deleted (E_TABLE_MODEL (model), pos); g_ptr_array_remove (comp_objects, comp_data); } + e_cal_component_free_id (id); + g_object_unref (comp); } g_list_foreach (objects, (GFunc) icalcomponent_free, NULL); @@ -1328,8 +1335,13 @@ show_completed_rows (ECalModel *model, GList *clients_list, char *show_sexp, GPt for (m = objects; m; m = m->next) { ECalModelComponent *comp_data; + ECalComponentId *id; + ECalComponent *comp = e_cal_component_new (); + + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (m->data)); + id = e_cal_component_get_id (comp); - if (!(e_cal_model_get_component_for_uid (model, icalcomponent_get_uid (m->data)))) { + if (!(e_cal_model_get_component_for_uid (model, id))) { e_table_model_pre_change (E_TABLE_MODEL (model)); comp_data = g_new0 (ECalModelComponent, 1); comp_data->client = client; @@ -1342,6 +1354,8 @@ show_completed_rows (ECalModel *model, GList *clients_list, char *show_sexp, GPt g_ptr_array_add (comp_objects, comp_data); e_table_model_row_inserted (E_TABLE_MODEL (model), comp_objects->len - 1); } + e_cal_component_free_id (id); + g_object_unref (comp); } } } diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index efb3c580db..81420ceb14 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -863,7 +863,10 @@ delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); vtype = e_cal_component_get_vtype (comp); - e_cal_component_set_recurid (comp, NULL); + + /*FIXME remove it once the we dont set the recurrence id for all the generated instances */ + if (!e_cal_get_static_capability (event->comp_data->client, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) + e_cal_component_set_recurid (comp, NULL); if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) { const char *uid; @@ -882,8 +885,9 @@ delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) return; } - if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_is_instance (event->comp_data->icalcomp)) - e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_ALL, &error); + if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) + e_cal_remove_object_with_mod (event->comp_data->client, uid, + e_cal_component_get_recurid_as_string (comp), CALOBJ_MOD_ALL, &error); else e_cal_remove_object (event->comp_data->client, uid, &error); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index b74e98308d..a013256744 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -516,7 +516,7 @@ dn_e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer dat /* Callback used when the calendar query reports of a removed object */ static void -dn_e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer data) +dn_e_cal_view_objects_removed_cb (ECalView *query, GList *ids, gpointer data) { GnomeCalendar *gcal; -- cgit v1.2.3