diff options
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/ChangeLog | 24 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 164 | ||||
-rw-r--r-- | calendar/cal-util/calobj.h | 9 | ||||
-rw-r--r-- | calendar/calendar.c | 4 | ||||
-rw-r--r-- | calendar/calobj.c | 164 | ||||
-rw-r--r-- | calendar/calobj.h | 9 | ||||
-rw-r--r-- | calendar/eventedit.c | 1 | ||||
-rw-r--r-- | calendar/gncal-day-panel.c | 6 | ||||
-rw-r--r-- | calendar/gncal-full-day.c | 2 | ||||
-rw-r--r-- | calendar/gnome-cal.c | 6 | ||||
-rw-r--r-- | calendar/gui/calendar.c | 4 | ||||
-rw-r--r-- | calendar/gui/eventedit.c | 1 | ||||
-rw-r--r-- | calendar/gui/gncal-day-panel.c | 6 | ||||
-rw-r--r-- | calendar/gui/gncal-full-day.c | 2 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 6 | ||||
-rw-r--r-- | calendar/gui/main.c | 2 | ||||
-rw-r--r-- | calendar/gui/year-view.c | 2 | ||||
-rw-r--r-- | calendar/main.c | 2 | ||||
-rw-r--r-- | calendar/pcs/calobj.c | 164 | ||||
-rw-r--r-- | calendar/pcs/calobj.h | 9 | ||||
-rw-r--r-- | calendar/timeutil.c | 70 | ||||
-rw-r--r-- | calendar/timeutil.h | 13 | ||||
-rw-r--r-- | calendar/year-view.c | 2 |
23 files changed, 434 insertions, 238 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 690276863f..cc17eaa6f3 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,27 @@ +1998-10-02 Federico Mena Quintero <federico@nuclecu.unam.mx> + + * timeutil.c (time_day_begin): Changed name from + time_start_of_day() to be consistent with the other begin/end functions. + (time_day_end): Likewise. + + * calobj.c (ical_object_get_first_weekday): New public function to + get the first toggled day in a weekday mask. Since we do not + support multiple weekdays in a monthly-by-pos rule, we just fetch + the first toggled one. + (ical_object_generate_events): Added a missing break statement. + + * timeutil.c (time_month_end): Made it consistent with the rest of + the time begin/end functions -- now it returns the first second of + the *next* month. + (time_week_end): Actually implemented this function. It will be + used when the week view is rewritten. + + * calobj.c (time_in_range): Fix off-by-one in the comparison of + the time against the end time. + + * gncal-full-day.c (expand_space): Fixed bug where the columns not + were being expanded due to a missing "slot + j". + 1998-10-01 Federico Mena Quintero <federico@nuclecu.unam.mx> * month-view.c (month_view_init): Use the font #defines. diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index 33aff8cda8..9e5f41bc27 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -1025,15 +1025,28 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) e_t = mktime (&dt_end); - if (s_t == -1 || e_t == -1){ + if ((s_t == -1) || (e_t == -1)) { g_warning ("Produced invalid dates!\n"); return 0; } - return (*cb)(ico, s_t, e_t, closure); + + return (*cb) (ico, s_t, e_t, closure); +} + +int +ical_object_get_first_weekday (int weekday_mask) +{ + int i; + + for (i = 0; i < 7; i++) + if (weekday_mask & (1 << i)) + return i; + + return -1; } -#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1)) -#define recur_in_range(t,r) (r->enddate ? (t < r->enddate) : 1) +#define time_in_range(t, a, b) ((t >= a) && (b ? (t < b) : 1)) +#define recur_in_range(t, r) (r->enddate ? (t < r->enddate) : 1) /* * Generate every possible event. Invokes the callback routine for @@ -1046,88 +1059,104 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure) { - Recurrence *recur = ico->recur; time_t current; - int first_week_day, i; - - if (!ico->recur){ - if ((end && (ico->dtstart < end) && ico->dtend > start) || - (end == 0 && ico->dtend > start)){ + int first_week_day; + + /* If there is no recurrence, just check ranges */ + + if (!ico->recur) { + if ((end && (ico->dtstart < end) && (ico->dtend > start)) + || ((end == 0) && (ico->dtend > start))) { time_t ev_s, ev_e; - ev_s = ico->dtstart < start ? start : ico->dtstart; - ev_e = ico->dtend > end ? end : ico->dtend; - (*cb)(ico, ev_s, ev_e, closure); + /* Clip range */ + + ev_s = MAX (ico->dtstart, start); + ev_e = MIN (ico->dtend, end); + + (* cb) (ico, ev_s, ev_e, closure); } return; } - /* The event has a recurrence rule */ - if (end != 0){ + /* The event has a recurrence rule -- check that we will generate at least one instance */ + + if (end != 0) { if (ico->dtstart > end) return; - if (!IS_INFINITE (recur) && recur->enddate < start) + + if (!IS_INFINITE (ico->recur) && (ico->recur->enddate < start)) return; } + /* Generate the instances */ + current = ico->dtstart; - switch (recur->type){ + + switch (ico->recur->type) { case RECUR_DAILY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - } /* Advance */ - current = time_add_day (current, recur->interval); - - if (current == -1){ - g_warning ("RECUR_DAILY: mktime error\n"); + + current = time_add_day (current, ico->recur->interval); + + if (current == -1) { + g_warning ("RECUR_DAILY: time_add_day() returned invalid time"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_WEEKLY: do { - struct tm *tm = localtime (¤t); - - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ - if (recur->weekday & (1 << tm->tm_wday)) + struct tm *tm; + + tm = localtime (¤t); + + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) { + /* Weekdays to recur on are specified as a bitmask */ + if (ico->recur->weekday & (1 << tm->tm_wday)) if (!generate (ico, current, cb, closure)) return; } /* Advance by day for scanning the week or by interval at week end */ + if (tm->tm_wday == 6) - current = time_add_day (current, (recur->interval-1) * 7 + 1); + current = time_add_day (current, (ico->recur->interval - 1) * 7 + 1); else current = time_add_day (current, 1); - if (current == -1){ - g_warning ("RECUR_WEEKLY: mktime error\n"); + if (current == -1) { + g_warning ("RECUR_WEEKLY: time_add_day() returned invalid time\n"); return; } } while (current < end || (end == 0)); + break; - + case RECUR_MONTHLY_BY_POS: /* FIXME: We only deal with positives now */ - if (recur->u.month_pos < 0) + if (ico->recur->u.month_pos < 0) { + g_warning ("RECUR_MONTHLY_BY_POS does not support negative positions yet"); return; - - if (recur->u.month_pos == 0) + } + + if (ico->recur->u.month_pos == 0) return; - - first_week_day = 7; - for (i = 6; i >= 0; i--) - if (recur->weekday & (1 << i)) - first_week_day = i; + + first_week_day = ical_object_get_first_weekday (ico->recur->weekday); /* This should not happen, but take it into account */ - if (first_week_day == 7) + if (first_week_day == -1) { + g_warning ("ical_object_get_first_weekday() returned -1"); return; + } do { struct tm tm; @@ -1140,63 +1169,76 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar tm = *localtime (&t); week_day_start = tm.tm_wday; - tm.tm_mday = 7 * (recur->u.month_pos - - ((week_day_start <= first_week_day ) ? 1 : 0)) - - (week_day_start - first_week_day) + 1; - + tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0)) + - (week_day_start - first_week_day) + 1); + t = mktime (&tm); - - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + current = mktime (&tm); tm.tm_mday = 1; - tm.tm_mon += recur->interval; + tm.tm_mon += ico->recur->interval; current = mktime (&tm); - if (current == -1){ + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_MONTHLY_BY_DAY: do { - struct tm *tm = localtime (¤t); + struct tm *tm; time_t t; int p; + tm = localtime (¤t); + p = tm->tm_mday; - tm->tm_mday = recur->u.month_day; + tm->tm_mday = ico->recur->u.month_day; t = mktime (tm); - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + tm->tm_mday = p; - tm->tm_mon += recur->interval; + tm->tm_mon += ico->recur->interval; current = mktime (tm); - if (current == -1){ + + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } } while (current < end || (end == 0)); + + break; case RECUR_YEARLY_BY_MONTH: case RECUR_YEARLY_BY_DAY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)) + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - + /* Advance */ - current = time_add_year (current, recur->interval); + + current = time_add_year (current, ico->recur->interval); } while (current < end || (end == 0)); + + break; + + default: + g_assert_not_reached (); } } @@ -1210,7 +1252,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) (*count)++; if (ico->recur->duration == *count) { - ico->recur->enddate = time_end_of_day (end); + ico->recur->enddate = time_day_end (end); return 0; } return 1; diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h index d18acd4f8a..05f6d00291 100644 --- a/calendar/cal-util/calobj.h +++ b/calendar/cal-util/calobj.h @@ -100,7 +100,7 @@ typedef struct { * this is what got specified) or it is our computed * ending date (computed from the duration item). */ - + int weekday; union { @@ -175,7 +175,7 @@ typedef struct { } iCalObject; /* The callback for the recurrence generator */ -typedef int (*calendarfn)(iCalObject *, time_t, time_t, void *); +typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *); iCalObject *ical_new (char *comment, char *organizer, char *summary); iCalObject *ical_object_new (void); @@ -190,6 +190,11 @@ void ical_object_add_exdate (iCalObject *o, time_t t); /* Computes the enddate field of the recurrence based on the duration */ void ical_object_compute_end (iCalObject *ico); +/* Returns the first toggled day in a weekday mask -- we do this because we do not support multiple + * days on a monthly-by-pos recurrence. If no days are toggled, it returns -1. + */ +int ical_object_get_first_weekday (int weekday_mask); + /* Returns the number of seconds configured to trigger the alarm in advance to an event */ int alarm_compute_offset (CalendarAlarm *a); diff --git a/calendar/calendar.c b/calendar/calendar.c index a76d95758f..bacd7c9291 100644 --- a/calendar/calendar.c +++ b/calendar/calendar.c @@ -287,8 +287,8 @@ calendar_load (Calendar *cal, char *fname) return "Could not load the calendar"; calendar_today = time (NULL); - calendar_day_begin = time_start_of_day (calendar_today); - calendar_day_end = time_end_of_day (calendar_today); + calendar_day_begin = time_day_begin (calendar_today); + calendar_day_end = time_day_end (calendar_today); calendar_load_from_vobject (cal, vcal); cleanVObject (vcal); diff --git a/calendar/calobj.c b/calendar/calobj.c index 33aff8cda8..9e5f41bc27 100644 --- a/calendar/calobj.c +++ b/calendar/calobj.c @@ -1025,15 +1025,28 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) e_t = mktime (&dt_end); - if (s_t == -1 || e_t == -1){ + if ((s_t == -1) || (e_t == -1)) { g_warning ("Produced invalid dates!\n"); return 0; } - return (*cb)(ico, s_t, e_t, closure); + + return (*cb) (ico, s_t, e_t, closure); +} + +int +ical_object_get_first_weekday (int weekday_mask) +{ + int i; + + for (i = 0; i < 7; i++) + if (weekday_mask & (1 << i)) + return i; + + return -1; } -#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1)) -#define recur_in_range(t,r) (r->enddate ? (t < r->enddate) : 1) +#define time_in_range(t, a, b) ((t >= a) && (b ? (t < b) : 1)) +#define recur_in_range(t, r) (r->enddate ? (t < r->enddate) : 1) /* * Generate every possible event. Invokes the callback routine for @@ -1046,88 +1059,104 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure) { - Recurrence *recur = ico->recur; time_t current; - int first_week_day, i; - - if (!ico->recur){ - if ((end && (ico->dtstart < end) && ico->dtend > start) || - (end == 0 && ico->dtend > start)){ + int first_week_day; + + /* If there is no recurrence, just check ranges */ + + if (!ico->recur) { + if ((end && (ico->dtstart < end) && (ico->dtend > start)) + || ((end == 0) && (ico->dtend > start))) { time_t ev_s, ev_e; - ev_s = ico->dtstart < start ? start : ico->dtstart; - ev_e = ico->dtend > end ? end : ico->dtend; - (*cb)(ico, ev_s, ev_e, closure); + /* Clip range */ + + ev_s = MAX (ico->dtstart, start); + ev_e = MIN (ico->dtend, end); + + (* cb) (ico, ev_s, ev_e, closure); } return; } - /* The event has a recurrence rule */ - if (end != 0){ + /* The event has a recurrence rule -- check that we will generate at least one instance */ + + if (end != 0) { if (ico->dtstart > end) return; - if (!IS_INFINITE (recur) && recur->enddate < start) + + if (!IS_INFINITE (ico->recur) && (ico->recur->enddate < start)) return; } + /* Generate the instances */ + current = ico->dtstart; - switch (recur->type){ + + switch (ico->recur->type) { case RECUR_DAILY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - } /* Advance */ - current = time_add_day (current, recur->interval); - - if (current == -1){ - g_warning ("RECUR_DAILY: mktime error\n"); + + current = time_add_day (current, ico->recur->interval); + + if (current == -1) { + g_warning ("RECUR_DAILY: time_add_day() returned invalid time"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_WEEKLY: do { - struct tm *tm = localtime (¤t); - - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ - if (recur->weekday & (1 << tm->tm_wday)) + struct tm *tm; + + tm = localtime (¤t); + + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) { + /* Weekdays to recur on are specified as a bitmask */ + if (ico->recur->weekday & (1 << tm->tm_wday)) if (!generate (ico, current, cb, closure)) return; } /* Advance by day for scanning the week or by interval at week end */ + if (tm->tm_wday == 6) - current = time_add_day (current, (recur->interval-1) * 7 + 1); + current = time_add_day (current, (ico->recur->interval - 1) * 7 + 1); else current = time_add_day (current, 1); - if (current == -1){ - g_warning ("RECUR_WEEKLY: mktime error\n"); + if (current == -1) { + g_warning ("RECUR_WEEKLY: time_add_day() returned invalid time\n"); return; } } while (current < end || (end == 0)); + break; - + case RECUR_MONTHLY_BY_POS: /* FIXME: We only deal with positives now */ - if (recur->u.month_pos < 0) + if (ico->recur->u.month_pos < 0) { + g_warning ("RECUR_MONTHLY_BY_POS does not support negative positions yet"); return; - - if (recur->u.month_pos == 0) + } + + if (ico->recur->u.month_pos == 0) return; - - first_week_day = 7; - for (i = 6; i >= 0; i--) - if (recur->weekday & (1 << i)) - first_week_day = i; + + first_week_day = ical_object_get_first_weekday (ico->recur->weekday); /* This should not happen, but take it into account */ - if (first_week_day == 7) + if (first_week_day == -1) { + g_warning ("ical_object_get_first_weekday() returned -1"); return; + } do { struct tm tm; @@ -1140,63 +1169,76 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar tm = *localtime (&t); week_day_start = tm.tm_wday; - tm.tm_mday = 7 * (recur->u.month_pos - - ((week_day_start <= first_week_day ) ? 1 : 0)) - - (week_day_start - first_week_day) + 1; - + tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0)) + - (week_day_start - first_week_day) + 1); + t = mktime (&tm); - - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + current = mktime (&tm); tm.tm_mday = 1; - tm.tm_mon += recur->interval; + tm.tm_mon += ico->recur->interval; current = mktime (&tm); - if (current == -1){ + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_MONTHLY_BY_DAY: do { - struct tm *tm = localtime (¤t); + struct tm *tm; time_t t; int p; + tm = localtime (¤t); + p = tm->tm_mday; - tm->tm_mday = recur->u.month_day; + tm->tm_mday = ico->recur->u.month_day; t = mktime (tm); - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + tm->tm_mday = p; - tm->tm_mon += recur->interval; + tm->tm_mon += ico->recur->interval; current = mktime (tm); - if (current == -1){ + + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } } while (current < end || (end == 0)); + + break; case RECUR_YEARLY_BY_MONTH: case RECUR_YEARLY_BY_DAY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)) + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - + /* Advance */ - current = time_add_year (current, recur->interval); + + current = time_add_year (current, ico->recur->interval); } while (current < end || (end == 0)); + + break; + + default: + g_assert_not_reached (); } } @@ -1210,7 +1252,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) (*count)++; if (ico->recur->duration == *count) { - ico->recur->enddate = time_end_of_day (end); + ico->recur->enddate = time_day_end (end); return 0; } return 1; diff --git a/calendar/calobj.h b/calendar/calobj.h index d18acd4f8a..05f6d00291 100644 --- a/calendar/calobj.h +++ b/calendar/calobj.h @@ -100,7 +100,7 @@ typedef struct { * this is what got specified) or it is our computed * ending date (computed from the duration item). */ - + int weekday; union { @@ -175,7 +175,7 @@ typedef struct { } iCalObject; /* The callback for the recurrence generator */ -typedef int (*calendarfn)(iCalObject *, time_t, time_t, void *); +typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *); iCalObject *ical_new (char *comment, char *organizer, char *summary); iCalObject *ical_object_new (void); @@ -190,6 +190,11 @@ void ical_object_add_exdate (iCalObject *o, time_t t); /* Computes the enddate field of the recurrence based on the duration */ void ical_object_compute_end (iCalObject *ico); +/* Returns the first toggled day in a weekday mask -- we do this because we do not support multiple + * days on a monthly-by-pos recurrence. If no days are toggled, it returns -1. + */ +int ical_object_get_first_weekday (int weekday_mask); + /* Returns the number of seconds configured to trigger the alarm in advance to an event */ int alarm_compute_offset (CalendarAlarm *a); diff --git a/calendar/eventedit.c b/calendar/eventedit.c index 3189b11300..a44b18e886 100644 --- a/calendar/eventedit.c +++ b/calendar/eventedit.c @@ -565,7 +565,6 @@ ee_store_recur_rule_to_ical (EventEditor *ee) ical->recur->u.month_day = option_menu_active_number (ee->recur_rr_month_weekday); } - break; case 4: diff --git a/calendar/gncal-day-panel.c b/calendar/gncal-day-panel.c index 11a2d21a7d..c4ea354e25 100644 --- a/calendar/gncal-day-panel.c +++ b/calendar/gncal-day-panel.c @@ -128,7 +128,7 @@ gncal_day_panel_new (GnomeCalendar *calendar, time_t start_of_day) 0, 0); gtk_widget_show (w); - w = gncal_full_day_new (calendar, time_start_of_day (start_of_day), time_end_of_day (start_of_day)); + w = gncal_full_day_new (calendar, time_day_begin (start_of_day), time_day_end (start_of_day)); dpanel->fullday = GNCAL_FULL_DAY (w); gtk_signal_connect (GTK_OBJECT (dpanel->fullday), "range_activated", (GtkSignalFunc) day_view_range_activated, @@ -221,7 +221,7 @@ gncal_day_panel_set (GncalDayPanel *dpanel, time_t start_of_day) g_return_if_fail (dpanel != NULL); g_return_if_fail (GNCAL_IS_DAY_PANEL (dpanel)); - dpanel->start_of_day = time_start_of_day (start_of_day); + dpanel->start_of_day = time_day_begin (start_of_day); if (dpanel->fullday->lower == dpanel->start_of_day) return; @@ -229,7 +229,7 @@ gncal_day_panel_set (GncalDayPanel *dpanel, time_t start_of_day) strftime (buf, sizeof (buf), "%a %b %d %Y", &tm); gtk_label_set (GTK_LABEL (dpanel->date_label), buf); - gncal_full_day_set_bounds (dpanel->fullday, dpanel->start_of_day, time_end_of_day (dpanel->start_of_day)); + gncal_full_day_set_bounds (dpanel->fullday, dpanel->start_of_day, time_day_end (dpanel->start_of_day)); gtk_calendar_select_month (dpanel->gtk_calendar, tm.tm_mon, tm.tm_year + 1900); diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c index a84e185eb1..6acc8ca16b 100644 --- a/calendar/gncal-full-day.c +++ b/calendar/gncal-full-day.c @@ -825,7 +825,7 @@ expand_space (char *array, int *allocations, int val, int lower, int count, int for (i = 0; i < count; i++){ slot = allocations [val] + 1; for (j = 0; j < cols; j++) - xy (array, slot, lower+i) = val; + xy (array, slot + j, lower+i) = val; } } diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c index fbbd5c2c19..979c6df667 100644 --- a/calendar/gnome-cal.c +++ b/calendar/gnome-cal.c @@ -94,7 +94,7 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) g_return_if_fail (new_time != -1); - new_time = time_start_of_day (new_time); + new_time = time_day_begin (new_time); if (current == gcal->day_view) gncal_day_panel_set (GNCAL_DAY_PANEL (gcal->day_view), new_time); @@ -192,7 +192,7 @@ gnome_calendar_new (char *title) gtk_window_set_title(GTK_WINDOW(retval), title); - gcal->current_display = time_start_of_day (time (NULL)); + gcal->current_display = time_day_begin (time (NULL)); gcal->cal = calendar_new (title); setup_widgets (gcal); return retval; @@ -385,7 +385,7 @@ mark_gtk_calendar_day (iCalObject *obj, time_t start, time_t end, void *c) time_t t, day_end; tm_s = *localtime (&start); - day_end = time_end_of_day (end); + day_end = time_day_end (end); for (t = start; t <= day_end; t += 60*60*24){ time_t new = mktime (&tm_s); diff --git a/calendar/gui/calendar.c b/calendar/gui/calendar.c index a76d95758f..bacd7c9291 100644 --- a/calendar/gui/calendar.c +++ b/calendar/gui/calendar.c @@ -287,8 +287,8 @@ calendar_load (Calendar *cal, char *fname) return "Could not load the calendar"; calendar_today = time (NULL); - calendar_day_begin = time_start_of_day (calendar_today); - calendar_day_end = time_end_of_day (calendar_today); + calendar_day_begin = time_day_begin (calendar_today); + calendar_day_end = time_day_end (calendar_today); calendar_load_from_vobject (cal, vcal); cleanVObject (vcal); diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c index 3189b11300..a44b18e886 100644 --- a/calendar/gui/eventedit.c +++ b/calendar/gui/eventedit.c @@ -565,7 +565,6 @@ ee_store_recur_rule_to_ical (EventEditor *ee) ical->recur->u.month_day = option_menu_active_number (ee->recur_rr_month_weekday); } - break; case 4: diff --git a/calendar/gui/gncal-day-panel.c b/calendar/gui/gncal-day-panel.c index 11a2d21a7d..c4ea354e25 100644 --- a/calendar/gui/gncal-day-panel.c +++ b/calendar/gui/gncal-day-panel.c @@ -128,7 +128,7 @@ gncal_day_panel_new (GnomeCalendar *calendar, time_t start_of_day) 0, 0); gtk_widget_show (w); - w = gncal_full_day_new (calendar, time_start_of_day (start_of_day), time_end_of_day (start_of_day)); + w = gncal_full_day_new (calendar, time_day_begin (start_of_day), time_day_end (start_of_day)); dpanel->fullday = GNCAL_FULL_DAY (w); gtk_signal_connect (GTK_OBJECT (dpanel->fullday), "range_activated", (GtkSignalFunc) day_view_range_activated, @@ -221,7 +221,7 @@ gncal_day_panel_set (GncalDayPanel *dpanel, time_t start_of_day) g_return_if_fail (dpanel != NULL); g_return_if_fail (GNCAL_IS_DAY_PANEL (dpanel)); - dpanel->start_of_day = time_start_of_day (start_of_day); + dpanel->start_of_day = time_day_begin (start_of_day); if (dpanel->fullday->lower == dpanel->start_of_day) return; @@ -229,7 +229,7 @@ gncal_day_panel_set (GncalDayPanel *dpanel, time_t start_of_day) strftime (buf, sizeof (buf), "%a %b %d %Y", &tm); gtk_label_set (GTK_LABEL (dpanel->date_label), buf); - gncal_full_day_set_bounds (dpanel->fullday, dpanel->start_of_day, time_end_of_day (dpanel->start_of_day)); + gncal_full_day_set_bounds (dpanel->fullday, dpanel->start_of_day, time_day_end (dpanel->start_of_day)); gtk_calendar_select_month (dpanel->gtk_calendar, tm.tm_mon, tm.tm_year + 1900); diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c index a84e185eb1..6acc8ca16b 100644 --- a/calendar/gui/gncal-full-day.c +++ b/calendar/gui/gncal-full-day.c @@ -825,7 +825,7 @@ expand_space (char *array, int *allocations, int val, int lower, int count, int for (i = 0; i < count; i++){ slot = allocations [val] + 1; for (j = 0; j < cols; j++) - xy (array, slot, lower+i) = val; + xy (array, slot + j, lower+i) = val; } } diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index fbbd5c2c19..979c6df667 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -94,7 +94,7 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) g_return_if_fail (new_time != -1); - new_time = time_start_of_day (new_time); + new_time = time_day_begin (new_time); if (current == gcal->day_view) gncal_day_panel_set (GNCAL_DAY_PANEL (gcal->day_view), new_time); @@ -192,7 +192,7 @@ gnome_calendar_new (char *title) gtk_window_set_title(GTK_WINDOW(retval), title); - gcal->current_display = time_start_of_day (time (NULL)); + gcal->current_display = time_day_begin (time (NULL)); gcal->cal = calendar_new (title); setup_widgets (gcal); return retval; @@ -385,7 +385,7 @@ mark_gtk_calendar_day (iCalObject *obj, time_t start, time_t end, void *c) time_t t, day_end; tm_s = *localtime (&start); - day_end = time_end_of_day (end); + day_end = time_day_end (end); for (t = start; t <= day_end; t += 60*60*24){ time_t new = mktime (&tm_s); diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 9b468de7f8..7fad966413 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -511,7 +511,7 @@ static void process_dates (void) { if (!from_t) - from_t = time_start_of_day (time (NULL)); + from_t = time_day_begin (time (NULL)); if (!to_t || to_t < from_t) to_t = time_add_day (from_t, 1); diff --git a/calendar/gui/year-view.c b/calendar/gui/year-view.c index 6878080d3a..5746d61803 100644 --- a/calendar/gui/year-view.c +++ b/calendar/gui/year-view.c @@ -325,7 +325,7 @@ do_quick_view_popup (YearView *yv, GdkEventButton *event, int year, int month, i char date_str[256]; day_start = time_from_day (year, month, day); - day_end = time_end_of_day (day_start); + day_end = time_day_end (day_start); list = calendar_get_events_in_range (yv->calendar->cal, day_start, day_end); diff --git a/calendar/main.c b/calendar/main.c index 9b468de7f8..7fad966413 100644 --- a/calendar/main.c +++ b/calendar/main.c @@ -511,7 +511,7 @@ static void process_dates (void) { if (!from_t) - from_t = time_start_of_day (time (NULL)); + from_t = time_day_begin (time (NULL)); if (!to_t || to_t < from_t) to_t = time_add_day (from_t, 1); diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c index 33aff8cda8..9e5f41bc27 100644 --- a/calendar/pcs/calobj.c +++ b/calendar/pcs/calobj.c @@ -1025,15 +1025,28 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) e_t = mktime (&dt_end); - if (s_t == -1 || e_t == -1){ + if ((s_t == -1) || (e_t == -1)) { g_warning ("Produced invalid dates!\n"); return 0; } - return (*cb)(ico, s_t, e_t, closure); + + return (*cb) (ico, s_t, e_t, closure); +} + +int +ical_object_get_first_weekday (int weekday_mask) +{ + int i; + + for (i = 0; i < 7; i++) + if (weekday_mask & (1 << i)) + return i; + + return -1; } -#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1)) -#define recur_in_range(t,r) (r->enddate ? (t < r->enddate) : 1) +#define time_in_range(t, a, b) ((t >= a) && (b ? (t < b) : 1)) +#define recur_in_range(t, r) (r->enddate ? (t < r->enddate) : 1) /* * Generate every possible event. Invokes the callback routine for @@ -1046,88 +1059,104 @@ generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure) { - Recurrence *recur = ico->recur; time_t current; - int first_week_day, i; - - if (!ico->recur){ - if ((end && (ico->dtstart < end) && ico->dtend > start) || - (end == 0 && ico->dtend > start)){ + int first_week_day; + + /* If there is no recurrence, just check ranges */ + + if (!ico->recur) { + if ((end && (ico->dtstart < end) && (ico->dtend > start)) + || ((end == 0) && (ico->dtend > start))) { time_t ev_s, ev_e; - ev_s = ico->dtstart < start ? start : ico->dtstart; - ev_e = ico->dtend > end ? end : ico->dtend; - (*cb)(ico, ev_s, ev_e, closure); + /* Clip range */ + + ev_s = MAX (ico->dtstart, start); + ev_e = MIN (ico->dtend, end); + + (* cb) (ico, ev_s, ev_e, closure); } return; } - /* The event has a recurrence rule */ - if (end != 0){ + /* The event has a recurrence rule -- check that we will generate at least one instance */ + + if (end != 0) { if (ico->dtstart > end) return; - if (!IS_INFINITE (recur) && recur->enddate < start) + + if (!IS_INFINITE (ico->recur) && (ico->recur->enddate < start)) return; } + /* Generate the instances */ + current = ico->dtstart; - switch (recur->type){ + + switch (ico->recur->type) { case RECUR_DAILY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - } /* Advance */ - current = time_add_day (current, recur->interval); - - if (current == -1){ - g_warning ("RECUR_DAILY: mktime error\n"); + + current = time_add_day (current, ico->recur->interval); + + if (current == -1) { + g_warning ("RECUR_DAILY: time_add_day() returned invalid time"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_WEEKLY: do { - struct tm *tm = localtime (¤t); - - if (time_in_range (current, start, end) && recur_in_range (current, recur)){ - if (recur->weekday & (1 << tm->tm_wday)) + struct tm *tm; + + tm = localtime (¤t); + + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) { + /* Weekdays to recur on are specified as a bitmask */ + if (ico->recur->weekday & (1 << tm->tm_wday)) if (!generate (ico, current, cb, closure)) return; } /* Advance by day for scanning the week or by interval at week end */ + if (tm->tm_wday == 6) - current = time_add_day (current, (recur->interval-1) * 7 + 1); + current = time_add_day (current, (ico->recur->interval - 1) * 7 + 1); else current = time_add_day (current, 1); - if (current == -1){ - g_warning ("RECUR_WEEKLY: mktime error\n"); + if (current == -1) { + g_warning ("RECUR_WEEKLY: time_add_day() returned invalid time\n"); return; } } while (current < end || (end == 0)); + break; - + case RECUR_MONTHLY_BY_POS: /* FIXME: We only deal with positives now */ - if (recur->u.month_pos < 0) + if (ico->recur->u.month_pos < 0) { + g_warning ("RECUR_MONTHLY_BY_POS does not support negative positions yet"); return; - - if (recur->u.month_pos == 0) + } + + if (ico->recur->u.month_pos == 0) return; - - first_week_day = 7; - for (i = 6; i >= 0; i--) - if (recur->weekday & (1 << i)) - first_week_day = i; + + first_week_day = ical_object_get_first_weekday (ico->recur->weekday); /* This should not happen, but take it into account */ - if (first_week_day == 7) + if (first_week_day == -1) { + g_warning ("ical_object_get_first_weekday() returned -1"); return; + } do { struct tm tm; @@ -1140,63 +1169,76 @@ ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendar tm = *localtime (&t); week_day_start = tm.tm_wday; - tm.tm_mday = 7 * (recur->u.month_pos - - ((week_day_start <= first_week_day ) ? 1 : 0)) - - (week_day_start - first_week_day) + 1; - + tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0)) + - (week_day_start - first_week_day) + 1); + t = mktime (&tm); - - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + current = mktime (&tm); tm.tm_mday = 1; - tm.tm_mon += recur->interval; + tm.tm_mon += ico->recur->interval; current = mktime (&tm); - if (current == -1){ + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } - } while (current < end || (end == 0)); + } while ((current < end) || (end == 0)); + break; case RECUR_MONTHLY_BY_DAY: do { - struct tm *tm = localtime (¤t); + struct tm *tm; time_t t; int p; + tm = localtime (¤t); + p = tm->tm_mday; - tm->tm_mday = recur->u.month_day; + tm->tm_mday = ico->recur->u.month_day; t = mktime (tm); - if (time_in_range (t, start, end) && recur_in_range (current, recur)) + if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, t, cb, closure)) return; - /* Advance a month */ + /* Advance by the appropriate number of months */ + tm->tm_mday = p; - tm->tm_mon += recur->interval; + tm->tm_mon += ico->recur->interval; current = mktime (tm); - if (current == -1){ + + if (current == -1) { g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); return; } } while (current < end || (end == 0)); + + break; case RECUR_YEARLY_BY_MONTH: case RECUR_YEARLY_BY_DAY: do { - if (time_in_range (current, start, end) && recur_in_range (current, recur)) + if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) if (!generate (ico, current, cb, closure)) return; - + /* Advance */ - current = time_add_year (current, recur->interval); + + current = time_add_year (current, ico->recur->interval); } while (current < end || (end == 0)); + + break; + + default: + g_assert_not_reached (); } } @@ -1210,7 +1252,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) (*count)++; if (ico->recur->duration == *count) { - ico->recur->enddate = time_end_of_day (end); + ico->recur->enddate = time_day_end (end); return 0; } return 1; diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h index d18acd4f8a..05f6d00291 100644 --- a/calendar/pcs/calobj.h +++ b/calendar/pcs/calobj.h @@ -100,7 +100,7 @@ typedef struct { * this is what got specified) or it is our computed * ending date (computed from the duration item). */ - + int weekday; union { @@ -175,7 +175,7 @@ typedef struct { } iCalObject; /* The callback for the recurrence generator */ -typedef int (*calendarfn)(iCalObject *, time_t, time_t, void *); +typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *); iCalObject *ical_new (char *comment, char *organizer, char *summary); iCalObject *ical_object_new (void); @@ -190,6 +190,11 @@ void ical_object_add_exdate (iCalObject *o, time_t t); /* Computes the enddate field of the recurrence based on the duration */ void ical_object_compute_end (iCalObject *ico); +/* Returns the first toggled day in a weekday mask -- we do this because we do not support multiple + * days on a monthly-by-pos recurrence. If no days are toggled, it returns -1. + */ +int ical_object_get_first_weekday (int weekday_mask); + /* Returns the number of seconds configured to trigger the alarm in advance to an event */ int alarm_compute_offset (CalendarAlarm *a); diff --git a/calendar/timeutil.c b/calendar/timeutil.c index 5d4008e75d..7a0550c069 100644 --- a/calendar/timeutil.c +++ b/calendar/timeutil.c @@ -210,34 +210,38 @@ time_from_day (int year, int month, int day) } time_t -time_start_of_day (time_t t) +time_year_begin (time_t t) { struct tm tm; - + tm = *localtime (&t); tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; + tm.tm_mon = 0; + tm.tm_mday = 1; return mktime (&tm); } time_t -time_end_of_day (time_t t) +time_year_end (time_t t) { struct tm tm; - + tm = *localtime (&t); tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; - tm.tm_mday++; - + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_year++; + return mktime (&tm); } time_t -time_year_begin (time_t t) +time_month_begin (time_t t) { struct tm tm; @@ -245,62 +249,82 @@ time_year_begin (time_t t) tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; - tm.tm_mon = 0; tm.tm_mday = 1; return mktime (&tm); } time_t -time_year_end (time_t t) +time_month_end (time_t t) { struct tm tm; tm = *localtime (&t); - tm.tm_hour = 23; - tm.tm_min = 59; - tm.tm_sec = 59; - tm.tm_mon = 11; - tm.tm_mday = 31; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday = 1; + tm.tm_mon++; return mktime (&tm); } time_t -time_month_begin (time_t t) +time_week_begin (time_t t) { struct tm tm; + /* FIXME: make it take week_starts_on_monday into account */ + tm = *localtime (&t); tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; - tm.tm_mday = 1; + tm.tm_mday -= tm.tm_wday; return mktime (&tm); } time_t -time_month_end (time_t t) +time_week_end (time_t t) { struct tm tm; + /* FIXME: make it take week_starts_on_monday into account */ + tm = *localtime (&t); - tm.tm_hour = 23; - tm.tm_min = 59; - tm.tm_sec = 59; - tm.tm_mday = time_days_in_month (tm.tm_year + 1900, tm.tm_mon); + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday += 7 - tm.tm_wday; return mktime (&tm); } time_t -time_week_begin (time_t t) +time_day_begin (time_t t) { struct tm tm; + + tm = *localtime (&t); + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + + return mktime (&tm); +} +time_t +time_day_end (time_t t) +{ + struct tm tm; + tm = *localtime (&t); - tm.tm_mday -= tm.tm_wday; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_mday++; + return mktime (&tm); } diff --git a/calendar/timeutil.h b/calendar/timeutil.h index ac006012ac..2c2ddfcbac 100644 --- a/calendar/timeutil.h +++ b/calendar/timeutil.h @@ -43,10 +43,12 @@ int time_days_in_month (int year, int month); */ time_t time_from_day (int year, int month, int day); -time_t time_start_of_day (time_t t); -time_t time_end_of_day (time_t t); time_t time_day_hour (time_t t, int hour); +/* For the functions below, time ranges are considered to contain the start time, but not the end + * time. + */ + /* These two functions take a time value and return the beginning or end of the corresponding year, * respectively. */ @@ -65,6 +67,13 @@ time_t time_month_end (time_t t); time_t time_week_begin (time_t t); time_t time_week_end (time_t t); +/* These two functions take a time value and return the beginning or end of the corresponding day, + * respectively. + */ +time_t time_day_begin (time_t t); +time_t time_day_end (time_t t); + + time_t parse_date (char *str); void print_time_t (time_t t); diff --git a/calendar/year-view.c b/calendar/year-view.c index 6878080d3a..5746d61803 100644 --- a/calendar/year-view.c +++ b/calendar/year-view.c @@ -325,7 +325,7 @@ do_quick_view_popup (YearView *yv, GdkEventButton *event, int year, int month, i char date_str[256]; day_start = time_from_day (year, month, day); - day_end = time_end_of_day (day_start); + day_end = time_day_end (day_start); list = calendar_get_events_in_range (yv->calendar->cal, day_start, day_end); |