aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
authorArturo Espinosa <unammx@src.gnome.org>1998-04-18 03:35:43 +0800
committerArturo Espinosa <unammx@src.gnome.org>1998-04-18 03:35:43 +0800
commit55f88f14fed53f67e4b3cd5337cbe92aee0ec638 (patch)
treed783e0896a0649b70ec67c13073841c7f3fbd64f /calendar
parentad0347d16bfd10f5f6b0783d7030cac420c4362a (diff)
downloadgsoc2013-evolution-55f88f14fed53f67e4b3cd5337cbe92aee0ec638.tar.gz
gsoc2013-evolution-55f88f14fed53f67e4b3cd5337cbe92aee0ec638.tar.zst
gsoc2013-evolution-55f88f14fed53f67e4b3cd5337cbe92aee0ec638.zip
Large number of updates. Recurrence basically works now in most of its
Large number of updates. Recurrence basically works now in most of its forms (daily, weekly, month-by-position). Miguel. svn path=/trunk/; revision=148
Diffstat (limited to 'calendar')
-rw-r--r--calendar/cal-util/calobj.c212
-rw-r--r--calendar/cal-util/calobj.h18
-rw-r--r--calendar/calendar.c16
-rw-r--r--calendar/calendar.h2
-rw-r--r--calendar/calobj.c212
-rw-r--r--calendar/calobj.h18
-rw-r--r--calendar/gncal-full-day.c10
-rw-r--r--calendar/gnome-cal.c7
-rw-r--r--calendar/gui/calendar.c16
-rw-r--r--calendar/gui/calendar.h2
-rw-r--r--calendar/gui/gncal-full-day.c10
-rw-r--r--calendar/gui/gnome-cal.c7
-rw-r--r--calendar/gui/test.vcf23
-rw-r--r--calendar/gui/year-view.c76
-rw-r--r--calendar/pcs/calobj.c212
-rw-r--r--calendar/pcs/calobj.h18
-rw-r--r--calendar/test.vcf23
-rw-r--r--calendar/timeutil.c28
-rw-r--r--calendar/timeutil.h13
-rw-r--r--calendar/year-view.c76
20 files changed, 807 insertions, 192 deletions
diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c
index c2fadad4d7..76bb488663 100644
--- a/calendar/cal-util/calobj.c
+++ b/calendar/cal-util/calobj.c
@@ -12,6 +12,8 @@
#include "timeutil.h"
#include "versit/vcc.h"
+static void ical_object_compute_end (iCalObject *ico);
+
iCalObject *
ical_object_new (void)
{
@@ -35,7 +37,6 @@ default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum Alar
alarm->count = 15;
alarm->units = ALARM_MINUTES;
} else {
- printf ("uno!\n");
alarm->count = 1;
alarm->units = ALARM_DAYS;
}
@@ -140,7 +141,7 @@ static void
ignore_space(char **str)
{
while (**str && isspace (**str))
- str++;
+ (*str)++;
}
static void
@@ -183,6 +184,12 @@ weekdaylist (iCalObject *o, char **str)
}
}
} while (isalpha (**str));
+
+ if (o->recur->weekday == 0){
+ struct tm *tm = localtime (&o->dtstart);
+
+ o->recur->weekday = 1 << tm->tm_wday;
+ }
}
static void
@@ -223,11 +230,11 @@ daynumber (iCalObject *o, char **str)
while (**str && isdigit (**str)){
val = val * 10 + (**str - '0');
- str++;
+ (*str)++;
}
if (**str == '+')
- str++;
+ (*str)++;
if (**str == '-')
val *= -1;
@@ -245,8 +252,10 @@ daynumberlist (iCalObject *o, char **str)
while (**str){
if (!isdigit (**str))
return;
- while (**str && isdigit (**str))
+ while (**str && isdigit (**str)){
val = 10 * val + (**str - '0');
+ (*str)++;
+ }
if (!first){
o->recur->u.month_day = val;
first = 1;
@@ -300,10 +309,12 @@ duration (iCalObject *o, char **str)
ignore_space (str);
if (**str != '#')
return;
- while (**str && isdigit (**str))
+ (*str)++;
+ while (**str && isdigit (**str)){
duration = duration * 10 + (**str - '0');
-
- o->recur->temp_duration = duration;
+ (*str)++;
+ }
+ o->recur->duration = duration;
}
static void
@@ -311,7 +322,7 @@ enddate (iCalObject *o, char **str)
{
ignore_space (str);
if (isdigit (**str)){
- o->recur->enddate = time_from_isodate (*str);
+ o->recur->_enddate = time_from_isodate (*str);
*str += 16;
}
}
@@ -335,7 +346,7 @@ load_recurrence (iCalObject *o, char *str)
case 'M':
if (*str == 'P')
type = RECUR_MONTHLY_BY_POS;
- else if (*str == 'D')
+ else if (*str == 'D')
type = RECUR_MONTHLY_BY_DAY;
str++;
break;
@@ -356,13 +367,18 @@ load_recurrence (iCalObject *o, char *str)
ignore_space (&str);
/* Get the interval */
- while (*str && isdigit (*str))
+ for (;*str && isdigit (*str);str++)
interval = interval * 10 + (*str-'0');
o->recur->interval = interval;
+
+ /* this is the default per the spec */
+ o->recur->duration = 2;
ignore_space (&str);
switch (type){
+ case RECUR_DAILY:
+ break;
case RECUR_WEEKLY:
load_recur_weekly (o, &str);
break;
@@ -385,6 +401,17 @@ load_recurrence (iCalObject *o, char *str)
duration (o, &str);
enddate (o, &str);
+ /* Compute the enddate */
+ if (o->recur->_enddate == 0){
+ printf ("ENDDATE es 0, d=%d\n", o->recur->duration);
+ if (o->recur->duration != 0){
+ ical_object_compute_end (o);
+ } else
+ o->recur->enddate = 0;
+ } else {
+ printf ("El evento termina\n");
+ o->recur->enddate = o->recur->_enddate;
+ }
return 1;
}
@@ -689,14 +716,173 @@ ical_foreach (GList *events, calendarfn fn, void *closure)
}
}
+static int
+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);
+
+ dt_start.tm_mday = ref.tm_mday;
+ dt_start.tm_mon = ref.tm_mon;
+ dt_start.tm_year = ref.tm_year;
+
+ dt_end.tm_mday = ref.tm_mday;
+ dt_end.tm_mon = ref.tm_mon;
+ dt_end.tm_year = ref.tm_year;
+
+ s_t = mktime (&dt_start);
+ e_t = mktime (&dt_end);
+ if (s_t == -1 || e_t == -1){
+ g_warning ("Produced invalid dates!\n");
+ return 0;
+ }
+ return (*cb)(ico, s_t, e_t, closure);
+}
+
+#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1))
+
+/*
+ * Generate every possible event. Invokes the callback routine for
+ * every occurrence of the event in the [START, END] time interval.
+ *
+ * If END is zero, the event is generated forever.
+ * The callback routine is expected to return 0 when no further event
+ * generation is requested.
+ */
void
ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure)
{
+ Recurrence *recur = ico->recur;
+ time_t current;
+
if (!ico->recur){
- if ((start <= ico->dtstart) && (ico->dtend <= end))
- (*cb)(ico, ico->dtstart, ico->dtend, closure);
+ if (time_in_range (ico->dtstart, start, end) ||
+ time_in_range (ico->dtend, start, end)){
+ 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);
+ }
return;
}
/* The event has a recurrence rule */
+ if (end != 0){
+ if (ico->dtstart > end)
+ return;
+ if (!IS_INFINITE (ico->recur) && recur->enddate < start)
+ return;
+ }
+
+ current = ico->dtstart;
+ switch (recur->type){
+ case RECUR_DAILY:
+ do {
+ if (time_in_range (current, start, end)){
+ 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");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_WEEKLY:
+ do {
+ struct tm *tm = localtime (&current);
+
+ if (time_in_range (current, start, end)){
+ if (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);
+ else
+ current = time_add_day (current, 1);
+
+ if (current == -1){
+ g_warning ("RECUR_WEEKLY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_MONTHLY_BY_POS:
+ g_warning ("We still do not handle MONTHLY_BY_POS\n");
+ break;
+
+ case RECUR_MONTHLY_BY_DAY:
+ do {
+ struct tm *tm = localtime (&current);
+ time_t t;
+ int p;
+
+ p = tm->tm_mday;
+ tm->tm_mday = recur->u.month_day;
+ t = mktime (tm);
+ if (time_in_range (t, start, end))
+ if (!generate (ico, t, cb, closure))
+ return;
+
+ /* Advance a month */
+ tm->tm_mday = p;
+ tm->tm_mon += recur->interval;
+ current = mktime (tm);
+ if (current == -1){
+ g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+
+ case RECUR_YEARLY_BY_MONTH:
+ case RECUR_YEARLY_BY_DAY:
+ do {
+ if (time_in_range (current, start, end))
+ if (!generate (ico, current, cb, closure))
+ return;
+
+ /* Advance */
+ current = time_add_year (current, recur->interval);
+ } while (current < end || (end == 0));
+ }
+}
+
+static int
+duration_callback (iCalObject *ico, time_t start, time_t end, void *closure)
+{
+ int *count = closure;
+
+ (*count)++;
+ if (ico->recur->duration == *count){
+ ico->recur->enddate = end;
+ return 0;
+ }
+ return 1;
}
+
+/* Computes ico->recur->enddate from ico->recur->duration */
+void
+ical_object_compute_end (iCalObject *ico)
+{
+ int count = 0;
+
+ g_return_if_fail (ico->recur != NULL);
+
+ ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count);
+}
+
+
diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h
index ab9d061956..8cbdffa484 100644
--- a/calendar/cal-util/calobj.h
+++ b/calendar/cal-util/calobj.h
@@ -86,16 +86,26 @@ typedef struct {
enum RecurType type;
int interval;
- time_t enddate;
+
+ /* Used for recur computation */
+ time_t enddate; /* If the value is zero, it is an infinite event
+ * otherwise, it is either the _enddate value (if
+ * this is what got specified) or it is our computed
+ * ending date (computed from the duration item).
+ */
+
int weekday;
union {
int month_pos;
int month_day;
} u;
-
- int temp_duration; /* Used temporarly, we compute enddate */
+
+ int duration;
+ time_t _enddate; /* As found on the vCalendar file */
+ int __count;
} Recurrence;
+#define IS_INFINITE(r) (r->duration == 0)
/* Flags to indicate what has changed in an object */
typedef enum {
@@ -157,7 +167,7 @@ typedef struct {
} iCalObject;
/* The callback for the recurrence generator */
-typedef void (*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);
diff --git a/calendar/calendar.c b/calendar/calendar.c
index 7b5f50c46f..641d6d765e 100644
--- a/calendar/calendar.c
+++ b/calendar/calendar.c
@@ -207,21 +207,25 @@ calendar_load_from_vobject (Calendar *cal, VObject *vcal)
}
/* Loads a calendar from a file */
-void
+char *
calendar_load (Calendar *cal, char *fname)
{
VObject *vcal;
if (cal->filename){
g_warning ("Calendar load called again\n");
- return;
+ return "Internal error";
}
cal->filename = g_strdup (fname);
vcal = Parse_MIME_FromFileName (fname);
+ if (!vcal)
+ return "Could not load the calendar";
+
calendar_load_from_vobject (cal, vcal);
cleanVObject (vcal);
cleanStrTbl ();
+ return NULL;
}
void
@@ -250,7 +254,7 @@ calendar_save (Calendar *cal, char *fname)
cleanStrTbl ();
}
-static void
+static gint
calendar_object_compare_by_start (gpointer a, gpointer b)
{
CalendarObject *ca = a;
@@ -261,7 +265,7 @@ calendar_object_compare_by_start (gpointer a, gpointer b)
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
-static void
+static int
assemble_event_list (iCalObject *obj, time_t start, time_t end, void *c)
{
CalendarObject *co;
@@ -272,6 +276,8 @@ assemble_event_list (iCalObject *obj, time_t start, time_t end, void *c)
co->ev_end = end;
co->ico = obj;
*l = g_list_insert_sorted (*l, co, calendar_object_compare_by_start);
+
+ return 1;
}
void
@@ -280,7 +286,7 @@ calendar_destroy_event_list (GList *l)
GList *p;
for (p = l; p; p = p->next)
- g_free (l->data);
+ g_free (p->data);
g_list_free (l);
}
diff --git a/calendar/calendar.h b/calendar/calendar.h
index 9fbb6088a4..e68b74ebf4 100644
--- a/calendar/calendar.h
+++ b/calendar/calendar.h
@@ -38,7 +38,7 @@ typedef struct {
} CalendarObject;
Calendar *calendar_new (char *title);
-void calendar_load (Calendar *cal, char *fname);
+char *calendar_load (Calendar *cal, char *fname);
void calendar_add_object (Calendar *cal, iCalObject *obj);
void calendar_remove_object (Calendar *cal, iCalObject *obj);
void calendar_destroy (Calendar *cal);
diff --git a/calendar/calobj.c b/calendar/calobj.c
index c2fadad4d7..76bb488663 100644
--- a/calendar/calobj.c
+++ b/calendar/calobj.c
@@ -12,6 +12,8 @@
#include "timeutil.h"
#include "versit/vcc.h"
+static void ical_object_compute_end (iCalObject *ico);
+
iCalObject *
ical_object_new (void)
{
@@ -35,7 +37,6 @@ default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum Alar
alarm->count = 15;
alarm->units = ALARM_MINUTES;
} else {
- printf ("uno!\n");
alarm->count = 1;
alarm->units = ALARM_DAYS;
}
@@ -140,7 +141,7 @@ static void
ignore_space(char **str)
{
while (**str && isspace (**str))
- str++;
+ (*str)++;
}
static void
@@ -183,6 +184,12 @@ weekdaylist (iCalObject *o, char **str)
}
}
} while (isalpha (**str));
+
+ if (o->recur->weekday == 0){
+ struct tm *tm = localtime (&o->dtstart);
+
+ o->recur->weekday = 1 << tm->tm_wday;
+ }
}
static void
@@ -223,11 +230,11 @@ daynumber (iCalObject *o, char **str)
while (**str && isdigit (**str)){
val = val * 10 + (**str - '0');
- str++;
+ (*str)++;
}
if (**str == '+')
- str++;
+ (*str)++;
if (**str == '-')
val *= -1;
@@ -245,8 +252,10 @@ daynumberlist (iCalObject *o, char **str)
while (**str){
if (!isdigit (**str))
return;
- while (**str && isdigit (**str))
+ while (**str && isdigit (**str)){
val = 10 * val + (**str - '0');
+ (*str)++;
+ }
if (!first){
o->recur->u.month_day = val;
first = 1;
@@ -300,10 +309,12 @@ duration (iCalObject *o, char **str)
ignore_space (str);
if (**str != '#')
return;
- while (**str && isdigit (**str))
+ (*str)++;
+ while (**str && isdigit (**str)){
duration = duration * 10 + (**str - '0');
-
- o->recur->temp_duration = duration;
+ (*str)++;
+ }
+ o->recur->duration = duration;
}
static void
@@ -311,7 +322,7 @@ enddate (iCalObject *o, char **str)
{
ignore_space (str);
if (isdigit (**str)){
- o->recur->enddate = time_from_isodate (*str);
+ o->recur->_enddate = time_from_isodate (*str);
*str += 16;
}
}
@@ -335,7 +346,7 @@ load_recurrence (iCalObject *o, char *str)
case 'M':
if (*str == 'P')
type = RECUR_MONTHLY_BY_POS;
- else if (*str == 'D')
+ else if (*str == 'D')
type = RECUR_MONTHLY_BY_DAY;
str++;
break;
@@ -356,13 +367,18 @@ load_recurrence (iCalObject *o, char *str)
ignore_space (&str);
/* Get the interval */
- while (*str && isdigit (*str))
+ for (;*str && isdigit (*str);str++)
interval = interval * 10 + (*str-'0');
o->recur->interval = interval;
+
+ /* this is the default per the spec */
+ o->recur->duration = 2;
ignore_space (&str);
switch (type){
+ case RECUR_DAILY:
+ break;
case RECUR_WEEKLY:
load_recur_weekly (o, &str);
break;
@@ -385,6 +401,17 @@ load_recurrence (iCalObject *o, char *str)
duration (o, &str);
enddate (o, &str);
+ /* Compute the enddate */
+ if (o->recur->_enddate == 0){
+ printf ("ENDDATE es 0, d=%d\n", o->recur->duration);
+ if (o->recur->duration != 0){
+ ical_object_compute_end (o);
+ } else
+ o->recur->enddate = 0;
+ } else {
+ printf ("El evento termina\n");
+ o->recur->enddate = o->recur->_enddate;
+ }
return 1;
}
@@ -689,14 +716,173 @@ ical_foreach (GList *events, calendarfn fn, void *closure)
}
}
+static int
+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);
+
+ dt_start.tm_mday = ref.tm_mday;
+ dt_start.tm_mon = ref.tm_mon;
+ dt_start.tm_year = ref.tm_year;
+
+ dt_end.tm_mday = ref.tm_mday;
+ dt_end.tm_mon = ref.tm_mon;
+ dt_end.tm_year = ref.tm_year;
+
+ s_t = mktime (&dt_start);
+ e_t = mktime (&dt_end);
+ if (s_t == -1 || e_t == -1){
+ g_warning ("Produced invalid dates!\n");
+ return 0;
+ }
+ return (*cb)(ico, s_t, e_t, closure);
+}
+
+#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1))
+
+/*
+ * Generate every possible event. Invokes the callback routine for
+ * every occurrence of the event in the [START, END] time interval.
+ *
+ * If END is zero, the event is generated forever.
+ * The callback routine is expected to return 0 when no further event
+ * generation is requested.
+ */
void
ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure)
{
+ Recurrence *recur = ico->recur;
+ time_t current;
+
if (!ico->recur){
- if ((start <= ico->dtstart) && (ico->dtend <= end))
- (*cb)(ico, ico->dtstart, ico->dtend, closure);
+ if (time_in_range (ico->dtstart, start, end) ||
+ time_in_range (ico->dtend, start, end)){
+ 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);
+ }
return;
}
/* The event has a recurrence rule */
+ if (end != 0){
+ if (ico->dtstart > end)
+ return;
+ if (!IS_INFINITE (ico->recur) && recur->enddate < start)
+ return;
+ }
+
+ current = ico->dtstart;
+ switch (recur->type){
+ case RECUR_DAILY:
+ do {
+ if (time_in_range (current, start, end)){
+ 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");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_WEEKLY:
+ do {
+ struct tm *tm = localtime (&current);
+
+ if (time_in_range (current, start, end)){
+ if (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);
+ else
+ current = time_add_day (current, 1);
+
+ if (current == -1){
+ g_warning ("RECUR_WEEKLY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_MONTHLY_BY_POS:
+ g_warning ("We still do not handle MONTHLY_BY_POS\n");
+ break;
+
+ case RECUR_MONTHLY_BY_DAY:
+ do {
+ struct tm *tm = localtime (&current);
+ time_t t;
+ int p;
+
+ p = tm->tm_mday;
+ tm->tm_mday = recur->u.month_day;
+ t = mktime (tm);
+ if (time_in_range (t, start, end))
+ if (!generate (ico, t, cb, closure))
+ return;
+
+ /* Advance a month */
+ tm->tm_mday = p;
+ tm->tm_mon += recur->interval;
+ current = mktime (tm);
+ if (current == -1){
+ g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+
+ case RECUR_YEARLY_BY_MONTH:
+ case RECUR_YEARLY_BY_DAY:
+ do {
+ if (time_in_range (current, start, end))
+ if (!generate (ico, current, cb, closure))
+ return;
+
+ /* Advance */
+ current = time_add_year (current, recur->interval);
+ } while (current < end || (end == 0));
+ }
+}
+
+static int
+duration_callback (iCalObject *ico, time_t start, time_t end, void *closure)
+{
+ int *count = closure;
+
+ (*count)++;
+ if (ico->recur->duration == *count){
+ ico->recur->enddate = end;
+ return 0;
+ }
+ return 1;
}
+
+/* Computes ico->recur->enddate from ico->recur->duration */
+void
+ical_object_compute_end (iCalObject *ico)
+{
+ int count = 0;
+
+ g_return_if_fail (ico->recur != NULL);
+
+ ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count);
+}
+
+
diff --git a/calendar/calobj.h b/calendar/calobj.h
index ab9d061956..8cbdffa484 100644
--- a/calendar/calobj.h
+++ b/calendar/calobj.h
@@ -86,16 +86,26 @@ typedef struct {
enum RecurType type;
int interval;
- time_t enddate;
+
+ /* Used for recur computation */
+ time_t enddate; /* If the value is zero, it is an infinite event
+ * otherwise, it is either the _enddate value (if
+ * this is what got specified) or it is our computed
+ * ending date (computed from the duration item).
+ */
+
int weekday;
union {
int month_pos;
int month_day;
} u;
-
- int temp_duration; /* Used temporarly, we compute enddate */
+
+ int duration;
+ time_t _enddate; /* As found on the vCalendar file */
+ int __count;
} Recurrence;
+#define IS_INFINITE(r) (r->duration == 0)
/* Flags to indicate what has changed in an object */
typedef enum {
@@ -157,7 +167,7 @@ typedef struct {
} iCalObject;
/* The callback for the recurrence generator */
-typedef void (*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);
diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c
index b048ba9de7..c3151f6dcf 100644
--- a/calendar/gncal-full-day.c
+++ b/calendar/gncal-full-day.c
@@ -1447,7 +1447,7 @@ button_1 (GncalFullDay *fullday, GdkEventButton *event)
child = find_child_by_window (fullday, event->window, &on_text);
- if (!child || on_text)
+ if (!child || on_text || child->ico->recur)
return FALSE;
/* Prepare for drag */
@@ -1647,8 +1647,8 @@ update_from_drag_info (GncalFullDay *fullday)
widget = GTK_WIDGET (fullday);
get_time_from_rows (fullday, di->child_start_row, di->child_rows_used,
- &di->child->start,
- &di->child->end);
+ &di->child->ico->dtstart,
+ &di->child->ico->dtend);
child_range_changed (fullday, di->child);
@@ -1878,7 +1878,7 @@ child_compare_by_start (gpointer a, gpointer b)
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
-static void
+static int
fullday_add_children (iCalObject *obj, time_t start, time_t end, void *c)
{
GncalFullDay *fullday = c;
@@ -1886,6 +1886,8 @@ fullday_add_children (iCalObject *obj, time_t start, time_t end, void *c)
child = child_new (fullday, start, end, obj);
fullday->children = g_list_insert_sorted (fullday->children, child, child_compare_by_start);
+
+ return 1;
}
void
diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c
index e38f818c49..c6ca54331f 100644
--- a/calendar/gnome-cal.c
+++ b/calendar/gnome-cal.c
@@ -198,7 +198,12 @@ gnome_calendar_update_all (GnomeCalendar *cal, iCalObject *object, int flags)
void
gnome_calendar_load (GnomeCalendar *gcal, char *file)
{
- calendar_load (gcal->cal, file);
+ char *r;
+
+ if ((r = calendar_load (gcal->cal, file)) != NULL){
+ printf ("Error loading calendar: %s\n", r);
+ return;
+ }
gnome_calendar_update_all (gcal, NULL, 0);
}
diff --git a/calendar/gui/calendar.c b/calendar/gui/calendar.c
index 7b5f50c46f..641d6d765e 100644
--- a/calendar/gui/calendar.c
+++ b/calendar/gui/calendar.c
@@ -207,21 +207,25 @@ calendar_load_from_vobject (Calendar *cal, VObject *vcal)
}
/* Loads a calendar from a file */
-void
+char *
calendar_load (Calendar *cal, char *fname)
{
VObject *vcal;
if (cal->filename){
g_warning ("Calendar load called again\n");
- return;
+ return "Internal error";
}
cal->filename = g_strdup (fname);
vcal = Parse_MIME_FromFileName (fname);
+ if (!vcal)
+ return "Could not load the calendar";
+
calendar_load_from_vobject (cal, vcal);
cleanVObject (vcal);
cleanStrTbl ();
+ return NULL;
}
void
@@ -250,7 +254,7 @@ calendar_save (Calendar *cal, char *fname)
cleanStrTbl ();
}
-static void
+static gint
calendar_object_compare_by_start (gpointer a, gpointer b)
{
CalendarObject *ca = a;
@@ -261,7 +265,7 @@ calendar_object_compare_by_start (gpointer a, gpointer b)
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
-static void
+static int
assemble_event_list (iCalObject *obj, time_t start, time_t end, void *c)
{
CalendarObject *co;
@@ -272,6 +276,8 @@ assemble_event_list (iCalObject *obj, time_t start, time_t end, void *c)
co->ev_end = end;
co->ico = obj;
*l = g_list_insert_sorted (*l, co, calendar_object_compare_by_start);
+
+ return 1;
}
void
@@ -280,7 +286,7 @@ calendar_destroy_event_list (GList *l)
GList *p;
for (p = l; p; p = p->next)
- g_free (l->data);
+ g_free (p->data);
g_list_free (l);
}
diff --git a/calendar/gui/calendar.h b/calendar/gui/calendar.h
index 9fbb6088a4..e68b74ebf4 100644
--- a/calendar/gui/calendar.h
+++ b/calendar/gui/calendar.h
@@ -38,7 +38,7 @@ typedef struct {
} CalendarObject;
Calendar *calendar_new (char *title);
-void calendar_load (Calendar *cal, char *fname);
+char *calendar_load (Calendar *cal, char *fname);
void calendar_add_object (Calendar *cal, iCalObject *obj);
void calendar_remove_object (Calendar *cal, iCalObject *obj);
void calendar_destroy (Calendar *cal);
diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c
index b048ba9de7..c3151f6dcf 100644
--- a/calendar/gui/gncal-full-day.c
+++ b/calendar/gui/gncal-full-day.c
@@ -1447,7 +1447,7 @@ button_1 (GncalFullDay *fullday, GdkEventButton *event)
child = find_child_by_window (fullday, event->window, &on_text);
- if (!child || on_text)
+ if (!child || on_text || child->ico->recur)
return FALSE;
/* Prepare for drag */
@@ -1647,8 +1647,8 @@ update_from_drag_info (GncalFullDay *fullday)
widget = GTK_WIDGET (fullday);
get_time_from_rows (fullday, di->child_start_row, di->child_rows_used,
- &di->child->start,
- &di->child->end);
+ &di->child->ico->dtstart,
+ &di->child->ico->dtend);
child_range_changed (fullday, di->child);
@@ -1878,7 +1878,7 @@ child_compare_by_start (gpointer a, gpointer b)
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
-static void
+static int
fullday_add_children (iCalObject *obj, time_t start, time_t end, void *c)
{
GncalFullDay *fullday = c;
@@ -1886,6 +1886,8 @@ fullday_add_children (iCalObject *obj, time_t start, time_t end, void *c)
child = child_new (fullday, start, end, obj);
fullday->children = g_list_insert_sorted (fullday->children, child, child_compare_by_start);
+
+ return 1;
}
void
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index e38f818c49..c6ca54331f 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -198,7 +198,12 @@ gnome_calendar_update_all (GnomeCalendar *cal, iCalObject *object, int flags)
void
gnome_calendar_load (GnomeCalendar *gcal, char *file)
{
- calendar_load (gcal->cal, file);
+ char *r;
+
+ if ((r = calendar_load (gcal->cal, file)) != NULL){
+ printf ("Error loading calendar: %s\n", r);
+ return;
+ }
gnome_calendar_update_all (gcal, NULL, 0);
}
diff --git a/calendar/gui/test.vcf b/calendar/gui/test.vcf
index 7d41d14878..b0892bbf5f 100644
--- a/calendar/gui/test.vcf
+++ b/calendar/gui/test.vcf
@@ -8,34 +8,19 @@ DCREATED:19980402T023552
UID:KOrganizer - 1804289383
SEQUENCE:1
LAST-MODIFIED:19980330T225948
-DTSTART:19980415T003000
-DTEND:19980415T010000
-SUMMARY:asdfasdfasfasdfasdf
+DTSTART:19980415T116000
+DTEND:19980415T119000
+SUMMARY:Mensual, el 15, durante 4 semanas
STATUS:NEEDS ACTION
CLASS:PUBLIC
PRIORITY:0
TRANSP:0
+RRULE:MD1 15 #4
RELATED-TO:0
X-PILOTID:0
X-PILOTSTAT:0
END:VEVENT
-BEGIN:VEVENT
-DCREATED:19980402T023558
-UID:KOrganizer - 846930886
-SEQUENCE:1
-LAST-MODIFIED:19980402T023558
-DTSTART:19980415T140000
-DTEND:19980415T160000
-SUMMARY:asdfasfdasfasdfasfd
-STATUS:NEEDS ACTION
-CLASS:PUBLIC
-PRIORITY:0
-TRANSP:0
-RELATED-TO:0
-X-PILOTID:0
-X-PILOTSTAT:0
-END:VEVENT
END:VCALENDAR
diff --git a/calendar/gui/year-view.c b/calendar/gui/year-view.c
index 8f5a786239..a8972a7558 100644
--- a/calendar/gui/year-view.c
+++ b/calendar/gui/year-view.c
@@ -136,23 +136,6 @@ gncal_year_view_new (GnomeCalendar *calendar, time_t date)
return GTK_WIDGET (yview);
}
-void gncal_year_view_set (GncalYearView *yview, time_t date)
-{
- int i;
- char buff[10];
- struct tm *tmptm;
-
- tmptm = localtime(&date);
- yview->year = tmptm->tm_year;
-
- snprintf(buff, 10, "%d", yview->year + 1900);
- gtk_label_set(GTK_LABEL(yview->year_label), buff);
-
- for (i = 0; i < 12; i++) {
- gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year);
- }
-}
-
static void
year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure)
{
@@ -174,6 +157,47 @@ year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure)
}
}
+static void
+gncal_year_view_set_year (GncalYearView *yview, int year)
+{
+ time_t year_begin, year_end;
+ char buff[20];
+ GList *l;
+ int i;
+
+ if (!yview->gcal->cal)
+ return;
+
+ snprintf(buff, 20, "%d", yview->year + 1900);
+ gtk_label_set(GTK_LABEL(yview->year_label), buff);
+
+ for (i = 0; i < 12; i++) {
+ gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year);
+ }
+
+ year_begin = time_year_begin (yview->year);
+ year_end = time_year_end (yview->year);
+
+ l = calendar_get_events_in_range (yview->gcal->cal, year_begin, year_end);
+ for (; l; l = l->next){
+ CalendarObject *co = l->data;
+
+ year_view_mark_day (co->ico, co->ev_start, co->ev_end, yview);
+ }
+ calendar_destroy_event_list (l);
+}
+
+void
+gncal_year_view_set (GncalYearView *yview, time_t date)
+{
+ struct tm *tmptm;
+
+ tmptm = localtime(&date);
+ yview->year = tmptm->tm_year;
+
+ gncal_year_view_set_year (yview, yview->year);
+}
+
void
gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags)
{
@@ -184,19 +208,7 @@ gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags)
if ((flags & CHANGE_SUMMARY) == flags)
return;
- if (flags & CHANGE_NEW){
- time_t year_begin, year_end;
- GList *l, *nl;
-
- year_begin = time_year_begin (yview->year);
- year_end = time_year_end (yview->year);
-
- l = g_list_append (NULL, ico);
- nl = calendar_get_objects_in_range (l, year_begin, year_end, NULL);
- if (nl){
- ical_foreach (nl, year_view_mark_day, yview);
- g_list_free (nl);
- }
- g_list_free (l);
- }
+ printf ("MARCANDO!\n");
+ if (flags & CHANGE_NEW)
+ gncal_year_view_set_year (yview, yview->year);
}
diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c
index c2fadad4d7..76bb488663 100644
--- a/calendar/pcs/calobj.c
+++ b/calendar/pcs/calobj.c
@@ -12,6 +12,8 @@
#include "timeutil.h"
#include "versit/vcc.h"
+static void ical_object_compute_end (iCalObject *ico);
+
iCalObject *
ical_object_new (void)
{
@@ -35,7 +37,6 @@ default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum Alar
alarm->count = 15;
alarm->units = ALARM_MINUTES;
} else {
- printf ("uno!\n");
alarm->count = 1;
alarm->units = ALARM_DAYS;
}
@@ -140,7 +141,7 @@ static void
ignore_space(char **str)
{
while (**str && isspace (**str))
- str++;
+ (*str)++;
}
static void
@@ -183,6 +184,12 @@ weekdaylist (iCalObject *o, char **str)
}
}
} while (isalpha (**str));
+
+ if (o->recur->weekday == 0){
+ struct tm *tm = localtime (&o->dtstart);
+
+ o->recur->weekday = 1 << tm->tm_wday;
+ }
}
static void
@@ -223,11 +230,11 @@ daynumber (iCalObject *o, char **str)
while (**str && isdigit (**str)){
val = val * 10 + (**str - '0');
- str++;
+ (*str)++;
}
if (**str == '+')
- str++;
+ (*str)++;
if (**str == '-')
val *= -1;
@@ -245,8 +252,10 @@ daynumberlist (iCalObject *o, char **str)
while (**str){
if (!isdigit (**str))
return;
- while (**str && isdigit (**str))
+ while (**str && isdigit (**str)){
val = 10 * val + (**str - '0');
+ (*str)++;
+ }
if (!first){
o->recur->u.month_day = val;
first = 1;
@@ -300,10 +309,12 @@ duration (iCalObject *o, char **str)
ignore_space (str);
if (**str != '#')
return;
- while (**str && isdigit (**str))
+ (*str)++;
+ while (**str && isdigit (**str)){
duration = duration * 10 + (**str - '0');
-
- o->recur->temp_duration = duration;
+ (*str)++;
+ }
+ o->recur->duration = duration;
}
static void
@@ -311,7 +322,7 @@ enddate (iCalObject *o, char **str)
{
ignore_space (str);
if (isdigit (**str)){
- o->recur->enddate = time_from_isodate (*str);
+ o->recur->_enddate = time_from_isodate (*str);
*str += 16;
}
}
@@ -335,7 +346,7 @@ load_recurrence (iCalObject *o, char *str)
case 'M':
if (*str == 'P')
type = RECUR_MONTHLY_BY_POS;
- else if (*str == 'D')
+ else if (*str == 'D')
type = RECUR_MONTHLY_BY_DAY;
str++;
break;
@@ -356,13 +367,18 @@ load_recurrence (iCalObject *o, char *str)
ignore_space (&str);
/* Get the interval */
- while (*str && isdigit (*str))
+ for (;*str && isdigit (*str);str++)
interval = interval * 10 + (*str-'0');
o->recur->interval = interval;
+
+ /* this is the default per the spec */
+ o->recur->duration = 2;
ignore_space (&str);
switch (type){
+ case RECUR_DAILY:
+ break;
case RECUR_WEEKLY:
load_recur_weekly (o, &str);
break;
@@ -385,6 +401,17 @@ load_recurrence (iCalObject *o, char *str)
duration (o, &str);
enddate (o, &str);
+ /* Compute the enddate */
+ if (o->recur->_enddate == 0){
+ printf ("ENDDATE es 0, d=%d\n", o->recur->duration);
+ if (o->recur->duration != 0){
+ ical_object_compute_end (o);
+ } else
+ o->recur->enddate = 0;
+ } else {
+ printf ("El evento termina\n");
+ o->recur->enddate = o->recur->_enddate;
+ }
return 1;
}
@@ -689,14 +716,173 @@ ical_foreach (GList *events, calendarfn fn, void *closure)
}
}
+static int
+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);
+
+ dt_start.tm_mday = ref.tm_mday;
+ dt_start.tm_mon = ref.tm_mon;
+ dt_start.tm_year = ref.tm_year;
+
+ dt_end.tm_mday = ref.tm_mday;
+ dt_end.tm_mon = ref.tm_mon;
+ dt_end.tm_year = ref.tm_year;
+
+ s_t = mktime (&dt_start);
+ e_t = mktime (&dt_end);
+ if (s_t == -1 || e_t == -1){
+ g_warning ("Produced invalid dates!\n");
+ return 0;
+ }
+ return (*cb)(ico, s_t, e_t, closure);
+}
+
+#define time_in_range(x,a,b) ((x >= a) && (b ? x <= b : 1))
+
+/*
+ * Generate every possible event. Invokes the callback routine for
+ * every occurrence of the event in the [START, END] time interval.
+ *
+ * If END is zero, the event is generated forever.
+ * The callback routine is expected to return 0 when no further event
+ * generation is requested.
+ */
void
ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure)
{
+ Recurrence *recur = ico->recur;
+ time_t current;
+
if (!ico->recur){
- if ((start <= ico->dtstart) && (ico->dtend <= end))
- (*cb)(ico, ico->dtstart, ico->dtend, closure);
+ if (time_in_range (ico->dtstart, start, end) ||
+ time_in_range (ico->dtend, start, end)){
+ 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);
+ }
return;
}
/* The event has a recurrence rule */
+ if (end != 0){
+ if (ico->dtstart > end)
+ return;
+ if (!IS_INFINITE (ico->recur) && recur->enddate < start)
+ return;
+ }
+
+ current = ico->dtstart;
+ switch (recur->type){
+ case RECUR_DAILY:
+ do {
+ if (time_in_range (current, start, end)){
+ 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");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_WEEKLY:
+ do {
+ struct tm *tm = localtime (&current);
+
+ if (time_in_range (current, start, end)){
+ if (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);
+ else
+ current = time_add_day (current, 1);
+
+ if (current == -1){
+ g_warning ("RECUR_WEEKLY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+ break;
+
+ case RECUR_MONTHLY_BY_POS:
+ g_warning ("We still do not handle MONTHLY_BY_POS\n");
+ break;
+
+ case RECUR_MONTHLY_BY_DAY:
+ do {
+ struct tm *tm = localtime (&current);
+ time_t t;
+ int p;
+
+ p = tm->tm_mday;
+ tm->tm_mday = recur->u.month_day;
+ t = mktime (tm);
+ if (time_in_range (t, start, end))
+ if (!generate (ico, t, cb, closure))
+ return;
+
+ /* Advance a month */
+ tm->tm_mday = p;
+ tm->tm_mon += recur->interval;
+ current = mktime (tm);
+ if (current == -1){
+ g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n");
+ return;
+ }
+ } while (current < end || (end == 0));
+
+ case RECUR_YEARLY_BY_MONTH:
+ case RECUR_YEARLY_BY_DAY:
+ do {
+ if (time_in_range (current, start, end))
+ if (!generate (ico, current, cb, closure))
+ return;
+
+ /* Advance */
+ current = time_add_year (current, recur->interval);
+ } while (current < end || (end == 0));
+ }
+}
+
+static int
+duration_callback (iCalObject *ico, time_t start, time_t end, void *closure)
+{
+ int *count = closure;
+
+ (*count)++;
+ if (ico->recur->duration == *count){
+ ico->recur->enddate = end;
+ return 0;
+ }
+ return 1;
}
+
+/* Computes ico->recur->enddate from ico->recur->duration */
+void
+ical_object_compute_end (iCalObject *ico)
+{
+ int count = 0;
+
+ g_return_if_fail (ico->recur != NULL);
+
+ ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count);
+}
+
+
diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h
index ab9d061956..8cbdffa484 100644
--- a/calendar/pcs/calobj.h
+++ b/calendar/pcs/calobj.h
@@ -86,16 +86,26 @@ typedef struct {
enum RecurType type;
int interval;
- time_t enddate;
+
+ /* Used for recur computation */
+ time_t enddate; /* If the value is zero, it is an infinite event
+ * otherwise, it is either the _enddate value (if
+ * this is what got specified) or it is our computed
+ * ending date (computed from the duration item).
+ */
+
int weekday;
union {
int month_pos;
int month_day;
} u;
-
- int temp_duration; /* Used temporarly, we compute enddate */
+
+ int duration;
+ time_t _enddate; /* As found on the vCalendar file */
+ int __count;
} Recurrence;
+#define IS_INFINITE(r) (r->duration == 0)
/* Flags to indicate what has changed in an object */
typedef enum {
@@ -157,7 +167,7 @@ typedef struct {
} iCalObject;
/* The callback for the recurrence generator */
-typedef void (*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);
diff --git a/calendar/test.vcf b/calendar/test.vcf
index 7d41d14878..b0892bbf5f 100644
--- a/calendar/test.vcf
+++ b/calendar/test.vcf
@@ -8,34 +8,19 @@ DCREATED:19980402T023552
UID:KOrganizer - 1804289383
SEQUENCE:1
LAST-MODIFIED:19980330T225948
-DTSTART:19980415T003000
-DTEND:19980415T010000
-SUMMARY:asdfasdfasfasdfasdf
+DTSTART:19980415T116000
+DTEND:19980415T119000
+SUMMARY:Mensual, el 15, durante 4 semanas
STATUS:NEEDS ACTION
CLASS:PUBLIC
PRIORITY:0
TRANSP:0
+RRULE:MD1 15 #4
RELATED-TO:0
X-PILOTID:0
X-PILOTSTAT:0
END:VEVENT
-BEGIN:VEVENT
-DCREATED:19980402T023558
-UID:KOrganizer - 846930886
-SEQUENCE:1
-LAST-MODIFIED:19980402T023558
-DTSTART:19980415T140000
-DTEND:19980415T160000
-SUMMARY:asdfasfdasfasdfasfd
-STATUS:NEEDS ACTION
-CLASS:PUBLIC
-PRIORITY:0
-TRANSP:0
-RELATED-TO:0
-X-PILOTID:0
-X-PILOTSTAT:0
-END:VEVENT
END:VCALENDAR
diff --git a/calendar/timeutil.c b/calendar/timeutil.c
index 63b78a4152..3e912a0fa3 100644
--- a/calendar/timeutil.c
+++ b/calendar/timeutil.c
@@ -122,15 +122,13 @@ time_t
time_day_hour (time_t t, int hour)
{
struct tm tm;
- time_t retval;
tm = *localtime (&t);
tm.tm_hour = hour;
tm.tm_min = 0;
tm.tm_sec = 0;
- retval = mktime (&tm);
- return retval;
+ return mktime (&tm);
}
@@ -138,22 +136,19 @@ time_t
time_start_of_day (time_t t)
{
struct tm tm;
- time_t retval;
tm = *localtime (&t);
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
- retval = mktime (&tm);
- return retval;
+ return mktime (&tm);
}
time_t
time_end_of_day (time_t t)
{
struct tm tm;
- time_t retval;
tm = *localtime (&t);
tm.tm_hour = 0;
@@ -161,8 +156,7 @@ time_end_of_day (time_t t)
tm.tm_sec = 0;
tm.tm_mday++;
- retval = mktime (&tm);
- return retval;
+ return mktime (&tm);
}
time_t
@@ -187,7 +181,6 @@ time_t
time_year_end (int year)
{
struct tm tm;
- time_t retval;
tm.tm_hour = 23;
tm.tm_min = 59;
@@ -197,6 +190,17 @@ time_year_end (int year)
tm.tm_mday = 31;
tm.tm_isdst = -1;
- retval = mktime (&tm);
- return retval;
+ return mktime (&tm);
+}
+
+time_t
+time_week_begin (time_t t)
+{
+ struct tm tm;
+ time_t retval;
+
+ tm = *localtime (&t);
+ tm.tm_mday -= tm.tm_wday;
+ return mktime (&tm);
}
+
diff --git a/calendar/timeutil.h b/calendar/timeutil.h
index 0c91450f47..df2862b37f 100644
--- a/calendar/timeutil.h
+++ b/calendar/timeutil.h
@@ -19,9 +19,10 @@ char *isodate_from_time_t (time_t t);
int get_time_t_hour (time_t t);
time_t time_add_week (time_t time, int weeks);
-time_t time_add_day (time_t time, int weeks);
+time_t time_add_day (time_t time, int days);
time_t time_add_year (time_t time, int years);
+
/* Returns pointer to a statically-allocated buffer with a string of the form
* 3am, 4am, 12pm, 08h, 17h, etc.
* The string is internationalized, hopefully correctly.
@@ -29,10 +30,12 @@ time_t time_add_year (time_t time, int years);
char *format_simple_hour (int hour, int use_am_pm);
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);
-time_t time_year_begin (int year);
-time_t time_year_end (int year);
+time_t time_end_of_day (time_t t);
+time_t time_day_hour (time_t t, int hour);
+time_t time_year_begin (int year);
+time_t time_year_end (int year);
+time_t time_week_begin (time_t t);
+void print_time_t (time_t t);
#endif
diff --git a/calendar/year-view.c b/calendar/year-view.c
index 8f5a786239..a8972a7558 100644
--- a/calendar/year-view.c
+++ b/calendar/year-view.c
@@ -136,23 +136,6 @@ gncal_year_view_new (GnomeCalendar *calendar, time_t date)
return GTK_WIDGET (yview);
}
-void gncal_year_view_set (GncalYearView *yview, time_t date)
-{
- int i;
- char buff[10];
- struct tm *tmptm;
-
- tmptm = localtime(&date);
- yview->year = tmptm->tm_year;
-
- snprintf(buff, 10, "%d", yview->year + 1900);
- gtk_label_set(GTK_LABEL(yview->year_label), buff);
-
- for (i = 0; i < 12; i++) {
- gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year);
- }
-}
-
static void
year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure)
{
@@ -174,6 +157,47 @@ year_view_mark_day (iCalObject *ical, time_t start, time_t end, void *closure)
}
}
+static void
+gncal_year_view_set_year (GncalYearView *yview, int year)
+{
+ time_t year_begin, year_end;
+ char buff[20];
+ GList *l;
+ int i;
+
+ if (!yview->gcal->cal)
+ return;
+
+ snprintf(buff, 20, "%d", yview->year + 1900);
+ gtk_label_set(GTK_LABEL(yview->year_label), buff);
+
+ for (i = 0; i < 12; i++) {
+ gtk_calendar_select_month (GTK_CALENDAR(yview->calendar[i]), i, yview->year);
+ }
+
+ year_begin = time_year_begin (yview->year);
+ year_end = time_year_end (yview->year);
+
+ l = calendar_get_events_in_range (yview->gcal->cal, year_begin, year_end);
+ for (; l; l = l->next){
+ CalendarObject *co = l->data;
+
+ year_view_mark_day (co->ico, co->ev_start, co->ev_end, yview);
+ }
+ calendar_destroy_event_list (l);
+}
+
+void
+gncal_year_view_set (GncalYearView *yview, time_t date)
+{
+ struct tm *tmptm;
+
+ tmptm = localtime(&date);
+ yview->year = tmptm->tm_year;
+
+ gncal_year_view_set_year (yview, yview->year);
+}
+
void
gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags)
{
@@ -184,19 +208,7 @@ gncal_year_view_update (GncalYearView *yview, iCalObject *ico, int flags)
if ((flags & CHANGE_SUMMARY) == flags)
return;
- if (flags & CHANGE_NEW){
- time_t year_begin, year_end;
- GList *l, *nl;
-
- year_begin = time_year_begin (yview->year);
- year_end = time_year_end (yview->year);
-
- l = g_list_append (NULL, ico);
- nl = calendar_get_objects_in_range (l, year_begin, year_end, NULL);
- if (nl){
- ical_foreach (nl, year_view_mark_day, yview);
- g_list_free (nl);
- }
- g_list_free (l);
- }
+ printf ("MARCANDO!\n");
+ if (flags & CHANGE_NEW)
+ gncal_year_view_set_year (yview, yview->year);
}