[Xfce4-commits] <orage:master> 4.7.4.6 Fixed BUG 5090 Recurring event does not adapt to DST changes
Juha Kautto
noreply at xfce.org
Mon Sep 21 16:12:01 CEST 2009
Updating branch refs/heads/master
to a4ced8555b79a359f4b2e704ad96f9458d9ac71f (commit)
from 6ef448c9ba421280e94f82bf1efc692992288882 (commit)
commit a4ced8555b79a359f4b2e704ad96f9458d9ac71f
Author: Juha Kautto <juha at xfce.org>
Date: Mon Sep 21 17:04:58 2009 +0300
4.7.4.6 Fixed BUG 5090 Recurring event does not adapt to DST changes
- Alarms converted times too early to local timezone. Conversion needs
to happen last after all comparisons.
- Enhanced timezone selection a little by reading also the previous
time change time.
- Fixed a small error in timezone selection when reading country names:
Need to check the 2-char country code is in correct place as some of them
appear in the file also in other places.
configure.in.in | 2 +-
src/ical-archive.c | 4 +-
src/ical-code.c | 52 +++++++++++++++++++++++++++------------------
src/timezone_selection.c | 32 +++++++++++++++++++++-------
src/tz_zoneinfo_read.c | 45 +++++++++++++++++++++++++++++++--------
src/tz_zoneinfo_read.h | 1 +
6 files changed, 95 insertions(+), 41 deletions(-)
diff --git a/configure.in.in b/configure.in.in
index b75fbbb..ac28494 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -9,7 +9,7 @@ dnl Written for Xfce by Juha Kautto <juha at xfce.org>
dnl
dnl Version information
-m4_define([orage_version], [4.7.4.5-test])
+m4_define([orage_version], [4.7.4.6-test])
m4_define([gtk_minimum_version], [2.10.0])
m4_define([xfce_minimum_version], [4.6.0])
diff --git a/src/ical-archive.c b/src/ical-archive.c
index 3390247..100be99 100644
--- a/src/ical-archive.c
+++ b/src/ical-archive.c
@@ -85,7 +85,7 @@ typedef struct
char *ic_get_char_timezone(icalproperty *p);
struct icaltimetype ic_convert_to_timezone(struct icaltimetype t
, icalproperty *p);
-xfical_period ic_get_period(icalcomponent *c) ;
+xfical_period ic_get_period(icalcomponent *c, gboolean local);
gboolean ic_internal_file_open(icalcomponent **p_ical
, icalset **p_fical, gchar *file_icalpath, gboolean test);
@@ -388,7 +388,7 @@ gboolean xfical_archive(void)
edate = sdate;
}
*/
- per = ic_get_period(c);
+ per = ic_get_period(c, TRUE);
uid = (char *)icalcomponent_get_uid(c);
/* Items with endate before threshold => archived.
* Recurring events are marked in the main file by adding special
diff --git a/src/ical-code.c b/src/ical-code.c
index 5c213d1..ff30e67 100644
--- a/src/ical-code.c
+++ b/src/ical-code.c
@@ -580,7 +580,7 @@ static struct icaltimetype convert_to_local_timezone(struct icaltimetype t
return (tl);
}
-xfical_period ic_get_period(icalcomponent *c)
+xfical_period ic_get_period(icalcomponent *c, gboolean local)
{
#undef P_N
#define P_N "ic_get_period: "
@@ -596,7 +596,10 @@ xfical_period ic_get_period(icalcomponent *c)
p = icalcomponent_get_first_property(c, ICAL_DTSTART_PROPERTY);
if (p != NULL) {
per.stime = icalproperty_get_dtstart(p);
- per.stime = convert_to_local_timezone(per.stime, p);
+ if (local)
+ per.stime = convert_to_local_timezone(per.stime, p);
+ else
+ per.stime = ic_convert_to_timezone(per.stime, p);
}
else {
per.stime = icaltime_null_time();
@@ -625,7 +628,10 @@ xfical_period ic_get_period(icalcomponent *c)
per.etime = icalproperty_get_dtend(p);
else if (per.ikind == ICAL_VTODO_COMPONENT)
per.etime = icalproperty_get_due(p);
- per.etime = convert_to_local_timezone(per.etime, p);
+ if (local)
+ per.etime = convert_to_local_timezone(per.etime, p);
+ else
+ per.etime = ic_convert_to_timezone(per.etime, p);
per.duration = icaltime_subtract(per.etime, per.stime);
if (icaltime_is_date(per.stime)
&& icaldurationtype_as_int(per.duration) != 0) {
@@ -653,7 +659,10 @@ xfical_period ic_get_period(icalcomponent *c)
if (p2 != NULL) {
per.ctime = icalproperty_get_completed(p2);
- per.ctime = convert_to_local_timezone(per.ctime, p2);
+ if (local)
+ per.ctime = convert_to_local_timezone(per.ctime, p2);
+ else
+ per.ctime = ic_convert_to_timezone(per.ctime, p);
}
else
per.ctime = icaltime_null_time();
@@ -2517,6 +2526,7 @@ static void set_todo_times(icalcomponent *c, xfical_period *per)
}
}
+/* this works in UTC times */
struct icaltimetype count_alarm_time(xfical_period per
, struct icaltimetype cur_time
, struct icaldurationtype dur
@@ -2529,18 +2539,18 @@ struct icaltimetype count_alarm_time(xfical_period per
* when counting alarm time. */
if (rel == ICAL_RELATED_START) {
per.stime.is_date = 0;
- per.stime.is_utc = cur_time.is_utc;
- per.stime.is_daylight = cur_time.is_daylight;
- per.stime.zone = cur_time.zone;
+ per.stime.is_utc = 1;
+ per.stime.is_daylight = 0;
+ per.stime.zone = utc_icaltimezone;
per.stime.hour = 0;
per.stime.minute = 0;
per.stime.second = 0;
}
else {
per.etime.is_date = 0;
- per.etime.is_utc = cur_time.is_utc;
- per.etime.is_daylight = cur_time.is_daylight;
- per.etime.zone = cur_time.zone;
+ per.etime.is_utc = 1;
+ per.etime.is_daylight = 0;
+ per.etime.zone = utc_icaltimezone;
per.etime.hour = 0;
per.etime.minute = 0;
per.etime.second = 0;
@@ -2558,7 +2568,7 @@ struct icaltimetype count_alarm_time(xfical_period per
* FIXME: We assume all alarms have similar trigger, which
* may not be true for other than Orage appointments
*/
-static alarm_struct *process_alarm_trigger(icalcomponent *c
+alarm_struct *process_alarm_trigger(icalcomponent *c
, icalcomponent *ca, struct icaltimetype cur_time, int *cnt_repeat)
{ /* c == main component; ca == alarm component */
#undef P_N
@@ -2592,7 +2602,7 @@ static alarm_struct *process_alarm_trigger(icalcomponent *c
rel = icalparameter_get_related(trg_related_par);
else
rel = ICAL_RELATED_START;
- per = ic_get_period(c);
+ per = ic_get_period(c, FALSE);
next_alarm_time = count_alarm_time(per, cur_time, trg.duration, rel);
alarm_start_diff = icaltime_subtract(per.stime, next_alarm_time);
/* we only have ctime for TODOs and only if todo has been completed.
@@ -2600,7 +2610,7 @@ static alarm_struct *process_alarm_trigger(icalcomponent *c
* current date */
if (per.ikind == ICAL_VTODO_COMPONENT) {
if (icaltime_is_null_time(per.ctime)
- || local_compare(per.ctime, per.stime) < 0) {
+ || icaltime_compare(per.ctime, per.stime) < 0) {
/* VTODO is never completed */
/* or it has completed before start, so
* this one is not done and needs to be counted */
@@ -2625,9 +2635,9 @@ static alarm_struct *process_alarm_trigger(icalcomponent *c
next_start_time = icaltime_add(next_alarm_time, alarm_start_diff);
!icaltime_is_null_time(next_alarm_time)
&& ((per.ikind == ICAL_VTODO_COMPONENT
- && local_compare(next_start_time, per.ctime) <= 0)
+ && icaltime_compare(next_start_time, per.ctime) <= 0)
|| (per.ikind != ICAL_VTODO_COMPONENT
- && local_compare(next_alarm_time, cur_time) <= 0)
+ && icaltime_compare(next_alarm_time, cur_time) <= 0)
|| icalproperty_recurrence_is_excluded(c
, &per.stime, &next_start_time));
next_alarm_time = icalrecur_iterator_next(ri),
@@ -2677,6 +2687,7 @@ static alarm_struct *process_alarm_trigger(icalcomponent *c
continue;
/* it has same timezone than startdate, convert to local time */
+ /* FIXME: this should not convert, but just set the timezone */
if (icaltime_is_utc(next_start_time)) {
/* FIXME: tarkista että convert_to_local_timezone toimii oikein
* UTC:llä. se ei toimi kuten tässä */
@@ -2716,6 +2727,7 @@ static alarm_struct *process_alarm_trigger(icalcomponent *c
if (trg_active) {
new_alarm = g_new0(alarm_struct, 1);
+ next_alarm_time = icaltime_convert_to_zone(next_alarm_time, local_icaltimezone);
new_alarm->alarm_time = g_strdup(icaltime_as_ical_string(next_alarm_time));
return(new_alarm);
}
@@ -2873,7 +2885,8 @@ static void xfical_alarm_build_list_internal_real(gboolean first_list_today
#ifdef ORAGE_DEBUG
orage_message(-200, P_N);
#endif
- cur_time = ical_get_current_local_time();
+ /* cur_time = ical_get_current_local_time(); */
+ cur_time = icaltime_current_time_with_zone(utc_icaltimezone);
for (c = icalcomponent_get_first_component(base, ICAL_ANY_COMPONENT);
c != 0;
@@ -2914,9 +2927,6 @@ static void xfical_alarm_build_list_internal_real(gboolean first_list_today
(char *)icalcomponent_get_description(c));
g_par.alarm_list = g_list_prepend(g_par.alarm_list, new_alarm);
cnt_alarm_add++;
- /*
- g_print(P_N "added alarm (%s) at (%s)\n", new_alarm->title, new_alarm->alarm_time);
- */
}
} /* COMPONENT */
if (first_list_today) {
@@ -3027,7 +3037,7 @@ static xfical_appt *xfical_appt_get_next_on_day_internal(char *a_day
icalcompiter_next(&ci)) {
/* next appointment loop. check if it is ok */
c = icalcompiter_deref(&ci);
- per = ic_get_period(c);
+ per = ic_get_period(c, TRUE);
if (type == XFICAL_TYPE_TODO) {
if (icaltime_is_null_time(per.ctime)
|| local_compare(per.ctime, per.stime) <= 0)
@@ -3323,7 +3333,7 @@ static void xfical_mark_calendar_from_component(GtkCalendar *gtkcal
*/
} /* ICAL_VEVENT_COMPONENT */
else if (kind == ICAL_VTODO_COMPONENT) {
- per = ic_get_period(c);
+ per = ic_get_period(c, TRUE);
marked = FALSE;
if (icaltime_is_null_time(per.ctime)
|| (local_compare(per.ctime, per.stime) < 0)) {
diff --git a/src/timezone_selection.c b/src/timezone_selection.c
index baeae91..e5eafa7 100644
--- a/src/timezone_selection.c
+++ b/src/timezone_selection.c
@@ -67,6 +67,7 @@ enum {
LOCATION_ENG,
OFFSET,
COUNTRY,
+ PREV_CHANGE,
NEXT_CHANGE,
N_COLUMNS
};
@@ -81,12 +82,12 @@ static GtkTreeStore *tz_button_create_store(gboolean details)
GtkTreeIter iter1, iter2, main;
orage_timezone_array tz_a;
char area_old[MAX_AREA_LENGTH+2]; /*+2 = / + null */
- char s_offset[100], s_country[100], s_next[100];
+ char s_offset[100], s_country[100], s_next[100], s_prev[100];
gint i, j, offs_hour, offs_min;
store = gtk_tree_store_new(N_COLUMNS
, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING
- , G_TYPE_STRING, G_TYPE_STRING);
+ , G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
strcpy(area_old, "S T a R T"); /* this never matches */
tz_a = get_orage_timezones(details, 1);
/*
@@ -100,6 +101,7 @@ static GtkTreeStore *tz_button_create_store(gboolean details)
, LOCATION_ENG, " Other"
, OFFSET, " "
, COUNTRY, " "
+ , PREV_CHANGE, " "
, NEXT_CHANGE, " "
, -1);
main = iter1; /* need to remember that */
@@ -124,6 +126,7 @@ static GtkTreeStore *tz_button_create_store(gboolean details)
, LOCATION_ENG, area_old
, OFFSET, " "
, COUNTRY, " "
+ , PREV_CHANGE, " "
, NEXT_CHANGE, " "
, -1);
/* let's make sure we do not match accidentally to those
@@ -147,21 +150,29 @@ static GtkTreeStore *tz_button_create_store(gboolean details)
, offs_hour, offs_min
, (tz_a.dst[i]) ? "dst" : "std"
, (tz_a.tz[i]) ? tz_a.tz[i] : "-");
- if (details && tz_a.country[i] && tz_a.cc[i])
- g_snprintf(s_country, 100, "%s (%s)", tz_a.country[i], tz_a.cc[i]);
- else
- strcpy(s_country, " ");
- if (details)
+ if (details) {
+ if (tz_a.country[i] && tz_a.cc[i])
+ g_snprintf(s_country, 100, "%s (%s)"
+ , tz_a.country[i], tz_a.cc[i]);
+ else
+ strcpy(s_country, " ");
+ g_snprintf(s_prev, 100, "%s"
+ , (tz_a.prev[i]) ? tz_a.prev[i] : _("not changed"));
g_snprintf(s_next, 100, "%s"
, (tz_a.next[i]) ? tz_a.next[i] : _("not changing"));
- else
+ }
+ else {
+ strcpy(s_country, " ");
+ strcpy(s_prev, " ");
strcpy(s_next, " ");
+ }
gtk_tree_store_set(store, &iter2
, LOCATION, _(tz_a.city[i])
, LOCATION_ENG, tz_a.city[i]
, OFFSET, s_offset
, COUNTRY, s_country
+ , PREV_CHANGE, s_prev
, NEXT_CHANGE, s_next
, -1);
}
@@ -224,6 +235,11 @@ GtkWidget *tz_button_create_view(gboolean details, GtkTreeStore *store)
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col);
rend = gtk_cell_renderer_text_new();
+ col = gtk_tree_view_column_new_with_attributes(_("Previous Change")
+ , rend, "text", PREV_CHANGE, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col);
+
+ rend = gtk_cell_renderer_text_new();
col = gtk_tree_view_column_new_with_attributes(_("Next Change")
, rend, "text", NEXT_CHANGE, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col);
diff --git a/src/tz_zoneinfo_read.c b/src/tz_zoneinfo_read.c
index a97a8eb..8a48d02 100644
--- a/src/tz_zoneinfo_read.c
+++ b/src/tz_zoneinfo_read.c
@@ -333,7 +333,7 @@ static int process_file(const char *file_name)
static void get_country()
{ /* tz_array.city[tz_array.count] contains the city name.
We will find corresponding country and fill it to the table */
- char *str, *str_nl;
+ char *str, *str_nl, cc[4];
if (!(str = strstr(zone_tab_buf, tz_array.city[tz_array.count])))
return; /* not found */
@@ -350,12 +350,19 @@ static void get_country()
strncpy(tz_array.cc[tz_array.count], ++str_nl, 2);
tz_array.cc[tz_array.count][2] = '\0';
- /* then search the country */
- if (!(str = strstr(country_buf, tz_array.cc[tz_array.count])))
+ /********** then search the country **********/
+ /* Need to search line, which starts with country code.
+ * Note that it is not enough to search any country coed, but it really
+ * needs to be the first two chars in the line */
+ cc[0] = '\n';
+ cc[1] = tz_array.cc[tz_array.count][0];
+ cc[2] = tz_array.cc[tz_array.count][1];
+ cc[3] = '\0';
+ if (!(str = strstr(country_buf, cc)))
return; /* not found */
/* country name is after the country code and a single tab */
str += 3;
- /* but w still need to find how long it is.
+ /* but we still need to find how long it is.
* It ends in the line end.
* (There is a line end at the end of the file also.) */
for (str_nl = str; str_nl[0] != '\n'; str_nl++)
@@ -385,8 +392,8 @@ static int write_ical_file(const char *in_file_name
unsigned int tct_i, abbr_i;
struct tm cur_gm_time;
time_t tt_now = time(NULL);
- long tc_time = 0; /* TimeChange time */
- char s_next[101];
+ long tc_time = 0, prev_tc_time; /* TimeChange times */
+ char s_next[101], s_prev[101];
if (debug > 1)
printf("***** write_ical_file: start *****\n\n");
@@ -403,6 +410,7 @@ static int write_ical_file(const char *in_file_name
/* search for current time setting.
* timecnt tells how many changes we have in the tz file.
* i points to the next value to read. */
+ prev_tc_time = tc_time;
tc_time = get_long(); /* start time of this timechange */
}
/* i points to the next value to be read, so need to -- */
@@ -412,6 +420,7 @@ static int write_ical_file(const char *in_file_name
tz_array.utc_offset[tz_array.count] = 0;
tz_array.dst[tz_array.count] = 0;
tz_array.tz[tz_array.count] = "UTC";
+ tz_array.prev[tz_array.count] = NULL;
tz_array.next[tz_array.count] = NULL;
tz_array.count++;
return(1); /* done */
@@ -420,16 +429,29 @@ static int write_ical_file(const char *in_file_name
/* we found previous and next value */
/* tc_time has the next change time */
if (details) {
+ localtime_r((const time_t *)&prev_tc_time, &cur_gm_time);
+ strftime(s_prev, 100, "%c", &cur_gm_time);
+ tz_array.prev[tz_array.count] = strdup(s_prev);
localtime_r((const time_t *)&tc_time, &cur_gm_time);
strftime(s_next, 100, "%c", &cur_gm_time);
tz_array.next[tz_array.count] = strdup(s_next);
}
- else
+ else {
tz_array.next[tz_array.count] = NULL;
+ tz_array.prev[tz_array.count] = NULL;
+ }
i--; /* we need to take the previous value */
}
- else
+ else { /* no next value, but previous may exist */
tz_array.next[tz_array.count] = NULL;
+ if (details && prev_tc_time) {
+ localtime_r((const time_t *)&prev_tc_time, &cur_gm_time);
+ strftime(s_prev, 100, "%c", &cur_gm_time);
+ tz_array.prev[tz_array.count] = strdup(s_prev);
+ }
+ else
+ tz_array.prev[tz_array.count] = NULL;
+ }
/* i now points to latest time change and shows current time.
* So we found our result and can start collecting real data: */
@@ -476,7 +498,6 @@ static int file_call(const char *file_name, const struct stat *sb, int flags
+ strlen("zoneinfo/")]);
timezone_name = strdup(in_timezone_name);
if (check_ical && !timezone_exists_in_ical()) {
- printf("\t\tfile_call: skipped file=(%s)\n", file_name);
free(in_timezone_name);
free(timezone_name);
return(FTW_CONTINUE);
@@ -807,6 +828,7 @@ orage_timezone_array get_orage_timezones(int show_details, int ical)
tz_array.utc_offset = (int *)malloc(sizeof(int)*(tz_array_size+2));
tz_array.dst = (int *)malloc(sizeof(int)*(tz_array_size+2));
tz_array.tz = (char **)malloc(sizeof(char *)*(tz_array_size+2));
+ tz_array.prev = (char **)malloc(sizeof(char *)*(tz_array_size+2));
tz_array.next = (char **)malloc(sizeof(char *)*(tz_array_size+2));
tz_array.country = (char **)malloc(sizeof(char *)*(tz_array_size+2));
tz_array.cc = (char **)malloc(sizeof(char *)*(tz_array_size+2));
@@ -832,6 +854,7 @@ orage_timezone_array get_orage_timezones(int show_details, int ical)
tz_array.utc_offset[tz_array.count] = 0;
tz_array.dst[tz_array.count] = 0;
tz_array.tz[tz_array.count] = strdup("UTC");
+ tz_array.prev[tz_array.count] = NULL;
tz_array.next[tz_array.count] = NULL;
tz_array.country[tz_array.count] = NULL;
tz_array.cc[tz_array.count] = NULL;
@@ -840,6 +863,7 @@ orage_timezone_array get_orage_timezones(int show_details, int ical)
tz_array.utc_offset[tz_array.count] = 0;
tz_array.dst[tz_array.count] = 0;
tz_array.tz[tz_array.count] = NULL;
+ tz_array.prev[tz_array.count] = NULL;
tz_array.next[tz_array.count] = NULL;
tz_array.country[tz_array.count] = NULL;
tz_array.cc[tz_array.count] = NULL;
@@ -857,6 +881,8 @@ void free_orage_timezones(int show_details)
free(tz_array.city[i]);
if (tz_array.tz[i])
free(tz_array.tz[i]);
+ if (tz_array.prev[i])
+ free(tz_array.prev[i]);
if (tz_array.next[i])
free(tz_array.next[i]);
if (tz_array.country[i])
@@ -868,6 +894,7 @@ void free_orage_timezones(int show_details)
free(tz_array.utc_offset);
free(tz_array.dst);
free(tz_array.tz);
+ free(tz_array.prev);
free(tz_array.next);
free(tz_array.country);
free(tz_array.cc);
diff --git a/src/tz_zoneinfo_read.h b/src/tz_zoneinfo_read.h
index 8e05e1b..1f70f73 100644
--- a/src/tz_zoneinfo_read.h
+++ b/src/tz_zoneinfo_read.h
@@ -25,6 +25,7 @@ typedef struct _orage_timezone_array
int *utc_offset; /* pointer to int array holding utc offsets */
int *dst; /* pointer to int array holding dst settings */
char **tz; /* pointer to timezone name strings */
+ char **prev; /* pointer to previous time change strings */
char **next; /* pointer to next time change strings */
char **country; /* pointer to country name strings */
char **cc; /* pointer to country code strings */
More information about the Xfce4-commits
mailing list