aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/calendar-config.c14
-rw-r--r--calendar/gui/calendar-model.c70
-rw-r--r--calendar/gui/calendar-model.h5
-rw-r--r--calendar/gui/comp-util.c6
-rw-r--r--calendar/gui/comp-util.h2
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.c12
-rw-r--r--calendar/gui/dialogs/comp-editor-page.c51
-rw-r--r--calendar/gui/dialogs/comp-editor-page.h14
-rw-r--r--calendar/gui/dialogs/comp-editor-util.c124
-rw-r--r--calendar/gui/dialogs/comp-editor-util.h2
-rw-r--r--calendar/gui/dialogs/comp-editor.c5
-rw-r--r--calendar/gui/dialogs/e-timezone-dialog.c45
-rw-r--r--calendar/gui/dialogs/e-timezone-dialog.h15
-rw-r--r--calendar/gui/dialogs/event-page.c346
-rw-r--r--calendar/gui/dialogs/meeting-page.c2
-rw-r--r--calendar/gui/dialogs/recurrence-page.c211
-rw-r--r--calendar/gui/dialogs/task-details-page.c97
-rw-r--r--calendar/gui/dialogs/task-details-page.glade38
-rw-r--r--calendar/gui/dialogs/task-page.c166
-rw-r--r--calendar/gui/e-calendar-table.c37
-rw-r--r--calendar/gui/e-day-view-main-item.c10
-rw-r--r--calendar/gui/e-day-view-top-item.c11
-rw-r--r--calendar/gui/e-day-view.c154
-rw-r--r--calendar/gui/e-day-view.h8
-rw-r--r--calendar/gui/e-itip-control.c3
-rw-r--r--calendar/gui/e-timezone-entry.c90
-rw-r--r--calendar/gui/e-timezone-entry.h6
-rw-r--r--calendar/gui/e-week-view.c110
-rw-r--r--calendar/gui/e-week-view.h8
-rw-r--r--calendar/gui/gnome-cal.c124
-rw-r--r--calendar/gui/gnome-cal.h4
-rw-r--r--calendar/gui/goto.c53
-rw-r--r--calendar/gui/tag-calendar.c70
-rw-r--r--calendar/gui/tag-calendar.h3
34 files changed, 1422 insertions, 494 deletions
diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c
index f4678ab098..41c55ab91c 100644
--- a/calendar/gui/calendar-config.c
+++ b/calendar/gui/calendar-config.c
@@ -582,6 +582,8 @@ calendar_config_configure_e_calendar_table (ECalendarTable *cal_table)
{
CalendarModel *model;
gboolean use_24_hour;
+ char *location;
+ icaltimezone *zone;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
@@ -590,6 +592,10 @@ calendar_config_configure_e_calendar_table (ECalendarTable *cal_table)
model = e_calendar_table_get_model (cal_table);
calendar_model_set_use_24_hour_format (model, use_24_hour);
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+ calendar_model_set_timezone (model, zone);
+
calendar_config_configure_e_cell_date_edit (cal_table->dates_cell);
/* This is for changing the colors of the text; they will be re-fetched
@@ -636,12 +642,12 @@ on_timezone_set (GnomeDialog *dialog,
int button,
ETimezoneDialog *etd)
{
- char *zone;
+ char *display_name;
- zone = e_timezone_dialog_get_timezone (etd);
+ e_timezone_dialog_get_timezone (etd, &display_name);
- if (zone && zone[0]) {
- calendar_config_set_timezone (zone);
+ if (display_name && display_name[0]) {
+ calendar_config_set_timezone (display_name);
calendar_config_write ();
update_all_config_settings ();
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
index bcd4d69843..6d1625238d 100644
--- a/calendar/gui/calendar-model.c
+++ b/calendar/gui/calendar-model.c
@@ -75,6 +75,9 @@ struct _CalendarModelPrivate {
/* A balanced tree of the categories used by all the tasks/events. */
GTree *categories;
+
+ /* The current timezone. */
+ icaltimezone *zone;
};
enum {
@@ -201,6 +204,8 @@ calendar_model_init (CalendarModel *model)
priv->use_24_hour_format = TRUE;
priv->categories = g_tree_new ((GCompareFunc)strcmp);
+
+ priv->zone = NULL;
}
/* Called from g_hash_table_foreach_remove(), frees a stored UID->index
@@ -317,13 +322,26 @@ static char*
get_time_t (CalendarModel *model, time_t *t, gboolean show_midnight)
{
static char buffer[64];
- struct tm *tmp_tm;
+ struct tm tmp_tm;
+ struct icaltimetype tt;
if (*t <= 0) {
buffer[0] = '\0';
} else {
- tmp_tm = localtime (t);
- e_time_format_date_and_time (tmp_tm,
+ tt = icaltime_from_timet_with_zone (*t, FALSE,
+ model->priv->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;
+
+ /* Call mktime() to set the weekday. */
+ mktime (&tmp_tm);
+
+ e_time_format_date_and_time (&tmp_tm,
model->priv->use_24_hour_format,
show_midnight, FALSE,
buffer, sizeof (buffer));
@@ -383,12 +401,15 @@ get_completed (CalendarModel *model,
struct icaltimetype *completed;
time_t t;
+ /* FIXME: COMPLETED is in UTC, but we probably want to show it in
+ the current timezone. */
+
cal_component_get_completed (comp, &completed);
if (!completed)
t = 0;
else {
- t = icaltime_as_timet (*completed);
+ t = icaltime_as_timet_with_zone (*completed, icaltimezone_get_utc_timezone ());
cal_component_free_icaltimetype (completed);
}
@@ -840,6 +861,8 @@ show_date_warning (CalendarModel *model)
struct tm *tmp_tm;
t = time (NULL);
+ /* We are only using this as an example, so the timezone doesn't
+ matter. */
tmp_tm = localtime (&t);
if (model->priv->use_24_hour_format)
@@ -972,6 +995,9 @@ set_completed (CalendarModel *model, CalComponent *comp, const char *value)
struct tm tmp_tm;
time_t t;
+ /* FIXME: COMPLETED is in UTC, but we probably want to show it in
+ the current timezone. */
+
status = e_time_parse_date_and_time (value, &tmp_tm);
if (status == E_TIME_PARSE_INVALID) {
@@ -991,7 +1017,6 @@ set_datetime (CalendarModel *model, CalComponent *comp, const char *value,
{
ETimeParseStatus status;
struct tm tmp_tm;
- time_t t;
status = e_time_parse_date_and_time (value, &tmp_tm);
@@ -1001,12 +1026,18 @@ set_datetime (CalendarModel *model, CalComponent *comp, const char *value,
(* set_func) (comp, NULL);
} else {
CalComponentDateTime dt;
- struct icaltimetype itt;
+ struct icaltimetype itt = icaltime_null_time ();
+
+ itt.year = tmp_tm.tm_year + 1900;
+ itt.month = tmp_tm.tm_mon + 1;
+ itt.day = tmp_tm.tm_mday;
+ itt.hour = tmp_tm.tm_hour;
+ itt.minute = tmp_tm.tm_min;
+ itt.second = tmp_tm.tm_sec;
- t = mktime (&tmp_tm);
- itt = icaltime_from_timet (t, FALSE);
dt.value = &itt;
- dt.tzid = NULL;
+ /* We assume it is being set to the current timezone. */
+ dt.tzid = icaltimezone_get_tzid (model->priv->zone);
(* set_func) (comp, &dt);
}
@@ -2305,3 +2336,24 @@ calendar_model_get_categories (CalendarModel *model)
return model->priv->categories;
}
+
+
+/* The current timezone. */
+icaltimezone*
+calendar_model_get_timezone (CalendarModel *model)
+{
+ g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL);
+
+ return model->priv->zone;
+}
+
+
+void
+calendar_model_set_timezone (CalendarModel *model,
+ icaltimezone *zone)
+{
+ g_return_if_fail (IS_CALENDAR_MODEL (model));
+
+ if (model->priv->zone != zone)
+ model->priv->zone = zone;
+}
diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h
index c74a2b41ee..5a47d3752e 100644
--- a/calendar/gui/calendar-model.h
+++ b/calendar/gui/calendar-model.h
@@ -80,6 +80,11 @@ gboolean calendar_model_get_use_24_hour_format (CalendarModel *model);
void calendar_model_set_use_24_hour_format (CalendarModel *model,
gboolean use_24_hour_format);
+/* The current timezone. */
+icaltimezone* calendar_model_get_timezone (CalendarModel *model);
+void calendar_model_set_timezone (CalendarModel *model,
+ icaltimezone *zone);
+
GTree* calendar_model_get_categories (CalendarModel *model);
void calendar_model_set_default_category (CalendarModel *model,
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 8b612f0ca9..944b5dcdce 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -37,7 +37,7 @@
* component object.
**/
void
-cal_comp_util_add_exdate (CalComponent *comp, struct icaltimetype itt)
+cal_comp_util_add_exdate (CalComponent *comp, time_t t, icaltimezone *zone)
{
GSList *list;
CalComponentDateTime *cdt;
@@ -49,8 +49,8 @@ cal_comp_util_add_exdate (CalComponent *comp, struct icaltimetype itt)
cdt = g_new (CalComponentDateTime, 1);
cdt->value = g_new (struct icaltimetype, 1);
- *cdt->value = itt;
- cdt->tzid = NULL;
+ *cdt->value = icaltime_from_timet_with_zone (t, TRUE, zone);
+ cdt->tzid = icaltimezone_get_tzid (zone);
list = g_slist_append (list, cdt);
cal_component_set_exdate_list (comp, list);
diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h
index 4da2557f1b..d0c39259ab 100644
--- a/calendar/gui/comp-util.h
+++ b/calendar/gui/comp-util.h
@@ -25,6 +25,6 @@
#include <cal-util/cal-component.h>
-void cal_comp_util_add_exdate (CalComponent *comp, struct icaltimetype itt);
+void cal_comp_util_add_exdate (CalComponent *comp, time_t t, icaltimezone *zone);
#endif
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c
index de3cbf2483..59acefc263 100644
--- a/calendar/gui/dialogs/cal-prefs-dialog.c
+++ b/calendar/gui/dialogs/cal-prefs-dialog.c
@@ -390,14 +390,16 @@ cal_prefs_dialog_show_config (CalPrefsDialog *prefs)
CalPrefsDialogPrivate *priv;
CalWeekdays working_days;
gint mask, day, week_start_day, time_divisions;
- char *zone;
+ char *zone_name;
+ icaltimezone *zone;
priv = prefs->priv;
/* Timezone. */
- zone = calendar_config_get_timezone ();
+ zone_name = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (zone_name);
e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->timezone),
- zone ? zone : "");
+ zone);
/* Working Days. */
working_days = calendar_config_get_working_days ();
@@ -482,13 +484,13 @@ cal_prefs_dialog_update_config (CalPrefsDialog *prefs)
CalPrefsDialogPrivate *priv;
CalWeekdays working_days;
gint mask, day, week_start_day, time_divisions, hour, minute;
- char *zone;
+ icaltimezone *zone;
priv = prefs->priv;
/* Timezone. */
zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->timezone));
- calendar_config_set_timezone (zone);
+ calendar_config_set_timezone (icaltimezone_get_location (zone));
/* Working Days. */
working_days = 0;
diff --git a/calendar/gui/dialogs/comp-editor-page.c b/calendar/gui/dialogs/comp-editor-page.c
index afa09177f5..85e7b8c9af 100644
--- a/calendar/gui/dialogs/comp-editor-page.c
+++ b/calendar/gui/dialogs/comp-editor-page.c
@@ -29,6 +29,8 @@
static void comp_editor_page_class_init (CompEditorPageClass *class);
+static void comp_editor_page_init (CompEditorPage *page);
+static void comp_editor_page_destroy (GtkObject *object);
/* Signal IDs */
@@ -65,7 +67,7 @@ comp_editor_page_get_type (void)
sizeof (CompEditorPage),
sizeof (CompEditorPageClass),
(GtkClassInitFunc) comp_editor_page_class_init,
- (GtkObjectInitFunc) NULL,
+ (GtkObjectInitFunc) comp_editor_page_init,
NULL, /* reserved_1 */
NULL, /* reserved_2 */
(GtkClassInitFunc) NULL
@@ -136,10 +138,36 @@ comp_editor_page_class_init (CompEditorPageClass *class)
class->fill_component = NULL;
class->set_summary = NULL;
class->set_dates = NULL;
+
+ object_class->destroy = comp_editor_page_destroy;
}
+static void
+comp_editor_page_init (CompEditorPage *page)
+{
+ page->client = NULL;
+}
+
+
+static void
+comp_editor_page_destroy (GtkObject *object)
+{
+ CompEditorPage *page;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (object));
+
+ page = COMP_EDITOR_PAGE (object);
+
+ if (page->client) {
+ gtk_object_ref (GTK_OBJECT (page->client));
+ page->client = NULL;
+ }
+}
+
+
/**
* comp_editor_page_get_widget:
* @page: An editor page.
@@ -198,6 +226,27 @@ comp_editor_page_fill_component (CompEditorPage *page, CalComponent *comp)
}
/**
+ * comp_editor_page_set_cal_client:
+ * @page: An editor page
+ * @client: A #CalClient object
+ *
+ * Sets the #CalClient for the dialog page to use.
+ **/
+void
+comp_editor_page_set_cal_client (CompEditorPage *page, CalClient *client)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ if (page->client)
+ gtk_object_unref (GTK_OBJECT (client));
+
+ page->client = client;
+ if (page->client)
+ gtk_object_ref (GTK_OBJECT (client));
+}
+
+/**
* comp_editor_page_set_summary:
* @page: An editor page
* @summary: The text of the new summary value
diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h
index b544200a76..08fe1d8508 100644
--- a/calendar/gui/dialogs/comp-editor-page.h
+++ b/calendar/gui/dialogs/comp-editor-page.h
@@ -26,6 +26,7 @@
#include <libgnome/gnome-defs.h>
#include <gtk/gtkwidget.h>
#include <cal-util/cal-component.h>
+#include "cal-client.h"
BEGIN_GNOME_DECLS
@@ -38,14 +39,17 @@ BEGIN_GNOME_DECLS
#define IS_COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_COMP_EDITOR_PAGE))
typedef struct {
- time_t start;
- time_t end;
- time_t due;
- time_t complete;
+ struct icaltimetype *start;
+ struct icaltimetype *end;
+ struct icaltimetype *due;
+ struct icaltimetype *complete;
} CompEditorPageDates;
typedef struct {
GtkObject object;
+
+ /* Some of the pages need the CalClient to access timezone data. */
+ CalClient *client;
} CompEditorPage;
typedef struct {
@@ -77,6 +81,8 @@ void comp_editor_page_fill_widgets (CompEditorPage *page,
CalComponent *comp);
void comp_editor_page_fill_component (CompEditorPage *page,
CalComponent *comp);
+void comp_editor_page_set_cal_client (CompEditorPage *page,
+ CalClient *client);
void comp_editor_page_set_summary (CompEditorPage *page,
const char *summary);
void comp_editor_page_set_dates (CompEditorPage *page,
diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c
index b6c169f6ed..e3cf454e84 100644
--- a/calendar/gui/dialogs/comp-editor-util.c
+++ b/calendar/gui/dialogs/comp-editor-util.c
@@ -24,6 +24,7 @@
#endif
#include <string.h>
+#include <ical.h>
#include <glib.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
@@ -39,50 +40,77 @@
* @comp: The component to extract the dates from
*
* Extracts the dates from the calendar component into the
- * CompEditorPageDates structure
+ * CompEditorPageDates structure. Note that it returns pointers to static
+ * structs, so these will be overwritten in the next call.
**/
void
comp_editor_dates (CompEditorPageDates *dates, CalComponent *comp)
{
+ static struct icaltimetype start;
+ static struct icaltimetype end;
+ static struct icaltimetype due;
+ static struct icaltimetype complete;
+
CalComponentDateTime dt;
- struct icaltimetype *completed;
+ struct icaltimetype *comp_complete;
+
- dates->start = 0;
- dates->end = 0;
- dates->due = 0;
- dates->complete = 0;
+ dates->start = NULL;
+ dates->end = NULL;
+ dates->due = NULL;
+ dates->complete = NULL;
cal_component_get_dtstart (comp, &dt);
- if (dt.value)
- dates->start = icaltime_as_timet (*dt.value);
+ if (dt.value) {
+ start = *dt.value;
+ dates->start = &start;
+ }
+ cal_component_free_datetime (&dt);
cal_component_get_dtend (comp, &dt);
- if (dt.value)
- dates->end = icaltime_as_timet (*dt.value);
+ if (dt.value) {
+ end = *dt.value;
+ dates->end = &end;
+ }
+ cal_component_free_datetime (&dt);
cal_component_get_due (comp, &dt);
- if (dt.value)
- dates->due = icaltime_as_timet (*dt.value);
+ if (dt.value) {
+ due = *dt.value;
+ dates->due = &due;
+ }
+ cal_component_free_datetime (&dt);
- cal_component_get_completed (comp, &completed);
- if (completed) {
- dates->complete = icaltime_as_timet (*completed);
- cal_component_free_icaltimetype (completed);
+ cal_component_get_completed (comp, &comp_complete);
+ if (comp_complete) {
+ complete = *comp_complete;
+ dates->complete = &complete;
}
+ cal_component_free_icaltimetype (comp_complete);
}
static void
-write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
+write_label_piece (struct icaltimetype *tt, char *buffer, int size,
+ char *stext, char *etext)
{
- struct tm *tmp_tm;
+ struct tm tmp_tm;
int len;
- tmp_tm = localtime (&t);
+ /* FIXME: May want to convert the time to an appropriate zone. */
+
if (stext != NULL)
strcat (buffer, stext);
+ 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;
+
len = strlen (buffer);
- e_time_format_date_and_time (tmp_tm,
+ e_time_format_date_and_time (&tmp_tm,
calendar_config_get_24_hour_format (),
FALSE, FALSE,
&buffer[len], size - len);
@@ -101,25 +129,36 @@ write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
void
comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label)
{
- static char buffer[1024];
+ char buffer[1024];
+ gboolean start_set = FALSE, end_set = FALSE;
+ gboolean complete_set = FALSE, due_set = FALSE;
buffer[0] = '\0';
- if (dates->start > 0)
+ if (dates->start && !icaltime_is_null_time (*dates->start))
+ start_set = TRUE;
+ if (dates->end && !icaltime_is_null_time (*dates->end))
+ end_set = TRUE;
+ if (dates->complete && !icaltime_is_null_time (*dates->complete))
+ complete_set = TRUE;
+ if (dates->due && !icaltime_is_null_time (*dates->due))
+ due_set = TRUE;
+
+ if (start_set)
write_label_piece (dates->start, buffer, 1024, NULL, NULL);
- if (dates->end > 0 && dates->start > 0)
+ if (start_set && end_set)
write_label_piece (dates->end, buffer, 1024, _(" to "), NULL);
- if (dates->complete > 0) {
- if (dates->start > 0)
+ if (complete_set) {
+ if (start_set)
write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")");
else
write_label_piece (dates->complete, buffer, 1024, _("Completed "), NULL);
}
- if (dates->due > 0 && dates->complete == 0) {
- if (dates->start > 0)
+ if (due_set && dates->complete == NULL) {
+ if (start_set)
write_label_piece (dates->due, buffer, 1024, _(" (Due "), ")");
else
write_label_piece (dates->due, buffer, 1024, _("Due "), NULL);
@@ -151,3 +190,34 @@ comp_editor_new_date_edit (gboolean show_date, gboolean show_time)
return GTK_WIDGET (dedit);
}
+
+
+/* Returns the current time, for EDateEdit widgets and ECalendar items in the
+ dialogs.
+ FIXME: Should probably use the timezone from somewhere in the component
+ rather than the current timezone. */
+struct tm
+comp_editor_get_current_time (GtkObject *object, gpointer data)
+{
+ char *location;
+ icaltimezone *zone;
+ struct icaltimetype tt;
+ struct tm tmp_tm = { 0 };
+
+ /* Get the current timezone. */
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ 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;
+
+ return tmp_tm;
+}
diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h
index f2299e27c4..4e8e344731 100644
--- a/calendar/gui/dialogs/comp-editor-util.h
+++ b/calendar/gui/dialogs/comp-editor-util.h
@@ -30,4 +30,6 @@ void comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label);
GtkWidget *comp_editor_new_date_edit (gboolean show_date, gboolean show_time);
+struct tm comp_editor_get_current_time (GtkObject *object, gpointer data);
+
#endif
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index 08677260e7..c001207783 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -364,6 +364,7 @@ void
comp_editor_set_cal_client (CompEditor *editor, CalClient *client)
{
CompEditorPrivate *priv;
+ GList *elem;
g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
@@ -388,6 +389,10 @@ comp_editor_set_cal_client (CompEditor *editor, CalClient *client)
priv->client = client;
+ /* Pass the client to any pages that need it. */
+ for (elem = priv->pages; elem; elem = elem->next)
+ comp_editor_page_set_cal_client (elem->data, client);
+
gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
GTK_SIGNAL_FUNC (obj_updated_cb), editor);
diff --git a/calendar/gui/dialogs/e-timezone-dialog.c b/calendar/gui/dialogs/e-timezone-dialog.c
index ad9acfb528..70061addd6 100644
--- a/calendar/gui/dialogs/e-timezone-dialog.c
+++ b/calendar/gui/dialogs/e-timezone-dialog.c
@@ -37,6 +37,11 @@
#define E_TIMEZONE_DIALOG_MAP_POINT_SELECTED_2_RGBA 0x000000ff
struct _ETimezoneDialogPrivate {
+ /* The TZID of the timezone. May be NULL for a 'local time' (i.e. when
+ the displayed name is "") or for builtin timezones which we haven't
+ loaded yet. */
+ char *tzid;
+
/* Glade XML data */
GladeXML *xml;
@@ -131,6 +136,7 @@ e_timezone_dialog_init (ETimezoneDialog *etd)
priv = g_new0 (ETimezoneDialogPrivate, 1);
etd->priv = priv;
+ priv->tzid = NULL;
priv->point_selected = NULL;
priv->point_hover = NULL;
priv->timeout_id = 0;
@@ -149,6 +155,9 @@ e_timezone_dialog_destroy (GtkObject *object)
etd = E_TIMEZONE_DIALOG (object);
priv = etd->priv;
+ g_free (priv->tzid);
+ priv->tzid = NULL;
+
if (priv->timeout_id) {
g_source_remove (priv->timeout_id);
priv->timeout_id = 0;
@@ -460,6 +469,9 @@ on_map_button_pressed (GtkWidget *w, GdkEventButton *event, gpointer data)
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry),
get_zone_from_point (etd, priv->point_selected));
+
+ g_free (priv->tzid);
+ priv->tzid = NULL;
}
return TRUE;
@@ -508,8 +520,13 @@ get_zone_from_point (ETimezoneDialog *etd,
}
+/* Returns the TZID of the timezone set, and optionally its displayed name.
+ The TZID may be NULL, in which case the builtin timezone with the city name
+ of display_name should be used. If display_name is also NULL or "", then it
+ is assumed to be a 'local time'. */
char*
-e_timezone_dialog_get_timezone (ETimezoneDialog *etd)
+e_timezone_dialog_get_timezone (ETimezoneDialog *etd,
+ char **display_name)
{
ETimezoneDialogPrivate *priv;
@@ -518,13 +535,21 @@ e_timezone_dialog_get_timezone (ETimezoneDialog *etd)
priv = etd->priv;
- return gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry));
+ if (display_name)
+ *display_name = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry));
+
+ return priv->tzid;
}
+/* Sets the TZID and displayed name of the timezone. The TZID may be NULL for
+ a 'local time' (i.e. display_name is NULL or "") or if it is a builtin
+ timezone which hasn't been loaded yet. (This is done so we don't load
+ timezones until we really need them.) */
void
e_timezone_dialog_set_timezone (ETimezoneDialog *etd,
- char *timezone)
+ char *tzid,
+ char *display_name)
{
ETimezoneDialogPrivate *priv;
@@ -533,8 +558,13 @@ e_timezone_dialog_set_timezone (ETimezoneDialog *etd,
priv = etd->priv;
+ if (priv->tzid)
+ g_free (priv->tzid);
+
+ priv->tzid = g_strdup (tzid);
+
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->timezone_combo)->entry),
- timezone);
+ display_name ? display_name : "");
find_selected_point (etd);
}
@@ -605,5 +635,12 @@ find_selected_point (ETimezoneDialog *etd)
static void
on_combo_changed (GtkEditable *entry, ETimezoneDialog *etd)
{
+ ETimezoneDialogPrivate *priv;
+
+ priv = etd->priv;
+
find_selected_point (etd);
+
+ g_free (priv->tzid);
+ priv->tzid = NULL;
}
diff --git a/calendar/gui/dialogs/e-timezone-dialog.h b/calendar/gui/dialogs/e-timezone-dialog.h
index 323375c5fc..4f6f9dd934 100644
--- a/calendar/gui/dialogs/e-timezone-dialog.h
+++ b/calendar/gui/dialogs/e-timezone-dialog.h
@@ -56,9 +56,20 @@ ETimezoneDialog* e_timezone_dialog_construct (ETimezoneDialog *etd);
ETimezoneDialog* e_timezone_dialog_new (void);
-char* e_timezone_dialog_get_timezone (ETimezoneDialog *etd);
+/* Returns the TZID of the timezone set, and optionally its displayed name.
+ The TZID may be NULL, in which case the builtin timezone with the city name
+ of display_name should be used. If display_name is also NULL or "", then it
+ is assumed to be a 'local time'. */
+char* e_timezone_dialog_get_timezone (ETimezoneDialog *etd,
+ char **display_name);
+
+/* Sets the TZID and displayed name of the timezone. The TZID may be NULL for
+ a 'local time' (i.e. display_name is NULL or "") or if it is a builtin
+ timezone which hasn't been loaded yet. (This is done so we don't load
+ timezones until we really need them.) */
void e_timezone_dialog_set_timezone (ETimezoneDialog *etd,
- char *timezone);
+ char *tzid,
+ char *display_name);
GtkWidget* e_timezone_dialog_get_toplevel (ETimezoneDialog *etd);
diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c
index 89835ae4b3..c9f1891fdc 100644
--- a/calendar/gui/dialogs/event-page.c
+++ b/calendar/gui/dialogs/event-page.c
@@ -232,22 +232,20 @@ static void
check_all_day (EventPage *epage)
{
EventPagePrivate *priv;
- time_t ev_start, ev_end;
- gboolean all_day = FALSE;
+ gboolean all_day = FALSE, start_set, end_set;
+ gint start_hour, start_minute, end_hour, end_minute;
priv = epage->priv;
- /* Currently we just return if the date is not set or not valid.
- I'm not entirely sure this is the corrent thing to do. */
- ev_start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_assert (ev_start != -1);
+ start_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time),
+ &start_hour, &start_minute);
- ev_end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_assert (ev_end != -1);
+ end_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time),
+ &end_hour, &end_minute);
/* all day event checkbox */
- if (time_day_begin (ev_start) == ev_start
- && time_day_begin (ev_end) == ev_end)
+ if ((!start_set || (start_hour == 0 && start_minute == 0))
+ && (!end_set || (end_hour == 0 && end_minute == 0)))
all_day = TRUE;
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event),
@@ -265,12 +263,9 @@ static void
clear_widgets (EventPage *epage)
{
EventPagePrivate *priv;
- time_t now;
priv = epage->priv;
- now = time (NULL);
-
/* Summary, description */
e_dialog_editable_set (priv->summary, NULL);
e_dialog_editable_set (priv->description, NULL);
@@ -280,8 +275,8 @@ clear_widgets (EventPage *epage)
epage);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), now);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), now);
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_time), 0);
+ e_date_edit_set_time (E_DATE_EDIT (priv->end_time), 0);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
epage);
@@ -306,10 +301,14 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
EventPagePrivate *priv;
CalComponentText text;
CalComponentClassification cl;
- CalComponentDateTime d;
+ CalComponentDateTime start_date, end_date;
GSList *l;
- time_t dtstart, dtend;
const char *categories;
+ CalClientGetStatus status;
+ struct icaltimetype *start_tt, *end_tt;
+ icaltimezone *start_zone = NULL, *end_zone = NULL;
+
+ g_return_if_fail (page->client != NULL);
epage = EVENT_PAGE (page);
priv = epage->priv;
@@ -334,40 +333,63 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
/* Start and end times */
+ cal_component_get_dtstart (comp, &start_date);
+ status = cal_client_get_timezone (page->client, start_date.tzid,
+ &start_zone);
+ /* FIXME: Handle error better. */
+ if (status != CAL_CLIENT_GET_SUCCESS)
+ g_warning ("Couldn't get timezone from server: %s",
+ start_date.tzid ? start_date.tzid : "");
+
+ cal_component_get_dtend (comp, &end_date);
+ status = cal_client_get_timezone (page->client, end_date.tzid, &end_zone);
+ /* FIXME: Handle error better. */
+ if (status != CAL_CLIENT_GET_SUCCESS)
+ g_warning ("Couldn't get timezone from server: %s",
+ end_date.tzid ? end_date.tzid : "");
+
/* All-day events are inclusive, i.e. if the end date shown is 2nd Feb
then the event includes all of the 2nd Feb. We would normally show
3rd Feb as the end date, since it really ends at midnight on 3rd,
so we have to subtract a day so we only show the 2nd. */
- cal_component_get_dtstart (comp, &d);
- dtstart = icaltime_as_timet (*d.value);
- cal_component_free_datetime (&d);
-
- cal_component_get_dtend (comp, &d);
- dtend = icaltime_as_timet (*d.value);
- cal_component_free_datetime (&d);
-
- if (time_day_begin (dtstart) == dtstart
- && time_day_begin (dtend) == dtend)
- dtend = time_add_day (dtend, -1);
+ start_tt = start_date.value;
+ end_tt = end_date.value;
+ if (start_tt->hour == 0 && start_tt->minute == 0 && start_tt->second == 0
+ && end_tt->hour == 0 && end_tt->minute == 0 && end_tt->second == 0)
+ icaltime_adjust (end_tt, 1, 0, 0, 0);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time),
epage);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), dtstart);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), dtend);
+ e_date_edit_set_date (E_DATE_EDIT (priv->start_time), start_tt->year,
+ start_tt->month, start_tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time),
+ start_tt->hour, start_tt->minute);
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->end_time), end_tt->year,
+ end_tt->month, end_tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time),
+ end_tt->hour, end_tt->minute);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
epage);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time),
epage);
+ cal_component_free_datetime (&start_date);
+ cal_component_free_datetime (&end_date);
+
check_all_day (epage);
- /* FIXME: Get the timezones from the event and put them in the
- widgets. Set sync_timezones to TRUE if both timezones are the same.
- */
- priv->sync_timezones = TRUE;
+ /* Set the timezones, and set sync_timezones to TRUE if both timezones
+ are the same. */
+ e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->start_timezone),
+ start_zone);
+ e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->end_timezone),
+ end_zone);
+ priv->sync_timezones = (start_zone == end_zone) ? TRUE : FALSE;
+
/* Classification */
@@ -413,10 +435,10 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp)
EventPagePrivate *priv;
CalComponentDateTime date;
struct icaltimetype icaltime;
- time_t t;
- gboolean all_day_event;
+ gboolean all_day_event, date_set;
char *cat, *str;
CalComponentClassification classif;
+ icaltimezone *zone;
epage = EVENT_PAGE (page);
priv = epage->priv;
@@ -463,28 +485,51 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp)
date.value = &icaltime;
date.tzid = NULL;
- t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_dtstart (comp, &date);
- } else {
- /* FIXME: What do we do here? */
- }
+ icaltime.is_utc = 0;
+ /* FIXME: We should use is_date at some point. */
+ icaltime.is_date = 0;
+ icaltime.is_daylight = 0;
+ icaltime.second = 0;
+
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time),
+ &icaltime.hour,
+ &icaltime.minute);
+ g_assert (date_set);
+ zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone));
+ if (zone)
+ date.tzid = icaltimezone_get_tzid (zone);
+ cal_component_set_dtstart (comp, &date);
/* If the all_day toggle is set, the end date is inclusive of the
entire day on which it points to. */
all_day_event = e_dialog_toggle_get (priv->all_day_event);
- t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- if (t != -1) {
- if (all_day_event)
- t = time_day_end (t);
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_dtend (comp, &date);
- } else {
- /* FIXME: What do we do here? */
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time),
+ &icaltime.hour,
+ &icaltime.minute);
+ g_assert (date_set);
+
+ if (all_day_event) {
+ icaltime.hour = 0;
+ icaltime.minute = 0;
+ icaltime.second = 0;
+ icaltime_adjust (&icaltime, 1, 0, 0, 0);
}
+ zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone));
+ if (zone)
+ date.tzid = icaltimezone_get_tzid (zone);
+ cal_component_set_dtend (comp, &date);
+
+
/* Categories */
cat = e_dialog_editable_get (priv->categories);
@@ -606,9 +651,11 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
{
EventPage *epage;
EventPagePrivate *priv;
- time_t start, end;
- struct tm tm_start, tm_end;
CompEditorPageDates dates;
+ struct icaltimetype start_tt = icaltime_null_time();
+ struct icaltimetype end_tt = icaltime_null_time();
+ int cmp;
+ gboolean date_set;
epage = EVENT_PAGE (data);
priv = epage->priv;
@@ -617,49 +664,67 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
return;
/* Ensure that start < end */
- start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_assert (start != -1);
- end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_assert (end != -1);
-
- if (start >= end) {
- tm_start = *localtime (&start);
- tm_end = *localtime (&end);
-
- if (start == end && tm_start.tm_hour == 0
- && tm_start.tm_min == 0 && tm_start.tm_sec == 0) {
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time),
+ &start_tt.year,
+ &start_tt.month,
+ &start_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time),
+ &start_tt.hour,
+ &start_tt.minute);
+ g_assert (date_set);
+
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time),
+ &end_tt.year,
+ &end_tt.month,
+ &end_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time),
+ &end_tt.hour,
+ &end_tt.minute);
+ g_assert (date_set);
+
+ cmp = icaltime_compare (start_tt, end_tt);
+ if (cmp >= 0) {
+ if (cmp == 0 && start_tt.hour == 0
+ && start_tt.minute == 0
+ && start_tt.second == 0) {
/* If the start and end times are the same, but both
* are on day boundaries, then that is OK since it
* means we have an all-day event lasting 1 day. So
* we do nothing here.
*/
} else if (GTK_WIDGET (dedit) == priv->start_time) {
- /* Modify the end time */
+ /* Modify the end time, to be the start + 1 hour. */
- tm_end.tm_year = tm_start.tm_year;
- tm_end.tm_mon = tm_start.tm_mon;
- tm_end.tm_mday = tm_start.tm_mday;
- tm_end.tm_hour = tm_start.tm_hour + 1;
- tm_end.tm_min = tm_start.tm_min;
- tm_end.tm_sec = tm_start.tm_sec;
+ end_tt = start_tt;
+ icaltime_adjust (&end_tt, 0, 1, 0, 0);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
- end = mktime (&tm_end);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), end);
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->end_time),
+ end_tt.year,
+ end_tt.month,
+ end_tt.day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time),
+ end_tt.hour,
+ end_tt.minute);
+
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage);
} else if (GTK_WIDGET (dedit) == priv->end_time) {
- /* Modify the start time */
+ /* Modify the start time, to be the end - 1 hour. */
- tm_start.tm_year = tm_end.tm_year;
- tm_start.tm_mon = tm_end.tm_mon;
- tm_start.tm_mday = tm_end.tm_mday;
- tm_start.tm_hour = tm_end.tm_hour - 1;
- tm_start.tm_min = tm_end.tm_min;
- tm_start.tm_sec = tm_end.tm_sec;
+ start_tt = end_tt;
+ icaltime_adjust (&start_tt, 0, -1, 0, 0);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage);
- start = mktime (&tm_start);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), start);
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->start_time),
+ start_tt.year,
+ start_tt.month,
+ start_tt.day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time),
+ start_tt.hour,
+ start_tt.minute);
+
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage);
} else
g_assert_not_reached ();
@@ -669,10 +734,10 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
check_all_day (epage);
/* Notify upstream */
- dates.start = start;
- dates.end = end;
- dates.due = 0;
- dates.complete = 0;
+ dates.start = &start_tt;
+ dates.end = &end_tt;
+ dates.due = NULL;
+ dates.complete = NULL;
comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage),
&dates);
}
@@ -686,7 +751,7 @@ start_timezone_changed_cb (GtkWidget *widget, gpointer data)
{
EventPage *epage;
EventPagePrivate *priv;
- char *zone;
+ icaltimezone *zone;
epage = EVENT_PAGE (data);
priv = epage->priv;
@@ -706,7 +771,7 @@ end_timezone_changed_cb (GtkWidget *widget, gpointer data)
{
EventPage *epage;
EventPagePrivate *priv;
- char *start_zone, *end_zone;
+ icaltimezone *start_zone, *end_zone;
epage = EVENT_PAGE (data);
priv = epage->priv;
@@ -714,7 +779,7 @@ end_timezone_changed_cb (GtkWidget *widget, gpointer data)
start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone));
end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone));
- priv->sync_timezones = (strcmp (start_zone, end_zone)) ? FALSE : TRUE;
+ priv->sync_timezones = (start_zone == end_zone) ? TRUE : FALSE;
}
/* Callback: all day event button toggled.
@@ -727,11 +792,12 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
{
EventPage *epage;
EventPagePrivate *priv;
- struct tm start_tm, end_tm;
- time_t start_t, end_t;
gboolean all_day;
CompEditorPageDates dates;
-
+ struct icaltimetype start_tt = icaltime_null_time();
+ struct icaltimetype end_tt = icaltime_null_time();
+ gboolean date_set;
+
epage = EVENT_PAGE (data);
priv = epage->priv;
@@ -755,51 +821,58 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
/*
* Start time.
*/
- start_t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_assert (start_t != -1);
-
- start_tm = *localtime (&start_t);
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time),
+ &start_tt.year,
+ &start_tt.month,
+ &start_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time),
+ &start_tt.hour,
+ &start_tt.minute);
+ g_assert (date_set);
if (all_day) {
/* Round down to the start of the day. */
- start_tm.tm_hour = 0;
- start_tm.tm_min = 0;
- start_tm.tm_sec = 0;
+ start_tt.hour = 0;
+ start_tt.minute = 0;
+ start_tt.second = 0;
} else {
/* Set to the start of the working day. */
- start_tm.tm_hour = calendar_config_get_day_start_hour ();
- start_tm.tm_min = calendar_config_get_day_start_minute ();
- start_tm.tm_sec = 0;
+ start_tt.hour = calendar_config_get_day_start_hour ();
+ start_tt.minute = calendar_config_get_day_start_minute ();
+ start_tt.second = 0;
}
/*
* End time.
*/
- end_t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_assert (end_t != -1);
-
- end_tm = *localtime (&end_t);
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time),
+ &end_tt.year,
+ &end_tt.month,
+ &end_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time),
+ &end_tt.hour,
+ &end_tt.minute);
+ g_assert (date_set);
if (all_day) {
/* Round down to the start of the day. */
- end_tm.tm_hour = 0;
- end_tm.tm_min = 0;
- end_tm.tm_sec = 0;
+ end_tt.hour = 0;
+ end_tt.minute = 0;
+ end_tt.second = 0;
} else {
/* If the event end is now on or before the event start day,
- * make it end one hour after the start. mktime() will fix any
- * overflows.
- */
- if (end_tm.tm_year < start_tm.tm_year
- || (end_tm.tm_year == start_tm.tm_year
- && end_tm.tm_mon < start_tm.tm_mon)
- || (end_tm.tm_year == start_tm.tm_year
- && end_tm.tm_mon == start_tm.tm_mon
- && end_tm.tm_mday <= start_tm.tm_mday)) {
- end_tm.tm_year = start_tm.tm_year;
- end_tm.tm_mon = start_tm.tm_mon;
- end_tm.tm_mday = start_tm.tm_mday;
- end_tm.tm_hour = start_tm.tm_hour + 1;
+ * make it end one hour after the start. */
+ if (end_tt.year < start_tt.year
+ || (end_tt.year == start_tt.year
+ && end_tt.month < start_tt.month)
+ || (end_tt.year == start_tt.year
+ && end_tt.month == start_tt.month
+ && end_tt.day <= start_tt.day)) {
+ end_tt.year = start_tt.year;
+ end_tt.month = start_tt.month;
+ end_tt.day = start_tt.day;
+ end_tt.hour = start_tt.hour;
+ icaltime_adjust (&end_tt, 0, 1, 0, 0);
}
}
@@ -808,10 +881,15 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time),
epage);
- start_t = mktime (&start_tm);
- end_t = mktime (&end_tm);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), start_t);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), end_t);
+ e_date_edit_set_date (E_DATE_EDIT (priv->start_time), start_tt.year,
+ start_tt.month, start_tt.day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time),
+ start_tt.hour, start_tt.minute);
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->end_time), end_tt.year,
+ end_tt.month, end_tt.day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time),
+ end_tt.hour, end_tt.minute);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
epage);
@@ -822,9 +900,10 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day);
/* Notify upstream */
- dates.start = start_t;
- dates.end = end_t;
- dates.due = 0;
+ dates.start = &start_tt;
+ dates.end = &end_tt;
+ dates.due = NULL;
+ dates.complete = NULL;
comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage),
&dates);
}
@@ -868,6 +947,15 @@ init_widgets (EventPage *epage)
priv = epage->priv;
+ /* Make sure the EDateEdit widgets use our timezones to get the
+ current time. */
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_time),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ epage, NULL);
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->end_time),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ epage, NULL);
+
/* Summary */
gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
GTK_SIGNAL_FUNC (summary_changed_cb), epage);
diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c
index 2ef94bafff..566422aa9b 100644
--- a/calendar/gui/dialogs/meeting-page.c
+++ b/calendar/gui/dialogs/meeting-page.c
@@ -41,7 +41,7 @@
#include <widgets/misc/e-dateedit.h>
#include <widgets/meeting-time-sel/e-meeting-time-sel.h>
#include <e-util/e-dialog-widgets.h>
-#include "../Evolution-Addressbook-SelectNames.h"
+#include <addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.h>
#include "comp-editor-util.h"
#include "meeting-page.h"
diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c
index e1656ad83f..4023cd6b5a 100644
--- a/calendar/gui/dialogs/recurrence-page.c
+++ b/calendar/gui/dialogs/recurrence-page.c
@@ -43,6 +43,10 @@
+/* We set this as the TZID on all exceptions added. When we actually fill
+ the component, we replace it with the TZID from DTSTART. */
+static char *DUMMY_TZID = "DUMMY";
+
enum month_day_options {
MONTH_DAY_NTH,
MONTH_DAY_MON,
@@ -287,10 +291,11 @@ free_exception_clist_data (RecurrencePage *rpage)
GtkCList *clist = GTK_CLIST (priv->exception_list);
for (i = 0; i < clist->rows; i++) {
- gpointer data;
+ CalComponentDateTime *dt;
- data = gtk_clist_get_row_data (clist, i);
- g_free (data);
+ dt = gtk_clist_get_row_data (clist, i);
+ g_free (dt->value);
+ g_free (dt);
gtk_clist_set_row_data (clist, i, NULL);
}
@@ -391,42 +396,58 @@ clear_widgets (RecurrencePage *rpage)
/* Builds a static string out of an exception date */
static char *
-get_exception_string (time_t t)
+get_exception_string (CalComponentDateTime *dt)
{
static char buf[256];
+ struct tm tmp_tm;
+
+ tmp_tm.tm_year = dt->value->year - 1900;
+ tmp_tm.tm_mon = dt->value->month - 1;
+ tmp_tm.tm_mday = dt->value->day;
+ tmp_tm.tm_hour = dt->value->hour;
+ tmp_tm.tm_min = dt->value->minute;
+ tmp_tm.tm_sec = dt->value->second;
+ tmp_tm.tm_isdst = -1;
- strftime (buf, sizeof (buf), _("%a %b %d %Y"), localtime (&t));
+ strftime (buf, sizeof (buf), _("%a %b %d %Y"), &tmp_tm);
return buf;
}
/* Appends an exception date to the list */
static void
-append_exception (RecurrencePage *rpage, time_t t)
+append_exception (RecurrencePage *rpage, CalComponentDateTime *datetime)
{
RecurrencePagePrivate *priv;
- time_t *tt;
+ CalComponentDateTime *dt;
char *c[1];
int i;
GtkCList *clist;
+ struct icaltimetype *tt;
priv = rpage->priv;
- tt = g_new (time_t, 1);
- *tt = t;
+ dt = g_new (CalComponentDateTime, 1);
+ dt->value = g_new (struct icaltimetype, 1);
+ *dt->value = *datetime->value;
+ dt->tzid = datetime->tzid;
clist = GTK_CLIST (priv->exception_list);
gtk_signal_handler_block_by_data (GTK_OBJECT (clist), rpage);
- c[0] = get_exception_string (t);
+ c[0] = get_exception_string (dt);
i = gtk_clist_append (clist, c);
- gtk_clist_set_row_data (clist, i, tt);
+ gtk_clist_set_row_data (clist, i, dt);
gtk_clist_select_row (clist, i, 0);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), rpage);
- e_date_edit_set_time (E_DATE_EDIT (priv->exception_date), t);
+ tt = dt->value;
+ e_date_edit_set_date (E_DATE_EDIT (priv->exception_date),
+ tt->year, tt->month, tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->exception_date),
+ tt->hour, tt->minute);
gtk_widget_set_sensitive (priv->exception_modify, TRUE);
gtk_widget_set_sensitive (priv->exception_delete, TRUE);
@@ -448,13 +469,11 @@ fill_exception_widgets (RecurrencePage *rpage, CalComponent *comp)
for (l = list; l; l = l->next) {
CalComponentDateTime *cdt;
- time_t ext;
added = TRUE;
cdt = l->data;
- ext = icaltime_as_timet (*cdt->value);
- append_exception (rpage, ext);
+ append_exception (rpage, cdt);
}
cal_component_free_exdate_list (list);
@@ -475,13 +494,10 @@ get_start_weekday_mask (CalComponent *comp)
cal_component_get_dtstart (comp, &dt);
if (dt.value) {
- time_t t;
- struct tm tm;
-
- t = icaltime_as_timet (*dt.value);
- tm = *localtime (&t);
+ short weekday;
- retval = 0x1 << tm.tm_wday;
+ weekday = icaltime_day_of_week (*dt.value);
+ retval = 0x1 << (weekday - 1);
} else
retval = 0;
@@ -575,6 +591,8 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp)
struct icalrecurrencetype r;
GSList l;
enum ending_type ending_type;
+ gboolean date_set;
+ struct icaltimetype icaltime = icaltime_null_time ();
priv = rpage->priv;
@@ -716,9 +734,21 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp)
g_assert (priv->ending_date_edit != NULL);
g_assert (E_IS_DATE_EDIT (priv->ending_date_edit));
- r.until = icaltime_from_timet (
- e_date_edit_get_time (E_DATE_EDIT (priv->ending_date_edit)),
- TRUE);
+ /* UNTIL must be in UTC, unless it is a date. So we probably
+ want to convert it to local time when showing. */
+ icaltime.is_utc = 0;
+ icaltime.is_date = 1;
+ icaltime.is_daylight = 0;
+
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->ending_date_edit),
+ &r.until.year,
+ &r.until.month,
+ &r.until.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->ending_date_edit),
+ &r.until.hour,
+ &r.until.minute);
+ g_assert (date_set);
+
break;
case ENDING_FOREVER:
@@ -744,9 +774,11 @@ static void
fill_component (RecurrencePage *rpage, CalComponent *comp)
{
RecurrencePagePrivate *priv;
+ CalComponentDateTime start_date;
enum recur_type recur_type;
GtkCList *exception_list;
GSList *list;
+ const char *tzid;
int i;
priv = rpage->priv;
@@ -776,19 +808,31 @@ fill_component (RecurrencePage *rpage, CalComponent *comp)
/* Set exceptions */
+ cal_component_get_dtstart (comp, &start_date);
+ tzid = start_date.tzid;
+ cal_component_free_datetime (&start_date);
+
list = NULL;
exception_list = GTK_CLIST (priv->exception_list);
for (i = 0; i < exception_list->rows; i++) {
- CalComponentDateTime *cdt;
- time_t *tim;
+ CalComponentDateTime *cdt, *dt;
cdt = g_new (CalComponentDateTime, 1);
cdt->value = g_new (struct icaltimetype, 1);
- cdt->tzid = NULL;
- tim = gtk_clist_get_row_data (exception_list, i);
- g_assert (tim != NULL);
- *cdt->value = icaltime_from_timet (*tim, FALSE);
+ dt = gtk_clist_get_row_data (exception_list, i);
+ g_assert (dt != NULL);
+
+ *cdt->value = *dt->value;
+
+ /* If the dummy TZID was used, we use the TZID from the
+ start date. We do this because we don't allow editing
+ of timezones for RDATEs, so we try to use the same timezone
+ as the DTSTART for all new exceptions added. */
+ if (dt->tzid == DUMMY_TZID)
+ cdt->tzid = tzid;
+ else
+ cdt->tzid = dt->tzid;
list = g_slist_prepend (list, cdt);
}
@@ -849,7 +893,8 @@ preview_recur (RecurrencePage *rpage)
fill_component (rpage, comp);
- tag_calendar_by_comp (E_CALENDAR (priv->preview_calendar), comp);
+ tag_calendar_by_comp (E_CALENDAR (priv->preview_calendar), comp,
+ COMP_EDITOR_PAGE (rpage)->client);
gtk_object_unref (GTK_OBJECT (comp));
}
@@ -1294,6 +1339,7 @@ fill_ending_date (RecurrencePage *rpage, struct icalrecurrencetype *r)
} else {
/* Ending date */
+ /* FIXME: UNTIL needs to be checked. */
priv->ending_date = icaltime_as_timet (r->until);
e_dialog_option_menu_set (priv->ending_menu,
ENDING_UNTIL,
@@ -1693,7 +1739,7 @@ recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
- CalComponentDateTime dt;
+ CalComponentDateTime dt, old_dt;
struct icaltimetype icaltime;
guint8 mask;
@@ -1708,13 +1754,32 @@ recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
return;
dt.value = &icaltime;
- dt.tzid = NULL;
- *dt.value = icaltime_from_timet (dates->start, FALSE);
- cal_component_set_dtstart (priv->comp, &dt);
+ if (dates->start) {
+ icaltime = *dates->start;
+
+ /* Copy the TZID from the old property.
+ FIXME: Should get notified when the TZID changes.*/
+ cal_component_get_dtstart (priv->comp, &old_dt);
+ dt.tzid = NULL;
+ if (old_dt.tzid)
+ dt.tzid = old_dt.tzid;
+ cal_component_free_datetime (&old_dt);
+
+ cal_component_set_dtstart (priv->comp, &dt);
+ }
+
+ if (dates->end) {
+ icaltime = *dates->end;
+
+ /* Copy the TZID from the old property.
+ FIXME: Should get notified when the TZID changes.*/
+ cal_component_get_dtend (priv->comp, &old_dt);
+ dt.tzid = NULL;
+ if (old_dt.tzid)
+ dt.tzid = old_dt.tzid;
+ cal_component_free_datetime (&old_dt);
- if (dates->end != 0) {
- *dt.value = icaltime_from_timet (dates->end, FALSE);
cal_component_set_dtend (priv->comp, &dt);
}
@@ -1876,15 +1941,32 @@ exception_add_cb (GtkWidget *widget, gpointer data)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
- time_t t;
+ CalComponentDateTime dt;
+ struct icaltimetype icaltime = icaltime_null_time ();
+ gboolean date_set;
rpage = RECURRENCE_PAGE (data);
priv = rpage->priv;
field_changed (rpage);
- t = e_date_edit_get_time (E_DATE_EDIT (priv->exception_date));
- append_exception (rpage, t);
+ dt.value = &icaltime;
+ /* We set this to the dummy TZID for now. When we fill the component
+ we will replace it with the TZID from DTSTART. */
+ dt.tzid = DUMMY_TZID;
+
+ icaltime.is_date = 1;
+
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->exception_date),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->exception_date),
+ &icaltime.hour,
+ &icaltime.minute);
+ g_assert (date_set);
+
+ append_exception (rpage, &dt);
preview_recur (rpage);
}
@@ -1895,7 +1977,8 @@ exception_modify_cb (GtkWidget *widget, gpointer data)
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
GtkCList *clist;
- time_t *t;
+ CalComponentDateTime *dt;
+ struct icaltimetype *tt;
int sel;
rpage = RECURRENCE_PAGE (data);
@@ -1909,10 +1992,15 @@ exception_modify_cb (GtkWidget *widget, gpointer data)
sel = GPOINTER_TO_INT (clist->selection->data);
- t = gtk_clist_get_row_data (clist, sel);
- *t = e_date_edit_get_time (E_DATE_EDIT (priv->exception_date));
+ dt = gtk_clist_get_row_data (clist, sel);
+ tt = dt->value;
+ e_date_edit_get_date (E_DATE_EDIT (priv->exception_date),
+ &tt->year, &tt->month, &tt->day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->exception_date),
+ &tt->hour, &tt->minute);
+ tt->second = 0;
- gtk_clist_set_text (clist, sel, 0, get_exception_string (*t));
+ gtk_clist_set_text (clist, sel, 0, get_exception_string (dt));
preview_recur (rpage);
}
@@ -1925,7 +2013,7 @@ exception_delete_cb (GtkWidget *widget, gpointer data)
RecurrencePagePrivate *priv;
GtkCList *clist;
int sel;
- time_t *t;
+ CalComponentDateTime *dt;
rpage = RECURRENCE_PAGE (data);
priv = rpage->priv;
@@ -1938,9 +2026,10 @@ exception_delete_cb (GtkWidget *widget, gpointer data)
sel = GPOINTER_TO_INT (clist->selection->data);
- t = gtk_clist_get_row_data (clist, sel);
- g_assert (t != NULL);
- g_free (t);
+ dt = gtk_clist_get_row_data (clist, sel);
+ g_assert (dt != NULL);
+ g_free (dt->value);
+ g_free (dt);
gtk_clist_remove (clist, sel);
if (sel >= clist->rows)
@@ -1966,15 +2055,21 @@ exception_select_row_cb (GtkCList *clist, gint row, gint col,
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
- time_t *t;
+ CalComponentDateTime *dt;
+ struct icaltimetype *t;
rpage = RECURRENCE_PAGE (data);
priv = rpage->priv;
- t = gtk_clist_get_row_data (clist, row);
- g_assert (t != NULL);
+ dt = gtk_clist_get_row_data (clist, row);
+ g_assert (dt != NULL);
- e_date_edit_set_time (E_DATE_EDIT (priv->exception_date), *t);
+ t = dt->value;
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->exception_date),
+ t->year, t->month, t->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->exception_date),
+ t->hour, t->minute);
}
/* This is called when any field is changed; it notifies upstream. */
@@ -2013,6 +2108,18 @@ init_widgets (RecurrencePage *rpage)
priv->preview_calendar);
gtk_widget_show (priv->preview_calendar);
+ /* Make sure the EDateEdit widgets and ECalendarItem use our timezones
+ to get the current time. */
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->exception_date),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ rpage, NULL);
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->ending_date_edit),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ rpage, NULL);
+ e_calendar_item_set_get_time_callback (ecal->calitem,
+ (ECalendarItemGetTimeCallback) comp_editor_get_current_time,
+ rpage, NULL);
+
/* Recurrence types */
gtk_signal_connect (GTK_OBJECT (priv->none), "toggled",
diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c
index 9a1a4b46c6..82d3e14b62 100644
--- a/calendar/gui/dialogs/task-details-page.c
+++ b/calendar/gui/dialogs/task-details-page.c
@@ -32,6 +32,7 @@
#include <gal/widgets/e-unicode.h>
#include <widgets/misc/e-dateedit.h>
#include "e-util/e-dialog-widgets.h"
+#include "../calendar-config.h"
#include "../e-timezone-entry.h"
#include "comp-editor-util.h"
#include "task-details-page.h"
@@ -50,7 +51,6 @@ struct _TaskDetailsPagePrivate {
GtkWidget *date_time;
GtkWidget *completed_date;
- GtkWidget *completed_timezone;
GtkWidget *url;
@@ -149,7 +149,6 @@ task_details_page_init (TaskDetailsPage *tdpage)
priv->summary = NULL;
priv->date_time = NULL;
priv->completed_date = NULL;
- priv->completed_timezone = NULL;
priv->url = NULL;
priv->updating = FALSE;
@@ -277,30 +276,46 @@ task_details_page_fill_component (CompEditorPage *page, CalComponent *comp)
{
TaskDetailsPage *tdpage;
TaskDetailsPagePrivate *priv;
+ struct icaltimetype icaltime;
GSList list;
CalComponentDateTime date;
CalComponentOrganizer organizer;
CalComponentAttendee attendee;
- time_t t;
char *url;
+ gboolean date_set;
tdpage = TASK_DETAILS_PAGE (page);
priv = tdpage->priv;
- /* Completed Date. */
- date.value = g_new (struct icaltimetype, 1);
- date.tzid = NULL;
+ /* COMPLETED must be in UTC. */
+ icaltime.is_utc = 1;
+ icaltime.is_date = 0;
+ icaltime.is_daylight = 0;
- t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_completed (comp, date.value);
+ /* Completed Date. */
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->completed_date),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->completed_date),
+ &icaltime.hour,
+ &icaltime.minute);
+ if (date_set) {
+ /* COMPLETED must be in UTC, so we assume that the date in the
+ dialog is in the current timezone, and we now convert it
+ to UTC. FIXME: We should really use one timezone for the
+ entire time the dialog is shown. Otherwise if the user
+ changes the timezone, the COMPLETED date may get changed
+ as well. */
+ char *location = calendar_config_get_timezone ();
+ icaltimezone *zone = icaltimezone_get_builtin_timezone (location);
+ icaltimezone_convert_time (&icaltime, zone,
+ icaltimezone_get_utc_timezone ());
+ cal_component_set_completed (comp, &icaltime);
} else {
cal_component_set_completed (comp, NULL);
}
- g_free (date.value);
-
/* URL. */
url = e_dialog_editable_get (priv->url);
cal_component_set_url (comp, url);
@@ -359,9 +374,30 @@ task_details_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
priv = tdpage->priv;
comp_editor_date_label (dates, priv->date_time);
- if (dates->complete != 0)
- e_date_edit_set_time (E_DATE_EDIT (priv->completed_date),
- dates->complete);
+
+ if (dates->complete) {
+ if (icaltime_is_null_time (*dates->complete)) {
+ e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), -1);
+ } else {
+ struct icaltimetype *tt = dates->complete;
+
+ /* Convert it from UTC to local time to display.
+ FIXME: We should really use one timezone for the
+ entire time the dialog is shown. Otherwise if the
+ user changes the timezone, the COMPLETED date may
+ get changed as well. */
+ char *location = calendar_config_get_timezone ();
+ icaltimezone *zone = icaltimezone_get_builtin_timezone (location);
+ icaltimezone_convert_time (tt,
+ icaltimezone_get_utc_timezone (),
+ zone);
+
+ e_date_edit_set_date (E_DATE_EDIT (priv->completed_date),
+ tt->year, tt->month, tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->completed_date),
+ tt->hour, tt->minute);
+ }
+ }
}
@@ -387,7 +423,6 @@ get_widgets (TaskDetailsPage *tdpage)
priv->date_time = GW ("date-time");
priv->completed_date = GW ("completed-date");
- priv->completed_timezone = GW ("completed-timezone");
priv->url = GW ("url");
@@ -403,7 +438,6 @@ get_widgets (TaskDetailsPage *tdpage)
return (priv->summary
&& priv->date_time
&& priv->completed_date
- && priv->completed_timezone
&& priv->url
&& priv->organizer
&& priv->organizer_lbl
@@ -422,6 +456,8 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
TaskDetailsPage *tdpage;
TaskDetailsPagePrivate *priv;
CompEditorPageDates dates;
+ struct icaltimetype completed_tt = icaltime_null_time();
+ gboolean date_set;
tdpage = TASK_DETAILS_PAGE (data);
priv = tdpage->priv;
@@ -429,10 +465,20 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
if (priv->updating)
return;
- dates.start = 0;
- dates.end = 0;
- dates.due = 0;
- dates.complete = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->completed_date),
+ &completed_tt.year,
+ &completed_tt.month,
+ &completed_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->completed_date),
+ &completed_tt.hour,
+ &completed_tt.minute);
+ if (!date_set)
+ completed_tt = icaltime_null_time ();
+
+ dates.start = NULL;
+ dates.end = NULL;
+ dates.due = NULL;
+ dates.complete = &completed_tt;
/* Notify upstream */
comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tdpage), &dates);
@@ -460,13 +506,16 @@ init_widgets (TaskDetailsPage *tdpage)
priv = tdpage->priv;
+ /* Make sure the EDateEdit widgets use our timezones to get the
+ current time. */
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->completed_date),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ tdpage, NULL);
+
/* Completed Date */
gtk_signal_connect (GTK_OBJECT (priv->completed_date), "changed",
GTK_SIGNAL_FUNC (date_changed_cb), tdpage);
- gtk_signal_connect (GTK_OBJECT (priv->completed_timezone), "changed",
- GTK_SIGNAL_FUNC (field_changed_cb), tdpage);
-
/* URL */
gtk_signal_connect (GTK_OBJECT (priv->url), "changed",
GTK_SIGNAL_FUNC (field_changed_cb), tdpage);
diff --git a/calendar/gui/dialogs/task-details-page.glade b/calendar/gui/dialogs/task-details-page.glade
index 962906ebb4..c92bd52b8f 100644
--- a/calendar/gui/dialogs/task-details-page.glade
+++ b/calendar/gui/dialogs/task-details-page.glade
@@ -403,10 +403,12 @@
</widget>
<widget>
- <class>GtkHBox</class>
- <name>hbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
+ <class>Custom</class>
+ <name>completed-date</name>
+ <creation_function>task_details_page_create_date_edit</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Fri, 01 Jun 2001 18:58:51 GMT</last_modification_time>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
@@ -421,34 +423,6 @@
<xfill>True</xfill>
<yfill>True</yfill>
</child>
-
- <widget>
- <class>Custom</class>
- <name>completed-date</name>
- <creation_function>task_details_page_create_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 01 Jun 2001 18:58:51 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>completed-timezone</name>
- <creation_function>make_timezone_entry</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 19 Jun 2001 04:32:42 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
</widget>
</widget>
</widget>
diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c
index 705477f794..2fc7bbf23e 100644
--- a/calendar/gui/dialogs/task-page.c
+++ b/calendar/gui/dialogs/task-page.c
@@ -254,19 +254,16 @@ static void
clear_widgets (TaskPage *tpage)
{
TaskPagePrivate *priv;
- time_t now;
priv = tpage->priv;
- now = time (NULL);
-
/* Summary, description */
e_dialog_editable_set (priv->summary, NULL);
e_dialog_editable_set (priv->description, NULL);
/* Start, due times */
- e_date_edit_set_time (E_DATE_EDIT (priv->start_date), now);
- e_date_edit_set_time (E_DATE_EDIT (priv->due_date), now);
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_date), 0);
+ e_date_edit_set_time (E_DATE_EDIT (priv->due_date), 0);
/* Classification */
e_dialog_radio_set (priv->classification_public,
@@ -341,12 +338,13 @@ task_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
CalComponentText text;
CalComponentDateTime d;
CalComponentClassification cl;
+ CalClientGetStatus get_tz_status;
GSList *l;
- time_t t;
int *priority_value, *percent;
icalproperty_status status;
TaskEditorPriority priority;
const char *categories;
+ icaltimezone *zone;
tpage = TASK_PAGE (page);
priv = tpage->priv;
@@ -372,20 +370,50 @@ task_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
/* Due Date. */
cal_component_get_due (comp, &d);
if (d.value) {
- t = icaltime_as_timet (*d.value);
+ struct icaltimetype *due_tt = d.value;
+ e_date_edit_set_date (E_DATE_EDIT (priv->due_date),
+ due_tt->year, due_tt->month,
+ due_tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->due_date),
+ due_tt->hour, due_tt->minute);
} else {
- t = -1;
+ e_date_edit_set_time (E_DATE_EDIT (priv->due_date), -1);
}
- e_date_edit_set_time (E_DATE_EDIT (priv->due_date), t);
+
+ get_tz_status = cal_client_get_timezone (page->client, d.tzid, &zone);
+ /* FIXME: Handle error better. */
+ if (get_tz_status != CAL_CLIENT_GET_SUCCESS)
+ g_warning ("Couldn't get timezone from server: %s",
+ d.tzid ? d.tzid : "");
+ e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->due_timezone),
+ zone);
+
+ cal_component_free_datetime (&d);
+
/* Start Date. */
cal_component_get_dtstart (comp, &d);
if (d.value) {
- t = icaltime_as_timet (*d.value);
+ struct icaltimetype *start_tt = d.value;
+ e_date_edit_set_date (E_DATE_EDIT (priv->start_date),
+ start_tt->year, start_tt->month,
+ start_tt->day);
+ e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_date),
+ start_tt->hour, start_tt->minute);
} else {
- t = -1;
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_date), -1);
}
- e_date_edit_set_time (E_DATE_EDIT (priv->start_date), t);
+
+ get_tz_status = cal_client_get_timezone (page->client, d.tzid, &zone);
+ /* FIXME: Handle error better. */
+ if (get_tz_status != CAL_CLIENT_GET_SUCCESS)
+ g_warning ("Couldn't get timezone from server: %s",
+ d.tzid ? d.tzid : "");
+ e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->start_timezone),
+ zone);
+
+ cal_component_free_datetime (&d);
+
/* Percent Complete. */
cal_component_get_percent (comp, &percent);
@@ -460,12 +488,14 @@ task_page_fill_component (CompEditorPage *page, CalComponent *comp)
TaskPage *tpage;
TaskPagePrivate *priv;
CalComponentDateTime date;
- time_t t;
+ struct icaltimetype icaltime;
icalproperty_status status;
TaskEditorPriority priority;
int priority_value, percent;
char *cat;
char *str;
+ gboolean date_set;
+ icaltimezone *zone;
tpage = TASK_PAGE (page);
priv = tpage->priv;
@@ -509,22 +539,44 @@ task_page_fill_component (CompEditorPage *page, CalComponent *comp)
/* Dates */
- date.value = g_new (struct icaltimetype, 1);
+ date.value = &icaltime;
date.tzid = NULL;
+ icaltime.is_utc = 0;
+ /* FIXME: We should use is_date at some point. */
+ icaltime.is_date = 0;
+ icaltime.is_daylight = 0;
+ icaltime.second = 0;
+
/* Due Date. */
- t = e_date_edit_get_time (E_DATE_EDIT (priv->due_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->due_date),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->due_date),
+ &icaltime.hour,
+ &icaltime.minute);
+ if (date_set) {
+ zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->due_timezone));
+ if (zone)
+ date.tzid = icaltimezone_get_tzid (zone);
cal_component_set_due (comp, &date);
} else {
cal_component_set_due (comp, NULL);
}
/* Start Date. */
- t = e_date_edit_get_time (E_DATE_EDIT (priv->start_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_date),
+ &icaltime.year,
+ &icaltime.month,
+ &icaltime.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_date),
+ &icaltime.hour,
+ &icaltime.minute);
+ if (date_set) {
+ zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone));
+ if (zone)
+ date.tzid = icaltimezone_get_tzid (zone);
cal_component_set_dtstart (comp, &date);
} else {
cal_component_set_dtstart (comp, NULL);
@@ -583,8 +635,8 @@ task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
priv->updating = TRUE;
- if (dates->complete != 0) {
- if (dates->complete == -1) {
+ if (dates->complete) {
+ if (icaltime_is_null_time (*dates->complete)) {
/* If the 'Completed Date' is set to 'None',
we set the status to 'Not Started' and the
percent-complete to 0. The task may
@@ -698,6 +750,9 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
TaskPage *tpage;
TaskPagePrivate *priv;
CompEditorPageDates dates;
+ gboolean date_set;
+ struct icaltimetype start_tt = icaltime_null_time();
+ struct icaltimetype due_tt = icaltime_null_time();
tpage = TASK_PAGE (data);
priv = tpage->priv;
@@ -705,10 +760,30 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
if (priv->updating)
return;
- dates.start = e_date_edit_get_time (E_DATE_EDIT (priv->start_date));
- dates.end = 0;
- dates.due = e_date_edit_get_time (E_DATE_EDIT (priv->due_date));
- dates.complete = 0;
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_date),
+ &start_tt.year,
+ &start_tt.month,
+ &start_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_date),
+ &start_tt.hour,
+ &start_tt.minute);
+ if (!date_set)
+ start_tt = icaltime_null_time ();
+
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->due_date),
+ &due_tt.year,
+ &due_tt.month,
+ &due_tt.day);
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->due_date),
+ &due_tt.hour,
+ &due_tt.minute);
+ if (!date_set)
+ due_tt = icaltime_null_time ();
+
+ dates.start = &start_tt;
+ dates.end = NULL;
+ dates.due = &due_tt;
+ dates.complete = NULL;
/* Notify upstream */
comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tpage),
@@ -747,17 +822,24 @@ field_changed_cb (GtkWidget *widget, gpointer data)
}
static void
-complete_date_changed (TaskPage *tpage, time_t complete)
+complete_date_changed (TaskPage *tpage, gboolean complete)
{
TaskPagePrivate *priv;
CompEditorPageDates dates;
+ icaltimezone *zone;
+ struct icaltimetype completed_tt = icaltime_null_time();
priv = tpage->priv;
- dates.start = 0;
- dates.end = 0;
- dates.due = 0;
- dates.complete = complete;
+ /* Get the current time in UTC. */
+ zone = icaltimezone_get_utc_timezone ();
+ completed_tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+ completed_tt.is_utc = TRUE;
+
+ dates.start = NULL;
+ dates.end = NULL;
+ dates.due = NULL;
+ dates.complete = &completed_tt;
/* Notify upstream */
comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tpage),
@@ -780,13 +862,13 @@ status_changed (GtkMenu *menu, TaskPage *tpage)
status = e_dialog_option_menu_get (priv->status, status_map);
if (status == ICAL_STATUS_NEEDSACTION) {
e_dialog_spin_set (priv->percent_complete, 0);
- complete_date_changed (tpage, -1);
+ complete_date_changed (tpage, FALSE);
} else if (status == ICAL_STATUS_INPROCESS) {
e_dialog_spin_set (priv->percent_complete, 50);
- complete_date_changed (tpage, -1);
+ complete_date_changed (tpage, FALSE);
} else if (status == ICAL_STATUS_COMPLETED) {
e_dialog_spin_set (priv->percent_complete, 100);
- complete_date_changed (tpage, time (NULL) - (time (NULL) % 60));
+ complete_date_changed (tpage, TRUE);
}
priv->updating = FALSE;
@@ -800,7 +882,7 @@ percent_complete_changed (GtkAdjustment *adj, TaskPage *tpage)
TaskPagePrivate *priv;
gint percent;
icalproperty_status status;
- time_t date_completed;
+ gboolean complete;
priv = tpage->priv;
@@ -811,10 +893,10 @@ percent_complete_changed (GtkAdjustment *adj, TaskPage *tpage)
percent = e_dialog_spin_get_int (priv->percent_complete);
if (percent == 100) {
- date_completed = time (NULL);
+ complete = TRUE;
status = ICAL_STATUS_COMPLETED;
} else {
- date_completed = -1;
+ complete = FALSE;
if (percent == 0)
status = ICAL_STATUS_NEEDSACTION;
@@ -823,7 +905,7 @@ percent_complete_changed (GtkAdjustment *adj, TaskPage *tpage)
}
e_dialog_option_menu_set (priv->status, status, status_map);
- complete_date_changed (tpage, date_completed);
+ complete_date_changed (tpage, complete);
priv->updating = FALSE;
@@ -839,6 +921,14 @@ init_widgets (TaskPage *tpage)
priv = tpage->priv;
+ /* Make sure the EDateEdit widgets use our timezones to get the
+ current time. */
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_date),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ tpage, NULL);
+ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->due_date),
+ (EDateEditGetTimeCallback) comp_editor_get_current_time,
+ tpage, NULL);
/* Summary */
gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 931c721dd4..9f5726b01e 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -40,6 +40,7 @@
#include <gal/e-table/e-cell-combo.h>
#include <widgets/misc/e-cell-date-edit.h>
#include "e-calendar-table.h"
+#include "calendar-config.h"
#include "calendar-model.h"
#include "dialogs/delete-comp.h"
#include "dialogs/task-editor.h"
@@ -107,6 +108,8 @@ static void selection_get (GtkWidget *invisible,
ECalendarTable *cal_table);
static void invisible_destroyed (GtkWidget *invisible,
ECalendarTable *cal_table);
+static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde,
+ gpointer data);
/* The icons to represent the task. */
@@ -396,6 +399,10 @@ e_calendar_table_init (ECalendarTable *cal_table)
e_table_extras_add_cell (extras, "dateedit", popup_cell);
cal_table->dates_cell = E_CELL_DATE_EDIT (popup_cell);
+ e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell),
+ e_calendar_table_get_current_time,
+ cal_table, NULL);
+
/*
* Combo fields.
@@ -1281,3 +1288,33 @@ selection_received (GtkWidget *invisible,
gtk_object_unref (GTK_OBJECT (comp));
}
}
+
+
+/* Returns the current time, for the ECellDateEdit items.
+ FIXME: Should probably use the timezone of the item rather than the
+ current timezone, though that may be difficult to get from here. */
+static struct tm
+e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data)
+{
+ char *location;
+ icaltimezone *zone;
+ struct tm tmp_tm = { 0 };
+ struct icaltimetype tt;
+
+ /* Get the current timezone. */
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ 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;
+
+ return tmp_tm;
+}
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index 661f62b702..cc6224987a 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -192,7 +192,8 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
gint work_day_start_y, work_day_end_y;
gint day_x, day_w, work_day;
gint start_row, end_row, rect_x, rect_y, rect_width, rect_height;
- struct tm *day_start;
+ struct icaltimetype day_start_tt;
+ gint weekday;
#if 0
g_print ("In e_day_view_main_item_draw %i,%i %ix%i\n",
@@ -213,9 +214,10 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
work_day_end_y = work_day_end_row * day_view->row_height - y;
for (day = 0; day < day_view->days_shown; day++) {
- day_start = localtime (&day_view->day_starts[day]);
-
- work_day = day_view->working_days & (1 << day_start->tm_wday);
+ day_start_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, day_view->zone);
+ weekday = icaltime_day_of_week (day_start_tt) - 1;
+
+ work_day = day_view->working_days & (1 << weekday);
day_x = day_view->day_offsets[day] - x;
day_w = day_view->day_widths[day];
diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c
index 7f2e8663af..62e58f7ec5 100644
--- a/calendar/gui/e-day-view-top-item.c
+++ b/calendar/gui/e-day-view-top-item.c
@@ -192,7 +192,8 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item,
GdkFont *font;
gint canvas_width, canvas_height, left_edge, day, date_width, date_x;
gint item_height, event_num;
- struct tm *day_start;
+ struct tm day_start = { 0 };
+ struct icaltimetype day_start_tt;
#if 0
g_print ("In e_day_view_top_item_draw %i,%i %ix%i\n",
@@ -267,7 +268,11 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item,
/* Draw the date. Set a clipping rectangle so we don't draw over the
next day. */
for (day = 0; day < day_view->days_shown; day++) {
- day_start = localtime (&day_view->day_starts[day]);
+ day_start_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, day_view->zone);
+ day_start.tm_year = day_start_tt.year - 1900;
+ day_start.tm_mon = day_start_tt.month - 1;
+ day_start.tm_mday = day_start_tt.day;
+ day_start.tm_isdst = -1;
if (day_view->date_format == E_DAY_VIEW_DATE_FULL)
/* strftime format %A = full weekday name, %d = day of month,
@@ -284,7 +289,7 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item,
else
format = "%d";
- strftime (buffer, sizeof (buffer), format, day_start);
+ strftime (buffer, sizeof (buffer), format, &day_start);
clip_rect.x = day_view->day_offsets[day] - x;
clip_rect.y = 2 - y;
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 38623cdc6d..0cf6704798 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -511,6 +511,8 @@ e_day_view_init (EDayView *day_view)
day_view->work_week_view = FALSE;
day_view->days_shown = 1;
+ day_view->zone = NULL;
+
day_view->mins_per_row = 30;
day_view->date_format = E_DAY_VIEW_DATE_FULL;
day_view->rows_in_top_display = 0;
@@ -1483,8 +1485,8 @@ query_obj_updated_cb (CalQuery *query, const char *uid,
/* Add the occurrences of the event. */
cal_recur_generate_instances (comp, day_view->lower,
day_view->upper,
- e_day_view_add_event,
- day_view);
+ e_day_view_add_event, day_view,
+ cal_client_resolve_tzid, day_view->client);
gtk_object_unref (GTK_OBJECT (comp));
e_day_view_check_layout (day_view);
@@ -2496,6 +2498,48 @@ e_day_view_set_show_event_end_times (EDayView *day_view,
}
+/* The current timezone. */
+icaltimezone*
+e_day_view_get_timezone (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL);
+
+ return day_view->zone;
+}
+
+
+void
+e_day_view_set_timezone (EDayView *day_view,
+ icaltimezone *zone)
+{
+ icaltimezone *old_zone;
+ struct icaltimetype tt;
+ time_t lower;
+
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ old_zone = day_view->zone;
+ if (old_zone == zone)
+ return;
+
+ day_view->zone = zone;
+
+ /* If our time hasn't been set yet, just return. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return;
+
+ /* Recalculate the new start of the first day. We just use exactly
+ the same time, but with the new timezone. */
+ tt = icaltime_from_timet_with_zone (day_view->lower, FALSE,
+ old_zone);
+
+ lower = icaltime_as_timet_with_zone (tt, zone);
+
+ e_day_view_recalc_day_starts (day_view, lower);
+ update_query (day_view);
+}
+
+
/* This is a callback used to update all day event labels. */
static gboolean
e_day_view_set_show_times_cb (EDayView *day_view,
@@ -3413,7 +3457,7 @@ e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data)
/* We must duplicate the CalComponent, or we won't know it has changed
when we get the "update_event" callback. */
comp = cal_component_clone (event->comp);
- cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, FALSE));
+ cal_comp_util_add_exdate (comp, event->start, day_view->zone);
if (!cal_client_update_object (day_view->client, comp))
g_message ("e_day_view_on_delete_occurrence(): Could not update the object!");
@@ -3525,7 +3569,7 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
instance. */
comp = cal_component_clone (event->comp);
- cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, FALSE));
+ cal_comp_util_add_exdate (comp, event->start, day_view->zone);
/* For the unrecurred instance we duplicate the original object,
create a new uid for it, get rid of the recurrence rules, and set
@@ -3538,13 +3582,16 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
cal_component_set_exrule_list (new_comp, NULL);
date.value = &itt;
- date.tzid = NULL;
+ date.tzid = icaltimezone_get_tzid (day_view->zone);
- *date.value = icaltime_from_timet (event->start, FALSE);
+ *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
+ day_view->zone);
cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet (event->end, FALSE);
+ *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
+ day_view->zone);
cal_component_set_dtend (new_comp, &date);
+
/* Now update both CalComponents. Note that we do this last since at
* present the updates happen synchronously so our event may disappear.
*/
@@ -4064,15 +4111,19 @@ e_day_view_finish_long_event_resize (EDayView *day_view)
comp = cal_component_clone (event->comp);
date.value = &itt;
- date.tzid = NULL;
+ /* FIXME: Should probably keep the timezone of the original start
+ and end times. */
+ date.tzid = icaltimezone_get_tzid (day_view->zone);
if (day_view->resize_drag_pos == E_DAY_VIEW_POS_LEFT_EDGE) {
dt = day_view->day_starts[day_view->resize_start_row];
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtstart (comp, &date);
} else {
dt = day_view->day_starts[day_view->resize_end_row + 1];
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtend (comp, &date);
}
@@ -4110,15 +4161,19 @@ e_day_view_finish_resize (EDayView *day_view)
comp = cal_component_clone (event->comp);
date.value = &itt;
- date.tzid = NULL;
+ /* FIXME: Should probably keep the timezone of the original start
+ and end times. */
+ date.tzid = icaltimezone_get_tzid (day_view->zone);
if (day_view->resize_drag_pos == E_DAY_VIEW_POS_TOP_EDGE) {
dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_start_row);
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtstart (comp, &date);
} else {
dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_end_row + 1);
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtend (comp, &date);
}
@@ -4226,7 +4281,7 @@ e_day_view_add_event (CalComponent *comp,
EDayView *day_view;
EDayViewEvent event;
gint day, offset;
- struct tm start_tm, end_tm;
+ struct icaltimetype start_tt, end_tt;
day_view = E_DAY_VIEW (data);
@@ -4242,8 +4297,10 @@ e_day_view_add_event (CalComponent *comp,
g_return_val_if_fail (start < day_view->upper, TRUE);
g_return_val_if_fail (end > day_view->lower, TRUE);
- start_tm = *(localtime (&start));
- end_tm = *(localtime (&end));
+ start_tt = icaltime_from_timet_with_zone (start, FALSE,
+ day_view->zone);
+ end_tt = icaltime_from_timet_with_zone (end, FALSE,
+ day_view->zone);
event.comp = comp;
gtk_object_ref (GTK_OBJECT (comp));
@@ -4255,8 +4312,8 @@ e_day_view_add_event (CalComponent *comp,
display. */
offset = day_view->first_hour_shown * 60
+ day_view->first_minute_shown;
- event.start_minute = start_tm.tm_hour * 60 + start_tm.tm_min - offset;
- event.end_minute = end_tm.tm_hour * 60 + end_tm.tm_min - offset;
+ event.start_minute = start_tt.hour * 60 + start_tt.minute - offset;
+ event.end_minute = end_tt.hour * 60 + end_tt.minute - offset;
event.start_row_or_col = -1;
event.num_columns = -1;
@@ -4836,12 +4893,14 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event)
e_day_view_get_selected_time_range (day_view, &dtstart, &dtend);
dt.value = &itt;
- dt.tzid = NULL;
+ dt.tzid = icaltimezone_get_tzid (day_view->zone);
- *dt.value = icaltime_from_timet (dtstart, FALSE);
+ *dt.value = icaltime_from_timet_with_zone (dtstart, FALSE,
+ day_view->zone);
cal_component_set_dtstart (comp, &dt);
- *dt.value = icaltime_from_timet (dtend, FALSE);
+ *dt.value = icaltime_from_timet_with_zone (dtend, FALSE,
+ day_view->zone);
cal_component_set_dtend (comp, &dt);
/* We add the event locally and start editing it. When we get the
@@ -5383,7 +5442,7 @@ e_day_view_convert_grid_position_to_time (EDayView *day_view,
gint col,
gint row)
{
- struct tm *tmp_tm;
+ struct icaltimetype tt;
time_t val;
gint minutes;
@@ -5397,15 +5456,15 @@ e_day_view_convert_grid_position_to_time (EDayView *day_view,
if (minutes == 60 * 24)
return day_view->day_starts[col + 1];
- /* We convert the start of the day to a struct tm, then set the
- hour and minute, then convert it back to a time_t. */
- tmp_tm = localtime (&day_view->day_starts[col]);
+ /* Create an icaltimetype and convert to a time_t. */
+ tt = icaltime_from_timet_with_zone (day_view->day_starts[col],
+ FALSE, day_view->zone);
+ tt.hour = minutes / 60;
+ tt.minute = minutes % 60;
+ tt.second = 0;
+ tt.is_daylight = -1;
- tmp_tm->tm_hour = minutes / 60;
- tmp_tm->tm_min = minutes % 60;
- tmp_tm->tm_isdst = -1;
-
- val = mktime (tmp_tm);
+ val = icaltime_as_timet_with_zone (tt, day_view->zone);
return val;
}
@@ -5416,7 +5475,7 @@ e_day_view_convert_time_to_grid_position (EDayView *day_view,
gint *col,
gint *row)
{
- struct tm *tmp_tm;
+ struct icaltimetype tt;
gint day, minutes;
*col = *row = 0;
@@ -5432,11 +5491,12 @@ e_day_view_convert_time_to_grid_position (EDayView *day_view,
}
}
- /* To find the row we need to convert the time to a struct tm,
+ /* To find the row we need to convert the time to an icaltimetype,
calculate the offset in minutes from the top of the display and
divide it by the mins per row setting. */
- tmp_tm = localtime (&time);
- minutes = tmp_tm->tm_hour * 60 + tmp_tm->tm_min;
+ tt = icaltime_from_timet_with_zone (time, FALSE, day_view->zone);
+
+ minutes = tt.hour * 60 + tt.minute;
minutes -= day_view->first_hour_shown * 60
+ day_view->first_minute_shown;
@@ -6354,16 +6414,20 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget,
comp = cal_component_clone (event->comp);
date.value = &itt;
- date.tzid = NULL;
+ /* FIXME: Should probably keep the timezone of the
+ original start and end times. */
+ date.tzid = icaltimezone_get_tzid (day_view->zone);
dt = day_view->day_starts[day] + start_offset * 60;
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtstart (comp, &date);
if (end_offset == -1 || end_offset == 0)
dt = day_view->day_starts[day + num_days];
else
dt = day_view->day_starts[day + num_days - 1] + end_offset * 60;
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtend (comp, &date);
gtk_drag_finish (context, TRUE, TRUE, time);
@@ -6458,13 +6522,15 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget,
comp = cal_component_clone (event->comp);
date.value = &itt;
- date.tzid = NULL;
+ date.tzid = icaltimezone_get_tzid (day_view->zone);
dt = e_day_view_convert_grid_position_to_time (day_view, day, row) + start_offset * 60;
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtstart (comp, &date);
dt = e_day_view_convert_grid_position_to_time (day_view, day, row + num_rows) - end_offset * 60;
- *date.value = icaltime_from_timet (dt, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dt, FALSE,
+ day_view->zone);
cal_component_set_dtend (comp, &date);
gtk_drag_finish (context, TRUE, TRUE, time);
@@ -6595,10 +6661,14 @@ selection_received (GtkWidget *invisible,
if (icalcomp) {
e_day_view_get_selected_time_range (day_view, &dtstart, &dtend);
- itime = icaltime_from_timet (dtstart, FALSE);
+ itime = icaltime_from_timet_with_zone (dtstart, FALSE,
+ day_view->zone);
+ /* FIXME: Need to set TZID. */
icalcomponent_set_dtstart (icalcomp, itime);
- itime = icaltime_from_timet (dtend, FALSE);
+ itime = icaltime_from_timet_with_zone (dtend, FALSE,
+ day_view->zone);
+ /* FIXME: Need to set TZID. */
icalcomponent_set_dtend (icalcomp, itime);
comp = cal_component_new ();
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 2d3f5104fb..94354244ba 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -254,6 +254,8 @@ struct _EDayView
/* The start of each day & an extra element to hold the last time. */
time_t day_starts[E_DAY_VIEW_MAX_DAYS + 1];
+ /* The timezone. */
+ icaltimezone *zone;
/* An array of EDayViewEvent elements for the top view and each day. */
GArray *long_events;
@@ -561,6 +563,12 @@ gint e_day_view_get_week_start_day (EDayView *day_view);
void e_day_view_set_week_start_day (EDayView *day_view,
gint week_start_day);
+/* The current timezone. */
+icaltimezone* e_day_view_get_timezone (EDayView *day_view);
+void e_day_view_set_timezone (EDayView *day_view,
+ icaltimezone *zone);
+
+
/* Clipboard-related functions */
void e_day_view_cut_clipboard (EDayView *day_view);
void e_day_view_copy_clipboard (EDayView *day_view);
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index 24717b0aa7..3d82632adc 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -502,6 +502,7 @@ write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
struct tm *tmp_tm;
int len;
+ /* FIXME: Convert to an appropriate timezone. */
tmp_tm = localtime (&t);
if (stext != NULL)
strcat (buffer, stext);
@@ -522,6 +523,7 @@ set_date_label (GtkWidget *lbl, CalComponent *comp)
time_t start = 0, end = 0, complete = 0, due = 0;
static char buffer[1024];
+ /* FIXME: timezones. */
cal_component_get_dtstart (comp, &datetime);
if (datetime.value)
start = icaltime_as_timet (*datetime.value);
@@ -905,6 +907,7 @@ send_freebusy (EItipControl *itip)
priv = itip->priv;
+ /* FIXME: timezones. */
cal_component_get_dtstart (priv->comp, &datetime);
start = icaltime_as_timet (*datetime.value);
cal_component_get_dtend (priv->comp, &datetime);
diff --git a/calendar/gui/e-timezone-entry.c b/calendar/gui/e-timezone-entry.c
index ff54a92da4..e7e64f0934 100644
--- a/calendar/gui/e-timezone-entry.c
+++ b/calendar/gui/e-timezone-entry.c
@@ -40,6 +40,17 @@
struct _ETimezoneEntryPrivate {
+ /* This is the timezone set in e_timezone_entry_set_timezone().
+ Note that we don't copy it or use a ref count - we assume it is
+ never destroyed for the lifetime of this widget. */
+ icaltimezone *zone;
+
+ /* This is TRUE if the timezone has been changed since being set.
+ If it hasn't, we can just return zone, If it has, we return the
+ builtin timezone with tzid. (It can only be changed to a builtin
+ timezone, or to 'local time', i.e. no timezone.) */
+ gboolean changed;
+
GtkWidget *entry;
GtkWidget *button;
};
@@ -60,6 +71,8 @@ static void on_entry_changed (GtkEntry *entry,
static void on_button_clicked (GtkWidget *widget,
ETimezoneEntry *tentry);
+static char* e_timezone_entry_get_display_name (icaltimezone *zone);
+
static GtkHBoxClass *parent_class;
static guint timezone_entry_signals[LAST_SIGNAL] = { 0 };
@@ -127,6 +140,9 @@ e_timezone_entry_init (ETimezoneEntry *tentry)
tentry->priv = priv = g_new0 (ETimezoneEntryPrivate, 1);
+ priv->zone = NULL;
+ priv->changed = FALSE;
+
priv->entry = gtk_entry_new ();
gtk_entry_set_editable (GTK_ENTRY (priv->entry), FALSE);
/*gtk_widget_set_usize (priv->date_entry, 90, 0);*/
@@ -190,19 +206,33 @@ on_button_clicked (GtkWidget *widget,
ETimezoneEntryPrivate *priv;
ETimezoneDialog *timezone_dialog;
GtkWidget *dialog;
- char *zone;
+ char *tzid = NULL, *display_name, *old_display_name;
priv = tentry->priv;
+ display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry));
+
+ if (priv->zone)
+ tzid = icaltimezone_get_tzid (priv->zone);
+
timezone_dialog = e_timezone_dialog_new ();
- zone = e_timezone_entry_get_timezone (tentry);
- e_timezone_dialog_set_timezone (timezone_dialog, zone);
+ e_timezone_dialog_set_timezone (timezone_dialog, tzid, display_name);
dialog = e_timezone_dialog_get_toplevel (timezone_dialog);
if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0) {
- zone = e_timezone_dialog_get_timezone (E_TIMEZONE_DIALOG (timezone_dialog));
- e_timezone_entry_set_timezone (tentry, zone);
+ tzid = e_timezone_dialog_get_timezone (E_TIMEZONE_DIALOG (timezone_dialog), &display_name);
+ old_display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry));
+ /* See if the timezone has been changed. It can only have been
+ changed to a builtin timezone, in which case the returned
+ TZID will be NULL. */
+ if (strcmp (old_display_name, display_name)
+ || (!tzid && priv->zone)) {
+ priv->changed = TRUE;
+ priv->zone = NULL;
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), display_name);
}
gtk_object_unref (GTK_OBJECT (timezone_dialog));
@@ -217,20 +247,62 @@ on_entry_changed (GtkEntry *entry,
}
-char*
+icaltimezone*
e_timezone_entry_get_timezone (ETimezoneEntry *tentry)
{
+ ETimezoneEntryPrivate *priv;
+ char *display_name;
+
g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (tentry), NULL);
- return gtk_entry_get_text (GTK_ENTRY (tentry->priv->entry));
+ priv = tentry->priv;
+
+ /* If the timezone hasn't been change, we can just return the same
+ zone we were passed in. */
+ if (!priv->changed)
+ return priv->zone;
+
+ /* If the timezone has changed, it can only have been changed to a
+ builtin timezone or 'local time' (i.e. no timezone). */
+ display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry));
+
+ if (display_name && display_name[0])
+ return icaltimezone_get_builtin_timezone (display_name);
+ return NULL;
}
void
e_timezone_entry_set_timezone (ETimezoneEntry *tentry,
- char *timezone)
+ icaltimezone *zone)
{
+ ETimezoneEntryPrivate *priv;
+
g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry));
- gtk_entry_set_text (GTK_ENTRY (tentry->priv->entry), timezone);
+ priv = tentry->priv;
+
+ priv->zone = zone;
+ priv->changed = FALSE;
+
+ gtk_entry_set_text (GTK_ENTRY (priv->entry),
+ e_timezone_entry_get_display_name (zone));
+}
+
+
+/* Returns the timezone name to display to the user. . We prefer to use the
+ Olson city name, but fall back on the TZNAME, or finally the TZID. We don't
+ want to use "" as it may be wrongly interpreted as a 'local time'. */
+static char*
+e_timezone_entry_get_display_name (icaltimezone *zone)
+{
+ char *display_name;
+
+ display_name = icaltimezone_get_location (zone);
+ if (!display_name)
+ display_name = icaltimezone_get_tznames (zone);
+ if (!display_name)
+ display_name = icaltimezone_get_tzid (zone);
+
+ return display_name;
}
diff --git a/calendar/gui/e-timezone-entry.h b/calendar/gui/e-timezone-entry.h
index 0eadf1bef0..bfc8525f64 100644
--- a/calendar/gui/e-timezone-entry.h
+++ b/calendar/gui/e-timezone-entry.h
@@ -67,9 +67,9 @@ struct _ETimezoneEntryClass {
guint e_timezone_entry_get_type (void);
GtkWidget* e_timezone_entry_new (void);
-char* e_timezone_entry_get_timezone (ETimezoneEntry *tentry);
-void e_timezone_entry_set_timezone (ETimezoneEntry *tentry,
- char *timezone);
+icaltimezone* e_timezone_entry_get_timezone (ETimezoneEntry *tentry);
+void e_timezone_entry_set_timezone (ETimezoneEntry *tentry,
+ icaltimezone *zone);
END_GNOME_DECLS
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index fbe9ee435a..10655feecb 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -271,6 +271,7 @@ e_week_view_init (EWeekView *week_view)
week_view->spans = NULL;
+ week_view->zone = NULL;
week_view->multi_week_view = FALSE;
week_view->weeks_shown = 6;
week_view->rows = 6;
@@ -988,8 +989,8 @@ query_obj_updated_cb (CalQuery *query, const char *uid,
cal_recur_generate_instances (comp,
week_view->day_starts[0],
week_view->day_starts[num_days],
- e_week_view_add_event,
- week_view);
+ e_week_view_add_event, week_view,
+ cal_client_resolve_tzid, week_view->client);
gtk_object_unref (GTK_OBJECT (comp));
@@ -1332,7 +1333,7 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
gint weekday, day_offset, num_days;
gboolean update_adjustment_value = FALSE;
guint32 old_selection_start_julian = 0, old_selection_end_julian = 0;
- struct tm start_tm;
+ struct icaltimetype start_tt = icaltime_null_time ();
time_t start_time;
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
@@ -1369,8 +1370,14 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
if (!g_date_valid (&week_view->first_day_shown)
|| g_date_compare (&week_view->first_day_shown, &base_date)) {
week_view->first_day_shown = base_date;
- g_date_to_struct_tm (&base_date, &start_tm);
- start_time = mktime (&start_tm);
+
+ start_tt.year = g_date_year (&base_date);
+ start_tt.month = g_date_month (&base_date);
+ start_tt.day = g_date_day (&base_date);
+
+ start_time = icaltime_as_timet_with_zone (start_tt,
+ week_view->zone);
+
e_week_view_recalc_day_starts (week_view, start_time);
update_query (week_view);
}
@@ -1643,6 +1650,51 @@ e_week_view_set_24_hour_format (EWeekView *week_view,
gtk_widget_queue_draw (week_view->main_canvas);
}
+
+/* The current timezone. */
+icaltimezone*
+e_week_view_get_timezone (EWeekView *week_view)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), NULL);
+
+ return week_view->zone;
+}
+
+
+void
+e_week_view_set_timezone (EWeekView *week_view,
+ icaltimezone *zone)
+{
+ icaltimezone *old_zone;
+ struct icaltimetype tt = icaltime_null_time ();
+ time_t lower;
+
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+
+ old_zone = week_view->zone;
+ if (old_zone == zone)
+ return;
+
+ week_view->zone = zone;
+
+ /* If we don't have a valid date set yet, just return. */
+ if (!g_date_valid (&week_view->first_day_shown))
+ return;
+
+ /* Recalculate the new start of the first week. We just use exactly
+ the same time, but with the new timezone. */
+ tt.year = g_date_year (&week_view->first_day_shown);
+ tt.month = g_date_month (&week_view->first_day_shown);
+ tt.day = g_date_day (&week_view->first_day_shown);
+ tt.is_daylight = -1;
+
+ lower = icaltime_as_timet_with_zone (tt, zone);
+
+ e_week_view_recalc_day_starts (week_view, lower);
+ update_query (week_view);
+}
+
+
void
e_week_view_cut_clipboard (EWeekView *week_view)
{
@@ -2186,7 +2238,7 @@ e_week_view_add_event (CalComponent *comp,
EWeekView *week_view;
EWeekViewEvent event;
gint num_days;
- struct tm start_tm, end_tm;
+ struct icaltimetype start_tt, end_tt;
week_view = E_WEEK_VIEW (data);
@@ -2203,8 +2255,10 @@ e_week_view_add_event (CalComponent *comp,
g_return_val_if_fail (start < week_view->day_starts[num_days], TRUE);
g_return_val_if_fail (end > week_view->day_starts[0], TRUE);
- start_tm = *(localtime (&start));
- end_tm = *(localtime (&end));
+ start_tt = icaltime_from_timet_with_zone (start, FALSE,
+ week_view->zone);
+ end_tt = icaltime_from_timet_with_zone (end, FALSE,
+ week_view->zone);
event.comp = comp;
gtk_object_ref (GTK_OBJECT (event.comp));
@@ -2213,8 +2267,8 @@ e_week_view_add_event (CalComponent *comp,
event.spans_index = 0;
event.num_spans = 0;
- event.start_minute = start_tm.tm_hour * 60 + start_tm.tm_min;
- event.end_minute = end_tm.tm_hour * 60 + end_tm.tm_min;
+ event.start_minute = start_tt.hour * 60 + start_tt.minute;
+ event.end_minute = end_tt.hour * 60 + end_tt.minute;
if (event.end_minute == 0 && start != end)
event.end_minute = 24 * 60;
@@ -2583,7 +2637,7 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
{
GDate date;
gint week_offset;
- struct tm tm;
+ struct icaltimetype start_tt = icaltime_null_time ();
time_t lower, start, end;
guint32 old_first_day_julian, new_first_day_julian;
@@ -2608,9 +2662,11 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
week_view->first_day_shown = date;
/* Convert it to a time_t. */
- g_date_to_struct_tm (&date, &tm);
- lower = mktime (&tm);
- lower = time_day_begin (lower);
+ start_tt.year = g_date_year (&date);
+ start_tt.month = g_date_month (&date);
+ start_tt.day = g_date_day (&date);
+
+ lower = icaltime_as_timet_with_zone (start_tt, week_view->zone);
e_week_view_recalc_day_starts (week_view, lower);
update_query (week_view);
@@ -3019,11 +3075,13 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event)
dtend = week_view->day_starts[week_view->selection_end_day + 1];
date.value = &itt;
- date.tzid = NULL;
+ date.tzid = icaltimezone_get_tzid (week_view->zone);
- *date.value = icaltime_from_timet (dtstart, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dtstart, FALSE,
+ week_view->zone);
cal_component_set_dtstart (comp, &date);
- *date.value = icaltime_from_timet (dtend, FALSE);
+ *date.value = icaltime_from_timet_with_zone (dtend, FALSE,
+ week_view->zone);
cal_component_set_dtend (comp, &date);
/* We add the event locally and start editing it. We don't send the
@@ -3245,7 +3303,7 @@ e_week_view_on_delete_occurrence (GtkWidget *widget, gpointer data)
when we get the "update_event" callback. */
comp = cal_component_clone (event->comp);
- cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, TRUE));
+ cal_comp_util_add_exdate (comp, event->start, week_view->zone);
if (!cal_client_update_object (week_view->client, comp))
g_message ("e_week_view_on_delete_occurrence(): Could not update the object!");
@@ -3358,7 +3416,7 @@ e_week_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
/* For the recurring object, we add a exception to get rid of the
instance. */
comp = cal_component_clone (event->comp);
- cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, TRUE));
+ cal_comp_util_add_exdate (comp, event->start, week_view->zone);
/* For the unrecurred instance we duplicate the original object,
create a new uid for it, get rid of the recurrence rules, and set
@@ -3371,11 +3429,13 @@ e_week_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
cal_component_set_exrule_list (new_comp, NULL);
date.value = &itt;
- date.tzid = NULL;
+ date.tzid = icaltimezone_get_tzid (week_view->zone);
- *date.value = icaltime_from_timet (event->start, TRUE);
+ *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
+ week_view->zone);
cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet (event->end, TRUE);
+ *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
+ week_view->zone);
cal_component_set_dtend (new_comp, &date);
/* Now update both CalComponents. Note that we do this last since at
@@ -3527,11 +3587,13 @@ selection_received (GtkWidget *invisible,
icalcomp = icalparser_parse_string ((const char *) comp_str);
if (icalcomp) {
dtstart = week_view->day_starts[week_view->selection_start_day];
- itime = icaltime_from_timet (dtstart, FALSE);
+ itime = icaltime_from_timet_with_zone (dtstart, FALSE,
+ week_view->zone);
icalcomponent_set_dtstart (icalcomp, itime);
dtend = week_view->day_starts[week_view->selection_end_day + 1];
- itime = icaltime_from_timet (dtend, FALSE);
+ itime = icaltime_from_timet_with_zone (dtend, FALSE,
+ week_view->zone);
icalcomponent_set_dtend (icalcomp, itime);
comp = cal_component_new ();
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index cf1986b3bb..4bbc0477d2 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -209,6 +209,9 @@ struct _EWeekView
/* The start of each day displayed. */
time_t day_starts[E_WEEK_VIEW_MAX_WEEKS * 7 + 1];
+ /* The timezone. */
+ icaltimezone *zone;
+
/* The base date, where the adjustment value is 0. */
GDate base_date;
@@ -418,6 +421,11 @@ gboolean e_week_view_get_24_hour_format (EWeekView *week_view);
void e_week_view_set_24_hour_format (EWeekView *week_view,
gboolean use_24_hour);
+/* The current timezone. */
+icaltimezone* e_week_view_get_timezone (EWeekView *week_view);
+void e_week_view_set_timezone (EWeekView *week_view,
+ icaltimezone *zone);
+
/* Clipboard related functions */
void e_week_view_cut_clipboard (EWeekView *week_view);
void e_week_view_copy_clipboard (EWeekView *week_view);
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 9c99efaec9..5ea48a4d6e 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -133,6 +133,9 @@ struct _GnomeCalendarPrivate {
* editor hash table.
*/
guint in_destroy : 1;
+
+ /* Our current timezone. */
+ icaltimezone *zone;
};
@@ -343,6 +346,37 @@ search_bar_menu_activated_cb (ESearchBar *search_bar, int item, gpointer data)
}
}
+/* Returns the current time, for the ECalendarItem. */
+static struct tm
+get_current_time (ECalendarItem *calitem, gpointer data)
+{
+ GnomeCalendar *cal = data;
+ char *location;
+ icaltimezone *zone;
+ struct tm tmp_tm = { 0 };
+ struct icaltimetype tt;
+
+ g_return_val_if_fail (cal != NULL, tmp_tm);
+ g_return_val_if_fail (GNOME_IS_CALENDAR (cal), tmp_tm);
+
+ /* Get the current timezone. */
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ 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;
+
+ return tmp_tm;
+}
+
static void
setup_widgets (GnomeCalendar *gcal)
{
@@ -386,6 +420,9 @@ setup_widgets (GnomeCalendar *gcal)
e_calendar_item_set_days_start_week_sel (priv->date_navigator->calitem, 9);
e_calendar_item_set_max_days_sel (priv->date_navigator->calitem, 42);
gtk_widget_show (w);
+ e_calendar_item_set_get_time_callback (priv->date_navigator->calitem,
+ (ECalendarItemGetTimeCallback) get_current_time,
+ gcal, NULL);
e_paned_pack1 (E_PANED (priv->vpane), w, FALSE, TRUE);
gtk_signal_connect (GTK_OBJECT (priv->date_navigator),
@@ -473,6 +510,8 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->view_collection = NULL;
priv->view_menus = NULL;
+
+ priv->zone = NULL;
}
/* Used from g_hash_table_foreach(); frees an UID string */
@@ -1315,6 +1354,7 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
gint week_start_day, time_divisions;
gint start_hour, start_minute, end_hour, end_minute;
gboolean use_24_hour, show_event_end, compress_weekend;
+ char *location;
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
@@ -1388,6 +1428,14 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->todo));
+ location = calendar_config_get_timezone ();
+ priv->zone = icaltimezone_get_builtin_timezone (location);
+
+ e_day_view_set_timezone (E_DAY_VIEW (priv->day_view), priv->zone);
+ e_day_view_set_timezone (E_DAY_VIEW (priv->work_week_view), priv->zone);
+ e_week_view_set_timezone (E_WEEK_VIEW (priv->week_view), priv->zone);
+ e_week_view_set_timezone (E_WEEK_VIEW (priv->month_view), priv->zone);
+
if (initializing) {
priv->hpane_pos = calendar_config_get_hpane_pos ();
priv->vpane_pos = calendar_config_get_vpane_pos ();
@@ -1537,6 +1585,7 @@ gnome_calendar_new_appointment_for (GnomeCalendar *cal,
time_t dtstart, time_t dtend,
gboolean all_day)
{
+ GnomeCalendarPrivate *priv;
struct icaltimetype itt;
CalComponentDateTime dt;
CalComponent *comp;
@@ -1544,21 +1593,24 @@ gnome_calendar_new_appointment_for (GnomeCalendar *cal,
g_return_if_fail (cal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (cal));
- if (all_day){
- dtstart = time_day_begin (dtstart);
- dtend = time_day_end (dtend);
- }
+ priv = cal->priv;
dt.value = &itt;
- dt.tzid = NULL;
+ dt.tzid = icaltimezone_get_tzid (priv->zone);
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
- itt = icaltime_from_timet (dtstart, FALSE);
+ itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
+ if (all_day)
+ itt.hour = itt.minute = itt.second = 0;
cal_component_set_dtstart (comp, &dt);
- itt = icaltime_from_timet (dtend, FALSE);
+ itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
+ if (all_day) {
+ itt.hour = itt.minute = itt.second = 0;
+ icaltime_adjust (&itt, 1, 0, 0, 0);
+ }
cal_component_set_dtend (comp, &dt);
cal_component_commit_sequence (comp);
@@ -1705,10 +1757,7 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem,
GnomeCalendarPrivate *priv;
GDate start_date, end_date, new_start_date, new_end_date;
gint days_shown, new_days_shown;
- gint start_year, start_month, start_day;
- gint end_year, end_month, end_day;
gboolean starts_on_week_start_day;
- struct tm tm;
priv = gcal->priv;
@@ -1750,30 +1799,35 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem,
set_view (gcal, GNOME_CAL_WEEK_VIEW, TRUE, FALSE);
gnome_calendar_update_date_navigator (gcal);
} else {
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ struct icaltimetype tt;
+
start_year = g_date_year (&new_start_date);
- start_month = g_date_month (&new_start_date) - 1;
+ start_month = g_date_month (&new_start_date);
start_day = g_date_day (&new_start_date);
end_year = g_date_year (&new_end_date);
- end_month = g_date_month (&new_end_date) - 1;
+ end_month = g_date_month (&new_end_date);
end_day = g_date_day (&new_end_date);
- tm.tm_year = start_year - 1900;
- tm.tm_mon = start_month;
- tm.tm_mday = start_day;
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- tm.tm_isdst = -1;
- priv->selection_start_time = mktime (&tm);
-
- tm.tm_year = end_year - 1900;
- tm.tm_mon = end_month;
- tm.tm_mday = end_day + 1; /* mktime() will normalize this. */
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- tm.tm_isdst = -1;
- priv->selection_end_time = mktime (&tm);
+ tt.year = start_year;
+ tt.month = start_month;
+ tt.day = start_day;
+ tt.hour = 0;
+ tt.minute = 0;
+ tt.second = 0;
+ tt.is_daylight = -1;
+ priv->selection_start_time = icaltime_as_timet_with_zone (tt, priv->zone);
+
+ tt.year = end_year;
+ tt.month = end_month;
+ tt.day = end_day;
+ tt.hour = 0;
+ tt.minute = 0;
+ tt.second = 0;
+ tt.is_daylight = -1;
+ icaltime_adjust (&tt, 1, 0, 0, 0);
+ priv->selection_end_time = icaltime_as_timet_with_zone (tt, priv->zone);
e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown);
gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, TRUE, FALSE);
@@ -2033,3 +2087,15 @@ gnome_calendar_paste_clipboard (GnomeCalendar *gcal)
break;
}
}
+
+
+/* Get the current timezone. */
+icaltimezone*
+gnome_calendar_get_timezone (GnomeCalendar *gcal)
+{
+ g_return_val_if_fail (gcal != NULL, NULL);
+ g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
+
+ return gcal->priv->zone;
+}
+
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index 950d650d1a..4b0dca84e3 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -134,6 +134,10 @@ void gnome_calendar_set_view_buttons (GnomeCalendar *gcal,
just return without doing anything. */
void gnome_calendar_update_view_buttons (GnomeCalendar *gcal);
+/* Get the current timezone. */
+icaltimezone *gnome_calendar_get_timezone (GnomeCalendar *gcal);
+
+
/* Clipboard operations */
void gnome_calendar_cut_clipboard (GnomeCalendar *gcal);
void gnome_calendar_copy_clipboard (GnomeCalendar *gcal);
diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c
index 16c1eecc9f..06250a1a70 100644
--- a/calendar/gui/goto.c
+++ b/calendar/gui/goto.c
@@ -18,6 +18,7 @@
#include <libgnomeui/gnome-dialog.h>
#include <glade/glade.h>
#include "calendar-commands.h"
+#include "calendar-config.h"
#include "tag-calendar.h"
#include "goto.h"
@@ -83,18 +84,49 @@ ecal_event (ECalendarItem *calitem, gpointer user_data)
{
GoToDialog *dlg = user_data;
GDate start_date, end_date;
- struct tm tm;
+ struct icaltimetype tt = icaltime_null_time ();
time_t et;
e_calendar_item_get_selection (calitem, &start_date, &end_date);
- g_date_to_struct_tm (&start_date, &tm);
- et = mktime (&tm);
-
+
+ tt.year = g_date_year (&start_date);
+ tt.month = g_date_month (&start_date);
+ tt.day = g_date_day (&start_date);
+
+ et = icaltime_as_timet_with_zone (tt, gnome_calendar_get_timezone (dlg->gcal));
+
gnome_calendar_goto (dlg->gcal, et);
gnome_dialog_close (GNOME_DIALOG (dlg->dialog));
}
+/* Returns the current time, for the ECalendarItem. */
+static struct tm
+get_current_time (ECalendarItem *calitem, gpointer data)
+{
+ char *location;
+ icaltimezone *zone;
+ struct tm tmp_tm = { 0 };
+ struct icaltimetype tt;
+
+ /* Get the current timezone. */
+ location = calendar_config_get_timezone ();
+ zone = icaltimezone_get_builtin_timezone (location);
+
+ tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
+
+ /* Now copy it to the struct tm and return it. */
+ 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;
+
+ return tmp_tm;
+}
+
/* Creates the ecalendar */
static void
create_ecal (GoToDialog *dlg)
@@ -109,6 +141,9 @@ create_ecal (GoToDialog *dlg)
gtk_box_pack_start (GTK_BOX (dlg->vbox), GTK_WIDGET (dlg->ecal), TRUE, TRUE, 0);
e_calendar_item_set_first_month (calitem, dlg->year_val, dlg->month_val);
+ e_calendar_item_set_get_time_callback (calitem,
+ get_current_time,
+ dlg, NULL);
ecal_date_range_changed (calitem, dlg);
}
@@ -171,7 +206,7 @@ goto_dialog (GnomeCalendar *gcal)
{
GtkWidget *menu;
time_t start_time;
- struct tm tm;
+ struct icaltimetype tt;
int b;
if (dlg) {
@@ -196,10 +231,10 @@ goto_dialog (GnomeCalendar *gcal)
dlg->gcal = gcal;
gnome_calendar_get_selected_time_range (dlg->gcal, &start_time, NULL);
- tm = *localtime (&start_time);
- dlg->year_val = tm.tm_year + 1900;
- dlg->month_val = tm.tm_mon;
- dlg->day_val = tm.tm_mday;
+ tt = icaltime_from_timet_with_zone (start_time, FALSE, gnome_calendar_get_timezone (gcal));
+ dlg->year_val = tt.year;
+ dlg->month_val = tt.month - 1;
+ dlg->day_val = tt.day;
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (dlg->month));
gtk_option_menu_set_history (GTK_OPTION_MENU (dlg->month), dlg->month_val);
diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c
index 3d6ba40f45..485e013c4e 100644
--- a/calendar/gui/tag-calendar.c
+++ b/calendar/gui/tag-calendar.c
@@ -25,12 +25,14 @@
#endif
#include <cal-util/timeutil.h>
+#include "calendar-config.h"
#include "tag-calendar.h"
struct calendar_tag_closure {
ECalendarItem *calitem;
+ icaltimezone *zone;
time_t start_time;
time_t end_time;
};
@@ -44,7 +46,9 @@ prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c)
{
gint start_year, start_month, start_day;
gint end_year, end_month, end_day;
- struct tm start_tm = { 0 }, end_tm = { 0 };
+ struct icaltimetype start_tt = icaltime_null_time ();
+ struct icaltimetype end_tt = icaltime_null_time ();
+ char *location;
e_calendar_item_clear_marks (ecal->calitem);
@@ -54,25 +58,26 @@ prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c)
&end_year, &end_month, &end_day))
return FALSE;
- start_tm.tm_year = start_year - 1900;
- start_tm.tm_mon = start_month;
- start_tm.tm_mday = start_day;
- start_tm.tm_hour = 0;
- start_tm.tm_min = 0;
- start_tm.tm_sec = 0;
- start_tm.tm_isdst = -1;
-
- end_tm.tm_year = end_year - 1900;
- end_tm.tm_mon = end_month;
- end_tm.tm_mday = end_day + 1;
- end_tm.tm_hour = 0;
- end_tm.tm_min = 0;
- end_tm.tm_sec = 0;
- end_tm.tm_isdst = -1;
+ start_tt.year = start_year;
+ start_tt.month = start_month + 1;
+ start_tt.day = start_day;
+ start_tt.is_daylight = -1;
+
+ end_tt.year = end_year;
+ end_tt.month = end_month + 1;
+ end_tt.day = end_day;
+ end_tt.is_daylight = -1;
+
+ icaltime_adjust (&end_tt, 1, 0, 0, 0);
c->calitem = ecal->calitem;
- c->start_time = mktime (&start_tm);
- c->end_time = mktime (&end_tm);
+
+ /* FIXME. It may be better if the timezone is passed in. */
+ location = calendar_config_get_timezone ();
+ c->zone = icaltimezone_get_builtin_timezone (location);
+
+ c->start_time = icaltime_as_timet_with_zone (start_tt, c->zone);
+ c->end_time = icaltime_as_timet_with_zone (end_tt, c->zone);
return TRUE;
}
@@ -85,21 +90,16 @@ tag_calendar_cb (CalComponent *comp,
gpointer data)
{
struct calendar_tag_closure *c = data;
- time_t t;
-
- t = time_day_begin (istart);
-
- do {
- struct tm tm;
-
- tm = *localtime (&t);
-
- e_calendar_item_mark_day (c->calitem, tm.tm_year + 1900,
- tm.tm_mon, tm.tm_mday,
- E_CALENDAR_ITEM_MARK_BOLD);
+ struct icaltimetype start_tt, end_tt;
- t = time_day_end (t);
- } while (t < iend);
+ start_tt = icaltime_from_timet_with_zone (istart, FALSE, c->zone);
+ end_tt = icaltime_from_timet_with_zone (iend, FALSE, c->zone);
+ e_calendar_item_mark_days (c->calitem,
+ start_tt.year, start_tt.month - 1,
+ start_tt.day,
+ end_tt.year, end_tt.month - 1,
+ end_tt.day,
+ E_CALENDAR_ITEM_MARK_BOLD);
return TRUE;
}
@@ -149,7 +149,7 @@ tag_calendar_by_client (ECalendar *ecal, CalClient *client)
* component that occur within the calendar's current time range.
**/
void
-tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp)
+tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, CalClient *client)
{
struct calendar_tag_closure c;
@@ -168,5 +168,7 @@ tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp)
#if 0
g_print ("DateNavigator generating instances\n");
#endif
- cal_recur_generate_instances (comp, c.start_time, c.end_time, tag_calendar_cb, &c);
+ cal_recur_generate_instances (comp, c.start_time, c.end_time,
+ tag_calendar_cb, &c,
+ cal_client_resolve_tzid, client);
}
diff --git a/calendar/gui/tag-calendar.h b/calendar/gui/tag-calendar.h
index 74c669493b..f9b11c1a5a 100644
--- a/calendar/gui/tag-calendar.h
+++ b/calendar/gui/tag-calendar.h
@@ -27,6 +27,7 @@
#include <cal-client/cal-client.h>
void tag_calendar_by_client (ECalendar *ecal, CalClient *client);
-void tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp);
+void tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp,
+ CalClient *client);
#endif