propagate from branch 'ca.inverse.sogo.1_3_18' (head 6715d58c21f1a56fe1676af927c8dbc0dc2b3cdf)

to branch 'ca.inverse.sogo' (head 02b6f913c445756d25887e84a443f77942949032)

Monotone-Parent: 02b6f913c445756d25887e84a443f77942949032
Monotone-Parent: 6715d58c21f1a56fe1676af927c8dbc0dc2b3cdf
Monotone-Revision: b142d5d1ddfd110920b6b9d0c4efbba96c4ccedd

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2012-08-29T03:57:53
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2012-08-29 03:57:53 +00:00
commit 23d45acf5d
56 changed files with 768 additions and 322 deletions

View File

@ -1,7 +1,41 @@
2012-08-28 Jean Raby <jraby@inverse.ca>
2012-08-28 Jean Raby <jraby@inverse.ca>
* Scripts/openchange_cleanup.py:
New script to clean an openchange user profile
2012-08-27 Francis Lachapelle <flachapelle@inverse.ca>
* 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 <lmarcotte@inverse.ca>
* 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 <flachapelle@inverse.ca>
* UI/MailPartViewers/UIxMailPartHTMLViewer.m (-_sanitizeContent):
fix invalid void tags to insure proper HTML decoding. Fixes #1581.
2012-08-23 Ludovic Marcotte <lmarcotte@inverse.ca>
* 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 <wsourdeau@inverse.ca>
* 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 <lmarcotte@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m

21
NEWS
View File

@ -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

View File

@ -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" )
);

View File

@ -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}\".";
"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}.";

View File

@ -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:";

View File

@ -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}.";

View File

@ -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}.";
"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}.";

View File

@ -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}\".";
"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}.";

View File

@ -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}\".";
"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}.";

View File

@ -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

View File

@ -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 <wsourdeau@inverse.ca>
*
@ -19,6 +19,7 @@
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/NSCharacterSet.h>
#import <SOGo/NSDictionary+Utilities.h>
#import <SOGo/NSObject+Utilities.h>
@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 <wsourdeau@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
*
* 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;

View File

@ -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}\".";
"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}.";

View File

@ -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}\".";
"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}.";

View File

@ -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 <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
*
* 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

View File

@ -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 <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
*
* 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;

View File

@ -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";

View File

@ -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.";

View File

@ -1,6 +1,6 @@
/* this file is in UTF-8 format! */
"Contact" = "Herlaad";
"Contact" = "Contactpersoon";
"Address" = "Adres";
"Photos" = "Foto's";
"Other" = "Overige";

View File

@ -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.";

View File

@ -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." = "Записи не были импортированы.";

View File

@ -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";

View File

@ -42,5 +42,5 @@ reply_info = "Это ответ на Ваше приглашение на мер
"Subject" = "Тема";
"From" = "От";
"Date" = "Дата";
"To" = "К";
"To" = "Кому";
"Issuer" = "Эмитент";

View File

@ -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 :
//
// <meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
//
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: </br> is replaced by <br>
*/
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;
}

View File

@ -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.";

View File

@ -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.";

View File

@ -283,9 +283,9 @@
= "Сообщения не могут быть помещены в корзину. Хотите ли вы уничтожить их немедленно?";
/* Message editing */
"error_validationfailed" = "Проверка завершилась неудачей";
"error_missingsubject" = "Тема сообщения не указана";
"error_missingrecipients" = "Не указан адрес получателя";
"Send Anyway" = "Всё равно послать";
/* Message sending */
"cannot send message: (smtp) all recipients discarded" = "Не удается отправить сообщение: всем получателям, все получатели являются недействительными.";

View File

@ -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";

View File

@ -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";

View File

@ -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.";

View File

@ -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";

View File

@ -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" = "Изменение пароля не удалось";

View File

@ -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ó";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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 календаря";

View File

@ -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;

View File

@ -1,3 +1,44 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
h1 small { font-size: 12px; color: #999; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; color: #999; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<var:if condition="apt.location.length"
><dt><var:string label:value="location_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.location" const:escapeHTML="NO"/></dd></var:if>
<dt><var:string label:value="startDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptStartDate" const:escapeHTML="NO"
/><var:if condition="formattedAptStartTime.length"> - <var:string value="formattedAptStartTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<dt><var:string label:value="endDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptEndDate" const:escapeHTML="NO"
/><var:if condition="formattedAptEndTime.length"> - <var:string value="formattedAptEndTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<var:if condition="apt.comment.length"
><dt><var:string label:value="comment_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.comment" const:escapeHTML="NO"/></dd></var:if>
</dl>
</div>
</body>
</html>

View File

@ -1,3 +1,30 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/></h1>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string value="bodyStartText" const:escapeHTML="NO"/></dd>
</dl>
</div>
</body>
</html>

View File

@ -1,3 +1,44 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
h1 small { font-size: 12px; color: #999; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<var:if condition="apt.location.length"
><dt><var:string label:value="location_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.location" const:escapeHTML="NO"/></dd></var:if>
<dt><var:string label:value="startDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptStartDate" const:escapeHTML="NO"
/><var:if condition="formattedAptStartTime.length"> - <var:string value="formattedAptStartTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<dt><var:string label:value="endDate_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="formattedAptEndDate" const:escapeHTML="NO"
/><var:if condition="formattedAptEndTime.length"> - <var:string value="formattedAptEndTime" const:escapeHTML="NO"/> <var:string value="viewTZ" const:escapeHTML="NO"/>
</var:if></dd>
<var:if condition="apt.comment.length"
><dt><var:string label:value="comment_label" const:escapeHTML="NO"/></dt>
<dd><var:string value="apt.comment" const:escapeHTML="NO"/></dd></var:if>
</dl>
</div>
</body>
</html>

View File

@ -9,7 +9,7 @@
<head>
<style type="text/css">
.container { width: 600px; }
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
dt { font-weight: bold; line-height: 17px; }

View File

@ -1,3 +1,45 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE container>
<container xmlns="http://www.w3.org/1999/xhtml"></container>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
xmlns:label="OGo:label">
<head>
<style type="text/css">
.container { max-width: 600px; }
h1 { font-size: 18px; font-weight: normal; padding-bottom: 9px; border-bottom: 1px solid #ccc; }
.dl-horizontal dt { float: left; width: 120px; overflow: hidden; clear: left; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
h1 small { font-size: 12px; color: #999; }
dt { font-weight: bold; line-height: 17px; }
dt, dd { font-size: 12px; line-height: 18px; }
dt { display: block; }
h1, dd, .dl-list dt { margin-left: 130px; }
</style>
</head>
<body>
<div class="container">
<h1><var:string value="getSubject" const:escapeHTML="NO"/>
<small><var:string value="organizerName" const:escapeHTML="NO"/><var:string value="sentByText" const:escapeHTML="NO"/></small></h1>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string value="bodyStartText" const:escapeHTML="NO"/></dd>
</dl>
<dl class="dl-horizontal">
<var:foreach list="allChangesList" item="currentItem"
><dt><var:string var:value="currentItem"/></dt>
<dd><var:string var:value="valueForCurrentItem"/></dd>
</var:foreach>
</dl>
<dl class="dl-horizontal">
<dt></dt>
<dd><var:string label:value="Please accept or decline those changes." const:escapeHTML="NO"/></dd>
</dl>
</div>
</body>
</html>

View File

@ -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
{

View File

@ -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; }

View File

@ -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);

View File

@ -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) {

View File

@ -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++) {