]> err.no Git - scalable-opengroupware.org/blob - SOGoLogic/SOGoAppointment.m
15f3db7a60cfa238fbca3a2db3231d2decd83afb
[scalable-opengroupware.org] / SOGoLogic / SOGoAppointment.m
1 /*
2   Copyright (C) 2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include "SOGoAppointment.h"
24 #include "SOGoAppointmentICalRenderer.h"
25 #include <SaxObjC/SaxObjC.h>
26 #include <NGiCal/NGiCal.h>
27 #include <EOControl/EOControl.h>
28 #include "common.h"
29
30 @interface SOGoAppointment (PrivateAPI)
31 - (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
32 @end
33
34 @implementation SOGoAppointment
35
36 static id<NSObject,SaxXMLReader> parser = nil;
37 static SaxObjectDecoder          *sax   = nil;
38
39 + (void)initialize {
40   if (parser == nil) {
41     parser = [[[SaxXMLReaderFactory standardXMLReaderFactory] 
42                 createXMLReaderForMimeType:@"text/calendar"]
43                 retain];
44     if (parser == nil)
45       NSLog(@"ERROR: did not find a parser for text/calendar!");
46   }
47   if (sax == nil) {
48     sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
49     if (sax == nil)
50       NSLog(@"ERROR: could not create the iCal SAX handler!");
51   }
52   
53   [parser setContentHandler:sax];
54   [parser setErrorHandler:sax];
55 }
56
57 - (id)initWithICalRootObject:(id)_root {
58   if ((self = [super init])) {
59 #if 0
60     [self logWithFormat:@"root is: %@", root];
61 #endif
62     
63     if ([_root isKindOfClass:[iCalEvent class]]) {
64       self->event = [_root retain];
65     }
66     else if ([_root isKindOfClass:[NSDictionary class]]) {
67       /* multiple vevents in the calendar */
68       [self logWithFormat:
69               @"ERROR(%s): tried to initialize with multiple records: %@",
70               __PRETTY_FUNCTION__, _root];
71       [self release];
72       return nil;
73     }
74     else {
75       self->calendar = [_root retain];
76       self->event    = [[[self->calendar events] lastObject] retain];
77     }
78   }
79   return self;
80 }
81 - (id)initWithICalString:(NSString *)_iCal {
82   id root;
83   
84   if ([_iCal length] == 0) {
85     [self logWithFormat:@"ERROR: tried to init SOGoAppointment without iCal"];
86     [self release];
87     return nil;
88   }
89   if (parser == nil || sax == nil) {
90     [self logWithFormat:@"ERROR: iCal parser not properly set up!"];
91     [self release];
92     return nil;
93   }
94
95   if ([_iCal length] > 0) {
96     [parser parseFromSource:_iCal];
97     root = [[sax rootObject] retain]; /* retain to keep it around */
98     [sax reset];
99   }
100   else
101     root = nil;
102
103   self = [self initWithICalRootObject:root];
104   [root release];
105   return self;
106 }
107
108 - (void)dealloc {
109   [self->calendar release];
110   [self->event    release];
111   [super dealloc];
112 }
113
114 /* accessors */
115
116 - (id)calendar {
117   return self->calendar;
118 }
119
120 - (id)event {
121   return self->event;
122 }
123
124 - (NSString *)iCalString {
125   return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
126                                        stringForAppointment:self];
127 }
128
129 /* forwarded methods */
130
131 - (void)setUid:(NSString *)_value {
132   [self->event setUid:_value];
133 }
134 - (NSString *)uid {
135   return [self->event uid];
136 }
137
138 - (void)setSummary:(NSString *)_value {
139   [self->event setSummary:_value];
140 }
141 - (NSString *)summary {
142   return [self->event summary];
143 }
144
145 - (void)setLocation:(NSString *)_value {
146   [self->event setLocation:_value];
147 }
148 - (NSString *)location {
149   return [self->event location];
150 }
151 - (BOOL)hasLocation {
152   if (![[self location] isNotNull])
153     return NO;
154   return  [[self location] length] > 0 ? YES : NO;
155 }
156
157 - (void)setComment:(NSString *)_value {
158   if([_value length] == 0)
159     _value = nil;
160   [self->event setComment:_value];
161 }
162 - (NSString *)comment {
163   return [self->event comment];
164 }
165 - (BOOL)hasComment {
166   NSString *s = [self comment];
167   if(!s || [s length] == 0)
168     return NO;
169   return YES;
170 }
171
172 - (void)setPriority:(NSString *)_value {
173   [self->event setPriority:_value];
174 }
175 - (NSString *)priority {
176   return [self->event priority];
177 }
178 - (BOOL)hasPriority {
179   NSString *prio = [self priority];
180   NSRange r;
181   
182   if(!prio)
183     return NO;
184   
185   r = [prio rangeOfString:@";"];
186   if(r.length > 0) {
187     prio = [prio substringToIndex:r.location];
188   }
189   return [prio isEqualToString:@"0"] ? NO : YES;
190 }
191
192 - (void)setCategories:(NSArray *)_value {
193   NSString *catString;
194
195   if(!_value || [_value count] == 0) {
196     [self->event setCategories:nil];
197     return;
198   }
199   _value = [_value sortedArrayUsingSelector:@selector(compareAscending:)];
200   catString = [_value componentsJoinedByString:@","];
201   [self->event setCategories:catString];
202   [catString release];
203 }
204 - (NSArray *)categories {
205   NSString *catString;
206   NSArray *cats;
207   NSRange r;
208
209   catString = [self->event categories];
210   if(!catString) {
211     return [NSArray array];
212   }
213   r = [catString rangeOfString:@";"];
214   if(r.length > 0) {
215     catString = [catString substringToIndex:r.location];
216   }
217   cats = [catString componentsSeparatedByString:@","];
218   return cats;
219 }
220 - (BOOL)hasCategories {
221   return [self->event categories] != nil ? YES : NO;
222 }
223
224 - (void)setStatus:(NSString *)_value {
225   [self->event setStatus:_value];
226 }
227 - (NSString *)status {
228   return [self->event status];
229 }
230
231 - (void)setStartDate:(NSCalendarDate *)_date {
232   [self->event setStartDate:_date];
233 }
234 - (NSCalendarDate *)startDate {
235   return [self->event startDate];
236 }
237
238 - (void)setEndDate:(NSCalendarDate *)_date {
239   [self->event setEndDate:_date];
240 }
241 - (NSCalendarDate *)endDate {
242   return [self->event endDate];
243 }
244 - (BOOL)hasEndDate {
245   return [self->event hasEndDate];
246 }
247
248 - (void)setDuration:(NSTimeInterval)_duration {
249   // TODO
250   [self logWithFormat:@"WARNING: could not apply duration!"];
251 }
252 - (BOOL)hasDuration {
253   return [self->event hasDuration];
254 }
255 - (NSTimeInterval)duration {
256   return [self->event durationAsTimeInterval];
257 }
258
259 - (void)setOrganizer:(iCalPerson *)_organizer {
260   [self->event setOrganizer:_organizer];
261 }
262 - (iCalPerson *)organizer {
263   return [self->event organizer];
264 }
265
266 - (void)removeAllAttendees {
267   [self setAttendees:nil];
268 }
269 - (void)addToAttendees:(iCalPerson *)_person {
270   [self->event addToAttendees:_person];
271 }
272 - (void)appendAttendees:(NSArray *)_persons {
273   unsigned i, count;
274   
275   count = [_persons count];
276   for (i = 0; i < count; i++)
277     [self addToAttendees:[_persons objectAtIndex:i]];
278 }
279 - (void)setAttendees:(NSArray *)_persons {
280   [self->event removeAllAttendees];
281   if ([_persons count] > 0) 
282     [self appendAttendees:_persons];
283 }
284 - (NSArray *)attendees {
285   return [self->event attendees];
286 }
287
288 - (NSArray *)participants {
289   if (self->participants)
290     return self->participants;
291   
292   self->participants = [[self _filteredAttendeesThinkingOfPersons:YES] retain];
293   return self->participants;
294 }
295 - (BOOL)hasParticipants {
296   return [[self participants] count] != 0;
297 }
298
299 - (NSArray *)resources {
300   return [self _filteredAttendeesThinkingOfPersons:NO];
301 }
302
303 - (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons {
304   NSArray        *list;
305   NSMutableArray *filtered;
306   unsigned       i, count;
307
308   list     = [self attendees];
309   count    = [list count];
310   filtered = [NSMutableArray arrayWithCapacity:count];
311   for (i = 0; i < count; i++) {
312     iCalPerson *p;
313     NSString   *role;
314     
315     p = [list objectAtIndex:i];
316     role = [p role];
317     if (_persons) {
318       if (role == nil || ![role isEqualToString:@"NON-PART"])
319         [filtered addObject:p];
320     }
321     else {
322       if ([role isEqualToString:@"NON-PART"])
323         [filtered addObject:p];
324     }
325   }
326   return filtered;
327 }
328
329 @end /* SOGoAppointment */