aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog31
-rw-r--r--calendar/gui/e-cal-list-view.c1
-rw-r--r--calendar/gui/e-cal-model-calendar.c20
-rw-r--r--calendar/gui/e-cal-model.c205
-rw-r--r--calendar/gui/e-cal-model.h16
-rw-r--r--calendar/gui/e-calendar-view.c16
-rw-r--r--calendar/gui/e-day-view.c2
-rw-r--r--calendar/gui/e-week-view.c2
8 files changed, 224 insertions, 69 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 6487a72351..49816845e4 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,34 @@
+2004-07-30 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-29 JP Rosevear <jpr@novell.com>
* gui/e-calendar-view.c: creating new items no longer needs to be
diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c
index ab1feefa7c..db194895fd 100644
--- a/calendar/gui/e-cal-list-view.c
+++ b/calendar/gui/e-cal-list-view.c
@@ -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)) {
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index 3649352372..4754927bbd 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -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, int row)
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 :
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index e5f0f8c418..64b8d6e328 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -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, ECalModelClass *klass)
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, ECalModelComponent *comp_data)
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 (ECalModel *model, icalcomponent_kind kind)
}
/**
+ * 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 *objects, gpointer item)
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 *query, GList *objects, gpointer user_data
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 *query, GList *objects, gpointer user_d
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;
- comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), icalcomponent_get_uid (l->data));
- if (!comp_data)
- continue;
+ /* 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;
- }
+ 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 *query, GList *uids, gpointer user_data)
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;
+ /* 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);
- 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 *client, gboolean do_query)
{
ECalModelPrivate *priv;
ECalModelClient *client_data;
- ECal *existing_client;
priv = model->priv;
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index 846d7b4acd..69feef8842 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -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 (void);
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_default_category (ECalModel
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_range (ECalModel
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);
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index e95bc458ff..0cb5cb9f3d 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -910,17 +910,13 @@ e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view)
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);
}
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index cf60e91fcc..4830bbda89 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -4131,6 +4131,8 @@ e_day_view_add_event (ECalComponent *comp,
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. */
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index d53918ae5e..ee884db3de 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -2437,6 +2437,8 @@ e_week_view_add_event (ECalComponent *comp,
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;