2 Copyright (C) 2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
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.
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
23 #include "SOGoAppointment.h"
24 #include <SaxObjC/SaxObjC.h>
25 #include <NGiCal/NGiCal.h>
26 #include <EOControl/EOControl.h>
27 #include "SOGoAppointmentICalRenderer.h"
30 @interface SOGoAppointment (PrivateAPI)
31 - (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
34 @implementation SOGoAppointment
36 static id<NSObject,SaxXMLReader> parser = nil;
37 static SaxObjectDecoder *sax = nil;
41 parser = [[[SaxXMLReaderFactory standardXMLReaderFactory]
42 createXMLReaderForMimeType:@"text/calendar"]
45 NSLog(@"ERROR: did not find a parser for text/calendar!");
48 sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
50 NSLog(@"ERROR: could not create the iCal SAX handler!");
53 [parser setContentHandler:sax];
54 [parser setErrorHandler:sax];
57 - (id)initWithICalRootObject:(id)_root {
58 if ((self = [super init])) {
60 [self logWithFormat:@"root is: %@", root];
63 if ([_root isKindOfClass:[iCalEvent class]]) {
64 self->event = [_root retain];
66 else if ([_root isKindOfClass:[NSDictionary class]]) {
67 /* multiple vevents in the calendar */
68 [self errorWithFormat:
69 @"(%s): tried to initialize with multiple records: %@",
70 __PRETTY_FUNCTION__, _root];
75 self->calendar = [_root retain];
76 self->event = [[[self->calendar events] lastObject] retain];
81 - (id)initWithICalString:(NSString *)_iCal {
84 if ([_iCal length] == 0) {
85 [self errorWithFormat:@"tried to init SOGoAppointment without iCal"];
89 if (parser == nil || sax == nil) {
90 [self errorWithFormat:@"iCal parser not properly set up!"];
95 if ([_iCal length] > 0) {
96 [parser parseFromSource:_iCal];
97 root = [[sax rootObject] retain]; /* retain to keep it around */
103 self = [self initWithICalRootObject:root];
109 [self->calendar release];
110 [self->event release];
117 return self->calendar;
124 - (NSString *)iCalString {
125 return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
126 stringForAppointment:self];
128 - (NSString *)vEventString {
129 return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
130 vEventStringForAppointment:self];
133 /* forwarded methods */
135 - (void)setUid:(NSString *)_value {
136 [self->event setUid:_value];
139 return [self->event uid];
142 - (void)setSummary:(NSString *)_value {
143 [self->event setSummary:_value];
145 - (NSString *)summary {
146 return [self->event summary];
149 - (void)setLocation:(NSString *)_value {
150 [self->event setLocation:_value];
152 - (NSString *)location {
153 return [self->event location];
155 - (BOOL)hasLocation {
156 if (![[self location] isNotNull])
158 return [[self location] length] > 0 ? YES : NO;
161 - (void)setComment:(NSString *)_value {
162 if([_value length] == 0)
164 [self->event setComment:_value];
166 - (NSString *)comment {
167 return [self->event comment];
170 NSString *s = [self comment];
171 if(!s || [s length] == 0)
176 - (void)setPriority:(NSString *)_value {
177 [self->event setPriority:_value];
179 - (NSString *)priority {
180 return [self->event priority];
182 - (BOOL)hasPriority {
183 NSString *prio = [self priority];
189 r = [prio rangeOfString:@";"];
191 prio = [prio substringToIndex:r.location];
193 return [prio isEqualToString:@"0"] ? NO : YES;
196 - (void)setCategories:(NSArray *)_value {
199 if(!_value || [_value count] == 0) {
200 [self->event setCategories:nil];
203 _value = [_value sortedArrayUsingSelector:@selector(compareAscending:)];
204 catString = [_value componentsJoinedByString:@","];
205 [self->event setCategories:catString];
208 - (NSArray *)categories {
213 catString = [self->event categories];
214 if (![catString isNotNull])
215 return [NSArray array];
217 r = [[catString stringValue] rangeOfString:@";"];
219 catString = [catString substringToIndex:r.location];
221 cats = [catString componentsSeparatedByString:@","];
224 - (BOOL)hasCategories {
225 return [self->event categories] != nil ? YES : NO;
228 - (void)setStatus:(NSString *)_value {
229 [self->event setStatus:_value];
231 - (NSString *)status {
232 return [self->event status];
235 - (void)setStartDate:(NSCalendarDate *)_date {
236 [self->event setStartDate:_date];
238 - (NSCalendarDate *)startDate {
239 return [self->event startDate];
242 - (void)setEndDate:(NSCalendarDate *)_date {
243 [self->event setEndDate:_date];
245 - (NSCalendarDate *)endDate {
246 return [self->event endDate];
249 return [self->event hasEndDate];
252 - (void)setDuration:(NSTimeInterval)_duration {
254 [self warnWithFormat:@"could not apply duration!"];
256 - (BOOL)hasDuration {
257 return [self->event hasDuration];
259 - (NSTimeInterval)duration {
260 return [self->event durationAsTimeInterval];
263 - (void)setOrganizer:(iCalPerson *)_organizer {
264 [self->event setOrganizer:_organizer];
266 - (iCalPerson *)organizer {
267 return [self->event organizer];
270 - (void)removeAllAttendees {
271 [self setAttendees:nil];
273 - (void)addToAttendees:(iCalPerson *)_person {
274 [self->event addToAttendees:_person];
276 - (void)appendAttendees:(NSArray *)_persons {
279 count = [_persons count];
280 for (i = 0; i < count; i++)
281 [self addToAttendees:[_persons objectAtIndex:i]];
283 - (void)setAttendees:(NSArray *)_persons {
284 [self->event removeAllAttendees];
285 if ([_persons count] > 0)
286 [self appendAttendees:_persons];
288 - (NSArray *)attendees {
289 return [self->event attendees];
292 - (NSArray *)participants {
293 if (self->participants != nil)
294 return self->participants;
296 self->participants = [[self _filteredAttendeesThinkingOfPersons:YES] retain];
297 return self->participants;
299 - (BOOL)hasParticipants {
300 return [[self participants] count] != 0;
303 - (NSArray *)resources {
304 return [self _filteredAttendeesThinkingOfPersons:NO];
307 - (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons {
309 NSMutableArray *filtered;
312 list = [self attendees];
313 count = [list count];
314 filtered = [NSMutableArray arrayWithCapacity:count];
315 for (i = 0; i < count; i++) {
319 p = [list objectAtIndex:i];
322 if (role == nil || ![role hasPrefix:@"NON-PART"])
323 [filtered addObject:p];
326 if ([role hasPrefix:@"NON-PART"])
327 [filtered addObject:p];
333 - (BOOL)isOrganizer:(id)_email {
334 return [[[self organizer] rfc822Email] isEqualToString:_email];
337 - (BOOL)isParticipant:(id)_email {
340 partEmails = [[self participants] valueForKey:@"rfc822Email"];
341 return [partEmails containsObject:_email];
346 - (void)appendAttributesToDescription:(NSMutableString *)_ms {
347 [_ms appendFormat:@" uid=%@", [self uid]];
348 [_ms appendFormat:@" date=%@", [self startDate]];
351 - (NSString *)description {
354 ms = [NSMutableString stringWithCapacity:64];
355 [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
356 [self appendAttributesToDescription:ms];
357 [ms appendString:@">"];
361 @end /* SOGoAppointment */