evolution-data-server r9025 - branches/gnome-2-22/calendar/libecal



Author: pohly
Date: Sun Jun 22 11:55:40 2008
New Revision: 9025
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9025&view=rev

Log:
GNOME Bugzilla #52890: replace time zone definitions when exporting events

There are reasons why calendars might contain events which
use an old and/or incomplete time zone definition:
* created with old Evolution release which did not yet use system time zones
* events created with other programs with TZIDs which could not be mapped yet
when the event was imported

This patch changes e_cal_get_timezone() so that if possible, the returned time
zone definition is taken from the system time zone database. Care was taken to
return the time zone with the TZID requested by the caller; otherwise the TZID
in a VEVENT would not match with the TZID in the system time zone.

I have checked a few situations and they all went through e_cal_get_timezone():
* exporting an event in SyncEvolution (via e_cal_component_as_string())
* saving an event in Evolution (also uses e_cal_component_as_string())
* sending an invitation in Evolution (via itip-util code)

The advantage of this patch is that updating system time zone information has
an effect on existing events. The drawback is that for historic events the
attached VTIMEZONE might be correct while the one generated by the current
Evolution for the current year is not. This drawback would go away as soon as
the generated VTIMEZONEs are complete. But until then the drawback of using an
outdated definition for a recurring event is probably worse, so the patch is
IMHO an improvement.

A (positive) side effect of the patch is that the backend is not called for
system time zones because they go through the new code path which takes the
definition from libical directly.


Modified:
   branches/gnome-2-22/calendar/libecal/e-cal.c

Modified: branches/gnome-2-22/calendar/libecal/e-cal.c
==============================================================================
--- branches/gnome-2-22/calendar/libecal/e-cal.c	(original)
+++ branches/gnome-2-22/calendar/libecal/e-cal.c	Sun Jun 22 11:55:40 2008
@@ -32,6 +32,7 @@
 #include <bonobo/bonobo-exception.h>
 #include <bonobo/bonobo-main.h>
 
+#include "libecal/e-cal-check-timezones.h"
 #include "libedataserver/e-component-listener.h"
 #include "libedataserver/e-flag.h"
 #include "libedataserver/e-url.h"
@@ -4635,9 +4636,10 @@
 {
 	ECalPrivate *priv;
 	CORBA_Environment ev;
-	ECalendarStatus status;
+	ECalendarStatus status = E_CALENDAR_STATUS_OK;
 	ECalendarOp *our_op;
 	icalcomponent *icalcomp;
+	const char *systzid;
 
 	e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
 	e_return_error_if_fail (zone, E_CALENDAR_STATUS_INVALID_ARG);
@@ -4688,34 +4690,74 @@
 		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
 	}
 
-	/* call the backend */
-	CORBA_exception_init (&ev);
+	/*
+	 * Try to replace the original time zone with a more complete
+	 * and/or potentially updated system time zone. Note that this
+	 * also applies to TZIDs which match system time zones exactly:
+	 * they are extracted via icaltimezone_get_builtin_timezone_from_tzid()
+	 * below without a roundtrip to the backend.
+	 */
+	systzid = e_cal_match_tzid (tzid);
+	if (!systzid) {
+		/* call the backend */
+		CORBA_exception_init (&ev);
 
-	GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
-	if (BONOBO_EX (&ev)) {
-		e_calendar_remove_op (ecal, our_op);
-		e_calendar_free_op (our_op);
+		GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
+		if (BONOBO_EX (&ev)) {
+			e_calendar_remove_op (ecal, our_op);
+			e_calendar_free_op (our_op);
 
-		CORBA_exception_free (&ev);
+			CORBA_exception_free (&ev);
 
-		g_warning (G_STRLOC ": Unable to contact backend");
+			g_warning (G_STRLOC ": Unable to contact backend");
 
-		E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
-	}
+			E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+		}
 
-	CORBA_exception_free (&ev);
+		CORBA_exception_free (&ev);
 
-	e_flag_wait (our_op->done);
+		e_flag_wait (our_op->done);
 
-	status = our_op->status;
-        if (status != E_CALENDAR_STATUS_OK){
-                icalcomp = NULL;
-        } else {
-                icalcomp = icalparser_parse_string (our_op->string);
-		if (!icalcomp)
+		status = our_op->status;
+		if (status != E_CALENDAR_STATUS_OK){
+			icalcomp = NULL;
+		} else {
+			icalcomp = icalparser_parse_string (our_op->string);
+			if (!icalcomp)
+				status = E_CALENDAR_STATUS_INVALID_OBJECT;
+		}
+		g_free (our_op->string);
+	} else {
+		/*
+		 * Use built-in time zone *and* rename it:
+		 * if the caller is asking for a TZID=FOO,
+		 * then likely because it has an event with
+		 * such a TZID. Returning a different TZID
+		 * would lead to broken VCALENDARs in the
+		 * caller.
+		 */
+		icaltimezone *syszone = icaltimezone_get_builtin_timezone_from_tzid (systzid);
+		g_assert (syszone);
+		if (syszone) {
+			gboolean found = FALSE;
+			icalproperty *prop;
+
+			icalcomp = icalcomponent_new_clone (icaltimezone_get_component (syszone));
+			prop = icalcomponent_get_first_property(icalcomp,
+								ICAL_ANY_PROPERTY);
+			while (!found && prop) {
+				if (icalproperty_isa(prop) == ICAL_TZID_PROPERTY) {
+					icalproperty_set_value_from_string(prop, tzid, "NO");
+					found = TRUE;
+				}
+				prop = icalcomponent_get_next_property(icalcomp,
+								       ICAL_ANY_PROPERTY);
+			}
+			g_assert (found);
+		} else {
 			status = E_CALENDAR_STATUS_INVALID_OBJECT;
+		}
 	}
-	g_free (our_op->string);
 
 	if (!icalcomp) {
 		e_calendar_remove_op (ecal, our_op);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]