]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/iCalEvent.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1013 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SOPE / NGCards / iCalEvent.m
1 /*
2   Copyright (C) 2000-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 #import <NGExtensions/NGCalendarDateRange.h>
23
24 #import "NSCalendarDate+NGCards.h"
25 #import "CardGroup+iCal.h"
26 #import "NSString+NGCards.h"
27
28 #import "iCalEventChanges.h"
29 #import "iCalDateTime.h"
30
31 #import "iCalEvent.h"
32
33 @implementation iCalEvent
34
35 - (Class) classForTag: (NSString *) classTag
36 {
37   Class tagClass;
38
39   if ([classTag isEqualToString: @"DURATION"]
40       || [classTag isEqualToString: @"TRANSP"])
41     tagClass = [CardElement class];
42   else if ([classTag isEqualToString: @"DTEND"])
43     tagClass = [iCalDateTime class];
44   else
45     tagClass = [super classForTag: classTag];
46
47   return tagClass;
48 }
49
50 /* accessors */
51
52 - (void) setEndDate: (NSCalendarDate *)_date
53 {
54   [self setDate: _date forDateTimeValue: @"dtend"];
55 }
56
57 - (NSCalendarDate *) endDate
58 {
59   return [self dateForDateTimeValue: @"dtend"];
60 }
61
62 - (BOOL) hasEndDate
63 {
64   return ([[self childrenWithTag: @"dtend"] count] > 0);
65 }
66
67 - (void) setDuration: (NSString *) _value
68 {
69   [[self uniqueChildWithTag: @"duration"] setValue: 0
70                                           to: _value];
71 }
72
73 - (NSString *) duration
74 {
75   return [[self uniqueChildWithTag: @"duration"] value: 0];
76 }
77
78 - (BOOL) hasDuration
79 {
80   return ([[self childrenWithTag: @"duration"] count] > 0);
81 }
82
83 - (NSTimeInterval) durationAsTimeInterval
84 {
85   /*
86     eg: DURATION:PT1H
87     P      - "period"
88     P2H30M - "2 hours 30 minutes"
89
90      dur-value  = (["+"] / "-") "P" (dur-date / dur-time / dur-week)
91
92      dur-date   = dur-day [dur-time]
93      dur-time   = "T" (dur-hour / dur-minute / dur-second)
94      dur-week   = 1*DIGIT "W"
95      dur-hour   = 1*DIGIT "H" [dur-minute]
96      dur-minute = 1*DIGIT "M" [dur-second]
97      dur-second = 1*DIGIT "S"
98      dur-day    = 1*DIGIT "D"
99   */
100   NSTimeInterval interval;
101
102   if ([self hasDuration])
103     interval = [[self duration] durationAsTimeInterval];
104   else if ([self hasEndDate] && [self hasStartDate])
105     /* calculate duration using enddate */
106     interval = [[self endDate] timeIntervalSinceDate: [self startDate]];
107   else
108     interval = 0.0;
109
110   return interval;
111 }
112
113 - (void) setTransparency: (NSString *) _transparency
114 {
115   [[self uniqueChildWithTag: @"transp"] setValue: 0
116                                         to: _transparency];
117 }
118
119 - (NSString *) transparency
120 {
121   return [[self uniqueChildWithTag: @"transp"] value: 0];
122 }
123
124 /* convenience */
125
126 - (BOOL) isOpaque
127 {
128   NSString *s;
129   
130   s = [[self transparency] uppercaseString];
131
132   return (![s isEqualToString: @"TRANSPARENT"]);
133 }
134
135 /* TODO: FIX THIS!
136    The problem is, that startDate/endDate are inappropriately modelled here.
137    We'd need to have a special iCalDate in order to fix all the mess.
138    For the time being, we chose allday to mean 00:00 - 23:59 in startDate's
139    timezone.
140 */
141 - (BOOL) isAllDay
142 {
143   NSCalendarDate *ed, *startDate;
144   BOOL allDay;
145
146   if ([self hasEndDate])
147     {
148       ed = [self endDate];
149       startDate = [self startDate];
150       [ed setTimeZone: [startDate timeZone]];
151       allDay = (([startDate hourOfDay] ==  0)
152                 && ([startDate minuteOfHour] ==  0)
153                 && ([ed hourOfDay] == 23)
154                 && ([ed minuteOfHour] == 59));
155     }
156   else
157     allDay = NO;
158
159   return allDay;
160 }
161
162 - (BOOL) isWithinCalendarDateRange: (NGCalendarDateRange *) _range
163 {
164   NGCalendarDateRange *r;
165   NSCalendarDate *startDate, *endDate;
166   NGCalendarDateRange *fir;
167
168   startDate = [self startDate];
169   endDate = [self endDate];
170
171   if (![self isRecurrent])
172     {
173       if ([self hasStartDate] && [self hasEndDate])
174         {
175           r = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate
176                                    endDate: endDate];
177           return [_range containsDateRange: r];
178         }
179       else
180         return [_range containsDate: startDate];
181     }
182   else
183     {
184       fir = [NGCalendarDateRange calendarDateRangeWithStartDate:startDate
185                                  endDate: endDate];
186     
187       return [self isWithinCalendarDateRange: _range
188                    firstInstanceCalendarDateRange: fir];
189     }
190
191   return NO;
192 }
193
194 - (NSArray *) recurrenceRangesWithinCalendarDateRange: (NGCalendarDateRange *)_r
195 {
196   NGCalendarDateRange *fir;
197   
198   if (![self isRecurrent])
199     return nil;
200
201   fir = [NGCalendarDateRange calendarDateRangeWithStartDate: [self startDate]
202                              endDate: [self endDate]];
203   return [self recurrenceRangesWithinCalendarDateRange:_r
204                firstInstanceCalendarDateRange:fir];
205 }
206
207 - (NSCalendarDate *) lastPossibleRecurrenceStartDate
208 {
209   NGCalendarDateRange *fir;
210
211   if (![self isRecurrent])
212     return nil;
213
214   fir = [NGCalendarDateRange calendarDateRangeWithStartDate: [self startDate]
215                              endDate: [self endDate]];
216
217   return [self lastPossibleRecurrenceStartDateUsingFirstInstanceCalendarDateRange: fir];
218 }
219
220 /* ical typing */
221
222 - (NSString *) entityName
223 {
224   return @"vevent";
225 }
226
227 /* descriptions */
228
229 // - (NSString *) description {
230 //   NSMutableString *ms;
231
232 //   ms = [NSMutableString stringWithCapacity:128];
233 //   [ms appendFormat:@"<0x%p[%@]:", self, NSStringFromClass([self class])];
234
235 //   if (uid)       [ms appendFormat:@" uid=%@", uid];
236 //   if (startDate) [ms appendFormat:@" from=%@", startDate];
237 //   if (endDate)   [ms appendFormat:@" to=%@", endDate];
238 //   if (summary)   [ms appendFormat:@" summary=%@", summary];
239   
240 //   if (organizer)
241 //     [ms appendFormat:@" organizer=%@", organizer];
242 //   if (attendees)
243 //     [ms appendFormat:@" attendees=%@", attendees];
244   
245 //   if ([self hasAlarms])
246 //     [ms appendFormat:@" alarms=%@", alarms];
247   
248 //   [ms appendString:@">"];
249 //   return ms;
250 // }
251
252 /* changes */
253
254 - (iCalEventChanges *) getChangesRelativeToEvent: (iCalEvent *) _event
255 {
256   return [iCalEventChanges changesFromEvent: _event
257                            toEvent: self];
258 }
259
260 @end /* iCalEvent */