2006-06-15 21:34:10 +02:00
|
|
|
/*
|
2015-06-04 01:42:30 +02:00
|
|
|
Copyright (C) 2006-2015 Inverse inc.
|
2013-07-16 17:31:08 +02:00
|
|
|
|
2011-07-05 15:24:25 +02:00
|
|
|
This file is part of SOGo.
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2011-07-05 15:24:25 +02:00
|
|
|
SOGo is free software; you can redistribute it and/or modify it under
|
2006-06-15 21:34:10 +02:00
|
|
|
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.
|
|
|
|
|
2011-07-05 15:24:25 +02:00
|
|
|
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
2006-06-15 21:34:10 +02:00
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
2007-11-10 01:02:30 +01:00
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
2006-06-15 21:34:10 +02:00
|
|
|
License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2011-07-05 15:24:25 +02:00
|
|
|
License along with SOGo; see the file COPYING. If not, write to the
|
2006-06-15 21:34:10 +02:00
|
|
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
UIxMailPartICalViewer
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
Show plain/calendar mail parts.
|
|
|
|
*/
|
|
|
|
|
2010-04-21 16:44:42 +02:00
|
|
|
#import <Foundation/NSDictionary.h>
|
2012-10-22 16:09:13 +02:00
|
|
|
#import <Foundation/NSException.h>
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <Foundation/NSValue.h>
|
|
|
|
|
2007-11-13 18:39:33 +01:00
|
|
|
|
2007-07-30 16:10:18 +02:00
|
|
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
|
|
|
|
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
|
|
|
|
|
|
|
#import <NGCards/iCalCalendar.h>
|
|
|
|
#import <NGCards/iCalEvent.h>
|
|
|
|
#import <NGCards/iCalPerson.h>
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/SOGoDateFormatter.h>
|
|
|
|
#import <SOGo/SOGoUser.h>
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <SOGo/SOGoUserFolder.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/SOGoUserDefaults.h>
|
|
|
|
#import <Appointments/iCalEntityObject+SOGo.h>
|
|
|
|
#import <Appointments/SOGoAppointmentFolder.h>
|
|
|
|
#import <Appointments/SOGoAppointmentObject.h>
|
|
|
|
#import <Mailer/SOGoMailObject.h>
|
|
|
|
#import <Mailer/SOGoMailBodyPart.h>
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2006-09-29 20:31:20 +02:00
|
|
|
#import "UIxMailPartICalViewer.h"
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
@implementation UIxMailPartICalViewer
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
[storedEventObject release];
|
|
|
|
[storedEvent release];
|
|
|
|
[inCalendar release];
|
|
|
|
[dateFormatter release];
|
2006-06-15 21:34:10 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* maintain caches */
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (void) resetPathCaches
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
[super resetPathCaches];
|
2009-02-06 21:15:41 +01:00
|
|
|
inEvent = nil;
|
2007-11-10 01:02:30 +01:00
|
|
|
[inCalendar release]; inCalendar = nil;
|
|
|
|
[storedEventObject release]; storedEventObject = nil;
|
|
|
|
[storedEvent release]; storedEvent = nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* accessors */
|
|
|
|
|
2006-09-29 20:31:20 +02:00
|
|
|
- (iCalCalendar *) inCalendar
|
|
|
|
{
|
|
|
|
if (!inCalendar)
|
|
|
|
{
|
|
|
|
inCalendar
|
2007-11-10 01:02:30 +01:00
|
|
|
= [iCalCalendar parseSingleFromSource: [self flatContentAsString]];
|
2006-09-29 20:31:20 +02:00
|
|
|
[inCalendar retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return inCalendar;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-09-29 20:31:20 +02:00
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (BOOL) couldParseCalendar
|
|
|
|
{
|
2007-12-17 16:29:06 +01:00
|
|
|
return ([self inCalendar] != nil);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (iCalEvent *) inEvent
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *events;
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
if (!inEvent)
|
|
|
|
{
|
|
|
|
events = [[self inCalendar] events];
|
|
|
|
if ([events count] > 0)
|
2009-02-06 21:15:41 +01:00
|
|
|
inEvent = [events objectAtIndex: 0];
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return inEvent;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* formatters */
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (SOGoDateFormatter *) dateFormatter
|
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
if (!dateFormatter)
|
|
|
|
{
|
|
|
|
dateFormatter = [[context activeUser] dateFormatterInContext: context];
|
|
|
|
[dateFormatter retain];
|
|
|
|
}
|
2007-06-19 20:06:42 +02:00
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
return dateFormatter;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-03-30 20:09:55 +02:00
|
|
|
- (NSString *) _personForDisplay: (iCalPerson *) person
|
|
|
|
{
|
2007-11-10 01:02:30 +01:00
|
|
|
NSString *fn, *email, *result;
|
|
|
|
|
|
|
|
fn = [person cnWithoutQuotes];
|
|
|
|
email = [person rfc822Email];
|
|
|
|
if ([fn length])
|
|
|
|
result = [NSString stringWithFormat: @"%@ <%@>",
|
2015-08-04 19:52:31 +02:00
|
|
|
fn, email];
|
2007-11-10 01:02:30 +01:00
|
|
|
else
|
|
|
|
result = email;
|
|
|
|
|
|
|
|
return result;
|
2007-03-30 20:09:55 +02:00
|
|
|
}
|
|
|
|
|
2009-03-24 21:50:18 +01:00
|
|
|
- (NSCalendarDate *) startCalendarDate
|
2007-04-11 21:08:58 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSCalendarDate *date;
|
2009-11-29 05:19:32 +01:00
|
|
|
SOGoUserDefaults *ud;
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2008-11-29 00:18:54 +01:00
|
|
|
date = [[self inEvent] startDate];
|
2009-11-29 05:19:32 +01:00
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
[date setTimeZone: [ud timeZone]];
|
2009-03-24 21:50:18 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
2015-06-04 01:42:30 +02:00
|
|
|
/*
|
|
|
|
In v3.0, we moved the template's logic here to format
|
|
|
|
the event's start/end date-time. The previous logic was:
|
|
|
|
|
|
|
|
<dd><var:string value="startDate" />
|
|
|
|
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
|
|
|
<var:string value="startTime" />
|
|
|
|
</var:if>
|
|
|
|
<var:if condition="isEndDateOnSameDay">
|
|
|
|
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
|
|
|
<var:string label:value="to" />
|
|
|
|
<var:string value="endTime" />
|
|
|
|
</var:if>
|
|
|
|
</var:if>
|
|
|
|
<var:if condition="isEndDateOnSameDay" const:negate="YES">
|
|
|
|
<var:string label:value="to" />
|
|
|
|
<var:string value="endDate" />
|
|
|
|
<var:if condition="inEvent.isAllDay" const:negate="YES">
|
|
|
|
<var:string value="endTime" />
|
|
|
|
</var:if>
|
|
|
|
</var:if>
|
|
|
|
</dd>
|
|
|
|
|
|
|
|
*/
|
|
|
|
- (NSString *) formattedDateTime
|
|
|
|
{
|
|
|
|
NSMutableString *s;
|
|
|
|
|
|
|
|
s = [NSMutableString string];
|
|
|
|
|
|
|
|
[s appendString: [self startDate]];
|
|
|
|
|
|
|
|
if (![[self inEvent] isAllDay])
|
|
|
|
[s appendFormat: @" %@", [self startTime]];
|
|
|
|
|
|
|
|
if ([self isEndDateOnSameDay] &&
|
|
|
|
![[self inEvent] isAllDay])
|
|
|
|
{
|
|
|
|
[s appendFormat: @" %@", [self labelForKey: @"to"]];
|
|
|
|
[s appendFormat: @" %@", [self endTime]];
|
|
|
|
}
|
|
|
|
else if (![self isEndDateOnSameDay])
|
|
|
|
{
|
|
|
|
[s appendFormat: @" %@", [self labelForKey: @"to"]];
|
|
|
|
[s appendFormat: @" %@", [self endDate]];
|
|
|
|
|
|
|
|
if (![[self inEvent] isAllDay])
|
|
|
|
[s appendFormat: @" %@", [self endTime]];
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2009-03-24 21:50:18 +01:00
|
|
|
- (NSString *) startDate
|
|
|
|
{
|
|
|
|
return [[self dateFormatter] formattedDate: [self startCalendarDate]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) startTime
|
|
|
|
{
|
|
|
|
return [[self dateFormatter] formattedTime: [self startCalendarDate]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSCalendarDate *) endCalendarDate
|
2007-04-11 21:08:58 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSCalendarDate *date;
|
2009-11-29 05:19:32 +01:00
|
|
|
SOGoUserDefaults *ud;
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2008-11-29 00:18:54 +01:00
|
|
|
date = [[self inEvent] endDate];
|
2009-11-29 05:19:32 +01:00
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
[date setTimeZone: [ud timeZone]];
|
2007-04-11 21:08:58 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
2009-03-24 21:50:18 +01:00
|
|
|
- (NSString *) endDate
|
|
|
|
{
|
|
|
|
NSCalendarDate *aDate;
|
|
|
|
if ([[self inEvent] isAllDay])
|
|
|
|
aDate = [[self endCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-1];
|
|
|
|
else
|
|
|
|
aDate = [self endCalendarDate];
|
|
|
|
|
|
|
|
return [[self dateFormatter] formattedDate: aDate];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) endTime
|
|
|
|
{
|
|
|
|
return [[self dateFormatter] formattedTime: [self endCalendarDate]];
|
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (BOOL) isEndDateOnSameDay
|
|
|
|
{
|
2009-03-24 21:50:18 +01:00
|
|
|
NSCalendarDate *aDate;
|
|
|
|
if ([[self inEvent] isAllDay])
|
|
|
|
aDate = [[self endCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-1];
|
|
|
|
else
|
|
|
|
aDate = [self endCalendarDate];
|
|
|
|
return [[self startCalendarDate] isDateOnSameDay: aDate];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-11-10 01:02:30 +01:00
|
|
|
|
|
|
|
- (NSTimeInterval) duration
|
|
|
|
{
|
2009-03-24 21:50:18 +01:00
|
|
|
return [[self endCalendarDate] timeIntervalSinceDate:[self startCalendarDate]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* calendar folder support */
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (SOGoAppointmentFolder *) calendarFolder
|
2007-09-17 20:01:02 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* return scheduling calendar of currently logged-in user */
|
2007-05-09 21:23:45 +02:00
|
|
|
SOGoUser *user;
|
|
|
|
id folder;
|
|
|
|
|
|
|
|
user = [context activeUser];
|
|
|
|
folder = [[user homeFolderInContext: context] lookupName: @"Calendar"
|
|
|
|
inContext: context
|
|
|
|
acquire: NO];
|
|
|
|
|
2007-09-17 20:01:02 +02:00
|
|
|
return [folder lookupName: @"personal" inContext: context acquire: NO];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-08-28 19:22:36 +02:00
|
|
|
- (BOOL) hasCalendarAccess
|
|
|
|
{
|
|
|
|
return [[context activeUser] canAccessModule: @"Calendar"];
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (SOGoAppointmentObject *) storedEventObject
|
2007-11-10 01:02:30 +01:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* lookup object in the users Calendar */
|
2007-11-18 11:16:25 +01:00
|
|
|
SOGoAppointmentFolder *calendar;
|
|
|
|
NSString *filename;
|
2009-06-17 15:35:08 +02:00
|
|
|
|
|
|
|
if (!storedEventFetched)
|
2007-11-18 11:16:25 +01:00
|
|
|
{
|
2009-06-17 15:35:08 +02:00
|
|
|
if ([self hasCalendarAccess])
|
|
|
|
{
|
|
|
|
calendar = [self calendarFolder];
|
|
|
|
if ([calendar isKindOfClass: [NSException class]])
|
|
|
|
[self errorWithFormat:@"Did not find Calendar folder: %@", calendar];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
|
|
|
|
if (filename)
|
|
|
|
{
|
|
|
|
storedEventObject = [calendar lookupName: filename
|
|
|
|
inContext: [self context]
|
|
|
|
acquire: NO];
|
|
|
|
if ([storedEventObject isKindOfClass: [NSException class]])
|
2008-08-28 19:22:36 +02:00
|
|
|
storedEventObject = nil;
|
2009-06-17 15:35:08 +02:00
|
|
|
else
|
|
|
|
[storedEventObject retain];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
storedEventFetched = YES;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-11-10 01:02:30 +01:00
|
|
|
|
|
|
|
return storedEventObject;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (BOOL) isEventStoredInCalendar
|
|
|
|
{
|
2008-12-05 17:11:54 +01:00
|
|
|
NSCalendarDate *recurrenceId;
|
|
|
|
NSString *recurrenceTime;
|
2008-12-30 15:48:25 +01:00
|
|
|
BOOL isInCalendar;
|
2008-12-05 17:11:54 +01:00
|
|
|
|
|
|
|
recurrenceId = [[self inEvent] recurrenceId];
|
|
|
|
|
|
|
|
if (recurrenceId)
|
|
|
|
{
|
|
|
|
recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]];
|
2012-07-13 23:03:50 +02:00
|
|
|
isInCalendar = ([[self storedEventObject] lookupOccurrence: recurrenceTime] != nil);
|
2008-12-05 17:11:54 +01:00
|
|
|
}
|
|
|
|
else
|
2008-12-30 15:48:25 +01:00
|
|
|
isInCalendar = ([self storedEventObject] != nil);
|
2008-12-05 17:11:54 +01:00
|
|
|
|
2008-12-30 15:48:25 +01:00
|
|
|
return isInCalendar;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (iCalEvent *) storedEvent
|
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
if (!storedEvent)
|
|
|
|
{
|
2008-12-03 17:18:12 +01:00
|
|
|
NSCalendarDate *recurrenceId;
|
|
|
|
|
|
|
|
recurrenceId = [[self inEvent] recurrenceId];
|
|
|
|
|
|
|
|
if (recurrenceId == nil)
|
|
|
|
storedEvent = [[self storedEventObject] component: NO secure: NO];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Find the specific occurence within the repeating vEvent.
|
|
|
|
NSString *recurrenceTime;
|
2008-12-05 17:11:54 +01:00
|
|
|
iCalPerson *organizer;
|
2008-12-03 17:18:12 +01:00
|
|
|
|
|
|
|
recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]];
|
2012-07-13 23:03:50 +02:00
|
|
|
storedEvent = (iCalEvent*)[[self storedEventObject] lookupOccurrence: recurrenceTime];
|
2008-12-03 17:18:12 +01:00
|
|
|
|
|
|
|
if (storedEvent == nil)
|
|
|
|
// If no occurence found, create one
|
|
|
|
storedEvent = (iCalEvent*)[storedEventObject newOccurenceWithID: recurrenceTime];
|
2008-12-05 17:11:54 +01:00
|
|
|
|
|
|
|
// Add organizer to occurence if not present
|
|
|
|
organizer = [storedEvent organizer];
|
|
|
|
if (organizer == nil || [organizer isVoid])
|
|
|
|
{
|
2009-04-01 15:49:24 +02:00
|
|
|
organizer = [(iCalEntityObject *)[[storedEvent parent] firstChildWithTag: [storedEventObject componentTag]] organizer];
|
2008-12-05 17:11:54 +01:00
|
|
|
[storedEvent setOrganizer: organizer];
|
|
|
|
}
|
2008-12-03 17:18:12 +01:00
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
[storedEvent retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return storedEvent;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* organizer tracking */
|
|
|
|
|
2007-08-15 22:13:41 +02:00
|
|
|
- (NSString *) loggedInUserEMail
|
|
|
|
{
|
|
|
|
NSDictionary *identity;
|
|
|
|
|
|
|
|
identity = [[context activeUser] primaryIdentity];
|
|
|
|
|
|
|
|
return [identity objectForKey: @"email"];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (iCalEvent *) authorativeEvent
|
|
|
|
{
|
2007-11-13 23:38:05 +01:00
|
|
|
iCalEvent *authorativeEvent;
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
[self storedEvent];
|
|
|
|
if (!storedEvent
|
|
|
|
|| ([storedEvent compare: [self inEvent]] == NSOrderedAscending))
|
2007-11-13 23:38:05 +01:00
|
|
|
authorativeEvent = inEvent;
|
|
|
|
else
|
2007-11-18 11:16:25 +01:00
|
|
|
authorativeEvent = [self storedEvent];
|
2007-11-13 23:38:05 +01:00
|
|
|
|
|
|
|
return authorativeEvent;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (BOOL) isLoggedInUserTheOrganizer
|
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
return [[self authorativeEvent] userIsOrganizer: [context activeUser]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (BOOL) isLoggedInUserAnAttendee
|
|
|
|
{
|
2010-05-05 15:56:19 +02:00
|
|
|
return [[self authorativeEvent] userIsAttendee: [context activeUser]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* derived fields */
|
|
|
|
|
2007-03-30 20:09:55 +02:00
|
|
|
- (NSString *) organizerDisplayName
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
iCalPerson *organizer;
|
2007-03-30 20:09:55 +02:00
|
|
|
NSString *value;
|
|
|
|
|
|
|
|
organizer = [[self authorativeEvent] organizer];
|
2008-12-05 17:11:54 +01:00
|
|
|
if ([organizer isVoid])
|
2007-03-30 20:09:55 +02:00
|
|
|
value = @"[todo: no organizer set, use 'from']";
|
2008-12-05 17:11:54 +01:00
|
|
|
else
|
|
|
|
value = [self _personForDisplay: organizer];
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-03-30 20:09:55 +02:00
|
|
|
return value;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* replies */
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (NGImap4EnvelopeAddress *) replySenderAddress
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
The iMIP reply is the sender of the mail, the 'attendees' are NOT set to
|
|
|
|
the actual attendees. BUT the attendee field contains the reply-status!
|
|
|
|
*/
|
|
|
|
id tmp;
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
tmp = [[self clientObject] fromEnvelopeAddresses];
|
|
|
|
if ([tmp count] == 0) return nil;
|
|
|
|
return [tmp objectAtIndex:0];
|
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (NSString *) replySenderEMail
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self replySenderAddress] email];
|
|
|
|
}
|
2007-11-10 01:02:30 +01:00
|
|
|
|
|
|
|
- (NSString *) replySenderBaseEMail
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self replySenderAddress] baseEMail];
|
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (iCalPerson *) inReplyAttendee
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *attendees;
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
attendees = [[self inEvent] attendees];
|
|
|
|
if ([attendees count] == 0)
|
|
|
|
return nil;
|
|
|
|
if ([attendees count] > 1)
|
|
|
|
[self warnWithFormat:@"More than one attendee in REPLY: %@", attendees];
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return [attendees objectAtIndex:0];
|
|
|
|
}
|
2007-11-10 01:02:30 +01:00
|
|
|
|
2008-02-08 22:45:51 +01:00
|
|
|
- (iCalPerson *) currentUserAttendee
|
|
|
|
{
|
|
|
|
iCalPerson *currentUser;
|
|
|
|
|
2010-05-05 15:56:19 +02:00
|
|
|
currentUser = [[self authorativeEvent] userAsAttendee: [context activeUser]];
|
2008-02-08 22:45:51 +01:00
|
|
|
|
|
|
|
return currentUser;
|
|
|
|
}
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
- (iCalPerson *) storedReplyAttendee
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
TODO: since an attendee can have multiple email addresses, maybe we
|
2007-11-10 01:02:30 +01:00
|
|
|
should translate the email to an internal uid and then retrieve
|
|
|
|
all emails addresses for matching the participant.
|
|
|
|
|
2010-05-05 15:56:19 +02:00
|
|
|
Note: -findAttendeeWithEmail: does not parse the email!
|
2006-06-15 21:34:10 +02:00
|
|
|
*/
|
2007-11-10 01:02:30 +01:00
|
|
|
iCalEvent *e;
|
2006-06-15 21:34:10 +02:00
|
|
|
iCalPerson *p;
|
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
p = nil;
|
|
|
|
|
|
|
|
e = [self storedEvent];
|
|
|
|
if (e)
|
|
|
|
{
|
2010-05-05 15:56:19 +02:00
|
|
|
p = [e findAttendeeWithEmail: [self replySenderBaseEMail]];
|
2007-11-10 01:02:30 +01:00
|
|
|
if (!p)
|
2010-05-05 15:56:19 +02:00
|
|
|
p = [e findAttendeeWithEmail:[self replySenderEMail]];
|
2007-11-10 01:02:30 +01:00
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-11-10 01:02:30 +01:00
|
|
|
return p;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-11-10 01:02:30 +01:00
|
|
|
|
|
|
|
- (BOOL) isReplySenderAnAttendee
|
|
|
|
{
|
2007-12-17 16:29:06 +01:00
|
|
|
return ([self storedReplyAttendee] != nil);
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
|
|
|
|
{
|
|
|
|
NSString *emailFrom;
|
|
|
|
SOGoMailObject *mailObject;
|
|
|
|
NGImap4EnvelopeAddress *address;
|
|
|
|
|
|
|
|
mailObject = [[self clientObject] mailObject];
|
|
|
|
address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
|
|
|
|
emailFrom = [address baseEMail];
|
|
|
|
|
2010-05-05 15:56:19 +02:00
|
|
|
return [event findAttendeeWithEmail: emailFrom];
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) hasSenderStatusChanged
|
|
|
|
{
|
|
|
|
iCalPerson *emailParticipant, *calendarParticipant;
|
|
|
|
|
|
|
|
[self inEvent];
|
|
|
|
[self storedEvent];
|
|
|
|
emailParticipant = [self _emailParticipantWithEvent: inEvent];
|
|
|
|
calendarParticipant = [self _emailParticipantWithEvent: storedEvent];
|
|
|
|
|
|
|
|
return ([[emailParticipant partStat]
|
|
|
|
caseInsensitiveCompare: [calendarParticipant partStat]]
|
|
|
|
!= NSOrderedSame);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-06-02 22:05:38 +02:00
|
|
|
- (BOOL) canOriginalEventBeUpdated
|
|
|
|
{
|
2008-08-28 19:22:36 +02:00
|
|
|
return ([self hasCalendarAccess]
|
|
|
|
&& [self hasSenderStatusChanged]
|
2008-06-02 22:05:38 +02:00
|
|
|
&& ([[inEvent sequence] compare: [storedEvent sequence]]
|
|
|
|
!= NSOrderedAscending));
|
|
|
|
}
|
|
|
|
|
2015-08-04 19:52:31 +02:00
|
|
|
- (id) renderedPart
|
|
|
|
{
|
|
|
|
NSMutableDictionary *d;
|
|
|
|
NSArray *participants;
|
|
|
|
iCalPerson *person;
|
|
|
|
NSMutableArray *a;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
d = [NSMutableDictionary dictionaryWithDictionary: [super renderedPart]];
|
|
|
|
|
|
|
|
// We also add our participants
|
|
|
|
participants = [[self authorativeEvent] participants];
|
|
|
|
a = [NSMutableArray array];
|
|
|
|
|
|
|
|
for (i = 0; i < [participants count]; i++)
|
|
|
|
{
|
|
|
|
person = [participants objectAtIndex: i];
|
|
|
|
|
|
|
|
if (![[person delegatedTo] length])
|
|
|
|
[a addObject: [NSDictionary dictionaryWithObjectsAndKeys: ([person cnWithoutQuotes] ? [person cnWithoutQuotes] : [person rfc822Email]), @"name",
|
|
|
|
[person rfc822Email], @"email",
|
|
|
|
[[person partStatWithDefault] lowercaseString], @"status", nil]];
|
|
|
|
}
|
|
|
|
|
|
|
|
[d setObject: a forKey: @"participants"];
|
|
|
|
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@end /* UIxMailPartICalViewer */
|