From 439248ee89ff5a567c64a9b35c5b0cd4e726442a Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Mon, 28 May 2012 20:30:35 +0000 Subject: [PATCH 1/6] See ChangeLog. Monotone-Parent: a7e3713b79d3ec5043152d79550eec23b2ff854f Monotone-Revision: 0bc4e04aaead15b626a732a223ebf47ee22e73f0 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-05-28T20:30:35 --- ChangeLog | 11 +++++++++-- UI/Contacts/English.lproj/Localizable.strings | 1 + UI/Scheduler/English.lproj/Localizable.strings | 1 + UI/WebServerResources/ContactsUI.js | 12 ++++++++++-- UI/WebServerResources/SchedulerUI.js | 12 ++++++++++-- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffc062ee7..2321bbc06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-05-28 Francis Lachapelle + + * UI/WebServerResources/SchedulerUI.js (validateUploadForm): hide + Cancel button when the form is valid and disable the Submit button. + + * UI/WebServerResources/ContactsUI.js (validateUploadForm): idem. + 2012-05-24 Jean Raby * debian*/rules: Restart sogod after pkg upgrade (dh_installinit -R) @@ -35,7 +42,7 @@ to read its freebusy info. Without this, sogo would always auto-accept invitations from 'unprivileged' users, potentially bypassing the multiplebooking parameter. - + 2012-05-14 Wolfgang Sourdeau * OpenChange/gen-property-selectors.py: "bannedProps" is now a @@ -105,7 +112,7 @@ * OpenChange/MAPIStoreSOGo.m: register and unregister current thread before and after each backend operation, in order to avoid - issues in multithreaded environment. + issues in multithreaded environment. 2012-05-01 Wolfgang Sourdeau diff --git a/UI/Contacts/English.lproj/Localizable.strings b/UI/Contacts/English.lproj/Localizable.strings index 9d2fcea6a..341bb39d0 100644 --- a/UI/Contacts/English.lproj/Localizable.strings +++ b/UI/Contacts/English.lproj/Localizable.strings @@ -198,6 +198,7 @@ "Import Cards" = "Import Cards"; "Select a vCard or LDIF file." = "Select a vCard or LDIF file."; "Upload" = "Upload"; +"Uploading" = "Uploading"; "Done" = "Done"; "An error occured while importing contacts." = "An error occured while importing contacts."; "No card was imported." = "No card was imported."; diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index fb704adc3..8aa9e8642 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -110,6 +110,7 @@ "Import Events" = "Import Events"; "Select an iCalendar file (.ics)." = "Select an iCalendar file (.ics)."; "Upload" = "Upload"; +"Uploading" = "Uploading"; "Publish Calendar..." = "Publish Calendar..."; "Reload Remote Calendars" = "Reload Remote Calendars"; "Properties" = "Properties"; diff --git a/UI/WebServerResources/ContactsUI.js b/UI/WebServerResources/ContactsUI.js index 6a14b5678..7a87247da 100644 --- a/UI/WebServerResources/ContactsUI.js +++ b/UI/WebServerResources/ContactsUI.js @@ -799,13 +799,21 @@ function hideImportResults () { } function validateUploadForm () { rc = false; - if ($("contactsFile").value.length) + if ($("contactsFile").value.length) { + var btn = jQuery('#uploadSubmit'); + jQuery('#uploadCancel').fadeOut('fast'); + btn.addClass("disabled"); + btn.children('span').text(_('Uploading')); rc = true; + } return rc; } function uploadCompleted(response) { data = response.evalJSON(true); - + jQuery('#uploadCancel').show(); + var btn = jQuery('#uploadSubmit'); + btn.removeClass("disabled"); + btn.children('span').text(_('Upload')); var div = $("uploadResults"); if (data.imported <= 0) $("uploadResultsContent").update(_("An error occured while importing contacts.")); diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 601279356..f077995a9 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -2849,13 +2849,21 @@ function hideImportResults(event) { } function validateUploadForm() { rc = false; - if ($("calendarFile").value.length) + if ($("calendarFile").value.length) { + var btn = jQuery('#uploadSubmit'); + jQuery('#uploadCancel').fadeOut('fast'); + btn.addClass("disabled"); + btn.children('span').text(_('Uploading')); rc = true; + } return rc; } function uploadCompleted(response) { data = response.evalJSON(true); - + jQuery('#uploadCancel').show(); + var btn = jQuery('#uploadSubmit'); + btn.removeClass("disabled"); + btn.children('span').text(_('Upload')); var div = $("uploadResults"); if (data.imported < 0) $("uploadResultsContent").update(_("An error occurred while importing calendar.")); From 19ea16d5baf13db6aa88e70b1e0a010e4018db20 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 29 May 2012 14:20:06 +0000 Subject: [PATCH 2/6] See ChangeLog. Monotone-Parent: 0bc4e04aaead15b626a732a223ebf47ee22e73f0 Monotone-Revision: 28cde64403e65a1ebeda3a984650fd31d8614f29 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-05-29T14:20:06 --- ChangeLog | 15 ++++ UI/MailPartViewers/UIxMailPartMessageViewer.m | 2 +- UI/MailerUI/English.lproj/Localizable.strings | 6 +- UI/MailerUI/UIxMailEditor.m | 5 +- UI/MailerUI/UIxMailListActions.m | 2 +- UI/MailerUI/UIxMailView.m | 2 - UI/WebServerResources/ContactsUI.js | 19 ----- UI/WebServerResources/UIxMailEditor.css | 2 +- UI/WebServerResources/UIxMailEditor.js | 76 +++++++++---------- 9 files changed, 57 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2321bbc06..d31ae0065 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-05-29 Francis Lachapelle + + * UI/WebServerResources/UIxMailEditor.js (validateEditorInput): + merged with onValidate. + (onValidate): don't force the subject to be defined, but alert + the user. + + * UI/MailerUI/UIxMailView.m (-messageSubject): don't set the + subject to "Untitled" if it's not set. + + * UI/MailPartViewers/UIxMailPartMessageViewer.m (-messageSubject): idem. + + * UI/MailerUI/UIxMailEditor.m (-validateForSend): don't force the + subject to be defined. + 2012-05-28 Francis Lachapelle * UI/WebServerResources/SchedulerUI.js (validateUploadForm): hide diff --git a/UI/MailPartViewers/UIxMailPartMessageViewer.m b/UI/MailPartViewers/UIxMailPartMessageViewer.m index 0fd3a7c90..7e18cb703 100644 --- a/UI/MailPartViewers/UIxMailPartMessageViewer.m +++ b/UI/MailPartViewers/UIxMailPartMessageViewer.m @@ -165,7 +165,7 @@ subject = [baseSubject decodedHeader]; if (![subject length]) - subject = [self labelForKey: @"Untitled"]; + subject = @""; return subject; } diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index ae23ec20e..4ae64d679 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -283,9 +283,9 @@ = "The messages could not be moved to the trash folder. Would you like to delete them immediately?"; /* Message editing */ -"error_validationfailed" = "Validation failed"; -"error_missingsubject" = "Subject is missing"; -"error_missingrecipients" = "No recipients specified"; +"error_missingsubject" = "The message has no subject. Are you sure you want to send it?"; +"error_missingrecipients" = "Please specify at least one recipient."; +"Send Anyway" = "Send Anyway"; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "Cannot send message: all recipients are invalid."; diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index aa32a7a59..95609e19b 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -653,10 +653,7 @@ static NSArray *infoKeys = nil; if (![self hasOneOrMoreRecipients]) error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ - reason: @"Please select a recipient!"]; - else if ([[self subject] length] == 0) - error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ - reason: @"Please set a subject!"]; + reason: [self labelForKey: @"error_missingrecipients"]]; else error = nil; diff --git a/UI/MailerUI/UIxMailListActions.m b/UI/MailerUI/UIxMailListActions.m index 240b175c0..b6c2e6e4e 100644 --- a/UI/MailerUI/UIxMailListActions.m +++ b/UI/MailerUI/UIxMailListActions.m @@ -192,7 +192,7 @@ baseSubject = [[message valueForKey: @"envelope"] subject]; subject = [baseSubject decodedHeader]; if (![subject length]) - subject = [self labelForKey: @"Untitled"]; + subject = @""; return [subject stringByEscapingHTMLString]; } diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index f9d104dce..48dac90ba 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -96,8 +96,6 @@ static NSString *mailETag = nil; NSString *subject; subject = [[self clientObject] decodedSubject]; - if (![subject length]) - subject = [self labelForKey: @"Untitled"]; return subject; } diff --git a/UI/WebServerResources/ContactsUI.js b/UI/WebServerResources/ContactsUI.js index 7a87247da..f836a7166 100644 --- a/UI/WebServerResources/ContactsUI.js +++ b/UI/WebServerResources/ContactsUI.js @@ -12,25 +12,6 @@ var Contact = { deleteContactsRequestCount: null }; -function validateEditorInput(sender) { - var errortext = ""; - var field; - - field = document.pageform.subject; - if (field.value == "") - errortext = errortext + labels.error_missingsubject + "\n"; - - if (!hasRecipients()) - errortext = errortext + labels.error_missingrecipients + "\n"; - - if (errortext.length > 0) { - alert(labels.error_validationfailed + ":\n" - + errortext); - return false; - } - return true; -} - function openContactsFolder(contactsFolder, reload, idx) { if ((contactsFolder && contactsFolder != Contact.currentAddressBook) || reload) { diff --git a/UI/WebServerResources/UIxMailEditor.css b/UI/WebServerResources/UIxMailEditor.css index 7d047bea8..bb3374a7b 100644 --- a/UI/WebServerResources/UIxMailEditor.css +++ b/UI/WebServerResources/UIxMailEditor.css @@ -237,7 +237,7 @@ TABLE#contactsList TD#mailHeader DIV.contactSelection { - z-index: 10; + z-index: 1; background: inherit; position: absolute; bottom: 0em; diff --git a/UI/WebServerResources/UIxMailEditor.js b/UI/WebServerResources/UIxMailEditor.js index 0f12384e2..31bd83a45 100644 --- a/UI/WebServerResources/UIxMailEditor.js +++ b/UI/WebServerResources/UIxMailEditor.js @@ -107,51 +107,45 @@ function insertContact(inputNode, contactName, contactEmail) { /* mail editor */ -function validateEditorInput() { - var errortext = ""; - var field; - - field = document.pageform.subject; - if (field.value == "") - errortext = errortext + _("error_missingsubject") + "\n"; - - if (!hasRecipients()) - errortext = errortext + _("error_missingrecipients") + "\n"; - - if (errortext.length > 0) { - alert(_("error_validationfailed") + ":\n" + errortext); - return false; +function onValidate(onSuccess) { + if (document.pageform.action != "send") { + + if (!hasRecipients()) { + showAlertDialog(_("error_missingrecipients")); + } + else if (document.pageform.subject.value == "") { + showConfirmDialog(_("Warning"), _("error_missingsubject"), onValidateDone.bind(this, onSuccess), null, _("Send anyway"), _("Cancel")); + } + else { + onValidateDone(onSuccess); + } } - - return true; } -function onValidate(event) { - var rc = false; +function onValidateDone(onSuccess) { + var input = currentAttachmentInput(); + if (input) + input.parentNode.removeChild(input); - if (document.pageform.action != "send" - && validateEditorInput()) { - var input = currentAttachmentInput(); - if (input) - input.parentNode.removeChild(input); - - var toolbar = document.getElementById("toolbar"); - if (!document.busyAnim) - document.busyAnim = startAnimation(toolbar); - - var lastRow = $("lastRow"); - lastRow.down("select").name = "popup_last"; + var toolbar = document.getElementById("toolbar"); + if (!document.busyAnim) + document.busyAnim = startAnimation(toolbar); - window.shouldPreserve = true; + var lastRow = $("lastRow"); + lastRow.down("select").name = "popup_last"; + + window.shouldPreserve = true; + + document.pageform.action = "send"; + + AIM.submit($(document.pageform), {'onComplete' : onPostComplete}); + + if (typeof onSuccess == 'function') + onSuccess(); - document.pageform.action = "send"; + disposeDialog(); - AIM.submit($(document.pageform), {'onComplete' : onPostComplete}); - - rc = true; - } - - return rc; + return true; } function onPostComplete(response) { @@ -184,9 +178,9 @@ function onPostComplete(response) { } function clickedEditorSend() { - if (onValidate()) { - document.pageform.submit(); - } + onValidate(function() { + document.pageform.submit(); + }); return false; } From 66c972eb972f6435538efc0766e44d0d2de19609 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 29 May 2012 14:31:14 +0000 Subject: [PATCH 3/6] See ChangeLog. Monotone-Parent: 28cde64403e65a1ebeda3a984650fd31d8614f29 Monotone-Revision: f51ae70ff345179926dfdd4fd5856e968bdfc327 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-05-29T14:31:14 --- ChangeLog | 4 ++++ SoObjects/Mailer/SOGoMailObject+Draft.m | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index d31ae0065..a254d5c1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,10 @@ * UI/MailerUI/UIxMailEditor.m (-validateForSend): don't force the subject to be defined. + * SoObjects/Mailer/SOGoMailObject+Draft.m (-subjectForReply): make + sure subject is a defined value to avoid "null" strings in the + reply message. + 2012-05-28 Francis Lachapelle * UI/WebServerResources/SchedulerUI.js (validateUploadForm): hide diff --git a/SoObjects/Mailer/SOGoMailObject+Draft.m b/SoObjects/Mailer/SOGoMailObject+Draft.m index b0aec21ed..aede6309e 100644 --- a/SoObjects/Mailer/SOGoMailObject+Draft.m +++ b/SoObjects/Mailer/SOGoMailObject+Draft.m @@ -59,6 +59,8 @@ hasPrefix = NO; subject = [self decodedSubject]; + if (![subject length]) subject = @""; + i = 0; while (!hasPrefix && replyPrefixes[i]) if ([subject hasPrefix: replyPrefixes[i]]) From 2e49702e3f2293816b8903c713e8a7bb5014dabd Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 29 May 2012 17:24:24 +0000 Subject: [PATCH 4/6] See ChangeLog. Monotone-Parent: f51ae70ff345179926dfdd4fd5856e968bdfc327 Monotone-Revision: 1e79eab4c546452715e5171f1c326b7d36f1c195 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-05-29T17:24:24 --- SOPE/NGCards/ChangeLog | 8 ++++++++ SOPE/NGCards/iCalRecurrenceCalculator.m | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/SOPE/NGCards/ChangeLog b/SOPE/NGCards/ChangeLog index 5e7f0c1ca..28740b538 100644 --- a/SOPE/NGCards/ChangeLog +++ b/SOPE/NGCards/ChangeLog @@ -1,3 +1,11 @@ +2012-05-29 Francis Lachapelle + + * iCalRecurrenceCalculator.m + (_removeExceptionDatesFromRanges:withDates:withinRange:startingWithDate:): + when removing exception dates, avoid removing dates matching the + end date of the occurrence. This fixes an issue with all-day + daily events. + 2012-04-23 Wolfgang Sourdeau * iCalMonthlyRecurrenceCalculator.m (NGMonthDaySet_clear): make diff --git a/SOPE/NGCards/iCalRecurrenceCalculator.m b/SOPE/NGCards/iCalRecurrenceCalculator.m index 284e74b2a..7e60c0d9a 100644 --- a/SOPE/NGCards/iCalRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalRecurrenceCalculator.m @@ -189,6 +189,7 @@ static Class yearlyCalcClass = Nil; NSCalendarDate *currentDate; NGCalendarDateRange *currentRange; unsigned int count, maxRanges; + NSComparisonResult compare; dates = [[self _dates: exdates withinRange: limits] objectEnumerator]; while ((currentDate = [dates nextObject])) @@ -197,7 +198,9 @@ static Class yearlyCalcClass = Nil; for (count = maxRanges; count > 0; count--) { currentRange = [ranges objectAtIndex: count - 1]; - if ([currentRange containsDate: currentDate]) + compare = [[currentRange startDate] compare: currentDate]; + if ((compare == NSOrderedAscending || compare == NSOrderedSame) && + [[currentRange endDate] compare: currentDate] == NSOrderedDescending) [ranges removeObjectAtIndex: count - 1]; } } From d6f02033516b24d07fffa230d0d3c033dfb7cb41 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Tue, 29 May 2012 18:56:15 +0000 Subject: [PATCH 5/6] Patch applied from bug #1664 Monotone-Parent: 1e79eab4c546452715e5171f1c326b7d36f1c195 Monotone-Revision: 99dc7d9dce88b8a323b1e7aab60de99ed2bfda60 Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2012-05-29T18:56:15 --- SOPE/NGCards/CardGroup.m | 6 +++--- SoObjects/Mailer/SOGoMailObject+Draft.m | 8 ++++---- SoObjects/SOGo/NSString+Utilities.m | 3 ++- .../UIxMailPartAlternativeViewer.m | 18 +++++++++--------- UI/MailerUI/UIxMailEditor.m | 2 +- UI/MailerUI/UIxMailMainFrame.m | 14 +++++++------- UI/Scheduler/UIxCalView.m | 7 ++++--- UI/Scheduler/UIxComponentEditor.m | 12 ++++++------ 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/SOPE/NGCards/CardGroup.m b/SOPE/NGCards/CardGroup.m index d19b1a321..702257148 100644 --- a/SOPE/NGCards/CardGroup.m +++ b/SOPE/NGCards/CardGroup.m @@ -354,7 +354,7 @@ static NGCardsSaxHandler *sax = nil; - (void) setChildrenAsCopy: (NSMutableArray *) someChildren { - unsigned int count, max; + NSUInteger count, max; ASSIGN (children, someChildren); @@ -399,7 +399,7 @@ static NGCardsSaxHandler *sax = nil; - (NSString *) description { NSMutableString *str; - unsigned int count, max; + NSUInteger count, max; str = [NSMutableString stringWithCapacity:64]; [str appendFormat:@"<%p[%@]:%@", @@ -421,7 +421,7 @@ static NGCardsSaxHandler *sax = nil; - (void) replaceThisElement: (CardElement *) oldElement withThisOne: (CardElement *) newElement { - unsigned int index; + NSUInteger index; index = [children indexOfObject: oldElement]; if (index != NSNotFound) diff --git a/SoObjects/Mailer/SOGoMailObject+Draft.m b/SoObjects/Mailer/SOGoMailObject+Draft.m index aede6309e..40eb060e5 100644 --- a/SoObjects/Mailer/SOGoMailObject+Draft.m +++ b/SoObjects/Mailer/SOGoMailObject+Draft.m @@ -53,7 +53,7 @@ nil }; BOOL hasPrefix; - unsigned int i; + NSUInteger i; NSString *subject, *newSubject; hasPrefix = NO; @@ -101,7 +101,7 @@ NSDictionary *parts; NSString *rawPart, *content, *contentKey; SOGoUserDefaults *ud; - int index; + NSUInteger index; BOOL htmlComposition, htmlContent; content = @""; @@ -191,7 +191,7 @@ static NSString *sescape[] = { @"/", @"..", @"~", @"\"", @"'", @" ", @".", nil }; - unsigned int count, length; + NSUInteger count, length; subject = [self decodedSubject]; length = [subject length]; @@ -300,7 +300,7 @@ NSString *newPath; NSArray *subparts; NSString *type; - unsigned int i; + NSUInteger i; type = [[part objectForKey: @"type"] lowercaseString]; if ([type isEqualToString: @"multipart"]) diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 9cfe2788f..64f87f010 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -471,7 +471,8 @@ static int cssEscapingCount; - (int) timeValue { - int i, time; + int time; + NSInteger i; if ([self length] > 0) { diff --git a/UI/MailPartViewers/UIxMailPartAlternativeViewer.m b/UI/MailPartViewers/UIxMailPartAlternativeViewer.m index 9174a205c..16e15d24d 100644 --- a/UI/MailPartViewers/UIxMailPartAlternativeViewer.m +++ b/UI/MailPartViewers/UIxMailPartAlternativeViewer.m @@ -43,7 +43,7 @@ @interface UIxMailPartAlternativeViewer : UIxMailPartViewer { id childInfo; - unsigned int childIndex; + NSUInteger childIndex; } @end @@ -70,7 +70,7 @@ - (NSArray *) childPartTypes { NSMutableArray *types; - unsigned i, count; + NSUInteger i, count; NSArray *childParts; childParts = [[self bodyInfo] valueForKey:@"parts"]; @@ -89,10 +89,10 @@ return types; } -- (unsigned int) _preferredTypesPart: (NSArray *) types +- (NSUInteger) _preferredTypesPart: (NSArray *) types { - unsigned int count, max; - unsigned int part; + NSUInteger count, max; + NSUInteger part; const NSString *priorities[] = { @"multipart/related", @"multipart/mixed", @"text/calendar", @"text/html", @"text/plain" }; @@ -113,7 +113,7 @@ - (int) _selectPartIndexFromTypes: (NSArray *) _types { /* returns the index of the selected part or NSNotFound */ - unsigned count, max, part; + NSUInteger count, max, part; part = [self _preferredTypesPart: _types]; if (part == NSNotFound) @@ -136,7 +136,7 @@ - (void) selectChildInfo { - unsigned idx; + NSUInteger idx; [childInfo release]; childInfo = nil; childIndex = 0; @@ -164,7 +164,7 @@ return childInfo; } -- (unsigned int) childIndex +- (NSUInteger) childIndex { if (!childIndex) [self selectChildInfo]; @@ -176,7 +176,7 @@ { char buf[8]; - sprintf (buf, "%d", [self childIndex] + 1); + sprintf (buf, "%"PRIuPTR"", [self childIndex] + 1); return [NSString stringWithCString:buf]; } diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index 95609e19b..e10b02ac6 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -394,7 +394,7 @@ static NSArray *infoKeys = nil; { if (![_info isNotNull]) return; [self debugWithFormat:@"loading info ..."]; - [self takeValuesFromDictionary:_info]; + [self setValuesForKeysWithDictionary:_info]; } - (NSDictionary *) storeInfo diff --git a/UI/MailerUI/UIxMailMainFrame.m b/UI/MailerUI/UIxMailMainFrame.m index 0d121651b..8db3cf656 100644 --- a/UI/MailerUI/UIxMailMainFrame.m +++ b/UI/MailerUI/UIxMailMainFrame.m @@ -125,8 +125,8 @@ // TODO: this is ugly, create reusable link facility in SOPE // TODO: remove 'search' and 'filterpopup', preserve sorting NSMutableString *ms; - NSArray *qp; - unsigned i, count; + NSArray *qp; + NSUInteger i, count; qp = [[u substringFromIndex:(r.location + r.length)] componentsSeparatedByString:@"&"]; @@ -193,8 +193,8 @@ SOGoMailAccounts *co; SOGoContactFolders *folders; SOGoParentFolder *folder; - WORequest *request; - int i, count; + WORequest *request; + NSUInteger i, count; parameters = nil; co = [self clientObject]; @@ -549,7 +549,7 @@ NSArray *available; NSDictionary *metaData; SOGoUserDefaults *ud; - unsigned int i; + NSUInteger i; if (!columnsOrder) { @@ -636,8 +636,8 @@ NSMutableArray *folders; NSMutableString *path; SOGoUserDefaults *ud; - NSString *s; - int i, j, k; + NSString *s; + NSUInteger i, j, k; ud = [[context activeUser] userDefaults]; folders = [NSMutableArray array]; diff --git a/UI/Scheduler/UIxCalView.m b/UI/Scheduler/UIxCalView.m index 5b594dbce..2ed982b00 100644 --- a/UI/Scheduler/UIxCalView.m +++ b/UI/Scheduler/UIxCalView.m @@ -118,7 +118,7 @@ - (NSArray *) filterAppointments:(NSArray *) _apts { NSMutableArray *filtered; - unsigned i, count, p, pCount; + NSUInteger i, count, p, pCount; NSString *email, *partmailsString, *state, *pEmail; NSDictionary *info, *primaryIdentity; NSArray *partmails, *partstates; @@ -370,7 +370,7 @@ { NSArray *apts; NSMutableArray *filtered; - unsigned i, count; + NSUInteger i, count; if (allDayApts) return allDayApts; @@ -532,7 +532,8 @@ NSString *uidsString, *loc, *prevMethod, *userFolderID; id r; BOOL useGroups; - unsigned index; + NSUInteger index; + uidsString = [self queryParameterForKey: @"userUIDString"]; uidsString = [uidsString stringByTrimmingSpaces]; diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index e2186e180..3813f9646 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -525,7 +525,7 @@ iRANGE(2); iCalTrigger *aTrigger; NSString *duration, *quantity; unichar c; - unsigned int i; + NSUInteger i; if ([component hasAlarms]) { @@ -1289,7 +1289,7 @@ iRANGE(2); NSString *currentOwner; SOGoAppointmentFolder *currentCalendar; SOGoUser *currentUser; - unsigned i; + NSUInteger i; calendars = [self calendarList]; owners = [NSMutableArray arrayWithCapacity: [calendars count]]; @@ -1562,7 +1562,7 @@ RANGE(2); { NSString *cycleRep; NSArray *cycles; - unsigned i, count; + NSUInteger i, count; if (!_rrule) return [[self cycles] objectAtIndex:0]; @@ -1721,7 +1721,7 @@ RANGE(2); // s = [self queryParameterForKey:_qp]; // if(s && [s length] > 0) { // NSArray *es; -// unsigned i, count; +// NSUInteger i, count; // es = [s componentsSeparatedByString: @","]; // count = [es count]; @@ -1766,7 +1766,7 @@ RANGE(2); - (void) _handleAttendeesEdition { NSMutableArray *newAttendees; - unsigned int count, max; + NSUInteger count, max; NSString *currentEmail; iCalPerson *currentAttendee; NSString *json, *role, *partstat; @@ -2189,7 +2189,7 @@ RANGE(2); iCalTrigger *aTrigger; iCalAlarm *anAlarm; NSString *aValue; - unsigned int index; + NSUInteger index; anAlarm = [iCalAlarm new]; From d98db782b3332e4cc342f846fbccec052e55cfce Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Wed, 30 May 2012 11:34:24 +0000 Subject: [PATCH 6/6] See SOPE/NGCards/ChangeLog. Monotone-Parent: 99dc7d9dce88b8a323b1e7aab60de99ed2bfda60 Monotone-Revision: d29498142c4a9f1d780373bd5f0d80b17f6e2c33 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-05-30T11:34:24 --- SOPE/NGCards/ChangeLog | 6 +++ SOPE/NGCards/iCalRecurrenceCalculator.m | 4 +- SOPE/NGCards/iCalRepeatableEntityObject.h | 8 ++-- SOPE/NGCards/iCalRepeatableEntityObject.m | 37 +++++++++++++++---- .../iCalRepeatableEntityObject+SOGo.m | 21 ++++++----- 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/SOPE/NGCards/ChangeLog b/SOPE/NGCards/ChangeLog index 28740b538..00e9c352b 100644 --- a/SOPE/NGCards/ChangeLog +++ b/SOPE/NGCards/ChangeLog @@ -1,3 +1,9 @@ +2012-05-30 Francis Lachapelle + + * iCalRepeatableEntityObject.m (-exceptionDatesWithTimeZone:) + (-rules:withTimeZone:): exception dates and exception rules must + also be adjusted for floating all-day repeating events. + 2012-05-29 Francis Lachapelle * iCalRecurrenceCalculator.m diff --git a/SOPE/NGCards/iCalRecurrenceCalculator.m b/SOPE/NGCards/iCalRecurrenceCalculator.m index 7e60c0d9a..eebaa6dfb 100644 --- a/SOPE/NGCards/iCalRecurrenceCalculator.m +++ b/SOPE/NGCards/iCalRecurrenceCalculator.m @@ -201,7 +201,9 @@ static Class yearlyCalcClass = Nil; compare = [[currentRange startDate] compare: currentDate]; if ((compare == NSOrderedAscending || compare == NSOrderedSame) && [[currentRange endDate] compare: currentDate] == NSOrderedDescending) - [ranges removeObjectAtIndex: count - 1]; + { + [ranges removeObjectAtIndex: count - 1]; + } } } } diff --git a/SOPE/NGCards/iCalRepeatableEntityObject.h b/SOPE/NGCards/iCalRepeatableEntityObject.h index 9f70e2033..e1f259d4e 100644 --- a/SOPE/NGCards/iCalRepeatableEntityObject.h +++ b/SOPE/NGCards/iCalRepeatableEntityObject.h @@ -42,21 +42,21 @@ - (void)setRecurrenceRules:(NSArray *)_rrule; - (BOOL)hasRecurrenceRules; - (NSArray *)recurrenceRules; -- (NSArray *)recurrenceRulesWithTimeZone: (iCalTimeZone *) timezone; +- (NSArray *)recurrenceRulesWithTimeZone: (id) timezone; - (void)removeAllExceptionRules; - (void)addToExceptionRules:(id)_rrule; - (BOOL)hasExceptionRules; - (NSArray *)exceptionRules; -- (NSArray *)exceptionRulesWithTimeZone: (iCalTimeZone *) timezone; +- (NSArray *)exceptionRulesWithTimeZone: (id) timezone; - (void)removeAllExceptionDates; - (void)addToExceptionDates:(NSCalendarDate *)_date; - (BOOL)hasExceptionDates; - (NSArray *)exceptionDates; -- (NSArray *)exceptionDatesWithTimeZone: (iCalTimeZone*) theTimeZone; +- (NSArray *)exceptionDatesWithTimeZone: (id) theTimeZone; -- (NSArray *) rules: (NSArray *) theRules withTimeZone: (iCalTimeZone *) theTimeZone; +- (NSArray *) rules: (NSArray *) theRules withTimeZone: (id) theTimeZone; - (BOOL)isRecurrent; - (BOOL)isWithinCalendarDateRange:(NGCalendarDateRange *)_range diff --git a/SOPE/NGCards/iCalRepeatableEntityObject.m b/SOPE/NGCards/iCalRepeatableEntityObject.m index b2e9a00e6..5f675e29e 100644 --- a/SOPE/NGCards/iCalRepeatableEntityObject.m +++ b/SOPE/NGCards/iCalRepeatableEntityObject.m @@ -1,6 +1,6 @@ /* Copyright (C) 2004-2005 SKYRIX Software AG - Copyright (C) 2011 Inverse inc. + Copyright (C) 2012 Inverse inc. This file is part of SOPE. @@ -24,10 +24,12 @@ #import #import #import +#import #import #import "NSCalendarDate+NGCards.h" +#import "NSString+NGCards.h" #import "iCalDateTime.h" #import "iCalEvent.h" #import "iCalTimeZone.h" @@ -79,7 +81,7 @@ return [self childrenWithTag: @"rrule"]; } -- (NSArray *) recurrenceRulesWithTimeZone: (iCalTimeZone *) timezone +- (NSArray *) recurrenceRulesWithTimeZone: (id) timezone { NSArray *rules; @@ -113,7 +115,7 @@ return [self childrenWithTag: @"exrule"]; } -- (NSArray *) exceptionRulesWithTimeZone: (iCalTimeZone *) timezone +- (NSArray *) exceptionRulesWithTimeZone: (id) timezone { NSArray *rules; @@ -131,12 +133,13 @@ * @see exceptionRulesWithTimeZone: * @return a new array of iCalRecurrenceRule instances, adjusted for the timezone. */ -- (NSArray *) rules: (NSArray *) theRules withTimeZone: (iCalTimeZone *) theTimeZone +- (NSArray *) rules: (NSArray *) theRules withTimeZone: (id) theTimeZone { NSArray *rules; NSCalendarDate *untilDate; NSMutableArray *fixedRules; iCalRecurrenceRule *currentRule; + int offset; unsigned int max, count; rules = theRules; @@ -152,7 +155,14 @@ untilDate = [currentRule untilDate]; if (untilDate) { - untilDate = [theTimeZone computedDateForDate: untilDate]; + if ([theTimeZone isKindOfClass: [iCalTimeZone class]]) + untilDate = [(iCalTimeZone *) theTimeZone computedDateForDate: untilDate]; + else + { + offset = [(NSTimeZone *) theTimeZone secondsFromGMTForDate: untilDate]; + untilDate = (NSCalendarDate *) [untilDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 + seconds:-offset]; + } [currentRule setUntilDate: untilDate]; } [fixedRules addObject: currentRule]; @@ -232,12 +242,13 @@ * @see [iCalTimeZone computedDatesForStrings:] * @return the exception dates, adjusted to the timezone. */ -- (NSArray *) exceptionDatesWithTimeZone: (iCalTimeZone *) theTimeZone +- (NSArray *) exceptionDatesWithTimeZone: (id) theTimeZone { NSArray *dates, *exDates; NSEnumerator *dateList; NSCalendarDate *exDate; NSString *dateString; + int offset; unsigned i; if (theTimeZone) @@ -251,9 +262,19 @@ for (i = 0; i < [exDates count]; i++) { dateString = [exDates objectAtIndex: i]; - exDate = [theTimeZone computedDateForString: dateString]; + if ([theTimeZone isKindOfClass: [iCalTimeZone class]]) + { + exDate = [(iCalTimeZone *) theTimeZone computedDateForString: dateString]; + } + else + { + exDate = [dateString asCalendarDate]; + offset = [(NSTimeZone *) theTimeZone secondsFromGMTForDate: exDate]; + exDate = (NSCalendarDate *) [exDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 + seconds:-offset]; + } [(NSMutableArray *) dates addObject: exDate]; - } + } } } else diff --git a/SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m b/SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m index 04e6f93b3..d15760f64 100644 --- a/SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m +++ b/SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.m @@ -125,9 +125,7 @@ NSArray *ranges; NGCalendarDateRange *checkRange, *firstRange; NSCalendarDate *startDate, *endDate; - NSTimeZone *timeZone; - id firstStartDate, firstEndDate; - iCalTimeZone *eventTimeZone; + id firstStartDate, firstEndDate, timeZone; BOOL doesOccur; int offset; @@ -139,9 +137,11 @@ // Set the range to check with respect to the event timezone (extracted from the start date) firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"]; - eventTimeZone = [(iCalDateTime *)firstStartDate timeZone]; - if (eventTimeZone) - startDate = [eventTimeZone computedDateForDate: theOccurenceDate]; + timeZone = [(iCalDateTime *)firstStartDate timeZone]; + if (timeZone) + { + startDate = [(iCalTimeZone *)timeZone computedDateForDate: theOccurenceDate]; + } else { startDate = theOccurenceDate; @@ -150,13 +150,14 @@ // The event lasts all-day and has no timezone (floating); we convert the range of the first event // to the occurence's timezone. timeZone = [theOccurenceDate timeZone]; - offset = [timeZone secondsFromGMTForDate: [firstRange startDate]]; + offset = [(NSTimeZone *)timeZone secondsFromGMTForDate: [firstRange startDate]]; firstStartDate = (NSCalendarDate *)[[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-offset]; firstEndDate = (NSCalendarDate *)[[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:-offset]; [(NSCalendarDate *)firstStartDate setTimeZone: timeZone]; [(NSCalendarDate *)firstEndDate setTimeZone: timeZone]; + firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate endDate: firstEndDate]; } @@ -168,9 +169,9 @@ // Calculate the occurrences for the given date ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: checkRange firstInstanceCalendarDateRange: firstRange - recurrenceRules: [self recurrenceRulesWithTimeZone: eventTimeZone] - exceptionRules: [self exceptionRulesWithTimeZone: eventTimeZone] - exceptionDates: [self exceptionDatesWithTimeZone: eventTimeZone]]; + recurrenceRules: [self recurrenceRulesWithTimeZone: timeZone] + exceptionRules: [self exceptionRulesWithTimeZone: timeZone] + exceptionDates: [self exceptionDatesWithTimeZone: timeZone]]; doesOccur = [ranges dateRangeArrayContainsDate: startDate]; }