Monotone-Parent: fe67bff0ab967ccf03cfe54c248865c9df889c21
Monotone-Revision: 7342d9cd31675160736e0f2db8a83047d9babea9 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2007-10-09T17:19:20 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
084ffb7bc8
commit
03382298b8
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2007-10-05 Ludovic Marcotte <ludovic@inverse.ca>
|
||||
|
||||
* UI/WebServerResources/MailerUI.js
|
||||
We check if at least one message is selected
|
||||
before performing a Reply/Reply All/Forward
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
and others - implemented support for recurring
|
||||
events (with some known limitations right now,
|
||||
all soon to be fixed).
|
||||
|
||||
2007-10-04 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* Main/SOGo.m ([SOGo -isUserName:_keyinContext:_ctx]): removed
|
||||
|
|
|
@ -262,10 +262,9 @@ static void NGMonthDaySet_fillWithByDayX(NGMonthDaySet *daySet,
|
|||
interval = [self->rrule repeatInterval];
|
||||
until = [self lastInstanceStartDate]; // TODO: maybe replace
|
||||
byMonthDay = [self->rrule byMonthDay];
|
||||
|
||||
|
||||
/* check whether the range to be processed is beyond the 'until' date */
|
||||
|
||||
|
||||
/* check whether the range to be processed is beyond the 'until' date */
|
||||
if (until != nil) {
|
||||
if ([until compare:rStart] == NSOrderedAscending) /* until before start */
|
||||
return nil;
|
||||
|
@ -314,7 +313,7 @@ static void NGMonthDaySet_fillWithByDayX(NGMonthDaySet *daySet,
|
|||
continue;
|
||||
|
||||
/* first check whether we are in the interval */
|
||||
|
||||
|
||||
if ((monthIdxInRecurrence % interval) != 0)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -100,9 +100,10 @@ static Class yearlyCalcClass = Nil;
|
|||
rule = [_rRules objectAtIndex:i];
|
||||
if (![rule isKindOfClass:iCalRecurrenceRuleClass])
|
||||
rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:rule];
|
||||
|
||||
|
||||
calc = [self recurrenceCalculatorForRecurrenceRule:rule
|
||||
withFirstInstanceCalendarDateRange:_fir];
|
||||
|
||||
rs = [calc recurrenceRangesWithinCalendarDateRange:_r];
|
||||
[ranges addObjectsFromArray:rs];
|
||||
}
|
||||
|
@ -158,6 +159,7 @@ static Class yearlyCalcClass = Nil;
|
|||
unsigned k;
|
||||
|
||||
exDate = [exDates objectAtIndex:i];
|
||||
|
||||
for (k = 0; k < rCount; k++) {
|
||||
unsigned rIdx;
|
||||
|
||||
|
|
|
@ -568,13 +568,16 @@ static NSNumber *sharedYes = nil;
|
|||
|
||||
md = [[_record mutableCopy] autorelease];
|
||||
|
||||
/* cycle is in _r */
|
||||
/* cycle is in _r. We also have to override the c_startdate/c_enddate with the date values of
|
||||
the reccurence since we use those when displaying events in SOGo Web */
|
||||
tmp = [_r startDate];
|
||||
[tmp setTimeZone: timeZone];
|
||||
[md setObject:tmp forKey:@"startDate"];
|
||||
[md setObject: [NSNumber numberWithInt: [tmp timeIntervalSince1970]] forKey: @"c_startdate"];
|
||||
tmp = [_r endDate];
|
||||
[tmp setTimeZone: timeZone];
|
||||
[md setObject:tmp forKey:@"endDate"];
|
||||
[md setObject: [NSNumber numberWithInt: [tmp timeIntervalSince1970]] forKey: @"c_enddate"];
|
||||
|
||||
return md;
|
||||
}
|
||||
|
@ -633,20 +636,24 @@ static NSNumber *sharedYes = nil;
|
|||
rules = [cycleinfo objectForKey:@"rules"];
|
||||
exRules = [cycleinfo objectForKey:@"exRules"];
|
||||
exDates = [cycleinfo objectForKey:@"exDates"];
|
||||
|
||||
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange:_r
|
||||
firstInstanceCalendarDateRange:fir
|
||||
recurrenceRules:rules
|
||||
exceptionRules:exRules
|
||||
exceptionDates:exDates];
|
||||
count = [ranges count];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
NGCalendarDateRange *rRange;
|
||||
id fixedRow;
|
||||
|
||||
rRange = [ranges objectAtIndex:i];
|
||||
fixedRow = [self fixupCycleRecord:row cycleRange:rRange];
|
||||
if (fixedRow != nil) [_ma addObject:fixedRow];
|
||||
if (fixedRow != nil)
|
||||
{
|
||||
[_ma addObject:fixedRow];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -845,21 +852,20 @@ static NSNumber *sharedYes = nil;
|
|||
ma = [NSMutableArray arrayWithArray: records];
|
||||
}
|
||||
|
||||
/* fetch recurrent apts now */
|
||||
sql = [NSString stringWithFormat: @"(c_iscycle = 1)%@%@%@",
|
||||
dateSqlString, componentSqlString, privacySqlString];
|
||||
/* fetch recurrent apts now. we do NOT consider the date range when doing that
|
||||
as the c_startdate/c_enddate of a recurring event is always set to the first
|
||||
recurrence - others are generated on the fly */
|
||||
sql = [NSString stringWithFormat: @"(c_iscycle = 1)%@%@", componentSqlString, privacySqlString];
|
||||
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
|
||||
|
||||
[fields addObject: @"c_cycleinfo"];
|
||||
|
||||
records = [_folder fetchFields: fields matchingQualifier: qualifier];
|
||||
|
||||
if (records)
|
||||
{
|
||||
if (logger)
|
||||
[self debugWithFormat: @"fetched %i cyclic records: %@",
|
||||
[records count], records];
|
||||
if (r)
|
||||
if (r) {
|
||||
records = [self fixupCyclicRecords: records fetchRange: r];
|
||||
}
|
||||
if (!ma)
|
||||
ma = [NSMutableArray arrayWithCapacity: [records count]];
|
||||
|
||||
|
|
|
@ -153,5 +153,6 @@
|
|||
|
||||
"quotasFormat" = "Quotas: %{0} used on %{1} Kb; %{2}%";
|
||||
|
||||
"Please select a message." = "Please select a message.";
|
||||
"Please select a message to print." = "Please select a message to print.";
|
||||
"Please select only one message to print." = "Please select only one message to print.";
|
||||
|
|
|
@ -203,5 +203,6 @@
|
|||
|
||||
"quotasFormat" = "Quotas: %{0} Ko utilisés sur %{1}; %{2}%";
|
||||
|
||||
"Please select a message." = "Veuillez sélectionner un message.";
|
||||
"Please select a message to print." = "Veuillez sélectionner un message à imprimer.";
|
||||
"Please select only one message to print." = "Veuillez ne sélectionner qu'un seul message à imprimer.";
|
||||
|
|
|
@ -186,5 +186,6 @@
|
|||
|
||||
"quotasFormat" = "Quota: %{0} von %{1} KB verwendet; %{2}%";
|
||||
|
||||
"Please select a message." = "Sie müssen eine Nachricht auswählen.";
|
||||
"Please select a message to print." = "Sie müssen eine Nachricht zum Drucken auswählen.";
|
||||
"Please select only one message to print." = "Bitte wählen Sie nur eine Nachricht zum Drucken aus.";
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
NSCalendarDate *aptStartDate;
|
||||
NSCalendarDate *aptEndDate;
|
||||
NSString *item;
|
||||
NSString *repeat;
|
||||
}
|
||||
|
||||
/* template values */
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#warning WE LEAK IVARS LIKE CRAZY HERE
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#import <NGObjWeb/SoObject.h>
|
||||
|
@ -29,6 +31,7 @@
|
|||
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoContentObject.h>
|
||||
|
@ -48,12 +51,19 @@
|
|||
aptEndDate = nil;
|
||||
item = nil;
|
||||
event = nil;
|
||||
repeat = nil;
|
||||
isAllDay = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(repeat);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* template values */
|
||||
- (iCalEvent *) event
|
||||
{
|
||||
|
@ -132,6 +142,8 @@
|
|||
else
|
||||
text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
|
||||
|
||||
NSLog(@"itemRepeatText: %@", text);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
@ -198,11 +210,12 @@
|
|||
|
||||
- (NSString *) repeat
|
||||
{
|
||||
return @"";
|
||||
return repeat;
|
||||
}
|
||||
|
||||
- (void) setRepeat: (NSString *) newRepeat
|
||||
{
|
||||
ASSIGN(repeat, newRepeat);
|
||||
}
|
||||
|
||||
- (NSString *) reminder
|
||||
|
@ -276,8 +289,32 @@
|
|||
ASSIGN (aptStartDate, startDate);
|
||||
ASSIGN (aptEndDate, endDate);
|
||||
|
||||
// We initialize our repeat ivars
|
||||
if ([event hasRecurrenceRules])
|
||||
{
|
||||
iCalRecurrenceRule *rule;
|
||||
|
||||
repeat = @"CUSTOM";
|
||||
|
||||
/* here comes the code for initializing repeat, reminder and isAllDay... */
|
||||
rule = [[event recurrenceRules] lastObject];
|
||||
|
||||
if ([rule frequency] == iCalRecurrenceFrequenceWeekly)
|
||||
{
|
||||
if ([rule repeatInterval] == 1) repeat = @"WEEKLY";
|
||||
else if ([rule repeatInterval] == 2) repeat = @"BI-WEEKLY";
|
||||
}
|
||||
else if ([rule frequency] == iCalRecurrenceFrequenceDaily)
|
||||
{
|
||||
if ([rule byDayMask] == (iCalWeekDayMonday|iCalWeekDayTuesday|iCalWeekDayWednesday|iCalWeekDayThursday|iCalWeekDayFriday)) repeat = @"EVERY WEEKDAY";
|
||||
else if (![rule byDayMask]) repeat = @"DAILY";
|
||||
}
|
||||
else if ([rule frequency] == iCalRecurrenceFrequenceMonthly && [rule repeatInterval] == 1) repeat = @"MONTHLY";
|
||||
else if ([rule frequency] == iCalRecurrenceFrequenceYearly && [rule repeatInterval] == 1) repeat = @"YEARLY";
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY(repeat);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -310,7 +347,11 @@
|
|||
NSString *iCalString;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
NSLog(@"saveAction, clientObject = %@", clientObject);
|
||||
|
||||
iCalString = [[clientObject calendar: NO] versitString];
|
||||
|
||||
NSLog(@"saveAction, iCalString = %@", iCalString);
|
||||
[clientObject saveContentString: iCalString];
|
||||
|
||||
return [self jsCloseWithRefreshMethod: @"refreshEventsAndDisplay()"];
|
||||
|
@ -352,6 +393,37 @@
|
|||
}
|
||||
if ([clientObject isNew])
|
||||
[event setTransparency: @"OPAQUE"];
|
||||
|
||||
// We remove any repeat rules
|
||||
if (!repeat && [event hasRecurrenceRules])
|
||||
{
|
||||
[event removeAllRecurrenceRules];
|
||||
}
|
||||
else if (!([repeat caseInsensitiveCompare: @"-"] == NSOrderedSame || [repeat caseInsensitiveCompare: @"CUSTOM"] == NSOrderedSame))
|
||||
{
|
||||
iCalRecurrenceRule *rule;
|
||||
|
||||
rule = [[iCalRecurrenceRule alloc] init];
|
||||
|
||||
if ([repeat caseInsensitiveCompare: @"BI-WEEKLY"] == NSOrderedSame)
|
||||
{
|
||||
[rule setFrequency: iCalRecurrenceFrequenceWeekly];
|
||||
[rule setInterval: @"2"];
|
||||
}
|
||||
else if ([repeat caseInsensitiveCompare: @"EVERY WEEKDAY"] == NSOrderedSame)
|
||||
{
|
||||
[rule setByDayMask: (iCalWeekDayMonday|iCalWeekDayTuesday|iCalWeekDayWednesday|iCalWeekDayThursday|iCalWeekDayFriday)];
|
||||
[rule setFrequency: iCalRecurrenceFrequenceDaily];
|
||||
[rule setInterval: @"1"];
|
||||
}
|
||||
else
|
||||
{
|
||||
[rule setFrequency: (iCalRecurrenceFrequency)[rule valueForFrequency: repeat]];
|
||||
[rule setInterval: @"1"];
|
||||
}
|
||||
[event setRecurrenceRules: [NSArray arrayWithObject: rule]];
|
||||
RELEASE(rule);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add tentatively
|
||||
|
|
|
@ -221,50 +221,42 @@
|
|||
{
|
||||
NSEnumerator *folders, *currentInfos;
|
||||
SOGoAppointmentFolder *currentFolder;
|
||||
NSMutableDictionary *infos, *currentInfo, *newInfo;
|
||||
NSString *owner, *uid;
|
||||
NSMutableDictionary *newInfo;
|
||||
NSMutableArray *infos;
|
||||
NSNull *marker;
|
||||
SOGoAppointmentFolders *clientObject;
|
||||
|
||||
marker = [NSNull null];
|
||||
|
||||
infos = [NSMutableDictionary dictionary];
|
||||
clientObject = [self clientObject];
|
||||
clientObject = [self clientObject];
|
||||
|
||||
folders = [[clientObject subFolders] objectEnumerator];
|
||||
currentFolder = [folders nextObject];
|
||||
|
||||
infos = [NSMutableArray array];
|
||||
while (currentFolder)
|
||||
{
|
||||
if ([currentFolder isActive])
|
||||
{
|
||||
owner = [currentFolder ownerInContext: context];
|
||||
currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
component: component] objectEnumerator];
|
||||
newInfo = [currentInfos nextObject];
|
||||
while (newInfo)
|
||||
|
||||
while ((newInfo = [currentInfos nextObject]))
|
||||
{
|
||||
uid = [newInfo objectForKey: @"c_uid"];
|
||||
currentInfo = [infos objectForKey: uid];
|
||||
if (!currentInfo
|
||||
|| [owner isEqualToString: userLogin])
|
||||
{
|
||||
[self _updatePrivacyInComponent: newInfo
|
||||
fromFolder: currentFolder];
|
||||
[newInfo setObject: [currentFolder nameInContainer]
|
||||
forKey: @"c_folder"];
|
||||
// [newInfo setObject: owner forKey: @"c_owner"];
|
||||
[infos setObject: [newInfo objectsForKeys: fields
|
||||
notFoundMarker: marker]
|
||||
forKey: uid];
|
||||
}
|
||||
newInfo = [currentInfos nextObject];
|
||||
[self _updatePrivacyInComponent: newInfo
|
||||
fromFolder: currentFolder];
|
||||
[newInfo setObject: [currentFolder nameInContainer]
|
||||
forKey: @"c_folder"];
|
||||
|
||||
[infos addObject: [newInfo objectsForKeys: fields
|
||||
notFoundMarker: marker]];
|
||||
}
|
||||
}
|
||||
currentFolder = [folders nextObject];
|
||||
}
|
||||
|
||||
return [infos allValues];
|
||||
return infos;
|
||||
}
|
||||
|
||||
- (WOResponse *) _responseWithData: (NSArray *) data
|
||||
|
|
Loading…
Reference in New Issue