diff --git a/ChangeLog b/ChangeLog index f1ad054e2..b2bbc2e29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,41 @@ -2012-08-28 Jean Raby +2012-08-28 Jean Raby + * Scripts/openchange_cleanup.py: New script to clean an openchange user profile +2012-08-27 Francis Lachapelle + + * SoObjects/Appointments/SOGoAptMailInvitation.m, + SoObjects/Appointments/SOGoAptMailNotification.m, + SoObjects/Appointments/SOGoAptMailDeletion.m, + SoObjects/Appointments/SOGoAptMailUpdate.m, + SoObjects/Appointments/SOGoAptMailICalReply.m, + SoObjects/Appointments/SOGoCalendarComponent.m: send HTML messages + instead of text/plain. + + * UI/WebServerResources/generic.js (openMailTo): mail addresses + must now be separated by semi-colons and not commas. This allow + display names to contain commas. + + * UI/WebServerResources/SchedulerUI.js (tasksListCallback): prefix + tasks with a color box instead of changing the task's background color. + + * UI/Scheduler/UIxCalListingActions.m + (-_getStatusClassForStatusCode:andEndDateStamp::): set the + timezone of the due date to the user's timezone to properly + identify tasks due today. + +2012-08-27 Ludovic Marcotte + + * SoObjects/Appointments/iCalPerson+SOGo.m (mailAddress): + We now properly add double-quotes if we find a comma and + the person's name isn't already double-quoted. Fixes #1649 + +2012-08-24 Francis Lachapelle + + * UI/MailPartViewers/UIxMailPartHTMLViewer.m (-_sanitizeContent): + fix invalid void tags to insure proper HTML decoding. Fixes #1581. + 2012-08-23 Ludovic Marcotte * SoObjects/Mailer/SOGoMailFolder.m - added safety @@ -396,8 +430,6 @@ (-save): don t swap the bytes of the version number as it would return a wrong change number and a wrong change key for DB objects. -####### Ancestor -======= end 2012-07-20 Wolfgang Sourdeau * OpenChange/NSObject+MAPIStore.m (-getSMTPAddrType:inMemCtx:): @@ -485,8 +517,6 @@ (-save): don t swap the bytes of the version number as it would return a wrong change number and a wrong change key for DB objects. -####### Ancestor -======= end 2012-07-18 Ludovic Marcotte * SoObjects/Appointments/SOGoAppointmentObject.m diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index b120fb26c..6e4c31170 100644 Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ diff --git a/Documentation/SOGo Mobile Devices Configuration.odt b/Documentation/SOGo Mobile Devices Configuration.odt index 039c6a1bc..b0d95a3a8 100644 Binary files a/Documentation/SOGo Mobile Devices Configuration.odt and b/Documentation/SOGo Mobile Devices Configuration.odt differ diff --git a/Documentation/SOGo Mozilla Thunderbird Configuration.odt b/Documentation/SOGo Mozilla Thunderbird Configuration.odt index 3d5c13597..0a2b8a7da 100644 Binary files a/Documentation/SOGo Mozilla Thunderbird Configuration.odt and b/Documentation/SOGo Mozilla Thunderbird Configuration.odt differ diff --git a/NEWS b/NEWS index b27b7915f..b482828bc 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,24 @@ +1.3.18 (2012-08-28) +------------------- +Enhancements + - updated Catalan, Dutch, German, Hungarian, Russian, Spanish (Argentina), and + Spanish (Spain) translations + - mail filters (Sieve) are no longer conditional to each other (all filters are + executed, no matter if a previous condition matches) + - improved tasks list display + - RPM packages now treat logrotate file as a config file + - completed the transition from text/plain message templates to HTML + - new packages for Debian 7.0 (Wheezy) + +Bug Fixes + - fixed passwords that would be prefixed with '{none}' when not using a + password algorithm + - fixed handling of duplicated contacts in contact lists + - fixed handling of exception dates with timezones in recurrent events + - fixed validation of the interval in daily recurrent events with a day mask + covering multiple days + - fixed name quoting when sending invitations + 1.3.17 (2012-07-26) ------------------- New Features diff --git a/Scripts/updates.php b/Scripts/updates.php index 7e07166e6..f17fc8d92 100755 --- a/Scripts/updates.php +++ b/Scripts/updates.php @@ -28,15 +28,15 @@ $plugins = array( "sogo-connector@inverse.ca" => array( "application" => "thunderbird", - "version" => "10.0.0", - "filename" => "sogo-connector-10.0.0.xpi" ), + "version" => "10.0.3", + "filename" => "sogo-connector-10.0.3.xpi" ), "sogo-integrator@inverse.ca" => array( "application" => "thunderbird", - "version" => "10.0.0", - "filename" => "sogo-integrator-10.0.0.xpi" ), + "version" => "10.0.3", + "filename" => "sogo-integrator-10.0.3.xpi" ), "{e2fda1a4-762b-4020-b5ad-a41df1933103}" => array( "application" => "thunderbird", - "version" => "1.2.1", + "version" => "1.2.3", "filename" => "lightning.xpi" ) ); diff --git a/SoObjects/Appointments/Catalan.lproj/Localizable.strings b/SoObjects/Appointments/Catalan.lproj/Localizable.strings index 098987ec6..847e6eb15 100644 --- a/SoObjects/Appointments/Catalan.lproj/Localizable.strings +++ b/SoObjects/Appointments/Catalan.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Tasca privada)"; vtodo_class2 = "(Tasca confidencial)"; /* Receipts */ -"Title:" = "Títol:"; -"Start:" = "Començament:"; -"End:" = "Final:"; - -"Receipt: users invited to a meeting" = "Recepció: usuaris invitats a una reunió"; -"You have invited the following attendees(s):" = "Heu invitat els assistents següents:"; -"... to attend the following event:" = "... a acudir a aquest esdeveniment:"; - -"Receipt: invitation updated" = "Recepció: invitació actualitzada"; -"The following attendees(s):" = "Els assistents següents:"; -"... have been notified of the changes to the following event:" = "... han estat notificats dels canvis en aquest esdeveniment:"; - -"Receipt: attendees removed from an event" = "Recepció: assistents suprimits d'un esdeveniment"; -"You have removed the following attendees(s):" = "Heu suprimit els assistents següents:"; -"... from the following event:" = "... d'aquest esdeveniment:"; +"The event \"%{Summary}\" was created" = "Es va crear l'esdeveniment \"%{Summary}\" "; +"The event \"%{Summary}\" was deleted" = "Es va esborrar l'esdeveniment \"%{Summary}\" "; +"The event \"%{Summary}\" was updated" = "Es va modificar l'esdeveniment \"%{Summary}\" "; +"The following attendees(s) were notified:" = "I va notificar als següents participants: "; +"The following attendees(s) were added:" = "Es van agregar els següents participants: "; +"The following attendees(s) were removed:" = "Heu suprimit els assistents següents:"; /* IMIP messages */ "startDate_label" = "Inici:"; @@ -35,14 +26,19 @@ vtodo_class2 = "(Tasca confidencial)"; /* Invitation */ "Event Invitation: \"%{Summary}\"" = "Invitació a l'esdeveniment: \"%{Summary}\""; "(sent by %{SentBy}) " = "(enviada per %{SentBy}) "; +"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} us ha invitat a %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} us ha invitat a %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"; /* Deletion */ "Event Cancelled: \"%{Summary}\"" = "Esdeveniment suspès: \"%{Summary}\""; +"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" += "%{Organizer} %{SentByText}ha suspès aquest esdeveniment: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"; "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}ha suspès aquest esdeveniment: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"; /* Update */ +"The appointment \"%{Summary}\" for the %{OldStartDate} has changed" += "La cita \"%{Summary}\" per al dia %{OldStartDate} ha canviat"; "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed" = "La cita \"%{Summary}\" per al dia %{OldStartDate} a les %{OldStartTime} ha canviat"; "The following parameters have changed in the \"%{Summary}\" meeting:" @@ -62,4 +58,5 @@ vtodo_class2 = "(Tasca confidencial)"; = "%{Attendee} %{SentByText}encara no s'ha decidit sobre la invitació a l'esdeveniment."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Nombre màxim de reserves simultànies (%{NumberOfSimultaneousBookings}) assolit per al recurs \"%{Cn}{%SystemEmail}\"."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "No es pot accedir al recurs: \"%{Cn} %{SystemEmail}\" "; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Nombre màxim de reserves simultànies (%{NumberOfSimultaneousBookings}) assolit per al recurs \"%{Cn} %{SystemEmail}\". L'esdeveniment que entra en conflicte és \"%{EventTitle}\", i comença el %{StartDate}."; diff --git a/SoObjects/Appointments/English.lproj/Localizable.strings b/SoObjects/Appointments/English.lproj/Localizable.strings index 22106a1b9..9bce92a0a 100644 --- a/SoObjects/Appointments/English.lproj/Localizable.strings +++ b/SoObjects/Appointments/English.lproj/Localizable.strings @@ -11,9 +11,9 @@ vtodo_class2 = "(Confidential task)"; "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:"; +"The following attendees(s) were notified:" = "The following attendee(s) were notified:"; +"The following attendees(s) were added:" = "The following attendee(s) were added:"; +"The following attendees(s) were removed:" = "The following attendee(s) were removed:"; /* IMIP messages */ "startDate_label" = "Start:"; diff --git a/SoObjects/Appointments/French.lproj/Localizable.strings b/SoObjects/Appointments/French.lproj/Localizable.strings index 7d9a84de3..4e5130cd3 100644 --- a/SoObjects/Appointments/French.lproj/Localizable.strings +++ b/SoObjects/Appointments/French.lproj/Localizable.strings @@ -24,7 +24,7 @@ vtodo_class2 = "(Tâche confidentielle)"; "comment_label" = "Description :"; /* Invitation */ -"Event Invitation: \"%{Summary}\"" = "Invitation à la réunion : \"%{Summary}\""; +"Event Invitation: \"%{Summary}\"" = "Invitation à la réunion : «%{Summary}»"; "(sent by %{SentBy}) " = "(envoyé par %{SentBy}) "; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}vous a invité à la réunion « %{Summary} ».\n\nDébut: %{StartDate}\nFin: %{EndDate}\nDescription: %{Description}"; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}vous a invité à la réunion « %{Summary} ».\n\nDébut: %{StartDate} à %{StartTime}\nFin: %{EndDate} à %{EndTime}\nDescription: %{Description}"; @@ -58,5 +58,5 @@ vtodo_class2 = "(Tâche confidentielle)"; = "%{Attendee} %{SentByText}choisit de reporter sa décision par rapport à votre invitation."; /* Resources */ -"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Impossible d'accéder à la ressource suivante: \"%{Cn} %{SystemEmail}\""; +"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/German.lproj/Localizable.strings b/SoObjects/Appointments/German.lproj/Localizable.strings index 7a484948d..0bfaa2771 100644 --- a/SoObjects/Appointments/German.lproj/Localizable.strings +++ b/SoObjects/Appointments/German.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Private Aufgabe)"; vtodo_class2 = "(Vertrauliche Aufgabe)"; /* Receipts */ -"Title:" = "Titel:"; -"Start:" = "Beginn:"; -"End:" = "Ende:"; - -"Receipt: users invited to a meeting" = "Empfangsbestätigung: Benutzer zum Termin eingeladen"; -"You have invited the following attendees(s):" = "Sie haben folgende Teilnehmer eingeladen:"; -"... to attend the following event:" = "... um an folgendem Termin teilzunehmen:"; - -"Receipt: invitation updated" = "Empfangsbestätigung: Einladung aktualisiert"; -"The following attendees(s):" = "Die folgenden Teilnehmer:"; -"... have been notified of the changes to the following event:" = "... wurden über die Änderung des folgenden Termins informiert:"; - -"Receipt: attendees removed from an event" = "Empfangsbestätigung: Teilnehmer eines Termins entfernt"; -"You have removed the following attendees(s):" = "Sie haben folgende Teilnehmer entfernt:"; -"... from the following event:" = "... von folgendem Termin:"; +"The event \"%{Summary}\" was created" = "Der Termin \"%{Summary}\" wurde angelegt"; +"The event \"%{Summary}\" was deleted" = "Der Termin \"%{Summary}\" wurde gelöscht"; +"The event \"%{Summary}\" was updated" = "Der Termin \"%{Summary}\" wurde geändert"; +"The following attendees(s) were notified:" = "Die folgenden Teilnehmer wurden benachrichtigt:"; +"The following attendees(s) were added:" = "Die folgenden Teilnehmer wurden hinzugefügt:"; +"The following attendees(s) were removed:" = "Die folgenden Teilnehmer wurden entfernt:"; /* IMIP messages */ "startDate_label" = "Beginn:"; @@ -36,7 +27,7 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; "Event Invitation: \"%{Summary}\"" = "Termineinladung: \"%{Summary}\""; "(sent by %{SentBy}) " = "(gesendet von %{SentBy}) "; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText} Hat Sie eingeladen zu %{Summary}.\n\nBeginn: %{StartDate}\nEnde: %{EndDate}\nBeschreibung: %{Description}"; -"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} hat Sie eingeladen zu %{Summary}.\n\nBeginn: %{StartDate} um %{StartTime}\nEnde: %{EndDate} um %{EndTime}\nBeschreibung: %{Description}"; +"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText} hat Sie eingeladen zu \"%{Summary}\".\n\nBeginn: %{StartDate} um %{StartTime}\nEnde: %{EndDate} um %{EndTime}\nBeschreibung: %{Description}"; /* Deletion */ "Event Cancelled: \"%{Summary}\"" = "Termin abgesagt: \"%{Summary}\""; @@ -49,7 +40,7 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; "The appointment \"%{Summary}\" for the %{OldStartDate} has changed" = "Die Verabredung \"%{Summary}\" am %{OldStartDate} wurde geändert"; "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed" -= "Der Termin \"%{Summary}\" für den %{OldStartDate} um %{OldStartTime} hat sich geändert"; += "Der Termin \"%{Summary}\" am %{OldStartDate} um %{OldStartTime} hat sich geändert"; "The following parameters have changed in the \"%{Summary}\" meeting:" = "Folgendes wurde am Termin \"%{Summary}\" geändert:"; "Please accept or decline those changes." @@ -67,4 +58,5 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; = "%{Attendee} %{SentByText} hat noch nicht über Ihre Termineinladung entschieden."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Die maximale Anzahl von gleichzeitigen Buchungen (%{NumberOfSimultaneousBookings}) für die Ressource \"%{Cn} %{SystemEmail}\" ist erreicht. Der kollidierende Termin ist \"%{EventTitle}\", und beginnt am %{StartDate}."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Kann auf folgende Ressource nicht zugreifen: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Die maximale Anzahl von gleichzeitigen Buchungen (%{NumberOfSimultaneousBookings}) für die Ressource \"%{Cn} %{SystemEmail}\" ist erreicht. Der kollidierende Termin ist \"%{EventTitle}\", und beginnt am %{StartDate}."; diff --git a/SoObjects/Appointments/Hungarian.lproj/Localizable.strings b/SoObjects/Appointments/Hungarian.lproj/Localizable.strings index 6c67e984c..65ba708e2 100644 --- a/SoObjects/Appointments/Hungarian.lproj/Localizable.strings +++ b/SoObjects/Appointments/Hungarian.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Magán feladat)"; vtodo_class2 = "(Bizalmas feladat)"; /* Receipts */ -"Title:" = "Cím:"; -"Start:" = "Kezdete:"; -"End:" = "Vége:"; - -"Receipt: users invited to a meeting" = "Visszaigazolás: meghívás találkozóra"; -"You have invited the following attendees(s):" = "Az alábbi résztvevőket hívta meg:"; -"... to attend the following event:" = "... hogy vegyen részt az alábbi eseményen:"; - -"Receipt: invitation updated" = "Visszaigazolás: meghívás módosítása"; -"The following attendees(s):" = "Az alábbi résztvevők:"; -"... have been notified of the changes to the following event:" = "lettek értesítve az alábbi esemény változásáról:"; - -"Receipt: attendees removed from an event" = "Visszaigazolás: résztvevők meghívásának visszavonása"; -"You have removed the following attendees(s):" = "Az alábbi résztvevők meghívását vonta vissza:"; -"... from the following event:" = "... az alábbi eseményről:"; +"The event \"%{Summary}\" was created" = "A \"%{Summary}\" esemény létre lett hozva"; +"The event \"%{Summary}\" was deleted" = "A \"%{Summary}\" esemény törölve lett"; +"The event \"%{Summary}\" was updated" = "A \"%{Summary}\" esemény módosítva lett"; +"The following attendees(s) were notified:" = "Az alábbi résztvevők lettek értesítve:"; +"The following attendees(s) were added:" = "Az alábbi résztvevők lettek hozzáadva:"; +"The following attendees(s) were removed:" = "Az alábbi résztvevők lettek eltávolítva:"; /* IMIP messages */ "startDate_label" = "Kezdete:"; @@ -67,4 +58,5 @@ vtodo_class2 = "(Bizalmas feladat)"; = "%{Attendee} %{SentByText}még meggondolja a meghívását."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Az egyidejű foglalások száma (%{NumberOfSimultaneousBookings}) elérte a maximumot \"%{Cn} %{SystemEmail}\"."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Az alábbi elem nem elérhető: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "A maximális egyidejű foglalás számát (%{NumberOfSimultaneousBookings}) elérte a(z) \"%{Cn} %{SystemEmail}\" elem esetében. Az ütköző esemény a(z) \"%{EventTitle}\", a kezdeti időpontja %{StartDate}."; diff --git a/SoObjects/Appointments/Russian.lproj/Localizable.strings b/SoObjects/Appointments/Russian.lproj/Localizable.strings index 8ba4e1883..95b2f21d1 100644 --- a/SoObjects/Appointments/Russian.lproj/Localizable.strings +++ b/SoObjects/Appointments/Russian.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Личная задача)"; vtodo_class2 = "(Конфиденциальная задача)"; /* Receipts */ -"Title:" = "Название:"; -"Start:" = "Начало:"; -"End:" = "Конец:"; - -"Receipt: users invited to a meeting" = "Подтверждение: пользователей пригласили на встречу"; -"You have invited the following attendees(s):" = "Вы пригласили следующих участников:"; -"... to attend the following event:" = "... участвовать в следующем мероприятии:"; - -"Receipt: invitation updated" = "Подтверждение: приглашение обновлено"; -"The following attendees(s):" = "Следующие участники:"; -"... have been notified of the changes to the following event:" = "... были уведомлены об изменениях следующего мероприятия:"; - -"Receipt: attendees removed from an event" = "Подтверждение: участники удалены из мероприятия"; -"You have removed the following attendees(s):" = "Вы удалили следующих приглашенных:"; -"... from the following event:" = "... из списка участников в следующем мероприятии:"; +"The event \"%{Summary}\" was created" = "Было создано мероприятие \"%{Summary}\""; +"The event \"%{Summary}\" was deleted" = "Мероприятие \"%{Summary}\" было удалено"; +"The event \"%{Summary}\" was updated" = "Мероприятие \"%{Summary}\" было обновлено"; +"The following attendees(s) were notified:" = "Следующие приглашенные были оповещены:"; +"The following attendees(s) were added:" = "Следующие люди были добавлены в список приглашенных:"; +"The following attendees(s) were removed:" = "Следующие люди были исключены из списка приглашенных:"; /* IMIP messages */ "startDate_label" = "Начало:"; @@ -67,4 +58,5 @@ vtodo_class2 = "(Конфиденциальная задача)"; = "%{Attendee} %{SentByText}не определился с желанием участвовать в запланированном мероприятии."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Уже подано максимальное количество заявок (%{NumberOfSimultaneousBookings}) на ресурс \"%{Cn} %{SystemEmail}\"."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Нет доступа к ресурсу: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Достигнуто предельное число заявок (%{NumberOfSimultaneousBookings}) на ресурс \"%{Cn} %{SystemEmail}\". Конкурирующее событие называется \"%{EventTitle}\", оно начинается %{StartDate}."; diff --git a/SoObjects/Appointments/SOGoAptMailDeletion.m b/SoObjects/Appointments/SOGoAptMailDeletion.m index 987a8fece..75509c59d 100644 --- a/SoObjects/Appointments/SOGoAptMailDeletion.m +++ b/SoObjects/Appointments/SOGoAptMailDeletion.m @@ -44,27 +44,14 @@ - (NSString *) getBody { - NSString *bodyFormat; + NSString *body; if (!values) [self setupValues]; - if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) - bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled" - @" this event: %{Summary}.\n\n" - @"Start: %{StartDate} at %{StartTime}\n" - @"End: %{EndDate} at %{EndTime}\n" - @"Description: %{Description}") - inContext: context]; - else - bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled" - @" this event: %{Summary}.\n\n" - @"Start: %{StartDate}\n" - @"End: %{EndDate}\n" - @"Description: %{Description}") - inContext: context]; + body = [[self generateResponse] contentAsString]; - return [values keysWithFormat: bodyFormat]; + return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; } @end diff --git a/SoObjects/Appointments/SOGoAptMailICalReply.m b/SoObjects/Appointments/SOGoAptMailICalReply.m index 8a0f3b140..ba796632b 100644 --- a/SoObjects/Appointments/SOGoAptMailICalReply.m +++ b/SoObjects/Appointments/SOGoAptMailICalReply.m @@ -1,6 +1,6 @@ /* SOGoAptMailICalReply - this file is part of SOGo * - * Copyright (C) 2010 Inverse inc. + * Copyright (C) 2010-2012 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -19,6 +19,7 @@ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ +#import #import #import @@ -105,14 +106,11 @@ return [values keysWithFormat: subjectFormat]; } -- (NSString *) getBody +- (NSString *) bodyStartText { NSString *bodyFormat; NSString *partStat, *delegate; - if (!values) - [self setupValues]; - partStat = [[attendee partStat] lowercaseString]; if ([partStat isEqualToString: @"accepted"]) bodyFormat = @"%{Attendee} %{SentByText}has accepted your event invitation."; @@ -135,7 +133,19 @@ else bodyFormat = @"%{Attendee} %{SentByText}has not yet decided upon your event invitation."; - return [values keysWithFormat: [self labelForKey: bodyFormat inContext: context]]; + return [values keysWithFormat: bodyFormat]; +} + +- (NSString *) getBody +{ + NSString *body; + + if (!values) + [self setupValues]; + + body = [[self generateResponse] contentAsString]; + + return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; } @end diff --git a/SoObjects/Appointments/SOGoAptMailInvitation.m b/SoObjects/Appointments/SOGoAptMailInvitation.m index 09be772ce..18b285afa 100644 --- a/SoObjects/Appointments/SOGoAptMailInvitation.m +++ b/SoObjects/Appointments/SOGoAptMailInvitation.m @@ -49,27 +49,14 @@ - (NSString *) getBody { - NSString *bodyFormat; + NSString *body; if (!values) [self setupValues]; - if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) - bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you" - @" to %{Summary}.\n\n" - @"Start: %{StartDate} at %{StartTime}\n" - @"End: %{EndDate} at %{EndTime}\n" - @"Description: %{Description}") - inContext: context]; - else - bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you" - @" to %{Summary}.\n\n" - @"Start: %{StartDate}\n" - @"End: %{EndDate}\n" - @"Description: %{Description}") - inContext: context]; + body = [[self generateResponse] contentAsString]; - return [values keysWithFormat: bodyFormat]; + return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; } @end diff --git a/SoObjects/Appointments/SOGoAptMailNotification.h b/SoObjects/Appointments/SOGoAptMailNotification.h index 984ca668d..407c25184 100644 --- a/SoObjects/Appointments/SOGoAptMailNotification.h +++ b/SoObjects/Appointments/SOGoAptMailNotification.h @@ -1,15 +1,15 @@ /* - Copyright (C) 2006-2010 Inverse inc. + Copyright (C) 2006-2012 Inverse inc. Copyright (C) 2000-2005 SKYRIX Software AG - This file is part of OpenGroupware.org. + This file is part of SOGo. - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. @@ -30,6 +30,7 @@ @class NSString; @class NSTimeZone; @class iCalEvent; +@class SOGoDateFormatter; /* * NOTE: We inherit from SoComponent in order to get the correct @@ -47,6 +48,7 @@ NSCalendarDate *newEndDate; NSString *organizerName; NSMutableDictionary *values; + SOGoDateFormatter *dateFormatter; } - (void) setupValues; @@ -66,6 +68,12 @@ - (NSCalendarDate *) oldEndDate; - (NSCalendarDate *) newEndDate; +- (NSString *) sentByText; +- (NSString *) formattedAptStartDate; +- (NSString *) formattedAptStartTime; +- (NSString *) formattedAptEndDate; +- (NSString *) formattedAptEndTime; + - (NSString *) getSubject; - (NSString *) getBody; diff --git a/SoObjects/Appointments/SOGoAptMailNotification.m b/SoObjects/Appointments/SOGoAptMailNotification.m index 63c694103..026137cc0 100644 --- a/SoObjects/Appointments/SOGoAptMailNotification.m +++ b/SoObjects/Appointments/SOGoAptMailNotification.m @@ -49,6 +49,7 @@ { apt = nil; values = nil; + dateFormatter = RETAIN([[context activeUser] dateFormatterInContext: context]); } return self; @@ -65,6 +66,7 @@ [newStartDate release]; [oldEndDate release]; [newEndDate release]; + [dateFormatter release]; [super dealloc]; } @@ -153,7 +155,105 @@ return organizerName; } -/* Helpers */ +- (NSString *) sentByText +{ + NSDictionary *sentByValues; + NSString *sentByText; + id value; + + sentByText = @""; + + if (organizerName) + { + value = [[apt organizer] sentBy]; + + if (value && [value length]) + { + sentByValues = [NSDictionary dictionaryWithObject: value + forKey: @"SentBy"]; + sentByText + = [sentByValues keysWithFormat: [self + labelForKey: @"(sent by %{SentBy}) " + inContext: context]]; + } + } + + return sentByText; +} + +- (NSString *) formattedAptStartDate +{ + NSString *s; + id value; + + value = [self newStartDate]; + s = @""; + + if (value) + s = [dateFormatter formattedDate: value]; + + return s; +} + + +- (NSString *) formattedAptStartTime +{ + NSString *s; + id value; + + value = [self newStartDate]; + s = @""; + + if (value && ![apt isAllDay]) + s = [dateFormatter formattedTime: value]; + + return s; +} + +- (NSString *) formattedAptEndDate +{ + NSString *s; + id value; + + value = [self newEndDate]; + s = @""; + + if (value) + s = [dateFormatter formattedDate: value]; + + return s; +} + +- (NSString *) formattedAptEndTime +{ + NSString *s; + id value; + + value = [self newEndDate]; + s = @""; + + if (value && ![apt isAllDay]) + s = [dateFormatter formattedTime: value]; + + return s; +} + +- (void) setupValues +{ + SOGoUser *user; + id value; + + user = [context activeUser]; + viewTZ = [[user userDefaults] timeZone]; + [viewTZ retain]; + + values = [NSMutableDictionary new]; + value = [self summary]; + if (!value) + value = @""; + + [values setObject: value forKey: @"Summary"]; +} /* Generate Response */ @@ -171,69 +271,4 @@ return nil; } -- (void) setupValues -{ - NSString *sentByText; - id value; - NSDictionary *sentByValues; - SOGoUser *user; - SOGoDateFormatter *dateFormatter; - - user = [context activeUser]; - viewTZ = [[user userDefaults] timeZone]; - [viewTZ retain]; - - values = [NSMutableDictionary new]; - value = [self summary]; - if (!value) - value = @""; - [values setObject: value forKey: @"Summary"]; - if (organizerName) - { - [values setObject: organizerName forKey: @"Organizer"]; - - value = [[apt organizer] sentBy]; - if (value) - { - sentByValues = [NSDictionary dictionaryWithObject: value - forKey: @"SentBy"]; - sentByText - = [sentByValues keysWithFormat: [self - labelForKey: @"(sent by %{SentBy}) " - inContext: context]]; - } - else - sentByText = @""; - - [values setObject: sentByText forKey: @"SentByText"]; - } - - dateFormatter = [[context activeUser] dateFormatterInContext: context]; - - value = [self newStartDate]; - if (value) - { - [values setObject: [dateFormatter shortFormattedDate: value] - forKey: @"StartDate"]; - if (![apt isAllDay]) - [values setObject: [dateFormatter formattedTime: value] - forKey: @"StartTime"]; - } - - value = [self newEndDate]; - if (value) - { - [values setObject: [dateFormatter shortFormattedDate: value] - forKey: @"EndDate"]; - if (![apt isAllDay]) - [values setObject: [dateFormatter formattedTime: value] - forKey: @"EndTime"]; - } - - value = [[self apt] comment]; - if (!value) - value = @""; - [values setObject: value forKey: @"Description"]; -} - @end diff --git a/SoObjects/Appointments/SOGoAptMailUpdate.m b/SoObjects/Appointments/SOGoAptMailUpdate.m index 5b413e38b..c88854da2 100644 --- a/SoObjects/Appointments/SOGoAptMailUpdate.m +++ b/SoObjects/Appointments/SOGoAptMailUpdate.m @@ -33,10 +33,31 @@ #import "SOGoAptMailNotification.h" @interface SOGoAptMailUpdate : SOGoAptMailNotification +{ + NSMutableDictionary *changes; + NSString *currentItem; +} + @end @implementation SOGoAptMailUpdate +- (id) init +{ + self = [super init]; + + changes = [[NSMutableDictionary alloc] init]; + + return self; +} + +- (void) dealloc +{ + RELEASE(currentItem); + RELEASE(changes); + [super dealloc]; +} + - (NSString *) valueForProperty: (NSString *) property withDateFormatter: (SOGoDateFormatter *) dateFormatter { @@ -64,7 +85,10 @@ if ([valueType isEqualToString: @"date"]) { [value setTimeZone: viewTZ]; - value = [dateFormatter formattedDateAndTime: value]; + if ([apt isAllDay]) + value = [dateFormatter formattedDate: value]; + else + value = [dateFormatter formattedDateAndTime: value]; } } else @@ -75,15 +99,13 @@ - (void) _setupBodyContentWithFormatter: (SOGoDateFormatter *) dateFormatter { - NSArray *updatedProperties; - NSMutableString *bodyContent; NSString *property, *label, *value; + NSArray *updatedProperties; int count, max; updatedProperties = [[iCalEventChanges changesFromEvent: previousApt toEvent: apt] updatedProperties]; - bodyContent = [NSMutableString new]; max = [updatedProperties count]; for (count = 0; count < max; count++) { @@ -96,27 +118,40 @@ label = [self labelForKey: [NSString stringWithFormat: @"%@_label", property] inContext: context]; - [bodyContent appendFormat: @" %@ %@\n", label, value]; + [changes setObject: value forKey: label]; } } - [values setObject: bodyContent forKey: @"_bodyContent"]; - [bodyContent release]; } -- (void) _setupBodyValuesWithFormatter: (SOGoDateFormatter *) dateFormatter +- (NSArray *) allChangesList +{ + return [changes allKeys]; +} + +- (void) setCurrentItem: (NSString *) theItem +{ + ASSIGN(currentItem, theItem); +} + +- (NSString *) currentItem +{ + return currentItem; +} + +- (NSString *) valueForCurrentItem +{ + return [changes objectForKey: currentItem]; +} + +- (NSString *) bodyStartText { NSString *bodyText; bodyText = [self labelForKey: @"The following parameters have changed" @" in the \"%{Summary}\" meeting:" inContext: context]; - [values setObject: [values keysWithFormat: bodyText] - forKey: @"_bodyStart"]; - [self _setupBodyContentWithFormatter: dateFormatter]; - [values setObject: [self labelForKey: @"Please accept" - @" or decline those changes." - inContext: context] - forKey: @"_bodyEnd"]; + + return [values keysWithFormat: bodyText]; } - (void) setupValues @@ -136,7 +171,7 @@ [values setObject: [dateFormatter formattedTime: date] forKey: @"OldStartTime"]; - [self _setupBodyValuesWithFormatter: dateFormatter]; + [self _setupBodyContentWithFormatter: dateFormatter]; } - (NSString *) getSubject @@ -162,11 +197,14 @@ - (NSString *) getBody { + NSString *body; + if (!values) [self setupValues]; - return [values keysWithFormat: - @"%{_bodyStart}\n%{_bodyContent}\n%{_bodyEnd}\n"]; + body = [[self generateResponse] contentAsString]; + + return [body stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; } @end diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 6c4c9ee97..8163cda53 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -1,9 +1,10 @@ /* SOGoCalendarComponent.m - this file is part of SOGo * - * Copyright (C) 2006-2011 Inverse inc. + * Copyright (C) 2006-2012 Inverse inc. * * Author: Wolfgang Sourdeau * Francis Lachapelle + * Ludovic Marcotte * * 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 @@ -844,8 +845,8 @@ /* text part */ headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; - [headerMap setObject: @"text/plain; charset=\"UTF-8\"" - forKey: @"content-type"]; + [headerMap setObject: @"text/html; charset=utf-8" + forKey: @"content-type"]; bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap]; [bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]]; @@ -926,8 +927,8 @@ /* text part */ headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; - [headerMap setObject: @"text/plain; charset=utf-8" - forKey: @"content-type"]; + [headerMap setObject: @"text/html; charset=utf-8" + forKey: @"content-type"]; bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap]; bodyData = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding]; [bodyPart setBody: bodyData]; @@ -951,6 +952,9 @@ } } +// +// +// - (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent from: (SOGoUser *) from { @@ -969,6 +973,9 @@ } } +// +// +// - (void) sendReceiptEmailForObject: (iCalRepeatableEntityObject *) object addedAttendees: (NSArray *) theAddedAttendees deletedAttendees: (NSArray *) theDeletedAttendees @@ -1069,6 +1076,9 @@ } +// +// +// - (iCalPerson *) findParticipantWithUID: (NSString *) uid { iCalEntityObject *component; @@ -1080,6 +1090,9 @@ return [component userAsAttendee: user]; } +// +// +// - (iCalPerson *) iCalPersonWithUID: (NSString *) uid { iCalPerson *person; @@ -1097,6 +1110,9 @@ return person; } +// +// +// - (NSArray *) getUIDsForICalPersons: (NSArray *) iCalPersons { iCalPerson *currentPerson; diff --git a/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings b/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings index e6e09e215..905d54adb 100644 --- a/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings +++ b/SoObjects/Appointments/SpanishArgentina.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Tarea privada)"; vtodo_class2 = "(Tarea confidencial)"; /* Receipts */ -"Title:" = "Título:"; -"Start:" = "Inicio:"; -"End:" = "Fin:"; - -"Receipt: users invited to a meeting" = "Recepción: usuarios invitados a una reunión"; -"You have invited the following attendees(s):" = "Ha invitado a los siguientes asistentes:"; -"... to attend the following event:" = "... para asistir al siguiente evento:"; - -"Receipt: invitation updated" = "Recepción: invitación actualizada"; -"The following attendees(s):" = "Los siguientes asistentes:"; -"... have been notified of the changes to the following event:" = "... han sido notificado de los cambios para el siguiente evento:"; - -"Receipt: attendees removed from an event" = "Recepción: asistentes eliminados de un evento"; -"You have removed the following attendees(s):" = "Ha eliminado a los siguiente asistentes:"; -"... from the following event:" = "... del siguiente evento:"; +"The event \"%{Summary}\" was created" = "Se creó el evento \"%{Summary}\""; +"The event \"%{Summary}\" was deleted" = "Se borró el evento \"%{Summary}\""; +"The event \"%{Summary}\" was updated" = "Se actualizó la información del evento \"%{Summary}\""; +"The following attendees(s) were notified:" = "Se notificó a los siguientes participantes:"; +"The following attendees(s) were added:" = "Se agregaron los siguientes participantes:"; +"The following attendees(s) were removed:" = "Se removieron los siguientes participantes:"; /* IMIP messages */ "startDate_label" = "Inicio:"; @@ -33,7 +24,7 @@ vtodo_class2 = "(Tarea confidencial)"; "comment_label" = "Comentario:"; /* Invitation */ -"Event Invitation: \"%{Summary}\"" = "Invitación al evento: "; +"Event Invitation: \"%{Summary}\"" = "Invitación al evento: \"%{Summary}\""; "(sent by %{SentBy}) " = "(enviado por %{SentBy}) "; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}lo ha invitado a %{Summary}.\n\nComienzo: %{StartDate}\nFin: %{EndDate}\nDescripción: %{Description}"; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}lo ha invitado %{Summary}.\n\nComienzo: %{StartDate} a las %{StartTime}\nFinalización: %{EndDate} a las %{EndTime}\nDescripción: %{Description}"; @@ -67,4 +58,5 @@ vtodo_class2 = "(Tarea confidencial)"; = "%{Attendee} %{SentByText}no ha tomado tadavia una decision respecto a esta cita."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Número máximo de reservas simultáneas (%{NumberOfSimultaneousBookings}) alcanzado para el recurso \"%{Cn} %{SystemEmail}\"."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "No se puede acceder a este recurso: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = " Número máximo de reservas simultáneas\n(%{NumberOfSimultaneousBookings}) reservas para el recurso \"%{Cn} %{SystemEmail}\". El evento que entra en conflicto es \"%{EventTitle}\", y comienza el %{StartDate}."; diff --git a/SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings b/SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings index 94fd6e882..337861071 100644 --- a/SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings +++ b/SoObjects/Appointments/SpanishSpain.lproj/Localizable.strings @@ -8,21 +8,12 @@ vtodo_class1 = "(Tarea privada)"; vtodo_class2 = "(Tarea confidencial)"; /* Receipts */ -"Title:" = "Título:"; -"Start:" = "Inicio:"; -"End:" = "Fin:"; - -"Receipt: users invited to a meeting" = "Recepción: usuarios invitados a una reunión"; -"You have invited the following attendees(s):" = "Ha invitado a los siguientes asistentes:"; -"... to attend the following event:" = "... para asistir al siguiente evento:"; - -"Receipt: invitation updated" = "Recepción: invitación actualizada"; -"The following attendees(s):" = "Lossiguientes asistentes:"; -"... have been notified of the changes to the following event:" = "... ha sido notificado de los cambios para el siguiente evento:"; - -"Receipt: attendees removed from an event" = "Recepción: asistentes eliminados de un evento"; -"You have removed the following attendees(s):" = "Ha eliminado a los siguiente asistentes:"; -"... from the following event:" = "... del siguiente evento:"; +"The event \"%{Summary}\" was created" = "El evento \"%{Summary}\" ha sido creado"; +"The event \"%{Summary}\" was deleted" = "El evento \"%{Summary}\" ha sido borrado"; +"The event \"%{Summary}\" was updated" = "El evento \"%{Summary}\" ha sido actualizado"; +"The following attendees(s) were notified:" = "Los invitados siguientes han sido notificado:"; +"The following attendees(s) were added:" = "Los invitados siguientes han sido añadido:"; +"The following attendees(s) were removed:" = "Los invitados siguientes han sido quitado:"; /* IMIP messages */ "startDate_label" = "Inicio:"; @@ -35,22 +26,19 @@ vtodo_class2 = "(Tarea confidencial)"; /* Invitation */ "Event Invitation: \"%{Summary}\"" = "Invitación al evento: \"% {Summary}\""; "(sent by %{SentBy}) " = "(enviado por %{SentBy}) "; -"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}le ha invitado a %{Summary}. - -Inicio: %{StartDate} a las %{StartTime} -Fin: %{EndDate} a las %{EndTime} -Descripción: %{Description}"; +"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}le ha invitado a %{Summary}.\n\nInicio: %{StartDate}\nFin: %{EndDate}\nDescripción: %{Description}"; +"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}le ha invitado a %{Summary}.\n\nInicio: %{StartDate} a las %{StartTime}\nFin: %{EndDate} a las %{EndTime}\nDescripción: %{Description}"; /* Deletion */ "Event Cancelled: \"%{Summary}\"" = "Evento Cancelado: \"% {Summary}\""; +"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" += "%{Organizer} %{SentByText}ha cancelado este evento: %{Summary}.\n\nInicio: %{StartDate}\nFin: %{EndDate}\nDescripción: %{Description}"; "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" -= "%{Organizer} %{SentByText} ha cancelado este evento: %{Summary}. - -Inicio: %{StartDate} a las %{StartTime} -Fin:%{EndDate} a las {EndTime} -Descripción: %{Description}"; += "%{Organizer} %{SentByText} ha cancelado este evento: %{Summary}.\n\nInicio: %{StartDate} a las %{StartTime}\nFin:%{EndDate} a las {EndTime}\nDescripción: %{Description}"; /* Update */ +"The appointment \"%{Summary}\" for the %{OldStartDate} has changed" += "El evento \"%{Summary}\" del %{OldStartDate} ha cambiado"; "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed" = "La cita \"%{Summary}\" para el %{OldStartDate} a las %{OldStartTime} ha cambiado"; "The following parameters have changed in the \"%{Summary}\" meeting:" @@ -70,4 +58,5 @@ Descripción: %{Description}"; = "%{Attendee} %{SentByText}no ha tomado tadavia una decision sobre esta cita."; /* Resources */ -"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Número máximo de reservas simultáneas (%{NumberOfSimultaneousBookings}) alcanzado para recurso \"%{Cn} %{SystemEmail}\"."; \ No newline at end of file +"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "No se puede acceder al recurso: \"%{Cn} %{SystemEmail}\""; +"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Numero maximo de reserva simultánea (%{NumberOfSimultaneousBookings}) alcanzada para el recurso \"%{Cn} %{SystemEmail}\". El evento generando el conflicto es \"%{EventTitle}\", y empeza el %{StartDate}."; diff --git a/SoObjects/Appointments/iCalPerson+SOGo.h b/SoObjects/Appointments/iCalPerson+SOGo.h index 184e67542..3ce9d31a5 100644 --- a/SoObjects/Appointments/iCalPerson+SOGo.h +++ b/SoObjects/Appointments/iCalPerson+SOGo.h @@ -1,8 +1,9 @@ /* iCalPerson+SOGo.h - this file is part of SOGo * - * Copyright (C) 2007-2009 Inverse inc. + * Copyright (C) 2007-2012 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * 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 diff --git a/SoObjects/Appointments/iCalPerson+SOGo.m b/SoObjects/Appointments/iCalPerson+SOGo.m index e0d07e956..b7dc8e941 100644 --- a/SoObjects/Appointments/iCalPerson+SOGo.m +++ b/SoObjects/Appointments/iCalPerson+SOGo.m @@ -1,8 +1,9 @@ /* iCalPerson+SOGo.m - this file is part of SOGo * - * Copyright (C) 2007-2009 Inverse inc. + * Copyright (C) 2007-2012 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * 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 @@ -33,11 +34,23 @@ static SOGoUserManager *um = nil; - (NSString *) mailAddress { NSString *cn, *email, *mailAddress; + unsigned int len; cn = [self cnWithoutQuotes]; email = [self rfc822Email]; - if ([cn length]) - mailAddress = [NSString stringWithFormat:@"%@ <%@>", cn, email]; + len = [cn length]; + + if (len) + { + // We must check if we have to double-quote properly the person's name, + // in case for example we find a comma + if ([cn characterAtIndex: 0] != '"' && + [cn characterAtIndex: len-1] != '"' && + [cn rangeOfString: @","].length) + mailAddress = [NSString stringWithFormat:@"\"%@\" <%@>", cn, email]; + else + mailAddress = [NSString stringWithFormat:@"%@ <%@>", cn, email]; + } else mailAddress = email; diff --git a/UI/Common/Catalan.lproj/Localizable.strings b/UI/Common/Catalan.lproj/Localizable.strings index 346105191..90282b94c 100644 --- a/UI/Common/Catalan.lproj/Localizable.strings +++ b/UI/Common/Catalan.lproj/Localizable.strings @@ -37,10 +37,16 @@ "Sorry, the user rights can not be configured for that object." = "Els permisos d'accés no es poden configurar per a aquest objecte."; +"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?" + = "Qualsevol usuari amb un compte en el sistema tindrà accés a la seua bústia de correu \"%{0}\". Està segur de voler donar accés a qualsevol usuari en el sistema? "; "Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?" = "Qualsevol altre usuari amb un compte al sistema serà capaç d'accedir al seu calendari \"%{0}\". ¿Està vostè segur de voler permetre aço?"; "Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?" = "Potencialment, qualsevol usuari d'Internet podrà accedir al seu calendari \"% {0}\", encara que no tinga un compte en aquest sistema. Aquesta informació és adequada per publicar-la en Internet?"; +"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?" + = "Qualsevol usuari amb un compte en el sistema tindrà accés al seu calendari \"%{0}\". Està segur de voler donar accés a qualsevol usuari en el sistema? "; +"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?" + = "Qualsevol usuari amb un compte en el sistema tindrà accés a la seua llibreta d'adreces \"%{0}\". Està segur de voler donar accés a qualsevol usuari en el sistema? "; "Give Access" = "Donar accés"; "Keep Private" = "Mantenir en privat"; diff --git a/UI/Contacts/Catalan.lproj/Localizable.strings b/UI/Contacts/Catalan.lproj/Localizable.strings index e5c0d9bea..2249ab989 100644 --- a/UI/Contacts/Catalan.lproj/Localizable.strings +++ b/UI/Contacts/Catalan.lproj/Localizable.strings @@ -195,9 +195,11 @@ "Lists can't be moved or copied." = "Les llistes no es poden moure o copiar."; "Export" = "Exportar"; "Export Address Book..." = "Exportar llibreta..."; +"View Raw Source" = "Veure l'original "; "Import Cards" = "Importar contactes"; "Select a vCard or LDIF file." = "Seleccionar una targeta de presentació electrònica o un fitxer LDIF."; "Upload" = "Carregar"; +"Uploading" = "Carregant"; "Done" = "Fet"; "An error occured while importing contacts." = "Hi ha hagut un error en importar els contactes."; "No card was imported." = "No s'ha importat cap contacte."; diff --git a/UI/Contacts/Dutch.lproj/Localizable.strings b/UI/Contacts/Dutch.lproj/Localizable.strings index ffbc04f29..6025fafa9 100644 --- a/UI/Contacts/Dutch.lproj/Localizable.strings +++ b/UI/Contacts/Dutch.lproj/Localizable.strings @@ -1,6 +1,6 @@ /* this file is in UTF-8 format! */ -"Contact" = "Herlaad"; +"Contact" = "Contactpersoon"; "Address" = "Adres"; "Photos" = "Foto's"; "Other" = "Overige"; diff --git a/UI/Contacts/Hungarian.lproj/Localizable.strings b/UI/Contacts/Hungarian.lproj/Localizable.strings index 0290126c6..ae46f7b79 100644 --- a/UI/Contacts/Hungarian.lproj/Localizable.strings +++ b/UI/Contacts/Hungarian.lproj/Localizable.strings @@ -195,9 +195,11 @@ "Lists can't be moved or copied." = "Lists can't be moved or copied."; "Export" = "Export"; "Export Address Book..." = "Export Address Book..."; +"View Raw Source" = "Forrás megtekintése"; "Import Cards" = "Import Cards"; "Select a vCard or LDIF file." = "Select LDIF or vCard file."; "Upload" = "Upload"; +"Uploading" = "Feltöltés"; "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/Contacts/Russian.lproj/Localizable.strings b/UI/Contacts/Russian.lproj/Localizable.strings index 884fa7d9e..b04d20f0e 100644 --- a/UI/Contacts/Russian.lproj/Localizable.strings +++ b/UI/Contacts/Russian.lproj/Localizable.strings @@ -195,9 +195,11 @@ "Lists can't be moved or copied." = "Списки не могут быть перемещены или скопированы."; "Export" = "Экспорт"; "Export Address Book..." = "Экспорт адресной книги..."; +"View Raw Source" = "Посмотреть исходный код"; "Import Cards" = "Импорт записей"; "Select a vCard or LDIF file." = "Выберите файл vCard или LDIF."; "Upload" = "Загрузить"; +"Uploading" = "Закачивается"; "Done" = "Готово"; "An error occured while importing contacts." = "Произошла ошибка при импорте контактов."; "No card was imported." = "Записи не были импортированы."; diff --git a/UI/Contacts/SpanishArgentina.lproj/Localizable.strings b/UI/Contacts/SpanishArgentina.lproj/Localizable.strings index ed776eb4e..c6f890d78 100644 --- a/UI/Contacts/SpanishArgentina.lproj/Localizable.strings +++ b/UI/Contacts/SpanishArgentina.lproj/Localizable.strings @@ -94,7 +94,7 @@ "Work:" = "Trabajo:"; "Home:" = "Casa:"; "Fax:" = "Fax:"; -"Mobile:" = "Celularl:"; +"Mobile:" = "Celular:"; "Pager:" = "Buscapersonas:"; /* categories */ @@ -121,7 +121,7 @@ "Note:" = "Nota:"; "Timezone:" = "Zona horaria:"; "Birthday:" = "Fecha de nacimiento:"; -"Birthday (yyyy-mm-dd):" = "Fecha e nacimiento (yyyy-mm-dd):"; +"Birthday (yyyy-mm-dd):" = "Fecha e nacimiento (aaaa-mm-dd):"; "Freebusy URL:" = "URL de disponibilidad:"; "Add as..." = "Añadir como..."; @@ -162,15 +162,15 @@ "Public Access" = "Acceso público"; "This person can add cards to this addressbook." -= "Esta persona puede añadir nuevos contactos a esta libreta de direcciones."; += "Esta persona puede añadir nuevos contactos a la libreta de direcciones."; "This person can edit the cards of this addressbook." -= "Esta persona puede modificar los contactos de esta libreta de direcciones."; += "Esta persona puede modificar los contactos de la libreta de direcciones."; "This person can list the content of this addressbook." -= "Esta persona puede listar los contactos de esta libreta de direcciones."; += "Esta persona puede listar los contactos de la libreta de direcciones."; "This person can read the cards of this addressbook." -= "Esta persona puede leer los contactos de esta libreta de direcciones."; += "Esta persona puede leer los contactos de la libreta de direcciones."; "This person can erase cards from this addressbook." -= "Esta persona puede borrar los contactos de esta libreta de direcciones."; += "Esta persona puede borrar los contactos de la libreta de direcciones."; "The selected contact has no email address." = "El contacto seleccionado no tiene dirección de correo electrónico."; @@ -201,8 +201,8 @@ "Upload" = "Cargar"; "Uploading" = "Cargando"; "Done" = "Hecho"; -"An error occured while importing contacts." = "Ha ocurrido un error mientras importaba contactos."; -"No card was imported." = "El contacto no ha sido importado."; +"An error occured while importing contacts." = "Ha ocurrido un error mientras se importaban los contactos."; +"No card was imported." = "No se ha importado ningún contacto."; "A total of %{0} cards were imported in the addressbook." = "Un total de %{0} contactos han sido importados a la libreta de direcciones."; "Reload" = "Recargar"; diff --git a/UI/MailPartViewers/Russian.lproj/Localizable.strings b/UI/MailPartViewers/Russian.lproj/Localizable.strings index 194bff177..529206e1f 100644 --- a/UI/MailPartViewers/Russian.lproj/Localizable.strings +++ b/UI/MailPartViewers/Russian.lproj/Localizable.strings @@ -42,5 +42,5 @@ reply_info = "Это ответ на Ваше приглашение на мер "Subject" = "Тема"; "From" = "От"; "Date" = "Дата"; -"To" = "К"; +"To" = "Кому"; "Issuer" = "Эмитент"; diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 53404fa7d..8f5d3daca 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -55,7 +55,7 @@ static NSArray *BannedTags = nil; /* Tags that can't have any contents (no end tag) */ -static NSArray *VoidTags = nil; +static NSArray *VoidTags= nil; static xmlCharEncoding _xmlCharsetForCharset (NSString *charset) @@ -141,14 +141,16 @@ _xmlCharsetForCharset (NSString *charset) static NSData* _sanitizeContent(NSData *theData) { NSMutableData *d; + NSString *found_tag, *tag; + NSEnumerator *tags; const char *bytes; + char *buf; int i, j, len; - BOOL seen_head; + BOOL found_delimiter; d = [NSMutableData dataWithData: theData]; bytes = [d bytes]; len = [d length]; - seen_head = NO; i = 0; while (i < len) @@ -164,14 +166,14 @@ static NSData* _sanitizeContent(NSData *theData) (*(bytes+3) == 'a' || *(bytes+3) == 'A') && (*(bytes+4) == 'd' || *(bytes+4) == 'D') && (*(bytes+7) == '>')) - seen_head = YES; + break; } // We search for something like : // // // - if (!seen_head && i < len-9) + if (i < len-9) { if ((*bytes == 'c' || *bytes == 'C') && (*(bytes+1) == 'h' || *(bytes+1) == 'H') && @@ -184,6 +186,7 @@ static NSData* _sanitizeContent(NSData *theData) { // We search until we find a '"' or a space j = 8; + found_delimiter = YES; while (*(bytes+j) != ' ' && *(bytes+j) != '"') { @@ -191,12 +194,16 @@ static NSData* _sanitizeContent(NSData *theData) // We haven't found anything, let's return the data untouched if ((i+j) >= len) - return theData; + { + found_delimiter = NO; + break; + } } - - [d replaceBytesInRange: NSMakeRange(i, j) - withBytes: NULL - length: 0]; + + if (found_delimiter) + [d replaceBytesInRange: NSMakeRange(i, j) + withBytes: NULL + length: 0]; break; } } @@ -204,6 +211,89 @@ static NSData* _sanitizeContent(NSData *theData) bytes++; i++; } + + /* + * Replace badly formatted void tags + * + * A void tag that begins with a slash is considered invalid. + * We remove the slash from those tags. + * + * Ex:
is replaced by
+ */ + + if (!VoidTags) + { + /* see http://www.w3.org/TR/html4/index/elements.html */ + VoidTags = [[NSArray alloc] initWithObjects: @"area", @"base", + @"basefont", @"br", @"col", @"frame", @"hr", + @"img", @"input", @"isindex", @"link", + @"meta", @"param", @"", nil]; + } + + bytes = [d bytes]; + len = [d length]; + i = 0; + while (i < len) + { + if (i < len-3) + { + // Search for ending tags + if ((*bytes == '<') && (*(bytes+1) == '/')) + { + i += 2; + bytes += 2; + j = 0; + found_delimiter = YES; + + while (*(bytes+j) != '>') + { + j++; + if ((i+j) >= len) + { + found_delimiter = NO; + break; + } + } + + if (found_delimiter && j > 0) + { + // Copy the ending tag to a NSString + buf = malloc((j+1) * sizeof(char)); + memset (buf, 0, j+1); + memcpy (buf, bytes, j); + found_tag = [NSString stringWithCString: buf encoding: NSASCIIStringEncoding]; + + tags = [VoidTags objectEnumerator]; + tag = [tags nextObject]; + while (tag) + { + if ([tag caseInsensitiveCompare: found_tag] == NSOrderedSame) + { + // Remove the leading slash + NSLog(@"Found void tag with invalid leading slash: ", found_tag); + i--; + [d replaceBytesInRange: NSMakeRange(i, 1) + withBytes: NULL + length: 0]; + bytes = [d bytes]; + bytes += i; + len = [d length]; + break; + } + tag = [tags nextObject]; + } + free(buf); + + // Continue the parsing after end tag + i += j; + bytes += j; + } + } + } + + bytes++; + i++; + } return d; } diff --git a/UI/MailerUI/Catalan.lproj/Localizable.strings b/UI/MailerUI/Catalan.lproj/Localizable.strings index 08a333ff8..49f1ae897 100644 --- a/UI/MailerUI/Catalan.lproj/Localizable.strings +++ b/UI/MailerUI/Catalan.lproj/Localizable.strings @@ -283,9 +283,9 @@ = "Els missatges no poden traslladar-se a la paperera. Els voleu esborrar immediatament?"; /* Message editing */ -"error_validationfailed" = "Error de validació"; "error_missingsubject" = "No heu indicat l'assumpte"; "error_missingrecipients" = "No heu indicat els destinataris"; +"Send Anyway" = "Enviar igualment"; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "No s'ha pogut enviar el missatge: tots els destinataris són incorrectes."; diff --git a/UI/MailerUI/Hungarian.lproj/Localizable.strings b/UI/MailerUI/Hungarian.lproj/Localizable.strings index 78991a536..afb363b25 100644 --- a/UI/MailerUI/Hungarian.lproj/Localizable.strings +++ b/UI/MailerUI/Hungarian.lproj/Localizable.strings @@ -283,9 +283,9 @@ = "Az üzeneteket nem lehetett a szemétkosárba helyezni. Kívánja őket közvetlenül törölni?"; /* Message editing */ -"error_validationfailed" = "Az ellenőrzés végrehatása nem sikerült"; "error_missingsubject" = "Az üzenet tárgya hiányzik"; "error_missingrecipients" = "Nincsenek címzettek megadva"; +"Send Anyway" = "Így küldöm el"; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "Az üzenetet nem lehetett elküldeni: az összes címzett érvénytelen."; diff --git a/UI/MailerUI/Russian.lproj/Localizable.strings b/UI/MailerUI/Russian.lproj/Localizable.strings index cbf37944e..e4410cf5d 100644 --- a/UI/MailerUI/Russian.lproj/Localizable.strings +++ b/UI/MailerUI/Russian.lproj/Localizable.strings @@ -283,9 +283,9 @@ = "Сообщения не могут быть помещены в корзину. Хотите ли вы уничтожить их немедленно?"; /* Message editing */ -"error_validationfailed" = "Проверка завершилась неудачей"; "error_missingsubject" = "Тема сообщения не указана"; "error_missingrecipients" = "Не указан адрес получателя"; +"Send Anyway" = "Всё равно послать"; /* Message sending */ "cannot send message: (smtp) all recipients discarded" = "Не удается отправить сообщение: всем получателям, все получатели являются недействительными."; diff --git a/UI/PreferencesUI/Catalan.lproj/Localizable.strings b/UI/PreferencesUI/Catalan.lproj/Localizable.strings index b3b62ed52..140fc1e83 100644 --- a/UI/PreferencesUI/Catalan.lproj/Localizable.strings +++ b/UI/PreferencesUI/Catalan.lproj/Localizable.strings @@ -30,6 +30,7 @@ "Disable auto reply on" = "Desactivar la resposta automàtica en"; "Please specify your message and your email addresses for which you want to enable auto reply." = "Especifiqueu el missatge i les adreces de correu per a les quals voleu activar la resposta automàtica."; +"Your vacation message must not end with a single dot on a line." = "El seu missatge d'autoresposta per vacances no ha d'acabar amb un punt en una línia a part. "; "End date of your auto reply must be in the future." = "La data de finalització de la seva resposta automàtica ha d'estar en el futur."; @@ -76,11 +77,17 @@ "longDateFmt_3" = "%e de %b de %Y"; "longDateFmt_4" = "%e %B %Y"; "longDateFmt_5" = ""; +"longDateFmt_6" = ""; +"longDateFmt_7" = ""; +"longDateFmt_8" = ""; +"longDateFmt_9" = ""; +"longDateFmt_10" = ""; "timeFmt_0" = "%H:%M"; "timeFmt_1" = "%H.%M"; "timeFmt_2" = "%H h. %M"; "timeFmt_3" = ""; +"timeFmt_4" = ""; /* calendar */ "Week begins on :" = "Setmana comença en: "; @@ -153,12 +160,16 @@ "Full Name:" = "Nom complet:"; "Email:" = "Correu electrònic:"; +"Reply To Email:" = "Respondre a aquesta adreça de correu: "; "Signature:" = "Signatura:"; "(Click to create)" = "(Clic per a crear-la)"; "Signature" = "Signatura"; "Please enter your signature below:" = "Si us plau, poseu la signatura a sota:"; +"Please specify a valid sender address." = "Per favor, especifique una adreça vàlida per al remitent. "; +"Please specify a valid reply-to address." = "Per favor, especifique una adreça de resposta vàlida. "; + /* Additional Parameters */ "Additional Parameters" = "Paràmetres addicionals"; @@ -168,11 +179,11 @@ "Change" = "Canviar"; /* Event+task classifications */ -"Default events classification :" = "Default events classification :"; -"Default tasks classification :" = "Default tasks classification :"; -"PUBLIC_item" = "Public"; -"CONFIDENTIAL_item" = "Confidential"; -"PRIVATE_item" = "Private"; +"Default events classification :" = "Classificació per defecte dels esdeveniments "; +"Default tasks classification :" = "Classificació per defecte de les tasques "; +"PUBLIC_item" = "Públic "; +"CONFIDENTIAL_item" = "Confidencial "; +"PRIVATE_item" = "Privat "; /* Event+task categories */ "category_none" = "Cap"; @@ -189,7 +200,7 @@ "choose" = "Choose ..."; "Catalan" = "Català"; "Czech" = "Česky"; -"DanishDenmark" = "Dansk (Danmark)"; +"Danish" = "Dansk (Danmark)"; "Dutch" = "Nederlands"; "English" = "English"; "French" = "Français"; @@ -271,6 +282,7 @@ "Label 4" = "Etiqueta 4"; "Label 5" = "Etiqueta 5"; +"The password was changed successfully." = "La contrasenya s'ha canviat correctament"; "Password must not be empty." = "La contrasenya no ha d'estar buida."; "The passwords do not match. Please try again." = "Les contrasenyes no coincideixen. Intenta-ho de nou."; "Password change failed" = "Ha fallat el canvi de contrasenya"; diff --git a/UI/PreferencesUI/Dutch.lproj/Localizable.strings b/UI/PreferencesUI/Dutch.lproj/Localizable.strings index 544af48fe..2748d7e7d 100644 --- a/UI/PreferencesUI/Dutch.lproj/Localizable.strings +++ b/UI/PreferencesUI/Dutch.lproj/Localizable.strings @@ -167,6 +167,9 @@ "Signature" = "Ondertekening"; "Please enter your signature below:" = "Stel de ondertekening hieronder op:"; +"Please specify a valid sender address." = "Geef alstublieft een geldig afzendadres aan."; +"Please specify a valid reply-to address." = "Geef alstublieft een geldig antwoordadres aan."; + /* Additional Parameters */ "Additional Parameters" = "Extra Parameters"; @@ -279,6 +282,7 @@ "Label 4" = "Label 4"; "Label 5" = "Label 5"; +"The password was changed successfully." = "Het wachtwoord is met succes veranderd."; "Password must not be empty." = "Wachtwoord mag niet leeg zijn."; "The passwords do not match. Please try again." = "De wachtwoorden komen niet overeen. Probeer opnieuw."; "Password change failed" = "Wachtwoord wijzigen mislukt"; diff --git a/UI/PreferencesUI/German.lproj/Localizable.strings b/UI/PreferencesUI/German.lproj/Localizable.strings index d6c219a6e..0a6227f00 100644 --- a/UI/PreferencesUI/German.lproj/Localizable.strings +++ b/UI/PreferencesUI/German.lproj/Localizable.strings @@ -70,7 +70,7 @@ "shortDateFmt_14" = ""; "shortDateFmt_15" = ""; - + "longDateFmt_0" = "%A, %d. %B %Y"; "longDateFmt_1" = "%A, %e. %B %Y"; "longDateFmt_2" = "%a. %d. %B %Y"; @@ -81,7 +81,6 @@ "longDateFmt_7" = "%a. %e. %b. %Y"; "longDateFmt_8" = "%d. %B %Y"; "longDateFmt_9" = "%e. %B %Y"; - "longDateFmt_10" = ""; "timeFmt_0" = "%H:%M"; @@ -161,12 +160,16 @@ "Full Name:" = "Name:"; "Email:" = "E-Mail-Adresse:"; +"Reply To Email:" = "\"Antworten An\" E-Mail-Adresse (Reply-To):"; "Signature:" = "Signatur:"; "(Click to create)" = "(Klick zum Erstellen)"; "Signature" = "Signatur"; "Please enter your signature below:" = "Bitte fügen Sie die Signatur hier ein:"; +"Please specify a valid sender address." = "Bitte geben Sie eine gültige Absenderadresse an."; +"Please specify a valid reply-to address." = "Bitte geben Sie eine gültige \"Antworten An\"-Adresse (Reply-To) an."; + /* Additional Parameters */ "Additional Parameters" = "Zusätzliche Einstellungen"; @@ -279,6 +282,7 @@ "Label 4" = "Label 4"; "Label 5" = "Label 5"; +"The password was changed successfully." = "Das Passwort wurde erfolgreich geändert."; "Password must not be empty." = "Das Passwort darf nicht leer sein."; "The passwords do not match. Please try again." = "Die Passwörter stimmen nicht überein. Bitte versuchen Sie es noch einmal."; "Password change failed" = "Passwortänderung fehlgeschlagen."; diff --git a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings index 70a7df7f0..14f8c4554 100644 --- a/UI/PreferencesUI/Hungarian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Hungarian.lproj/Localizable.strings @@ -87,6 +87,7 @@ "timeFmt_1" = "%I:%M %p"; "timeFmt_2" = ""; "timeFmt_3" = ""; +"timeFmt_4" = ""; /* calendar */ "Week begins on :" = "Hét kezdőnapja:"; @@ -159,12 +160,16 @@ "Full Name:" = "Teljes név:"; "Email:" = "Email cím:"; +"Reply To Email:" = "Válaszlevél"; "Signature:" = "Aláírás:"; "(Click to create)" = "(A létrehozáshoz kattintson ide)"; "Signature" = "Aláírás"; "Please enter your signature below:" = "Kérem itt adja meg az aláírását"; +"Please specify a valid sender address." = "Egy érvényes feladó címet adjon meg."; +"Please specify a valid reply-to address." = "Egy érvényes válaszcímet adjon meg."; + /* Additional Parameters */ "Additional Parameters" = "További beállítások"; @@ -277,6 +282,7 @@ "Label 4" = "Címke 4"; "Label 5" = "Címke 5"; +"The password was changed successfully." = "A jelszó megváltoztatása sikeres."; "Password must not be empty." = "Le mot de passe ne doit pas être vide."; "The passwords do not match. Please try again." = "Les mots de passe ne sont pas identiques. Essayez de nouveau."; "Password change failed" = "Échec au changement"; diff --git a/UI/PreferencesUI/Russian.lproj/Localizable.strings b/UI/PreferencesUI/Russian.lproj/Localizable.strings index fd5950014..b7a6d3b28 100644 --- a/UI/PreferencesUI/Russian.lproj/Localizable.strings +++ b/UI/PreferencesUI/Russian.lproj/Localizable.strings @@ -160,12 +160,16 @@ "Full Name:" = "Full Name:"; "Email:" = "Email:"; +"Reply To Email:" = "Ответить на Email:"; "Signature:" = "Подпись:"; "(Click to create)" = "(Click to create)"; "Signature" = "Подпись"; "Please enter your signature below:" = "Please enter your signature below:"; +"Please specify a valid sender address." = "Пожалуйста укажите правильный адрес отправителя."; +"Please specify a valid reply-to address." = "Пожалуйста укажите правильный адрес для ответа."; + /* Additional Parameters */ "Additional Parameters" = "Дополнительные параметры"; @@ -278,6 +282,7 @@ "Label 4" = "Label 4"; "Label 5" = "Label 5"; +"The password was changed successfully." = "Пароль был успешно изменен."; "Password must not be empty." = "Пароль не должен быть пустым"; "The passwords do not match. Please try again." = "Пароли не совпадают. Пожалуйста попробуйте заново."; "Password change failed" = "Изменение пароля не удалось"; diff --git a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings index 8c98086d2..20b542229 100644 --- a/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings @@ -22,10 +22,10 @@ /* vacation (auto-reply) */ "Enable vacation auto reply" = "Activar respuesta automática por vacaciones"; -"Auto reply message :" = "Mensaje de respuesta automática :"; -"Email addresses (separated by commas) :" = "Dirección de correo (separado por comas) :"; +"Auto reply message :" = "Mensaje de respuesta automática:"; +"Email addresses (separated by commas) :" = "Dirección de correo (separado por comas):"; "Add default email addresses" = "Añadir dirección de correo por defecto"; -"Days between responses :" = "Dias entre respuestas :"; +"Days between responses :" = "Dias entre respuestas:"; "Do not send responses to mailing lists" = "No enviar respuestas a listas de correo"; "Disable auto reply on" = "Deshabilitar la autorrespuesta en la siguiente fecha"; "Please specify your message and your email addresses for which you want to enable auto reply." @@ -167,6 +167,9 @@ "Signature" = "Firma"; "Please enter your signature below:" = "Por favor, escriba su firma abajo:"; +"Please specify a valid sender address." = "Por favor, especifique una dirección válida para el remitente."; +"Please specify a valid reply-to address." = "Por favor, especifique una dirección de respuesta válida."; + /* Additional Parameters */ "Additional Parameters" = "Parámetros Adicionales"; @@ -279,6 +282,7 @@ "Label 4" = "Etiqueta 4"; "Label 5" = "Etiqueta 5"; +"The password was changed successfully." = "El cambio de clave fue exitoso"; "Password must not be empty." = "La contraseña no puede estar en blanco"; "The passwords do not match. Please try again." = "Las contraseñas no coinciden. Por favor intente de nuevo"; "Password change failed" = "El cambio de contraseña falló"; diff --git a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings index fa14c0e88..8261b8674 100644 --- a/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings +++ b/UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings @@ -167,6 +167,9 @@ "Signature" = "Firma"; "Please enter your signature below:" = "Por favor, ponga su firma abajo:"; +"Please specify a valid sender address." = "Por favor, especifica una dirección de correo electrónico valida para el remitente."; +"Please specify a valid reply-to address." = "Por favor, especifica una dirección de correo electrónico valida para responder."; + /* Additional Parameters */ "Additional Parameters" = "Parámetros Adicionales"; @@ -279,6 +282,7 @@ "Label 4" = "Etiqueta 4"; "Label 5" = "Etiqueta 5"; +"The password was changed successfully." = "La contraseña se ha cambiado correctamente."; "Password must not be empty." = "La contraseña no puede estar vacía."; "The passwords do not match. Please try again." = "Las contraseñas no coinciden. Por favor, inténtalo de nuevo."; "Password change failed" = "Cambio de contraseña fallido"; diff --git a/UI/Scheduler/Catalan.lproj/Localizable.strings b/UI/Scheduler/Catalan.lproj/Localizable.strings index f8bda1b69..e5fd66ec3 100644 --- a/UI/Scheduler/Catalan.lproj/Localizable.strings +++ b/UI/Scheduler/Catalan.lproj/Localizable.strings @@ -110,6 +110,7 @@ "Import Events" = "Importar esdeveniments"; "Select an iCalendar file (.ics)." = "Seleccionar un fitxer iCalendar (.ics)."; "Upload" = "Carregar"; +"Uploading" = "carregant "; "Publish Calendar..." = "Publicar calendari..."; "Reload Remote Calendars" = "Actualitzar calendaris remots"; "Properties" = "Propietats"; @@ -536,6 +537,10 @@ vtodo_class2 = "(Tasca confidencial)"; "Show alarms" = "Mostra les alarmes"; "Show tasks" = "Mostra les tasques"; +"Receive a mail when I modify my calendar" = "Rebre un correu de notificació quan modifique el meu calendari"; +"Receive a mail when someone else modifies my calendar" = "Rebre un correu de notificació quan altra persona modifique el meu calendari "; +"When I modify my calendar, send a mail to:" = "Quan modifique el meu calendari, enviar un correu a: "; + "Links to this Calendar" = "Enllaços a aquest calendari"; "Authenticated User Access" = "Accés autenticat"; "CalDAV URL" = "url CalDAV"; @@ -564,6 +569,7 @@ vtodo_class2 = "(Tasca confidencial)"; "Delete Task" = "Esborrar tasca"; "Delete Event" = "Esorrar esdeveniment"; "Copy event to my calendar" = "Copiar l'esdeveniment al meu calendari"; +"View Raw Source" = "Veure l'original"; "Subscribe to a web calendar..." = "Subscriure's a un calendari web..."; "URL of the Calendar" = "URL del calendari"; diff --git a/UI/Scheduler/German.lproj/Localizable.strings b/UI/Scheduler/German.lproj/Localizable.strings index 738dc0fea..edc8861d2 100644 --- a/UI/Scheduler/German.lproj/Localizable.strings +++ b/UI/Scheduler/German.lproj/Localizable.strings @@ -110,6 +110,7 @@ "Import Events" = "Termine importieren"; "Select an iCalendar file (.ics)." = "Wählen Sie eine iCalendar-Datei (.ics)."; "Upload" = "Hochladen"; +"Uploading" = "Hochladen"; "Publish Calendar..." = "Kalender publizieren..."; "Reload Remote Calendars" = "Externe Kalender neu laden"; "Properties" = "Einstellungen"; @@ -536,6 +537,10 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; "Show alarms" = "Zeige Erinnerungen"; "Show tasks" = "Zeige Aufgaben"; +"Receive a mail when I modify my calendar" = "E-Mail erhalten, wenn ich meinen Kalender verändere"; +"Receive a mail when someone else modifies my calendar" = "E-Mail erhalten, wenn jemand anderes meinen Kalender verändert"; +"When I modify my calendar, send a mail to:" = "Wenn ich meinen Kalender verändere, schicke eine E-Mail an: "; + "Links to this Calendar" = "Links zu diesem Kalender"; "Authenticated User Access" = "Zugang für angemeldete Benutzer"; "CalDAV URL" = "CalDAV-URL"; @@ -564,6 +569,7 @@ vtodo_class2 = "(Vertrauliche Aufgabe)"; "Delete Task" = "Aufgabe löschen"; "Delete Event" = "Termin löschen"; "Copy event to my calendar" = "Kopiere diesen Termin in meinen Kalender"; +"View Raw Source" = "Roher Quelltext anzeigen"; "Subscribe to a web calendar..." = "Einen Webkalender abonnieren..."; "URL of the Calendar" = "URL des Kalenders"; diff --git a/UI/Scheduler/Hungarian.lproj/Localizable.strings b/UI/Scheduler/Hungarian.lproj/Localizable.strings index 78d6ddab3..636baebb3 100644 --- a/UI/Scheduler/Hungarian.lproj/Localizable.strings +++ b/UI/Scheduler/Hungarian.lproj/Localizable.strings @@ -110,6 +110,7 @@ "Import Events" = "Események importálása"; "Select an iCalendar file (.ics)." = "Válasszon egy iCalendar fájlt (.ics)."; "Upload" = "Feltöltés"; +"Uploading" = "Feltöltés"; "Publish Calendar..." = "Naptár közzététele..."; "Reload Remote Calendars" = "Távoli naptárak frissítése"; "Properties" = "Tulajdonságok"; @@ -536,6 +537,10 @@ vtodo_class2 = "(Bizalmas feladat)"; "Show alarms" = "Riasztások megjelenítése"; "Show tasks" = "Feladatok megjelenítése"; +"Receive a mail when I modify my calendar" = "Kapjak email értesítést, amikor módosítok a naptáramon"; +"Receive a mail when someone else modifies my calendar" = "Kapjak email értesítést, amikor mások módosítják a naptáramat"; +"When I modify my calendar, send a mail to:" = "Email értesítés küldése az alábbi címre a naptáram módosításakor"; + "Links to this Calendar" = "Hivatkozások ehhez a naptárhoz"; "Authenticated User Access" = "Belépett felhasználók"; "CalDAV URL" = "CalDAV url"; @@ -564,6 +569,7 @@ vtodo_class2 = "(Bizalmas feladat)"; "Delete Task" = "Feladat törlése"; "Delete Event" = "Esemény törlése"; "Copy event to my calendar" = "Esemény másolása a naptáromba"; +"View Raw Source" = "Forrás megtekintése"; "Subscribe to a web calendar..." = "Internetes naptár becsatolása"; "URL of the Calendar" = "A naptár URL címe"; diff --git a/UI/Scheduler/Russian.lproj/Localizable.strings b/UI/Scheduler/Russian.lproj/Localizable.strings index 210b9af8e..1946593da 100644 --- a/UI/Scheduler/Russian.lproj/Localizable.strings +++ b/UI/Scheduler/Russian.lproj/Localizable.strings @@ -110,6 +110,7 @@ "Import Events" = "Импорт событий"; "Select an iCalendar file (.ics)." = "Выберите iCalendar файл (.ics)."; "Upload" = "Загрузить"; +"Uploading" = "Закачивается"; "Publish Calendar..." = "Опубликовать календарь..."; "Reload Remote Calendars" = "Обновить удаленные календари"; "Properties" = "Свойства"; @@ -536,6 +537,10 @@ vtodo_class2 = "(Конфиденциальное задание)"; "Show alarms" = "Показать сигналы"; "Show tasks" = "Показать задания"; +"Receive a mail when I modify my calendar" = "Получать письмо в случае если я изменю свой календарь"; +"Receive a mail when someone else modifies my calendar" = "Получать письмо если кто-то изменит мой календарь"; +"When I modify my calendar, send a mail to:" = "Если я изменю свой календарь, отправить письмо на адрес: "; + "Links to this Calendar" = "Ссылки на этот календарь"; "Authenticated User Access" = "Доступ авторизированных пользователей"; "CalDAV URL" = "CalDAV url"; @@ -564,6 +569,7 @@ vtodo_class2 = "(Конфиденциальное задание)"; "Delete Task" = "Удалить задачу"; "Delete Event" = "Удалить событие"; "Copy event to my calendar" = "Копировать событие в мой календарь"; +"View Raw Source" = "Показать исходный код сообщения"; "Subscribe to a web calendar..." = "Подписаться на калентарь в сети..."; "URL of the Calendar" = "URL календаря"; diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m index b6ef06590..7782c3216 100644 --- a/UI/Scheduler/UIxCalListingActions.m +++ b/UI/Scheduler/UIxCalListingActions.m @@ -1023,6 +1023,7 @@ _computeBlocksPosition (NSArray *blocks) now = [NSCalendarDate calendarDate]; taskDate = [NSCalendarDate dateWithTimeIntervalSince1970: endDateStamp]; + [taskDate setTimeZone: userTimeZone]; if ([taskDate earlierDate: now] == taskDate) statusClass = @"overdue"; else @@ -1034,7 +1035,7 @@ _computeBlocksPosition (NSArray *blocks) } } else - statusClass = @"duelater"; + statusClass = @"noduedate"; } return statusClass; diff --git a/UI/Templates/Appointments/SOGoAptMailDeletion.wox b/UI/Templates/Appointments/SOGoAptMailDeletion.wox index 030a9112c..b19a19f2f 100644 --- a/UI/Templates/Appointments/SOGoAptMailDeletion.wox +++ b/UI/Templates/Appointments/SOGoAptMailDeletion.wox @@ -1,3 +1,44 @@ - - + + + + + + +
+

+

+ +
+
+
+
+
- +
+
+
- +
+
+
+
+
+ + diff --git a/UI/Templates/Appointments/SOGoAptMailICalReply.wox b/UI/Templates/Appointments/SOGoAptMailICalReply.wox index 030a9112c..fb8e01b75 100644 --- a/UI/Templates/Appointments/SOGoAptMailICalReply.wox +++ b/UI/Templates/Appointments/SOGoAptMailICalReply.wox @@ -1,3 +1,30 @@ - - + + + + + + +
+

+ +
+
+
+
+
+ + diff --git a/UI/Templates/Appointments/SOGoAptMailInvitation.wox b/UI/Templates/Appointments/SOGoAptMailInvitation.wox index 030a9112c..b5af75331 100644 --- a/UI/Templates/Appointments/SOGoAptMailInvitation.wox +++ b/UI/Templates/Appointments/SOGoAptMailInvitation.wox @@ -1,3 +1,44 @@ - - + + + + + + +
+

+

+ +
+
+
+
+
- +
+
+
- +
+
+
+
+
+ + diff --git a/UI/Templates/Appointments/SOGoAptMailReceipt.wox b/UI/Templates/Appointments/SOGoAptMailReceipt.wox index 957ca8fc4..c93a1dc3e 100644 --- a/UI/Templates/Appointments/SOGoAptMailReceipt.wox +++ b/UI/Templates/Appointments/SOGoAptMailReceipt.wox @@ -9,7 +9,7 @@ + + +
+ +

+

+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ + \ No newline at end of file diff --git a/UI/WebServerResources/MailerUI.css b/UI/WebServerResources/MailerUI.css index 7e4bbf453..d182c4213 100644 --- a/UI/WebServerResources/MailerUI.css +++ b/UI/WebServerResources/MailerUI.css @@ -604,6 +604,13 @@ DIV.linked_attachment_frame /*background: #F0F0F0;*/ } +DIV.linked_attachment_frame fieldset +{ + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + DIV.linked_attachment_frame.file { display: inline; clear: none; @@ -629,16 +636,33 @@ TABLE.linked_attachment_meta font-style: italic; } +DIV.linked_attachment_body HR +{ + border: 0px; + border-top: 1px solid #ddd; +} + DIV.bodyFields { - background: #efefef; - font-family: serif; - margin: 0.5em; + background: #eee; + line-height: 1.5em; + margin: 0.5em 0px; + padding-bottom: 0.5em; + padding-top: 0.5em; text-align: left; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; } DIV.bodyFields SPAN.fieldName -{ font-weight: bold; } +{ + float: left; + font-weight: bold; + padding-right: 1em; + text-align: right; + width: 9em; +} DIV.bodyAdditionalFields { diff --git a/UI/WebServerResources/SchedulerUI.css b/UI/WebServerResources/SchedulerUI.css index e6bc2d6c3..e243922ed 100644 --- a/UI/WebServerResources/SchedulerUI.css +++ b/UI/WebServerResources/SchedulerUI.css @@ -82,22 +82,24 @@ UL#tasksList LI width: 100%; white-space: nowrap; } +UL#tasksList LI.duelater, +UL#tasksList LI.duetoday, UL#tasksList LI.overdue +{ font-weight: bold; } + +UL#tasksList LI.overdue, +UL#tasksList LI.important { color: #f00 !important; } UL#tasksList LI.duetoday { color: #00f !important; } -UL#tasksList LI.completed +UL#tasksList LI.completed SPAN { text-decoration: line-through; color: #000; } -UL#tasksList LI.duelater -{ color: #999 !important; } - UL#tasksList LI.important SPAN -{ color: #f00 !important; - background-image: url(important.png); +{ background-image: url(important.png); background-repeat: no-repeat; background-position: 3px 2px; padding-left: 10px; @@ -105,16 +107,16 @@ UL#tasksList LI.important SPAN UL#tasksList LI SPAN { padding-left: 2px; } -UL#tasksList LI[class~="_selected"].overdue +UL#tasksList LI._selected.overdue { color: #fff !important; background-color: #f00 !important; } -UL#tasksList LI[class~="_selected"].duetoday +UL#tasksList LI._selected.duetoday { color: #fff !important; background-color: #00f !important; } -UL#tasksList LI[class~="_selected"].duelater, -UL#tasksList LI[class~="_selected"].completed +UL#tasksList LI._selected.duelater, +UL#tasksList LI._selected.completed { color: #fff !important; background-color: #9ABCD8 !important; } diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 3e316355b..f0f128dc1 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1027,7 +1027,6 @@ function tasksListCallback(http) { //listItem.addClassName(data[i][5]); // Classification listItem.addClassName(data[i][9]); // status (duelater, completed, etc) listItem.calendar = calendar; - listItem.addClassName("calendarFolder" + calendar); listItem.cname = cname; listItem.erasable = data[i][7] || IsSuperUser; var input = createElement("input"); @@ -1044,6 +1043,10 @@ function tasksListCallback(http) { input.setAttribute("checked", "checked"); $(input).addClassName("checkBox"); + var colorDiv = createElement("div", false, "colorBox calendarFolder" + calendar); + colorDiv.update('OO'); + listItem.appendChild(colorDiv); + var t = new Element ("span"); t.update(data[i][3]); listItem.appendChild (t); diff --git a/UI/WebServerResources/UIxAppointmentEditor.js b/UI/WebServerResources/UIxAppointmentEditor.js index f9189d3bc..372f1abfd 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.js +++ b/UI/WebServerResources/UIxAppointmentEditor.js @@ -143,7 +143,7 @@ function onComposeToAllAttendees() } }); if (window.opener) - window.opener.openMailTo(addresses.join(",")); + window.opener.openMailTo(addresses.join(";")); } function onComposeToUndecidedAttendees() @@ -165,7 +165,7 @@ function onComposeToUndecidedAttendees() } }); if (window.opener) - window.opener.openMailTo(addresses.join(",")); + window.opener.openMailTo(addresses.join(";")); } function addContact(tag, fullContactName, contactId, contactName, contactEmail) { diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 2d04513a0..63817e1bf 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -319,7 +319,7 @@ function openMailComposeWindow(url, wId) { } function openMailTo(senderMailTo) { - var addresses = senderMailTo.split(","); + var addresses = senderMailTo.split(";"); var sanitizedAddresses = new Array(); var subject = extractSubject(senderMailTo); for (var i = 0; i < addresses.length; i++) {