From c3876df777704e70f1d91689b4b29a69f8bf3e66 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Wed, 24 Oct 2001 17:27:22 +0000 Subject: Fixes bug #5282. 2001-10-24 Federico Mena Quintero Fixes bug #5282. * cal-util/timeutil.c (icaltimetype_to_tm_with_zone): New function to avoid copying the same code all over the place. (icaltimetype_to_tm): Also set the tm.tm_wday. * gui/alarm-notify/alarm-queue.c (queue_midnight_refresh): Use time_day_end_with_zone(). (load_alarms_for_today): Likewise. And oops, we were only computing the times and not loading the alarms. (obj_updated_cb): Likewise. (load_alarms): Removed assertion that is no longer valid because we may load the alarms for a client in two stages. * gui/dialogs/alarm-page.c (get_alarm_string): Convert absolute trigger times to the local timezone. * gui/alarm-notify/alarm-notify-dialog.c (write_html_heading): Convert the times to the local timezone. (alarm_notify_dialog): Likewise, for the window title. (alarm_notify_dialog): Set the window layer to WIN_LAYER_ONTOP. * gui/e-cell-date-edit-text.c (ecd_get_text): Use icaltimetype_to_tm_with_zone(). * gui/alarm-notify/save.c (get_config_db): Made public. (discard_config_db): Made public. * gui/alarm-notify/config-data.[ch]: New files with functions to fetch the calendar configuration data used by the alarm daemon. svn path=/trunk/; revision=13986 --- calendar/gui/alarm-notify/Makefile.am | 2 + calendar/gui/alarm-notify/alarm-notify-dialog.c | 110 ++++++++++++++--------- calendar/gui/alarm-notify/alarm-queue.c | 24 +++-- calendar/gui/alarm-notify/alarm.c | 4 +- calendar/gui/alarm-notify/config-data.c | 111 ++++++++++++++++++++++++ calendar/gui/alarm-notify/config-data.h | 32 +++++++ calendar/gui/alarm-notify/save.c | 5 +- calendar/gui/alarm-notify/save.h | 4 + calendar/gui/dialogs/alarm-page.c | 30 ++++--- calendar/gui/e-cell-date-edit-text.c | 13 +-- calendar/gui/gnome-cal.c | 4 +- 11 files changed, 261 insertions(+), 78 deletions(-) create mode 100644 calendar/gui/alarm-notify/config-data.c create mode 100644 calendar/gui/alarm-notify/config-data.h (limited to 'calendar/gui') diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am index 26965fffea..5e4fb8d5ee 100644 --- a/calendar/gui/alarm-notify/Makefile.am +++ b/calendar/gui/alarm-notify/Makefile.am @@ -53,6 +53,8 @@ evolution_alarm_notify_SOURCES = \ alarm-notify-dialog.h \ alarm-queue.c \ alarm-queue.h \ + config-data.c \ + config-data.h \ notify-main.c \ save.c \ save.h diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.c b/calendar/gui/alarm-notify/alarm-notify-dialog.c index c6644264c6..c17bd52fa7 100644 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.c +++ b/calendar/gui/alarm-notify/alarm-notify-dialog.c @@ -38,7 +38,9 @@ #include #include #include +#include "cal-util/timeutil.h" #include "alarm-notify-dialog.h" +#include "config-data.h" GtkWidget *make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow); @@ -136,7 +138,7 @@ static void url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) { - if (!strncmp ("file:///", url, strlen ("file:///"))) { + if (!strncmp ("file:///", url, strlen ("file:///"))) { FILE *fp; const char *filename = url + strlen ("file://"); char buf[4096]; @@ -149,16 +151,16 @@ url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointe gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); return; } - + while ((len = fread (buf, 1, sizeof(buf), fp)) > 0) gtk_html_stream_write (stream, buf, len); - + if (feof (fp)) { fclose (fp); gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); return; - } - + } + fclose (fp); } @@ -174,7 +176,7 @@ make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shado gtk_widget_push_visual(gdk_rgb_get_visual()); gtk_widget_push_colormap(gdk_rgb_get_cmap()); - + html = gtk_html_new(); gtk_html_set_default_content_type (GTK_HTML (html), @@ -185,27 +187,27 @@ make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shado GTK_SIGNAL_FUNC (url_requested_cb), NULL); - gtk_widget_pop_colormap(); + gtk_widget_pop_colormap(); gtk_widget_pop_visual(); frame = e_scroll_frame_new(NULL, NULL); - + e_scroll_frame_set_policy(E_SCROLL_FRAME(frame), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - + + e_scroll_frame_set_shadow_type (E_SCROLL_FRAME (frame), GTK_SHADOW_IN); gtk_widget_set_usize (frame, 300, 200); gtk_container_add(GTK_CONTAINER (frame), html); - + gtk_widget_show_all(frame); - + gtk_object_set_user_data(GTK_OBJECT (frame), html); - return frame; + return frame; } static void @@ -218,34 +220,51 @@ write_times (GtkHTMLStream *stream, char *start, char *end) } +/* Converts a time_t to a string, relative to the specified timezone */ +static char * +timet_to_str_with_zone (time_t t, icaltimezone *zone) +{ + struct icaltimetype itt; + struct tm tm; + char buf[256]; + + if (t == -1) + return g_strdup (_("invalid time")); + + itt = icaltime_from_timet_with_zone (t, FALSE, zone); + tm = icaltimetype_to_tm (&itt); + + e_time_format_date_and_time (&tm, config_data_get_24_hour_format (), + FALSE, FALSE, buf, sizeof (buf)); + return g_strdup (buf); +} + /* Creates a heading for the alarm notification dialog */ static void -write_html_heading (GtkHTMLStream *stream, const char *message, CalComponentVType vtype, time_t occur_start, time_t occur_end) +write_html_heading (GtkHTMLStream *stream, const char *message, + CalComponentVType vtype, time_t occur_start, time_t occur_end) { char *buf; - char s[128], e[128]; - char *start = NULL, *end = NULL; + char *start, *end; char *bg_path = "file://" EVOLUTION_ICONSDIR "/bcg.png"; char *image_path = "file://" EVOLUTION_ICONSDIR "/alarm.png"; + icaltimezone *current_zone; - if (occur_start != -1) { - struct tm tm; + /* Stringize the times */ - tm = *localtime (&occur_start); - strftime (s, sizeof (s), "%A %b %d %Y %H:%M", &tm); - start = e_utf8_from_locale_string (s); - } + current_zone = config_data_get_timezone (); - if (occur_end != -1) { - struct tm tm; + buf = timet_to_str_with_zone (occur_start, current_zone); + start = e_utf8_from_locale_string (buf); + g_free (buf); - tm = *localtime (&occur_end); - strftime (e, sizeof (e), "%A %b %d %Y %H:%M", &tm); - end = e_utf8_from_locale_string (e); - } + buf = timet_to_str_with_zone (occur_end, current_zone); + end = e_utf8_from_locale_string (buf); + g_free (buf); + + /* Write the header */ - /* I love combinatorial explosion */ - gtk_html_stream_printf (stream, + gtk_html_stream_printf (stream, "" "" "" @@ -259,25 +278,25 @@ write_html_heading (GtkHTMLStream *stream, const char *message, CalComponentVTyp gtk_html_stream_printf (stream, "

%s

", message); + /* Write the times */ + switch (vtype) { case CAL_COMPONENT_EVENT: - /* gtk_html_stream_printf (stream, "%s
", U_("Notification about your appointment")); */ write_times (stream, start, end); break; + case CAL_COMPONENT_TODO: - /* gtk_html_stream_printf (stream, "%s
", U_("Notification about your task")); */ write_times (stream, start, end); break; + default: /* Only VEVENTs and VTODOs can have alarms */ g_assert_not_reached (); - buf = NULL; break; } g_free (start); g_free (end); - return; } /** @@ -289,10 +308,10 @@ write_html_heading (GtkHTMLStream *stream, const char *message, CalComponentVTyp * @message; Message to display in the dialog; usually comes from the component. * @func: Function to be called when a dialog action is invoked. * @func_data: Closure data for @func. - * + * * Runs the alarm notification dialog. The specified @func will be used to * notify the client about result of the actions in the dialog. - * + * * Return value: TRUE on success, FALSE if the dialog could not be created. **/ gboolean @@ -301,9 +320,9 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, AlarmNotifyFunc func, gpointer func_data) { AlarmNotify *an; - char buf[256]; - struct tm tm_trigger; GtkHTMLStream *stream; + icaltimezone *current_zone; + char *buf, *title; g_return_val_if_fail (trigger != -1, FALSE); @@ -346,9 +365,15 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, GTK_SIGNAL_FUNC (dialog_destroy_cb), an); /* Title */ - tm_trigger = *localtime (&trigger); - strftime (buf, sizeof (buf), _("Alarm on %A %b %d %Y %H:%M"), &tm_trigger); - gtk_window_set_title (GTK_WINDOW (an->dialog), buf); + + current_zone = config_data_get_timezone (); + + buf = timet_to_str_with_zone (trigger, current_zone); + title = g_strdup_printf (_("Alarm on %s"), buf); + g_free (buf); + + gtk_window_set_title (GTK_WINDOW (an->dialog), title); + g_free (title); /* html heading */ stream = gtk_html_begin (GTK_HTML (an->html)); @@ -360,7 +385,7 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, gtk_signal_connect (GTK_OBJECT (an->dialog), "delete_event", GTK_SIGNAL_FUNC (delete_event_cb), an); - + gtk_signal_connect (GTK_OBJECT (an->close), "clicked", GTK_SIGNAL_FUNC (close_clicked_cb), an); @@ -379,6 +404,7 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, gtk_widget_realize (an->dialog); gnome_win_hints_set_state (an->dialog, WIN_STATE_STICKY); + gnome_win_hints_set_layer (an->dialog, WIN_LAYER_ONTOP); gnome_window_icon_set_from_file (GTK_WINDOW (an->dialog), EVOLUTION_ICONSDIR "/alarm.png"); gtk_widget_show (an->dialog); diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c index 0a57e78ad7..533635289e 100644 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ b/calendar/gui/alarm-notify/alarm-queue.c @@ -38,6 +38,7 @@ #include "alarm.h" #include "alarm-notify-dialog.h" #include "alarm-queue.h" +#include "config-data.h" #include "save.h" @@ -120,10 +121,13 @@ static void queue_midnight_refresh (void) { time_t midnight; + icaltimezone *zone; g_assert (midnight_refresh_id == NULL); - midnight = time_day_end (time (NULL)); + zone = config_data_get_timezone (); + + midnight = time_day_end_with_zone (time (NULL), zone); midnight_refresh_id = alarm_add (midnight, midnight_refresh_cb, NULL, NULL); if (!midnight_refresh_id) { @@ -347,11 +351,6 @@ load_alarms (ClientAlarms *ca, time_t start, time_t end) comp_alarms = cal_client_get_alarms_in_range (ca->client, start, end); - /* All of the last day's alarms should have already triggered and should - * have been removed, so we should have no pending components. - */ - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); - for (l = comp_alarms; l; l = l->next) { CalComponentAlarms *alarms; @@ -367,9 +366,14 @@ static void load_alarms_for_today (ClientAlarms *ca) { time_t now, day_end; + icaltimezone *zone; now = time (NULL); - day_end = time_day_end (now); + + zone = config_data_get_timezone (); + + day_end = time_day_end_with_zone (now, zone); + load_alarms (ca, now, day_end); } /* Adds any alarms that should have occurred while the alarm daemon was not @@ -460,13 +464,17 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data) time_t now, day_end; CalComponentAlarms *alarms; gboolean found; + icaltimezone *zone; ca = data; remove_comp (ca, uid); now = time (NULL); - day_end = time_day_end (now); + + zone = config_data_get_timezone (); + + day_end = time_day_end_with_zone (now, zone); found = cal_client_get_alarms_for_object (ca->client, uid, now, day_end, &alarms); diff --git a/calendar/gui/alarm-notify/alarm.c b/calendar/gui/alarm-notify/alarm.c index f750ed515c..f8e64b8bc0 100644 --- a/calendar/gui/alarm-notify/alarm.c +++ b/calendar/gui/alarm-notify/alarm.c @@ -114,7 +114,9 @@ alarm_ready_cb (gpointer data) return FALSE; } -/* Sets up a timeout for the next minute */ +/* Sets up a timeout for the next minute. We do not need to be concerned with + * timezones here, as this is just a periodic check on the alarm queue. + */ static void setup_timeout (time_t now) { diff --git a/calendar/gui/alarm-notify/config-data.c b/calendar/gui/alarm-notify/config-data.c new file mode 100644 index 0000000000..ece37cd10e --- /dev/null +++ b/calendar/gui/alarm-notify/config-data.c @@ -0,0 +1,111 @@ +/* Evolution calendar - Configuration values for the alarm notification daemon + * + * Copyright (C) 2001 Ximian, Inc. + * + * Authors: Federico Mena-Quintero + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "config-data.h" +#include "save.h" + + + +/* Whether we have initied ourselves by reading the data from the configuration engine */ +static gboolean inited; + +/* Configuration values */ +static icaltimezone *local_timezone; +static gboolean use_24_hour_format; + + + +/* Copied from ../calendar-config.c; returns whether the locale has 'am' and + * 'pm' strings defined. + */ +static gboolean +locale_supports_12_hour_format (void) +{ + char s[16]; + time_t t = 0; + + strftime (s, sizeof s, "%p", gmtime (&t)); + return s[0] != '\0'; +} + +/* Ensures that the configuration values have been read */ +static void +ensure_inited (void) +{ + Bonobo_ConfigDatabase db; + char *location; + + if (inited) + return; + + inited = TRUE; + + db = get_config_db (); + if (db == CORBA_OBJECT_NIL) { + /* This sucks */ + local_timezone = icaltimezone_get_utc_timezone (); + + /* This sucks as well */ + use_24_hour_format = TRUE; + + return; + } + + location = bonobo_config_get_string (db, "/Calendar/Display/Timezone", NULL); + if (location) { + local_timezone = icaltimezone_get_builtin_timezone (location); + g_free (location); + } else + local_timezone = icaltimezone_get_utc_timezone (); + + if (locale_supports_12_hour_format ()) { + /* Wasn't the whole point of a configuration engine *NOT* to + * have apps specify their own stupid defaults everywhere, but + * just in a schema file? + */ + use_24_hour_format = bonobo_config_get_boolean_with_default ( + db, + "/Calendar/Display/Use24HourFormat", FALSE, NULL); + } else + use_24_hour_format = TRUE; + + discard_config_db (db); +} + +icaltimezone * +config_data_get_timezone (void) +{ + ensure_inited (); + + return local_timezone; +} + +gboolean +config_data_get_24_hour_format (void) +{ + ensure_inited (); + + return use_24_hour_format; +} diff --git a/calendar/gui/alarm-notify/config-data.h b/calendar/gui/alarm-notify/config-data.h new file mode 100644 index 0000000000..614d944edd --- /dev/null +++ b/calendar/gui/alarm-notify/config-data.h @@ -0,0 +1,32 @@ +/* Evolution calendar - Configuration values for the alarm notification daemon + * + * Copyright (C) 2001 Ximian, Inc. + * + * Authors: Federico Mena-Quintero + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef CONFIG_DATA_H +#define CONFIG_DATA_H + +#include +#include + +icaltimezone *config_data_get_timezone (void); + +gboolean config_data_get_24_hour_format (void); + +#endif diff --git a/calendar/gui/alarm-notify/save.c b/calendar/gui/alarm-notify/save.c index 2a24a7d17a..8f138fb1a7 100644 --- a/calendar/gui/alarm-notify/save.c +++ b/calendar/gui/alarm-notify/save.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "evolution-calendar.h" #include "save.h" @@ -40,7 +39,7 @@ /* Tries to get the config database object; returns CORBA_OBJECT_NIL on failure. */ -static Bonobo_ConfigDatabase +Bonobo_ConfigDatabase get_config_db (void) { CORBA_Environment ev; @@ -59,7 +58,7 @@ get_config_db (void) } /* Syncs a database and unrefs it */ -static void +void discard_config_db (Bonobo_ConfigDatabase db) { CORBA_Environment ev; diff --git a/calendar/gui/alarm-notify/save.h b/calendar/gui/alarm-notify/save.h index 41fee52836..efacbefffb 100644 --- a/calendar/gui/alarm-notify/save.h +++ b/calendar/gui/alarm-notify/save.h @@ -23,6 +23,10 @@ #define SAVE_H #include +#include + +Bonobo_ConfigDatabase get_config_db (void); +void discard_config_db (Bonobo_ConfigDatabase db); void save_notification_time (time_t t); time_t get_saved_notification_time (void); diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c index 0824f410c5..276f6c3a24 100644 --- a/calendar/gui/dialogs/alarm-page.c +++ b/calendar/gui/dialogs/alarm-page.c @@ -33,7 +33,10 @@ #include #include #include "e-util/e-dialog-widgets.h" +#include "e-util/e-time-utils.h" #include "cal-util/cal-util.h" +#include "cal-util/timeutil.h" +#include "../calendar-config.h" #include "comp-editor-util.h" #include "alarm-options.h" #include "alarm-page.h" @@ -428,20 +431,27 @@ get_alarm_string (CalComponentAlarm *alarm) break; case CAL_ALARM_TRIGGER_ABSOLUTE: { - time_t t; + struct icaltimetype itt; + icaltimezone *utc_zone, *current_zone; + char *location; struct tm tm; + char buf[256]; char *date; - t = icaltime_as_timet (trigger.u.abs_time); - if (t == -1) - date = g_strdup_printf (_("%s at an unknown time"), base); - else { - char buf[256]; + /* Absolute triggers come in UTC, so convert them to the local timezone */ - tm = *localtime (&t); - strftime (buf, sizeof (buf), "%A %b %d %Y %H:%M", &tm); - date = g_strdup_printf (_("%s at %s"), base, buf); - } + itt = trigger.u.abs_time; + + utc_zone = icaltimezone_get_utc_timezone (); + location = calendar_config_get_timezone (); + current_zone = icaltimezone_get_builtin_timezone (location); + + tm = icaltimetype_to_tm_with_zone (&itt, utc_zone, current_zone); + + e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buf, sizeof (buf)); + + date = g_strdup_printf (_("%s at %s"), base, buf); break; } diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c index d0b9d2bf7a..b30fe41c97 100644 --- a/calendar/gui/e-cell-date-edit-text.c +++ b/calendar/gui/e-cell-date-edit-text.c @@ -85,18 +85,7 @@ ecd_get_text (ECellText *cell, ETableModel *model, int col, int row) timezone, we convert it to the current timezone to display it in the table. If the user actually edits the value, it will be set to the current timezone. See set_value(). */ - tt = dv->tt; - icaltimezone_convert_time (&tt, dv->zone, ecd->zone); - - tmp_tm.tm_year = tt.year - 1900; - tmp_tm.tm_mon = tt.month - 1; - tmp_tm.tm_mday = tt.day; - tmp_tm.tm_hour = tt.hour; - tmp_tm.tm_min = tt.minute; - tmp_tm.tm_sec = tt.second; - tmp_tm.tm_isdst = -1; - - tmp_tm.tm_wday = time_day_of_week (tt.day, tt.month - 1, tt.year); + tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, ecd->zone); e_time_format_date_and_time (&tmp_tm, ecd->use_24_hour_format, TRUE, FALSE, diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 28556ba522..728efba451 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -1341,7 +1341,7 @@ client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer da gcal = GNOME_CALENDAR (data); priv = gcal->priv; - e_week_view_set_status_message (priv->week_view, NULL); + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), NULL); switch (status) { case CAL_CLIENT_OPEN_SUCCESS: @@ -1682,7 +1682,7 @@ gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri) FALSE); message = g_strdup_printf (_("Opening calendar at %s"), str_uri); - e_week_view_set_status_message (priv->week_view, message); + e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), message); g_free (message); if (!cal_client_open_calendar (priv->client, str_uri, FALSE)) { -- cgit v1.2.3