[evolution-patches] patch for #59904 (calendar) for 2.0.x
- From: Rodrigo Moya <rodrigo novell com>
- To: Evolution Patches <evolution-patches lists ximian com>
- Subject: [evolution-patches] patch for #59904 (calendar) for 2.0.x
- Date: Wed, 10 Nov 2004 18:05:37 +0100
The attached patch backports the change I did to HEAD for speeding up
calendar viewing. Bug #59904 has got a lot of duplicates, so we really
need this to go to the 2.0.x branch
--
Rodrigo Moya <rodrigo novell com>
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/ChangeLog,v
retrieving revision 1.324.2.8
diff -u -p -r1.324.2.8 ChangeLog
--- ChangeLog 7 Oct 2004 14:21:30 -0000 1.324.2.8
+++ ChangeLog 10 Nov 2004 17:00:13 -0000
@@ -1,3 +1,20 @@
+2004-11-10 Rodrigo Moya <rodrigo novell com>
+
+ Fixes #59904
+
+ * libecal/e-cal.[ch] (e_cal_get_objects_for_uid): new function
+ to retrieve objects and detached recurrences for that object.
+ (e_cal_get_object): deal with the backend returning a VCALENDAR
+ object. In that case, just get the first component of the same
+ type we are using.
+ (generate_instances): when we have an UID, use the new function
+ e_cal_get_objects_for_uid, avoiding countless calls to
+ e_cal_get_object_list.
+
+ * backends/file/e-cal-backend-file.c (e_cal_backend_file_get_object):
+ if we have detached instances, return a VCALENDAR with the master
+ object and any detached instance.
+
2004-10-07 JP Rosevear <jpr novell com>
* libecal/e-cal.c (e_cal_new_system_tasks): load the correct type
Index: backends/file/e-cal-backend-file.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/backends/file/e-cal-backend-file.c,v
retrieving revision 1.35
diff -u -p -r1.35 e-cal-backend-file.c
--- backends/file/e-cal-backend-file.c 17 Aug 2004 14:32:39 -0000 1.35
+++ backends/file/e-cal-backend-file.c 10 Nov 2004 17:00:13 -0000
@@ -997,6 +997,17 @@ e_cal_backend_file_get_default_object (E
return GNOME_Evolution_Calendar_Success;
}
+static void
+add_detached_recur_to_vcalendar (gpointer key, gpointer value, gpointer user_data)
+{
+ ECalComponent *recurrence = value;
+ icalcomponent *vcalendar = user_data;
+
+ icalcomponent_add_component (
+ vcalendar,
+ icalcomponent_new_clone (e_cal_component_get_icalcomponent (recurrence)));
+}
+
/* Get_object_component handler for the file backend */
static ECalBackendSyncStatus
e_cal_backend_file_get_object (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *rid, char **object)
@@ -1004,8 +1015,6 @@ e_cal_backend_file_get_object (ECalBacke
ECalBackendFile *cbfile;
ECalBackendFilePrivate *priv;
ECalBackendFileObject *obj_data;
- ECalComponent *comp = NULL;
- gboolean free_comp = FALSE;
cbfile = E_CAL_BACKEND_FILE (backend);
priv = cbfile->priv;
@@ -1019,8 +1028,12 @@ e_cal_backend_file_get_object (ECalBacke
return GNOME_Evolution_Calendar_ObjectNotFound;
if (rid && *rid) {
+ ECalComponent *comp;
+
comp = g_hash_table_lookup (obj_data->recurrences, rid);
- if (!comp) {
+ if (comp) {
+ *object = e_cal_component_get_as_string (comp);
+ } else {
icalcomponent *icalcomp;
struct icaltimetype itt;
@@ -1031,20 +1044,29 @@ e_cal_backend_file_get_object (ECalBacke
if (!icalcomp)
return GNOME_Evolution_Calendar_ObjectNotFound;
- comp = e_cal_component_new ();
- free_comp = TRUE;
- e_cal_component_set_icalcomponent (comp, icalcomp);
- }
- } else
- comp = obj_data->full_object;
-
- if (!comp)
- return GNOME_Evolution_Calendar_ObjectNotFound;
+ *object = g_strdup (icalcomponent_as_ical_string (icalcomp));
- *object = e_cal_component_get_as_string (comp);
+ icalcomponent_free (icalcomp);
+ }
+ } else {
+ if (g_hash_table_size (obj_data->recurrences) > 0) {
+ icalcomponent *icalcomp;
- if (free_comp)
- g_object_unref (comp);
+ /* if we have detached recurrences, return a VCALENDAR */
+ icalcomp = e_cal_util_new_top_level ();
+ icalcomponent_add_component (
+ icalcomp,
+ icalcomponent_new_clone (e_cal_component_get_icalcomponent (obj_data->full_object)));
+
+ /* add all detached recurrences */
+ g_hash_table_foreach (obj_data->recurrences, (GHFunc) add_detached_recur_to_vcalendar, icalcomp);
+
+ *object = g_strdup (icalcomponent_as_ical_string (icalcomp));
+
+ icalcomponent_free (icalcomp);
+ } else
+ *object = e_cal_component_get_as_string (obj_data->full_object);
+ }
return GNOME_Evolution_Calendar_Success;
}
Index: libecal/e-cal.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal.c,v
retrieving revision 1.75.2.3
diff -u -p -r1.75.2.3 e-cal.c
--- libecal/e-cal.c 7 Oct 2004 14:21:30 -0000 1.75.2.3
+++ libecal/e-cal.c 10 Nov 2004 17:00:14 -0000
@@ -2368,9 +2368,9 @@ e_cal_get_default_object (ECal *ecal, ic
* e_cal_get_object:
* @ecal: A calendar ecal.
* @uid: Unique identifier for a calendar component.
- * @rid:
+ * @rid: Recurrence identifier.
* @icalcomp: Return value for the calendar component object.
- * @error:
+ * @error: Placeholder for error information.
*
* Queries a calendar for a calendar component object based on its unique
* identifier.
@@ -2380,7 +2380,6 @@ e_cal_get_default_object (ECal *ecal, ic
gboolean
e_cal_get_object (ECal *ecal, const char *uid, const char *rid, icalcomponent **icalcomp, GError **error)
{
-
ECalPrivate *priv;
CORBA_Environment ev;
ECalendarStatus status;
@@ -2433,9 +2432,164 @@ e_cal_get_object (ECal *ecal, const char
if (status != E_CALENDAR_STATUS_OK){
*icalcomp = NULL;
} else {
- *icalcomp = icalparser_parse_string (our_op->string);
- if (!(*icalcomp))
+ icalcomponent *tmp_icalcomp;
+ icalcomponent_kind kind;
+
+ tmp_icalcomp = icalparser_parse_string (our_op->string);
+ if (!tmp_icalcomp) {
status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ *icalcomp = NULL;
+ } else {
+ kind = icalcomponent_isa (tmp_icalcomp);
+ if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
+ (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO)) {
+ *icalcomp = icalcomponent_new_clone (tmp_icalcomp);
+ } else if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent *subcomp = NULL;
+
+ switch (priv->type) {
+ case E_CAL_SOURCE_TYPE_EVENT :
+ subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VEVENT_COMPONENT);
+ break;
+ case E_CAL_SOURCE_TYPE_TODO :
+ subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VTODO_COMPONENT);
+ break;
+ case E_CAL_SOURCE_TYPE_JOURNAL :
+ subcomp = icalcomponent_get_first_component (tmp_icalcomp, ICAL_VJOURNAL_COMPONENT);
+ break;
+ }
+
+ /* we are only interested in the first component */
+ if (subcomp)
+ *icalcomp = icalcomponent_new_clone (subcomp);
+ }
+
+ icalcomponent_free (tmp_icalcomp);
+ }
+ }
+ g_free (our_op->string);
+
+ e_calendar_remove_op (ecal, our_op);
+ g_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+/**
+ * e_cal_get_objects_for_uid:
+ * @ecal: A calendar ecal.
+ * @uid: Unique identifier for a calendar component.
+ * @objects: Return value for the list of objects obtained from the backend.
+ * @error: Placeholder for error information.
+ *
+ * Queries a calendar for all calendar components with the given unique
+ * ID. This will return any recurring event and all its detached recurrences.
+ * For non-recurring events, it will just return the object with that ID.
+ *
+ * Return value: Result code based on the status of the operation.
+ **/
+gboolean
+e_cal_get_objects_for_uid (ECal *ecal, const char *uid, GList **objects, GError **error)
+{
+ ECalPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
+
+ priv = ecal->priv;
+ *objects = NULL;
+
+ g_mutex_lock (ecal->priv->mutex);
+
+ if (ecal->priv->load_state != E_CAL_LOAD_LOADED) {
+ g_mutex_unlock (ecal->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (ecal->priv->current_op != NULL) {
+ g_mutex_unlock (ecal->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (ecal);
+
+ g_mutex_lock (our_op->mutex);
+
+ g_mutex_unlock (ecal->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, "", &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (ecal, our_op);
+ g_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ g_cond_wait (our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ if (status != E_CALENDAR_STATUS_OK){
+ *objects = NULL;
+ } else {
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+
+ icalcomp = icalparser_parse_string (our_op->string);
+ if (!icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ *objects = NULL;
+ } else {
+ ECalComponent *comp;
+
+ kind = icalcomponent_isa (icalcomp);
+ if ((kind == ICAL_VEVENT_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_EVENT) ||
+ (kind == ICAL_VTODO_COMPONENT && priv->type == E_CAL_SOURCE_TYPE_TODO)) {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ *objects = g_list_append (NULL, comp);
+ } else if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent *subcomp;
+ icalcomponent_kind kind_to_find;
+
+ switch (priv->type) {
+ case E_CAL_SOURCE_TYPE_EVENT :
+ kind_to_find = ICAL_VEVENT_COMPONENT;
+ break;
+ case E_CAL_SOURCE_TYPE_TODO :
+ kind_to_find = ICAL_VTODO_COMPONENT;
+ break;
+ case E_CAL_SOURCE_TYPE_JOURNAL :
+ kind_to_find = ICAL_VJOURNAL_COMPONENT;
+ break;
+ }
+
+ *objects = NULL;
+ subcomp = icalcomponent_get_first_component (icalcomp, kind_to_find);
+ while (subcomp) {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp));
+ *objects = g_list_append (*objects, comp);
+
+ subcomp = icalcomponent_get_next_component (icalcomp, kind_to_find);
+ }
+ }
+
+ icalcomponent_free (icalcomp);
+ }
}
g_free (our_op->string);
@@ -2887,30 +3041,32 @@ generate_instances (ECal *ecal, time_t s
priv = ecal->priv;
- iso_start = isodate_from_time_t (start);
- if (!iso_start)
- return;
-
- iso_end = isodate_from_time_t (end);
- if (!iso_end) {
- g_free (iso_start);
- return;
- }
-
/* Generate objects */
- if (uid && *uid)
- query = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\")) (uid? \"%s\"))",
- iso_start, iso_end, uid);
- else
+ if (uid && *uid) {
+ if (!e_cal_get_objects_for_uid (ecal, uid, &objects, NULL))
+ return;
+ }
+ else {
+ iso_start = isodate_from_time_t (start);
+ if (!iso_start)
+ return;
+
+ iso_end = isodate_from_time_t (end);
+ if (!iso_end) {
+ g_free (iso_start);
+ return;
+ }
+
query = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\") (make-time \"%s\"))",
iso_start, iso_end);
- g_free (iso_start);
- g_free (iso_end);
- if (!e_cal_get_object_list_as_comp (ecal, query, &objects, NULL)) {
+ g_free (iso_start);
+ g_free (iso_end);
+ if (!e_cal_get_object_list_as_comp (ecal, query, &objects, NULL)) {
+ g_free (query);
+ return;
+ }
g_free (query);
- return;
- }
- g_free (query);
+ }
instances = NULL;
Index: libecal/e-cal.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal.h,v
retrieving revision 1.19
diff -u -p -r1.19 e-cal.h
--- libecal/e-cal.h 2 Jun 2004 16:15:00 -0000 1.19
+++ libecal/e-cal.h 10 Nov 2004 17:00:14 -0000
@@ -141,6 +141,10 @@ gboolean e_cal_get_object (ECal *ecal,
const char *rid,
icalcomponent **icalcomp,
GError **error);
+gboolean e_cal_get_objects_for_uid (ECal *ecal,
+ const char *uid,
+ GList **objects,
+ GError **error);
gboolean e_cal_get_changes (ECal *ecal, const char *change_id, GList **changes, GError **error);
void e_cal_free_change_list (GList *list);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]