See ChangeLogs

Monotone-Parent: 5c6353cb6270d51a457d46a8fe98dadae4f37193
Monotone-Revision: c0509d9d92c69255be6d27969b4f578739e78c7f

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2011-07-08T00:22:10
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2011-07-08 00:22:10 +00:00
parent 34f2904f0d
commit a40357f9c4
8 changed files with 99 additions and 34 deletions

View File

@ -1,3 +1,19 @@
2011-07-11 Francis Lachapelle <flachapelle@inverse.ca>
* UI/Scheduler/UIxAppointmentEditor.m
(-takeValuesFromRequest:inContext:): when switching from an
all-day event to a non-all-day event, we must add the vTimeZone
definition. The opposite is also fixed.
* SoObjects/Appointments/SOGoComponentOccurence.m
(-prepareDelete): when deleting an occurrence of a floating
all-day event, we must adjust the exception date to the user's timezone.
* SoObjects/Appointments/SOGoAppointmentFolder.m
(-_flattenCycleRecord:forRange:intoArray:): when computing
occurrences of a floating all-day event, we must also ajdust the
exception dates to the user's timezone.
2011-07-08 Francis Lachapelle <flachapelle@inverse.ca> 2011-07-08 Francis Lachapelle <flachapelle@inverse.ca>
* UI/MailerUI/UIxMailListActions.m (-getUIDsAndHeadersInFolder) * UI/MailerUI/UIxMailListActions.m (-getUIDsAndHeadersInFolder)

View File

@ -1,3 +1,8 @@
2011-07-11 Francis Lachapelle <flachapelle@inverse.ca>
* iCalRepeatableEntityObject.m (-addToExceptionDates:): drop the
time part when dealing with an all-day event.
2011-03-29 Francis Lachapelle <flachapelle@inverse.ca> 2011-03-29 Francis Lachapelle <flachapelle@inverse.ca>
* iCalRepeatableEntityObject.m (-rules:withEventTimeZone:): new * iCalRepeatableEntityObject.m (-rules:withEventTimeZone:): new

View File

@ -29,6 +29,7 @@
#import "NSCalendarDate+NGCards.h" #import "NSCalendarDate+NGCards.h"
#import "iCalDateTime.h" #import "iCalDateTime.h"
#import "iCalEvent.h"
#import "iCalTimeZone.h" #import "iCalTimeZone.h"
#import "iCalRecurrenceRule.h" #import "iCalRecurrenceRule.h"
#import "iCalRecurrenceCalculator.h" #import "iCalRecurrenceCalculator.h"
@ -174,7 +175,10 @@
dateTime = [iCalDateTime new]; dateTime = [iCalDateTime new];
[dateTime setTag: @"exdate"]; [dateTime setTag: @"exdate"];
[dateTime setDateTime: _rdate]; if ([self isKindOfClass: [iCalEvent class]] && [(iCalEvent *)self isAllDay])
[dateTime setDate: _rdate];
else
[dateTime setDateTime: _rdate];
[self addChild: dateTime]; [self addChild: dateTime];
[dateTime release]; [dateTime release];
} }
@ -191,7 +195,7 @@
} }
/** /**
* Return the exception dates of the event in GMT. * Return the exception dates of the entity in GMT.
* @return an array of strings. * @return an array of strings.
*/ */
- (NSArray *) exceptionDates - (NSArray *) exceptionDates

View File

@ -850,8 +850,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
intoArray: (NSMutableArray *) theRecords intoArray: (NSMutableArray *) theRecords
{ {
NSMutableDictionary *row, *fixedRow; NSMutableDictionary *row, *fixedRow;
NSMutableArray *records; NSMutableArray *records, *newExDates;
NSDictionary *cycleinfo; NSDictionary *cycleinfo;
NSEnumerator *exDatesList;
NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange; NGCalendarDateRange *firstRange, *recurrenceRange, *oneRange;
NSArray *rules, *exRules, *exDates, *ranges; NSArray *rules, *exRules, *exDates, *ranges;
NSArray *elements, *components; NSArray *elements, *components;
@ -861,6 +862,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
iCalEvent *component; iCalEvent *component;
iCalTimeZone *eventTimeZone; iCalTimeZone *eventTimeZone;
unsigned count, max, offset; unsigned count, max, offset;
id exDate;
content = [theRecord objectForKey: @"c_cycleinfo"]; content = [theRecord objectForKey: @"c_cycleinfo"];
if (![content isNotNull]) if (![content isNotNull])
@ -935,6 +937,17 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
[firstEndDate setTimeZone: timeZone]; [firstEndDate setTimeZone: timeZone];
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
endDate: firstEndDate]; endDate: firstEndDate];
// Adjust the exception dates
exDatesList = [exDates objectEnumerator];
newExDates = [NSMutableArray arrayWithCapacity: [exDates count]];
while ((exDate = [exDatesList nextObject]))
{
exDate = [[exDate asCalendarDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
seconds:-offset];
[newExDates addObject: exDate];
}
exDates = newExDates;
} }
} }

View File

@ -91,11 +91,6 @@
iCalEvent *newOccurence, *master; iCalEvent *newOccurence, *master;
NSCalendarDate *date, *firstDate; NSCalendarDate *date, *firstDate;
unsigned int interval, nbrDays; unsigned int interval, nbrDays;
SOGoUserDefaults *ud;
NSTimeZone *timeZone;
ud = [[SOGoUser userWithLogin: owner] userDefaults];
timeZone = [ud timeZone];
newOccurence = (iCalEvent *) [super newOccurenceWithID: theRecurrenceID]; newOccurence = (iCalEvent *) [super newOccurenceWithID: theRecurrenceID];
date = [newOccurence recurrenceId]; date = [newOccurence recurrenceId];
@ -109,7 +104,7 @@
{ {
nbrDays = ((float) abs (interval) / 86400) + 1; nbrDays = ((float) abs (interval) / 86400) + 1;
[newOccurence setAllDayWithStartDate: date [newOccurence setAllDayWithStartDate: date
duration: nbrDays]; duration: nbrDays];
} }
else else
{ {
@ -121,7 +116,7 @@
minute: 0 minute: 0
second: interval]]; second: interval]];
} }
return newOccurence; return newOccurence;
} }

View File

@ -1218,7 +1218,7 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
return [self component: YES secure: NO]; return [self component: YES secure: NO];
} }
#warning alarms: we don not handle occurrences #warning alarms: we do not handle occurrences
- (NSException *) prepareDelete - (NSException *) prepareDelete
{ {
if ([[SOGoSystemDefaults sharedSystemDefaults] enableEMailAlarms]) if ([[SOGoSystemDefaults sharedSystemDefaults] enableEMailAlarms])

View File

@ -1,8 +1,9 @@
/* SOGoComponentOccurence.m - this file is part of SOGo /* SOGoComponentOccurence.m - this file is part of SOGo
* *
* Copyright (C) 2008-2010 Inverse inc. * Copyright (C) 2008-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
@ -25,8 +26,15 @@
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <NGCards/iCalCalendar.h> #import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalTimeZone.h>
#import <NGCards/iCalRepeatableEntityObject.h> #import <NGCards/iCalRepeatableEntityObject.h>
#import <NGObjWeb/WOContext+SoObjects.h>
#import <SOGo/SOGoUser.h>
#import <SOGo/SOGoDomainDefaults.h>
#import "SOGoAppointmentObject.h" #import "SOGoAppointmentObject.h"
#import "SOGoCalendarComponent.h" #import "SOGoCalendarComponent.h"
@ -144,8 +152,10 @@
NSCalendarDate *recurrenceId, *currentId; NSCalendarDate *recurrenceId, *currentId;
NSException *error; NSException *error;
NSString *newContent; NSString *newContent;
NSTimeZone *timeZone;
iCalCalendar *calendar; iCalCalendar *calendar;
iCalEntityObject *currentOccurence; iCalEntityObject *currentOccurence;
SOGoUserDefaults *ud;
int max, count; int max, count;
if (component == master) if (component == master)
@ -155,10 +165,7 @@
if ([container respondsToSelector: @selector (prepareDeleteOccurence:)]) if ([container respondsToSelector: @selector (prepareDeleteOccurence:)])
[container prepareDeleteOccurence: component]; [container prepareDeleteOccurence: component];
// Add an date exception
recurrenceId = [component recurrenceId]; recurrenceId = [component recurrenceId];
[master addToExceptionDates: recurrenceId];
[master increaseSequence];
// Remove the specified occurence within the repeating vEvent. // Remove the specified occurence within the repeating vEvent.
calendar = [master parent]; calendar = [master parent];
@ -177,6 +184,18 @@
count++; count++;
} }
// Add an date exception
if ([master respondsToSelector: @selector (isAllDay)] && [(iCalEvent *)master isAllDay])
{
// We're deleting an occurrence of an all-day event; adjust the recurrence id
// to the user's timezone.
ud = [[context activeUser] userDefaults];
timeZone = [ud timeZone];
[recurrenceId setTimeZone: timeZone];
}
[master addToExceptionDates: recurrenceId];
[master increaseSequence];
// We generate the updated iCalendar file and we save it // We generate the updated iCalendar file and we save it
// in the database. // in the database.
newContent = [calendar versitString]; newContent = [calendar versitString];
@ -186,9 +205,9 @@
return error; return error;
} }
- (void) saveComponent: (iCalRepeatableEntityObject *) newEvent - (NSException *) saveComponent: (iCalRepeatableEntityObject *) newObject
{ {
[container saveComponent: newEvent]; return [container saveComponent: newObject];
} }
#warning most of SOGoCalendarComponent and SOGoComponentOccurence share the same external interface... \ #warning most of SOGoCalendarComponent and SOGoComponentOccurence share the same external interface... \

View File

@ -525,19 +525,19 @@
inContext: (WOContext *) _ctx inContext: (WOContext *) _ctx
{ {
int nbrDays; int nbrDays;
iCalDateTime *startDate;
iCalTimeZone *tz;
SOGoUserDefaults *ud; SOGoUserDefaults *ud;
[self event]; [self event];
[super takeValuesFromRequest: _rq inContext: _ctx]; [super takeValuesFromRequest: _rq inContext: _ctx];
if (isAllDay) if (isAllDay)
{ {
nbrDays = ((float) abs ([aptEndDate timeIntervalSinceDate: aptStartDate]) nbrDays = ((float) abs ([aptEndDate timeIntervalSinceDate: aptStartDate])
/ 86400) + 1; / 86400) + 1;
[event setAllDayWithStartDate: aptStartDate [event setAllDayWithStartDate: aptStartDate
duration: nbrDays]; duration: nbrDays];
} }
else else
{ {
@ -545,20 +545,33 @@
[event setEndDate: aptEndDate]; [event setEndDate: aptEndDate];
} }
if ([[self clientObject] isNew]) if (!isAllDay)
{ {
iCalTimeZone *tz; // Make sure there's a vTimeZone associated to the event unless it
// is an all-day event.
// Don't add a vTimeZone to all-day events startDate = (iCalDateTime *)[event uniqueChildWithTag: @"dtstart"];
if (!isAllDay) if (![startDate timeZone])
{ {
ud = [[context activeUser] userDefaults]; ud = [[context activeUser] userDefaults];
tz = [iCalTimeZone timeZoneForName: [ud timeZoneName]];
tz = [iCalTimeZone timeZoneForName: [ud timeZoneName]]; if ([[event parent] addTimeZone: tz])
[[event parent] addTimeZone: tz]; {
[(iCalDateTime *)[event uniqueChildWithTag: @"dtstart"] setTimeZone: tz]; [startDate setTimeZone: tz];
[(iCalDateTime *)[event uniqueChildWithTag: @"dtend"] setTimeZone: tz]; [(iCalDateTime *)[event uniqueChildWithTag: @"dtend"] setTimeZone: tz];
} }
}
}
else if (![[self clientObject] isNew])
{
// Remove the vTimeZone when dealing with an all-day event.
startDate = (iCalDateTime *)[event uniqueChildWithTag: @"dtstart"];
tz = [startDate timeZone];
if (tz)
{
[startDate setTimeZone: nil];
[(iCalDateTime *)[event uniqueChildWithTag: @"dtend"] setTimeZone: nil];
[[event parent] removeChild: tz];
}
} }
[event setTransparency: (isTransparent? @"TRANSPARENT" : @"OPAQUE")]; [event setTransparency: (isTransparent? @"TRANSPARENT" : @"OPAQUE")];