diff options
-rw-r--r-- | calendar/ChangeLog | 16 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 65 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 95 |
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? */ |