Updating branch refs/heads/master to a4ced8555b79a359f4b2e704ad96f9458d9ac71f (commit) from 6ef448c9ba421280e94f82bf1efc692992288882 (commit)
commit a4ced8555b79a359f4b2e704ad96f9458d9ac71f Author: Juha Kautto <j...@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 <j...@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 */
_______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org http://foo-projects.org/mailman/listinfo/xfce4-commits