From 5c618e56385d5e2220c6739bacd8da6c2383ea98 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Jul 2012 18:34:59 +0000 Subject: [PATCH 1/3] Improved HTML of mail notifications. See ChangeLog. Monotone-Parent: 8ce46d6fa7b1d1a9d12069cee3ba796d99d668d2 Monotone-Revision: 5a6d160e6f9616edb725a40e08f24f0f0bf539b0 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-07-20T18:34:59 --- ChangeLog | 12 ++- .../English.lproj/Localizable.strings | 10 +- .../French.lproj/Localizable.strings | 28 ++---- SoObjects/Appointments/SOGoAptMailReceipt.h | 3 +- SoObjects/Appointments/SOGoAptMailReceipt.m | 24 ++++- .../Appointments/SOGoCalendarComponent.m | 2 +- UI/MailPartViewers/UIxMailPartHTMLViewer.m | 1 + .../Appointments/SOGoAptMailReceipt.wox | 92 +++++++++---------- 8 files changed, 91 insertions(+), 81 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2078ce707..1907ca606 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-07-20 Francis Lachapelle + + * UI/MailPartViewers/UIxMailPartHTMLViewer.m + (-startElement:namespace:rawName:attributes:): don't skip "mailto:" + href. + + * SoObjects/Appointments/SOGoAptMailReceipt.m (aptSummary-): new + method that returns a properly formatted string of the event title + with respect to the current operation (creation/deletion/update). + 2012-07-18 Ludovic Marcotte * SoObjects/Appointments/SOGoAppointmentObject.m @@ -114,7 +124,7 @@ when modifying their own calendars or when someone else to it. These defaults are over-writable by users from their calendar properties window. - * Implemented the code related to the two new defaults together with a + * Implemented the code related to the two new defaults together with a third option - which is to notify a specific person when one modifies his/her calendar. This commit is partial as more testing is required and some code changes to trigger the right notifications. diff --git a/SoObjects/Appointments/English.lproj/Localizable.strings b/SoObjects/Appointments/English.lproj/Localizable.strings index 9d73efbc0..22106a1b9 100644 --- a/SoObjects/Appointments/English.lproj/Localizable.strings +++ b/SoObjects/Appointments/English.lproj/Localizable.strings @@ -8,13 +8,9 @@ vtodo_class1 = "(Private task)"; vtodo_class2 = "(Confidential task)"; /* Receipts */ -"Title:" = "Title:"; -"Start:" = "Start:"; -"End:" = "End:"; -"Location:" = "Location:"; -"Receipt: event was created" = "Receipt: event was created"; -"Receipt: event was deleted" = "Receipt: event was deleted"; -"Receipt: event was updated" = "Receipt: event was updated"; +"The event \"%{Summary}\" was created" = "The event \"%{Summary}\" was created"; +"The event \"%{Summary}\" was deleted" = "The event \"%{Summary}\" was deleted"; +"The event \"%{Summary}\" was updated" = "The event \"%{Summary}\" was updated"; "The following attendees(s) were notified:" = "The following attendees(s) were notified:"; "The following attendees(s) were added:" = "The following attendees(s) were added:"; "The following attendees(s) were removed:" = "The following attendees(s) were removed:"; diff --git a/SoObjects/Appointments/French.lproj/Localizable.strings b/SoObjects/Appointments/French.lproj/Localizable.strings index eca257736..7d9a84de3 100644 --- a/SoObjects/Appointments/French.lproj/Localizable.strings +++ b/SoObjects/Appointments/French.lproj/Localizable.strings @@ -8,25 +8,16 @@ vtodo_class1 = "(Tâche privée)"; vtodo_class2 = "(Tâche confidentielle)"; /* Receipts */ -"Title:" = "Titre :"; -"Start:" = "Début :"; -"End:" = "Fin :"; - -"Receipt: users invited to a meeting" = "Acc. de réception : vous avez ajouté des participants à une réunion"; -"You have invited the following attendees(s):" = "Vous avez invité les personnes suivantes :"; -"... to attend the following event:" = "... à participer à cette réunion :"; - -"Receipt: invitation updated" = "Acc. de réception : invitation mise à jour"; -"The following attendees(s):" = "Les participants suivants :"; -"... have been notified of the changes to the following event:" = "... ont été avisés des changements apportés à cette réunion :"; - -"Receipt: attendees removed from an event" = "Acc. de réception: invitations annulées"; -"You have removed the following attendees(s):" = "Les utilisateurs suivants :"; -"... from the following event:" = "... ne sont plus invités à cette réunion :"; +"The event \"%{Summary}\" was created" = "L'événement «%{Summary}» a été créé"; +"The event \"%{Summary}\" was deleted" = "L'événement «%{Summary}» a été effacé"; +"The event \"%{Summary}\" was updated" = "L'événement «%{Summary}» a été modifié"; +"The following attendees(s) were notified:" = "Les invités suivants ont été avisés :"; +"The following attendees(s) were added:" = "Les invités suivants ont été ajoutés :"; +"The following attendees(s) were removed:" = "Les invités suivants ont été supprimés :"; /* IMIP messages */ -"startDate_label" = "Du :"; -"endDate_label" = "au :"; +"startDate_label" = "Début :"; +"endDate_label" = "Fin :"; "due_label" = "Fin prévue :"; "location_label" = "Lieu :"; "summary_label" = "Titre :"; @@ -67,4 +58,5 @@ vtodo_class2 = "(Tâche confidentielle)"; = "%{Attendee} %{SentByText}choisit de reporter sa décision par rapport à votre invitation."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Le nombre maximal de réservations simultanées (%{NumberOfSimultaneousBookings}) est atteint pour la ressource «%{Cn} %{SystemEmail}». L'événement en conflit est «%{EventTitle}» et débute le %{StartDate}."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Impossible d'accéder à la ressource suivante: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Le nombre maximal de réservations simultanées (%{NumberOfSimultaneousBookings}) est atteint pour la ressource «%{Cn} %{SystemEmail}». L'événement en conflit est «%{EventTitle}» et débute le %{StartDate}."; diff --git a/SoObjects/Appointments/SOGoAptMailReceipt.h b/SoObjects/Appointments/SOGoAptMailReceipt.h index 8c4d613f2..c5c909635 100644 --- a/SoObjects/Appointments/SOGoAptMailReceipt.h +++ b/SoObjects/Appointments/SOGoAptMailReceipt.h @@ -47,7 +47,8 @@ - (void) setDeletedAttendees: (NSArray *) theAttendees; - (void) setUpdatedAttendees: (NSArray *) theAttendees; - (void) setOperation: (SOGoEventOperation) theOperation; -- (NSString *) subject; + +- (NSString *) aptSummary; @end diff --git a/SoObjects/Appointments/SOGoAptMailReceipt.m b/SoObjects/Appointments/SOGoAptMailReceipt.m index 7998f3739..1431b218d 100644 --- a/SoObjects/Appointments/SOGoAptMailReceipt.m +++ b/SoObjects/Appointments/SOGoAptMailReceipt.m @@ -4,6 +4,7 @@ * * Author: Wolfgang Sourdeau * Ludovic Marcotte + * Francis Lachapelle * * 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 @@ -31,6 +32,7 @@ #import #import +#import #import #import #import @@ -138,25 +140,37 @@ static NSCharacterSet *wsSet = nil; operation = theOperation; } -- (NSString *) subject +- (NSString *) aptSummary { NSString *s; + + if (!values) + [self setupValues]; + switch (operation) { case EventCreated: - s = [self labelForKey: @"Receipt: event was created" inContext: context]; + s = [self labelForKey: @"The event \"%{Summary}\" was created" + inContext: context]; break; case EventDeleted: - s = [self labelForKey: @"Receipt: event was deleted" inContext: context]; + s = [self labelForKey: @"The event \"%{Summary}\" was deleted" + inContext: context]; break; case EventUpdated: default: - s = [self labelForKey: @"Receipt: event was updated" inContext: context]; + s = [self labelForKey: @"The event \"%{Summary}\" was updated" + inContext: context]; } - return [[s stringByTrimmingCharactersInSet: wsSet] asQPSubjectString: @"utf-8"]; + return [values keysWithFormat: s]; +} + +- (NSString *) getSubject +{ + return [[[self aptSummary] stringByTrimmingCharactersInSet: wsSet] asQPSubjectString: @"utf-8"]; } - (NSString *) _formattedUserDate: (NSCalendarDate *) date diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 20b0ea0e4..910c78b9b 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -1015,7 +1015,7 @@ mailDate = [[NSCalendarDate date] rfc822DateString]; [headerMap setObject: mailDate forKey: @"date"]; - [headerMap setObject: [page subject] forKey: @"subject"]; + [headerMap setObject: [page getSubject] forKey: @"subject"]; [headerMap setObject: @"1.0" forKey: @"MIME-Version"]; [headerMap setObject: @"text/html; charset=utf-8" forKey: @"content-type"]; diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 331a77e47..53404fa7d 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -468,6 +468,7 @@ static NSData* _sanitizeContent(NSData *theData) value = [_attributes valueAtIndex: count]; skipAttribute = ([value rangeOfString: @"://"].location == NSNotFound + && ![value hasPrefix: @"mailto:"] && ![value hasPrefix: @"#"]); } else diff --git a/UI/Templates/Appointments/SOGoAptMailReceipt.wox b/UI/Templates/Appointments/SOGoAptMailReceipt.wox index e3b206817..957ca8fc4 100644 --- a/UI/Templates/Appointments/SOGoAptMailReceipt.wox +++ b/UI/Templates/Appointments/SOGoAptMailReceipt.wox @@ -7,52 +7,48 @@ xmlns:rsrc="OGo:url" xmlns:label="OGo:label"> - -
- - -
- - - - -
- - -
- - -
- - - - - - -
- - - - - - -
- - - - - - -
- + + + + +
+

+ +
+
+
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
+ From 8a1781ea223c7db4fb00ce98aa8f4e8322a9131c Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Fri, 20 Jul 2012 18:48:28 +0000 Subject: [PATCH 2/3] See ChangeLog Monotone-Parent: 5a6d160e6f9616edb725a40e08f24f0f0bf539b0 Monotone-Revision: c9c54e20cc8e010c29ef8e5fa1cbd039c35e5344 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-07-20T18:48:28 --- ChangeLog | 3 +++ UI/WebServerResources/MailerUI.js | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1907ca606..84e07e25c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2012-07-20 Francis Lachapelle + * UI/WebServerResources/MailerUI.js (onEmailTo): append the email + address from the href attribute if it doesn't appear in the link content. + * UI/MailPartViewers/UIxMailPartHTMLViewer.m (-startElement:namespace:rawName:attributes:): don't skip "mailto:" href. diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 3422fee67..25af280f4 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -1790,7 +1790,11 @@ function newContactFromEmail(event) { } function onEmailTo(event) { - openMailTo(this.innerHTML.strip()); + var s = this.innerHTML.strip(); + if (!/@/.test(s)) { + s += ' <' + this.href.substr(7) + '>'; + } + openMailTo(s); Event.stop(event); return false; } From 8f31821e1d21a1ba12aca2eb3f081b8b9a72c338 Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 20 Jul 2012 19:07:03 +0000 Subject: [PATCH 3/3] Monotone-Parent: c9c54e20cc8e010c29ef8e5fa1cbd039c35e5344 Monotone-Revision: 7eb19f1f060daa6cb0a2421481ec351910c3af68 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2012-07-20T19:07:03 --- ChangeLog | 7 +++++++ SoObjects/Appointments/SOGoAppointmentFolder.m | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/ChangeLog b/ChangeLog index 84e07e25c..3ae8b8e02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-07-20 Wolfgang Sourdeau + + * SoObjects/Appointments/SOGoAppointmentFolder.m + (_appendCycleException:firstInstanceCalendarDateRange:fromRow:forRange:withTimeZone:toArray:): + return immediately if the occurrence does not have a valid + recurrence-id. + 2012-07-20 Francis Lachapelle * UI/WebServerResources/MailerUI.js (onEmailTo): append the email diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 29a64b77b..50cdd92f9 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -863,6 +863,11 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir newRecord = nil; recurrenceId = [component recurrenceId]; + if (!recurrenceId) + { + [self errorWithFormat: @"ignored component with an empty EXCEPTION-ID"]; + return; + } if (tz) {