aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog16
-rw-r--r--calendar/cal-util/calobj.c65
-rw-r--r--calendar/gui/gnome-cal.c95
3 files changed, 89 insertions, 87 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 4a52717667..d1215599c9 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,19 @@
+2000-05-12 Federico Mena Quintero <federico@helixcode.com>
+
+ * cal-util/calobj.c (generate): Use a (dtend - dtstart) offset to
+ compute the ending time of the occurrence. This takes care of
+ recurring events that span multiple days. Also, removed the DST
+ condition since it did not look right at all: if you have a daily
+ appointment at 18:00, it still should happen at 18:00 even during
+ daylight savings.
+
+ * gui/gnome-cal.c (gnome_calendar_tag_calendar): Use the timeutil
+ functions instead of calculating the month's times by hand. Use
+ cal_obj_instance_list_free() instead of freeing the list by hand.
+ Clip the range we pass to mark_gtk_calendar_day().
+ (mark_gtk_calendar_day): Fixed off-by-one error at the end of the
+ month by adding real day offsets.
+
2000-05-11 Federico Mena Quintero <federico@helixcode.com>
* gui/gnome-cal.c (add_alarms_for_object): New function to add
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
index 5ef1f1bb5f..4a3afd81ec 100644
--- a/calendar/cal-util/calobj.c
+++ b/calendar/cal-util/calobj.c
@@ -1178,48 +1178,53 @@ is_date_in_list (GList *list, struct tm *date)
return 0;
}
-
-/* FIXME: Doesn't work with events >= 1 day. */
-static int
+/* Generates an event instance based on the reference time */
+static gboolean
generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure)
{
- struct tm dt_start, dt_end, ref;
- time_t s_t, e_t;
-
- dt_start = *localtime (&ico->dtstart);
- dt_end = *localtime (&ico->dtend);
- ref = *localtime (&reference);
+ time_t offset;
+ struct tm tm_start, ref;
+ time_t start, end;
- dt_start.tm_mday = ref.tm_mday;
- dt_start.tm_mon = ref.tm_mon;
- dt_start.tm_year = ref.tm_year;
+ offset = ico->dtend - ico->dtstart;
- dt_end.tm_mday = ref.tm_mday;
- dt_end.tm_mon = ref.tm_mon;
- dt_end.tm_year = ref.tm_year;
+ tm_start = *localtime (&ico->dtstart);
+ ref = *localtime (&reference);
+ tm_start.tm_mday = ref.tm_mday;
+ tm_start.tm_mon = ref.tm_mon;
+ tm_start.tm_year = ref.tm_year;
- if (ref.tm_isdst > dt_start.tm_isdst){
- dt_start.tm_hour--;
- dt_end.tm_hour--;
- } else if (ref.tm_isdst < dt_start.tm_isdst){
- dt_start.tm_hour++;
- dt_end.tm_hour++;
+ start = mktime (&tm_start);
+ if (start == -1) {
+ g_message ("generate(): Produced invalid start date!");
+ return FALSE;
}
- s_t = mktime (&dt_start);
-
- if (ico->exdate && is_date_in_list (ico->exdate, &dt_start))
- return 1;
+ end = start + offset;
- e_t = mktime (&dt_end);
+#if 0
+ /* FIXME: I think this is not needed, since we are offsetting by full day values,
+ * and the times should remain the same --- if you have a daily appointment
+ * at 18:00, it is always at 18:00 even during daylight savings.
+ *
+ * However, what should happen on the exact change-of-savings day with
+ * appointments in the early morning hours?
+ */
- if ((s_t == -1) || (e_t == -1)) {
- g_warning ("Produced invalid dates!\n");
- return 0;
+ if (ref.tm_isdst > tm_start.tm_isdst) {
+ tm_start.tm_hour--;
+ tm_end.tm_hour--;
+ } else if (ref.tm_isdst < tm_start.tm_isdst) {
+ tm_start.tm_hour++;
+ tm_end.tm_hour++;
}
+#endif
+
+ if (ico->exdate && is_date_in_list (ico->exdate, &tm_start))
+ return TRUE;
- return (*cb) (ico, s_t, e_t, closure);
+ return (*cb) (ico, start, end, closure);
}
int
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 3041d80d07..e3b79e51b3 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -47,10 +47,6 @@ static void gnome_calendar_destroy (GtkObject *object);
static void gnome_calendar_update_view_times (GnomeCalendar *gcal,
GtkWidget *page);
static void gnome_calendar_update_gtk_calendar (GnomeCalendar *gcal);
-static int gnome_calendar_mark_gtk_calendar_day (GnomeCalendar *cal,
- GtkCalendar *gtk_cal,
- time_t start,
- time_t end);
static void gnome_calendar_on_day_selected (GtkCalendar *calendar,
GnomeCalendar *gcal);
static void gnome_calendar_on_month_changed (GtkCalendar *calendar,
@@ -1119,6 +1115,24 @@ calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
#endif
+/* Marks the specified range in a GtkCalendar */
+static void
+mark_gtk_calendar_day (GtkCalendar *calendar, time_t start, time_t end)
+{
+ time_t t;
+
+ t = time_day_begin (start);
+
+ do {
+ struct tm tm;
+
+ tm = *localtime (&t);
+ gtk_calendar_mark_day (calendar, tm.tm_mday);
+
+ t = time_day_end (t);
+ } while (t < end);
+}
+
/*
* Tags the dates with appointments in a GtkCalendar based on the
* GnomeCalendar contents
@@ -1127,7 +1141,6 @@ void
gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
{
time_t month_begin, month_end;
- struct tm tm;
GList *cois, *l;
g_return_if_fail (cal != NULL);
@@ -1139,21 +1152,17 @@ gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
if (!GTK_WIDGET_VISIBLE (cal->gtk_calendar))
return;
- /* compute month_begin */
- tm.tm_hour = 0;
- tm.tm_min = 0;
- tm.tm_sec = 0;
- /* setting tm_day to zero is a no-no; it will set mktime back to the
- end of the previous month, which may be 28,29,30; this may chop
- some days from the calendar */
- tm.tm_mday = 1;
- tm.tm_mon = gtk_cal->month;
- tm.tm_year = gtk_cal->year - 1900;
- tm.tm_isdst= -1;
-
- month_begin = mktime (&tm);
- tm.tm_mon++;
- month_end = mktime (&tm);
+ month_begin = time_from_day (gtk_cal->year, gtk_cal->month, 1);
+ if (month_begin == -1) {
+ g_message ("gnome_calendar_tag_calendar(): Generated invalid month begin!");
+ return;
+ }
+
+ month_end = time_month_end (month_begin);
+ if (month_end == -1) {
+ g_message ("gnome_calendar_tag_calendar(): Generated invalid month end!");
+ return;
+ }
gtk_calendar_freeze (gtk_cal);
gtk_calendar_clear_marks (gtk_cal);
@@ -1163,51 +1172,23 @@ gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
for (l = cois; l; l = l->next) {
CalObjInstance *coi = l->data;
+ time_t start, end;
- gnome_calendar_mark_gtk_calendar_day (cal, gtk_cal,
- coi->start, coi->end);
+ start = MAX (coi->start, month_begin);
+ end = MIN (coi->end, month_end);
- g_free (coi->uid);
- g_free (coi);
+ if (start > end)
+ continue;
+
+ /* Clip the occurrence's start and end times to the month's limits */
+ mark_gtk_calendar_day (gtk_cal, start, end);
}
- g_list_free (cois);
+ cal_obj_instance_list_free (cois);
gtk_calendar_thaw (gtk_cal);
}
-
-/*
- * This is called from gnome_calendar_tag_calendar to mark the days of a
- * GtkCalendar on which the user has appointments.
- */
-static int
-gnome_calendar_mark_gtk_calendar_day (GnomeCalendar *cal,
- GtkCalendar *gtk_cal,
- time_t start,
- time_t end)
-{
- struct tm tm_s, tm_e;
- gint start_day, end_day, day;
-
- tm_s = *localtime (&start);
- tm_e = *localtime (&end);
-
- start_day = tm_s.tm_mday;
- end_day = tm_e.tm_mday;
-
- /* If the event ends at midnight then really it ends on the previous
- day (unless it started at the same time). */
- if (start != end && tm_e.tm_hour == 0 && tm_e.tm_min == 0)
- end_day--;
-
- for (day = start_day; day <= end_day; day++)
- gtk_calendar_mark_day (gtk_cal, day);
-
- return TRUE;
-}
-
-
/* This is called when the day begin & end times, the AM/PM flag, or the
week_starts_on_monday flags are changed.
FIXME: Which of these options do we want the new views to support? */