*/
// $Id$
-
#include "SOGoAppointment.h"
+#include "SOGoAppointmentICalRenderer.h"
#include <SaxObjC/SaxObjC.h>
#include <NGiCal/NGiCal.h>
#include <EOControl/EOControl.h>
#include "common.h"
-@interface NSDate(UsedPrivates)
-- (NSString *)icalString; // declared in NGiCal
-@end
-
@interface SOGoAppointment (PrivateAPI)
- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
@end
[parser setErrorHandler:sax];
}
-- (id)initWithICalString:(NSString *)_iCal {
- if ([_iCal length] == 0) {
- [self logWithFormat:@"ERROR: tried to init SOGoAppointment without iCal"];
- [self release];
- return nil;
- }
- if ((self = [self init])) {
- id root;
+- (id)initWithICalRootObject:(id)_root {
+ if ((self = [super init])) {
+#if 0
+ [self logWithFormat:@"root is: %@", root];
+#endif
- if (parser == nil || sax == nil) {
- [self release];
- return nil;
+ if ([_root isKindOfClass:[iCalEvent class]]) {
+ self->event = [_root retain];
}
-
- /* parse */
-
- if ([_iCal length] > 0) {
- [parser parseFromSource:_iCal];
- root = [[sax rootObject] retain];
- [sax reset];
- }
- else
- root = nil;
-
- /* fill */
-
- // [self logWithFormat:@"root is: %@", root];
-
- if ([root isKindOfClass:[iCalEvent class]]) {
- self->event = root;
- }
- else if ([root isKindOfClass:[NSDictionary class]]) {
+ else if ([_root isKindOfClass:[NSDictionary class]]) {
/* multiple vevents in the calendar */
[self logWithFormat:
@"ERROR(%s): tried to initialize with multiple records: %@",
- __PRETTY_FUNCTION__, root];
+ __PRETTY_FUNCTION__, _root];
[self release];
return nil;
}
else {
- self->calendar = root;
+ self->calendar = [_root retain];
self->event = [[[self->calendar events] lastObject] retain];
}
}
return self;
}
+- (id)initWithICalString:(NSString *)_iCal {
+ id root;
+
+ if ([_iCal length] == 0) {
+ [self logWithFormat:@"ERROR: tried to init SOGoAppointment without iCal"];
+ [self release];
+ return nil;
+ }
+ if (parser == nil || sax == nil) {
+ [self logWithFormat:@"ERROR: iCal parser not properly set up!"];
+ [self release];
+ return nil;
+ }
+
+ if ([_iCal length] > 0) {
+ [parser parseFromSource:_iCal];
+ root = [[sax rootObject] retain]; /* retain to keep it around */
+ [sax reset];
+ }
+ else
+ root = nil;
+
+ self = [self initWithICalRootObject:root];
+ [root release];
+ return self;
+}
- (void)dealloc {
[self->calendar release];
return self->event;
}
-/* TODO: REMOVE THIS HACK ASAP */
- (NSString *)iCalString {
- NSMutableString *s;
- NSArray *persons;
- unsigned i, count;
- iCalPerson *p;
-
- /* assume length of 1K - reasonable ? */
- s = [NSMutableString stringWithCapacity:1024];
-
- [s appendString:@"BEGIN:VCALENDAR\nMETHOD:REQUEST\nPRODID:"];
- if (self->calendar == nil)
- [s appendString:@"SOGo/0.9"];
- else
- [s appendString:[self->calendar prodId]];
- [s appendString:@"\nVERSION:"];
- if (self->calendar == nil)
- [s appendString:@"2.0"];
- else
- [s appendString:[(iCalCalendar *)self->calendar version]];
- [s appendString:@"\nBEGIN:VEVENT"];
- [s appendString:@"\nSUMMARY:"];
- [s appendString:[self summary]];
- if([self hasLocation]) {
- [s appendString:@"\nLOCATION:"];
- [s appendString:[self location]];
- }
- [s appendString:@"\nUID:"];
- [s appendString:[self uid]];
- [s appendString:@"\nDTSTART:"];
- [s appendString:[[self startDate] icalString]];
- if([self hasEndDate]) {
- [s appendString:@"\nDTEND:"];
- [s appendString:[[self endDate] icalString]];
- }
- if([self hasDuration]) {
- [s appendString:@"\nDURATION:"];
- [s appendString:[(iCalEvent *)self->event duration]];
- }
- [s appendString:@"\nSTATUS:"];
- [s appendString:[self status]];
-
- /* what's all this? */
- [s appendString:@"\nTRANSP:OPAQUE"]; /* transparency */
- [s appendString:@"\nCLASS:PRIVATE"]; /* classification [like 'top secret'] */
-
- /* organizer */
- p = [self organizer];
- if(p) {
- NSString *x;
-
- [s appendString:@"\nORGANIZER;CN=\""];
- if((x = [p cn])) {
- [s appendString:x];
- }
- [s appendString:@"\""];
- if((x = [p email])) {
- [s appendString:@":"]; /* sic! */
- [s appendString:x];
- }
- }
-
- /* attendees */
- persons = [self attendees];
- count = [persons count];
- for (i = 0; i < count; i++) {
- NSString *x;
-
- p = [persons objectAtIndex:i];
- [s appendString:@"\nATTENDEE;"];
- if((x = [p role])) {
- [s appendString:@"ROLE="];
- [s appendString:x];
- [s appendString:@";"];
- }
- [s appendString:@"CN=\""];
- if((x = [p cn])) {
- [s appendString:x];
- }
- [s appendString:@"\""];
- if((x = [p email])) {
- [s appendString:@":"]; /* sic! */
- [s appendString:x];
- }
- }
-
- /* postamble */
- [s appendString:@"\nEND:VEVENT\nEND:VCALENDAR"];
- return s;
+ return [[SOGoAppointmentICalRenderer sharedAppointmentRenderer]
+ stringForAppointment:self];
}
-
/* forwarded methods */
-
- (void)setUid:(NSString *)_value {
[self->event setUid:_value];
}
}
- (void)setLocation:(NSString *)_value {
- [self->event setLocation:_value];
+ [self->event setLocation:_value];
}
- (NSString *)location {
- return [self->event location];
+ return [self->event location];
}
- (BOOL)hasLocation {
- return ([self location] != nil) && ([[self location] length] > 0);
+ if (![[self location] isNotNull])
+ return NO;
+ return [[self location] length] > 0 ? YES : NO;
}
- (void)setStatus:(NSString *)_value {
- [self->event setStatus:_value];
+ [self->event setStatus:_value];
}
- (NSString *)status {
- return [(iCalEvent *)self->event status];
+ return [(iCalEvent *)self->event status];
}
- (void)setStartDate:(NSCalendarDate *)_date {
- [self->event setStartDate:_date];
+ [self->event setStartDate:_date];
}
-
- (NSCalendarDate *)startDate {
- return [self->event startDate];
+ return [self->event startDate];
}
- (void)setEndDate:(NSCalendarDate *)_date {
- [self->event setEndDate:_date];
+ [self->event setEndDate:_date];
}
- (NSCalendarDate *)endDate {
- return [self->event endDate];
+ return [self->event endDate];
}
- (BOOL)hasEndDate {
- return [self->event hasEndDate];
+ return [self->event hasEndDate];
}
-- (BOOL)hasDuration {
- return [self->event hasDuration];
-}
- (void)setDuration:(NSTimeInterval)_duration {
+ // TODO
+ [self logWithFormat:@"WARNING: could not apply duration!"];
+}
+- (BOOL)hasDuration {
+ return [self->event hasDuration];
}
- (NSTimeInterval)duration {
- return [self->event durationAsTimeInterval];
+ return [self->event durationAsTimeInterval];
}
- (void)setOrganizer:(iCalPerson *)_organizer {
- [self->event setOrganizer:_organizer];
+ [self->event setOrganizer:_organizer];
}
- (iCalPerson *)organizer {
- return [self->event organizer];
+ return [self->event organizer];
}
- (void)removeAllAttendees {
- [self->event removeAllAttendees];
+ [self->event removeAllAttendees];
}
- (void)addToAttendees:(iCalPerson *)_person {
- [self->event addToAttendees:_person];
+ [self->event addToAttendees:_person];
}
- (void)appendAttendees:(NSArray *)_persons {
- unsigned i, count;
-
- count = [_persons count];
- for(i = 0; i < count; i++) {
- [self addToAttendees:[_persons objectAtIndex:i]];
- }
+ unsigned i, count;
+
+ count = [_persons count];
+ for (i = 0; i < count; i++)
+ [self addToAttendees:[_persons objectAtIndex:i]];
}
- (NSArray *)attendees {
- return [self->event attendees];
-}
-
-- (BOOL)hasParticipants {
- return [[self participants] count] != 0;
+ return [self->event attendees];
}
- (NSArray *)participants {
- if(self->participants == nil) {
- ASSIGN(self->participants,
- [self _filteredAttendeesThinkingOfPersons:YES]);
- }
+ if (self->participants)
return self->participants;
+
+ self->participants = [[self _filteredAttendeesThinkingOfPersons:YES] retain];
+ return self->participants;
+}
+- (BOOL)hasParticipants {
+ return [[self participants] count] != 0;
}
- (NSArray *)resources {
- return [self _filteredAttendeesThinkingOfPersons:NO];
+ return [self _filteredAttendeesThinkingOfPersons:NO];
}
- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons {
- NSArray *list;
- NSMutableArray *filtered;
- unsigned i, count;
-
- list = [self attendees];
- count = [list count];
- filtered = [[NSMutableArray alloc] initWithCapacity:count];
- for(i = 0; i < count; i++) {
- iCalPerson *p;
- NSString *role;
-
- p = [list objectAtIndex:i];
- role = [p role];
- if(_persons) {
- if(role == nil || ![role isEqualToString:@"NON-PART"])
- [filtered addObject:p];
- }
- else {
- if([role isEqualToString:@"NON-PART"])
- [filtered addObject:p];
- }
+ NSArray *list;
+ NSMutableArray *filtered;
+ unsigned i, count;
+
+ list = [self attendees];
+ count = [list count];
+ filtered = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ iCalPerson *p;
+ NSString *role;
+
+ p = [list objectAtIndex:i];
+ role = [p role];
+ if (_persons) {
+ if (role == nil || ![role isEqualToString:@"NON-PART"])
+ [filtered addObject:p];
}
- return [filtered autorelease];
+ else {
+ if ([role isEqualToString:@"NON-PART"])
+ [filtered addObject:p];
+ }
+ }
+ return filtered;
}
-@end
+@end /* SOGoAppointment */
--- /dev/null
+/*
+ Copyright (C) 2004 SKYRIX Software AG
+
+ This file is part of OpenGroupware.org.
+
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+
+#include "SOGoAppointmentICalRenderer.h"
+#include "SOGoAppointment.h"
+#include <NGiCal/NGiCal.h>
+#include "common.h"
+
+// TODO: the basic renderer should be part of NGiCal
+
+@interface NSDate(UsedPrivates)
+- (NSString *)icalString; // declared in NGiCal
+@end
+
+@implementation SOGoAppointmentICalRenderer
+
+static SOGoAppointmentICalRenderer *renderer = nil;
+
++ (id)sharedAppointmentRenderer {
+ if (renderer == nil)
+ renderer = [[self alloc] init];
+ return renderer;
+}
+
+/* renderer */
+
+- (void)addPreambleForAppointment:(SOGoAppointment *)_apt
+ toString:(NSMutableString *)s
+{
+ iCalCalendar *calendar;
+
+ calendar = [_apt calendar];
+
+ [s appendString:@"BEGIN:VCALENDAR\nMETHOD:REQUEST\n"];
+
+ [s appendString:@"PRODID:"];
+ [s appendString:[calendar isNotNull] ? [calendar prodId] : @"SOGo/0.9"];
+ [s appendString:@"\n"];
+
+ [s appendString:@"\nVERSION:"];
+ [s appendString:[calendar isNotNull] ? [calendar version] : @"2.0"];
+ [s appendString:@"\n"];
+}
+- (void)addPostambleForAppointment:(SOGoAppointment *)_apt
+ toString:(NSMutableString *)s
+{
+ [s appendString:@"END:VCALENDAR\n"];
+}
+
+- (void)addOrganizer:(iCalPerson *)p toString:(NSMutableString *)s {
+ NSString *x;
+
+ if (![p isNotNull]) return;
+
+ [s appendString:@"ORGANIZER;CN=\""];
+ if ((x = [p cn]))
+ [s appendString:x];
+
+ [s appendString:@"\""];
+ if ((x = [p email])) {
+ [s appendString:@":"]; /* sic! */
+ [s appendString:x];
+ }
+ [s appendString:@"\n"];
+}
+
+- (void)addAttendees:(NSArray *)persons toString:(NSMutableString *)s {
+ unsigned i, count;
+ iCalPerson *p;
+
+ count = [persons count];
+ for (i = 0; i < count; i++) {
+ NSString *x;
+
+ p = [persons objectAtIndex:i];
+ [s appendString:@"ATTENDEE;"];
+
+ if ((x = [p role])) {
+ [s appendString:@"ROLE="];
+ [s appendString:x];
+ [s appendString:@";"];
+ }
+
+ [s appendString:@"CN=\""];
+ if ((x = [p cn])) {
+ [s appendString:x];
+ }
+ [s appendString:@"\""];
+ if ([(x = [p email]) isNotNull]) {
+ [s appendString:@":"]; /* sic! */
+ [s appendString:x];
+ }
+ [s appendString:@"\n"];
+ }
+}
+
+- (void)addVEventForAppointment:(SOGoAppointment *)_apt
+ toString:(NSMutableString *)s
+{
+ iCalEvent *event;
+
+ event = [_apt event];
+
+ [s appendString:@"BEGIN:VEVENT\n"];
+
+ [s appendString:@"SUMMARY:"];
+ [s appendString:[_apt summary]];
+ [s appendString:@"\n"];
+ if ([_apt hasLocation]) {
+ [s appendString:@"LOCATION:"];
+ [s appendString:[_apt location]];
+ [s appendString:@"\n"];
+ }
+ [s appendString:@"UID:"];
+ [s appendString:[_apt uid]];
+ [s appendString:@"\n"];
+
+ [s appendString:@"DTSTART:"];
+ [s appendString:[[_apt startDate] icalString]];
+ [s appendString:@"\n"];
+ if ([_apt hasEndDate]) {
+ [s appendString:@"DTEND:"];
+ [s appendString:[[_apt endDate] icalString]];
+ }
+ if ([_apt hasDuration]) {
+ [s appendString:@"DURATION:"];
+ [s appendString:[event duration]];
+ }
+ [s appendString:@"\n"];
+
+ [s appendString:@"STATUS:"];
+ [s appendString:[_apt status]];
+ [s appendString:@"\n"];
+
+ /* what's all this? */
+ [s appendString:@"TRANSP:OPAQUE"]; /* transparency */
+ [s appendString:@"\nCLASS:PRIVATE"]; /* classification [like 'top secret'] */
+ [s appendString:@"\n"];
+
+ [self addOrganizer:[_apt organizer] toString:s];
+ [self addAttendees:[_apt attendees] toString:s];
+
+ /* postamble */
+ [s appendString:@"END:VEVENT\n"];
+}
+
+- (NSString *)stringForAppointment:(SOGoAppointment *)_apt {
+ NSMutableString *s;
+
+ /* assume length of 1K - reasonable ? */
+ s = [NSMutableString stringWithCapacity:1024];
+ [self addPreambleForAppointment:_apt toString:s];
+ [self addVEventForAppointment:_apt toString:s];
+ [self addPostambleForAppointment:_apt toString:s];
+ return s;
+}
+
+@end /* SOGoAppointmentICalRenderer */