aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog24
-rw-r--r--calendar/cal-util/calobj.c164
-rw-r--r--calendar/cal-util/calobj.h9
-rw-r--r--calendar/calendar.c4
-rw-r--r--calendar/calobj.c164
-rw-r--r--calendar/calobj.h9
-rw-r--r--calendar/eventedit.c1
-rw-r--r--calendar/gncal-day-panel.c6
-rw-r--r--calendar/gncal-full-day.c2
-rw-r--r--calendar/gnome-cal.c6
-rw-r--r--calendar/gui/calendar.c4
-rw-r--r--calendar/gui/eventedit.c1
-rw-r--r--calendar/gui/gncal-day-panel.c6
-rw-r--r--calendar/gui/gncal-full-day.c2
-rw-r--r--calendar/gui/gnome-cal.c6
-rw-r--r--calendar/gui/main.c2
-rw-r--r--calendar/gui/year-view.c2
-rw-r--r--calendar/main.c2
-rw-r--r--calendar/pcs/calobj.c164
-rw-r--r--calendar/pcs/calobj.h9
-rw-r--r--calendar/timeutil.c70
-rw-r--r--calendar/timeutil.h13
-rw-r--r--calendar/year-view.c2
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 (&current);
-
- if (time_in_range (current, start, end) && recur_in_range (current, recur)){
- if (recur->weekday & (1 << tm->tm_wday))
+ struct tm *tm;
+
+ tm = localtime (&current);
+
+ 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 (&current);
+ struct tm *tm;
time_t t;
int p;
+ tm = localtime (&current);
+
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 (&current);
-
- if (time_in_range (current, start, end) && recur_in_range (current, recur)){
- if (recur->weekday & (1 << tm->tm_wday))
+ struct tm *tm;
+
+ tm = localtime (&current);
+
+ 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 (&current);
+ struct tm *tm;
time_t t;
int p;
+ tm = localtime (&current);
+
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 (&current);
-
- if (time_in_range (current, start, end) && recur_in_range (current, recur)){
- if (recur->weekday & (1 << tm->tm_wday))
+ struct tm *tm;
+
+ tm = localtime (&current);
+
+ 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 (&current);
+ struct tm *tm;
time_t t;
int p;
+ tm = localtime (&current);
+
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);