diff options
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/dialogs/recur-comp.c | 13 | ||||
-rw-r--r-- | calendar/gui/e-cal-model-calendar.c | 39 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.c | 239 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 111 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 94 |
5 files changed, 254 insertions, 242 deletions
diff --git a/calendar/gui/dialogs/recur-comp.c b/calendar/gui/dialogs/recur-comp.c index 1f5c2b39e9..cfffa29c69 100644 --- a/calendar/gui/dialogs/recur-comp.c +++ b/calendar/gui/dialogs/recur-comp.c @@ -116,9 +116,20 @@ recur_component_dialog (ECal *client, *mod = CALOBJ_MOD_THISANDPRIOR; else if (rb_future && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_future))) *mod = CALOBJ_MOD_THISANDFUTURE; - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_all))) + else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_all))) { *mod = CALOBJ_MOD_ALL; + /* remove the RECURRENCE-ID from the object if modifying ALL instances */ + if (ret) { + icalproperty *prop; + + prop = icalcomponent_get_first_property (e_cal_component_get_icalcomponent (comp), + ICAL_RECURRENCEID_PROPERTY); + if (prop) + icalcomponent_remove_property (e_cal_component_get_icalcomponent (comp), prop); + } + } + gtk_widget_destroy (dialog); return ret; diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c index c4734d4d6f..5284332f72 100644 --- a/calendar/gui/e-cal-model-calendar.c +++ b/calendar/gui/e-cal-model-calendar.c @@ -26,7 +26,10 @@ #include <libgnome/gnome-i18n.h> #include "e-cal-model-calendar.h" #include "e-cell-date-edit-text.h" +#include "itip-utils.h" #include "misc.h" +#include "dialogs/recur-comp.h" +#include "dialogs/send-comp.h" struct _ECalModelCalendarPrivate { }; @@ -112,7 +115,7 @@ get_dtend (ECalModelCalendar *model, ECalModelComponent *comp_data) if (!comp_data->dtend) { icalproperty *prop; - icaltimezone *zone; + icaltimezone *zone, *model_zone; gboolean got_zone = FALSE; prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTEND_PROPERTY); @@ -125,11 +128,12 @@ get_dtend (ECalModelCalendar *model, ECalModelComponent *comp_data) && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_end), &zone, NULL)) got_zone = TRUE; - if ((e_cal_model_get_flags (E_CAL_MODEL (model)) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) && - (e_cal_util_component_has_recurrences (comp_data->icalcomp))) { - if (got_zone) + if (e_cal_model_get_flags (E_CAL_MODEL (model)) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) { + if (got_zone) { tt_end = icaltime_from_timet_with_zone (comp_data->instance_end, tt_end.is_date, zone); - else + if ((model_zone = e_cal_model_get_timezone (E_CAL_MODEL (model)))) + icaltimezone_convert_time (&tt_end, zone, model_zone); + } else tt_end = icaltime_from_timet (comp_data->instance_end, tt_end.is_date); } @@ -329,6 +333,8 @@ static void ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) { ECalModelComponent *comp_data; + CalObjModType mod = CALOBJ_MOD_ALL; + ECalComponent *comp; ECalModelCalendar *model = (ECalModelCalendar *) etm; g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); @@ -344,6 +350,20 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) if (!comp_data) return; + comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) { + g_object_unref (comp); + return; + } + + /* ask about mod type */ + if (e_cal_component_is_instance (comp)) { + if (!recur_component_dialog (comp_data->client, comp, &mod, NULL)) { + g_object_unref (comp); + return; + } + } + switch (col) { case E_CAL_MODEL_CALENDAR_FIELD_DTEND : set_dtend (comp_data, value); @@ -356,12 +376,17 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) break; } - /* FIXME ask about mod type */ - if (!e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) { + if (e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) { + if (itip_organizer_is_user (comp, comp_data->client) && + send_component_dialog (NULL, comp_data->client, comp, FALSE)) + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, comp_data->client, NULL); + } else { g_warning (G_STRLOC ": Could not modify the object!"); /* FIXME Show error dialog */ } + + g_object_unref (comp); } static gboolean diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 77f7e622ef..ff48c6bd4d 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -174,46 +174,6 @@ e_cal_model_init (ECalModel *model) } static void -free_comp_data (ECalModelComponent *comp_data) -{ - g_return_if_fail (comp_data != NULL); - - comp_data->client = NULL; - - if (comp_data->icalcomp) { - icalcomponent_free (comp_data->icalcomp); - comp_data->icalcomp = NULL; - } - - if (comp_data->dtstart) { - g_free (comp_data->dtstart); - comp_data->dtstart = NULL; - } - - if (comp_data->dtend) { - g_free (comp_data->dtend); - comp_data->dtend = NULL; - } - - if (comp_data->due) { - g_free (comp_data->due); - comp_data->due = NULL; - } - - if (comp_data->completed) { - g_free (comp_data->completed); - comp_data->completed = NULL; - } - - if (comp_data->color) { - g_free (comp_data->color); - comp_data->color = NULL; - } - - g_free (comp_data); -} - -static void clear_objects_array (ECalModelPrivate *priv) { gint i; @@ -223,7 +183,7 @@ clear_objects_array (ECalModelPrivate *priv) comp_data = g_ptr_array_index (priv->objects, i); g_assert (comp_data != NULL); - free_comp_data (comp_data); + e_cal_model_free_component_data (comp_data); } @@ -406,11 +366,12 @@ get_dtstart (ECalModel *model, ECalModelComponent *comp_data) && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_start), &zone, NULL)) got_zone = TRUE; - if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) && - (e_cal_util_component_has_recurrences (comp_data->icalcomp))) { - if (got_zone) + if (e_cal_model_get_flags (model) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) { + if (got_zone) { tt_start = icaltime_from_timet_with_zone (comp_data->instance_start, tt_start.is_date, zone); - else + if (priv->zone) + icaltimezone_convert_time (&tt_start, zone, priv->zone); + } else tt_start = icaltime_from_timet (comp_data->instance_start, tt_start.is_date); } @@ -758,7 +719,7 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row) g_return_if_fail (E_IS_CAL_MODEL (model)); g_return_if_fail (E_IS_TABLE_MODEL (source)); - memset (&comp_data, 0, sizeof (comp_data)); + memset (&comp_data, 0, sizeof (ECalModelComponent)); comp_data.client = e_cal_model_get_default_client (model); /* guard against saving before the calendar is open */ @@ -780,7 +741,6 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row) model_class->fill_component_from_model (model, &comp_data, source, row); } - if (!e_cal_create_object (comp_data.client, comp_data.icalcomp, NULL, NULL)) { g_warning (G_STRLOC ": Could not create the object!"); @@ -1314,16 +1274,29 @@ add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end ECalModelComponent *comp_data; ECalModelPrivate *priv; RecurrenceExpansionData *rdata = user_data; + struct icaltimetype itt; priv = rdata->model->priv; e_table_model_pre_change (E_TABLE_MODEL (rdata->model)); comp_data = g_new0 (ECalModelComponent, 1); - comp_data->client = g_object_ref (e_cal_view_get_client (rdata->query)); - comp_data->icalcomp = icalcomponent_new_clone (rdata->icalcomp); - comp_data->instance_start = instance_start; - comp_data->instance_end = instance_end; + comp_data->client = g_object_ref (rdata->client); + comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); + if (priv->zone) { + itt = icaltime_from_timet_with_zone (instance_start, FALSE, icaltimezone_get_utc_timezone ()); + icaltimezone_convert_time (&itt, icaltimezone_get_utc_timezone (), priv->zone); + comp_data->instance_start = icaltime_as_timet (itt); + + itt = icaltime_from_timet_with_zone (instance_end, FALSE, icaltimezone_get_utc_timezone ()); + icaltimezone_convert_time (&itt, icaltimezone_get_utc_timezone (), priv->zone); + comp_data->instance_end = icaltime_as_timet (itt); + } else { + comp_data->instance_start = instance_start; + comp_data->instance_end = instance_end; + } + comp_data->dtstart = comp_data->dtend = comp_data->due = comp_data->completed = NULL; + comp_data->color = NULL; g_ptr_array_add (priv->objects, comp_data); e_table_model_row_inserted (E_TABLE_MODEL (rdata->model), priv->objects->len - 1); @@ -1332,6 +1305,48 @@ add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end } static void +set_instance_times (ECalModelComponent *comp_data, icaltimezone *zone) +{ + struct icaltimetype recur_time, start_time, end_time; + + recur_time = icalcomponent_get_recurrenceid (comp_data->icalcomp); + start_time = icalcomponent_get_dtstart (comp_data->icalcomp); + end_time = icalcomponent_get_dtend (comp_data->icalcomp); + + if (zone) { + if (e_cal_util_component_is_instance (comp_data->icalcomp)) { + icaltimezone_convert_time (&recur_time, icaltimezone_get_utc_timezone (), zone); + comp_data->instance_start = icaltime_as_timet_with_zone (recur_time, zone); + + comp_data->instance_end = comp_data->instance_start + + (icaltime_as_timet_with_zone (end_time, zone) - + icaltime_as_timet_with_zone (start_time, zone)); + } else { + icaltimezone_convert_time (&start_time, + start_time.zone ? start_time.zone : icaltimezone_get_utc_timezone (), + zone); + comp_data->instance_start = icaltime_as_timet_with_zone (start_time, zone); + + icaltimezone_convert_time (&end_time, + end_time.zone ? end_time.zone : icaltimezone_get_utc_timezone (), + zone); + comp_data->instance_end = icaltime_as_timet_with_zone (end_time, zone); + } + } else { + if (e_cal_util_component_is_instance (comp_data->icalcomp)) { + icaltimezone_convert_time (&recur_time, icaltimezone_get_utc_timezone (), zone); + comp_data->instance_start = icaltime_as_timet_with_zone (recur_time, zone); + comp_data->instance_end = comp_data->instance_start + + (icaltime_as_timet (end_time) - + icaltime_as_timet (start_time)); + } else { + comp_data->instance_start = icaltime_as_timet (icalcomponent_get_dtstart (comp_data->icalcomp)); + comp_data->instance_end = icaltime_as_timet (icalcomponent_get_dtend (comp_data->icalcomp)); + } + } +} + +static void e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data) { ECalModel *model = (ECalModel *) user_data; @@ -1341,8 +1356,7 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data priv = model->priv; for (l = objects; l; l = l->next) { - if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) && - e_cal_util_component_has_recurrences (l->data)) { + if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) { RecurrenceExpansionData rdata; rdata.client = e_cal_view_get_client (query); @@ -1361,6 +1375,9 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data comp_data = g_new0 (ECalModelComponent, 1); comp_data->client = g_object_ref (e_cal_view_get_client (query)); comp_data->icalcomp = icalcomponent_new_clone (l->data); + set_instance_times (comp_data, priv->zone); + comp_data->dtstart = comp_data->dtend = comp_data->due = comp_data->completed = NULL; + comp_data->color = NULL; g_ptr_array_add (priv->objects, comp_data); e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1); @@ -1379,62 +1396,23 @@ e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer user_d for (l = objects; l; l = l->next) { ECalModelComponent *comp_data; + GList node; - if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) && - e_cal_util_component_has_recurrences (l->data)) { - GList node; - - /* 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; + /* 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); - - g_ptr_array_remove (priv->objects, comp_data); - free_comp_data (comp_data); - - e_table_model_row_deleted (E_TABLE_MODEL (model), pos); - } - - node.prev = node.next = NULL; - node.data = l->data; - e_cal_view_objects_added_cb (query, &node, model); - } else { - e_table_model_pre_change (E_TABLE_MODEL (model)); - - comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), - icalcomponent_get_uid (l->data)); - if (!comp_data) - continue; - - if (comp_data->icalcomp) - icalcomponent_free (comp_data->icalcomp); - if (comp_data->dtstart) { - g_free (comp_data->dtstart); - comp_data->dtstart = NULL; - } - if (comp_data->dtend) { - g_free (comp_data->dtend); - comp_data->dtend = NULL; - } - if (comp_data->due) { - g_free (comp_data->due); - comp_data->due = NULL; - } - if (comp_data->completed) { - g_free (comp_data->completed); - comp_data->completed = NULL; - } - if (comp_data->color) { - g_free (comp_data->color); - comp_data->color = NULL; - } - - comp_data->icalcomp = icalcomponent_new_clone (l->data); + pos = get_position_in_array (priv->objects, comp_data); + e_table_model_row_deleted (E_TABLE_MODEL (model), pos); - e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data)); + g_ptr_array_remove (priv->objects, comp_data); + e_cal_model_free_component_data (comp_data); } + + node.prev = node.next = NULL; + node.data = l->data; + e_cal_view_objects_added_cb (query, &node, model); } } @@ -1456,11 +1434,10 @@ e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer user_data) /* 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))) { pos = get_position_in_array (priv->objects, comp_data); - - g_ptr_array_remove (priv->objects, comp_data); - free_comp_data (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); } } } @@ -1628,11 +1605,10 @@ remove_client_objects (ECalModel *model, ECalModelClient *client_data) if (comp_data->client == client_data->client) { e_table_model_pre_change (E_TABLE_MODEL (model)); - - g_ptr_array_remove (model->priv->objects, comp_data); - free_comp_data (comp_data); - e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1); + + g_ptr_array_remove (model->priv->objects, comp_data); + e_cal_model_free_component_data (comp_data); } } } @@ -1991,10 +1967,9 @@ copy_ecdv (ECellDateEditValue *ecdv) { ECellDateEditValue *new_ecdv; - new_ecdv = g_new0 (ECellDateEditValue, 1); - new_ecdv->tt = ecdv->tt; - new_ecdv->zone = ecdv->zone; + new_ecdv->tt = ecdv ? ecdv->tt : icaltime_null_time (); + new_ecdv->zone = ecdv ? ecdv->zone : NULL; return new_ecdv; } @@ -2011,6 +1986,8 @@ e_cal_model_copy_component_data (ECalModelComponent *comp_data) new_data = g_new0 (ECalModelComponent, 1); + new_data->instance_start = comp_data->instance_start; + new_data->instance_end = comp_data->instance_end; if (comp_data->icalcomp) new_data->icalcomp = icalcomponent_new_clone (comp_data->icalcomp); if (comp_data->client) @@ -2023,6 +2000,8 @@ e_cal_model_copy_component_data (ECalModelComponent *comp_data) new_data->due = copy_ecdv (comp_data->due); if (comp_data->completed) new_data->completed = copy_ecdv (comp_data->completed); + if (comp_data->color) + new_data->color = g_strdup (comp_data->color); return new_data; } @@ -2035,20 +2014,34 @@ e_cal_model_free_component_data (ECalModelComponent *comp_data) { g_return_if_fail (comp_data != NULL); - if (comp_data->client) + if (comp_data->client) { g_object_unref (comp_data->client); - if (comp_data->icalcomp) + comp_data->client = NULL; + } + if (comp_data->icalcomp) { icalcomponent_free (comp_data->icalcomp); - if (comp_data->dtstart) + comp_data->icalcomp = NULL; + } + if (comp_data->dtstart) { g_free (comp_data->dtstart); - if (comp_data->dtend) + comp_data->dtstart = NULL; + } + if (comp_data->dtend) { g_free (comp_data->dtend); - if (comp_data->due) + comp_data->dtend = NULL; + } + if (comp_data->due) { g_free (comp_data->due); - if (comp_data->completed) + comp_data->due = NULL; + } + if (comp_data->completed) { g_free (comp_data->completed); - if (comp_data->color) + comp_data->completed = NULL; + } + if (comp_data->color) { g_free (comp_data->color); + comp_data->color = NULL; + } g_free (comp_data); } diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 970fe8a325..78f8cfc9b4 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -286,6 +286,7 @@ static ECalendarViewPosition e_day_view_convert_position_in_main_canvas (EDayVie gint *event_num_return); static gboolean e_day_view_find_event_from_uid (EDayView *day_view, const gchar *uid, + const gchar *rid, gint *day_return, gint *event_num_return); @@ -507,7 +508,7 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data) { EDayViewEvent *event; gint day, event_num; - const char *uid; + const char *uid, *rid; ECalComponent *comp; AddEventData add_event_data; @@ -524,11 +525,15 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data) } e_cal_component_get_uid (comp, &uid); + if (e_cal_component_is_instance (comp)) + rid = e_cal_component_get_recurid_as_string (comp); + else + rid = NULL; /* If the event already exists and the dates didn't change, we can update the event fairly easily without changing the events arrays or computing a new layout. */ - if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { + if (e_day_view_find_event_from_uid (day_view, uid, rid, &day, &event_num)) { ECalComponent *tmp_comp; if (day == E_DAY_VIEW_LONG_EVENT) @@ -546,7 +551,8 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data) #if 0 g_print ("updated object's dates unchanged\n"); #endif - e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, comp_data); + /* e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, comp_data); */ + e_day_view_update_event_cb (day_view, day, event_num, comp_data); gtk_widget_queue_draw (day_view->top_canvas); gtk_widget_queue_draw (day_view->main_canvas); return; @@ -557,19 +563,25 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data) #if 0 g_print ("dates changed - removing occurrences\n"); #endif - e_day_view_foreach_event_with_uid (day_view, uid, - e_day_view_remove_event_cb, - NULL); + e_day_view_remove_event_cb (day_view, day, event_num, NULL); g_object_unref (tmp_comp); + } else { + if (rid && e_day_view_find_event_from_uid (day_view, uid, NULL, &day, &event_num)) { + if (day == E_DAY_VIEW_LONG_EVENT) + event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); + else + event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); + + if (!e_cal_util_component_is_instance (event->comp_data->icalcomp)) + e_day_view_remove_event_cb (day_view, day, event_num, NULL); + } } - /* Add the occurrences of the event */ + /* Add the object */ add_event_data.day_view = day_view; add_event_data.comp_data = comp_data; - e_cal_generate_instances_for_object (comp_data->client, comp_data->icalcomp, day_view->lower, - day_view->upper, - e_day_view_add_event, &add_event_data); + e_day_view_add_event (comp, comp_data->instance_start, comp_data->instance_end, &add_event_data); g_object_unref (comp); } @@ -640,55 +652,35 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data } -static gboolean -row_deleted_check_cb (EDayView *day_view, gint day, gint event_num, gpointer data) -{ - GHashTable *uids = data; - EDayViewEvent *event; - ECalModel *model; - const char *uid; - - if (day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - } else { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - } - - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); - - if (!e_cal_model_get_component_for_uid (model, uid)) - g_hash_table_insert (uids, g_strdup(uid), GINT_TO_POINTER (1)); - - return TRUE; -} - -static void -remove_uid_cb (gpointer key, gpointer value, gpointer data) -{ - EDayView *day_view = data; - char *uid = key; - - e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_remove_event_cb, NULL); - g_free(uid); -} - static void model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data) { EDayView *day_view = E_DAY_VIEW (user_data); - GHashTable *uids; + int i; e_day_view_stop_editing_event (day_view); - uids = g_hash_table_new (g_str_hash, g_str_equal); - - e_day_view_foreach_event (day_view, row_deleted_check_cb, uids); - g_hash_table_foreach (uids, remove_uid_cb, day_view); + for (i = row + count; i > row; i--) { + gint day, event_num; + const char *uid, *rid = NULL; + ECalModelComponent *comp_data; - g_hash_table_destroy (uids); + comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), i - 1); + if (!comp_data) + continue; + + uid = icalcomponent_get_uid (comp_data->icalcomp); + if (e_cal_util_component_is_instance (comp_data->icalcomp)) { + icalproperty *prop; + + prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_RECURRENCEID_PROPERTY); + if (prop) + rid = icaltime_as_ical_string (icalcomponent_get_recurrenceid (comp_data->icalcomp)); + } + + if (e_day_view_find_event_from_uid (day_view, uid, rid, &day, &event_num)) + e_day_view_remove_event_cb (day_view, day, event_num, NULL); + } gtk_widget_queue_draw (day_view->top_canvas); gtk_widget_queue_draw (day_view->main_canvas); @@ -1080,6 +1072,7 @@ e_day_view_new (void) GObject *day_view; day_view = g_object_new (e_day_view_get_type (), NULL); + e_cal_model_set_flags (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES); return GTK_WIDGET (day_view); } @@ -1778,6 +1771,9 @@ e_day_view_remove_event_cb (EDayView *day_view, event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); + if (!event) + return TRUE; + /* If we were editing this event, set editing_event_day to -1 so on_editing_stopped doesn't try to update the event. */ if (day_view->editing_event_day == day @@ -1970,12 +1966,13 @@ e_day_view_find_event_from_item (EDayView *day_view, static gboolean e_day_view_find_event_from_uid (EDayView *day_view, const gchar *uid, + const gchar *rid, gint *day_return, gint *event_num_return) { EDayViewEvent *event; gint day, event_num; - const char *u; + const char *u, *r; if (!uid) return FALSE; @@ -1988,6 +1985,14 @@ e_day_view_find_event_from_uid (EDayView *day_view, u = icalcomponent_get_uid (event->comp_data->icalcomp); if (u && !strcmp (uid, u)) { + if (rid && *rid) { + r = icaltime_as_ical_string (icalcomponent_get_recurrenceid (event->comp_data->icalcomp)); + if (!r || !*r) + continue; + if (strcmp (rid, r) != 0) + continue; + } + *day_return = day; *event_num_return = event_num; return TRUE; @@ -4866,7 +4871,7 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event) gtk_widget_queue_draw (day_view->top_canvas); gtk_widget_queue_draw (day_view->main_canvas); - if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { + if (e_day_view_find_event_from_uid (day_view, uid, NULL, &day, &event_num)) { e_day_view_start_editing_event (day_view, day, event_num, initial_text); } else { diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 587b0f3e06..fb60e67d3f 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -162,6 +162,7 @@ static void e_week_view_on_editing_stopped (EWeekView *week_view, GnomeCanvasItem *item); static gboolean e_week_view_find_event_from_uid (EWeekView *week_view, const gchar *uid, + const gchar *rid, gint *event_num_return); typedef gboolean (* EWeekViewForeachEventCallback) (EWeekView *week_view, gint event_num, @@ -302,16 +303,6 @@ time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpo e_week_view_set_selected_time_range (E_CALENDAR_VIEW (week_view), start_time, start_time); } -static gboolean -process_component_recur_cb (ECalComponent *comp, time_t start, time_t end, gpointer data) -{ - AddEventData *add_event_data; - - add_event_data = data; - - return e_week_view_add_event (comp, start, end, FALSE, add_event_data); -} - static void process_component (EWeekView *week_view, ECalModelComponent *comp_data) { @@ -319,7 +310,7 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data) gint event_num, num_days; ECalComponent *comp = NULL; AddEventData add_event_data; - const char *uid; + const char *uid, *rid; /* If we don't have a valid date set yet, just return. */ if (!g_date_valid (&week_view->first_day_shown)) @@ -334,11 +325,15 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data) } e_cal_component_get_uid (comp, &uid); + if (e_cal_component_is_instance (comp)) + rid = e_cal_component_get_recurid_as_string (comp); + else + rid = NULL; /* If the event already exists and the dates didn't change, we can update the event fairly easily without changing the events arrays or computing a new layout. */ - if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { + if (e_week_view_find_event_from_uid (week_view, uid, rid, &event_num)) { ECalComponent *tmp_comp; event = &g_array_index (week_view->events, EWeekViewEvent, @@ -352,7 +347,8 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data) #if 0 g_print ("updated object's dates unchanged\n"); #endif - e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp_data); + /* e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp_data); */ + e_week_view_update_event_cb (week_view, event_num, comp_data); g_object_unref (comp); g_object_unref (tmp_comp); gtk_widget_queue_draw (week_view->main_canvas); @@ -364,22 +360,23 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data) #if 0 g_print ("dates changed - removing occurrences\n"); #endif - e_week_view_foreach_event_with_uid (week_view, uid, - e_week_view_remove_event_cb, - NULL); + e_week_view_remove_event_cb (week_view, event_num, NULL); g_object_unref (tmp_comp); + } else { + if (rid && e_week_view_find_event_from_uid (week_view, uid, NULL, &event_num)) { + event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + if (!e_cal_util_component_is_instance (event->comp_data->icalcomp)) + e_week_view_remove_event_cb (week_view, event_num, NULL); + } } - /* Add the occurrences of the event */ + /* Add the object */ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; add_event_data.week_view = week_view; add_event_data.comp_data = comp_data; - e_cal_generate_instances_for_object (comp_data->client, comp_data->icalcomp, - week_view->day_starts[0], - week_view->day_starts[num_days], - process_component_recur_cb, &add_event_data); + e_week_view_add_event (comp, comp_data->instance_start, comp_data->instance_end, FALSE, &add_event_data); g_object_unref (comp); } @@ -444,49 +441,17 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data e_week_view_queue_layout (week_view); } -static gboolean -row_deleted_check_cb (EWeekView *week_view, gint event_num, gpointer data) -{ - GHashTable *uids = data; - EWeekViewEvent *event; - ECalModel *model; - const char *uid; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); - - if (!e_cal_model_get_component_for_uid (model, uid)) - g_hash_table_insert (uids, g_strdup(uid), GINT_TO_POINTER (1)); - - return TRUE; -} - -static void -remove_uid_cb (gpointer key, gpointer value, gpointer data) -{ - EWeekView *week_view = data; - char *uid = key; - - e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_remove_event_cb, NULL); - g_free(uid); -} - static void model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data) { EWeekView *week_view = E_WEEK_VIEW (user_data); - GHashTable *uids; + int i; /* FIXME Stop editing? */ - - uids = g_hash_table_new (g_str_hash, g_str_equal); - e_week_view_foreach_event (week_view, row_deleted_check_cb, uids); - g_hash_table_foreach (uids, remove_uid_cb, week_view); + for (i = row + count; i > row; i--) + e_week_view_remove_event_cb (week_view, i - 1, NULL); - g_hash_table_destroy (uids); - gtk_widget_queue_draw (week_view->main_canvas); e_week_view_queue_layout (week_view); } @@ -691,6 +656,7 @@ e_week_view_new (void) GtkWidget *week_view; week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL)); + e_cal_model_set_flags (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES); return week_view; } @@ -1969,6 +1935,8 @@ e_week_view_remove_event_cb (EWeekView *week_view, gint span_num; event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + if (!event) + return TRUE; /* If we were editing this event, set editing_event_num to -1 so on_editing_stopped doesn't try to update the event. */ @@ -1992,6 +1960,7 @@ e_week_view_remove_event_cb (EWeekView *week_view, } e_cal_model_free_component_data (event->comp_data); + event->comp_data = NULL; g_array_remove_index (week_view->events, event_num); week_view->events_need_layout = TRUE; @@ -3425,6 +3394,7 @@ e_week_view_find_event_from_item (EWeekView *week_view, static gboolean e_week_view_find_event_from_uid (EWeekView *week_view, const gchar *uid, + const gchar *rid, gint *event_num_return) { EWeekViewEvent *event; @@ -3436,13 +3406,21 @@ e_week_view_find_event_from_uid (EWeekView *week_view, num_events = week_view->events->len; for (event_num = 0; event_num < num_events; event_num++) { - const char *u; + const char *u, *r; event = &g_array_index (week_view->events, EWeekViewEvent, event_num); u = icalcomponent_get_uid (event->comp_data->icalcomp); if (u && !strcmp (uid, u)) { + if (rid && *rid) { + r = icaltime_as_ical_string (icalcomponent_get_recurrenceid (event->comp_data->icalcomp)); + if (!r || !*r) + continue; + if (strcmp (rid, r) != 0) + continue; + } + *event_num_return = event_num; return TRUE; } @@ -3780,7 +3758,7 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event) e_week_view_check_layout (week_view); gtk_widget_queue_draw (week_view->main_canvas); - if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { + if (e_week_view_find_event_from_uid (week_view, uid, NULL, &event_num)) { EWeekViewEvent *event; EWeekViewEventSpan *span; |