]> err.no Git - sope/blob - sope-ical/NGiCal/iCalRepeatableEntityObject.m
a5fca2b6f7603fe5bdc1f776fae2e5909a3c3d5c
[sope] / sope-ical / NGiCal / iCalRepeatableEntityObject.m
1 /*
2   Copyright (C) 2004-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include "iCalRepeatableEntityObject.h"
23 #include <NGExtensions/NGCalendarDateRange.h>
24 #include "iCalRecurrenceRule.h"
25 #include "iCalRecurrenceCalculator.h"
26 #include "common.h"
27
28 @implementation iCalRepeatableEntityObject
29
30 - (void)dealloc {
31   [self->rRules  release];
32   [self->exRules release];
33   [self->exDates release];
34   [super dealloc];
35 }
36
37 /* NSCopying */
38
39 - (id)copyWithZone:(NSZone *)_zone {
40   iCalRepeatableEntityObject *new;
41
42   new = [super copyWithZone:_zone];
43   
44   ASSIGNCOPY(new->rRules,  self->rRules);
45   ASSIGNCOPY(new->exRules, self->exRules);
46   ASSIGNCOPY(new->exDates, self->exDates);
47
48   return new;
49 }
50
51 /* Accessors */
52
53 - (void)removeAllRecurrenceRules {
54   [self->rRules removeAllObjects];
55 }
56 - (void)addToRecurrenceRules:(id)_rrule {
57   if (_rrule == nil) return;
58   if (self->rRules == nil)
59     self->rRules = [[NSMutableArray alloc] initWithCapacity:1];
60   [self->rRules addObject:_rrule];
61 }
62 - (void)setRecurrenceRules:(NSArray *)_rrules {
63   if (_rrules == self->rRules)
64     return;
65   [self->rRules release];
66   self->rRules = [_rrules mutableCopy];
67 }
68 - (BOOL)hasRecurrenceRules {
69   return [self->rRules count] > 0 ? YES : NO;
70 }
71 - (NSArray *)recurrenceRules {
72   return self->rRules;
73 }
74
75 - (void)removeAllExceptionRules {
76   [self->exRules removeAllObjects];
77 }
78 - (void)addToExceptionRules:(id)_rrule {
79   if (_rrule == nil) return;
80   if (self->exRules == nil)
81     self->exRules = [[NSMutableArray alloc] initWithCapacity:1];
82   [self->exRules addObject:_rrule];
83 }
84 - (void)setExceptionRules:(NSArray *)_rrules {
85   if (_rrules == self->exRules)
86     return;
87   [self->exRules release];
88   self->exRules = [_rrules mutableCopy];
89 }
90 - (BOOL)hasExceptionRules {
91   return [self->exRules count] > 0 ? YES : NO;
92 }
93 - (NSArray *)exceptionRules {
94   return self->exRules;
95 }
96
97 - (void)removeAllExceptionDates {
98   [self->exDates removeAllObjects];
99 }
100 - (void)setExceptionDates:(NSArray *)_exDates {
101   if (_exDates == self->exDates)
102     return;
103   [self->exDates release];
104   self->exDates = [_exDates mutableCopy];
105 }
106 - (void)addToExceptionDates:(id)_date {
107   if (_date == nil) return;
108   if (self->exDates == nil)
109     self->exDates = [[NSMutableArray alloc] initWithCapacity:4];
110   [self->exDates addObject:_date];
111 }
112 - (BOOL)hasExceptionDates {
113   return [self->exDates count] > 0 ? YES : NO;
114 }
115 - (NSArray *)exceptionDates {
116   return self->exDates;
117 }
118
119 /* Convenience */
120
121 - (BOOL)isRecurrent {
122   return [self hasRecurrenceRules] ? YES : NO;
123 }
124
125 /* Matching */
126
127 - (BOOL)isWithinCalendarDateRange:(NGCalendarDateRange *)_range
128   firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir
129 {
130   NSArray *ranges;
131   
132   ranges = [self recurrenceRangesWithinCalendarDateRange:_range
133                  firstInstanceCalendarDateRange:_fir];
134   return [ranges count] > 0;
135 }
136
137 - (NSArray *)recurrenceRangesWithinCalendarDateRange:(NGCalendarDateRange *)_r
138   firstInstanceCalendarDateRange:(NGCalendarDateRange *)_fir
139 {
140   return [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange:_r
141                                    firstInstanceCalendarDateRange:_fir
142                                    recurrenceRules:self->rRules
143                                    exceptionRules:self->exRules
144                                    exceptionDates:self->exDates];
145 }
146
147
148 /* this is the outmost bound possible, not necessarily the real last date */
149 - (NSCalendarDate *)lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange:(NGCalendarDateRange *)_r
150 {
151   NSCalendarDate *date;
152   unsigned       i, count;
153   
154   count = [self->rRules count];
155   if (!count)
156     return nil;
157
158   date  = nil;
159   for (i = 0; i < count; i++) {
160     iCalRecurrenceRule       *rule;
161     iCalRecurrenceCalculator *calc;
162     NSCalendarDate           *rdate;
163
164     rule = [self->rRules objectAtIndex:i];
165     if ([rule isInfinite])
166       return nil; /* rule is not bound, hence no limit */
167     calc  = [iCalRecurrenceCalculator recurrenceCalculatorForRecurrenceRule:rule
168                                       withFirstInstanceCalendarDateRange:_r];
169     rdate = [[calc lastInstanceCalendarDateRange] startDate];
170     if (date == nil || [date compare:rdate] == NSOrderedAscending)
171       date = rdate;
172   }
173   return date;
174 }
175
176 @end