(fix) can now invite to exceptions only (fixes #2561)
parent
277342dced
commit
032b2fbbd4
12
NEWS
12
NEWS
|
@ -1,3 +1,15 @@
|
||||||
|
3.3.0 (2017-XX-XX)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
New features
|
||||||
|
- [core] can now invite attendees to exceptions only (#2561)
|
||||||
|
|
||||||
|
Enhancements
|
||||||
|
-
|
||||||
|
|
||||||
|
Bug fixes
|
||||||
|
-
|
||||||
|
|
||||||
3.2.10 (2017-07-05)
|
3.2.10 (2017-07-05)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* NSArray+Appointments.h - this file is part of SOGo
|
/* NSArray+Appointments.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse inc.
|
* Copyright (C) 2006-2017 Inverse inc.
|
||||||
*
|
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* NSArray+Appointments.m - this file is part of SOGo
|
/* NSArray+Appointments.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse inc.
|
* Copyright (C) 2006-2017 Inverse inc.
|
||||||
*
|
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1233,8 +1233,15 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||||
content = [theRecord objectForKey: @"c_cycleinfo"];
|
content = [theRecord objectForKey: @"c_cycleinfo"];
|
||||||
if (![content isNotNull])
|
if (![content isNotNull])
|
||||||
{
|
{
|
||||||
[self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@",
|
// If c_iscycle is set but c_cycleinfo is null, that means we're dealing with a vcalendar that
|
||||||
theRecord];
|
// contains ONLY one or more vevent with recurrence-id set for each of them. This can happen if
|
||||||
|
// an organizer invites an attendee only to one or many occurences of a repetitive event.
|
||||||
|
iCalCalendar *c;
|
||||||
|
|
||||||
|
c = [iCalCalendar parseSingleFromSource: [theRecord objectForKey: @"c_content"]];
|
||||||
|
[theRecords addObjectsFromArray: [self _fixupRecords: [c quickRecordsFromContent: [theRecord objectForKey: @"c_content"]
|
||||||
|
container: nil
|
||||||
|
nameInContainer: [theRecord objectForKey: @"c_name"]]]];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,9 +171,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// This method will *ONLY* add or update event information in attendees' calendars.
|
||||||
|
// It will NOT touch to the organizer calendar in anyway. This method is meant
|
||||||
|
// to reflect changes in attendees' calendars when the organizer makes changes
|
||||||
|
// to the event.
|
||||||
//
|
//
|
||||||
//
|
- (void) _addOrUpdateEvent: (iCalEvent *) newEvent
|
||||||
- (void) _addOrUpdateEvent: (iCalEvent *) theEvent
|
oldEvent: (iCalEvent *) oldEvent
|
||||||
forUID: (NSString *) theUID
|
forUID: (NSString *) theUID
|
||||||
owner: (NSString *) theOwner
|
owner: (NSString *) theOwner
|
||||||
{
|
{
|
||||||
|
@ -183,46 +187,70 @@
|
||||||
iCalCalendar *iCalendarToSave;
|
iCalCalendar *iCalendarToSave;
|
||||||
|
|
||||||
iCalendarToSave = nil;
|
iCalendarToSave = nil;
|
||||||
attendeeObject = [self _lookupEvent: [theEvent uid] forUID: theUID];
|
attendeeObject = [self _lookupEvent: [newEvent uid] forUID: theUID];
|
||||||
|
|
||||||
// We must add an occurence to a non-existing event. We have
|
if ([newEvent recurrenceId])
|
||||||
// to handle this with care, as in the postCalDAVEventRequestTo:from:
|
|
||||||
if ([attendeeObject isNew] && [theEvent recurrenceId])
|
|
||||||
{
|
{
|
||||||
iCalEvent *ownerEvent;
|
// We must add an occurence to a non-existing event.
|
||||||
iCalPerson *person;
|
if ([attendeeObject isNew])
|
||||||
SOGoUser *user;
|
|
||||||
|
|
||||||
// We check if the attendee that was added to a single occurence is
|
|
||||||
// present in the master component. If not, we add it with a participation
|
|
||||||
// status set to "DECLINED".
|
|
||||||
ownerEvent = [[[theEvent parent] events] objectAtIndex: 0];
|
|
||||||
user = [SOGoUser userWithLogin: theUID];
|
|
||||||
if (![ownerEvent userAsAttendee: user])
|
|
||||||
{
|
{
|
||||||
// Update the master event in the owner's calendar with the
|
iCalEvent *ownerEvent;
|
||||||
// status of the new attendee set as "DECLINED".
|
SOGoUser *user;
|
||||||
person = [iCalPerson elementWithTag: @"attendee"];
|
// We check if the attendee that was added to a single occurence is
|
||||||
[person setCn: [user cn]];
|
// present in the master component. If not, we add it with a participation
|
||||||
[person setEmail: [[user allEmails] objectAtIndex: 0]];
|
// status set to "DECLINED".
|
||||||
[person setParticipationStatus: iCalPersonPartStatDeclined];
|
ownerEvent = [[[newEvent parent] events] objectAtIndex: 0];
|
||||||
[person setRsvp: @"TRUE"];
|
user = [SOGoUser userWithLogin: theUID];
|
||||||
[person setRole: @"REQ-PARTICIPANT"];
|
|
||||||
[ownerEvent addToAttendees: person];
|
|
||||||
|
|
||||||
iCalendarToSave = [ownerEvent parent];
|
if (![ownerEvent userAsAttendee: user])
|
||||||
|
{
|
||||||
|
iCalendarToSave = [[[newEvent parent] mutableCopy] autorelease];
|
||||||
|
[iCalendarToSave removeChildren: [iCalendarToSave childrenWithTag: @"vevent"]];
|
||||||
|
[iCalendarToSave addChild: [[newEvent copy] autorelease]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only update this occurrence in attendee's calendar
|
||||||
|
// TODO : when updating the master event, handle exception dates
|
||||||
|
// in attendee's calendar (add exception dates and remove matching
|
||||||
|
// occurrences) -- see _updateRecurrenceIDsWithEvent:
|
||||||
|
NSCalendarDate *currentId;
|
||||||
|
NSArray *occurences;
|
||||||
|
iCalEvent *occurence;
|
||||||
|
int max, count;
|
||||||
|
|
||||||
|
iCalendarToSave = [attendeeObject calendar: NO secure: NO];
|
||||||
|
|
||||||
|
// If recurrenceId is defined, remove the occurence from
|
||||||
|
// the repeating event. If a recurrenceId is defined in the
|
||||||
|
// new event, let's make sure we don't already have one in
|
||||||
|
// the calendar alright. If so, also remove it.
|
||||||
|
if ([oldEvent recurrenceId] || [newEvent recurrenceId])
|
||||||
|
{
|
||||||
|
// FIXME: use _eventFromRecurrenceId:...
|
||||||
|
occurences = [iCalendarToSave events];
|
||||||
|
max = [occurences count];
|
||||||
|
count = 0;
|
||||||
|
while (count < max)
|
||||||
|
{
|
||||||
|
occurence = [occurences objectAtIndex: count];
|
||||||
|
currentId = ([oldEvent recurrenceId] ? [oldEvent recurrenceId]: [newEvent recurrenceId]);
|
||||||
|
if (currentId && [[occurence recurrenceId] compare: currentId] == NSOrderedSame)
|
||||||
|
{
|
||||||
|
[[iCalendarToSave children] removeObject: occurence];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[iCalendarToSave addChild: [[newEvent copy] autorelease]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO : if [theEvent recurrenceId], only update this occurrence
|
iCalendarToSave = [newEvent parent];
|
||||||
// in attendee's calendar
|
|
||||||
|
|
||||||
// TODO : when updating the master event, handle exception dates
|
|
||||||
// in attendee's calendar (add exception dates and remove matching
|
|
||||||
// occurrences) -- see _updateRecurrenceIDsWithEvent:
|
|
||||||
|
|
||||||
iCalendarToSave = [theEvent parent];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the event in the attendee's calendar
|
// Save the event in the attendee's calendar
|
||||||
|
@ -231,8 +259,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
// This method will *ONLY* delete event information in attendees' calendars.
|
||||||
|
// It will NOT touch to the organizer calendar in anyway. This method is meant
|
||||||
|
// to reflect changes in attendees' calendars when the organizer makes changes
|
||||||
|
// to the event.
|
||||||
//
|
//
|
||||||
- (void) _removeEventFromUID: (NSString *) theUID
|
- (void) _removeEventFromUID: (NSString *) theUID
|
||||||
owner: (NSString *) theOwner
|
owner: (NSString *) theOwner
|
||||||
|
@ -251,14 +283,16 @@
|
||||||
|
|
||||||
// Invitations are always written to the personal folder; it's not necessay
|
// Invitations are always written to the personal folder; it's not necessay
|
||||||
// to look into all folders of the user
|
// to look into all folders of the user
|
||||||
|
// FIXME: why look only in the personal calendar here?
|
||||||
folder = [[SOGoUser userWithLogin: theUID]
|
folder = [[SOGoUser userWithLogin: theUID]
|
||||||
personalCalendarFolderInContext: context];
|
personalCalendarFolderInContext: context];
|
||||||
object = [folder lookupName: nameInContainer
|
object = [folder lookupName: nameInContainer
|
||||||
inContext: context acquire: NO];
|
inContext: context
|
||||||
|
acquire: NO];
|
||||||
if (![object isKindOfClass: [NSException class]])
|
if (![object isKindOfClass: [NSException class]])
|
||||||
{
|
{
|
||||||
if (recurrenceId == nil)
|
if (recurrenceId == nil)
|
||||||
[object delete];
|
[object delete];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
calendar = [object calendar: NO secure: NO];
|
calendar = [object calendar: NO secure: NO];
|
||||||
|
@ -267,7 +301,7 @@
|
||||||
// the repeating event.
|
// the repeating event.
|
||||||
occurences = [calendar events];
|
occurences = [calendar events];
|
||||||
max = [occurences count];
|
max = [occurences count];
|
||||||
count = 1;
|
count = 0;
|
||||||
while (count < max)
|
while (count < max)
|
||||||
{
|
{
|
||||||
currentOccurence = [occurences objectAtIndex: count];
|
currentOccurence = [occurences objectAtIndex: count];
|
||||||
|
@ -290,6 +324,8 @@
|
||||||
[object saveCalendar: calendar];
|
[object saveCalendar: calendar];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
[self errorWithFormat: @"Unable to find event with UID %@ in %@'s calendar - skipping delete operation", nameInContainer, theUID];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +346,7 @@
|
||||||
if (currentUID)
|
if (currentUID)
|
||||||
[self _removeEventFromUID: currentUID
|
[self _removeEventFromUID: currentUID
|
||||||
owner: owner
|
owner: owner
|
||||||
withRecurrenceId: recurrenceId];
|
withRecurrenceId: recurrenceId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,6 +472,7 @@
|
||||||
currentUID = [currentAttendee uidInContext: context];
|
currentUID = [currentAttendee uidInContext: context];
|
||||||
if (currentUID)
|
if (currentUID)
|
||||||
[self _addOrUpdateEvent: newEvent
|
[self _addOrUpdateEvent: newEvent
|
||||||
|
oldEvent: oldEvent
|
||||||
forUID: currentUID
|
forUID: currentUID
|
||||||
owner: owner];
|
owner: owner];
|
||||||
}
|
}
|
||||||
|
@ -794,6 +831,7 @@
|
||||||
currentUID = [currentAttendee uidInContext: context];
|
currentUID = [currentAttendee uidInContext: context];
|
||||||
if (currentUID)
|
if (currentUID)
|
||||||
[self _addOrUpdateEvent: newEvent
|
[self _addOrUpdateEvent: newEvent
|
||||||
|
oldEvent: nil
|
||||||
forUID: currentUID
|
forUID: currentUID
|
||||||
owner: owner];
|
owner: owner];
|
||||||
}
|
}
|
||||||
|
@ -826,12 +864,10 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
e = [events objectAtIndex: i];
|
e = [events objectAtIndex: i];
|
||||||
if ([e recurrenceId])
|
if ([e recurrenceId])
|
||||||
for (j = 0; j < [theAttendees count]; j++) {
|
for (j = 0; j < [theAttendees count]; j++) {
|
||||||
if (shouldAdd) {
|
if (shouldAdd)
|
||||||
[e addToAttendees: [theAttendees objectAtIndex: j]];
|
[e addToAttendees: [theAttendees objectAtIndex: j]];
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
[e removeFromAttendees: [theAttendees objectAtIndex: j]];
|
[e removeFromAttendees: [theAttendees objectAtIndex: j]];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -924,6 +960,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
currentUID = [currentAttendee uidInContext: context];
|
currentUID = [currentAttendee uidInContext: context];
|
||||||
if (currentUID)
|
if (currentUID)
|
||||||
[self _addOrUpdateEvent: newEvent
|
[self _addOrUpdateEvent: newEvent
|
||||||
|
oldEvent: oldEvent
|
||||||
forUID: currentUID
|
forUID: currentUID
|
||||||
owner: owner];
|
owner: owner];
|
||||||
}
|
}
|
||||||
|
@ -959,7 +996,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
// | |
|
// | |
|
||||||
// [saveComponent:]---> _handleAddedUsers:fromEvent: <-+ |
|
// [saveComponent:]---> _handleAddedUsers:fromEvent: <-+ |
|
||||||
// | | v
|
// | | v
|
||||||
// +------------> _handleUpdatedEvent:fromOldEvent: ---> _addOrUpdateEvent:forUID:owner: <-----------+
|
// +------------> _handleUpdatedEvent:fromOldEvent: ---> _addOrUpdateEvent:oldEvent:forUID:owner: <-----------+
|
||||||
// | | ^ |
|
// | | ^ |
|
||||||
// v v | |
|
// v v | |
|
||||||
// _handleRemovedUsers:withRecurrenceId: _handleSequenceUpdateInEvent:ignoringAttendees:fromOldEvent: |
|
// _handleRemovedUsers:withRecurrenceId: _handleSequenceUpdateInEvent:ignoringAttendees:fromOldEvent: |
|
||||||
|
@ -1342,6 +1379,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
if (delegatedUID)
|
if (delegatedUID)
|
||||||
// Delegate attendee is a local user; add event to their calendar
|
// Delegate attendee is a local user; add event to their calendar
|
||||||
[self _addOrUpdateEvent: event
|
[self _addOrUpdateEvent: event
|
||||||
|
oldEvent: nil
|
||||||
forUID: delegatedUID
|
forUID: delegatedUID
|
||||||
owner: [theOwnerUser login]];
|
owner: [theOwnerUser login]];
|
||||||
|
|
||||||
|
@ -1637,14 +1675,28 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
// Retrieve this occurence ID.
|
// Retrieve this occurence ID.
|
||||||
recurrenceId = [occurence recurrenceId];
|
recurrenceId = [occurence recurrenceId];
|
||||||
|
|
||||||
if ([event userIsOrganizer: ownerUser])
|
if ([occurence userIsAttendee: ownerUser])
|
||||||
|
{
|
||||||
|
// The current user deletes the occurence; let the organizer know that
|
||||||
|
// the user has declined this occurence.
|
||||||
|
[self changeParticipationStatus: @"DECLINED"
|
||||||
|
withDelegate: nil
|
||||||
|
alarm: nil
|
||||||
|
forRecurrenceId: recurrenceId];
|
||||||
|
send_receipt = NO;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// The organizer deletes an occurence.
|
// The organizer deletes an occurence.
|
||||||
currentUser = [context activeUser];
|
currentUser = [context activeUser];
|
||||||
attendees = [occurence attendeesWithoutUser: currentUser];
|
|
||||||
|
|
||||||
if (![attendees count] && event != occurence)
|
if (recurrenceId)
|
||||||
attendees = [event attendeesWithoutUser: currentUser];
|
attendees = [occurence attendeesWithoutUser: currentUser];
|
||||||
|
else
|
||||||
|
attendees = [[event parent] attendeesWithoutUser: currentUser];
|
||||||
|
|
||||||
|
//if (![attendees count] && event != occurence)
|
||||||
|
//attendees = [event attendeesWithoutUser: currentUser];
|
||||||
|
|
||||||
if ([attendees count])
|
if ([attendees count])
|
||||||
{
|
{
|
||||||
|
@ -1661,16 +1713,6 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||||
withType: @"calendar:cancellation"];
|
withType: @"calendar:cancellation"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ([occurence userIsAttendee: ownerUser])
|
|
||||||
{
|
|
||||||
// The current user deletes the occurence; let the organizer know that
|
|
||||||
// the user has declined this occurence.
|
|
||||||
[self changeParticipationStatus: @"DECLINED"
|
|
||||||
withDelegate: nil
|
|
||||||
alarm: nil
|
|
||||||
forRecurrenceId: recurrenceId];
|
|
||||||
send_receipt = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (send_receipt)
|
if (send_receipt)
|
||||||
[self sendReceiptEmailForObject: event
|
[self sendReceiptEmailForObject: event
|
||||||
|
|
|
@ -804,15 +804,17 @@
|
||||||
/* sender */
|
/* sender */
|
||||||
shortSenderEmail = [[object organizer] rfc822Email];
|
shortSenderEmail = [[object organizer] rfc822Email];
|
||||||
if ([shortSenderEmail length])
|
if ([shortSenderEmail length])
|
||||||
{
|
senderEmail = [[object organizer] mailAddress];
|
||||||
senderEmail = [[object organizer] mailAddress];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shortSenderEmail = [[previousObject organizer] rfc822Email];
|
shortSenderEmail = [[previousObject organizer] rfc822Email];
|
||||||
senderEmail = [[previousObject organizer] mailAddress];
|
senderEmail = [[previousObject organizer] mailAddress];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No organizer, grab the event's owner
|
||||||
|
if (![senderEmail length])
|
||||||
|
senderEmail = shortSenderEmail = [[ownerUser defaultIdentity] objectForKey: @"email"];
|
||||||
|
|
||||||
/* calendar part */
|
/* calendar part */
|
||||||
eventBodyPart = [self _bodyPartForICalObject: object];
|
eventBodyPart = [self _bodyPartForICalObject: object];
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* iCalCalendar+SOGo.h - this file is part of SOGo
|
/* iCalCalendar+SOGo.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Inverse inc
|
* Copyright (C) 2012-2017 Inverse inc
|
||||||
*
|
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* iCalCalendar+SOGo.m - this file is part of SOGo
|
/* iCalCalendar+SOGo.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-2014 Inverse inc
|
* Copyright (C) 2012-2017 Inverse inc
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,12 +20,16 @@
|
||||||
|
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalEvent.h>
|
||||||
#import <NGCards/iCalRepeatableEntityObject.h>
|
#import <NGCards/iCalRepeatableEntityObject.h>
|
||||||
|
|
||||||
#import "iCalCalendar+SOGo.h"
|
#import "iCalCalendar+SOGo.h"
|
||||||
#import "iCalEntityObject+SOGo.h"
|
#import "iCalEntityObject+SOGo.h"
|
||||||
|
#import "NSArray+Appointments.h"
|
||||||
|
|
||||||
@implementation iCalCalendar (SOGoExtensions)
|
@implementation iCalCalendar (SOGoExtensions)
|
||||||
|
|
||||||
|
@ -45,9 +49,10 @@
|
||||||
/* master occurrence */
|
/* master occurrence */
|
||||||
component = [components objectAtIndex: 0];
|
component = [components objectAtIndex: 0];
|
||||||
|
|
||||||
if ([component hasRecurrenceRules])
|
if ([component hasRecurrenceRules] || [component recurrenceId])
|
||||||
{
|
{
|
||||||
count = 1; // skip master event
|
// Skip the master event if required
|
||||||
|
count = ([component recurrenceId] ? 0 : 1);
|
||||||
while (!occurrence && count < max)
|
while (!occurrence && count < max)
|
||||||
{
|
{
|
||||||
component = [components objectAtIndex: count];
|
component = [components objectAtIndex: count];
|
||||||
|
@ -101,4 +106,63 @@
|
||||||
return [(id)element quickRecordFromContent: theContent container: theContainer nameInContainer: nameInContainer];
|
return [(id)element quickRecordFromContent: theContent container: theContainer nameInContainer: nameInContainer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray *) quickRecordsFromContent: (NSString *) theContent
|
||||||
|
container: (id) theContainer
|
||||||
|
nameInContainer: (NSString *) nameInContainer
|
||||||
|
{
|
||||||
|
NSCalendarDate *recurrenceId;
|
||||||
|
NSMutableDictionary *record;
|
||||||
|
NSMutableArray *allRecords;
|
||||||
|
NSNumber *dateSecs;
|
||||||
|
NSArray *elements;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
allRecords = [NSMutableArray array];
|
||||||
|
|
||||||
|
// FIXME: what about tasks?
|
||||||
|
elements = [self events];
|
||||||
|
|
||||||
|
for (i = 0; i < [elements count]; i++)
|
||||||
|
{
|
||||||
|
record = [(id)[elements objectAtIndex: i] quickRecordFromContent: theContent container: theContainer nameInContainer: nameInContainer];
|
||||||
|
recurrenceId = [[elements objectAtIndex: i] recurrenceId];
|
||||||
|
dateSecs = [NSNumber numberWithDouble: [recurrenceId timeIntervalSince1970]];
|
||||||
|
|
||||||
|
[record setObject: nameInContainer forKey: @"c_name"];
|
||||||
|
[record setObject: dateSecs forKey: @"c_recurrence_id"];
|
||||||
|
|
||||||
|
[allRecords addObject: record];
|
||||||
|
}
|
||||||
|
|
||||||
|
return allRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) attendeesWithoutUser: (SOGoUser *) user
|
||||||
|
{
|
||||||
|
NSMutableArray *allAttendees;
|
||||||
|
NSArray *events, *attendees;
|
||||||
|
iCalPerson *attendee;
|
||||||
|
iCalEvent *event;
|
||||||
|
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
allAttendees = [NSMutableArray array];
|
||||||
|
events = [self events];
|
||||||
|
|
||||||
|
for (i = 0; i < [events count]; i++)
|
||||||
|
{
|
||||||
|
event = [events objectAtIndex: i];
|
||||||
|
attendees = [event attendees];
|
||||||
|
for (j = 0; j < [attendees count]; j++)
|
||||||
|
{
|
||||||
|
attendee = [attendees objectAtIndex: j];
|
||||||
|
[allAttendees removePerson: attendee];
|
||||||
|
[allAttendees addObject: attendee];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allAttendees;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
boolTmp = ((isAllDay) ? 1 : 0);
|
boolTmp = ((isAllDay) ? 1 : 0);
|
||||||
[row setObject: [NSNumber numberWithInt: boolTmp]
|
[row setObject: [NSNumber numberWithInt: boolTmp]
|
||||||
forKey: @"c_isallday"];
|
forKey: @"c_isallday"];
|
||||||
boolTmp = (([self isRecurrent]) ? 1 : 0);
|
boolTmp = ((([self isRecurrent] || [self recurrenceId])) ? 1 : 0);
|
||||||
[row setObject: [NSNumber numberWithInt: boolTmp]
|
[row setObject: [NSNumber numberWithInt: boolTmp]
|
||||||
forKey: @"c_iscycle"];
|
forKey: @"c_iscycle"];
|
||||||
boolTmp = (([self isOpaque]) ? 1 : 0);
|
boolTmp = (([self isOpaque]) ? 1 : 0);
|
||||||
|
|
|
@ -265,8 +265,8 @@ static NSArray *tasksFields = nil;
|
||||||
NSString *aDateField;
|
NSString *aDateField;
|
||||||
int daylightOffset;
|
int daylightOffset;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
static NSString *fields[] = { @"startDate", @"c_startdate",
|
|
||||||
@"endDate", @"c_enddate" };
|
static NSString *fields[] = { @"startDate", @"c_startdate", @"endDate", @"c_enddate" };
|
||||||
|
|
||||||
/* WARNING: This condition has been put and removed many times, please leave
|
/* WARNING: This condition has been put and removed many times, please leave
|
||||||
it. Here is the story...
|
it. Here is the story...
|
||||||
|
|
Loading…
Reference in New Issue