aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/pcs
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/pcs')
-rw-r--r--calendar/pcs/calobj.c212
-rw-r--r--calendar/pcs/calobj.h18
2 files changed, 213 insertions, 17 deletions
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);
a href='/~lantw44/cgit/gsoc2013-evolution/commit/?h=radioactive-1_1&id=92e8723c4f2bfafd43ee85d382f1730ca5da7c14'>Updated Slovenian translationAndraz Tori2000-08-061-1/+1 * Updated Slovenian translationAndraz Tori2000-08-051-852/+777 * Added a function to get the next row with sorting taken into account.Christopher James Lahey2000-08-055-0/+85 * Made it so that selection ranges work even if the table is using grouping.Christopher James Lahey2000-08-053-8/+17 * Made selection ranges work even if the table is sorted.Christopher James Lahey2000-08-0514-50/+875 * Updated the Turkish translation.Fatih Demir2000-08-052-216/+231 * New file. Contains contents of "COPYING", but marked up (probably not veryAaron Weber2000-08-0514-394/+1314 * Fixed a warning.Christopher James Lahey2000-08-054-2/+13 * Built code to have autodrags only work from within the table and to reportChristopher James Lahey2000-08-055-78/+478 * *** empty log message ***Seth Alves2000-08-051-0/+7 * if oaf isn't initialized by the time the conduit starts, start it up. weSeth Alves2000-08-053-5/+32 * tlauche is now called wombatSeth Alves2000-08-051-1/+1 * If we fail to get a dir_sep, then supply the default of "/". (get_folder):Jeffrey Stedfast2000-08-052-28/+37 * Coredump fix when IMAP get_folder with NULL dir_sepPeter Williams2000-08-052-1/+6 * Indexes into the flags array are message_number minus 1, not justDan Winship2000-08-052-2/+6 * Actually commit this - I though it went in already.JP Rosevear2000-08-0411-134/+79 * Made drag events calculate a row and column and signal that information.Christopher James Lahey2000-08-0417-64/+208 * I pity da foo that committed this bug!Peter Williams2000-08-042-1/+5 * Szabolcs BAN <shooby@gnome.hu>Szabolcs Ban2000-08-042-105/+114 * add a debugging macro for doing protocol tracing.Dan Winship2000-08-042-2/+29 * Fix a possible crash when using the quicksearch by freeing the UIDEttore Perazzoli2000-08-042-3/+12 * Everywhere unref the remote_uih having done a set_container.Michael Meeks2000-08-0411-2/+26 * only whack the sig in if the file exists.Michael Meeks2000-08-045-5/+38 * Remove erroneous refs on folder_type_registry, storage_set.Michael Meeks2000-08-046-9/+37 * Yay, no more compiler warningsJeffrey Stedfast2000-08-042-9/+10 * Make sure default_uri isn't NULL!!Jeffrey Stedfast2000-08-042-1/+6 * Only call imap_get_summary_internal if the folder can hold messagesJeffrey Stedfast2000-08-043-7/+13 * set config = NULL (provider_list) Eek! Initialize news to NULL! Also, useJeffrey Stedfast2000-08-042-29/+53 * Make the filter dialog display only the name of the folder, not theEttore Perazzoli2000-08-042-18/+21 * Add Irish translationAlastair McKinstry2000-08-044-1/+464 * Initialize the service_cache for the news/nntp providersJeffrey Stedfast2000-08-042-6/+15 * Use type instead of which.Peter Williams2000-08-041-1/+1 * Update docs.Ettore Perazzoli2000-08-041-1/+22 * Update inline docs.Ettore Perazzoli2000-08-041-1/+1 * Update the ::user_select_folder() interface so that it accepts both aEttore Perazzoli2000-08-048-13/+208 * Work with GtkHTML if it uses gconfPeter Williams2000-08-042-5/+7 * srcdir != builddir fixPeter Williams2000-08-032-0/+6 * Check for identity before sending ; remove gconf_init callPeter Williams2000-08-033-2/+20 * Increase window size slightly, rename "Transport" to "Mail Transport"JP Rosevear2000-08-036-185/+142 * *** empty log message ***Seth Alves2000-08-031-0/+5 * Fixed a g_return_if_fail that had two parameters and thus wouldn't build.Joe Shaw2000-08-032-1/+7 * fixed a bunch of bugs, added a lot of debug spew.Seth Alves2000-08-032-87/+253 * call save (cbimc) after setting the pilot id and status.Seth Alves2000-08-031-0/+7 * updated to match the new ETableModel append_row. This meant we could alsoDamon Chaplin2000-08-032-62/+22 * update for BonoboXMichael Meeks2000-08-032-9/+13 * Add camel/providers/nntpDan Winship2000-08-032-0/+5 * Kill this. It doesn't have any code to do anything the new mh providerDan Winship2000-08-0315-2068/+9 * Trim trailing space from the subject. I've now seen replies from twoDan Winship2000-08-032-1/+10 * Dum dum dum - FedericoFederico Mena Quintero2000-08-031-0/+36 * Emit "model_pre_change" signals as appropriate.Christopher James Lahey2000-08-032-0/+8 * Made clicking choose the right character even if show_borders is on.Christopher James Lahey2000-08-033-2/+19 * Make the "test settings" button FILL rather than SHRINK so it doesn't endDan Winship2000-08-033-6/+14 * Fix "cvs rm -rf" lossage.Dan Winship2000-08-0330-0/+4077 * New files for the iCalendar file backend.Federico Mena Quintero2000-08-037-9/+1108 * removed last files from GNOME CVSscottf2000-08-0330-4077/+0 * Ahem, these files will be back in a second - FedericoFederico Mena Quintero2000-08-031-2/+0 * Emit "model_pre_change" where appropriate.Christopher James Lahey2000-08-033-0/+9 * Protect mail-config.h against multiple inclusion.Peter Williams2000-08-032-0/+9 * Emit "model_pre_change" signal as appropriate.Christopher James Lahey2000-08-035-0/+14 * Add a handler for "model_pre_change" and properly stop editing.Christopher James Lahey2000-08-0317-20/+188 * various syntax checkingPablo Saratxaga2000-08-02