[Xfce4-commits] r25864 - xfcalendar/trunk/src
Juha Kautto
juha at xfce.org
Wed Jun 27 22:57:51 CEST 2007
Author: juha
Date: 2007-06-27 20:57:50 +0000 (Wed, 27 Jun 2007)
New Revision: 25864
Modified:
xfcalendar/trunk/src/ical-code.c
Log:
several bug fixes in archiving.
Modified: xfcalendar/trunk/src/ical-code.c
===================================================================
--- xfcalendar/trunk/src/ical-code.c 2007-06-26 21:10:27 UTC (rev 25863)
+++ xfcalendar/trunk/src/ical-code.c 2007-06-27 20:57:50 UTC (rev 25864)
@@ -75,6 +75,7 @@
struct icaltimetype etime; /* end time */
struct icaldurationtype duration;
struct icaltimetype ctime; /* completed time for VTODO appointmnets */
+ icalcomponent_kind ikind; /* type of component, VEVENt, VTODO... */
} xfical_period;
typedef struct
@@ -852,7 +853,6 @@
#define P_N "get_period: "
icalproperty *p = NULL, *p2 = NULL;
xfical_period per;
- icalcomponent_kind ikind = ICAL_VEVENT_COMPONENT;
struct icaldurationtype duration_tmp;
gint dur_int;
@@ -874,23 +874,23 @@
* But neither is required.
* VTODO may also have completed time
*/
- ikind = icalcomponent_isa(c);
- if (ikind == ICAL_VEVENT_COMPONENT)
+ per.ikind = icalcomponent_isa(c);
+ if (per.ikind == ICAL_VEVENT_COMPONENT)
p = icalcomponent_get_first_property(c, ICAL_DTEND_PROPERTY);
- else if (ikind == ICAL_VTODO_COMPONENT) {
+ else if (per.ikind == ICAL_VTODO_COMPONENT) {
p = icalcomponent_get_first_property(c, ICAL_DUE_PROPERTY);
p2 = icalcomponent_get_first_property(c, ICAL_COMPLETED_PROPERTY);
}
- else if (ikind == ICAL_VJOURNAL_COMPONENT)
+ else if (per.ikind == ICAL_VJOURNAL_COMPONENT)
p = NULL; /* does not exist for journal */
else {
g_warning(P_N "unknown component type (%s)", icalcomponent_get_uid(c));
p = NULL;
}
if (p != NULL) {
- if (ikind == ICAL_VEVENT_COMPONENT)
+ if (per.ikind == ICAL_VEVENT_COMPONENT)
per.etime = icalproperty_get_dtend(p);
- else if (ikind == ICAL_VTODO_COMPONENT)
+ else if (per.ikind == ICAL_VTODO_COMPONENT)
per.etime = icalproperty_get_due(p);
per.etime = convert_to_local_timezone(per.etime, p);
per.duration = icaltime_subtract(per.etime, per.stime);
@@ -3081,6 +3081,33 @@
return(0);
}
+static icalproperty *replace_repeating(icalcomponent *c, icalproperty *p
+ , icalproperty_kind k)
+{
+#undef P_N
+#define P_N "replace_repeating: "
+ icalproperty *s, *n;
+ const char *text;
+ const gint x_len = strlen("X-ORAGE-ORIG-");
+
+#ifdef ORAGE_DEBUG
+ g_print(P_N "\n");
+#endif
+ text = g_strdup(icalproperty_as_ical_string(p));
+ n = icalproperty_new_from_string(text + x_len);
+ g_free((gchar *)text);
+ s = icalcomponent_get_first_property(c, k);
+ /* remove X-ORAGE-ORIG...*/
+ icalcomponent_remove_property(c, p);
+ /* remove old k (=either DTSTART or DTEND) */
+ icalcomponent_remove_property(c, s);
+ /* add new DTSTART or DTEND */
+ icalcomponent_add_property(c, n);
+ /* we need to start again from the first since we messed the order,
+ * but there are not so many X- propoerties that this is worth worring */
+ return(icalcomponent_get_first_property(c, ICAL_X_PROPERTY));
+}
+
/* Read next EVENT/TODO/JOURNAL component on the specified date from
* ical datafile.
* a_day: start date of ical component which is to be read
@@ -3252,47 +3279,25 @@
const char *text;
char *text2;
icalproperty *p, *pdtstart, *pdtend;
- gboolean upd_edate = FALSE;
+ icalproperty *p_orig, *p_origdtstart, *p_origdtend;
+ gboolean upd_edate = FALSE;
+ gboolean has_orig_dtstart = FALSE, has_orig_dtend = FALSE;
#ifdef ORAGE_DEBUG
g_print(P_N "\n");
#endif
- /* *** PHASE 1 *** : Add to the archive file */
- /* We must first check that this event has not yet been archived.
- * It is recurrent, so we may have added it earlier already.
- * If it has been added, we do not have to do anything since the
- * one in the archive file must be older than our current event.
- */
- /*
- for (a = icalcomponent_get_first_component(aical, ICAL_VEVENT_COMPONENT);
- a != 0 && !key_found;
- a = icalcomponent_get_next_component(aical, ICAL_VEVENT_COMPONENT)) {
- text = icalcomponent_get_uid(a);
- if (strcmp(text, uid) == 0)
- key_found = TRUE;
- }
- if (!key_found) {
- d = icalcomponent_new_clone(e);
- icalcomponent_add_component(aical, d);
- }
- */
- /* *** PHASE 2 *** : Update startdate and enddate in the main file */
/* We must not remove recurrent events, but just modify start- and
* enddates and actually only the date parts since time will stay.
- * Note that we may need to remove limited recurrency events.
+ * Note that we may need to remove limited recurrency events. We only
+ * add X-ORAGE-ORIG... dates if those are not there already.
*/
sdate = icalcomponent_get_dtstart(e);
pdtstart = icalcomponent_get_first_property(e, ICAL_DTSTART_PROPERTY);
itime_tz = icalproperty_get_first_parameter(pdtstart, ICAL_TZID_PARAMETER);
- if (itime_tz) {
- stz_loc = (char *) icalparameter_get_tzid(itime_tz);
- l_icaltimezone = icaltimezone_get_builtin_timezone(stz_loc);
- if (!l_icaltimezone) {
- g_warning(P_N "builtin timezone %s not found, conversion failed.", stz_loc);
- }
- sdate = icaltime_convert_to_zone(sdate, l_icaltimezone);
- }
+ if (itime_tz)
+ stz_loc = (char *)icalparameter_get_tzid(itime_tz);
+ sdate = convert_to_timezone(sdate, pdtstart);
edate = icalcomponent_get_dtend(e);
if (icaltime_is_null_time(edate)) {
@@ -3302,14 +3307,10 @@
if (pdtend) { /* we have DTEND, so we need to adjust it. */
itime_tz = icalproperty_get_first_parameter(pdtend
, ICAL_TZID_PARAMETER);
- if (itime_tz) {
- etz_loc = (char *) icalparameter_get_tzid(itime_tz);
- l_icaltimezone = icaltimezone_get_builtin_timezone(etz_loc);
- if (!l_icaltimezone) {
- g_warning(P_N "builtin timezone %s not found, conversion failed.", etz_loc);
- }
- edate = icaltime_convert_to_zone(edate, l_icaltimezone);
- }
+ if (itime_tz)
+ etz_loc = (char *)icalparameter_get_tzid(itime_tz);
+
+ edate = convert_to_timezone(edate, pdtend);
duration = icaltime_subtract(edate, sdate);
upd_edate = TRUE;
}
@@ -3320,6 +3321,46 @@
else /* neither duration, nor dtend, assume dtend=dtstart */
duration = icaltime_subtract(edate, sdate);
}
+ p_orig = icalcomponent_get_first_property(e, ICAL_X_PROPERTY);
+ while (p_orig) {
+ text = icalproperty_get_x_name(p_orig);
+ if (g_str_has_prefix(text, "X-ORAGE-ORIG-DTSTART")) {
+ if (has_orig_dtstart) {
+ /* This fixes bug which existed prior to 4.5.9.7:
+ * It was possible that multiple entries were generated.
+ * They are in order: oldest first.
+ * And we only need the oldest, so delete the rest */
+ g_warning(P_N "Corrupted X-ORAGE-ORIG-DTSTART setting. Fixing");
+ icalcomponent_remove_property(e, p_orig);
+ /* we need to start from scratch since counting may go wrong
+ * bcause delete moves the pointer. */
+ has_orig_dtstart = FALSE;
+ has_orig_dtend = FALSE;
+ p_orig = icalcomponent_get_first_property(e, ICAL_X_PROPERTY);
+ }
+ else {
+ has_orig_dtstart = TRUE;
+ p_origdtstart = p_orig;
+ p_orig = icalcomponent_get_next_property(e, ICAL_X_PROPERTY);
+ }
+ }
+ else if (g_str_has_prefix(text, "X-ORAGE-ORIG-DTEND")) {
+ if (has_orig_dtend) {
+ g_warning(P_N "Corrupted X-ORAGE-ORIG-DTEND setting. Fixing");
+ icalcomponent_remove_property(e, p_orig);
+ has_orig_dtstart = FALSE;
+ has_orig_dtend = FALSE;
+ p_orig = icalcomponent_get_first_property(e, ICAL_X_PROPERTY);
+ }
+ else {
+ has_orig_dtend = TRUE;
+ p_origdtend = p_orig;
+ p_orig = icalcomponent_get_next_property(e, ICAL_X_PROPERTY);
+ }
+ }
+ else /* it was not our X-PROPERTY */
+ p_orig = icalcomponent_get_next_property(e, ICAL_X_PROPERTY);
+ }
p = icalcomponent_get_first_property(e, ICAL_RRULE_PROPERTY);
nsdate = icaltime_null_time();
@@ -3337,15 +3378,23 @@
}
icalrecur_iterator_free(ri);
- if (icaltime_is_null_time(nsdate)) /* remove since it has ended */
+ if (icaltime_is_null_time(nsdate)) { /* remove since it has ended */
+ orage_message(_("\tRecur ended, moving to archive file."));
+ if (has_orig_dtstart)
+ replace_repeating(e, p_origdtstart, ICAL_DTSTART_PROPERTY);
+ if (has_orig_dtend)
+ replace_repeating(e, p_origdtend, ICAL_DTEND_PROPERTY);
xfical_icalcomponent_archive_normal(e);
+ }
else { /* modify times*/
- text = g_strdup(icalproperty_as_ical_string(pdtstart));
- text2 = g_strjoin(NULL, "X-ORAGE-ORIG-", text, NULL);
- p = icalproperty_new_from_string(text2);
- g_free((gchar *)text2);
- g_free((gchar *)text);
- icalcomponent_add_property(e, p);
+ if (!has_orig_dtstart) {
+ text = g_strdup(icalproperty_as_ical_string(pdtstart));
+ text2 = g_strjoin(NULL, "X-ORAGE-ORIG-", text, NULL);
+ p = icalproperty_new_from_string(text2);
+ g_free((gchar *)text2);
+ g_free((gchar *)text);
+ icalcomponent_add_property(e, p);
+ }
icalcomponent_remove_property(e, pdtstart);
if (stz_loc == NULL)
icalcomponent_add_property(e, icalproperty_new_dtstart(nsdate));
@@ -3355,12 +3404,14 @@
, icalparameter_new_tzid(stz_loc)
, 0));
if (upd_edate) {
- text = g_strdup(icalproperty_as_ical_string(pdtend));
- text2 = g_strjoin(NULL, "X-ORAGE-ORIG-", text, NULL);
- p = icalproperty_new_from_string(text2);
- g_free((gchar *)text2);
- g_free((gchar *)text);
- icalcomponent_add_property(e, p);
+ if (!has_orig_dtend) {
+ text = g_strdup(icalproperty_as_ical_string(pdtend));
+ text2 = g_strjoin(NULL, "X-ORAGE-ORIG-", text, NULL);
+ p = icalproperty_new_from_string(text2);
+ g_free((gchar *)text2);
+ g_free((gchar *)text);
+ icalcomponent_add_property(e, p);
+ }
icalcomponent_remove_property(e, pdtend);
if (etz_loc == NULL)
icalcomponent_add_property(e, icalproperty_new_dtend(nedate));
@@ -3377,8 +3428,11 @@
{
#undef P_N
#define P_N "xfical_archive: "
+ /*
struct icaltimetype sdate, edate;
- static icalcomponent *c, *c2;
+ */
+ xfical_period per;
+ icalcomponent *c, *c2;
icalproperty *p;
struct tm *threshold;
char *uid;
@@ -3397,14 +3451,13 @@
threshold = orage_localtime();
threshold->tm_mday = 1;
threshold->tm_year += 1900;
- if (threshold->tm_mon > g_par.archive_limit) {
- threshold->tm_mon -= g_par.archive_limit;
- }
- else {
- threshold->tm_mon += (12 - g_par.archive_limit);
+ threshold->tm_mon += 1; /* convert from 0...11 to 1...12 */
+
+ threshold->tm_mon -= g_par.archive_limit;
+ if (threshold->tm_mon <= 0) {
+ threshold->tm_mon += 12;
threshold->tm_year--;
}
- threshold->tm_mon += 1;
orage_message(_("Archiving threshold: %d month(s)")
, g_par.archive_limit);
@@ -3414,35 +3467,46 @@
/* Check appointment file for items older than the threshold */
/* Note: remove moves the "c" pointer to next item, so we need to store it
- * first to process all of them or we end up skipping entries */
+ * first to process all of them or we end up skipping entries */
for (c = icalcomponent_get_first_component(ical, ICAL_ANY_COMPONENT);
c != 0;
c = c2) {
c2 = icalcomponent_get_next_component(ical, ICAL_ANY_COMPONENT);
+ /*
sdate = icalcomponent_get_dtstart(c);
edate = icalcomponent_get_dtend(c);
- uid = (char *)icalcomponent_get_uid(c);
if (icaltime_is_null_time(edate)) {
edate = sdate;
}
+ */
+ per = get_period(c);
+ uid = (char *)icalcomponent_get_uid(c);
/* Items with endate before threshold => archived.
* Recurring events are marked in the main file by adding special
* X-ORAGE_ORIG-DTSTART/X-ORAGE_ORIG-DTEND to save the original
* start/end dates. Then start_date is changed. These are NOT
- * written in archive file (unless of course they really have
- * ended).
+ * written in archive file (unless of course they really have ended).
*/
- if ((edate.year*12 + edate.month)
+ if ((per.etime.year*12 + per.etime.month)
< (threshold->tm_year*12 + threshold->tm_mon)) {
- p = icalcomponent_get_first_property(c, ICAL_RRULE_PROPERTY);
- orage_message(_("Archiving uid: %s (%s)")
- , uid, (p) ? _("recur") : _("normal"));
- orage_message(_("\tEnd year: %04d, month: %02d, day: %02d")
- , edate.year, edate.month, edate.day);
- if (p) /* it is recurrent event */
- xfical_icalcomponent_archive_recurrent(c, threshold, uid);
- else
- xfical_icalcomponent_archive_normal(c);
+ orage_message(_("Archiving uid: %s"), uid);
+ /* FIXME: check VTODO completed before archiving it */
+ if (per.ikind == ICAL_VTODO_COMPONENT
+ && ((per.ctime.year*12 + per.ctime.month)
+ < (per.stime.year*12 + per.stime.month))) {
+ /* VTODO not com,pleted, do not archive */
+ orage_message(_("\tVTODO not complete; not archived"));
+ }
+ else {
+ p = icalcomponent_get_first_property(c, ICAL_RRULE_PROPERTY);
+ if (p) { /* it is recurrent event */
+ orage_message(_("\tRecurring. End year: %04d, month: %02d, day: %02d")
+ , per.etime.year, per.etime.month, per.etime.day);
+ xfical_icalcomponent_archive_recurrent(c, threshold, uid);
+ }
+ else
+ xfical_icalcomponent_archive_normal(c);
+ }
}
}
@@ -3456,33 +3520,6 @@
return(TRUE);
}
-icalproperty *replace_repeating(icalcomponent *c, icalproperty *p
- , icalproperty_kind k)
-{
-#undef P_N
-#define P_N "replace_repeating: "
- icalproperty *s, *n;
- const char *text;
- const gint x_len = strlen("X-ORAGE-ORIG-");
-
-#ifdef ORAGE_DEBUG
- g_print(P_N "\n");
-#endif
- text = g_strdup(icalproperty_as_ical_string(p));
- n = icalproperty_new_from_string(text + x_len);
- g_free((gchar *)text);
- s = icalcomponent_get_first_property(c, k);
- /* remove X-ORAGE-ORIG...*/
- icalcomponent_remove_property(c, p);
- /* remove old k (=either DTSTART or DTEND) */
- icalcomponent_remove_property(c, s);
- /* add new DTSTART or DTEND */
- icalcomponent_add_property(c, n);
- /* we need to start again from the first since we messed the order,
- * but there are not so many X- propoerties that this is worth worring */
- return(icalcomponent_get_first_property(c, ICAL_X_PROPERTY));
-}
-
gboolean xfical_unarchive(void)
{
#undef P_N
@@ -3495,7 +3532,8 @@
g_print(P_N "\n");
#endif
/* PHASE 1: go through base orage file and remove "repeat" shortcuts */
- orage_message(_("Starting archive removal: PHASE 1: reset recurring appointments"));
+ orage_message(_("Starting archive removal."));
+ orage_message(_("\tPHASE 1: reset recurring appointments"));
if (!xfical_file_open(FALSE)) {
g_warning(P_N "file open error");
return(FALSE);
@@ -3517,6 +3555,7 @@
}
/* PHASE 2: go through archive file and add everything back to base orage.
* After that delete the whole arch file */
+ orage_message(_("\tPHASE 2: return archived appointments"));
if (!xfical_archive_open()) {
g_warning(P_N "archive file open error");
icalset_mark(fical);
@@ -3533,8 +3572,7 @@
}
xfical_archive_close();
if (g_remove(g_par.archive_file) == -1) {
- g_warning(P_N "Failed to remove archive file %s"
- , g_par.archive_file);
+ g_warning(P_N "Failed to remove archive file %s", g_par.archive_file);
}
icalset_mark(fical);
icalset_commit(fical);
More information about the Xfce4-commits
mailing list