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
22 #include "SOGoAppointmentICalRenderer.h"
23 #include "SOGoAppointment.h"
24 #include <NGiCal/NGiCal.h>
25 #include <NGiCal/iCalRenderer.h>
28 // TODO: the basic renderer should be part of NGiCal
30 @interface NSDate(UsedPrivates)
31 - (NSString *)icalString; // declared in NGiCal
34 @implementation SOGoAppointmentICalRenderer
36 static SOGoAppointmentICalRenderer *renderer = nil;
38 /* assume length of 1K - reasonable ? */
39 static unsigned DefaultICalStringCapacity = 1024;
41 + (id)sharedAppointmentRenderer {
43 renderer = [[self alloc] init];
49 - (void)addPreambleForAppointment:(SOGoAppointment *)_apt
50 toString:(NSMutableString *)s
52 iCalCalendar *calendar;
55 calendar = [_apt calendar];
57 [s appendString:@"BEGIN:VCALENDAR\r\n"];
58 [s appendString:@"METHOD:"];
59 if((x = [calendar method]))
60 [s appendString:[x iCalSafeString]];
62 [s appendString:@"REQUEST"];
63 [s appendString:@"\r\n"];
65 [s appendString:@"PRODID:"];
66 [s appendString:[calendar isNotNull] ? [calendar prodId] : @"SOGo/0.9"];
67 [s appendString:@"\r\n"];
69 [s appendString:@"VERSION:"];
70 [s appendString:[calendar isNotNull] ? [calendar version] : @"2.0"];
71 [s appendString:@"\r\n"];
73 - (void)addPostambleForAppointment:(SOGoAppointment *)_apt
74 toString:(NSMutableString *)s
76 [s appendString:@"END:VCALENDAR\r\n"];
79 - (void)addOrganizer:(iCalPerson *)p toString:(NSMutableString *)s {
82 if (![p isNotNull]) return;
84 [s appendString:@"ORGANIZER;CN=\""];
86 [s appendString:[x iCalDQUOTESafeString]];
88 [s appendString:@"\""];
89 if ((x = [p email])) {
90 [s appendString:@":"]; /* sic! */
91 [s appendString:[x iCalSafeString]];
93 [s appendString:@"\r\n"];
96 - (void)addAttendees:(NSArray *)persons toString:(NSMutableString *)s {
100 count = [persons count];
101 for (i = 0; i < count; i++) {
104 p = [persons objectAtIndex:i];
105 [s appendString:@"ATTENDEE;"];
107 if ((x = [p role])) {
108 [s appendString:@"ROLE="];
109 [s appendString:[x iCalSafeString]];
110 [s appendString:@";"];
113 if ((x = [p partStat])) {
114 if ([p participationStatus] != iCalPersonPartStatNeedsAction) {
115 [s appendString:@"PARTSTAT="];
116 [s appendString:[x iCalSafeString]];
117 [s appendString:@";"];
121 [s appendString:@"CN=\""];
122 if ((x = [p cnWithoutQuotes])) {
123 [s appendString:[x iCalDQUOTESafeString]];
125 [s appendString:@"\""];
126 if ([(x = [p email]) isNotNull]) {
127 [s appendString:@":"]; /* sic! */
128 [s appendString:[x iCalSafeString]];
130 [s appendString:@"\r\n"];
134 - (void)addVEventForAppointment:(SOGoAppointment *)_apt
135 toString:(NSMutableString *)s
139 event = [_apt event];
141 [s appendString:@"BEGIN:VEVENT\r\n"];
143 [s appendString:@"SUMMARY:"];
144 [s appendString:[[_apt summary] iCalSafeString]];
145 [s appendString:@"\r\n"];
146 if ([_apt hasLocation]) {
147 [s appendString:@"LOCATION:"];
148 [s appendString:[[_apt location] iCalSafeString]];
149 [s appendString:@"\r\n"];
151 [s appendString:@"UID:"];
152 [s appendString:[_apt uid]];
153 [s appendString:@"\r\n"];
155 [s appendString:@"DTSTART:"];
156 [s appendString:[[_apt startDate] icalString]];
157 [s appendString:@"\r\n"];
159 if ([_apt hasEndDate]) {
160 [s appendString:@"DTEND:"];
161 [s appendString:[[_apt endDate] icalString]];
162 [s appendString:@"\r\n"];
164 if ([_apt hasDuration]) {
165 [s appendString:@"DURATION:"];
166 [s appendString:[event duration]];
167 [s appendString:@"\r\n"];
169 if([_apt hasPriority]) {
170 [s appendString:@"PRIORITY:"];
171 [s appendString:[_apt priority]];
172 [s appendString:@"\r\n"];
174 if([_apt hasCategories]) {
177 catString = [[_apt categories] componentsJoinedByString:@","];
178 [s appendString:@"CATEGORIES:"];
179 [s appendString:catString];
180 [s appendString:@"\r\n"];
182 if([_apt hasComment]) {
183 [s appendString:@"DESCRIPTION:"]; /* this is what iCal.app does */
184 [s appendString:[[_apt comment] iCalSafeString]];
185 [s appendString:@"\r\n"];
188 [s appendString:@"STATUS:"];
189 [s appendString:[_apt status]];
190 [s appendString:@"\r\n"];
192 [s appendString:@"TRANSP:"];
193 [s appendString:[_apt transparency]];
194 [s appendString:@"\r\n"];
196 [s appendString:@"CLASS:"];
197 [s appendString:[_apt accessClass]];
198 [s appendString:@"\r\n"];
200 /* recurrence rules */
201 if ([_apt hasRecurrenceRule]) {
202 [s appendString:@"RRULE:"];
203 [s appendString:[[_apt recurrenceRule] iCalRepresentation]];
204 [s appendString:@"\r\n"];
207 [self addOrganizer:[_apt organizer] toString:s];
208 [self addAttendees:[_apt attendees] toString:s];
211 [s appendString:@"END:VEVENT\r\n"];
214 - (BOOL)isValidAppointment:(SOGoAppointment *)_apt {
215 if (![_apt isNotNull])
218 if ([[_apt uid] length] == 0) {
219 [self warnWithFormat:@"got apt without uid, rejecting iCal generation: %@",
223 if ([[[_apt startDate] icalString] length] == 0) {
224 [self warnWithFormat:@"got apt without start date, "
225 @"rejecting iCal generation: %@",
233 - (NSString *)vEventStringForAppointment:(SOGoAppointment *)_apt {
236 if (![self isValidAppointment:_apt])
239 s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity];
240 [self addVEventForAppointment:_apt toString:s];
244 - (NSString *)stringForAppointment:(SOGoAppointment *)_apt {
247 if (![self isValidAppointment:_apt])
250 s = [NSMutableString stringWithCapacity:DefaultICalStringCapacity];
251 [self addPreambleForAppointment:_apt toString:s];
252 [self addVEventForAppointment:_apt toString:s];
253 [self addPostambleForAppointment:_apt toString:s];
257 @end /* SOGoAppointmentICalRenderer */