Re: [evolution-patches] calendar patch for #57622
- From: Rodrigo Moya <rodrigo novell com>
- To: JP Rosevear <jpr novell com>
- Cc: Evolution Patches <evolution-patches lists ximian com>
- Subject: Re: [evolution-patches] calendar patch for #57622
- Date: Fri, 30 Jul 2004 13:58:24 +0200
On Thu, 2004-07-29 at 13:46 -0400, JP Rosevear wrote:
> On Thu, 2004-07-29 at 11:44 +0200, Rodrigo Moya wrote:
> > This fixes #57622. I don't like very much to remove all recurrences and
> > re-add them again in the objects_modified_cb, but trying to update every
> > individual recurrence (and removing the ones that don't apply anymore as
> > well as adding the new ones) might get the code too complicated for 2.0
> > I guess. With the attached patch, when you update a recurring
> > appointment, the recurrences disappear from the list view and show up
> > again at the end of the list, which might be confusing. Any suggestion?
>
> The only problem I see is that "Delete this Occurrence" in the list view
> adds an exdate of 1/1/1970 instead of the correct date.
>
right, we were using in that function the ECalViewEvent's start time,
which was only filled in in the day and week views. The attached patch
makes all views fill in the ECalModelComponent's instance_start, and
that is what is used.
--
Rodrigo Moya <rodrigo novell com>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2465
diff -u -p -r1.2465 ChangeLog
--- ChangeLog 30 Jul 2004 07:37:02 -0000 1.2465
+++ ChangeLog 30 Jul 2004 11:56:18 -0000
@@ -1,3 +1,34 @@
+2004-07-29 Rodrigo Moya <rodrigo novell com>
+
+ Fixes #57622
+
+ * gui/e-cal-model.h: added ECalModelFlags enum type.
+
+ * gui/e-cal-model.c (e_cal_model_set_flags, e_cal_model_get_flags):
+ new functions.
+ (e_cal_model_init): initialize the new internal field to keep the flags.
+ (e_cal_view_objects_added_cb): expand recurrences if the model flags
+ contain the EXPAND_RECUR bit.
+ (e_cal_view_objects_modified_cb): if EXPAND_RECUR is on, remove all
+ recurrences and regenerate them.
+ (e_cal_view_objects_removed_cb): remove all instances for given UIDs.
+ (add_new_client): killed warning.
+ (get_dtstart): use the instance_start time when dealing with recurrences.
+
+ * gui/e-cal-model-calendar.c (get_dtend): use the instance_end time
+ when dealing with recurrences.
+
+ * gui/e-cal-list-view.c (e_cal_list_view_new): set the EXPAND_RECUR
+ flag on the model for the list view.
+
+ * gui/e-week-view.c (e_week_view_add_event):
+ * gui/e-day-view.c (e_day_view_add_event): fill in the instance's
+ start and end times in the ECalModelComponent struct.
+
+ * gui/e-calendar-view.c (e_calendar_view_delete_selected_occurrence):
+ use the instance_start field to retrieve the RECUR-ID, now that all the
+ views fill it in.
+
2004-07-28 Larry Ewing <lewing novell com>
* gui/dialogs/calendar-setup.c (dialog_hide_unused_options): hide
Index: gui/e-cal-list-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-list-view.c,v
retrieving revision 1.9
diff -u -p -r1.9 e-cal-list-view.c
--- gui/e-cal-list-view.c 3 May 2004 18:23:10 -0000 1.9
+++ gui/e-cal-list-view.c 30 Jul 2004 11:56:19 -0000
@@ -318,6 +318,7 @@ e_cal_list_view_new (void)
ECalModel *model;
model = E_CAL_MODEL (e_cal_model_calendar_new ());
+ e_cal_model_set_flags (model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
cal_list_view = g_object_new (e_cal_list_view_get_type (), "model", model, NULL);
if (!e_cal_list_view_construct (cal_list_view)) {
Index: gui/e-cal-model-calendar.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-model-calendar.c,v
retrieving revision 1.12
diff -u -p -r1.12 e-cal-model-calendar.c
--- gui/e-cal-model-calendar.c 13 Jul 2004 11:07:19 -0000 1.12
+++ gui/e-cal-model-calendar.c 30 Jul 2004 11:56:19 -0000
@@ -112,22 +112,34 @@ ecmc_column_count (ETableModel *etm)
}
static ECellDateEditValue *
-get_dtend (ECalModelComponent *comp_data)
+get_dtend (ECalModel *model, ECalModelComponent *comp_data)
{
struct icaltimetype tt_end;
if (!comp_data->dtend) {
icaltimezone *zone;
+ gboolean got_zone = FALSE;
tt_end = icalcomponent_get_dtend (comp_data->icalcomp);
+ if (icaltime_get_tzid (tt_end)
+ && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_end), &zone, NULL))
+ got_zone = TRUE;
+
+ if ((e_cal_model_get_flags (model) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) &&
+ (e_cal_util_component_has_recurrences (comp_data->icalcomp))) {
+ if (got_zone)
+ tt_end = icaltime_from_timet_with_zone (comp_data->instance_end, tt_end.is_date, zone);
+ else
+ tt_end = icaltime_from_timet (comp_data->instance_end, tt_end.is_date);
+ }
+
if (!icaltime_is_valid_time (tt_end))
return NULL;
comp_data->dtend = g_new0 (ECellDateEditValue, 1);
comp_data->dtend->tt = tt_end;
- if (icaltime_get_tzid (tt_end)
- && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_end), &zone, NULL))
+ if (got_zone)
comp_data->dtend->zone = zone;
else
comp_data->dtend->zone = NULL;
@@ -192,7 +204,7 @@ ecmc_value_at (ETableModel *etm, int col
switch (col) {
case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
- return get_dtend (comp_data);
+ return get_dtend (model, comp_data);
case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
return get_location (comp_data);
case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
Index: gui/e-cal-model.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-model.c,v
retrieving revision 1.41
diff -u -p -r1.41 e-cal-model.c
--- gui/e-cal-model.c 28 Jul 2004 18:03:32 -0000 1.41
+++ gui/e-cal-model.c 30 Jul 2004 11:56:20 -0000
@@ -53,6 +53,7 @@ struct _ECalModelPrivate {
GPtrArray *objects;
icalcomponent_kind kind;
+ ECalModelFlags flags;
icaltimezone *zone;
/* The time range to display */
@@ -174,6 +175,7 @@ e_cal_model_init (ECalModel *model, ECal
priv->objects = g_ptr_array_new ();
priv->kind = ICAL_NO_COMPONENT;
+ priv->flags = 0;
priv->accounts = itip_addresses_get ();
@@ -400,21 +402,28 @@ get_dtstart (ECalModel *model, ECalModel
if (!comp_data->dtstart) {
icaltimezone *zone;
- icalproperty *prop;
+ gboolean got_zone = FALSE;
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY);
- if (!prop)
- return NULL;
+ tt_start = icalcomponent_get_dtstart (comp_data->icalcomp);
+ if (icaltime_get_tzid (tt_start)
+ && 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)
+ tt_start = icaltime_from_timet_with_zone (comp_data->instance_start, tt_start.is_date, zone);
+ else
+ tt_start = icaltime_from_timet (comp_data->instance_start, tt_start.is_date);
+ }
- tt_start = icalproperty_get_dtstart (prop);
if (!icaltime_is_valid_time (tt_start))
return NULL;
comp_data->dtstart = g_new0 (ECellDateEditValue, 1);
comp_data->dtstart->tt = tt_start;
- if (icaltime_get_tzid (tt_start)
- && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_start), &zone, NULL))
+ if (got_zone)
comp_data->dtstart->zone = zone;
else
comp_data->dtstart->zone = NULL;
@@ -1037,6 +1046,34 @@ e_cal_model_set_component_kind (ECalMode
}
/**
+ * e_cal_model_get_flags
+ */
+ECalModelFlags
+e_cal_model_get_flags (ECalModel *model)
+{
+ ECalModelPrivate *priv;
+
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), E_CAL_MODEL_FLAGS_INVALID);
+
+ priv = model->priv;
+ return priv->flags;
+}
+
+/**
+ * e_cal_model_set_flags
+ */
+void
+e_cal_model_set_flags (ECalModel *model, ECalModelFlags flags)
+{
+ ECalModelPrivate *priv;
+
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+
+ priv = model->priv;
+ priv->flags = flags;
+}
+
+/**
* e_cal_model_get_timezone
*/
icaltimezone *
@@ -1263,6 +1300,36 @@ get_position_in_array (GPtrArray *object
return -1;
}
+typedef struct {
+ ECal *client;
+ ECalView *query;
+ ECalModel *model;
+ icalcomponent *icalcomp;
+} RecurrenceExpansionData;
+
+static gboolean
+add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end, gpointer user_data)
+{
+ ECalModelComponent *comp_data;
+ ECalModelPrivate *priv;
+ RecurrenceExpansionData *rdata = user_data;
+
+ 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;
+
+ g_ptr_array_add (priv->objects, comp_data);
+ e_table_model_row_inserted (E_TABLE_MODEL (rdata->model), priv->objects->len - 1);
+
+ return TRUE;
+}
+
static void
e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data)
{
@@ -1273,17 +1340,30 @@ e_cal_view_objects_added_cb (ECalView *q
priv = model->priv;
for (l = objects; l; l = l->next) {
- ECalModelComponent *comp_data;
+ if ((priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) &&
+ e_cal_util_component_has_recurrences (l->data)) {
+ RecurrenceExpansionData rdata;
+
+ rdata.client = e_cal_view_get_client (query);
+ rdata.query = query;
+ rdata.model = model;
+ rdata.icalcomp = l->data;
+ e_cal_generate_instances_for_object (rdata.client, l->data,
+ priv->start, priv->end,
+ (ECalRecurInstanceFn) add_instance_cb,
+ &rdata);
+ } else {
+ ECalModelComponent *comp_data;
- e_table_model_pre_change (E_TABLE_MODEL (model));
+ e_table_model_pre_change (E_TABLE_MODEL (model));
- 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);
-
- g_ptr_array_add (priv->objects, comp_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);
- e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1);
+ g_ptr_array_add (priv->objects, comp_data);
+ e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1);
+ }
}
}
@@ -1299,38 +1379,61 @@ e_cal_view_objects_modified_cb (ECalView
for (l = objects; l; l = l->next) {
ECalModelComponent *comp_data;
- e_table_model_pre_change (E_TABLE_MODEL (model));
+ 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;
- comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), icalcomponent_get_uid (l->data));
- if (!comp_data)
- continue;
+ 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;
- }
+ 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);
+ comp_data->icalcomp = icalcomponent_new_clone (l->data);
- e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
+ e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
+ }
}
}
@@ -1349,16 +1452,15 @@ e_cal_view_objects_removed_cb (ECalView
e_table_model_pre_change (E_TABLE_MODEL (model));
- comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), l->data);
- if (!comp_data)
- continue;
-
- pos = get_position_in_array (priv->objects, comp_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);
+ g_ptr_array_remove (priv->objects, comp_data);
+ free_comp_data (comp_data);
- e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
+ e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
+ }
}
}
@@ -1460,7 +1562,6 @@ add_new_client (ECalModel *model, ECal *
{
ECalModelPrivate *priv;
ECalModelClient *client_data;
- ECal *existing_client;
priv = model->priv;
Index: gui/e-cal-model.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-model.h,v
retrieving revision 1.12
diff -u -p -r1.12 e-cal-model.h
--- gui/e-cal-model.h 14 Jul 2004 02:20:55 -0000 1.12
+++ gui/e-cal-model.h 30 Jul 2004 11:56:20 -0000
@@ -52,9 +52,16 @@ typedef enum {
E_CAL_MODEL_FIELD_LAST
} ECalModelField;
+typedef enum {
+ E_CAL_MODEL_FLAGS_INVALID = -1,
+ E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES = 0x01
+} ECalModelFlags;
+
typedef struct {
ECal *client;
icalcomponent *icalcomp;
+ time_t instance_start;
+ time_t instance_end;
/* private data */
ECellDateEditValue *dtstart;
@@ -91,6 +98,9 @@ GType e_cal_model_get_type
icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model);
void e_cal_model_set_component_kind (ECalModel *model,
icalcomponent_kind kind);
+ECalModelFlags e_cal_model_get_flags (ECalModel *model);
+void e_cal_model_set_flags (ECalModel *model,
+ ECalModelFlags flags);
icaltimezone *e_cal_model_get_timezone (ECalModel *model);
void e_cal_model_set_timezone (ECalModel *model,
icaltimezone *zone);
@@ -99,11 +109,11 @@ void e_cal_model_set_defa
gboolean e_cal_model_get_use_24_hour_format (ECalModel *model);
void e_cal_model_set_use_24_hour_format (ECalModel *model,
gboolean use24);
-ECal * e_cal_model_get_default_client (ECalModel *model);
+ECal *e_cal_model_get_default_client (ECalModel *model);
void e_cal_model_set_default_client (ECalModel *model,
ECal *client);
GList *e_cal_model_get_client_list (ECalModel *model);
-ECal * e_cal_model_get_client_for_uri (ECalModel *model,
+ECal *e_cal_model_get_client_for_uri (ECalModel *model,
const char *uri);
void e_cal_model_add_client (ECalModel *model,
ECal *client);
@@ -116,7 +126,7 @@ void e_cal_model_get_time
void e_cal_model_set_time_range (ECalModel *model,
time_t start,
time_t end);
-const char * e_cal_model_get_search_query (ECalModel *model);
+const char *e_cal_model_get_search_query (ECalModel *model);
void e_cal_model_set_search_query (ECalModel *model,
const gchar *sexp);
icalcomponent *e_cal_model_create_component_with_defaults (ECalModel *model);
Index: gui/e-calendar-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-calendar-view.c,v
retrieving revision 1.60
diff -u -p -r1.60 e-calendar-view.c
--- gui/e-calendar-view.c 14 Jul 2004 02:20:55 -0000 1.60
+++ gui/e-calendar-view.c 30 Jul 2004 11:56:20 -0000
@@ -910,17 +910,13 @@ e_calendar_view_delete_selected_occurren
return;
}
- /* get the RECUR-ID from the start date */
+ /* get the RECUR-ID from the instance start date */
e_cal_component_get_dtstart (comp, &dt);
- if (dt.value) {
- if (e_cal_get_timezone (event->comp_data->client, dt.tzid, &zone, NULL)) {
- rid = icaltime_as_ical_string (
- icaltime_from_timet_with_zone (event->start, TRUE, zone));
- } else {
- rid = icaltime_as_ical_string (
- icaltime_from_timet (event->start, TRUE));
- }
- }
+ if (e_cal_get_timezone (event->comp_data->client, dt.tzid, &zone, NULL)) {
+ rid = icaltime_as_ical_string (
+ icaltime_from_timet_with_zone (event->comp_data->instance_start, TRUE, zone));
+ } else
+ rid = icaltime_as_ical_string (icaltime_from_timet (event->comp_data->instance_start, TRUE));
e_cal_component_free_datetime (&dt);
}
Index: gui/e-day-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-day-view.c,v
retrieving revision 1.250
diff -u -p -r1.250 e-day-view.c
--- gui/e-day-view.c 16 Jul 2004 14:30:49 -0000 1.250
+++ gui/e-day-view.c 30 Jul 2004 11:56:24 -0000
@@ -4131,6 +4131,8 @@ e_day_view_add_event (ECalComponent *com
event.start = start;
event.end = end;
event.canvas_item = NULL;
+ event.comp_data->instance_start = start;
+ event.comp_data->instance_end = end;
/* Calculate the start & end minute, relative to the top of the
display. */
Index: gui/e-week-view.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-week-view.c,v
retrieving revision 1.220
diff -u -p -r1.220 e-week-view.c
--- gui/e-week-view.c 27 Jul 2004 02:29:11 -0000 1.220
+++ gui/e-week-view.c 30 Jul 2004 11:56:26 -0000
@@ -2437,6 +2437,8 @@ e_week_view_add_event (ECalComponent *co
event.end = end;
event.spans_index = 0;
event.num_spans = 0;
+ event.comp_data->instance_start = start;
+ event.comp_data->instance_end = end;
event.start_minute = start_tt.hour * 60 + start_tt.minute;
event.end_minute = end_tt.hour * 60 + end_tt.minute;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]