Commit c3876df7 authored by Federico Mena Quintero's avatar Federico Mena Quintero Committed by Federico Mena Quintero

Fixes bug #5282.

2001-10-24  Federico Mena Quintero  <federico@ximian.com>

	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
parent 4d26929f
2001-10-24 Federico Mena Quintero <federico@ximian.com>
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.
2001-10-23 Damon Chaplin <damon@ximian.com>
* cal-util/cal-component.c (cal_component_event_dates_match): make sure
......
......@@ -532,15 +532,51 @@ icaltimetype_to_tm (struct icaltimetype *itt)
tm.tm_min = itt->minute;
tm.tm_hour = itt->hour;
}
tm.tm_mday = itt->day;
tm.tm_mon = itt->month - 1;
tm.tm_year = itt->year - 1900;
tm.tm_wday = time_day_of_week (itt->day, itt->month - 1, itt->year);
tm.tm_isdst = -1;
return tm;
}
/**
* icaltimetype_to_tm_with_zone:
* @itt: A time value.
* @from_zone: Source timezone.
* @to_zone: Destination timezone.
*
* Converts a time value from one timezone to another, and returns a struct tm
* representation of the time.
*
* Return value: The converted time as a struct tm. All fields will be
* set properly except for tm.tm_yday.
**/
struct tm
icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
icaltimezone *from_zone,
icaltimezone *to_zone)
{
struct tm tm;
struct icaltimetype itt_copy;
memset (&tm, 0, sizeof (tm));
tm.tm_isdst = -1;
g_return_val_if_fail (itt != NULL, tm);
g_return_val_if_fail (from_zone != NULL, tm);
g_return_val_if_fail (to_zone != NULL, tm);
itt_copy = *itt;
icaltimezone_convert_time (&itt_copy, from_zone, to_zone);
tm = icaltimetype_to_tm (&itt_copy);
return tm;
}
struct icaltimetype
tm_to_icaltimetype (struct tm *tm, gboolean is_date)
{
......
......@@ -114,6 +114,9 @@ void time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone);
**************************************************************************/
struct tm icaltimetype_to_tm (struct icaltimetype *itt);
struct tm icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
icaltimezone *from_zone,
icaltimezone *to_zone);
struct icaltimetype tm_to_icaltimetype (struct tm *tm, gboolean is_date);
#endif
......@@ -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
......
......@@ -38,7 +38,9 @@
#include <gal/widgets/e-scroll-frame.h>
#include <gtkhtml/gtkhtml.h>
#include <gtkhtml/gtkhtml-stream.h>
#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,
"<HTML><BODY background=\"%s\">"
"<TABLE WIDTH=\"100%%\">"
"<TR>"
......@@ -259,25 +278,25 @@ write_html_heading (GtkHTMLStream *stream, const char *message, CalComponentVTyp
gtk_html_stream_printf (stream, "<br><br><font size=\"+2\">%s</font><br><br>", message);
/* Write the times */
switch (vtype) {
case CAL_COMPONENT_EVENT:
/* gtk_html_stream_printf (stream, "%s<br>", U_("Notification about your appointment")); */
write_times (stream, start, end);
break;
case CAL_COMPONENT_TODO:
/* gtk_html_stream_printf (stream, "%s<br>", 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);
......
......@@ -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);
......
......@@ -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)
{
......
/* Evolution calendar - Configuration values for the alarm notification daemon
*
* Copyright (C) 2001 Ximian, Inc.
*
* Authors: Federico Mena-Quintero <federico@ximian.com>
*
* 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 <config.h>
#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;
}
/* Evolution calendar - Configuration values for the alarm notification daemon
*
* Copyright (C) 2001 Ximian, Inc.
*
* Authors: Federico Mena-Quintero <federico@ximian.com>
*
* 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 <glib.h>
#include <ical.h>
icaltimezone *config_data_get_timezone (void);
gboolean config_data_get_24_hour_format (void);
#endif
......@@ -26,7 +26,6 @@
#include <bonobo/bonobo-arg.h>
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-moniker-util.h>
#include <bonobo-conf/bonobo-config-database.h>
#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;
......
......@@ -23,6 +23,10 @@
#define SAVE_H
#include <time.h>
#include <bonobo-conf/bonobo-config-database.h>
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);
......
......@@ -33,7 +33,10 @@
#include <glade/glade.h>
#include <gal/widgets/e-unicode.h>
#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; }
......
......@@ -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,
......
......@@ -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)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment