See Changelog.
Monotone-Parent: 8f58a8aa696d8fbbb82f1cd571800676a04b96af Monotone-Revision: b593ce96638476fad98d678453ca6af6112169fb Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2011-01-14T02:54:33 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
b6bc06b163
commit
64081b8fa7
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
2011-01-13 Francis Lachapelle <flachapelle@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m
|
||||||
|
(-doesOccurOnDate:): the date to verify must be adjusted to the
|
||||||
|
event's timezone before performing the calculation of the
|
||||||
|
recurrence rule.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/iCalEvent+SOGo.m (-firstOccurenceRange):
|
||||||
|
extract the original start and end dates from the event, based on
|
||||||
|
the event's timezone.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||||
|
(-fixupCycleRecord:cycleRange:firstInstanceCalendarDateRange:withEventTimeZone:):
|
||||||
|
the event dates must be first be adjusted to the event's timezone
|
||||||
|
before being adjusted to the user's timezone.
|
||||||
|
(-_flattenCycleRecord:forRange:intoArray:): the calculation of the
|
||||||
|
occurrences must be performed with respect to the event's
|
||||||
|
timezone, not the user's timezone.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/SOGoAppointmentObject.m
|
||||||
|
(-newOccurenceWithID:): new occurrences are now independant of the
|
||||||
|
user's timezone.
|
||||||
|
|
||||||
2011-01-11 Ludovic Marcotte <lmarcotte@inverse.ca>
|
2011-01-11 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
|
|
||||||
* OpenChange/MAPIStoreContactsMessageTable.m
|
* OpenChange/MAPIStoreContactsMessageTable.m
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
2011-01-13 Francis Lachapelle <flachapelle@inverse.ca>
|
||||||
|
|
||||||
|
* iCalTimeZone.m (-computedDateForDate:): Was
|
||||||
|
_computedDateTimeForDate. Adjusts a date with respect to this
|
||||||
|
vTimeZone.
|
||||||
|
|
||||||
|
* iCalDateTime.m (-dateTimes): when there's no timezone defined
|
||||||
|
(which is the case when parsing a vTimeZone!), don't fallback to
|
||||||
|
the system timezone.
|
||||||
|
|
||||||
2010-11-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2010-11-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* NGVCard.m (-setVName, vName): removed useless and non-standard
|
* NGVCard.m (-setVName, vName): removed useless and non-standard
|
||||||
|
|
|
@ -161,6 +161,7 @@
|
||||||
currentEndDate = [currentStartDate addTimeInterval: [firstRange duration]];
|
currentEndDate = [currentStartDate addTimeInterval: [firstRange duration]];
|
||||||
r = [NGCalendarDateRange calendarDateRangeWithStartDate: currentStartDate
|
r = [NGCalendarDateRange calendarDateRangeWithStartDate: currentStartDate
|
||||||
endDate: currentEndDate];
|
endDate: currentEndDate];
|
||||||
|
|
||||||
if ([_r containsDateRange: r])
|
if ([_r containsDateRange: r])
|
||||||
[ranges addObject: r];
|
[ranges addObject: r];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* iCalDateTime.m - this file is part of SOPE
|
/* iCalDateTime.m - this file is part of SOPE
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse inc.
|
* Copyright (C) 2006-2011 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
*
|
*
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
NSString *date;
|
NSString *date;
|
||||||
NSCalendarDate *initialDate, *dateTime;
|
NSCalendarDate *initialDate, *dateTime;
|
||||||
NSMutableArray *dates;
|
NSMutableArray *dates;
|
||||||
NSTimeZone *tz;
|
//NSTimeZone *tz;
|
||||||
unsigned count, i;
|
unsigned count, i;
|
||||||
|
|
||||||
count = [[self values] count];
|
count = [[self values] count];
|
||||||
|
@ -170,24 +170,28 @@
|
||||||
{
|
{
|
||||||
date = [self value: i];
|
date = [self value: i];
|
||||||
iTZ = [self timeZone];
|
iTZ = [self timeZone];
|
||||||
|
|
||||||
if (iTZ)
|
if (iTZ)
|
||||||
dateTime = [iTZ dateForDateTimeString: date];
|
dateTime = [iTZ dateForDateTimeString: date];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
initialDate = [date asCalendarDate];
|
initialDate = [date asCalendarDate];
|
||||||
if (initialDate)
|
if (initialDate)
|
||||||
|
dateTime = initialDate;
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
if ([date hasSuffix: @"Z"] || [date hasSuffix: @"z"])
|
if ([date hasSuffix: @"Z"] || [date hasSuffix: @"z"])
|
||||||
dateTime = initialDate;
|
dateTime = initialDate;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* same TODO as above */
|
// same TODO as above
|
||||||
tz = [NSTimeZone defaultTimeZone];
|
tz = [NSTimeZone defaultTimeZone];
|
||||||
dateTime = [initialDate addYear: 0 month: 0 day: 0
|
dateTime = [initialDate addYear: 0 month: 0 day: 0
|
||||||
hour: 0 minute: 0
|
hour: 0 minute: 0
|
||||||
second: -[tz secondsFromGMTForDate: initialDate]];
|
second: -[tz secondsFromGMTForDate: initialDate]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
else
|
else
|
||||||
dateTime = nil;
|
dateTime = nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* iCalTimeZone.h - this file is part of SOPE
|
/* iCalTimeZone.h - this file is part of SOPE
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2009 Inverse inc.
|
* Copyright (C) 2006-2011 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
*
|
*
|
||||||
|
@ -28,10 +28,14 @@
|
||||||
|
|
||||||
#import "CardGroup.h"
|
#import "CardGroup.h"
|
||||||
|
|
||||||
|
@class iCalTimeZonePeriod;
|
||||||
|
|
||||||
@interface iCalTimeZone : CardGroup
|
@interface iCalTimeZone : CardGroup
|
||||||
|
|
||||||
+ (iCalTimeZone *) timeZoneForName: (NSString *) theName;
|
+ (iCalTimeZone *) timeZoneForName: (NSString *) theName;
|
||||||
- (NSString *) tzId;
|
- (NSString *) tzId;
|
||||||
|
- (iCalTimeZonePeriod *) periodForDate: (NSCalendarDate *) date;
|
||||||
|
- (NSCalendarDate *) computedDateForDate: (NSCalendarDate *) theDate;
|
||||||
- (NSString *) dateTimeStringForDate: (NSCalendarDate *) date;
|
- (NSString *) dateTimeStringForDate: (NSCalendarDate *) date;
|
||||||
- (NSString *) dateStringForDate: (NSCalendarDate *) date;
|
- (NSString *) dateStringForDate: (NSCalendarDate *) date;
|
||||||
- (NSCalendarDate *) dateForDateTimeString: (NSString *) string;
|
- (NSCalendarDate *) dateForDateTimeString: (NSString *) string;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
/* iCalTimeZone.m - this file is part of SOPE
|
/* iCalTimeZone.m - this file is part of SOPE
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2009 Inverse inc.
|
* Copyright (C) 2006-2011 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
* Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||||
|
* Francis Lachapelle <flachapelle@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
|
||||||
|
@ -185,35 +186,38 @@ static NSMutableDictionary *cache;
|
||||||
period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"daylight"];
|
period = (iCalTimeZonePeriod *) [self uniqueChildWithTag: @"daylight"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// NSLog (@"chosen period: '%@'", [period tag]);
|
|
||||||
|
|
||||||
return period;
|
return period;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSCalendarDate *) _computedDateTimeForDate: (NSCalendarDate *) date
|
/**
|
||||||
|
* Adjust a date with respect to this vTimeZone.
|
||||||
|
* @param theDate the date to adjust to the timezone.
|
||||||
|
* @return a new GMT date adjusted with the offset of the timezone.
|
||||||
|
*/
|
||||||
|
- (NSCalendarDate *) computedDateForDate: (NSCalendarDate *) theDate
|
||||||
{
|
{
|
||||||
NSCalendarDate *tmpDate;
|
NSCalendarDate *tmpDate;
|
||||||
NSTimeZone *utc;
|
NSTimeZone *utc;
|
||||||
|
|
||||||
utc = [NSTimeZone timeZoneWithName: @"GMT"];
|
utc = [NSTimeZone timeZoneWithName: @"GMT"];
|
||||||
tmpDate = [date copy];
|
tmpDate = [theDate copy];
|
||||||
[tmpDate autorelease];
|
[tmpDate autorelease];
|
||||||
[tmpDate setTimeZone: utc];
|
[tmpDate setTimeZone: utc];
|
||||||
|
|
||||||
return [tmpDate addYear: 0 month: 0 day: 0
|
return [tmpDate addYear: 0 month: 0 day: 0
|
||||||
hour: 0 minute: 0
|
hour: 0 minute: 0
|
||||||
second: [[self periodForDate: date] secondsOffsetFromGMT]];
|
second: [[self periodForDate: theDate] secondsOffsetFromGMT]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) dateTimeStringForDate: (NSCalendarDate *) date
|
- (NSString *) dateTimeStringForDate: (NSCalendarDate *) date
|
||||||
{
|
{
|
||||||
return [[self _computedDateTimeForDate: date]
|
return [[self computedDateForDate: date]
|
||||||
iCalFormattedDateTimeString];
|
iCalFormattedDateTimeString];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) dateStringForDate: (NSCalendarDate *) date
|
- (NSString *) dateStringForDate: (NSCalendarDate *) date
|
||||||
{
|
{
|
||||||
return [[self _computedDateTimeForDate: date]
|
return [[self computedDateForDate: date]
|
||||||
iCalFormattedDateString];
|
iCalFormattedDateString];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
tzStart = [self startDate];
|
tzStart = [self startDate];
|
||||||
|
|
||||||
[tzStart setTimeZone: [NSTimeZone timeZoneWithName: @"GMT"]];
|
[tzStart setTimeZone: [NSTimeZone timeZoneWithName: @"GMT"]];
|
||||||
tmpDate = [NSCalendarDate dateWithYear: [refDate yearOfCommonEra]
|
tmpDate = [NSCalendarDate dateWithYear: [refDate yearOfCommonEra]
|
||||||
month: [[rrule namedValue: @"bymonth"] intValue]
|
month: [[rrule namedValue: @"bymonth"] intValue]
|
||||||
|
|
|
@ -186,6 +186,7 @@
|
||||||
currentEndDate = [currentStartDate addTimeInterval: [firstRange duration]];
|
currentEndDate = [currentStartDate addTimeInterval: [firstRange duration]];
|
||||||
r = [NGCalendarDateRange calendarDateRangeWithStartDate: currentStartDate
|
r = [NGCalendarDateRange calendarDateRangeWithStartDate: currentStartDate
|
||||||
endDate: currentEndDate];
|
endDate: currentEndDate];
|
||||||
|
|
||||||
if ([_r containsDateRange: r])
|
if ([_r containsDateRange: r])
|
||||||
[ranges addObject: r];
|
[ranges addObject: r];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2007-2009 Inverse inc.
|
Copyright (C) 2007-2011 Inverse inc.
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
This file is part of OpenGroupware.org.
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
#import <NGCards/iCalPerson.h>
|
#import <NGCards/iCalPerson.h>
|
||||||
#import <NGCards/iCalRecurrenceCalculator.h>
|
#import <NGCards/iCalRecurrenceCalculator.h>
|
||||||
#import <NGCards/iCalTimeZone.h>
|
#import <NGCards/iCalTimeZone.h>
|
||||||
|
#import <NGCards/iCalTimeZonePeriod.h>
|
||||||
#import <NGCards/NSString+NGCards.h>
|
#import <NGCards/NSString+NGCards.h>
|
||||||
#import <NGExtensions/NGCalendarDateRange.h>
|
#import <NGExtensions/NGCalendarDateRange.h>
|
||||||
#import <NGExtensions/NSNull+misc.h>
|
#import <NGExtensions/NSNull+misc.h>
|
||||||
|
@ -576,33 +577,38 @@ static NSNumber *sharedYes = nil;
|
||||||
forKey: [currentRecord objectForKey: @"c_name"]];
|
forKey: [currentRecord objectForKey: @"c_name"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableDictionary *) fixupRecord: (NSDictionary *) _record
|
/**
|
||||||
|
* Set the timezone of the event start and end dates to the user's timezone.
|
||||||
|
* @param theRecord an dictionnary with the attributes of the event.
|
||||||
|
* @return a copy of theRecord with adjusted dates.
|
||||||
|
*/
|
||||||
|
- (NSMutableDictionary *) fixupRecord: (NSDictionary *) theRecord
|
||||||
{
|
{
|
||||||
NSMutableDictionary *md;
|
NSMutableDictionary *record;
|
||||||
static NSString *fields[] = { @"c_startdate", @"startDate",
|
static NSString *fields[] = { @"c_startdate", @"startDate",
|
||||||
@"c_enddate", @"endDate" };
|
@"c_enddate", @"endDate" };
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
NSCalendarDate *date;
|
NSCalendarDate *date;
|
||||||
NSNumber *dateValue;
|
NSNumber *dateValue;
|
||||||
|
|
||||||
md = [[_record mutableCopy] autorelease];
|
record = [[theRecord mutableCopy] autorelease];
|
||||||
for (count = 0; count < 2; count++)
|
for (count = 0; count < 2; count++)
|
||||||
{
|
{
|
||||||
dateValue = [_record objectForKey: fields[count * 2]];
|
dateValue = [theRecord objectForKey: fields[count * 2]];
|
||||||
if (dateValue)
|
if (dateValue)
|
||||||
{
|
{
|
||||||
date = [NSCalendarDate dateWithTimeIntervalSince1970: [dateValue unsignedIntValue]];
|
date = [NSCalendarDate dateWithTimeIntervalSince1970: [dateValue unsignedIntValue]];
|
||||||
if (date)
|
if (date)
|
||||||
{
|
{
|
||||||
[date setTimeZone: timeZone];
|
[date setTimeZone: timeZone];
|
||||||
[md setObject: date forKey: fields[count * 2 + 1]];
|
[record setObject: date forKey: fields[count * 2 + 1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
[self logWithFormat: @"missing '%@' in record?", fields[count * 2]];
|
[self logWithFormat: @"missing '%@' in record?", fields[count * 2]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return md;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) fixupRecords: (NSArray *) theRecords
|
- (NSArray *) fixupRecords: (NSArray *) theRecords
|
||||||
|
@ -629,42 +635,52 @@ static NSNumber *sharedYes = nil;
|
||||||
return ma;
|
return ma;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableDictionary *) fixupCycleRecord: (NSDictionary *) _record
|
/**
|
||||||
cycleRange: (NGCalendarDateRange *) _r
|
* Adjust the timezone of the start and end dates to the user's timezone.
|
||||||
firstInstanceCalendarDateRange: (NGCalendarDateRange *) _fir
|
* The event is recurrent and the dates must first be adjusted with respect to
|
||||||
forViewRange: (NGCalendarDateRange *) _viewRange
|
* the event's timezone.
|
||||||
|
* @param theRecord
|
||||||
|
* @param theCycle
|
||||||
|
* @param theFirstCycle
|
||||||
|
* @param theEventTimeZone
|
||||||
|
* @see fixupRecord:
|
||||||
|
* @return a copy of theRecord with adjusted dates.
|
||||||
|
*/
|
||||||
|
- (NSMutableDictionary *) fixupCycleRecord: (NSDictionary *) theRecord
|
||||||
|
cycleRange: (NGCalendarDateRange *) theCycle
|
||||||
|
firstInstanceCalendarDateRange: (NGCalendarDateRange *) theFirstCycle
|
||||||
|
withEventTimeZone: (iCalTimeZone *) theEventTimeZone
|
||||||
{
|
{
|
||||||
NSMutableDictionary *md;
|
NSMutableDictionary *record;
|
||||||
NSNumber *dateSecs;
|
NSNumber *dateSecs;
|
||||||
id tmp;
|
id date;
|
||||||
|
int secondsOffsetFromGMT;
|
||||||
|
|
||||||
md = [[_record mutableCopy] autorelease];
|
record = [[theRecord mutableCopy] autorelease];
|
||||||
|
|
||||||
/* cycle is in _r. We also have to override the c_startdate/c_enddate with the date values of
|
date = [theCycle startDate];
|
||||||
the reccurence since we use those when displaying events in SOGo Web */
|
secondsOffsetFromGMT = (int) [[theEventTimeZone periodForDate: date] secondsOffsetFromGMT];
|
||||||
|
date = [date dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -secondsOffsetFromGMT];
|
||||||
|
[date setTimeZone: timeZone];
|
||||||
|
[record setObject: date forKey: @"startDate"];
|
||||||
|
dateSecs = [NSNumber numberWithInt: [date timeIntervalSince1970]];
|
||||||
|
[record setObject: dateSecs forKey: @"c_startdate"];
|
||||||
|
[record setObject: dateSecs forKey: @"c_recurrence_id"];
|
||||||
|
|
||||||
tmp = [_r startDate];
|
date = [theCycle endDate];
|
||||||
[tmp setTimeZone: timeZone];
|
secondsOffsetFromGMT = (int) [[theEventTimeZone periodForDate: date] secondsOffsetFromGMT];
|
||||||
[md setObject: tmp forKey: @"startDate"];
|
date = [date dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -secondsOffsetFromGMT];
|
||||||
dateSecs = [NSNumber numberWithInt: [tmp timeIntervalSince1970]];
|
[date setTimeZone: timeZone];
|
||||||
[md setObject: dateSecs forKey: @"c_startdate"];
|
[record setObject: date forKey: @"endDate"];
|
||||||
|
dateSecs = [NSNumber numberWithInt: [date timeIntervalSince1970]];
|
||||||
tmp = [_r endDate];
|
[record setObject: dateSecs forKey: @"c_enddate"];
|
||||||
[tmp setTimeZone: timeZone];
|
|
||||||
[md setObject: tmp forKey: @"endDate"];
|
|
||||||
dateSecs = [NSNumber numberWithInt: [tmp timeIntervalSince1970]];
|
|
||||||
[md setObject: dateSecs forKey: @"c_enddate"];
|
|
||||||
|
|
||||||
tmp = [_r startDate];
|
|
||||||
dateSecs = [NSNumber numberWithInt: [tmp timeIntervalSince1970]];
|
|
||||||
[md setObject: dateSecs forKey: @"c_recurrence_id"];
|
|
||||||
|
|
||||||
// The first instance date is added to the dictionary so it can
|
// The first instance date is added to the dictionary so it can
|
||||||
// be used by UIxCalListingActions to compute the DST offset.
|
// be used by UIxCalListingActions to compute the DST offset.
|
||||||
tmp = [_fir startDate];
|
date = [theFirstCycle startDate];
|
||||||
[md setObject: tmp forKey: @"cycleStartDate"];
|
[record setObject: date forKey: @"cycleStartDate"];
|
||||||
|
|
||||||
return md;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) _indexOfRecordMatchingDate: (NSCalendarDate *) matchDate
|
- (int) _indexOfRecordMatchingDate: (NSCalendarDate *) matchDate
|
||||||
|
@ -805,26 +821,39 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _flattenCycleRecord: (NSDictionary *) _row
|
/**
|
||||||
forRange: (NGCalendarDateRange *) _r
|
* Calculate and return the occurrences of the recurrent event for the given
|
||||||
intoArray: (NSMutableArray *) _ma
|
* period.
|
||||||
|
* @param theRecord the event definition.
|
||||||
|
* @param theRange the period to look in.
|
||||||
|
* @param theRecords the array into which are copied the resulting occurrences.
|
||||||
|
*/
|
||||||
|
- (void) _flattenCycleRecord: (NSDictionary *) theRecord
|
||||||
|
forRange: (NGCalendarDateRange *) theRange
|
||||||
|
intoArray: (NSMutableArray *) theRecords
|
||||||
{
|
{
|
||||||
NSMutableDictionary *row, *fixedRow;
|
NSMutableDictionary *row, *fixedRow;
|
||||||
NSMutableArray *recordArray;
|
NSMutableArray *records;
|
||||||
NSDictionary *cycleinfo;
|
NSDictionary *cycleinfo;
|
||||||
NSCalendarDate *startDate, *endDate;
|
NSCalendarDate *startDate, *endDate;
|
||||||
NGCalendarDateRange *fir, *rRange;
|
NGCalendarDateRange *firstRange, *oneRange;
|
||||||
NSArray *rules, *exRules, *exDates, *ranges;
|
NSArray *rules, *exRules, *exDates, *ranges;
|
||||||
unsigned i, count;
|
NSArray *elements, *components;
|
||||||
NSString *content;
|
NSString *content;
|
||||||
|
iCalRepeatableEntityObject *component;
|
||||||
|
iCalDateTime *firstStartDate, *firstEndDate;
|
||||||
|
NSCalendarDate *checkStartDate, *checkEndDate;
|
||||||
|
iCalTimeZone *eventTimeZone;
|
||||||
|
unsigned i, count;
|
||||||
|
|
||||||
recordArray = [NSMutableArray array];
|
records = [NSMutableArray array];
|
||||||
|
ranges = nil;
|
||||||
|
|
||||||
content = [_row objectForKey: @"c_cycleinfo"];
|
content = [theRecord objectForKey: @"c_cycleinfo"];
|
||||||
if (![content isNotNull])
|
if (![content isNotNull])
|
||||||
{
|
{
|
||||||
[self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@",
|
[self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@",
|
||||||
_row];
|
theRecord];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,45 +861,72 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||||
if (!cycleinfo)
|
if (!cycleinfo)
|
||||||
{
|
{
|
||||||
[self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@",
|
[self errorWithFormat:@"cyclic record doesn't have cycleinfo -> %@",
|
||||||
_row];
|
theRecord];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = [self fixupRecord: _row];
|
row = [self fixupRecord: theRecord];
|
||||||
[row removeObjectForKey: @"c_cycleinfo"];
|
[row removeObjectForKey: @"c_cycleinfo"];
|
||||||
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
||||||
|
|
||||||
startDate = [row objectForKey: @"startDate"];
|
startDate = [row objectForKey: @"startDate"];
|
||||||
endDate = [row objectForKey: @"endDate"];
|
endDate = [row objectForKey: @"endDate"];
|
||||||
fir = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate
|
|
||||||
endDate: endDate];
|
content = [theRecord objectForKey: @"c_content"];
|
||||||
|
if ([content length])
|
||||||
|
{
|
||||||
|
elements = [iCalCalendar parseFromSource: content];
|
||||||
|
if ([elements count])
|
||||||
|
{
|
||||||
|
components = [[elements objectAtIndex: 0] events];
|
||||||
|
if ([components count])
|
||||||
|
{
|
||||||
|
// Retrieve the range of the first event
|
||||||
|
component = [components objectAtIndex: 0];
|
||||||
|
firstStartDate = (iCalDateTime*)[component uniqueChildWithTag: @"dtstart"];
|
||||||
|
firstEndDate = (iCalDateTime*)[component uniqueChildWithTag: @"dtend"];
|
||||||
|
eventTimeZone = [firstStartDate timeZone];
|
||||||
|
startDate = [eventTimeZone computedDateForDate: startDate];
|
||||||
|
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: [[[firstStartDate values] lastObject] asCalendarDate]
|
||||||
|
endDate: [[[firstEndDate values] lastObject] asCalendarDate]];
|
||||||
|
|
||||||
|
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||||
|
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||||
|
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||||
|
theRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||||
|
endDate: checkEndDate];
|
||||||
|
|
||||||
|
// Calculate the occurrences for the given range
|
||||||
rules = [cycleinfo objectForKey: @"rules"];
|
rules = [cycleinfo objectForKey: @"rules"];
|
||||||
exRules = [cycleinfo objectForKey: @"exRules"];
|
exRules = [cycleinfo objectForKey: @"exRules"];
|
||||||
exDates = [cycleinfo objectForKey: @"exDates"];
|
exDates = [cycleinfo objectForKey: @"exDates"];
|
||||||
|
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: theRange
|
||||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: _r
|
firstInstanceCalendarDateRange: firstRange
|
||||||
firstInstanceCalendarDateRange: fir
|
|
||||||
recurrenceRules: rules
|
recurrenceRules: rules
|
||||||
exceptionRules: exRules
|
exceptionRules: exRules
|
||||||
exceptionDates: exDates];
|
exceptionDates: exDates];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count = [ranges count];
|
count = [ranges count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
rRange = [ranges objectAtIndex: i];
|
oneRange = [ranges objectAtIndex: i];
|
||||||
fixedRow = [self fixupCycleRecord: row
|
fixedRow = [self fixupCycleRecord: row
|
||||||
cycleRange: rRange
|
cycleRange: oneRange
|
||||||
firstInstanceCalendarDateRange: fir
|
firstInstanceCalendarDateRange: firstRange
|
||||||
forViewRange: _r];
|
withEventTimeZone: eventTimeZone];
|
||||||
if (fixedRow)
|
if (fixedRow)
|
||||||
[recordArray addObject: fixedRow];
|
[records addObject: fixedRow];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self _appendCycleExceptionsFromRow: row
|
[self _appendCycleExceptionsFromRow: row
|
||||||
firstInstanceCalendarDateRange: fir
|
firstInstanceCalendarDateRange: firstRange
|
||||||
forRange: _r
|
forRange: theRange
|
||||||
toArray: recordArray];
|
toArray: records];
|
||||||
|
|
||||||
[_ma addObjectsFromArray: recordArray];
|
[theRecords addObjectsFromArray: records];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) _flattenCycleRecords: (NSArray *) _records
|
- (NSArray *) _flattenCycleRecords: (NSArray *) _records
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
|
Copyright (C) 2007-2011 Inverse inc.
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
Copyright (C) 2007-2009 Inverse inc.
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
This file is part of OpenGroupware.org.
|
||||||
|
|
||||||
|
@ -80,33 +80,28 @@
|
||||||
inContainer: self];
|
inContainer: self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (iCalRepeatableEntityObject *) newOccurenceWithID: (NSString *) recID
|
/**
|
||||||
|
* Return a new exception in a the recurrent event.
|
||||||
|
* @param theRecurrenceID the ID of the occurence.
|
||||||
|
* @return a new occurence.
|
||||||
|
*/
|
||||||
|
- (iCalRepeatableEntityObject *) newOccurenceWithID: (NSString *) theRecurrenceID
|
||||||
{
|
{
|
||||||
iCalEvent *newOccurence, *master;
|
iCalEvent *newOccurence, *master;
|
||||||
NSCalendarDate *date, *firstDate;
|
NSCalendarDate *date, *firstDate;
|
||||||
unsigned int interval, nbrDays;
|
unsigned int interval, nbrDays;
|
||||||
SOGoUserDefaults *ud;
|
SOGoUserDefaults *ud;
|
||||||
NSTimeZone *timeZone;
|
NSTimeZone *timeZone;
|
||||||
int daylightOffset;
|
|
||||||
|
|
||||||
ud = [[SOGoUser userWithLogin: owner] userDefaults];
|
ud = [[SOGoUser userWithLogin: owner] userDefaults];
|
||||||
timeZone = [ud timeZone];
|
timeZone = [ud timeZone];
|
||||||
|
|
||||||
newOccurence = (iCalEvent *) [super newOccurenceWithID: recID];
|
newOccurence = (iCalEvent *) [super newOccurenceWithID: theRecurrenceID];
|
||||||
date = [newOccurence recurrenceId];
|
date = [newOccurence recurrenceId];
|
||||||
|
|
||||||
master = [self component: NO secure: NO];
|
master = [self component: NO secure: NO];
|
||||||
firstDate = [master startDate];
|
firstDate = [master startDate];
|
||||||
|
|
||||||
// We are creating a new exception in a recurrent event -- compute the daylight
|
|
||||||
// saving time with respect to the first occurrence of the recurrent event.
|
|
||||||
daylightOffset = (int) ([timeZone secondsFromGMTForDate: firstDate]
|
|
||||||
- [timeZone secondsFromGMTForDate: date]);
|
|
||||||
if (daylightOffset)
|
|
||||||
date = [date dateByAddingYears: 0 months: 0 days: 0
|
|
||||||
hours:0 minutes: 0 seconds: daylightOffset];
|
|
||||||
[date setTimeZone: timeZone];
|
|
||||||
|
|
||||||
interval = [[master endDate]
|
interval = [[master endDate]
|
||||||
timeIntervalSinceDate: firstDate];
|
timeIntervalSinceDate: firstDate];
|
||||||
if ([newOccurence isAllDay])
|
if ([newOccurence isAllDay])
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
/* iCalEvent+SOGo.m - this file is part of SOGo
|
/* iCalEvent+SOGo.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Inverse inc.
|
* Copyright (C) 2007-2011 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
* Francis Lachapelle <flachapelle@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
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
|
||||||
#import <NGCards/iCalAlarm.h>
|
#import <NGCards/iCalAlarm.h>
|
||||||
|
#import <NGCards/iCalDateTime.h>
|
||||||
#import <NGCards/iCalEvent.h>
|
#import <NGCards/iCalEvent.h>
|
||||||
#import <NGCards/iCalPerson.h>
|
#import <NGCards/iCalPerson.h>
|
||||||
#import <NGCards/iCalTrigger.h>
|
#import <NGCards/iCalTrigger.h>
|
||||||
|
@ -240,10 +242,22 @@
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the start and end dates from the event, from which all recurrence
|
||||||
|
* calculations will be based on.
|
||||||
|
* @return the range of the first occurrence.
|
||||||
|
*/
|
||||||
- (NGCalendarDateRange *) firstOccurenceRange
|
- (NGCalendarDateRange *) firstOccurenceRange
|
||||||
{
|
{
|
||||||
return [NGCalendarDateRange calendarDateRangeWithStartDate: [self startDate]
|
iCalDateTime *firstStartDate, *firstEndDate;
|
||||||
endDate: [self endDate]];
|
NGCalendarDateRange *firstRange;
|
||||||
|
|
||||||
|
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||||
|
firstEndDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtend"];
|
||||||
|
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: [[[firstStartDate values] lastObject] asCalendarDate]
|
||||||
|
endDate: [[[firstEndDate values] lastObject] asCalendarDate]];
|
||||||
|
|
||||||
|
return firstRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned int) occurenceInterval
|
- (unsigned int) occurenceInterval
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* iCalRepeatableEntityObject+SOGo.m - this file is part of SOGo
|
/*
|
||||||
|
Copyright (C) 2008-2011 Inverse inc.
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
Copyright (C) 2008 Inverse inc.
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
This file is part of OpenGroupware.org.
|
||||||
|
|
||||||
|
@ -26,8 +26,11 @@
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
#import <Foundation/NSTimeZone.h>
|
#import <Foundation/NSTimeZone.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalDateTime.h>
|
||||||
#import <NGCards/iCalRecurrenceRule.h>
|
#import <NGCards/iCalRecurrenceRule.h>
|
||||||
#import <NGCards/iCalRecurrenceCalculator.h>
|
#import <NGCards/iCalRecurrenceCalculator.h>
|
||||||
|
#import <NGCards/iCalTimeZone.h>
|
||||||
|
#import <NGCards/NSString+NGCards.h>
|
||||||
#import <NGExtensions/NGCalendarDateRange.h>
|
#import <NGExtensions/NGCalendarDateRange.h>
|
||||||
|
|
||||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||||
|
@ -104,25 +107,39 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) doesOccurOnDate: (NSCalendarDate *) occurenceDate
|
/**
|
||||||
|
* Checks if a date is part of the recurring entity.
|
||||||
|
* @param theOccurrenceDate the date to verify.
|
||||||
|
* @return true if the occurence date is part of the recurring entity.
|
||||||
|
*/
|
||||||
|
- (BOOL) doesOccurOnDate: (NSCalendarDate *) theOccurenceDate
|
||||||
{
|
{
|
||||||
NSArray *ranges;
|
NSArray *ranges;
|
||||||
NGCalendarDateRange *checkRange;
|
NGCalendarDateRange *checkRange, *firstRange;
|
||||||
NSCalendarDate *endDate;
|
NSCalendarDate *startDate, *endDate;
|
||||||
|
iCalDateTime *firstStartDate;
|
||||||
BOOL doesOccur;
|
BOOL doesOccur;
|
||||||
|
|
||||||
doesOccur = [self isRecurrent];
|
doesOccur = [self isRecurrent];
|
||||||
if (doesOccur)
|
if (doesOccur)
|
||||||
{
|
{
|
||||||
endDate = [occurenceDate addTimeInterval: [self occurenceInterval]];
|
// Retrieve the range of the first event
|
||||||
checkRange = [NGCalendarDateRange calendarDateRangeWithStartDate: occurenceDate
|
firstRange = [self firstOccurenceRange];
|
||||||
|
|
||||||
|
// Set the range to check with respect to the event timezone (extracted from the start date)
|
||||||
|
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||||
|
startDate = [[firstStartDate timeZone] computedDateForDate: theOccurenceDate];
|
||||||
|
endDate = [startDate addTimeInterval: [self occurenceInterval]];
|
||||||
|
checkRange = [NGCalendarDateRange calendarDateRangeWithStartDate: startDate
|
||||||
endDate: endDate];
|
endDate: endDate];
|
||||||
|
|
||||||
|
// Calculate the occurrences for the given date
|
||||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: checkRange
|
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: checkRange
|
||||||
firstInstanceCalendarDateRange: [self firstOccurenceRange]
|
firstInstanceCalendarDateRange: firstRange
|
||||||
recurrenceRules: [self recurrenceRules]
|
recurrenceRules: [self recurrenceRules]
|
||||||
exceptionRules: [self exceptionRules]
|
exceptionRules: [self exceptionRules]
|
||||||
exceptionDates: [self exceptionDates]];
|
exceptionDates: [self exceptionDates]];
|
||||||
doesOccur = [ranges dateRangeArrayContainsDate: occurenceDate];
|
doesOccur = [ranges dateRangeArrayContainsDate: startDate];
|
||||||
}
|
}
|
||||||
|
|
||||||
return doesOccur;
|
return doesOccur;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
/* UIxCalListingActions.m - this file is part of SOGo
|
/* UIxCalListingActions.m - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2010 Inverse inc.
|
* Copyright (C) 2006-2011 Inverse inc.
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
* Francis Lachapelle <flachapelle@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
|
||||||
|
@ -34,6 +35,8 @@
|
||||||
#import <NGObjWeb/WOResponse.h>
|
#import <NGObjWeb/WOResponse.h>
|
||||||
|
|
||||||
#import <NGCards/iCalPerson.h>
|
#import <NGCards/iCalPerson.h>
|
||||||
|
#import <NGCards/iCalTimeZone.h>
|
||||||
|
#import <NGCards/iCalDateTime.h>
|
||||||
|
|
||||||
#import <NGExtensions/NGCalendarDateRange.h>
|
#import <NGExtensions/NGCalendarDateRange.h>
|
||||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||||
|
@ -246,8 +249,12 @@ static NSArray *tasksFields = nil;
|
||||||
forKey: @"c_title"];
|
forKey: @"c_title"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: shouldn't this be handled when creating the quick records ? */
|
/*
|
||||||
- (void) _fixDates: (NSMutableDictionary *) aRecord
|
* Adjust the event start and end dates when there's a time change
|
||||||
|
* in the period covering the view for the user's timezone.
|
||||||
|
* @param theRecord the attributes of the event.
|
||||||
|
*/
|
||||||
|
- (void) _fixDates: (NSMutableDictionary *) theRecord
|
||||||
{
|
{
|
||||||
NSCalendarDate *aDate, *aStartDate;
|
NSCalendarDate *aDate, *aStartDate;
|
||||||
NSNumber *aDateValue;
|
NSNumber *aDateValue;
|
||||||
|
@ -272,41 +279,25 @@ static NSArray *tasksFields = nil;
|
||||||
http://www.sogo.nu/bugs/view.php?id=678
|
http://www.sogo.nu/bugs/view.php?id=678
|
||||||
...
|
...
|
||||||
*/
|
*/
|
||||||
if (dayBasedView || [[aRecord objectForKey: @"c_isallday"] boolValue])
|
|
||||||
|
if (dayBasedView || [[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||||
{
|
{
|
||||||
for (count = 0; count < 2; count++)
|
for (count = 0; count < 2; count++)
|
||||||
{
|
{
|
||||||
aDateField = fields[count * 2];
|
aDateField = fields[count * 2];
|
||||||
aDate = [aRecord objectForKey: aDateField];
|
aDate = [theRecord objectForKey: aDateField];
|
||||||
daylightOffset = (int) ([userTimeZone secondsFromGMTForDate: aDate]
|
daylightOffset = (int) ([userTimeZone secondsFromGMTForDate: aDate]
|
||||||
- [userTimeZone secondsFromGMTForDate: startDate]);
|
- [userTimeZone secondsFromGMTForDate: startDate]);
|
||||||
if (daylightOffset)
|
if (daylightOffset)
|
||||||
{
|
{
|
||||||
aDate = [aDate dateByAddingYears: 0 months: 0 days: 0 hours: 0
|
aDate = [aDate dateByAddingYears: 0 months: 0 days: 0 hours: 0
|
||||||
minutes: 0 seconds: daylightOffset];
|
minutes: 0 seconds: daylightOffset];
|
||||||
[aRecord setObject: aDate forKey: aDateField];
|
[theRecord setObject: aDate forKey: aDateField];
|
||||||
aDateValue = [NSNumber numberWithInt: [aDate timeIntervalSince1970]];
|
aDateValue = [NSNumber numberWithInt: [aDate timeIntervalSince1970]];
|
||||||
[aRecord setObject: aDateValue forKey: fields[count * 2 + 1]];
|
[theRecord setObject: aDateValue forKey: fields[count * 2 + 1]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aDateValue = [aRecord objectForKey: @"c_recurrence_id"];
|
|
||||||
aDate = [aRecord objectForKey: @"cycleStartDate"];
|
|
||||||
if (aDateValue && aDate)
|
|
||||||
{
|
|
||||||
aStartDate = [aRecord objectForKey: @"startDate"];
|
|
||||||
if ([userTimeZone isDaylightSavingTimeForDate: aStartDate] !=
|
|
||||||
[userTimeZone isDaylightSavingTimeForDate: aDate])
|
|
||||||
{
|
|
||||||
// For the event's recurrence id, compute the daylight saving time
|
|
||||||
// offset with respect to the first occurrence of the recurring event.
|
|
||||||
daylightOffset = (signed int)[userTimeZone secondsFromGMTForDate: aStartDate]
|
|
||||||
- (signed int)[userTimeZone secondsFromGMTForDate: aDate];
|
|
||||||
aDateValue = [NSNumber numberWithInt: [aDateValue intValue] + daylightOffset];
|
|
||||||
[aRecord setObject: aDateValue forKey: @"c_recurrence_id"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) _fetchFields: (NSArray *) fields
|
- (NSArray *) _fetchFields: (NSArray *) fields
|
||||||
|
@ -341,7 +332,6 @@ static NSArray *tasksFields = nil;
|
||||||
component: component] objectEnumerator];
|
component: component] objectEnumerator];
|
||||||
owner = [currentFolder ownerInContext: context];
|
owner = [currentFolder ownerInContext: context];
|
||||||
ownerUser = [SOGoUser userWithLogin: owner];
|
ownerUser = [SOGoUser userWithLogin: owner];
|
||||||
/* TODO: this should be handled per-folder rather than per-event. */
|
|
||||||
isErasable = ([owner isEqualToString: userLogin]
|
isErasable = ([owner isEqualToString: userLogin]
|
||||||
|| [[currentFolder aclsForUser: userLogin] containsObject: SOGoRole_ObjectEraser]);
|
|| [[currentFolder aclsForUser: userLogin] containsObject: SOGoRole_ObjectEraser]);
|
||||||
while ((newInfo = [currentInfos nextObject]))
|
while ((newInfo = [currentInfos nextObject]))
|
||||||
|
@ -349,10 +339,12 @@ static NSArray *tasksFields = nil;
|
||||||
if ([fields containsObject: @"editable"])
|
if ([fields containsObject: @"editable"])
|
||||||
{
|
{
|
||||||
if (folderIsRemote)
|
if (folderIsRemote)
|
||||||
|
// .ics subscriptions are not editable
|
||||||
[newInfo setObject: [NSNumber numberWithInt: 0]
|
[newInfo setObject: [NSNumber numberWithInt: 0]
|
||||||
forKey: @"editable"];
|
forKey: @"editable"];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Identifies whether the active user can edit the event.
|
||||||
role =
|
role =
|
||||||
[currentFolder roleForComponentsWithAccessClass:
|
[currentFolder roleForComponentsWithAccessClass:
|
||||||
[[newInfo objectForKey: @"c_classification"] intValue]
|
[[newInfo objectForKey: @"c_classification"] intValue]
|
||||||
|
|
Loading…
Reference in New Issue