2 Copyright (C) 2004-2005 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
25 Show plain/calendar mail parts.
28 #import <NGObjWeb/WOResponse.h>
30 #import <NGExtensions/NSCalendarDate+misc.h>
31 #import <NGExtensions/NSObject+Logs.h>
33 #import <NGImap4/NGImap4EnvelopeAddress.h>
35 #import <NGCards/iCalCalendar.h>
36 #import <NGCards/iCalEvent.h>
37 #import <NGCards/iCalPerson.h>
38 #import <NGCards/iCalDateTime.h>
40 #import <SoObjects/SOGo/SOGoDateFormatter.h>
41 #import <SoObjects/SOGo/SOGoUser.h>
42 #import <SoObjects/Appointments/iCalEntityObject+SOGo.h>
43 #import <SoObjects/Appointments/SOGoAppointmentFolder.h>
44 #import <SoObjects/Appointments/SOGoAppointmentObject.h>
45 #import <SoObjects/Mailer/SOGoMailObject.h>
46 #import <SoObjects/Mailer/SOGoMailBodyPart.h>
48 #import "UIxMailPartICalViewer.h"
50 @implementation UIxMailPartICalViewer
54 [storedEventObject release];
55 [storedEvent release];
60 [dateFormatter release];
66 - (void) resetPathCaches
68 [super resetPathCaches];
69 [inEvent release]; inEvent = nil;
70 [inCalendar release]; inCalendar = nil;
71 [storedEventObject release]; storedEventObject = nil;
72 [storedEvent release]; storedEvent = nil;
74 /* not strictly path-related, but useless without it anyway: */
75 [attendee release]; attendee = nil;
76 [item release]; item = nil;
81 - (iCalCalendar *) inCalendar
86 = [iCalCalendar parseSingleFromSource: [self flatContentAsString]];
93 - (BOOL) couldParseCalendar
95 return (([self inCalendar]));
98 - (iCalEvent *) inEvent
104 events = [[self inCalendar] events];
105 if ([events count] > 0)
106 inEvent = [[events objectAtIndex:0] retain];
114 - (SOGoDateFormatter *) dateFormatter
118 dateFormatter = [[context activeUser] dateFormatterInContext: context];
119 [dateFormatter retain];
122 return dateFormatter;
125 /* below is copied from UIxAppointmentView, can we avoid that? */
127 - (void) setAttendee: (id) _attendee
129 ASSIGN (attendee, _attendee);
137 - (NSString *) _personForDisplay: (iCalPerson *) person
139 NSString *fn, *email, *result;
141 fn = [person cnWithoutQuotes];
142 email = [person rfc822Email];
144 result = [NSString stringWithFormat: @"%@ <%@>",
152 - (NSString *) attendeeForDisplay
154 return [self _personForDisplay: attendee];
157 - (void) setItem: (id) _item
167 - (NSCalendarDate *) startTime
169 NSCalendarDate *date;
170 NSTimeZone *timeZone;
172 date = [[self authorativeEvent] startDate];
173 timeZone = [[context activeUser] timeZone];
174 [date setTimeZone: timeZone];
179 - (NSCalendarDate *) endTime
181 NSCalendarDate *date;
182 NSTimeZone *timeZone;
184 date = [[self authorativeEvent] endDate];
185 timeZone = [[context activeUser] timeZone];
186 [date setTimeZone: timeZone];
191 - (BOOL) isEndDateOnSameDay
193 return [[self startTime] isDateOnSameDay:[self endTime]];
196 - (NSTimeInterval) duration
198 return [[self endTime] timeIntervalSinceDate:[self startTime]];
201 /* calendar folder support */
203 - (SOGoAppointmentFolder *) calendarFolder
205 /* return scheduling calendar of currently logged-in user */
209 user = [context activeUser];
210 folder = [[user homeFolderInContext: context] lookupName: @"Calendar"
214 return [folder lookupName: @"personal" inContext: context acquire: NO];
217 - (SOGoAppointmentObject *) storedEventObject
219 /* lookup object in the users Calendar */
220 SOGoAppointmentFolder *calendar;
223 if (!storedEventObject)
225 calendar = [self calendarFolder];
226 if ([calendar isKindOfClass: [NSException class]])
227 [self errorWithFormat:@"Did not find Calendar folder: %@", calendar];
230 filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
233 storedEventObject = [calendar lookupName: filename
234 inContext: [self context]
236 if ([storedEventObject isKindOfClass: [NSException class]])
237 storedEventObject = nil;
239 [storedEventObject retain];
244 return storedEventObject;
247 - (BOOL) isEventStoredInCalendar
249 return (([self storedEventObject]));
252 - (iCalEvent *) storedEvent
256 storedEvent = [[self storedEventObject] component: NO secure: NO];
257 [storedEvent retain];
263 /* organizer tracking */
265 - (NSString *) loggedInUserEMail
267 NSDictionary *identity;
269 identity = [[context activeUser] primaryIdentity];
271 return [identity objectForKey: @"email"];
274 - (iCalEvent *) authorativeEvent
276 iCalEvent *authorativeEvent;
280 || ([storedEvent compare: [self inEvent]] == NSOrderedAscending))
281 authorativeEvent = inEvent;
283 authorativeEvent = [self storedEvent];
285 return authorativeEvent;
288 - (BOOL) isLoggedInUserTheOrganizer
290 return [[self authorativeEvent] userIsOrganizer: [context activeUser]];
293 - (BOOL) isLoggedInUserAnAttendee
295 return [[self authorativeEvent] userIsParticipant: [context activeUser]];
300 - (NSString *) organizerDisplayName
302 iCalPerson *organizer;
305 organizer = [[self authorativeEvent] organizer];
307 value = [self _personForDisplay: organizer];
309 value = @"[todo: no organizer set, use 'from']";
316 - (NGImap4EnvelopeAddress *) replySenderAddress
319 The iMIP reply is the sender of the mail, the 'attendees' are NOT set to
320 the actual attendees. BUT the attendee field contains the reply-status!
324 tmp = [[self clientObject] fromEnvelopeAddresses];
325 if ([tmp count] == 0) return nil;
326 return [tmp objectAtIndex:0];
329 - (NSString *) replySenderEMail
331 return [[self replySenderAddress] email];
334 - (NSString *) replySenderBaseEMail
336 return [[self replySenderAddress] baseEMail];
339 - (iCalPerson *) inReplyAttendee
343 attendees = [[self inEvent] attendees];
344 if ([attendees count] == 0)
346 if ([attendees count] > 1)
347 [self warnWithFormat:@"More than one attendee in REPLY: %@", attendees];
349 return [attendees objectAtIndex:0];
352 - (iCalPerson *) storedReplyAttendee
355 TODO: since an attendee can have multiple email addresses, maybe we
356 should translate the email to an internal uid and then retrieve
357 all emails addresses for matching the participant.
359 Note: -findParticipantWithEmail: does not parse the email!
366 e = [self storedEvent];
369 p = [e findParticipantWithEmail: [self replySenderBaseEMail]];
371 p = [e findParticipantWithEmail:[self replySenderEMail]];
377 - (BOOL) isReplySenderAnAttendee
379 return (([self storedReplyAttendee]));
382 - (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
385 SOGoMailObject *mailObject;
386 NGImap4EnvelopeAddress *address;
388 mailObject = [[self clientObject] mailObject];
389 address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
390 emailFrom = [address baseEMail];
392 return [event findParticipantWithEmail: emailFrom];
395 - (BOOL) hasSenderStatusChanged
397 iCalPerson *emailParticipant, *calendarParticipant;
401 emailParticipant = [self _emailParticipantWithEvent: inEvent];
402 calendarParticipant = [self _emailParticipantWithEvent: storedEvent];
404 return ([[emailParticipant partStat]
405 caseInsensitiveCompare: [calendarParticipant partStat]]
409 @end /* UIxMailPartICalViewer */