diff --git a/ChangeLog b/ChangeLog index 842e1cd04..cc7dac5c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2009-03-24 Ludovic Marcotte + + * UI/MailerUI/UIxMailListView.m + ([UIxMailListView messages)]: + Adjusted the sort so it's a little bit faster + and correctly work in case the server returns us + the FETCH response in an order different that what + we asked for. + +2009-03-24 Francis Lachapelle + + * SoObjects/Appointments/SOGoCalendarComponent.m + ([SOGoCalendarComponent + -sendEMailUsingTemplateNamed:forObject:previousObject:toAttendees:]): + no longer send a deletion notification to an attendee who already + declined the meeting. + + * UI/MailPartViewers/UIxMailPartICalActions.m + ([UIxMailPartICalActions -_eventObjectWithUID:forUser:]): when + looking for an event for a specific user, we now search into all + the user's calendar folders. + 2009-03-24 Wolfgang Sourdeau * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor @@ -119,8 +141,8 @@ * UI/MainUI/SOGoRootPage.m ([SOGoRootPage -version]): new method that returns the application version. - * iCalDateTime.m ([iCalDateTime -dateTime]): when not defined, the - timezone is now guessed from the date of the current object. + * SOPE/NGCards/iCalDateTime.m ([iCalDateTime -dateTime]): when not + defined, the timezone is now guessed from the date of the current object. 2009-03-18 Ludovic Marcotte diff --git a/SOPE/NGCards/ChangeLog b/SOPE/NGCards/ChangeLog index 09e7074bc..330b308a8 100644 --- a/SOPE/NGCards/ChangeLog +++ b/SOPE/NGCards/ChangeLog @@ -9,6 +9,11 @@ currentStartDate when instantiated from a copy of firDate, to avoid a leak. +2009-03-18 Francis Lachapelle + + * iCalDateTime.m ([iCalDateTime -dateTime]): when not defined, the + timezone is now guessed from the date of the current object. + 2009-02-06 Wolfgang Sourdeau * CardElement.m ([CardElement -setParent:aParent]): no longer diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 7c6758eca..457e22dc2 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -202,6 +202,7 @@ if (!object) { + folder = [container lookupCalendarFolderForUID: uid]; object = [SOGoAppointmentObject objectWithName: nameInContainer inContainer: folder]; [object setIsNew: YES]; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 017473402..82cc7899b 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -570,7 +570,11 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) for (i = 0; i < count; i++) { attendee = [attendees objectAtIndex: i]; - if (![[attendee uid] isEqualToString: owner]) + // Don't send a notification to the event organizer nor a deletion + // notification to an attendee who already declined the invitation. + if (![[attendee uid] isEqualToString: owner] && + !([[attendee partStat] compare: @"DECLINED"] == NSOrderedSame && + [newPageName compare: @"Deletion"] == NSOrderedSame)) { /* construct recipient */ recipient = [attendee mailAddress]; diff --git a/UI/MailPartViewers/UIxMailPartICalActions.m b/UI/MailPartViewers/UIxMailPartICalActions.m index e6e483d6c..a58978018 100644 --- a/UI/MailPartViewers/UIxMailPartICalActions.m +++ b/UI/MailPartViewers/UIxMailPartICalActions.m @@ -21,6 +21,7 @@ */ #import +#import #import #import @@ -41,6 +42,7 @@ #import #import #import +#import #import #import #import @@ -69,27 +71,33 @@ - (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid forUser: (SOGoUser *) user { - SOGoAppointmentFolder *personalFolder; + SOGoAppointmentFolder *folder; SOGoAppointmentObject *eventObject; + NSArray *folders; + NSEnumerator *e; NSString *cname; eventObject = nil; -#warning Should call lookupCalendarFoldersForUIDs to search among all folders - personalFolder = [user personalCalendarFolderInContext: context]; - cname = [personalFolder resourceNameForEventUID: uid]; - if (cname) + folders = [[user calendarsFolderInContext: context] subFolders]; + e = [folders objectEnumerator]; + while ( eventObject == nil && (folder = [e nextObject]) ) { - eventObject = [personalFolder lookupName: cname - inContext: context acquire: NO]; - if (![eventObject isKindOfClass: [SOGoAppointmentObject class]]) - eventObject = nil; + cname = [folder resourceNameForEventUID: uid]; + if (cname) + { + eventObject = [folder lookupName: cname + inContext: context acquire: NO]; + if (![eventObject isKindOfClass: [SOGoAppointmentObject class]]) + eventObject = nil; + } } - + if (!eventObject) { + folder = [user personalCalendarFolderInContext: context]; eventObject = [SOGoAppointmentObject objectWithName: uid - inContainer: personalFolder]; + inContainer: folder]; [eventObject setIsNew: YES]; } diff --git a/UI/MailerUI/UIxMailListView.m b/UI/MailerUI/UIxMailListView.m index 0ee6599fb..e560af6c4 100644 --- a/UI/MailerUI/UIxMailListView.m +++ b/UI/MailerUI/UIxMailListView.m @@ -1,14 +1,15 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG + Copyright (C) 2006-2009 Inverse inc. - This file is part of OpenGroupware.org. + This file is part of SOGo - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. @@ -459,21 +460,26 @@ - (NSArray *) messages { + NSMutableArray *unsortedMsgs; + NSMutableDictionary *map; + NSDictionary *msgs; NSArray *uids; - NSDictionary *msgs, *msg; - NSEnumerator *msgsList; - NSMutableArray *unsortedMsgs, *sortedMsgs; + + unsigned len, i, count; NSRange r; - unsigned len, index; if (!messages) { - r = [self fetchBlock]; + r = [self fetchBlock]; uids = [self sortedUIDs]; len = [uids count]; + + // only need to restrict if we have a lot if (len > r.length) - /* only need to restrict if we have a lot */ + { uids = [uids subarrayWithRange: r]; + len = [uids count]; + } // Don't assume the IMAP server return the messages in the // same order as the specified list of UIDs (specially true for @@ -481,17 +487,24 @@ msgs = (NSDictionary *) [[self clientObject] fetchUIDs: uids parts: [self fetchKeys]]; unsortedMsgs = [msgs objectForKey: @"fetch"]; - sortedMsgs = [NSMutableArray arrayWithCapacity: [unsortedMsgs count]]; - msgsList = [unsortedMsgs objectEnumerator]; - while ( (msg = [msgsList nextObject]) ) + count = [unsortedMsgs count]; + + messages = [NSMutableArray arrayWithCapacity: count]; + + // We build our uid->message map from our FETCH response + map = [[NSMutableDictionary alloc] initWithCapacity: count]; + + for (i = 0; i < count; i++) + [map setObject: [unsortedMsgs objectAtIndex: i] + forKey: [[unsortedMsgs objectAtIndex: i] objectForKey: @"uid"]]; + + for (i = 0; i < len; i++) { - index = [uids indexOfObject: [msg objectForKey: @"uid"]]; - if (index < [sortedMsgs count]) - [sortedMsgs insertObject: msg atIndex: index]; - else - [sortedMsgs addObject: msg]; + [(NSMutableArray *)messages addObject: [map objectForKey: [uids objectAtIndex: i]]]; } - messages = [[NSArray arrayWithArray: sortedMsgs] retain]; + + RELEASE(map); + RETAIN(messages); } return messages; diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 7849981f6..b9bf21130 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -1461,6 +1461,7 @@ function configureSortableTableHeaders(table) { var headers = $(table).getElementsByClassName("sortableTableHeader"); for (var i = 0; i < headers.length; i++) { var header = $(headers[i]); + header.stopObserving("click", onHeaderClick); header.observe("click", onHeaderClick); } }