From b09fc630b854d66265072b87a0ddcca083b849aa Mon Sep 17 00:00:00 2001 From: helge Date: Wed, 5 Oct 2005 16:06:58 +0000 Subject: [PATCH] implemented negative occurences git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1161 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-ical/NGiCal/ChangeLog | 5 ++ sope-ical/NGiCal/Version | 2 +- .../NGiCal/iCalMonthlyRecurrenceCalculator.m | 80 ++++++++++++++++--- 3 files changed, 75 insertions(+), 12 deletions(-) diff --git a/sope-ical/NGiCal/ChangeLog b/sope-ical/NGiCal/ChangeLog index c64773b4..775c367e 100644 --- a/sope-ical/NGiCal/ChangeLog +++ b/sope-ical/NGiCal/ChangeLog @@ -1,3 +1,8 @@ +2005-10-05 Helge Hess + + * iCalMonthlyRecurrenceCalculator.m: implemented calculation of + negative byday occurrences (eg -1TH) (v4.5.69) + 2005-09-22 Helge Hess * iCalRecurrenceRule.m: added direct parser support for 'interval', diff --git a/sope-ical/NGiCal/Version b/sope-ical/NGiCal/Version index 59e4f30b..e0046365 100644 --- a/sope-ical/NGiCal/Version +++ b/sope-ical/NGiCal/Version @@ -2,7 +2,7 @@ MAJOR_VERSION=4 MINOR_VERSION=5 -SUBMINOR_VERSION:=68 +SUBMINOR_VERSION:=69 # v4.5.40 requires NGExtensions v4.5.145 # v4.5.37 requires NGExtensions v4.5.140 diff --git a/sope-ical/NGiCal/iCalMonthlyRecurrenceCalculator.m b/sope-ical/NGiCal/iCalMonthlyRecurrenceCalculator.m index 2bfcdf5d..e54b224d 100644 --- a/sope-ical/NGiCal/iCalMonthlyRecurrenceCalculator.m +++ b/sope-ical/NGiCal/iCalMonthlyRecurrenceCalculator.m @@ -33,6 +33,8 @@ - (NSCalendarDate *)lastInstanceStartDate; @end +// #define HEAVY_DEBUG 1 + @implementation iCalMonthlyRecurrenceCalculator typedef BOOL NGMonthSet[12]; @@ -111,34 +113,89 @@ static inline unsigned iCalDoWForNSDoW(int dow) { } } +#if HEAVY_DEBUG +static NSString *dowEN[8] = { + @"SU", @"MO", @"TU", @"WE", @"TH", @"FR", @"SA", @"SU-" +}; +#endif + static void NGMonthDaySet_fillWithByDayX(NGMonthDaySet *daySet, unsigned dayMask, unsigned firstDoWInMonth, + unsigned numberOfDaysInMonth, int occurrence1) { // TODO: this is called 'X' because the API doesn't allow for full iCalendar // functionality. The daymask must be a list of occurence+dow register unsigned dayInMonth; - register unsigned dow; /* current day of the week */ + register int dow; /* current day of the week */ int occurrences[7] = { 0, 0, 0, 0, 0, 0, 0 } ; NGMonthDaySet_clear(daySet); - for (dayInMonth = 1, dow = firstDoWInMonth; dayInMonth <= 31; dayInMonth++) { - // TODO: complete me + if (occurrence1 >= 0) { + for (dayInMonth = 1, dow = firstDoWInMonth; dayInMonth<=31; dayInMonth++) { + // TODO: complete me + + if (dayMask & iCalDoWForNSDoW(dow)) { + if (occurrence1 == 0) + (*daySet)[dayInMonth] = YES; + else { /* occurrence1 > 0 */ + occurrences[dow] = occurrences[dow] + 1; + + if (occurrences[dow] == occurrence1) + (*daySet)[dayInMonth] = YES; + } + } + + dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1); + } + } + else { + int lastDoWInMonthSet; - if (dayMask & iCalDoWForNSDoW(dow)) { - if (occurrence1 == 0) - (*daySet)[dayInMonth] = YES; - else { + /* get the last dow in the set (not necessarily the month!) */ + for (dayInMonth = 1, dow = firstDoWInMonth; + dayInMonth < numberOfDaysInMonth;dayInMonth++) + dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1); + lastDoWInMonthSet = dow; + +#if HEAVY_DEBUG + NSLog(@"LAST DOW IN SET: %i / %@", + lastDoWInMonthSet, dowEN[lastDoWInMonthSet]); +#endif + /* start at the end of the set */ + for (dayInMonth = numberOfDaysInMonth, dow = lastDoWInMonthSet; + dayInMonth >= 1; dayInMonth--) { + // TODO: complete me + +#if HEAVY_DEBUG + NSLog(@" CHECK day-of-month %02i, " + @" dow=%i/%@ (first=%i/%@, last=%i/%@)", + dayInMonth, + dow, dowEN[dow], + firstDoWInMonth, dowEN[firstDoWInMonth], + lastDoWInMonthSet, dowEN[lastDoWInMonthSet] + ); +#endif + + if (dayMask & iCalDoWForNSDoW(dow)) { occurrences[dow] = occurrences[dow] + 1; - - if (occurrences[dow] == occurrence1) +#if HEAVY_DEBUG + NSLog(@" MATCH %i/%@ count: %i occurences=%i", + dow, dowEN[dow], occurrences[dow], occurrence1); +#endif + + if (occurrences[dow] == -occurrence1) { +#if HEAVY_DEBUG + NSLog(@" COUNT MATCH"); +#endif (*daySet)[dayInMonth] = YES; + } } + + dow = (dow == 0 /* Sun */) ? 6 /* Sat */ : (dow - 1); } - - dow = (dow == 6 /* Sat */) ? 0 /* Sun */ : (dow + 1); } } @@ -289,6 +346,7 @@ static void NGMonthDaySet_fillWithByDayX(NGMonthDaySet *daySet, NGMonthDaySet_fillWithByDayX(&ruleset, [self->rrule byDayMask], firstDoWInMonth, + [cursor numberOfDaysInMonth], [self->rrule byDayOccurence1]); NGMonthDaySet_copyOrUnion(&monthDays, &ruleset, !didByFill); didByFill = YES; -- 2.39.5