From 43ac57b671ecf4f0d81daf3e40fab856a5d3b52a Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Tue, 10 Jun 2014 16:18:12 -0400 Subject: [PATCH 01/20] display the number of active tasks in calendar view --- .../Appointments/SOGoAppointmentFolder.h | 2 + .../Appointments/SOGoAppointmentFolder.m | 22 ++++++- UI/Scheduler/UIxCalendarSelector.m | 60 ++++++++++--------- .../SchedulerUI/UIxCalendarSelector.wox | 9 ++- 4 files changed, 61 insertions(+), 32 deletions(-) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.h b/SoObjects/Appointments/SOGoAppointmentFolder.h index ee703b1d5..b09241cfd 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.h +++ b/SoObjects/Appointments/SOGoAppointmentFolder.h @@ -80,6 +80,8 @@ typedef enum { - (NSArray *) calendarUIDs; +- (NSString *) activeTasks; + /* vevent UID handling */ - (NSString *) resourceNameForEventUID: (NSString *) _uid; diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 61cef70dc..a70a0eb16 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -522,7 +522,6 @@ static iCalEvent *iCalEventK = nil; { /* this is used for group calendars (this folder just returns itself) */ NSString *s; - s = [[self container] nameInContainer]; // [self logWithFormat:@"CAL UID: %@", s]; return [s isNotNull] ? [NSArray arrayWithObjects:&s count:1] : nil; @@ -3270,4 +3269,25 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir return users; } +- (NSString *) activeTasks +{ + NSArray *tasksList; + NSString *activeTasks; + NSMutableArray *fields; + + fields = [NSMutableArray arrayWithObjects: @"c_component", @"c_status", nil]; + + tasksList = [self bareFetchFields: fields + from: nil + to: nil + title: nil + component: @"vtodo" + additionalFilters: @"c_status != 2 AND c_status != 3"]; + + activeTasks = [NSString stringWithFormat:@"(%d)", [tasksList count]]; + + return activeTasks; +} + + @end /* SOGoAppointmentFolder */ diff --git a/UI/Scheduler/UIxCalendarSelector.m b/UI/Scheduler/UIxCalendarSelector.m index 7da4392b3..196299fad 100644 --- a/UI/Scheduler/UIxCalendarSelector.m +++ b/UI/Scheduler/UIxCalendarSelector.m @@ -92,38 +92,42 @@ _intValueFromHex (NSString *hexString) SOGoAppointmentFolder *folder; NSMutableDictionary *calendar; unsigned int count, max; - NSString *folderName, *fDisplayName; + NSString *folderName, *fDisplayName, *fActiveTasks; NSNumber *isActive; - + if (!calendars) + { + co = [self clientObject]; + folders = [co subFolders]; + max = [folders count]; + calendars = [[NSMutableArray alloc] initWithCapacity: max]; + for (count = 0; count < max; count++) { - co = [self clientObject]; - folders = [co subFolders]; - max = [folders count]; - calendars = [[NSMutableArray alloc] initWithCapacity: max]; - for (count = 0; count < max; count++) - { - folder = [folders objectAtIndex: count]; - calendar = [NSMutableDictionary dictionary]; - folderName = [folder nameInContainer]; - fDisplayName = [folder displayName]; - if (fDisplayName == nil) - fDisplayName = @""; - if ([fDisplayName isEqualToString: [co defaultFolderName]]) - fDisplayName = [self labelForKey: fDisplayName]; - [calendar setObject: [NSString stringWithFormat: @"/%@", folderName] - forKey: @"id"]; - [calendar setObject: fDisplayName forKey: @"displayName"]; - [calendar setObject: folderName forKey: @"folder"]; - [calendar setObject: [folder calendarColor] forKey: @"color"]; - isActive = [NSNumber numberWithBool: [folder isActive]]; - [calendar setObject: isActive forKey: @"active"]; - [calendar setObject: [folder ownerInContext: context] - forKey: @"owner"]; - [calendars addObject: calendar]; - } + folder = [folders objectAtIndex: count]; + calendar = [NSMutableDictionary dictionary]; + folderName = [folder nameInContainer]; + fDisplayName = [folder displayName]; + if (fDisplayName == nil) + fDisplayName = @""; + if ([fDisplayName isEqualToString: [co defaultFolderName]]) + fDisplayName = [self labelForKey: fDisplayName]; + [calendar setObject: [NSString stringWithFormat: @"/%@", folderName] + forKey: @"id"]; + [calendar setObject: fDisplayName forKey: @"displayName"]; + [calendar setObject: folderName forKey: @"folder"]; + [calendar setObject: [folder calendarColor] forKey: @"color"]; + isActive = [NSNumber numberWithBool: [folder isActive]]; + [calendar setObject: isActive forKey: @"active"]; + [calendar setObject: [folder ownerInContext: context] + forKey: @"owner"]; + fActiveTasks = [folder activeTasks]; + if (fActiveTasks == nil) + fActiveTasks = @""; + [calendar setObject:fActiveTasks forKey:@"activeTasks" ]; + [calendars addObject: calendar]; } - + } + return calendars; } diff --git a/UI/Templates/SchedulerUI/UIxCalendarSelector.wox b/UI/Templates/SchedulerUI/UIxCalendarSelector.wox index 477a64513..e5f0b03e6 100644 --- a/UI/Templates/SchedulerUI/UIxCalendarSelector.wox +++ b/UI/Templates/SchedulerUI/UIxCalendarSelector.wox @@ -38,9 +38,12 @@ div.colorBox.calendarFolder
  • -
  • +
    + + + + +
    From de2ee2322af740251ac82ca06deb1f7585637024 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Wed, 11 Jun 2014 10:24:04 -0400 Subject: [PATCH 02/20] Change the NSString with NSNumber and add some JavaScript --- .../Appointments/SOGoAppointmentFolder.h | 2 +- .../Appointments/SOGoAppointmentFolder.m | 8 ++-- UI/Scheduler/UIxCalendarSelector.m | 6 +-- .../SchedulerUI/UIxCalendarSelector.wox | 6 +-- UI/WebServerResources/SchedulerUI.js | 44 ++++++++++--------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.h b/SoObjects/Appointments/SOGoAppointmentFolder.h index b09241cfd..05e760909 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.h +++ b/SoObjects/Appointments/SOGoAppointmentFolder.h @@ -80,7 +80,7 @@ typedef enum { - (NSArray *) calendarUIDs; -- (NSString *) activeTasks; +- (NSNumber *) activeTasks; /* vevent UID handling */ diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index a70a0eb16..0a8746083 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -3269,11 +3269,11 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir return users; } -- (NSString *) activeTasks +- (NSNumber *) activeTasks { NSArray *tasksList; - NSString *activeTasks; NSMutableArray *fields; + NSNumber *activeTasks; fields = [NSMutableArray arrayWithObjects: @"c_component", @"c_status", nil]; @@ -3284,8 +3284,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir component: @"vtodo" additionalFilters: @"c_status != 2 AND c_status != 3"]; - activeTasks = [NSString stringWithFormat:@"(%d)", [tasksList count]]; - + activeTasks = [NSNumber numberWithInt:[tasksList count]]; + return activeTasks; } diff --git a/UI/Scheduler/UIxCalendarSelector.m b/UI/Scheduler/UIxCalendarSelector.m index 196299fad..fd9e99c76 100644 --- a/UI/Scheduler/UIxCalendarSelector.m +++ b/UI/Scheduler/UIxCalendarSelector.m @@ -92,8 +92,8 @@ _intValueFromHex (NSString *hexString) SOGoAppointmentFolder *folder; NSMutableDictionary *calendar; unsigned int count, max; - NSString *folderName, *fDisplayName, *fActiveTasks; - NSNumber *isActive; + NSString *folderName, *fDisplayName; + NSNumber *isActive, *fActiveTasks; if (!calendars) { @@ -122,7 +122,7 @@ _intValueFromHex (NSString *hexString) forKey: @"owner"]; fActiveTasks = [folder activeTasks]; if (fActiveTasks == nil) - fActiveTasks = @""; + fActiveTasks = 0; [calendar setObject:fActiveTasks forKey:@"activeTasks" ]; [calendars addObject: calendar]; } diff --git a/UI/Templates/SchedulerUI/UIxCalendarSelector.wox b/UI/Templates/SchedulerUI/UIxCalendarSelector.wox index e5f0b03e6..5b3bd488e 100644 --- a/UI/Templates/SchedulerUI/UIxCalendarSelector.wox +++ b/UI/Templates/SchedulerUI/UIxCalendarSelector.wox @@ -39,10 +39,8 @@ div.colorBox.calendarFolder >
  • - - - - + +
  • diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 8a3a44215..ec3d7ce81 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -2900,27 +2900,29 @@ function configureDragHandles() { } function initCalendarSelector() { - var selector = $("calendarSelector"); - updateCalendarStatus(); // triggers the initial events refresh - selector.changeNotification = updateCalendarsList; - - var list = $("calendarList"); - list.on("mousedown", onCalendarSelectionChange); - list.on("dblclick", onCalendarModify); - list.on("selectstart", listRowMouseDownHandler); - list.attachMenu("calendarsMenu"); - - var items = list.childNodesWithTag("li"); - for (var i = 0; i < items.length; i++) { - var input = items[i].childNodesWithTag("input")[0]; - $(input).observe("click", clickEventWrapper(updateCalendarStatus)); - } - - var links = $("calendarSelectorButtons").childNodesWithTag("a"); - $(links[0]).observe("click", clickEventWrapper(onCalendarNew)); - $(links[1]).observe("click", clickEventWrapper(onCalendarWebAdd)); - $(links[2]).observe("click", clickEventWrapper(onCalendarAdd)); - $(links[3]).observe("click", clickEventWrapper(onCalendarRemove)); + var selector = $("calendarSelector"); + updateCalendarStatus(); // triggers the initial events refresh + selector.changeNotification = updateCalendarsList; + + var list = $("calendarList"); + list.on("mousedown", onCalendarSelectionChange); + list.on("dblclick", onCalendarModify); + list.on("selectstart", listRowMouseDownHandler); + list.attachMenu("calendarsMenu"); + + var items = list.childNodesWithTag("li"); + for (var i = 0; i < items.length; i++) { + var input = items[i].childNodesWithTag("input")[0]; + var activeTasks = items[i].childNodesWithTag("span")[0]; + $(input).observe("click", clickEventWrapper(updateCalendarStatus)); + $(activeTasks).innerHTML = "(" + activeTasks.innerText + ")"; + } + + var links = $("calendarSelectorButtons").childNodesWithTag("a"); + $(links[0]).observe("click", clickEventWrapper(onCalendarNew)); + $(links[1]).observe("click", clickEventWrapper(onCalendarWebAdd)); + $(links[2]).observe("click", clickEventWrapper(onCalendarAdd)); + $(links[3]).observe("click", clickEventWrapper(onCalendarRemove)); } function onCalendarSelectionChange(event) { From 0e182f84360aa35c87d39320cab08d7eaeb55d90 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Wed, 11 Jun 2014 11:25:17 -0400 Subject: [PATCH 03/20] Update SOGoAppointmentFolder.m Fix the status filtering from 2 to 1 --- SoObjects/Appointments/SOGoAppointmentFolder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 0a8746083..6f759a137 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -3282,7 +3282,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir to: nil title: nil component: @"vtodo" - additionalFilters: @"c_status != 2 AND c_status != 3"]; + additionalFilters: @"c_status != 1 AND c_status != 3"]; activeTasks = [NSNumber numberWithInt:[tasksList count]]; From e7ddfb0546fcb70f1ac3401375656936ea00c380 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Wed, 11 Jun 2014 12:55:51 -0400 Subject: [PATCH 04/20] Fix for bug #2805 --- ActiveSync/SOGoActiveSyncDispatcher.m | 45 +++++++++++++++++++++------ NEWS | 1 + 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index e84e7f966..b98ce3bd2 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -1899,9 +1899,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. value = [theDocumentElement getElementsByTagName: @"ReplaceMime"]; - // ReplaceMime isn't specified so we must NOT use the server copy + // ReplaceMime IS specified so we must NOT use the server copy // but rather take the data as-is from the client. - if (![value count]) + if ([value count]) { [self processSendMail: theDocumentElement inResponse: theResponse]; @@ -1921,11 +1921,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSData *data; NGMimeMessageGenerator *generator; - NGMimeBodyPart *bodyPart; + NGMimeBodyPart *bodyPart; NGMutableHashMap *map; NGMimeFileData *fdata; NSException *error; - id body; + + id body, bodyFromSmartForward; userFolder = [[context activeUser] homeFolderInContext: context]; accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; @@ -1941,10 +1942,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. parser = [[NGMimeMessageParser alloc] init]; data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding]; messageFromSmartForward = [parser parsePartFromData: data]; - RELEASE(parser); - // We create a new MIME multipart/mixed message. The first part will be the text part // of our "smart forward" and the second part will be the message/rfc822 part of the // "smart forwarded" message. @@ -1954,11 +1953,39 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease]; body = [[[NGMimeMultipartBody alloc] initWithPart: messageToSend] autorelease]; - // First part + // First part - either a text/* or a multipart/*. If it's a multipart, + // we take the first part text/* part we see. map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease]; - [map setObject: @"text/plain" forKey: @"content-type"]; + bodyFromSmartForward = nil; + + if ([[messageFromSmartForward body] isKindOfClass: [NGMimeMultipartBody class]]) + { + NGMimeBodyPart *part; + NSArray *parts; + int i; + + parts = [[messageFromSmartForward body] parts]; + + for (i = 0; i < [parts count]; i++) + { + part = [parts objectAtIndex: i]; + + if ([[[part contentType] type] isEqualToString: @"text"]) + { + [map setObject: [[part contentType] stringValue] forKey: @"content-type"]; + bodyFromSmartForward = [part body]; + break; + } + } + } + else + { + [map setObject: [[messageFromSmartForward contentType] stringValue] forKey: @"content-type"]; + bodyFromSmartForward = [messageFromSmartForward body]; + } + bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease]; - [bodyPart setBody: [messageFromSmartForward body]]; + [bodyPart setBody: bodyFromSmartForward]; [body addBodyPart: bodyPart]; // Second part diff --git a/NEWS b/NEWS index fb1aa4abe..c535e992a 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ Bug fixes - better handling of empty "Flag" messages over ActiveSync (#2806) - fixed Chinese charset handling (#2809) - fixed folder name (calendars and contacts) of new subscriptions (#2801) + - fixed the reply/forward operation over ActiveSync (#2805) 2.2.5 (2014-06-05) ------------------ From 5bb64916c6fc96bf20bc258a075c33413784ca01 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 12 Jun 2014 09:09:08 -0400 Subject: [PATCH 05/20] Fix regression when attaching files to a reply --- NEWS | 1 + UI/MailerUI/UIxMailEditor.m | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index c535e992a..5eb1e8fd1 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Bug fixes - fixed Chinese charset handling (#2809) - fixed folder name (calendars and contacts) of new subscriptions (#2801) - fixed the reply/forward operation over ActiveSync (#2805) + - fixed regression when attaching files to a reply 2.2.5 (2014-06-05) ------------------ diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index 28de05922..f78843b53 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -644,8 +644,9 @@ static NSArray *infoKeys = nil; if (!attachmentAttrs || ![co imap4URL]) { [co fetchInfo]; - if (![co inReplyTo] && [co IMAP4ID] > -1) + if ((![co inReplyTo] || currentAttachment) && [co IMAP4ID] > -1) { + // When currentAttachment is defined, it means we just attached a new file to the mail mail = [[[SOGoMailObject alloc] initWithImap4URL: [co imap4URL] inContainer: [co container]] autorelease]; a = [mail fetchFileAttachmentKeys]; ASSIGN (attachmentAttrs, a); From d9b578b869da27b876f019bc10acf72839220fd3 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Jun 2014 09:52:29 -0400 Subject: [PATCH 06/20] Wait 20 seconds before deleting temporary forms Those temporary forms are created to download attachments. Fixes #2811 --- NEWS | 1 + UI/WebServerResources/MailerUI.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5eb1e8fd1..1764f7ccf 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,7 @@ Bug fixes - fixed folder name (calendars and contacts) of new subscriptions (#2801) - fixed the reply/forward operation over ActiveSync (#2805) - fixed regression when attaching files to a reply + - wait 20 seconds (instead of 2) before deleting temporary download forms (#2811) 2.2.5 (2014-06-05) ------------------ diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 2c0575995..4f87b2a84 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -1749,7 +1749,7 @@ function download(url) { setTimeout(function () { form.remove(); div.remove(); - }, 2000); + }, 20000); } function saveAttachment(event) { From 8202d0588fb8e1774e502941fc01223fb9005334 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 16 Jun 2014 10:20:02 -0400 Subject: [PATCH 07/20] Add documentation for SOGoSubscriptionFolderFormat Fixes #2799 --- Documentation/SOGo Installation Guide.odt | Bin 169561 -> 169764 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index aaaf940245d21228472dc67cf3b39e907702e435..068556826e55ba771794bdb9899daa2985594310 100644 GIT binary patch delta 48334 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 J$^U5e{{XXTUjYCB delta 48081 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 MKm{p~_>aZ^2mZGk@c;k- From 50c0b49a6fe210b438d2e5a7abac7219bdb15b8f Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 16 Jun 2014 11:00:39 -0400 Subject: [PATCH 08/20] Fix for bug #2813 --- NEWS | 1 + SoObjects/SOGo/SOGoGCSFolder.m | 29 ++++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index 1764f7ccf..3abc862b0 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ Bug fixes - fixed the reply/forward operation over ActiveSync (#2805) - fixed regression when attaching files to a reply - wait 20 seconds (instead of 2) before deleting temporary download forms (#2811) + - avoid raising exceptions when the db is down and we try to access the preferences module (#2813) 2.2.5 (2014-06-05) ------------------ diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 3f626bc61..b0110f58d 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -329,17 +329,24 @@ static NSArray *childRecordFields = nil; fc = [cm acquireOpenChannelForURL: folderLocation]; if (fc) { - sql - = [NSString stringWithFormat: (@"SELECT c_foldername FROM %@" - @" WHERE c_path = '%@'"), - [folderLocation gcsTableName], ocsPath]; - [fc evaluateExpressionX: sql]; - attrs = [fc describeResults: NO]; - row = [fc fetchAttributes: attrs withZone: NULL]; - if (row) - [self _setDisplayNameFromRow: row]; - [fc cancelFetch]; - [cm releaseChannel: fc]; + // We use an exception handler here in case the database is down when + // performing the query. This could have unexpected results. + NS_DURING + { + sql + = [NSString stringWithFormat: (@"SELECT c_foldername FROM %@" + @" WHERE c_path = '%@'"), + [folderLocation gcsTableName], ocsPath]; + [fc evaluateExpressionX: sql]; + attrs = [fc describeResults: NO]; + row = [fc fetchAttributes: attrs withZone: NULL]; + if (row) + [self _setDisplayNameFromRow: row]; + [fc cancelFetch]; + [cm releaseChannel: fc]; + } + NS_HANDLER; + NS_ENDHANDLER; } } From 333b561a5932acbe66d5b62c8963dd166b9de7f2 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 16 Jun 2014 15:30:26 -0400 Subject: [PATCH 09/20] Applied patch from bug #2736 --- SOPE/NGCards/NGCardsSaxHandler.m | 2 +- SOPE/NGCards/samples/vcf2xml.m | 8 ++++---- SoObjects/Mailer/NSString+Mail.m | 2 +- UI/MailPartViewers/UIxMailPartHTMLViewer.m | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/SOPE/NGCards/NGCardsSaxHandler.m b/SOPE/NGCards/NGCardsSaxHandler.m index 5314dee08..fca1a64e6 100644 --- a/SOPE/NGCards/NGCardsSaxHandler.m +++ b/SOPE/NGCards/NGCardsSaxHandler.m @@ -232,7 +232,7 @@ static NSArray *privilegedTagNames = nil; } - (void) characters: (unichar *) _chars - length: (int) _len + length: (NSUInteger) _len { if (_len && _chars) { diff --git a/SOPE/NGCards/samples/vcf2xml.m b/SOPE/NGCards/samples/vcf2xml.m index 3f56c2c88..31d61f026 100644 --- a/SOPE/NGCards/samples/vcf2xml.m +++ b/SOPE/NGCards/samples/vcf2xml.m @@ -217,10 +217,10 @@ printf("\n", [_localName cString]); } -- (void)characters:(unichar *)_chars length:(int)_len { +- (void)characters:(unichar *)_chars length:(NSUInteger)_len { NSString *str; id tmp; - unsigned i, len; + NSUInteger i, len; if (_len == 0) { [self indent]; @@ -228,7 +228,7 @@ return; } - for (i = 0; i < (unsigned)_len; i++) { + for (i = 0; i < _len; i++) { if (_chars[i] > 255) { NSLog(@"detected large char: o%04o d%03i h%04X", _chars[i], _chars[i], _chars[i]); @@ -246,7 +246,7 @@ [self indent]; printf("\"%s\"\n", [str cString]); } -- (void)ignorableWhitespace:(unichar *)_chars length:(int)_len { +- (void)ignorableWhitespace:(unichar *)_chars length:(NSUInteger)_len { NSString *data; id tmp; diff --git a/SoObjects/Mailer/NSString+Mail.m b/SoObjects/Mailer/NSString+Mail.m index 48c850b9e..1efdcb62f 100644 --- a/SoObjects/Mailer/NSString+Mail.m +++ b/SoObjects/Mailer/NSString+Mail.m @@ -430,7 +430,7 @@ } - (void) ignorableWhitespace: (unichar *) whitespaces - length: (int) length + length: (NSUInteger) length { showWhoWeAre(); } diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 0b525680b..7160f6ba2 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -419,9 +419,9 @@ static NSData* _sanitizeContent(NSData *theData) } - (void) _appendStyle: (unichar *) _chars - length: (int) _len + length: (NSUInteger) _len { - unsigned int count, length; + NSUInteger count, length; unichar *start, *currentChar; start = _chars; @@ -688,7 +688,7 @@ static NSData* _sanitizeContent(NSData *theData) } - (void) characters: (unichar *) _chars - length: (int) _len + length: (NSUInteger) _len { showWhoWeAre(); if (!ignoredContent) @@ -712,7 +712,7 @@ static NSData* _sanitizeContent(NSData *theData) } - (void) ignorableWhitespace: (unichar *) _chars - length: (int) _len + length: (NSUInteger) _len { showWhoWeAre(); } @@ -735,7 +735,7 @@ static NSData* _sanitizeContent(NSData *theData) /* SaxLexicalHandler */ - (void) comment: (unichar *) _chars - length: (int) _len + length: (NSUInteger) _len { showWhoWeAre(); if (inStyle) From e048346cb715d03fe6bd32d837b96107fdb6d44b Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Thu, 19 Jun 2014 16:08:15 -0400 Subject: [PATCH 10/20] Include, in our private NS, all ACLs defined on a calendar collectiob --- .../Appointments/SOGoAppointmentFolder.m | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 61cef70dc..c05eeb31f 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -230,6 +230,8 @@ static iCalEvent *iCalEventK = nil; abstract: NO withEquivalent: SoPerm_AddDocumentsImagesAndFiles asChildOf: davElement (@"write", XMLNS_WEBDAV)]; + + /* read-acl and write-acl are defined in RFC3744 */ [aclManager registerDAVPermission: davElement (@"admin", nsI) abstract: YES withEquivalent: nil @@ -242,6 +244,72 @@ static iCalEvent *iCalEventK = nil; abstract: YES withEquivalent: SoPerm_ChangePermissions asChildOf: davElement (@"admin", nsI)]; + + /* Default permissions for calendars. These are very important so that DAV client can + detect permission changes on calendars and reload all items, if necessary */ + + /* Public ones */ + [aclManager registerDAVPermission: davElement (@"viewwhole-public-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewWholePublicRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"viewdant-public-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewDAndTOfPublicRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"modify-public-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ModifyPublicRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"respondto-public-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_RespondToPublicRecords + asChildOf: davElement (@"admin", nsI)]; + + /* Private ones */ + [aclManager registerDAVPermission: davElement (@"viewwhole-private-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewWholePrivateRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"viewdant-private-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewDAndTOfPrivateRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"modify-private-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ModifyPrivateRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"respondto-private-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_RespondToPrivateRecords + asChildOf: davElement (@"admin", nsI)]; + + /* Condifential ones */ + [aclManager registerDAVPermission: davElement (@"viewwhole-confidential-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewWholeConfidentialRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"viewdant-confidential-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ViewDAndTOfConfidentialRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"modify-confidential-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_ModifyConfidentialRecords + asChildOf: davElement (@"admin", nsI)]; + + [aclManager registerDAVPermission: davElement (@"respondto-confidential-records", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_RespondToConfidentialRecords + asChildOf: davElement (@"admin", nsI)]; } return aclManager; From 9fa0b42e19c76184d4195a1530039dcad5cb5a80 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Fri, 20 Jun 2014 11:25:02 -0400 Subject: [PATCH 11/20] Ignore SCHEDULE-AGENT for Thunderbird/Lightning --- NEWS | 2 ++ .../Appointments/SOGoAppointmentObject.m | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 3abc862b0..42cc196d5 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ Bug fixes - fixed regression when attaching files to a reply - wait 20 seconds (instead of 2) before deleting temporary download forms (#2811) - avoid raising exceptions when the db is down and we try to access the preferences module (#2813) + - we now ignore the SCHEDULE-AGENT property when Thunderbird/Ligthning sends it to avoid + not-generating invitation responses for externally received IMIP messages 2.2.5 (2014-06-05) ------------------ diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 1712ec7ea..0e397928f 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -1428,9 +1428,11 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent // - (BOOL) _shouldScheduleEvent: (iCalPerson *) theOrganizer { + NSArray *userAgents; NSString *v; BOOL b; - + int i; + b = YES; if (theOrganizer && (v = [theOrganizer value: 0 ofAttribute: @"SCHEDULE-AGENT"])) @@ -1440,6 +1442,27 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent b = NO; } + // + // If we have to deal with Thunderbird/Lightning, we always send invitation + // reponses, as Lightning v2.6 (at least this version) sets SCHEDULE-AGENT + // to NONE/CLIENT when responding to an external invitation received by + // SOGo - so no invitation responses are ever sent by Lightning. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=865726 and + // https://bugzilla.mozilla.org/show_bug.cgi?id=997784 + // + userAgents = [[context request] headersForKey: @"User-Agent"]; + + for (i = 0; i < [userAgents count]; i++) + { + if ([[userAgents objectAtIndex: i] rangeOfString: @"Thunderbird"].location != NSNotFound && + [[userAgents objectAtIndex: i] rangeOfString: @"Lightning"].location != NSNotFound) + { + b = YES; + break; + } + } + + return b; } From 3523dc489f00c147279217faab9ad12504ca7340 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 23 Jun 2014 12:19:02 -0400 Subject: [PATCH 12/20] Fix for bug #2825 --- SoObjects/SOGo/GCSSpecialQueries+SOGoCacheObject.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoObjects/SOGo/GCSSpecialQueries+SOGoCacheObject.m b/SoObjects/SOGo/GCSSpecialQueries+SOGoCacheObject.m index b0e9eea52..cef17775b 100644 --- a/SoObjects/SOGo/GCSSpecialQueries+SOGoCacheObject.m +++ b/SoObjects/SOGo/GCSSpecialQueries+SOGoCacheObject.m @@ -72,7 +72,7 @@ = (@"CREATE TABLE %@ (" @" c_path VARCHAR(255) PRIMARY KEY," @" c_parent_path VARCHAR(255)," - @" c_type TINYINT NOT NULL," + @" c_type TINYINT UNSIGNED NOT NULL," @" c_creationdate INT NOT NULL," @" c_lastmodified INT NOT NULL," @" c_version INT NOT NULL DEFAULT 0," From 22f5ed62fef337f9fa2f84318e3c24962ee3c207 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Wed, 25 Jun 2014 10:14:28 -0400 Subject: [PATCH 13/20] Fixed tests regarding default permissions on CalDAV collections --- Tests/Integration/test-davacl.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Tests/Integration/test-davacl.py b/Tests/Integration/test-davacl.py index a254f25f9..a8a1a5bac 100755 --- a/Tests/Integration/test-davacl.py +++ b/Tests/Integration/test-davacl.py @@ -401,7 +401,17 @@ class DAVCalendarAclTest(DAVAclTest): else: expStatus = 207 privileges = self._currentUserPrivilegeSet(self.resource, expStatus) - self._comparePrivilegeSets(expectedPrivileges, privileges) + + # When comparing privileges on DAV collection, we remove all 'default' + # privileges on the collection. + privileges_set = set(privileges); + for x in ("public", "private", "confidential"): + privileges_set.discard("{urn:inverse:params:xml:ns:inverse-dav}viewwhole-%s-records" % x) + privileges_set.discard("{urn:inverse:params:xml:ns:inverse-dav}viewdant-%s-records" % x) + privileges_set.discard("{urn:inverse:params:xml:ns:inverse-dav}modify-%s-records" % x) + privileges_set.discard("{urn:inverse:params:xml:ns:inverse-dav}respondto-%s-records" %x) + + self._comparePrivilegeSets(expectedPrivileges, list(privileges_set)) def _testEventDAVAcl(self, event_class, right, error_code): icsClass = self.classToICSClass[event_class].lower() From 5419f411e5bae58cc17ab22b3b95a88efab74252 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Wed, 25 Jun 2014 15:05:25 -0400 Subject: [PATCH 14/20] Fix for bug #2734 --- ActiveSync/SOGoActiveSyncDispatcher+Sync.m | 63 +++++++++++++++++++--- ActiveSync/SOGoActiveSyncDispatcher.m | 40 ++++++++++++++ NEWS | 1 + 3 files changed, 98 insertions(+), 6 deletions(-) diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index 8c206baaf..024b2a2a7 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -126,6 +126,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [[o properties] removeObjectForKey: @"SyncKey"]; [[o properties] removeObjectForKey: @"SyncCache"]; [[o properties] removeObjectForKey: @"DateCache"]; + [[o properties] removeObjectForKey: @"MoreAvailable"]; [[o properties] addEntriesFromDictionary: theFolderMetadata]; [o save]; @@ -477,21 +478,70 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lastServerKey: (NSString **) theLastServerKey { - NSMutableDictionary *folderMetadata; + NSMutableDictionary *folderMetadata, *dateCache, *syncCache; NSMutableString *s; BOOL more_available; int i, max; + s = [NSMutableString string]; + + more_available = NO; + + if (theFolderType == ActiveSyncMailFolder && !([theSyncKey isEqualToString: @"-1"]) && theFilterType) + { + NSArray *allKeys; + NSString *key; + int softdelete_count; + + softdelete_count = 0; + + folderMetadata = [self _folderMetadataForKey: [theCollection nameInContainer]]; + dateCache = [folderMetadata objectForKey: @"DateCache"]; + syncCache = [folderMetadata objectForKey: @"SyncCache"]; + + allKeys = [dateCache allKeys]; + for (i = 0; i < [allKeys count]; i++) + { + key = [allKeys objectAtIndex: i]; + + if ([[dateCache objectForKey:key] compare: theFilterType] == NSOrderedAscending) + { + [s appendString: @""]; + [s appendFormat: @"%@", key]; + [s appendString: @""]; + + [syncCache removeObjectForKey: key]; + [dateCache removeObjectForKey: key]; + + softdelete_count++; + } + + if (softdelete_count >= theWindowSize) + { + [folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"]; + [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + + more_available = YES; + *theLastServerKey = theSyncKey; + + // Since WindowSize is reached don't even try to add more to the response, let's just + // jump to the end and return the response immediately + goto return_response; + } + } + + [folderMetadata removeObjectForKey: @"MoreAvailable"]; + [self _setFolderMetadata: folderMetadata forKey: [theCollection nameInContainer]]; + } + // // No changes in the collection - 2.2.2.19.1.1 Empty Sync Request. // We check this and we don't generate any commands if we don't have to. // - if ([theSyncKey isEqualToString: [theCollection davCollectionTag]]) + if ([theSyncKey isEqualToString: [theCollection davCollectionTag]] && !([s length])) return; - s = [NSMutableString string]; - more_available = NO; switch (theFolderType) @@ -614,7 +664,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. case ActiveSyncMailFolder: default: { - NSMutableDictionary *syncCache, *dateCache; SOGoSyncCacheObject *lastCacheObject, *aCacheObject; NSMutableArray *allCacheObjects, *sortedBySequence; @@ -644,6 +693,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"]; [folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"]; } + // Check whether GUID in cache is equal to the GUID from imap - this is to avoid cache corruptions if a folder has been renamed and a new folder // with the same name has been created but folderSync has not yet updated the cache if (!([[theCollection nameInContainer] isEqualToString: @@ -805,6 +855,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. break; } // switch (folderType) ... + return_response: + if ([s length]) { [theBuffer appendString: @""]; @@ -1008,7 +1060,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. davCollectionTag = [collection davCollectionTag]; } - // Generate the response buffer [theBuffer appendString: @""]; diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index b98ce3bd2..82c1868fc 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import #import #import +#import #import #import #import @@ -170,6 +171,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. return [o properties]; } +- (unsigned int) _softDeleteCountWithFilter: (NSCalendarDate *) theFilter + collectionId: (NSString *) theCollectionId +{ + NSMutableDictionary *dateCache; + NSMutableArray *sdUids; + SOGoCacheGCSObject *o; + NSArray *allKeys; + NSString *key; + + int i; + + sdUids = [NSMutableArray array]; + + if (theFilter) + { + o = [SOGoCacheGCSObject objectWithName: [NSString stringWithFormat: @"%@+folder%@", [context objectForKey: @"DeviceId"], theCollectionId] inContainer: nil]; + [o setObjectType: ActiveSyncGlobalCacheObject]; + [o setTableUrl: [self folderTableURL]]; + [o reloadIfNeeded]; + + dateCache = [[o properties] objectForKey: @"DateCache"]; + allKeys = [dateCache allKeys]; + + for (i = 0; i < [allKeys count]; i++) + { + key = [allKeys objectAtIndex: i]; + + if ([[dateCache objectForKey:key] compare: theFilter ] == NSOrderedAscending) + [sdUids addObject: [dateCache objectForKey:key]]; + } + } + + return [sdUids count]; +} + - (id) globallyUniqueIDToIMAPFolderName: (NSString *) theIdToTranslate type: (SOGoMicrosoftActiveSyncFolderType) theFolderType { @@ -919,6 +955,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sortOrdering: @"REVERSE ARRIVAL" threaded: NO]; count = [uids count]; + + // Add the number of UIDs expected to "soft delete" + count += [self _softDeleteCountWithFilter: filter collectionId: realCollectionId]; + } else { diff --git a/NEWS b/NEWS index 42cc196d5..46be9433c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Enhancements - contacts photos are now synchronized using ActiveSync (#2807) - implemented the GetAttachment ActiveSync command (#2808) - implemented the Ping ActiveSync command + - added "soft deletes" support for ActiveSync (#2734) Bug fixes - better handling of empty "Flag" messages over ActiveSync (#2806) From b6be4e6e2fb8e00c8f0b29e4f493936d0fcfbb2e Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Thu, 26 Jun 2014 11:01:16 -0400 Subject: [PATCH 15/20] Applied patch from bug #2810 --- ActiveSync/SOGoMailObject+ActiveSync.m | 37 ++++++++++++++++++-------- NEWS | 1 + 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/ActiveSync/SOGoMailObject+ActiveSync.m b/ActiveSync/SOGoMailObject+ActiveSync.m index 58dca5cf1..e5f349092 100644 --- a/ActiveSync/SOGoMailObject+ActiveSync.m +++ b/ActiveSync/SOGoMailObject+ActiveSync.m @@ -238,6 +238,8 @@ struct GlobalObjectId { if (key) { + NSString *s, *charset; + d = [[self fetchPlainTextParts] objectForKey: key]; encoding = [[self lookupInfoForBodyPart: key] objectForKey: @"encoding"]; @@ -246,6 +248,14 @@ struct GlobalObjectId { d = [d dataByDecodingBase64]; else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame) d = [d dataByDecodingQuotedPrintableTransferEncoding]; + + charset = [[[self lookupInfoForBodyPart: key] objectForKey: @"parameterList"] objectForKey: @"charset"]; + + if (![charset length]) + charset = @"us-ascii"; + + s = [NSString stringWithData: d usingEncodingNamed: charset]; + d = [s dataUsingEncoding: NSUTF8StringEncoding]; } return d; @@ -296,13 +306,13 @@ struct GlobalObjectId { if ([body isKindOfClass: [NSData class]]) { NSString *charset; - int encoding; - + charset = [[thePart contentType] valueOfParameter: @"charset"]; - encoding = [NGMimeType stringEncodingForCharset: charset]; + + if (![charset length]) + charset = @"us-ascii"; - s = [[NSString alloc] initWithData: body encoding: encoding]; - AUTORELEASE(s); + s = [NSString stringWithData: body usingEncodingNamed: charset]; } else { @@ -396,6 +406,13 @@ struct GlobalObjectId { { if ([type isEqualToString: @"text"]) { + NSString *s, *charset; + + charset = [[[self lookupInfoForBodyPart: @""] objectForKey: @"parameterList"] objectForKey: @"charset"]; + + if (![charset length]) + charset = @"us-ascii"; + d = [[self fetchPlainTextParts] objectForKey: @""]; // We check if we have base64 encoded parts. If so, we just @@ -407,17 +424,15 @@ struct GlobalObjectId { else if ([encoding caseInsensitiveCompare: @"quoted-printable"] == NSOrderedSame) d = [d dataByDecodingQuotedPrintableTransferEncoding]; + s = [NSString stringWithData: d usingEncodingNamed: charset]; + // Check if we must convert html->plain if (theType == 1 && [subtype isEqualToString: @"html"]) { - NSString *s; - - s = [[NSString alloc] initWithData: d encoding: NSUTF8StringEncoding]; - AUTORELEASE(s); - s = [s htmlToText]; - d = [s dataUsingEncoding: NSUTF8StringEncoding]; } + + d = [s dataUsingEncoding: NSUTF8StringEncoding]; } else if ([type isEqualToString: @"multipart"]) { diff --git a/NEWS b/NEWS index 46be9433c..d83925097 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ Bug fixes - avoid raising exceptions when the db is down and we try to access the preferences module (#2813) - we now ignore the SCHEDULE-AGENT property when Thunderbird/Ligthning sends it to avoid not-generating invitation responses for externally received IMIP messages + - improved charset handling over ActiveSync (#2810) 2.2.5 (2014-06-05) ------------------ From 302e40a1c3c1f13578499d82e40c75e50beff79e Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Thu, 26 Jun 2014 16:08:47 -0400 Subject: [PATCH 16/20] bugFix#2823 --- SoObjects/Mailer/SOGoDraftObject.m | 20 ++++----- SoObjects/SOGo/SOGoParentFolder.m | 41 ++++++++++++------- UI/PreferencesUI/UIxPreferences.m | 30 +++++++------- UI/Templates/PreferencesUI/UIxPreferences.wox | 3 +- UI/WebServerResources/UIxPreferences.js | 12 +++++- 5 files changed, 64 insertions(+), 42 deletions(-) diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 7fd1a4c35..4d0f9aa38 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -1761,26 +1761,26 @@ static NSString *userAgent = nil; { SOGoUserDefaults *ud; ud = [[context activeUser] userDefaults]; - + if ([ud mailAddOutgoingAddresses]) { + Class contactGCSEntry; SOGoContactFolders *contactFolders; - NGMailAddressParser *parser; - id parsedRecipient; SOGoContactFolder *folder; SOGoContactGCSEntry *newContact; NGVCard *card; - Class contactGCSEntry; + NGMailAddressParser *parser; + NSArray *matchingContacts; NSMutableArray *recipients; NSString *recipient, *emailAddress, *addressBook, *uid; - NSArray *matchingContacts; + id parsedRecipient; int i; - + // Get all the addressbooks contactFolders = [[[context activeUser] homeFolderInContext: context] - lookupName: @"Contacts" - inContext: context - acquire: NO]; + lookupName: @"Contacts" + inContext: context + acquire: NO]; // Get all the recipients from the current email recipients = [self allRecipients]; for (i = 0; i < [recipients count]; i++) @@ -1790,7 +1790,7 @@ static NSString *userAgent = nil; parser = [NGMailAddressParser mailAddressParserWithString: recipient]; parsedRecipient = [parser parse]; emailAddress = [parsedRecipient address]; - + matchingContacts = [contactFolders allContactsFromFilter: emailAddress excludeGroups: YES excludeLists: YES]; diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index 4c7c7c31a..164296b83 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -164,34 +164,45 @@ static SoSecurityManager *sm = nil; NSString *folderName; SOGoGCSFolder *folder; SOGoUser *folderOwner; - + SOGoUserDefaults *ud; + roles = [[context activeUser] rolesForObject: self inContext: context]; folderOwner = [SOGoUser userWithLogin: [self ownerInContext: context]]; - + + // We autocreate the calendars if the user is the owner, a superuser or // if it's a resource as we won't necessarily want to login as a resource // in order to create its database tables. // FolderType is an enum where 0 = Personal and 1 = collected if ([roles containsObject: SoRole_Owner] || (folderOwner && [folderOwner isResource])) + { + if (folderType == SOGoPersonalFolder) { - if (folderType == SOGoPersonalFolder) - { - folderName = @"personal"; - folder = [subFolderClass objectWithName: folderName inContainer: self]; - [folder setDisplayName: [self defaultFolderName]]; - } - else if (folderType == SOGoCollectedFolder) - { - folderName = @"collected"; - folder = [subFolderClass objectWithName: folderName inContainer: self]; - [folder setDisplayName: [self collectedFolderName]]; - } + folderName = @"personal"; + folder = [subFolderClass objectWithName: folderName inContainer: self]; + [folder setDisplayName: [self defaultFolderName]]; [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", OCSPath, folderName]]; if ([folder create]) - [subFolders setObject: folder forKey: folderName]; + [subFolders setObject: folder forKey: folderName]; } + else if (folderType == SOGoCollectedFolder) + { + ud = [[context activeUser] userDefaults]; + if ([ud mailAddOutgoingAddresses]) { + folderName = @"collected"; + folder = [subFolderClass objectWithName: folderName inContainer: self]; + [folder setDisplayName: [self collectedFolderName]]; + [folder setOCSPath: [NSString stringWithFormat: @"%@/%@", OCSPath, folderName]]; + + if ([folder create]) + [subFolders setObject: folder forKey: folderName]; + + [ud setSelectedAddressBook:folderName]; + } + } + } } - (NSException *) fetchSpecialFolders: (NSString *) sql diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 54c0df6b8..c9c42f88a 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -699,47 +699,49 @@ static NSArray *reminderValues = nil; /* We want all the SourceIDS */ NSMutableArray *folders, *availableAddressBooksID, *availableAddressBooksName; SOGoParentFolder *contactFolders; - + int i, count; BOOL collectedAlreadyExist; - + contactFolders = [[[context activeUser] homeFolderInContext: context] lookupName: @"Contacts" inContext: context acquire: NO]; folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; count = [folders count]-1; - + // Inside this loop we remove all the public or shared addressbooks for (; count >= 0; count--) { if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) - [folders removeObjectAtIndex: count]; + [folders removeObjectAtIndex: count]; } - + // Parse the objects in order to have only the displayName of the addressbooks to be displayed on the preferences interface availableAddressBooksID = [NSMutableArray arrayWithCapacity: [folders count]]; availableAddressBooksName = [NSMutableArray arrayWithCapacity: [folders count]]; count = [folders count]-1; collectedAlreadyExist = NO; - + for (i = 0; i <= count ; i++) { [availableAddressBooksID addObject:[[folders objectAtIndex:i] realNameInContainer]]; [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; - + if ([[availableAddressBooksID objectAtIndex:i] isEqualToString: @"collected"]) - collectedAlreadyExist = YES; + collectedAlreadyExist = YES; } // Create the dictionary for the next function : itemAddressBookText. if (!addressBooksIDWithDisplayName) + { addressBooksIDWithDisplayName = [[NSMutableDictionary alloc] initWithObjects:availableAddressBooksName forKeys:availableAddressBooksID]; - if (!collectedAlreadyExist) - { - [availableAddressBooksID addObject: @"collected"]; - [addressBooksIDWithDisplayName setObject: [self labelForKey: @"Collected Address Book"] forKey: @"collected"]; - } - + } + if (!collectedAlreadyExist) + { + [availableAddressBooksID addObject: @"collected"]; + [addressBooksIDWithDisplayName setObject: [self labelForKey: @"Collected Address Book"] forKey: @"collected"]; + } + return availableAddressBooksID; } - (NSString *) itemAddressBookText diff --git a/UI/Templates/PreferencesUI/UIxPreferences.wox b/UI/Templates/PreferencesUI/UIxPreferences.wox index fbfc0b30a..9cc6675a2 100644 --- a/UI/Templates/PreferencesUI/UIxPreferences.wox +++ b/UI/Templates/PreferencesUI/UIxPreferences.wox @@ -299,7 +299,8 @@
    + var:checked="addOutgoingAddresses" + onChange = "onAddOutgoingAddressesCheck(this);"/>
    Date: Thu, 26 Jun 2014 16:42:05 -0400 Subject: [PATCH 17/20] applied comments --- SoObjects/Appointments/SOGoAppointmentFolder.m | 2 +- UI/Scheduler/UIxCalendarSelector.m | 2 -- UI/WebServerResources/SchedulerUI.js | 8 +++++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 0a8746083..6f759a137 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -3282,7 +3282,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir to: nil title: nil component: @"vtodo" - additionalFilters: @"c_status != 2 AND c_status != 3"]; + additionalFilters: @"c_status != 1 AND c_status != 3"]; activeTasks = [NSNumber numberWithInt:[tasksList count]]; diff --git a/UI/Scheduler/UIxCalendarSelector.m b/UI/Scheduler/UIxCalendarSelector.m index fd9e99c76..2c8a6910d 100644 --- a/UI/Scheduler/UIxCalendarSelector.m +++ b/UI/Scheduler/UIxCalendarSelector.m @@ -121,8 +121,6 @@ _intValueFromHex (NSString *hexString) [calendar setObject: [folder ownerInContext: context] forKey: @"owner"]; fActiveTasks = [folder activeTasks]; - if (fActiveTasks == nil) - fActiveTasks = 0; [calendar setObject:fActiveTasks forKey:@"activeTasks" ]; [calendars addObject: calendar]; } diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index ec3d7ce81..d69d69830 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -2915,7 +2915,13 @@ function initCalendarSelector() { var input = items[i].childNodesWithTag("input")[0]; var activeTasks = items[i].childNodesWithTag("span")[0]; $(input).observe("click", clickEventWrapper(updateCalendarStatus)); - $(activeTasks).innerHTML = "(" + activeTasks.innerText + ")"; + if (activeTasks.textContent == "0") { + activeTasks.innerHTML = ""; + } + else { + activeTasks.innerHTML = "(" + activeTasks.innerText + ")"; + } + } var links = $("calendarSelectorButtons").childNodesWithTag("a"); From 5b61df8ca4035d3bd66bb024a1f5b62cd6054a84 Mon Sep 17 00:00:00 2001 From: Alexandre Cloutier Date: Fri, 27 Jun 2014 17:00:32 -0400 Subject: [PATCH 18/20] activeTasks updates dynamically --- UI/Scheduler/UIxCalListingActions.m | 24 +- UI/Scheduler/product.plist | 5 + UI/WebServerResources/SchedulerUI.js | 327 +++++++++++++++------------ 3 files changed, 205 insertions(+), 151 deletions(-) diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m index 8670dc383..b7c1eddc7 100644 --- a/UI/Scheduler/UIxCalListingActions.m +++ b/UI/Scheduler/UIxCalListingActions.m @@ -480,7 +480,7 @@ static NSArray *tasksFields = nil; return infos; } -- (WOResponse *) _responseWithData: (NSArray *) data +- (WOResponse *) _responseWithData: (id) data { WOResponse *response; @@ -1208,4 +1208,26 @@ _computeBlocksPosition (NSArray *blocks) return [self _responseWithData: filteredTasks]; } +- (WOResponse *) activeTasksAction +{ + SOGoAppointmentFolders *co; + SOGoAppointmentFolder *folder; + NSArray *folders; + NSNumber *tasksCount, *foldersCount; + NSString *calendarID; + NSMutableDictionary *activeTasksByCalendars; + + co = [self clientObject]; + folders = [co subFolders]; + foldersCount = [folders count]; + activeTasksByCalendars = [NSMutableDictionary dictionaryWithCapacity:foldersCount]; + for (folder in folders) { + tasksCount = [folder activeTasks]; + calendarID = [folder nameInContainer]; + [activeTasksByCalendars setObject:tasksCount forKey:calendarID]; + } + + return [self _responseWithData: activeTasksByCalendars]; +} + @end diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index 417b9e2d6..aab66ebfc 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -94,6 +94,11 @@ actionClass = "UIxCalListingActions"; actionName = "tasksList"; }; + activeTasks = { + protectedBy = "View"; + actionClass = "UIxCalListingActions"; + actionName = "activeTasks"; + }; dayview = { protectedBy = "View"; pageName = "UIxCalDayView"; diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index d69d69830..33d179daa 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1085,142 +1085,166 @@ function eventsListCallback(http) { log ("eventsListCallback Ajax error"); } -function tasksListCallback(http) { - if (http.readyState == 4 - && http.status == 200) { - var div = $("tasksListView"); - document.tasksListAjaxRequest = null; - var table = $("tasksList"); - lastClickedRow = -1; // from generic.js - - var rows = table.select("TBODY TR"); - rows.each(function(e) { - e.remove(); - }); - - if (http.responseText.length > 0) { - var data = http.responseText.evalJSON(true); - - // [0] Task ID - // [1] Calendar ID - // [2] Calendar name - // [3] Status (0, 1 = completed, 2) - // [4] Title - // [5] Due date (int) - // [6] Classification (0 = public, 1, = private, 2 = confidential) - // [7] Location - // [8] Category - // [9] Editable? - // [10] Erasable? - // [11] Priority (0, 1 = important, 9 = low) - // [12] Status CSS class (duelater, completed, etc) - // (13) Due date (formatted) - - for (var i = 0; i < data.length; i++) { - var row = createElement("tr"); - table.tBodies[0].appendChild(row); - - row.on("dblclick", editDoubleClickedEvent); - - var calendar = escape(data[i][1]); - var cname = escape(data[i][0]); - row.setAttribute("id", calendar + "-" + cname); - //listItem.addClassName(data[i][5]); // Classification - row.addClassName(data[i][12]); // status - row.calendar = calendar; - row.cname = cname; - row.erasable = data[i][10] || IsSuperUser; - if (parseInt(data[i][11]) == 1) { - row.addClassName("important"); - } - else if (parseInt(data[i][11]) == 9) { - row.addClassName("low"); - } - - var cell = createElement("td"); - row.appendChild(cell); - var input = createElement("input"); - input.setAttribute("type", "checkbox"); - cell.appendChild(input); - input.setAttribute("value", "1"); - if (parseInt(data[i][9]) == 0) // editable? - input.setAttribute("disabled", true); - input.addClassName("checkBox"); - if (parseInt(data[i][3]) == 1) // completed? - input.setAttribute("checked", "checked"); - input.observe("click", updateTaskStatus, true); - - cell = createElement("td"); - row.appendChild(cell); - if (data[i][11] != null) { - cell.update(_("prio_" + data[i][11])); // Priority - } - else { - cell.update(""); // Priority - } - - cell = createElement("td"); - row.appendChild(cell); - var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar); - cell.appendChild(colorDiv); - colorDiv.update(' '); - var t = new Element ("span"); - cell.appendChild(t); - t.update(data[i][4]); // title - - cell = createElement("td"); - row.appendChild(cell); - if (data[i][13]) - cell.update(data[i][13]); // end date - - cell = createElement("td"); - row.appendChild(cell); - cell.update(data[i][7]); // location - - cell = createElement("td"); - row.appendChild(cell); - cell.update(data[i][8]); // category - - cell = createElement("td"); - row.appendChild(cell); - cell.update(data[i][2]); // calendar name - } - - table.scrollTop = table.previousScroll; - - if (sorting["task-attribute"] && sorting["task-attribute"].length > 0) { - var sortHeader = $(sorting["task-header"]); - - if (sortHeader) { - var sortImages = $(table.tHead).select(".sortImage"); - $(sortImages).each(function(item) { - item.remove(); - }); - - var sortImage = createElement("img", "messageSortImage", "sortImage"); - sortHeader.insertBefore(sortImage, sortHeader.firstChild); - if (sorting["task-ascending"]) - sortImage.src = ResourcesURL + "/arrow-up.png"; - else - sortImage.src = ResourcesURL + "/arrow-down.png"; - } - } - if (http.callbackData) { - var selectedNodesId = http.callbackData; - for (var i = 0; i < selectedNodesId.length; i++) { - // log(selectedNodesId[i] + " (" + i + ") is selected"); - var node = $(selectedNodesId[i]); - if (node) { - node.selectElement(); - } - } - } - else - log ("tasksListCallback: no data"); +function activeTasksCallback(http) { + if (http.readyState == 4 && http.status == 200) { + if (http.responseText.length > 0) { + var data = http.responseText.evalJSON(true); + var list = $("calendarList"); + + var items = list.childNodesWithTag("li"); + for (var i = 0; i < items.length; i++) { + var id = items[i].getAttribute("id").substr(1); + var number = data[id]; + var input = items[i].childNodesWithTag("input")[0]; + var activeTasks = items[i].childNodesWithTag("span")[0]; + $(input).observe("click", clickEventWrapper(updateCalendarStatus)); + if (number == "0") { + activeTasks.innerHTML = ""; } + else { + activeTasks.innerHTML = "(" + number + ")"; + } + } } - else - log ("tasksListCallback Ajax error"); + } +} + +function tasksListCallback(http) { + if (http.readyState == 4 + && http.status == 200) { + var div = $("tasksListView"); + document.tasksListAjaxRequest = null; + var table = $("tasksList"); + lastClickedRow = -1; // from generic.js + + var rows = table.select("TBODY TR"); + rows.each(function(e) { + e.remove(); + }); + + if (http.responseText.length > 0) { + var data = http.responseText.evalJSON(true); + + // [0] Task ID + // [1] Calendar ID + // [2] Calendar name + // [3] Status (0, 1 = completed, 2) + // [4] Title + // [5] Due date (int) + // [6] Classification (0 = public, 1, = private, 2 = confidential) + // [7] Location + // [8] Category + // [9] Editable? + // [10] Erasable? + // [11] Priority (0, 1 = important, 9 = low) + // [12] Status CSS class (duelater, completed, etc) + // (13) Due date (formatted) + + for (var i = 0; i < data.length; i++) { + var row = createElement("tr"); + table.tBodies[0].appendChild(row); + + row.on("dblclick", editDoubleClickedEvent); + + var calendar = escape(data[i][1]); + var cname = escape(data[i][0]); + row.setAttribute("id", calendar + "-" + cname); + //listItem.addClassName(data[i][5]); // Classification + row.addClassName(data[i][12]); // status + row.calendar = calendar; + row.cname = cname; + row.erasable = data[i][10] || IsSuperUser; + if (parseInt(data[i][11]) == 1) { + row.addClassName("important"); + } + else if (parseInt(data[i][11]) == 9) { + row.addClassName("low"); + } + + var cell = createElement("td"); + row.appendChild(cell); + var input = createElement("input"); + input.setAttribute("type", "checkbox"); + cell.appendChild(input); + input.setAttribute("value", "1"); + if (parseInt(data[i][9]) == 0) // editable? + input.setAttribute("disabled", true); + input.addClassName("checkBox"); + if (parseInt(data[i][3]) == 1) // completed? + input.setAttribute("checked", "checked"); + input.observe("click", updateTaskStatus, true); + + cell = createElement("td"); + row.appendChild(cell); + if (data[i][11] != null) { + cell.update(_("prio_" + data[i][11])); // Priority + } + else { + cell.update(""); // Priority + } + + cell = createElement("td"); + row.appendChild(cell); + var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar); + cell.appendChild(colorDiv); + colorDiv.update(' '); + var t = new Element ("span"); + cell.appendChild(t); + t.update(data[i][4]); // title + + cell = createElement("td"); + row.appendChild(cell); + if (data[i][13]) + cell.update(data[i][13]); // end date + + cell = createElement("td"); + row.appendChild(cell); + cell.update(data[i][7]); // location + + cell = createElement("td"); + row.appendChild(cell); + cell.update(data[i][8]); // category + + cell = createElement("td"); + row.appendChild(cell); + cell.update(data[i][2]); // calendar name + } + + table.scrollTop = table.previousScroll; + + if (sorting["task-attribute"] && sorting["task-attribute"].length > 0) { + var sortHeader = $(sorting["task-header"]); + + if (sortHeader) { + var sortImages = $(table.tHead).select(".sortImage"); + $(sortImages).each(function(item) { + item.remove(); + }); + + var sortImage = createElement("img", "messageSortImage", "sortImage"); + sortHeader.insertBefore(sortImage, sortHeader.firstChild); + if (sorting["task-ascending"]) + sortImage.src = ResourcesURL + "/arrow-up.png"; + else + sortImage.src = ResourcesURL + "/arrow-down.png"; + } + } + if (http.callbackData) { + var selectedNodesId = http.callbackData; + for (var i = 0; i < selectedNodesId.length; i++) { + // log(selectedNodesId[i] + " (" + i + ") is selected"); + var node = $(selectedNodesId[i]); + if (node) { + node.selectElement(); + } + } + } + else + log ("tasksListCallback: no data"); + } + } + else + log ("tasksListCallback Ajax error"); } /* in dateselector */ @@ -2193,22 +2217,25 @@ function _loadEventHref(href) { } function _loadTasksHref(href) { - if (document.tasksListAjaxRequest) { - document.tasksListAjaxRequest.aborted = true; - document.tasksListAjaxRequest.abort(); - } - url = ApplicationBaseURL + "/" + href; - - var tasksList = $("tasksList"); - var selectedIds; - if (tasksList) - selectedIds = tasksList.getSelectedNodesId(); - else - selectedIds = null; - document.tasksListAjaxRequest - = triggerAjaxRequest(url, tasksListCallback, selectedIds); - - return true; + if (document.tasksListAjaxRequest) { + document.tasksListAjaxRequest.aborted = true; + document.tasksListAjaxRequest.abort(); + } + url = ApplicationBaseURL + "/" + href; + urlActiveTasks = ApplicationBaseURL + "/activeTasks"; + + var tasksList = $("tasksList"); + var selectedIds; + if (tasksList) + selectedIds = tasksList.getSelectedNodesId(); + else + selectedIds = null; + + document.tasksListAjaxRequest = triggerAjaxRequest(url, tasksListCallback, selectedIds); + + triggerAjaxRequest(urlActiveTasks, activeTasksCallback); + + return true; } function onHeaderClick(event) { From 6da03bc75ca64a79785001897eb629b6250b2cb8 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Sat, 28 Jun 2014 08:31:07 -0400 Subject: [PATCH 19/20] Cleaned up code for older gcc --- UI/Scheduler/UIxCalListingActions.m | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m index b7c1eddc7..2a579be5f 100644 --- a/UI/Scheduler/UIxCalListingActions.m +++ b/UI/Scheduler/UIxCalListingActions.m @@ -1,9 +1,6 @@ /* UIxCalListingActions.m - this file is part of SOGo * - * Copyright (C) 2006-2011 Inverse inc. - * - * Author: Wolfgang Sourdeau - * Francis Lachapelle + * Copyright (C) 2006-2014 Inverse inc. * * 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 @@ -1210,21 +1207,23 @@ _computeBlocksPosition (NSArray *blocks) - (WOResponse *) activeTasksAction { - SOGoAppointmentFolders *co; - SOGoAppointmentFolder *folder; - NSArray *folders; - NSNumber *tasksCount, *foldersCount; - NSString *calendarID; NSMutableDictionary *activeTasksByCalendars; + SOGoAppointmentFolder *folder; + SOGoAppointmentFolders *co; + NSArray *folders; + + int i; co = [self clientObject]; folders = [co subFolders]; - foldersCount = [folders count]; - activeTasksByCalendars = [NSMutableDictionary dictionaryWithCapacity:foldersCount]; - for (folder in folders) { - tasksCount = [folder activeTasks]; - calendarID = [folder nameInContainer]; - [activeTasksByCalendars setObject:tasksCount forKey:calendarID]; + activeTasksByCalendars = [NSMutableDictionary dictionaryWithCapacity: [folders count]]; + + for (i = 0; i < [folders count]; i++) + { + folder = [folders objectAtIndex: i]; + + [activeTasksByCalendars setObject: [folder activeTasks] + forKey: [folder nameInContainer]]; } return [self _responseWithData: activeTasksByCalendars]; From ff015afde8700b0a4163c89ce4b9cdca5f6261e5 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 30 Jun 2014 10:35:55 -0400 Subject: [PATCH 20/20] Fixed indent --- UI/PreferencesUI/UIxPreferences.m | 70 ++++++++++++++++--------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index c9c42f88a..0900c4d3a 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -74,7 +74,7 @@ static NSArray *reminderValues = nil; if (!reminderItems && !reminderValues) { reminderItems = [NSArray arrayWithObjects: - @"5_MINUTES_BEFORE", + @"5_MINUTES_BEFORE", @"10_MINUTES_BEFORE", @"15_MINUTES_BEFORE", @"30_MINUTES_BEFORE", @@ -90,7 +90,7 @@ static NSArray *reminderValues = nil; @"1_WEEK_BEFORE", nil]; reminderValues = [NSArray arrayWithObjects: - @"-PT5M", + @"-PT5M", @"-PT10M", @"-PT15M", @"-PT30M", @@ -704,18 +704,18 @@ static NSArray *reminderValues = nil; BOOL collectedAlreadyExist; contactFolders = [[[context activeUser] homeFolderInContext: context] - lookupName: @"Contacts" - inContext: context - acquire: NO]; + lookupName: @"Contacts" + inContext: context + acquire: NO]; folders = [NSMutableArray arrayWithArray: [contactFolders subFolders]]; count = [folders count]-1; // Inside this loop we remove all the public or shared addressbooks for (; count >= 0; count--) - { - if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) - [folders removeObjectAtIndex: count]; - } + { + if (![[folders objectAtIndex: count] isKindOfClass: [SOGoContactGCSFolder class]]) + [folders removeObjectAtIndex: count]; + } // Parse the objects in order to have only the displayName of the addressbooks to be displayed on the preferences interface availableAddressBooksID = [NSMutableArray arrayWithCapacity: [folders count]]; @@ -723,27 +723,29 @@ static NSArray *reminderValues = nil; count = [folders count]-1; collectedAlreadyExist = NO; - for (i = 0; i <= count ; i++) { - [availableAddressBooksID addObject:[[folders objectAtIndex:i] realNameInContainer]]; - [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; - - if ([[availableAddressBooksID objectAtIndex:i] isEqualToString: @"collected"]) - collectedAlreadyExist = YES; - } + for (i = 0; i <= count ; i++) + { + [availableAddressBooksID addObject:[[folders objectAtIndex:i] realNameInContainer]]; + [availableAddressBooksName addObject:[[folders objectAtIndex:i] displayName]]; + + if ([[availableAddressBooksID objectAtIndex:i] isEqualToString: @"collected"]) + collectedAlreadyExist = YES; + } // Create the dictionary for the next function : itemAddressBookText. if (!addressBooksIDWithDisplayName) - { - addressBooksIDWithDisplayName = [[NSMutableDictionary alloc] initWithObjects:availableAddressBooksName - forKeys:availableAddressBooksID]; - } + { + addressBooksIDWithDisplayName = [[NSMutableDictionary alloc] initWithObjects:availableAddressBooksName + forKeys:availableAddressBooksID]; + } if (!collectedAlreadyExist) - { - [availableAddressBooksID addObject: @"collected"]; - [addressBooksIDWithDisplayName setObject: [self labelForKey: @"Collected Address Book"] forKey: @"collected"]; - } + { + [availableAddressBooksID addObject: @"collected"]; + [addressBooksIDWithDisplayName setObject: [self labelForKey: @"Collected Address Book"] forKey: @"collected"]; + } return availableAddressBooksID; } + - (NSString *) itemAddressBookText { return [addressBooksIDWithDisplayName objectForKey: item]; @@ -931,7 +933,7 @@ static NSArray *reminderValues = nil; capabilities = [[self sieveClient] capabilities]; else capabilities = [NSArray array]; - [capabilities retain]; + [capabilities retain]; } return [capabilities jsonRepresentation]; @@ -1222,12 +1224,12 @@ static NSArray *reminderValues = nil; SOGoSieveManager *manager; if (!client) - { - folder = [[self clientObject] mailAccountsFolder: @"Mail" inContext: context]; - account = [folder lookupName: @"0" inContext: context acquire: NO]; - manager = [SOGoSieveManager sieveManagerForUser: [context activeUser]]; - client = [[manager clientForAccount: account] retain]; - } + { + folder = [[self clientObject] mailAccountsFolder: @"Mail" inContext: context]; + account = [folder lookupName: @"0" inContext: context acquire: NO]; + manager = [SOGoSieveManager sieveManagerForUser: [context activeUser]]; + client = [[manager clientForAccount: account] retain]; + } return client; } @@ -1275,9 +1277,9 @@ static NSArray *reminderValues = nil; results = [self responseWithStatus: 502 andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Connection error", @"textStatus", nil]]; } - else - results = [self responseWithStatus: 503 - andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"textStatus", nil]]; + else + results = [self responseWithStatus: 503 + andJSONRepresentation: [NSDictionary dictionaryWithObjectsAndKeys: @"Service temporarily unavailable", @"textStatus", nil]]; } else results = self;