diff --git a/ChangeLog b/ChangeLog index b4a38934f..4321567ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-11-20 Ludovic Marcotte + + * Fixed a crash issue in SOGoCache - we don't + replaced the cached object. + * Reworked the freebusy code to ignore c_status + and rather consider the values of the particpant + states (accepted/needs-action/declined) + 2008-11-18 Ludovic Marcotte * SoObjects/Appointments/SOGoAppointmentObject.m diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index ce9193eb5..f2000487e 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -2217,7 +2217,7 @@ static Class sogoAppointmentFolderKlass = Nil; if (!infos) infos = [[NSArray alloc] initWithObjects: @"c_partmails", @"c_partstates", - @"c_isopaque", @"c_status", @"c_cycleinfo", nil]; + @"c_isopaque", @"c_status", @"c_cycleinfo", @"c_orgmail", nil]; return [self fetchFields: infos from: _startDate to: _endDate diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 9e7b2d152..8b4098e1f 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -568,7 +568,7 @@ while ((recipient = [recipientsEnum nextObject])) if ([[recipient lowercaseString] hasPrefix: @"mailto:"]) { - person = [iCalPerson new]; + person = [iCalPerson new]; [person setValue: 0 to: recipient]; uid = [person uid]; oldEvent = nil; diff --git a/SoObjects/Appointments/SOGoFreeBusyObject.m b/SoObjects/Appointments/SOGoFreeBusyObject.m index 85a8993d8..fe1e1c924 100644 --- a/SoObjects/Appointments/SOGoFreeBusyObject.m +++ b/SoObjects/Appointments/SOGoFreeBusyObject.m @@ -89,15 +89,15 @@ static unsigned int freebusyRangeEnd = 0; } /* Private API */ -- (iCalFreeBusyType) _fbTypeForEventStatus: (NSNumber *) eventStatus +- (iCalFreeBusyType) _fbTypeForEventStatus: (int) eventStatus { - unsigned int status; + //unsigned int status; iCalFreeBusyType fbType; - status = [eventStatus unsignedIntValue]; - if (status == 0) + //status = [eventStatus unsignedIntValue]; + if (eventStatus == 0) fbType = iCalFBBusyTentative; - else if (status == 1) + else if (eventStatus == 1) fbType = iCalFBBusy; else fbType = iCalFBFree; @@ -110,14 +110,18 @@ static unsigned int freebusyRangeEnd = 0; from: (NSCalendarDate *) _startDate to: (NSCalendarDate *) _endDate { - NSString *uid; + NSArray *emails, *partstates; NSEnumerator *events; iCalCalendar *calendar; iCalFreeBusy *freebusy; NSDictionary *info; iCalFreeBusyType type; + SOGoUser *user; + NSString *uid; + int i; uid = [container ownerInContext: context]; + user = [SOGoUser userWithLogin: uid roles: nil]; calendar = [iCalCalendar groupWithTag: @"vcalendar"]; [calendar setProdID: @"//Inverse inc./SOGo 0.9"]; @@ -143,10 +147,42 @@ static unsigned int freebusyRangeEnd = 0; while ((info = [events nextObject])) if ([[info objectForKey: @"c_isopaque"] boolValue]) { - type = [self _fbTypeForEventStatus: [info objectForKey: @"c_status"]]; - [freebusy addFreeBusyFrom: [info objectForKey: @"startDate"] - to: [info objectForKey: @"endDate"] - type: type]; + type = iCalFBFree; + + // If the event has NO organizer (which means it's the user that has created it) OR + // If we are the organizer of the event THEN we are automatically busy + if ([[info objectForKey: @"c_orgmail"] length] == 0 || + [user hasEmail: [info objectForKey: @"c_orgmail"]]) + { + type = iCalFBBusy; + } + else + { + // We check if the user has accepted/declined or needs action + // on the current event. + emails = [[info objectForKey: @"c_partmails"] componentsSeparatedByString: @"\n"]; + + for (i = 0; i < [emails count]; i++) + { + if ([user hasEmail: [emails objectAtIndex: i]]) + { + // We now fetch the c_partstates array and get the participation + // status of the user for the event + partstates = [[info objectForKey: @"c_partstates"] componentsSeparatedByString: @"\n"]; + + if (i < [partstates count]) + { + type = [self _fbTypeForEventStatus: [[partstates objectAtIndex: i] intValue]]; + } + break; + } + } + } + + if (type == iCalFBBusy || type == iCalFBBusyTentative) + [freebusy addFreeBusyFrom: [info objectForKey: @"startDate"] + to: [info objectForKey: @"endDate"] + type: type]; } [calendar setUniqueChild: freebusy]; diff --git a/SoObjects/SOGo/SOGoCache.m b/SoObjects/SOGo/SOGoCache.m index 5b5473d89..92344d77a 100644 --- a/SoObjects/SOGo/SOGoCache.m +++ b/SoObjects/SOGo/SOGoCache.m @@ -240,32 +240,28 @@ static SOGoCache *sharedCache = nil; - (void) _userDefaultsHaveChanged: (NSNotification *) theNotification { - SOGoUserDefaults *d; - - d = [[SOGoUserDefaults alloc] initWithTableURL: [[theNotification userInfo] objectForKey: @"url"] - uid: [[theNotification userInfo] objectForKey: @"uid"] - fieldName: [[theNotification userInfo] objectForKey: @"fieldName"]]; - [d setValues: [[theNotification userInfo] objectForKey: @"values"]]; + SOGoUser *user; + NSString *uid; - - [SOGoCache setCachedUserDefaults: d - user: [[theNotification userInfo] objectForKey: @"uid"]]; - [d release]; + uid = [[theNotification userInfo] objectForKey: @"uid"]; + + if ((user = [users objectForKey: uid])) + { + [[user userDefaults] setValues: [[theNotification userInfo] objectForKey: @"values"]]; + } } - (void) _userSettingsHaveChanged: (NSNotification *) theNotification { - SOGoUserDefaults *d; - - d = [[SOGoUserDefaults alloc] initWithTableURL: [[theNotification userInfo] objectForKey: @"url"] - uid: [[theNotification userInfo] objectForKey: @"uid"] - fieldName: [[theNotification userInfo] objectForKey: @"fieldName"]]; - [d setValues: [[theNotification userInfo] objectForKey: @"values"]]; + SOGoUser *user; + NSString *uid; - - [SOGoCache setCachedUserSettings: d - user: [[theNotification userInfo] objectForKey: @"uid"]]; - [d release]; + uid = [[theNotification userInfo] objectForKey: @"uid"]; + + if ((user = [users objectForKey: uid])) + { + [[user userSettings] setValues: [[theNotification userInfo] objectForKey: @"values"]]; + } } - (void) _cleanupSources diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index e23133532..6cb214ccc 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -274,8 +274,6 @@ static NSString *uidColumnName = @"c_uid"; d = [[NSMutableDictionary alloc] init]; [d setObject: values forKey: @"values"]; [d setObject: uid forKey: @"uid"]; - [d setObject: fieldName forKey: @"fieldName"]; - [d setObject: url forKey: @"url"]; #warning reenable when the code to use the SOGoCache is finished [[NSDistributedNotificationCenter defaultCenter] diff --git a/UI/MainUI/SOGoUserHomePage.m b/UI/MainUI/SOGoUserHomePage.m index 2b47ecc94..308f5d990 100644 --- a/UI/MainUI/SOGoUserHomePage.m +++ b/UI/MainUI/SOGoUserHomePage.m @@ -101,16 +101,54 @@ static NSString *LDAPContactInfoAttribute = nil; fromStartDate: (NSCalendarDate *) startDate toEndDate: (NSCalendarDate *) endDate { - NSDictionary *record; - int recordCount, recordMax, count, startInterval, endInterval; + NSArray *emails, *partstates; NSCalendarDate *currentDate; + NSDictionary *record; + SOGoUser *user; + + int recordCount, recordMax, count, startInterval, endInterval, i, type; recordMax = [records count]; + user = [SOGoUser userWithLogin: [[self clientObject] ownerInContext: context] + roles: nil]; + for (recordCount = 0; recordCount < recordMax; recordCount++) { record = [records objectAtIndex: recordCount]; if ([[record objectForKey: @"c_isopaque"] boolValue]) { + type = 0; + + // If the event has NO organizer (which means it's the user that has created it) OR + // If we are the organizer of the event THEN we are automatically busy + if ([[record objectForKey: @"c_orgmail"] length] == 0 || + [user hasEmail: [record objectForKey: @"c_orgmail"]]) + { + type = 1; + } + else + { + // We check if the user has accepted/declined or needs action + // on the current event. + emails = [[record objectForKey: @"c_partmails"] componentsSeparatedByString: @"\n"]; + + for (i = 0; i < [emails count]; i++) + { + if ([user hasEmail: [emails objectAtIndex: i]]) + { + // We now fetch the c_partstates array and get the participation + // status of the user for the event + partstates = [[record objectForKey: @"c_partstates"] componentsSeparatedByString: @"\n"]; + + if (i < [partstates count]) + { + type = ([[partstates objectAtIndex: i] intValue] < 2 ? 1 : 0); + } + break; + } + } + } + currentDate = [record objectForKey: @"startDate"]; if ([currentDate earlierDate: startDate] == currentDate) startInterval = 0; @@ -125,8 +163,9 @@ static NSString *LDAPContactInfoAttribute = nil; endInterval = ([currentDate timeIntervalSinceDate: startDate] / intervalSeconds); - for (count = startInterval; count < endInterval; count++) - *(items + count) = 1; + if (type == 1) + for (count = startInterval; count < endInterval; count++) + *(items + count) = 1; } } } diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index c50930322..e44974a46 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -918,15 +918,15 @@ iRANGE(2); - (NSArray *) statusTypes { - static NSArray *priorities = nil; + static NSArray *statusTypes = nil; - if (!priorities) + if (!statusTypes) { - priorities = [NSArray arrayWithObjects: @"", @"TENTATIVE", @"CONFIRMED", @"CANCELLED", nil]; - [priorities retain]; + statusTypes = [NSArray arrayWithObjects: @"", @"TENTATIVE", @"CONFIRMED", @"CANCELLED", nil]; + [statusTypes retain]; } - return priorities; + return statusTypes; } - (void) setStatus: (NSString *) _status