propagate from branch 'ca.inverse.sogo.1_3_1' (head f6a0b62965278336b461dac36045bfae5fc07f0a)

to branch 'ca.inverse.sogo' (head aa0663eb86f38080e2ab2d20b64f30547adbfa81)

Monotone-Parent: aa0663eb86f38080e2ab2d20b64f30547adbfa81
Monotone-Parent: f6a0b62965278336b461dac36045bfae5fc07f0a
Monotone-Revision: 0176ffcc344892f0535563789b246aea9810ee5e

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2010-08-12T18:23:23
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Ludovic Marcotte 2010-08-12 18:23:23 +00:00
commit 39626e8569
119 changed files with 2599 additions and 470 deletions

View File

@ -43,6 +43,25 @@
personal addressbook when the request is performed by
AddressBook.app.
2010-08-11 Ludovic Marcotte <lmarcotte@inverse.ca>
* SoObjects/Appointments/SOGoAppointmentObject.m
Removed all the old calendar-schedule code and
instead, implemented calendar-auto-schedule. The old
code will always succeed and the new code reuses
all the business logic used for the Web interface
of SOGo.
* SOPE/NGCards/iCalRecurrenceRule.m
Modified setInterval: so that when the value is
equal to 1, we do NOT set it.
* UI/WebServerResources/UIxAclEditor.js
In addUserCallback(), we remove the owner of the
resource if it was added. This fixes #682.
* We now correctly encode/decode the '&'
character in the mailbox name when copying and moving
messages and also when opening mailboxes. This
fixes #716.
2010-08-11 Francis Lachapelle <flachapelle@inverse.ca>
* UI/WebServerResources/MailerUI.js (refreshMessage): if the
@ -311,6 +330,14 @@
RowEditionController.onInputKeyDown: we now handle the tab key
too.
2010-08-03 Ludovic Marcotte <lmarcotte@inverse.ca>
* Applied patch for bug #690
* Applied patch for bug #703
* Applied patch for bug #714
* Updated Ukrainian translation - patch from
Oleksa Stasevych <oleksiy.stasevych@gmail.com>
2010-08-02 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/WebServerResources/RowEditionController.js: new class module

5
NEWS
View File

@ -1,7 +1,10 @@
1.3-201008xx (1.3.1)
--------------------
- added migration scripts for Horde (email signatures and address books)
- added Polish translation
- added crypt support to SQL sources
- updated Ukrainian translation
- added the caldav-auto-schedule capability
1.3-20100721 (1.3.0)
--------------------

View File

@ -51,7 +51,7 @@ static NSString *commaSeparator = nil;
foldedString = [NSMutableString string];
length = [self length];
if (length < 76)
if (length < 77)
[foldedString appendString: self];
else
{
@ -59,7 +59,7 @@ static NSString *commaSeparator = nil;
[foldedString appendFormat: @"%@\r\n",
[self substringWithRange: subStringRange]];
subStringRange = NSMakeRange (75, 74);
while ((length - subStringRange.location) > 74)
while ((length - subStringRange.location) > 75)
{
[foldedString appendFormat: @" %@\r\n",
[self substringWithRange: subStringRange]];

View File

@ -383,7 +383,10 @@ NSString *iCalWeekDayString[] = { @"SU", @"MO", @"TU", @"WE", @"TH", @"FR",
- (void) setInterval: (NSString *) _interval
{
[self setNamedValue: @"interval" to: _interval];
if (_interval && [_interval intValue] == 1)
[self setNamedValue: @"interval" to: nil];
else
[self setNamedValue: @"interval" to: _interval];
}
- (void) setCount: (NSString *) _count

View File

@ -47,7 +47,7 @@ Appointments_RESOURCE_FILES += \
Version \
product.plist \
Appointments_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
Appointments_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
Appointments_LOCALIZED_RESOURCE_FILES = Localizable.strings

View File

@ -0,0 +1,62 @@
"Personal Calendar" = "Kalendarz osobisty";
vevent_class0 = "(Wydarzenie publiczne)";
vevent_class1 = "(Wydarzenie prywatne)";
vevent_class2 = "(Wydarzenie poufne)";
vtodo_class0 = "(Zadanie publiczne)";
vtodo_class1 = "(Zadanie prywatne)";
vtodo_class2 = "(Zadanie poufne)";
/* Receipts */
"Title:" = "Tytuł:";
"Start:" = "Początek:";
"End:" = "Koniec:";
"Receipt: users invited to a meeting" = "Potwierdzenie: użytkownicy zaproszeni na spotkanie";
"You have invited the following attendees(s):" = "Następujący uczestnicy zostali zaproszeni przez Ciebie:";
"... to attend the following event:" = "... aby wziąć udział w następującym wydarzeniu:";
"Receipt: invitation updated" = "Potwierdzenie: aktualizacja zaproszenia";
"The following attendees(s):" = "Następujący uczestnicy:";
"... have been notified of the changes to the following event:" = "... zostali poinformowani o zmianach następującego wydarzenia:";
"Receipt: attendees removed from an event" = "Potwierdzenie: urzestnicy usunięci z wydarzenia";
"You have removed the following attendees(s):" = "Następujący użytkownicy zostali usunięci przez ciebie:";
"... from the following event:" = "... z następującego wydarzenia:";
/* IMIP messages */
"startDate_label" = "Początek:";
"endDate_label" = "Koniec:";
"due_label" = "Termin:";
"location_label" = "Miejsce:";
"summary_label" = "Podsumowanie:";
"comment_label" = "Komentarz:";
/* Invitation */
"Event Invitation: \"%{Summary}\"" = "Zaproszenie na wydarzenie: \"%{Summary}\"";
"(sent by %{SentBy}) " = "(wysłane przez %{SentBy}) ";
"%{Organizer} %{SentByText}has invited you to %{Summary}." = "%{Organizer} %{SentByText}zaprosił cię na %{Summary}.";
/* Deletion */
"Event Cancelled: \"%{Summary}\"" = "Wydarzenie anulowane: \"%{Summary}\"";
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}."
= "%{Organizer} %{SentByText}anulował(a) to wydarzenie: %{Summary}.";
/* Update */
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
= "Wydarzenie \"%{Summary}\" z dnia %{OldStartDate} z godz. %{OldStartTime} zostało zmienione";
"The following parameters have changed in the \"%{Summary}\" meeting:"
= "Zmienione zostały poniższe parametry spotkania \"%{Summary}\":";
"Please accept or decline those changes."
= "Zaakceptuj lub odrzuć te zmiany.";
/* Reply */
"Reply to invitation: \"%{Summary}\"" = "Odpowiedź na zaproszenie: \"%{Summary}\"";
"%{Attendee} %{SentByText}has accepted your event invitation."
= "%{Attendee} %{SentByText}zaakceptował(a) twoje zaproszenie na wydarzenie.";
"%{Attendee} %{SentByText}has declined your event invitation."
= "%{Attendee} %{SentByText}odrzucił(a) twoje zaproszenie na wydarzenie.";
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
= "%{Attendee} %{SentByText}oddelegował(a) %{Delegate} na twoje wydarzenie.";
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
= "%{Attendee} %{SentByText}jeszcze nie zdecydował(a) o obecności na twoim wydarzeniu.";

View File

@ -1856,7 +1856,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
if (primaryClasses)
[classes addObjectsFromArray: primaryClasses];
[classes addObject: @"calendar-access"];
[classes addObject: @"calendar-schedule"];
//[classes addObject: @"calendar-schedule"];
[classes addObject: @"calendar-auto-schedule"];
return classes;
}

View File

@ -380,7 +380,9 @@ static SoSecurityManager *sm = nil;
if (primaryClasses)
[classes addObjectsFromArray: primaryClasses];
[classes addObject: @"calendar-access"];
[classes addObject: @"calendar-schedule"];
//[classes addObject: @"calendar-schedule"];
[classes addObject: @"calendar-auto-schedule"];
return classes;
}

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2004-2005 SKYRIX Software AG
Copyright (C) 2007-2008 Inverse inc.
Copyright (C) 2007-2010 Inverse inc.
This file is part of OpenGroupware.org.
@ -53,11 +53,10 @@
withDelegate: (iCalPerson *) delegate
forRecurrenceId: (NSCalendarDate *) _recurrenceId;
- (void) takeAttendeeStatus: (iCalPerson *) attendee
withDelegate: (iCalPerson *) delegate
from: (SOGoUser *) originator
withRecurrenceId: (NSCalendarDate*) recurrenceId;
//
// Old CalDAV scheduling (draft 4 and below) methods. We keep them since we still
// advertise for its support but we do everything within the calendar-auto-scheduling code
//
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients from: (NSString *) originator;
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients from: (NSString *) originator;
- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients from: (NSString *) originator;

View File

@ -31,6 +31,7 @@
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalDateTime.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalEventChanges.h>
#import <NGCards/iCalPerson.h>
@ -510,6 +511,31 @@
}
}
//
// Workflow : +----------------------+
// | |
// [saveComponent:]---> _handleAddedUsers:fromEvent: <-+ |
// | | v
// +------------> _handleUpdatedEvent:fromOldEvent: ---> _addOrUpdateEvent:forUID:owner: <-----------+
// | | ^ |
// v v | |
// _handleRemoveUsers:withRecurrenceId: _handleSequenceUpdateInEvent:ignoringAttendees:fromOldEvent: |
// | |
// | [DELETEAction:] |
// | | {_handleAdded/Updated...}<--+ |
// | v | |
// | [prepareDeleteOccurence:] [PUTAction:] |
// | | | | |
// v v v v |
// _removeEventFromUID:owner:withRecurrenceId: [changeParticipationStatus:withDelegate:forRecurrenceId:] |
// | | |
// | v |
// +------------------------> _handleAttendee:withDelegate:ownerUser:statusChange:inEvent: ---> [sendResponseToOrganizer:from:]
// |
// v
// _updateAttendee:withDelegate:ownerUser:forEventUID:withRecurrenceId:withSequence:forUID:shouldAddSentBy:
//
//
- (void) saveComponent: (iCalEvent *) newEvent
{
iCalEvent *oldEvent, *oldMasterEvent;
@ -626,8 +652,8 @@
// If no occurence found, create one
event = [eventObject newOccurenceWithID: recurrenceTime];
}
if ([[event sequence] compare: sequence] == NSOrderedSame)
if ([[event sequence] intValue] <= [sequence intValue])
{
SOGoUser *currentUser;
@ -809,7 +835,7 @@
NSString *delegatedUID = nil;
NSMutableArray *delegates;
if (removeDelegate)
{
delegates = [NSMutableArray array];
@ -867,10 +893,14 @@
forObject: event to: delegates];
}
// We generate the updated iCalendar file and we save it
// in the database.
newContent = [[event parent] versitString];
ex = [self saveContentString: newContent];
// We generate the updated iCalendar file and we save it in the database.
// We do this ONLY when using SOGo from the Web interface. Over DAV, it'll
// be handled directly in PUTAction:
if ([[context request] handledByDefaultHandler])
{
newContent = [[event parent] versitString];
ex = [self saveContentString: newContent];
}
// If the current user isn't the organizer of the event
// that has just been updated, we update the event and
@ -950,373 +980,71 @@
}
//
// The originator here is the owner of the calendar where
// the event was created. Lightning sends us exactly this
// and handles the SENT-BY itself. We might have to review
// this if the originator ever becomes the user on whom
// the act is performed (ie. Alice creates an event in Bob's
// calendar and invites Thomas).
// Old CalDAV scheduling (draft 4 and below) methods. We keep them since we still
// advertise for its support but we do everything within the calendar-auto-scheduling code
//
- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients
from: (NSString *) originator
{
NSMutableArray *elements;
NSEnumerator *recipientsEnum;
NSString *recipient, *uid, *ownerUID;
iCalEvent *newEvent, *oldEvent, *emailEvent;
iCalPerson *person, *eventOwner;
BOOL isUpdate, hasChanged;
NSMutableArray *elements;
NSString *recipient;
elements = [NSMutableArray array];
ownerUID = [[SOGoUserManager sharedUserManager]
getUIDForEmail: originator];
eventOwner = [self iCalPersonWithUID: ownerUID];
emailEvent = [self component: NO secure: NO];
newEvent = [self component: NO secure: NO];
[newEvent removeAllAlarms];
[[newEvent parent] setMethod: @""];
recipientsEnum = [recipients objectEnumerator];
while ((recipient = [recipientsEnum nextObject]))
if ([[recipient lowercaseString] hasPrefix: @"mailto:"])
{
person = [iCalPerson new];
[person setValue: 0 to: recipient];
uid = [person uid];
oldEvent = nil;
hasChanged = YES;
isUpdate = NO;
if (uid)
{
// We check if we must send an invitation update
// rather than just a normal invitation.
NSCalendarDate *recurrenceId;
NSString *iCalString;
SOGoAppointmentObject *oldEventObject, *ownerEventObject;
iCalCalendar *calendar;
oldEventObject = [self _lookupEvent: [newEvent uid] forUID: uid];
calendar = [oldEventObject calendar: NO secure: NO];
ownerEventObject = nil;
recurrenceId = [newEvent recurrenceId];
if (![oldEventObject isNew])
{
// We are updating an existing event.
// If the event containts a recurrence-id, replace the proper
// occurrence of the recurrent event.
iCalEvent *currentOccurence;
iCalEventChanges *changes;
NSArray *occurences;
NSCalendarDate *currentId;
NSString *recurrenceTime;
unsigned int i;
if (recurrenceId == nil)
oldEvent = [oldEventObject component: NO secure: NO];
else
{
// If recurrenceId is defined, find the specified occurence
// within the repeating vEvent and remove it.
occurences = [calendar events];
for (i = 1; i < [occurences count]; i++)
{
currentOccurence = [occurences objectAtIndex: i];
currentId = [currentOccurence recurrenceId];
if ([currentId compare: recurrenceId] == NSOrderedSame)
{
oldEvent = currentOccurence;
[[calendar children] removeObject: currentOccurence];
break;
}
}
if (oldEvent == nil)
{
// If no occurence found, create one.
recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]];
oldEvent = (iCalEvent *)[oldEventObject newOccurenceWithID: recurrenceTime];
}
// Add the event as a new occurrence, without the organizer.
[newEvent setOrganizer: nil];
[calendar addChild: newEvent];
}
// Identify changes in order to send a notification to the attendee
// if necessary and with the proper template.
changes = [newEvent getChangesRelativeToEvent: oldEvent];
if ([[oldEvent sequence] compare: [newEvent sequence]] != NSOrderedSame
&& [changes sequenceShouldBeIncreased])
isUpdate = YES;
else
hasChanged = NO;
}
else if (recurrenceId)
{
NSArray *attendees;
unsigned int i;
BOOL found;
// We must add an occurence to a non-existing event -- simply retrieve
// the event from the organizer's calendar
if (ownerEventObject == nil)
ownerEventObject = [self _lookupEvent: [newEvent uid]
forUID: ownerUID];
newEvent = [ownerEventObject component: NO secure: NO];
attendees = [newEvent attendees];
found = NO;
/* We check if the attendee that was added to a single
occurence is present in the master component. If not, we
add it with a participation status set to "DECLINED" */
for (i = 0; i < [attendees count]; i++)
{
if ([[attendees objectAtIndex: i] hasSameEmailAddress: person])
{
found = YES;
break;
}
}
if (!found)
{
[person setParticipationStatus: iCalPersonPartStatDeclined];
[person setRsvp: @"TRUE"];
[person setRole: @"REQ-PARTICIPANT"];
[newEvent addToAttendees: person];
if ([[newEvent organizer] isVoid])
[newEvent setOrganizer: eventOwner];
[ownerEventObject saveContentString: [[newEvent parent] versitString]];
}
}
// We generate the updated iCalendar file and we save it
// in the database.
iCalString = [[newEvent parent] versitString];
[oldEventObject saveContentString: iCalString];
}
#warning fix this when sendEmailUsing blabla has been cleaned up
if (hasChanged)
{
[self sendEMailUsingTemplateNamed: (isUpdate ? @"Update" : @"Invitation")
forObject: emailEvent
previousObject: oldEvent
toAttendees: [NSArray arrayWithObject: person]];
}
[person release];
[elements
addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
[elements addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
}
[self sendReceiptEmailUsingTemplateNamed: (isUpdate
? @"Update" : @"Invitation")
forObject: emailEvent
to: [newEvent attendees]];
return elements;
}
//
// See our comment about the originator in the method above.
//
- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients
from: (NSString *) originator
{
NSMutableArray *elements;
NSEnumerator *recipientsEnum;
NSString *recipient, *ownerUID, *uid;
iCalEvent *event;
iCalPerson *person;
NSMutableArray *elements;
NSString *recipient;
elements = [NSMutableArray array];
ownerUID = [[SOGoUserManager sharedUserManager]
getUIDForEmail: originator];
event = [self component: NO secure: NO];
recipientsEnum = [recipients objectEnumerator];
while ((recipient = [recipientsEnum nextObject]))
if ([[recipient lowercaseString] hasPrefix: @"mailto:"])
{
person = [iCalPerson new];
[person setValue: 0 to: recipient];
uid = [person uid];
if (uid)
[self _removeEventFromUID: uid
owner: ownerUID
withRecurrenceId: [event recurrenceId]];
#warning fix this when sendEmailUsing blabla has been cleaned up
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: event
previousObject: nil
toAttendees: [NSArray arrayWithObject: person]];
[person release];
[elements
addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
[elements addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
}
[self sendReceiptEmailUsingTemplateNamed: @"Deletion"
forObject: event
to: [event attendees]];
return elements;
}
//
// This method is invoked by CalDAV clients such as
// Mozilla Lightning. We assume the SENT-BY has
// already been added, if required.
//
// It is used to update the status of an attendee.
// The originator is the actualy owner of the calendar
// where the update took place. The status must then
// be propagated to the organizer and the other attendees.
//
- (void) takeAttendeeStatus: (iCalPerson *) attendee
withDelegate: (iCalPerson *) delegate
from: (SOGoUser *) ownerUser
withRecurrenceId: (NSCalendarDate*) recurrenceId
{
iCalPerson *localAttendee;
iCalEvent *event;
NSString *recurrenceTime;
if (recurrenceId == nil)
// We must update the master event only.
event = [self component: NO secure: NO];
else
{
// If recurrenceId is defined, find the specified occurence
// within the repeating vEvent.
recurrenceTime = [NSString stringWithFormat: @"%f", [recurrenceId timeIntervalSince1970]];
event = (iCalEvent*)[self lookupOccurence: recurrenceTime];
if (event == nil)
// If no occurence found, create one
event = (iCalEvent*)[self newOccurenceWithID: recurrenceTime];
}
// Find attendee within event
localAttendee = [event findAttendeeWithEmail: [attendee rfc822Email]];
if (localAttendee)
{
// Update the attendee's status
#warning this code should probably not exist, as a REPLY POST will be followed \
by a PUT
[localAttendee setPartStat: [attendee partStat]];
[localAttendee setDelegatedTo: [attendee delegatedTo]];
[localAttendee setDelegatedFrom: [attendee delegatedFrom]];
[self saveComponent: event];
NSArray *attendees;
iCalPerson *att;
NSString *uid;
int i;
/* We update the copy of the organizer, only if it's a local user. */
uid = [[event organizer] uid];
if (uid)
[self _updateAttendee: attendee
withDelegate: delegate
ownerUser: ownerUser
forEventUID: [event uid]
withRecurrenceId: [event recurrenceId]
withSequence: [event sequence]
forUID: uid
shouldAddSentBy: NO];
attendees = [event attendees];
for (i = 0; i < [attendees count]; i++)
{
att = [attendees objectAtIndex: i];
uid = [att uid];
if (uid
&& !(att == attendee || att == delegate
/* We skip the update that correspond to the owner since
the CalDAV client will already have updated the actual
event. */
|| [ownerUser hasEmail: [att rfc822Email]]))
[self _updateAttendee: attendee
withDelegate: delegate
ownerUser: ownerUser
forEventUID: [event uid]
withRecurrenceId: [event recurrenceId]
withSequence: [event sequence]
forUID: uid
shouldAddSentBy: NO];
}
}
else
[self errorWithFormat: @"attendee not found: '%@'", attendee];
}
- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients
from: (NSString *) originator
{
NSMutableArray *elements;
NSEnumerator *recipientsEnum;
NSString *recipient, *uid, *eventUID, *delegateEmail;
iCalEvent *event;
iCalPerson *attendee, *person, *delegate;
SOGoAppointmentObject *recipientEvent;
SOGoUser *ownerUser;
NSMutableArray *elements;
NSString *recipient;
elements = [NSMutableArray array];
event = [self component: NO secure: NO];
[[event parent] setMethod: @""];
ownerUser = [SOGoUser userWithLogin: [[SOGoUserManager sharedUserManager]
getUIDForEmail: originator]];
attendee = [event userAsAttendee: ownerUser];
eventUID = [event uid];
delegate = nil;
delegateEmail = [attendee delegatedTo];
if ([delegateEmail length])
{
delegateEmail = [delegateEmail substringFromIndex: 7];
if ([delegateEmail length])
delegate
= [event findAttendeeWithEmail: delegateEmail];
}
recipientsEnum = [recipients objectEnumerator];
while ((recipient = [recipientsEnum nextObject]))
if ([[recipient lowercaseString] hasPrefix: @"mailto:"])
{
person = [iCalPerson new];
[person setValue: 0 to: recipient];
uid = [person uid];
if (uid)
{
recipientEvent = [self _lookupEvent: eventUID forUID: uid];
if ([recipientEvent isNew])
[recipientEvent saveComponent: event];
else
[recipientEvent takeAttendeeStatus: attendee
withDelegate: delegate
from: ownerUser
withRecurrenceId: [event recurrenceId]];
}
// Send reply to recipient/organizer
[self sendIMIPReplyForEvent: event
from: ownerUser
to: person];
[person release];
[elements
addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
[elements addObject: [self _caldavSuccessCodeWithRecipient: recipient]];
}
return elements;
}
//
// This method is invoked only from the SOGo Web interface.
//
//
- (NSException *) changeParticipationStatus: (NSString *) status
withDelegate: (iCalPerson *) delegate
@ -1405,59 +1133,59 @@
return ex;
}
//
//
//
- (void) prepareDeleteOccurence: (iCalEvent *) occurence
{
iCalEvent *event;
SOGoUser *ownerUser, *currentUser;
NSArray *attendees;
NSCalendarDate *recurrenceId;
if ([[context request] handledByDefaultHandler])
ownerUser = [SOGoUser userWithLogin: owner];
event = [self component: NO secure: NO];
if (occurence == nil)
{
ownerUser = [SOGoUser userWithLogin: owner];
event = [self component: NO secure: NO];
if (occurence == nil)
{
// No occurence specified; use the master event.
occurence = event;
recurrenceId = nil;
}
else
// Retrieve this occurence ID.
recurrenceId = [occurence recurrenceId];
if ([event userIsOrganizer: ownerUser])
{
// The organizer deletes an occurence.
currentUser = [context activeUser];
attendees = [occurence attendeesWithoutUser: currentUser];
#warning Make sure this is correct ..
if (![attendees count] && event != occurence)
attendees = [event attendeesWithoutUser: currentUser];
if ([attendees count])
{
// Remove the event from all attendees calendars
// and send them an email.
[self _handleRemovedUsers: attendees
withRecurrenceId: recurrenceId];
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: [occurence itipEntryWithMethod: @"cancel"]
previousObject: nil
toAttendees: attendees];
[self sendReceiptEmailUsingTemplateNamed: @"Deletion"
forObject: occurence
to: attendees];
}
}
else if ([occurence userIsAttendee: ownerUser])
// The current user deletes the occurence; let the organizer know that
// the user has declined this occurence.
[self changeParticipationStatus: @"DECLINED" withDelegate: nil
forRecurrenceId: recurrenceId];
// No occurence specified; use the master event.
occurence = event;
recurrenceId = nil;
}
else
// Retrieve this occurence ID.
recurrenceId = [occurence recurrenceId];
if ([event userIsOrganizer: ownerUser])
{
// The organizer deletes an occurence.
currentUser = [context activeUser];
attendees = [occurence attendeesWithoutUser: currentUser];
#warning Make sure this is correct ..
if (![attendees count] && event != occurence)
attendees = [event attendeesWithoutUser: currentUser];
if ([attendees count])
{
// Remove the event from all attendees calendars
// and send them an email.
[self _handleRemovedUsers: attendees
withRecurrenceId: recurrenceId];
[self sendEMailUsingTemplateNamed: @"Deletion"
forObject: [occurence itipEntryWithMethod: @"cancel"]
previousObject: nil
toAttendees: attendees];
[self sendReceiptEmailUsingTemplateNamed: @"Deletion"
forObject: occurence
to: attendees];
}
}
else if ([occurence userIsAttendee: ownerUser])
// The current user deletes the occurence; let the organizer know that
// the user has declined this occurence.
[self changeParticipationStatus: @"DECLINED" withDelegate: nil
forRecurrenceId: recurrenceId];
}
- (NSException *) prepareDelete
@ -1603,6 +1331,66 @@
[rq setContent: [[calendar versitString] dataUsingEncoding: [rq contentEncoding]]];
}
//
// If theRecurrenceId is nil, it returns immediately the
// first event that has a RECURRENCE-ID.
//
// Otherwise, it return values that matches.
//
- (iCalEvent *) _eventFromRecurrenceId: (NSCalendarDate *) theRecurrenceId
events: (NSArray *) allEvents
{
iCalEvent *event;
int i;
for (i = 0; i < [allEvents count]; i++)
{
event = [allEvents objectAtIndex: i];
if ([event recurrenceId] && !theRecurrenceId)
return event;
if ([event recurrenceId] && [[event recurrenceId] compare: theRecurrenceId] == NSOrderedSame)
return event;
}
return nil;
}
//
//
//
- (NSCalendarDate *) _addedExDate: (iCalEvent *) oldEvent
newEvent: (iCalEvent *) newEvent
{
NSArray *oldExDates, *newExDates;
NSMutableArray *dates;
int i;
dates = [NSMutableArray array];
newExDates = [newEvent childrenWithTag: @"exdate"];
for (i = 0; i < [newExDates count]; i++)
[dates addObject: [[newExDates objectAtIndex: i] dateTime]];
oldExDates = [oldEvent childrenWithTag: @"exdate"];
for (i = 0; i < [oldExDates count]; i++)
[dates removeObject: [[oldExDates objectAtIndex: i] dateTime]];
return [dates lastObject];
}
//
//
//
- (id) DELETEAction: (WOContext *) _ctx
{
[self prepareDeleteOccurence: nil];
return [super DELETEAction: _ctx];
}
//
// If we see "X-SOGo: NoGroupsDecomposition" in the HTTP headers, we
// simply invoke super's PUTAction.
@ -1614,10 +1402,16 @@
{
NSArray *roles;
WORequest *rq;
id response;
rq = [_ctx request];
roles = [[context activeUser] rolesForObject: self inContext: context];
roles = [[context activeUser] rolesForObject: self inContext: context];
//
// We check if we gave only the "Respond To" right and someone is actually
// responding to one of our invitation. In this case, _setupResponseCalendarInRequest
// will only take the new attendee status and actually discard any other modifications.
//
if ([roles containsObject: @"ComponentResponder"]
&& ![roles containsObject: @"ComponentModifier"])
[self _setupResponseCalendarInRequest: rq];
@ -1638,7 +1432,224 @@
}
}
return [super PUTAction: _ctx];
//
// We first check if it's a new event
//
if ([self isNew])
{
iCalCalendar *calendar;
iCalEvent *event;
SOGoUser *ownerUser;
calendar = [iCalCalendar parseSingleFromSource: [rq contentAsString]];
event = [[calendar events] objectAtIndex: 0];
ownerUser = [SOGoUser userWithLogin: owner];
//
// New event and we're the organizer -- send invitation to all attendees
//
if ([event userIsOrganizer: ownerUser])
{
NSArray *attendees;
attendees = [event attendeesWithoutUser: ownerUser];
if ([attendees count])
{
[self _handleAddedUsers: attendees fromEvent: event];
[self sendEMailUsingTemplateNamed: @"Invitation"
forObject: [event itipEntryWithMethod: @"request"]
previousObject: nil
toAttendees: attendees];
[self sendReceiptEmailUsingTemplateNamed: @"Invitation"
forObject: event to: attendees];
}
}
//
// We aren't the organizer but we're an attendee. That can happen when
// we receive an external invitation (IMIP/ITIP) and we accept it
// from a CUA - it gets added to a specific CalDAV calendar using a PUT
//
else if ([event userIsAttendee: ownerUser])
{
[self sendIMIPReplyForEvent: event
from: ownerUser
to: [event organizer]];
}
}
else
{
iCalCalendar *oldCalendar, *newCalendar;
iCalEvent *oldEvent, *newEvent;
iCalEventChanges *changes;
NSMutableArray *oldEvents, *newEvents;
NSCalendarDate *recurrenceId;
NSException *error;
BOOL master;
int i;
//
// We must check for etag changes prior doing anything since an attendee could
// have changed its participation status and the organizer didn't get the
// copy and is trying to do a modification to the event.
//
error = [self matchesRequestConditionInContext: _ctx];
if (error)
return (WOResponse *)error;
//
// We check what has changed in the event and react accordingly.
//
newCalendar = [iCalCalendar parseSingleFromSource: [rq contentAsString]];
newEvents = [NSMutableArray arrayWithArray: [newCalendar events]];
oldCalendar = [self calendar: NO secure: NO];
oldEvents = [NSMutableArray arrayWithArray: [oldCalendar events]];
recurrenceId = nil;
master = NO;
for (i = [newEvents count]-1; i >= 0; i--)
{
newEvent = [newEvents objectAtIndex: i];
if ([newEvent recurrenceId])
{
// Find the corresponding RECURRENCE-ID in the old calendar
// If not present, we assume it was created before the PUT
oldEvent = [self _eventFromRecurrenceId: [newEvent recurrenceId]
events: oldEvents];
// If present, we look for changes
changes = [iCalEventChanges changesFromEvent: oldEvent toEvent: newEvent];
if ([changes sequenceShouldBeIncreased] | [changes hasAttendeeChanges])
{
// We found a RECURRENCE-ID with changes, we consider it
recurrenceId = [newEvent recurrenceId];
break;
}
else
{
[newEvents removeObject: oldEvent];
[oldEvents removeObject: newEvent];
}
}
oldEvent = nil;
newEvent = nil;
}
// If no changes were observed, let's see if we have any left overs
// in the oldEvents or in the newEvents array
if (!oldEvent && !newEvent)
{
// We check if we only have to deal with the MASTER event
if ([newEvents count] == [oldEvents count])
{
oldEvent = [oldEvents objectAtIndex: 0];
newEvent = [newEvents objectAtIndex: 0];
master = YES;
}
// A RECURRENCE-ID was added
else if ([newEvents count] > [oldEvents count])
{
oldEvent = nil;
newEvent = [self _eventFromRecurrenceId: nil events: newEvents];
recurrenceId = [newEvent recurrenceId];
}
// A RECURRENCE-ID was removed
else
{
oldEvent = [self _eventFromRecurrenceId: nil events: oldEvents];
newEvent = nil;
recurrenceId = [oldEvent recurrenceId];
}
}
// We check if the PUT call is actually an PART-STATE change
// from one of the attendees - here's the logic :
//
// if owner == organizer
//
// if [context activeUser] == organizer
// [send the invitation update]
// else
// [react on SENT-BY as someone else is acting for the organizer]
//
//
if ([[newEvent attendees] count] || [[oldEvent attendees] count])
{
if ([[[newEvent organizer] uid] caseInsensitiveCompare: owner] == NSOrderedSame)
{
[self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent];
// A RECURRENCE-ID was removed so there has to be a change in the master event
// We could also have an EXDATE added in the master component of the attendees
// so we always compare the MASTER event.
if (!master)
{
newEvent = [newEvents objectAtIndex: 0];
oldEvent = [oldEvents objectAtIndex: 0];
[self _handleUpdatedEvent: newEvent fromOldEvent: oldEvent];
}
}
//
// else => attendee is responding
//
// if [context activeUser] == attendee
// [we change the PART-STATE]
// else
// [react on SENT-BY as someone else is acting for the attendee]
else
{
iCalPerson *attendee, *delegate;
NSString *delegateEmail;
attendee = [newEvent userAsAttendee: [SOGoUser userWithLogin: owner]];
delegate = nil;
delegateEmail = [attendee delegatedTo];
if ([delegateEmail length])
{
delegateEmail = [delegateEmail substringFromIndex: 7];
if ([delegateEmail length])
delegate = [newEvent findAttendeeWithEmail: delegateEmail];
}
changes = [iCalEventChanges changesFromEvent: oldEvent toEvent: newEvent];
// The current user deletes the occurence; let the organizer know that
// the user has declined this occurence.
if ([[changes updatedProperties] containsObject: @"exdate"])
{
[self changeParticipationStatus: @"DECLINED"
withDelegate: nil // (specify delegate?)
forRecurrenceId: [self _addedExDate: oldEvent newEvent: newEvent]];
}
else
[self changeParticipationStatus: [attendee partStat]
withDelegate: delegate
forRecurrenceId: recurrenceId];
// A RECURRENCE-ID was removed so there has to be a change in the master event
// We could also have an EXDATE added in the master component of the attendees
// so we always compare the MASTER event.
if (!master)
{
newEvent = [newEvents objectAtIndex: 0];
oldEvent = [oldEvents objectAtIndex: 0];
[self changeParticipationStatus: [attendee partStat] withDelegate: delegate];
}
}
}
}
// This will save the event into the database and also handle
// E-Tags properly, as well as content versioning.
response = [super PUTAction: _ctx];
return response;
}
@end /* SOGoAppointmentObject */

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2006-2010 Inverse inc.
Copyright (C) 2000-2005 SKYRIX Software AG
Copyright (C) 2006-2009 Inverse inc.
This file is part of SOGo.

View File

@ -1,6 +1,6 @@
/* SOGoComponentOccurence.m - this file is part of SOGo
*
* Copyright (C) 2008 Inverse inc.
* Copyright (C) 2008-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*

View File

@ -1,6 +1,6 @@
/* iCalEntityObject+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*

View File

@ -1,6 +1,6 @@
/* iCalEventChanges+SOGo.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
@ -34,7 +34,6 @@
@"due", @"duration",
@"rdate", @"rrule", @"exdate", @"exrule",
@"status", @"location",
//@"summary", @"comment",
nil};
NSString **currentProperty;
BOOL updateRequired;

View File

@ -25,7 +25,7 @@ Contacts_RESOURCE_FILES += \
Version \
product.plist \
Contacts_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
Contacts_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
Contacts_LOCALIZED_RESOURCE_FILES = Localizable.strings

View File

@ -0,0 +1 @@
"Personal Address Book" = "Osobista książka adresowa";

View File

@ -60,6 +60,8 @@ Mailer_RESOURCE_FILES += \
SOGoMailHungarianReply.wo \
SOGoMailItalianForward.wo \
SOGoMailItalianReply.wo \
SOGoMailPolishForward.wo \
SOGoMailPolishReply.wo \
SOGoMailRussianForward.wo \
SOGoMailRussianReply.wo \
SOGoMailSpanishForward.wo \

View File

@ -66,6 +66,9 @@
@interface SOGoMailSpanishForward : SOGoMailForward
@end
@interface SOGoMailPolishForward : SOGoMailForward
@end
@interface SOGoMailRussianForward : SOGoMailForward
@end

View File

@ -260,6 +260,9 @@
@implementation SOGoMailSpanishForward
@end
@implementation SOGoMailPolishForward
@end
@implementation SOGoMailRussianForward
@end

View File

@ -0,0 +1,13 @@
<#newLine/>
<#newLine/>
<#newLine/>
-------- Oryginalna wiadomość --------<#newLine/>
Temat: <#subject/><#newLine/>
Data: <#date/><#newLine/>
Od: <#from/><#newLine/>
<#hasReplyTo>Odpowiedź do: <#replyTo/></#hasReplyTo><#hasOrganization>Organizacja: <#organization/></#hasOrganization>Do: <#to/><#newLine/>
<#hasCc>DW: <#cc/></#hasCc><#hasNewsGroups>Grupy dyskusyjne: <#newsgroups/></#hasNewsGroups><#hasReferences>Odniesienia: <#references/></#hasReferences><#newLine/>
<#newLine/>
<#messageBody/><#newLine/>
<#newLine/>
<#signature/><#newLine/>

View File

@ -0,0 +1,79 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}

View File

@ -0,0 +1,16 @@
<#replyPlacementOnTop><#newLine/>
<#newLine/>
</#replyPlacementOnTop><#signaturePlacementOnTop><#newLine/>
<#signature/><#newLine/>
</#signaturePlacementOnTop><#outlookMode>-------- Oryginalna wiadomość --------<#newLine/>
Temat: <#subject/><#newLine/>
Data: <#date/><#newLine/>
Od: <#from/><#newLine/>
<#hasReplyTo>Odpowiedź do: <#replyTo/></#hasReplyTo><#hasOrganization>Organizacja: <#organization/></#hasOrganization>Do: <#to/><#newLine/>
<#hasCc>DW: <#cc/></#hasCc><#hasNewsGroups>Grupy dyskusyjne: <#newsgroups/></#hasNewsGroups><#hasReferences>Odniesienia: <#references/></#hasReferences></#outlookMode><#newLine/>
<#standardMode>Dnia <#date/>, <#from/> napisał(a):</#standardMode><#newLine/>
<#newLine/>
<#messageBody/><#newLine/>
<#replyPlacementOnBottom><#newLine/>
<#newLine/>
</#replyPlacementOnBottom><#signaturePlacementOnBottom><#signature/></#signaturePlacementOnBottom><#newLine/>

View File

@ -0,0 +1,106 @@
outlookMode: WOConditional {
condition = outlookMode;
}
standardMode: WOConditional {
condition = outlookMode;
negate = YES;
}
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}
replyPlacementOnTop: WOConditional {
condition = replyPlacementOnTop;
}
replyPlacementOnBottom: WOConditional {
condition = replyPlacementOnTop;
negate = YES;
}
signaturePlacementOnTop: WOConditional {
condition = signaturePlacementOnTop;
}
signaturePlacementOnBottom: WOConditional {
condition = signaturePlacementOnTop;
negate = YES;
}

View File

@ -71,6 +71,9 @@
@interface SOGoMailSpanishReply : SOGoMailReply
@end
@interface SOGoMailPolishReply : SOGoMailReply
@end
@interface SOGoMailRussianReply : SOGoMailReply
@end

View File

@ -128,6 +128,9 @@
@implementation SOGoMailSpanishReply
@end
@implementation SOGoMailPolishReply
@end
@implementation SOGoMailRussianReply
@end

View File

@ -0,0 +1,13 @@
<#newLine/>
<#newLine/>
<#newLine/>
-------- Початкове повідомлення --------<#newLine/>
Тема: <#subject/><#newLine/>
Дата: <#date/><#newLine/>
Від: <#from/><#newLine/>
<#hasReplyTo>Відповісти: <#replyTo/></#hasReplyTo><#hasOrganization>Організація: <#organization/></#hasOrganization>Кому: <#to/><#newLine/>
<#hasCc>Копія: <#cc/></#hasCc><#hasNewsGroups>Групи новин: <#newsgroups/></#hasNewsGroups><#hasReferences>Посилання: <#references/></#hasReferences><#newLine/>
<#newLine/>
<#messageBody/><#newLine/>
<#newLine/>
<#signature/><#newLine/>

View File

@ -0,0 +1,79 @@
subject: WOString {
value = subject;
escapeHTML = NO;
}
date: WOString {
value = date;
escapeHTML = NO;
}
from: WOString {
value = from;
escapeHTML = NO;
}
newLine: WOString {
value = newLine;
escapeHTML = NO;
}
hasReplyTo: WOConditional {
condition = hasReplyTo;
}
replyTo: WOString {
value = replyTo;
escapeHTML = NO;
}
hasOrganization: WOConditional {
condition = hasOrganization;
}
organization: WOString {
value = organization;
escapeHTML = NO;
}
to: WOString {
value = to;
escapeHTML = NO;
}
hasCc: WOConditional {
condition = hasCc;
}
cc: WOString {
value = cc;
escapeHTML = NO;
}
hasNewsGroups: WOConditional {
condition = hasNewsGroups;
}
newsgroups: WOString {
value = newsgroups;
escapeHTML = NO;
}
hasReferences: WOConditional {
condition = hasReferences;
}
references: WOString {
value = references;
escapeHTML = NO;
}
messageBody: WOString {
value = messageBody;
escapeHTML = NO;
}
signature: WOString {
value = signature;
escapeHTML = NO;
}

View File

@ -19,7 +19,7 @@ SOGo_LIBRARIES_DEPEND_UPON += \
-lNGCards \
-lNGMime \
-lNGStreams -lNGExtensions -lEOControl \
-lXmlRpc -lDOM -lSaxObjC \
-lXmlRpc -lDOM -lSaxObjC -lcrypt \
-lNGLdap
ADDITIONAL_TOOL_LIBS += \

View File

@ -263,12 +263,12 @@ static int cssEscapingCount;
int count;
strings = [NSArray arrayWithObjects: @"_U_", @"_D_", @"_H_", @"_A_", @"_S_",
@"_C_", @"_CO_", @"_SP_", @"_SQ_", nil];
@"_C_", @"_CO_", @"_SP_", @"_SQ_", @"_AM_", nil];
[strings retain];
cssEscapingStrings = [strings asPointersOfObjects];
characters = [NSArray arrayWithObjects: @"_", @".", @"#", @"@", @"*", @":",
@",", @" ", @"'", nil];
@",", @" ", @"'", @"&", nil];
cssEscapingCount = [strings count];
cssEscapingCharacters = NSZoneMalloc (NULL,
(cssEscapingCount + 1)

View File

@ -1,14 +1,15 @@
/*
Copyright (C) 2006-2010 Inverse inc.
Copyright (C) 2004-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.

View File

@ -15,7 +15,6 @@
SOGoCacheCleanupInterval = 300.0;
SOGoMemcachedHost = "localhost";
SOGoMemcachedPort = 11211;
SOGoUIxDebugEnabled = NO;
@ -33,7 +32,7 @@
SOGoLanguage = "English";
SOGoSupportedLanguages = ( "Czech", "Welsh", "English", "Spanish",
"French", "German", "Italian", "Hungarian",
"Dutch", "BrazilianPortuguese", "Russian",
"Dutch", "BrazilianPortuguese", "Polish", "Russian",
"Ukrainian", "Swedish");
SOGoTimeZone = "UTC";

View File

@ -115,6 +115,7 @@
/* operations */
- (NSException *)delete;
- (id) DELETEAction: (id) _ctx;
- (id)GETAction:(id)_ctx;
/* etag support */

View File

@ -35,6 +35,8 @@
#import <GDLAccess/EOAdaptorContext.h>
#import <GDLAccess/EOAttribute.h>
#include <unistd.h>
#include <openssl/evp.h>
#include <openssl/md5.h>
@ -139,6 +141,16 @@
{
return [plainPassword isEqualToString: encryptedPassword];
}
else if ([_userPasswordAlgorithm caseInsensitiveCompare: @"crypt"] == NSOrderedSame)
{
NSString *s;
char *buf;
buf = (char *)crypt([plainPassword UTF8String], [encryptedPassword UTF8String]);
s = [NSString stringWithUTF8String: buf];
return [s isEqualToString: encryptedPassword];
}
else if ([_userPasswordAlgorithm caseInsensitiveCompare: @"md5"] == NSOrderedSame)
{
NSString *s;

View File

@ -15,7 +15,7 @@ if __name__ == "__main__":
# Duplicated from UIxPreferences.m
languages = ["Czech", "Dutch", "English", "French",
"German", "Hungarian", "Italian", "BrazilianPortuguese",
"Russian", "Spanish", "Swedish", "Ukrainian", "Welsh"]
"Polish", "Russian", "Spanish", "Swedish", "Ukrainian", "Welsh"]
# We can disable testing all languages
testLanguages = False

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = AdministrationUI
AdministrationUI_PRINCIPAL_CLASS = AdministrationUIProduct
AdministrationUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
AdministrationUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
AdministrationUI_OBJC_FILES = \
AdministrationUIProduct.m \

View File

@ -0,0 +1,15 @@
/* this file is in UTF-8 format! */
"Help" = "Pomoc";
"Close" = "Zamknij";
"Modules" = "Moduły";
/* Modules short names */
"ACLs" = "ACLe";
/* Modules titles */
"ACLs_title" = "Zarządzanie uprawnieniami ACL folderów użytkowników";
/* Modules descriptions */
"ACLs_description" = "<p>Moduł zarządzania uprawnieniami ACL (ang. Access Control Lists) pozwala zmienić uprawnienia ACL na folderach poczty i książkach adresowych każdego użytkownika.</p><p>Aby zmodyfikować uprawnienie ACL foldera użytkownika, wpisz nazwę tego użytkownika w pole wyszukiwania w górnej części okna i kliknij podwójnie na wybranym folderze.</p>";

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = CommonUI
CommonUI_PRINCIPAL_CLASS = CommonUIProduct
CommonUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
CommonUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
CommonUI_OBJC_FILES += \
CommonUIProduct.m \

View File

@ -0,0 +1,72 @@
/* this file is in UTF-8 format! */
/* toolbars */
"Save" = "Zapisz";
"Close" = "Zamknij";
"Edit User Rights" = "Edytuj uprawnienia użytkownika";
"Home" = "Strona domowa";
"Calendar" = "Kalendarz";
"Address Book" = "Książka adresowa";
"Mail" = "Poczta";
"Preferences" = "Ustawienia";
"Administration" = "Administracja";
"Disconnect" = "Wyloguj";
"Right Administration" = "Administracja uprawnień";
"Log Console (dev.)" = "Konsola błędów (dev.)";
"User" = "Użytkownik";
"Help" = "Pomoc";
"noJavascriptError" = "Do pracy z SOGo wymagane jest włączenie obsługi Javascript. Upewnij się, że ta funkcja jest dostępna i włączona w ustawieniach twojej przeglądarki WWW.";
"noJavascriptRetry" = "Ponów";
"Owner:" = "Właściciel:";
"Publish the Free/Busy information" = "Opublikuj informację wolny/zajęty";
"Add..." = "Dodaj...";
"Remove" = "Usuń";
"Subscribe User" = "Subskrybuj użytkownika";
"Any Authenticated User" = "Każdy zalogowany użytkownik";
"Public Access" = "Dostęp publiczny";
"Any user not listed above" = "Każdy użytkownik spoza powyższej listy";
"Anybody accessing this resource from the public area" = "Każdy korzystający z tego zasobu z obszaru publicznego";
"Sorry, the user rights can not be configured for that object." = "Uprawnienia użytkownika na tym obiekcie nie mogą być konfigurowane.";
/* generic.js */
"Unable to subscribe to that folder!"
= "Nie można subskrybować tego foldera!";
"You cannot subscribe to a folder that you own!"
= "Nie możesz subskrybować foldera, który jest twoją własnością!";
"Unable to unsubscribe from that folder!"
= "Nie można wyłączyć subskrypcji tego foldera!";
"You cannot unsubscribe from a folder that you own!"
= "Nie możesz wyłączyć subskrypcji foldera, który jest twoją własnością!";
"Unable to rename that folder!" = "Nie można zmienić nazwy tego foldera!";
"You have already subscribed to that folder!"
= "Już subskrybujesz ten folder!";
"The user rights cannot be edited for this object!"
= "Uprawnienia użytkownika na tym obiekcie nie mogą być edytowane!";
"A folder by that name already exists." = "Folder o tej nazwie już istnieje.";
"You cannot create a list in a shared address book."
= "Nie możesz tworzyć list w udostępnionej książce adresowej.";
"You are not allowed to access this module or this system. Please contact your system administrator."
= "Nie masz pozwolenia na dostęp do tego modułu lub tego systemu. Skontaktuj się ze swoim administratorem.";
"You don't have the required privileges to perform the operation."
= "Nie masz potrzebnych uprawnień do wykonania tej operacji.";
"noEmailForDelegation" = "Musisz podać adres, na który chcesz delegować twoje zaproszenie.";
"delegate is organizer" = "Wskazany delegat jest organizatorem. Wskaż innego delegata.";
"delegate is a participant" = "Delegat jest już uczestnikiem.";
"delegate is a group" = "Wskazany adres jest grupą. Możesz oddelegować tylko pojedynczną osobę.";
/* alarms */
"Reminder:" = "Przypomnienie:";
"Start:" = "Początek:";
"Due Date:" = "Termin:";
"Location:" = "Miejsce:";

View File

@ -1,6 +1,6 @@
/* UIxAclEditor.m - this file is part of SOGo
*
* Copyright (C) 2006-2009 Inverse inc.
* Copyright (C) 2006-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*

View File

@ -1,6 +1,6 @@
/* UIxObjectActions.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse inc.
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*

View File

@ -28,13 +28,9 @@
"Add..." = "Додати...";
"Remove" = "Вилучити";
"Default Roles" = "Контроль доступу для всіх";
"Subscribe User" = "Підписати користувача";
"Any Authenticated User" = "Any Authenticated User";
"Public Access" = "Public Access";
"Any user not listed above" = "Any user not listed above";
"Anybody accessing this resource from the public area" = "Anybody accessing this resource from the public area";
"Sorry, the user rights can not be configured for that object." = "Вибачте, для цього об’єкту неможливо налаштувати права доступу.";
/* generic.js */

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Edita o contato selecionado";
"Send a mail message" = "Envia uma mensagem de email";
"Delete selected card or address book" = "Apaga o contato ou catálogo selecionado";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Desconhecido";
"htmlMailFormat_FALSE" = "Texto Puro";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Upravit označený kontakt";
"Send a mail message" = "Poslat zprávu";
"Delete selected card or address book" = "Smazat označený kontakt nebo složku kontaktů";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Neznámý";
"htmlMailFormat_FALSE" = "Plain Text";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Edit the selected card";
"Send a mail message" = "Send a mail message";
"Delete selected card or address book" = "Delete selected card or address book";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Onbekend";
"htmlMailFormat_FALSE" = "Platte tekst";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Edit the selected card";
"Send a mail message" = "Send a mail message";
"Delete selected card or address book" = "Delete selected card or address book";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Unknown";
"htmlMailFormat_FALSE" = "Plain Text";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Modifier la fiche sélectionnée";
"Send a mail message" = "Rédiger un courrier à la sélection";
"Delete selected card or address book" = "Supprimer la fiche sélectionnée";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Inconnu";
"htmlMailFormat_FALSE" = "Texte simple (sans HTML)";

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = ContactsUI
ContactsUI_PRINCIPAL_CLASS = ContactsUIProduct
ContactsUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
ContactsUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
ContactsUI_OBJC_FILES = \
UIxContactsUserFolders.m \

View File

@ -50,6 +50,7 @@
"Edit the selected card" = "Gewählte Karte bearbeiten";
"Send a mail message" = "Neue Nachricht verfassen";
"Delete selected card or address book" = "Gewählte Karte oder Adressbuch löschen";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Unbekannt";
"htmlMailFormat_FALSE" = "Reintext";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "A kijelölt névjegy szerkesztése";
"Send a mail message" = "Email üzenet küldése";
"Delete selected card or address book" = "Kijelölt névjegy vagy címjegyzék törlése";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Ismeretlen";
"htmlMailFormat_FALSE" = "Egyszerű szöveg";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Modifica il contatto selezionato";
"Send a mail message" = "Invia un'email";
"Delete selected card or address book" = "Cancella il contatto selezionato";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Sconosciuto";
"htmlMailFormat_FALSE" = "Testo normale";

View File

@ -0,0 +1,197 @@
/* this file is in UTF-8 format! */
"Contact" = "Kontakt";
"Address" = "Adres";
"Photos" = "Zdjęcia";
"Other" = "Inne";
"Address Books" = "Książki adresowe";
"Addressbook" = "Książka adresowa";
"Addresses" = "Adresy";
"Update" = "Aktualizacja";
"Cancel" = "Anuluj";
"Common" = "Wspólne";
"Contact editor" = "Edytor kontaktów";
"Contact viewer" = "Przeglądarka kontaktów";
"Email" = "E-mail";
"Screen Name" = "Nazwa ekranowa";
"Extended" = "Rozszerzone";
"Fax" = "Fax";
"Firstname" = "Imię";
"Home" = "Dom";
"HomePhone" = "Telefon domowy";
"Lastname" = "Nazwisko";
"Location" = "Miejscowość";
"MobilePhone" = "Telefon komórkowy";
"Name" = "Nazwa";
"OfficePhone" = "Telefon do biura";
"Organization" = "Organizacja";
"Work Phone" = "Telefon do pracy";
"Phone" = "Telefon";
"Phones" = "Telefony";
"Postal" = "Adres korespondencyjny";
"Save" = "Zapisz";
"Internet" = "Internet";
"Unit" = "Jednostka";
"delete" = "usuń";
"edit" = "edytuj";
"invalidemailwarn" = "Podany adres e-mail jest nieprawidłowy";
"invaliddatewarn" = "Podana data jest nieprawidłowa.";
"new" = "nowy";
"Preferred Phone" = "Preferowany telefon";
"Move To" = "Przenieś do";
"Copy To" = "Kopiuj do";
"Add to:" = "Dodaj do:";
/* Tooltips */
"Create a new address book card" = "Utwórz nowy kontakt w książce adresowej";
"Create a new list" = "Utwórz nową listę";
"Edit the selected card" = "Edytuj zaznaczoną kartę";
"Send a mail message" = "Wyślij wiadomość e-mail";
"Delete selected card or address book" = "Usuń zaznaczony kontakt lub książkę adresową";
"Reload all contacts" = "Przeładuj wszystkie kontakty";
"htmlMailFormat_UNKNOWN" = "Nieznany";
"htmlMailFormat_FALSE" = "czysty tekst";
"htmlMailFormat_TRUE" = "HTML";
"Name or Email" = "Nazwa lub e-mail";
"Personal Addressbook" = "Osobista książka adresowa";
"Search in Addressbook" = "Szukaj w książce adresowej";
"New Card" = "Nowy kontakt";
"New List" = "Nowa lista";
"Properties" = "Właściwości";
"Sharing..." = "Udostępnianie...";
"Write" = "Napisz";
"Delete" = "Usuń";
"Instant Message" = "Szybka wiadomość";
"Add..." = "Dodaj...";
"Remove" = "Usuń";
"Please wait..." = "Zaczekaj chwilę...";
"No possible subscription" = "Brak możliwej subskrypcji";
"Preferred" = "Preferowane";
"Card for %@" = "Kontakt %@";
"Display:" = "Wyświetl:";
"Display Name:" = "Nazwa wyświetlana:";
"Email:" = "E-mail:";
"Additional Email:" = "Dodatkowy E-mail:";
"Phone Number:" = "Numer telefonu:";
"Prefers to receive messages formatted as:" = "Preferuje wiadomości w formacie:";
"Screen Name:" = "Nazwa ekranowa:";
"First:" = "Imię:";
"Last:" = "Nazwisko:";
"Nickname:" = "Pseudonim:";
"Telephone" = "Telefon";
"Work:" = "Praca:";
"Home:" = "Dom:";
"Fax:" = "Fax:";
"Mobile:" = "Telefon kom.:";
"Pager:" = "Pager:";
"Title:" = "Tytuł:";
"Service:" = "Usługa:";
"Company:" = "Firma:";
"Department:" = "Oddział:";
"Organization:" = "Organizacja:";
"Address:" = "Adres:";
"City:" = "Miejscowość:";
"State_Province:" = "Województwo:";
"ZIP_Postal Code:" = "Kod pocztowy:";
"Country:" = "Kraj:";
"Web Page:" = "Strona WWW:";
"Work" = "Praca";
"Other Infos" = "Inne informacje";
"Note:" = "Uwagi:";
"Timezone:" = "Strefa czasowa:";
"Birthday:" = "Urodziny:";
"Birthday (yyyy-mm-dd):" = "Urodziny (yyyy-mm-dd):";
"Freebusy URL:" = "URL statusu wolny-zajęty:";
"Add as..." = "Dodaj jako...";
"Recipient" = "Odbiorca";
"Carbon Copy" = "Do wiadomości";
"Blind Carbon Copy" = "Ukryte do wiadomości";
"New Addressbook..." = "Nowa książka adresowa...";
"Subscribe to an Addressbook..." = "Subskrybuj książkę adresową...";
"Remove the selected Addressbook" = "Usuń zaznaczoną książkę adresową";
"Name of the Address Book" = "Nazwa książki adresowej";
"Are you sure you want to delete the selected address book?"
= "Czy na pewno chcesz skasować zaznaczoną książkę adresową?";
"You cannot remove nor unsubscribe from a public addressbook."
= "Nie możesz usunąć ani zrezygnować z subskrypcji publicznej książki adresowej.";
"You cannot remove nor unsubscribe from your personal addressbook."
= "Nie możesz usunąć ani zrezygnować z subskrypbji osobistej książki adresowej.";
"Are you sure you want to delete the selected contacts?"
= "Czy na pewno chcesz skasować zaznaczone kontakty?";
"You cannot delete the card of \"%{0}\"."
= "Nie możesz skasować kontaktu do \"%{0}\".";
"Address Book Name" = "Nazwa książki adresowej";
"You cannot subscribe to a folder that you own!"
= "Nie możesz zrezygnować z subskrypcji foldera, którego jesteś właścicielem.";
"Unable to subscribe to that folder!"
= "Nie można włączyć subskrypcji tego foldera.";
"User rights for:" = "Uprawnienia użytkownika:";
"Any Authenticated User" = "Każdy zalogowany użytkownik";
"Public Access" = "Dostęp publiczny";
"This person can add cards to this addressbook."
= "Ta osoba może dodawać kontakty do tej książki adresowej.";
"This person can edit the cards of this addressbook."
= "Ta osoba może edytować kontakty w tej książce adresowej.";
"This person can list the content of this addressbook."
= "Ta osoba może przeglądać zawartość tej książki adresowej.";
"This person can read the cards of this addressbook."
= "Ta osoba może odczytywać kontakty z tej książki adresowej.";
"This person can erase cards from this addressbook."
= "Ta osoba może usuwać kontakty z tej książki adresowej.";
"The selected contact has no email address."
= "Wskazany kontakt nie ma adresu e-mail.";
"Please select a contact." = "Zaznacz kontakt.";
/* Error messages for move and copy */
"SoAccessDeniedException" = "Nie masz prawa zapisu do tej książki adresowej.";
"Forbidden" = "Nie masz prawa zapisu do tej książki adresowej.";
"Invalid Contact" = "Wskazany kontakt już nie istnieje.";
"Unknown Destination Folder" = "Wybrana docelowa książka adresowa już nie istnieje.";
/* Lists */
"List details" = "Szczegóły listy";
"List name:" = "Nazwa listy:";
"List nickname:" = "Nick listy:";
"List description:" = "Opis listy:";
"Members" = "Członkowie";
"Contacts" = "Kontakty";
"Add" = "Dodaj";
"Lists can't be moved or copied." = "Listy nie mogą być przeniesione ani skopiowane.";
"Export" = "Eksport";
"Export Address Book..." = "Eksportuj książkę adresową...";
"Import Cards" = "Importuj kontakty";
"Select a vCard or LDIF file." = "Wskaż plik vCard lub LDIF.";
"Upload" = "Wyślij";
"Done" = "Zrobione";
"An error occured while importing contacts." = "W trakcie importu kontaktów pojawił się błąd.";
"No card was imported." = "Nie zaimportowano żadnego kontaktu.";
"A total of %{0} cards were imported in the addressbook." = "Liczba wszystkich kontaktów zaimportowanych do książki adresowej: %{0}.";
"Reload" = "Przeładuj";

View File

@ -45,6 +45,7 @@
"Edit the selected card" = "Edit the selected card";
"Send a mail message" = "Send a mail message";
"Delete selected card or address book" = "Delete selected card or address book";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Unknown";
"htmlMailFormat_FALSE" = "Plain Text";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Modificar el contacto seleccionado";
"Send a mail message" = "Enviar un correo";
"Delete selected card or address book" = "Borrar contacto o libreta de direcciones seleccionados";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Desconocido";
"htmlMailFormat_FALSE" = "Texto plano";

View File

@ -51,6 +51,7 @@
"Edit the selected card" = "Redigera markerat adresskort";
"Send a mail message" = "Skicka ett meddelande";
"Delete selected card or address book" = "Ta bort markerat adresskort eller adressbok";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Okänt";
"htmlMailFormat_FALSE" = "Oformaterad Text";

View File

@ -2,7 +2,6 @@
"Contact" = "Контакт";
"Address" = "Адреса";
"Photos" = "Photos";
"Other" = "Інше";
"Address Books" = "Адресні книги";
@ -112,7 +111,6 @@
"Note:" = "Примітки:";
"Timezone:" = "Часова зона:";
"Birthday:" = "День народження:";
"Birthday (yyyy-mm-dd):" = "День народження (yyyy-mm-dd):";
"Freebusy URL:" = "Freebusy URL:";
"Add as..." = "Додати як...";

View File

@ -45,6 +45,7 @@
"Edit the selected card" = "Golygu'r cerdyn dewisol";
"Send a mail message" = "Anfon neges ebost";
"Delete selected card or address book" = "Dileu y cerdyn dewisol neu'r llyfr cyfeiriadau";
"Reload all contacts" = "Reload all contacts";
"htmlMailFormat_UNKNOWN" = "Anhysbys";
"htmlMailFormat_FALSE" = "Testun plaen";

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = MailPartViewers
MailPartViewers_PRINCIPAL_CLASS = MailPartViewersProduct
MailPartViewers_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
MailPartViewers_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
MailPartViewers_OBJC_FILES += \
MailPartViewersProduct.m \

View File

@ -0,0 +1,45 @@
ACCEPTED = "zaakceptowane";
COMPLETED = "zakończone";
DECLINED = "odrzucone";
DELEGATED = "przekazane";
IN-PROCESS = "przetwarzane";
NEEDS-ACTION = "wymaga akcji";
TENTATIVE = "niepewny";
organized_by_you = "organizowane przez ciebie";
you_are_an_attendee = "jesteś uczestnikiem";
add_info_text = "żądania iMIP 'ADD' nie są jeszcze obsługiwane przez SOGo.";
publish_info_text = "Nadawca informuje cię o załączonym wydarzeniu.";
cancel_info_text = "Twoje zaproszenie lub całe wydarzenie zostało anulowane.";
request_info_no_attendee = "proponuje uczestnikom spotkanie. Otrzymujesz tę wiadomość jako powiadomienie, nie jesteś planowany jako uczestnik.";
Appointment = "Spotkanie";
Organizer = "Organizator";
Time = "Czas";
Attendees = "Uczestnicy";
request_info = "zaprasza cię na spotkanie.";
"Add to calendar" = "Dodaj do kalendarza";
"Delete from calendar" = "Usuń z kalendarza";
"Update status" = "Zaktualizuj status";
Accept = "Akceptuj";
Decline = "Odmów";
Tentative = "Niepewny";
"Delegate ..." = "Przekaż ...";
"Delegated to" = "Przekazane do";
"Update status in calendar" = "Zaktualizuj status w kalendarzu";
reply_info_no_attendee = "Otrzymałeś odpowiedź do wydarzenia ale nadawca nie jest uczestnikiem.";
reply_info = "To jest odpowiedź do utworzonego przez ciebie wydarzenia";
"to" = "do";
"Untitled" = "Bez tytułu";
"Size" = "Rozmiar";
"Digital signature is not valid" = "Podpis elektroniczny nie jest poprawny";
"Message is signed" = "Wiadomość jest podpisana";
"Subject" = "Temat";
"From" = "Od";
"Date" = "Data";
"To" = "Do";
"Issuer" = "Wystawca";

View File

@ -26,7 +26,6 @@ Tentative = "попередьно погодитись";
"Delegate ..." = "Делегуват ...";
"Delegated to" = "Делегувати";
"Update status in calendar" = "Поновити статус в календарі";
"delegated from" = "delegated from";
reply_info_no_attendee = "Ви отримали відповідь на запланований захід, але відправник повідомлення відсутній серед запрошених.";
reply_info = "Це відповідь на Ваше запрошення взяти участь у заході.";

View File

@ -136,6 +136,7 @@
"View" = "Visão";
"All" = "Tudo";
"Unread" = "Não Lido";
"No message" = "No message";
"messages" = "mensagens";
"first" = "Primeiro";

View File

@ -136,6 +136,7 @@
"View" = "Zobrazit";
"All" = "Všechny";
"Unread" = "Nepřečtené";
"No message" = "No message";
"messages" = "zprávy";
"first" = "Nejnovější";

View File

@ -136,6 +136,7 @@
"View" = "View";
"All" = "Alle";
"Unread" = "Ongelezen";
"No message" = "No message";
"messages" = "berichten";
"first" = "eerste";

View File

@ -136,6 +136,7 @@
"View" = "View";
"All" = "All";
"Unread" = "Unread";
"No message" = "No message";
"messages" = "messages";
"first" = "First";

View File

@ -136,6 +136,7 @@
"View" = "View";
"All" = "Tous";
"Unread" = "Non lus";
"No message" = "No message";
"messages" = "message(s)";
"first" = "Premier";

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = MailerUI
MailerUI_PRINCIPAL_CLASS = MailerUIProduct
MailerUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
MailerUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
MailerUI_OBJC_FILES += \
MailerUIProduct.m \

View File

@ -136,6 +136,7 @@
"View" = "Ansicht";
"All" = "Alle";
"Unread" = "Ungelesene";
"No message" = "No message";
"messages" = "Nachricht(en)";
"first" = "Erste";

View File

@ -136,6 +136,7 @@
"View" = "Nézet";
"All" = "Összes";
"Unread" = "Olvasatlan";
"No message" = "No message";
"messages" = "üzenetek";
"first" = "Első";

View File

@ -136,6 +136,7 @@
"View" = "Vista";
"All" = "Tutti";
"Unread" = "Non letti";
"No message" = "No message";
"messages" = "messaggi";
"first" = "Primo";

View File

@ -0,0 +1,272 @@
/* this file is in UTF-8 format! */
/* Icon's label */
"Create" = "Utwórz";
"Empty Trash" = "Opróżnij kosz";
"Delete" = "Usuń";
"Expunge" = "Wyczyść ostatecznie";
"Forward" = "Przekaż";
"Get Mail" = "Pobierz pocztę";
"Junk" = "Śmieć";
"Reply" = "Odpowiedz";
"Reply All" = "Odpowiedz wszystkim";
"Print" = "Drukuj";
"Stop" = "Zatrzymaj";
"Write" = "Napisz";
"Send" = "Wyślij";
"Contacts" = "Kontakty";
"Attach" = "Załącz";
"Save" = "Zapisz";
"Priority" = "Priorytet";
"Size" = "Rozmiar";
/* Tooltips */
"Send this message now" = "Wyślij teraz tę wiadomość";
"Select a recipient from an Address Book" = "Wybierz odbiorcę z książki adresowej";
"Include an attachment" = "Dodaj załącznik";
"Save this message" = "Zapisz tę wiadomość";
"Get new messages" = "Pobierz nową wiadomość";
"Create a new message" = "Utwórz nową wiadomość";
"Go to address book" = "Idź do książki adresowej";
"Reply to the message" = "Odpowiedz na wiadomość";
"Reply to sender and all recipients" = "Odpowiedz nadawcy i wszystkim odbiorcom";
"Forward selected message" = "Przekaż zaznaczoną wiadomość";
"Delete selected message or folder" = "Usuń zaznaczoną wiadomość lub folder";
"Mark the selected messages as junk" = "Oznacz zaznaczone wiadomości jako śmieci";
"Print this message" = "Wydrukuj tę wiadomość";
"Stop the current transfer" = "Zatrzymaj bieżący transfer";
"Attachment" = "Załącznik";
"Unread" = "Nieprzeczytane";
"Flagged" = "Oflagowane";
/* Main Frame */
"Home" = "Strona główna";
"Calendar" = "Kalendarz";
"Addressbook" = "Książka adresowa";
"Mail" = "Poczta";
"Right Administration" = "Uprawnienia";
"Help" = "Pomoc";
/* Mail account main windows */
"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Witaj w programie SOGo Mailer. Używaj drzewa folderów po lewej stronie by przeglądać swoje konta pocztowe!";
"Read messages" = "Wiadomości przeczytane";
"Write a new message" = "Napisz nową wiadomość";
"Share: " = "Udostępnianie: ";
"Account: " = "Konto: ";
"Shared Account: " = "Udostępnione konto: ";
/* acls */
"Default Roles" = "Domyślne role";
"User rights for:" = "Uprawnienia użytkownika dla:";
"List and see this folder" = "Wylistuj i zobacz ten folder";
"Read mails from this folder" = "Czytaj wiadomości z tego foldera";
"Mark mails read and unread" = "Zaznacz wiadomości jako przeczytane lub nie przeczytane";
"Modify the flags of the mails in this folder" = "Zmień oflagowanie wiadomości w tym folderze";
"Insert, copy and move mails into this folder" = "Wstaw, kopiuj lub przenieś wiadomości do tego foldera";
"Post mails" = "Wyślij wiadomości";
"Add subfolders to this folder" = "Utwórz podfoldery w tym folderze";
"Remove this folder" = "Usuń ten folder";
"Erase mails from this folder" = "Usuń wiadomości z tego foldera";
"Expunge this folder" = "Wyczyść ostatecznie ten folder";
"Archive This Folder" = "Zarchiwizuj ten folder";
"Modify the acl of this folder" = "Modyfikuj uprawnienia ACL tego foldera";
"Saved Messages.zip" = "Zapisano Messages.zip";
"Update" = "Zaktualizuj";
"Cancel" = "Anuluj";
/* Mail edition */
"From" = "Od";
"Subject" = "Temat";
"To" = "Do";
"Cc" = "DW";
"Bcc" = "UDW";
"Reply-To" = "Odpowiedź do";
"Add address" = "Dodaj adres";
"Attachments:" = "Załączniki:";
"Open" = "Otwórz";
"Select All" = "Zaznacz wszystkie";
"Attach Web Page..." = "Załącz stronę Web...";
"Attach File(s)..." = "Załącz plik(i)...";
"to" = "Do";
"cc" = "DW";
"bcc" = "UDW";
"Addressbook" = "Książka adresowa";
"Edit Draft..." = "Edytuj szkic...";
"Load Images" = "Załaduj obrazki";
"highest" = "Najwyższy";
"high" = "Wysoki";
"normal" = "Normalny";
"low" = "Niski";
"lowest" = "Najniższy";
"This mail is being sent from an unsecure network!" = "Ta wiadomość jest wysyłana z niezabezpieczonej sieci!";
/* Popup "show" */
"all" = "wszystkie";
"read" = "przeczytane";
"unread" = "nie przeczytane";
"deleted" = "usunięte";
"flagged" = "oflagowane";
/* MailListView */
"Sender" = "Nadawca";
"Subject or Sender" = "Temat lub nadawca";
"To or Cc" = "Do lub DW";
"Entire Message" = "Cała wiadomość";
"Date" = "Data";
"View" = "Widok";
"All" = "Wszystkie";
"Unread" = "Nie przeczytane";
"No message" = "Brak wiadomości";
"messages" = "wiadomości";
"first" = "Pierwsza";
"previous" = "Poprzednia";
"next" = "Następna";
"last" = "Ostatnia";
"msgnumber_to" = "do";
"msgnumber_of" = "z";
"Mark Unread" = "Oznacz jako nie przeczytane";
"Mark Read" = "Oznacz jako przeczytane";
"Untitled" = "Bez tytułu";
/* Tree */
"SentFolderName" = "Wysłane";
"TrashFolderName" = "Kosz";
"InboxFolderName" = "Odebrane";
"DraftsFolderName" = "Szkice";
"SieveFolderName" = "Filtry";
"Folders" = "Foldery"; /* title line */
/* MailMoveToPopUp */
"MoveTo" = "Przenieś &hellip;";
/* Address Popup menu */
"Add to Address Book..." = "Dodaj do książki adresowej...";
"Compose Mail To" = "Utwórz wiadomość do";
"Create Filter From Message..." = "Utwórz filtr z wiadomości...";
/* Image Popup menu */
"Save Image" = "Zapisz obrazek";
"Save Attachment" = "Zapisz załącznik";
/* Mailbox popup menus */
"Open in New Mail Window" = "Otwórz w nowym oknie";
"Copy Folder Location" = "Kopiuj położenie foldera";
"Subscribe..." = "Subskrybuj...";
"Mark Folder Read..." = "Oznacz folder jako przeczytany...";
"New Folder..." = "Nowy folder...";
"Compact This Folder" = "Kompaktuj ten folder";
"Search Messages..." = "Szukaj wiadomości...";
"Sharing..." = "Udostępnianie...";
"New Subfolder..." = "Nowy podfolder...";
"Rename Folder..." = "Zmień nazwę foldera...";
"Delete Folder" = "Usuń folder";
"Use This Folder For" = "Użyj tego foldera do";
"Get Messages for Account" = "Pobierz wiadomości z konta";
/* Use This Folder menu */
"Sent Messages" = "Wysłane";
"Drafts" = "Szkice";
"Deleted Messages" = "Usunięte";
/* Message list popup menu */
"Open Message In New Window" = "Otwórz wiadomość w nowym oknie";
"Reply to Sender Only" = "Odpowiedz tylko nadawcy";
"Reply to All" = "Odpowiedz wszystkim";
"Forward" = "Przekaż";
"Edit As New..." = "Edytuj jako nową...";
"Move To" = "Przenieś do";
"Copy To" = "Kopiuj do";
"Label" = "Etykieta";
"Mark" = "Oznacz";
"Save As..." = "Zapisz jako...";
"Print Preview" = "Podgląd wydruku";
"View Message Source" = "Pokaż źródło wiadomości";
"Print..." = "Drukuj...";
"Delete Message" = "Usuń wiadomość";
"Delete Selected Messages" = "Usuń zaznaczone wiadomości";
"This Folder" = "Ten folder";
/* Label popup menu */
"None" = "Brak";
"Important" = "Ważne";
"Work" = "Praca";
"Personal" = "Osobiste";
"To Do" = "Do zrobienia";
"Later" = "Później";
/* Mark popup menu */
"As Read" = "Jako przeczytane";
"Thread As Read" = "Wątek jako przeczytany";
"As Read By Date..." = "jako przeczytane do daty...";
"All Read" = "wszystkie przeczytane";
"Flag" = "Flaga";
"As Junk" = "Jako śmieć";
"As Not Junk" = "Jako nie-śmieć";
"Run Junk Mail Controls" = "Uruchom kontrole wiadomości śmieci";
/* Folder operations */
"Name :" = "Nazwa :";
"Enter the new name of your folder :"
= "Wprowadź nową nazwę twojego foldera :";
"Do you really want to move this folder into the trash ?"
= "Czy na pewno chcesz przenieść ten folder do kosza ?";
"Operation failed" = "Operacja nie powiodła się";
"Quota" = "Limit:";
"quotasFormat" = "użyte %{0}% z %{1} MB";
"Please select a message." = "Zaznacz wiadomość.";
"Please select a message to print." = "Zaznacz wiadomość do drukowania.";
"Please select only one message to print." = "Zaznacz tylko jedną wiadomość do drukowania.";
"The message you have selected doesn't exist anymore." = "Zaznaczona wiadomość już nie istnieje.";
"The folder with name \"%{0}\" could not be created."
= "Nie można było utworzyć foldera o nazwie \"%{0}\".";
"This folder could not be renamed to \"%{0}\"."
= "Nie można było zmienić nazwy foldera na \"%{0}\".";
"The folder could not be deleted."
= "Nie można było usunąć foldera.";
"The trash could not be emptied."
= "Nie można było opróżnić kosza.";
"The folder functionality could not be changed."
= "Nie można było zmienić funkcjonalności foldera.";
"You need to choose a non-virtual folder!" = "Musisz wybrać folder, który nie jest wirtualny!";
"Moving a message into its own folder is impossible!"
= "Przenoszenie wiadomości do jej obecnego foldera nie jest możliwe!";
"Copying a message into its own folder is impossible!"
= "Kopiowanie wiadomości do jej obecnego foldera nie jest możliwe!";
/* Message editing */
"error_validationfailed" = "Weryfikacja zakończona niepowodzeniem";
"error_missingsubject" = "Brak tematu";
"error_missingrecipients" = "Brak odbiorców";

View File

@ -136,6 +136,7 @@
"View" = "Просмотр";
"All" = "Все";
"Unread" = "Непрочитанные";
"No message" = "No message";
"messages" = "сообщения";
"first" = "первая";

View File

@ -136,6 +136,7 @@
"View" = "Vista";
"All" = "Todo";
"Unread" = "No leído";
"No message" = "No message";
"messages" = "mensajes";
"first" = "Primero";

View File

@ -136,6 +136,7 @@
"View" = "Visa";
"All" = "Alla";
"Unread" = "Oläst";
"No message" = "No message";
"messages" = "meddelanden";
"first" = "Första";

View File

@ -1,6 +1,6 @@
/* UIxMailFolderActions.m - this file is part of SOGo
*
* Copyright (C) 2007-2009 Inverse inc.
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*

View File

@ -45,7 +45,7 @@
"Home" = "Початок";
"Calendar" = "Календар";
"Addressbook" = "Адресна книга";
"Addressbook" = "Адресна";
"Mail" = "Пошта";
"Right Administration" = "Права доступу";

View File

@ -136,6 +136,7 @@
"View" = "Gweld";
"All" = "Oll";
"Unread" = "Heb ddarllen";
"No message" = "No message";
"messages" = "negeseuon";
"first" = "Cyntaf";

View File

@ -28,15 +28,16 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "Sobre";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.";
"Your account was locked due to too many failed attempts." = "Your account was locked due to too many failed attempts.";
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "O";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright (c) 2006-2010 Inverse inc.<br/>
Copyright (c) 2006-2009 Inverse inc.<br/>
Copyright (c) 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "Nové heslo:";
"Confirmation:" = "Potvrzení:";
"Cancel" = "Odvolat";
"Please wait..." = "Prosím čekejte...";
"Please wait..." = "Prosím čekejte...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "À propos";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "Nouveau mot de passe:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Annuler";
"Please wait..." = "Veuillez patienter...";
"Please wait..." = "Veuillez patienter...";

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = MainUI
MainUI_PRINCIPAL_CLASS = MainUIProduct
MainUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
MainUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
MainUI_OBJC_FILES += \
MainUIProduct.m \

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "Neues Passwort:";
"Confirmation:" = "Bestätigung:";
"Cancel" = "Abbrechen";
"Please wait..." = "Bitte warten...";
"Please wait..." = "Bitte warten...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "Névjegy";
"AboutBox" = "A SOGo az OpenGroupware.org (OGo) és a SOPE alkalmazás szerverre épülő csoportmunka szerver, amely a skálázhatóságra összpontosít.<br/><br/>
A SOGo egy AJAX alapú webes felültet biztosít, továbbá több desktop kliens programot is támogat olyan szabványos protokollokon keresztül, mint a CalDAV, a CardDAV és a GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
A szoftver a <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2. licensz alapján kerül terjesztésre<br/>
A szoftver egyes részei a GNU LGPL version 2. licensz alapján kerülnek terjesztésre.<br/><br/>
@ -67,4 +68,4 @@ Ez egy ingyenes szoftver: ön jogosult változtatni és továbbterjeszteni. Ninc
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -0,0 +1,35 @@
/* Polish */
{
NSLanguageName = "Polish";
NSFormalName = "Polski";
NSLocaleCode = "pl"; /* ISO 639-1 */
NSLanguageCode = "pol"; /* ISO 639-2 */
NSParentContext = "";
NSAMPMDesignation = (AM, PM);
NSCurrencySymbol = "zł";
NSDateFormatString = "%A, %B %e %Y";
NSDateTimeOrdering = YMDH;
NSDecimalDigits = ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
NSDecimalSeparator = ",";
NSEarlierTimeDesignations = ("przed", "ostatni", "po", "temu");
NSHourNameDesignations = ((0, "północ"), (10, "rano"), (12, "południe", "lunch"), (14, "popołudnie"), (19, "wieczór"));
NSInternationalCurrencyString = PLN; /* ISO 4217 */
NSLaterTimeDesignations = ("następny");
NSMonthNameArray = ("Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień");
NSNextDayDesignations = ("jutro");
NSNextNextDayDesignations = ("następny dzień");
NSPriorDayDesignations = ("wczoraj");
NSShortDateFormatString = "%e/%m/%y";
NSShortMonthNameArray = ("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru");
NSShortTimeDateFormatString = "%y-%m-%e %H:%M";
NSShortWeekDayNameArray = ("Nie", "Pon", "Wto", "Śro", "Czw", "Pią", "Sob");
NSThisDayDesignations = ("dzisiaj", "teraz");
NSThousandsSeparator = " ";
NSTimeDateFormatString = "%A, %e %B %Y %H:%M:%S %Z";
NSTimeFormatString = "%H:%M:%S";
NSWeekDayNameArray = ("Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota");
NSYearMonthWeekDesignations = ("rok", "miesiąc", "tydzień");
NSPositiveCurrencyFormatString = "9,999.00$";
NSNegativeCurrencyFormatString = "-9,999.00$";
}

View File

@ -0,0 +1,73 @@
/* this file is in UTF-8 format! */
"title" = "SOGo";
"Username:" = "Nazwa użytkownika:";
"Password:" = "Hasło:";
"Connect" = "Zaloguj";
"Wrong username or password." = "Zła nazwa użytkownika lub hasło.";
"cookiesNotEnabled" = "Nie możesz się zalogować ponieważ twoja przeglądarka ma zablokowaną obsługę ciasteczek (cookies). Włącz obsługę ciasteczek w ustawieniach twojej przeglądarki i spróbuj ponownie.";
"browserNotCompatible" = "Używasz przeglądarki WWW, która nie jest obecnie obsługiwana przez tę stronę. Rekomendowaną przeglądarką jest Firefox. Kliknij poniższy odnośnik aby pobrać najnowszą wersję tej przeglądarki.";
"alternativeBrowsers" = "Alternatywnie możesz także używać następujących przeglądarek";
"alternativeBrowserSafari" = "Alternatywnie możesz używać również przeglądarki Safari.";
"Download" = "Pobierz";
"Language:" = "Język:";
"choose" = "Wybierz ...";
"Czech" = "Česky";
"Dutch" = "Nederlands";
"English" = "English";
"French" = "Français";
"German" = "Deutsch";
"Hungarian" = "Magyar";
"Italian" = "Italiano";
"BrazilianPortuguese" = "Português brasileiro";
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Welsh" = "Cymraeg";
"Polish" = "Polski";
"About" = "O programie";
"AboutBox" = "SOGo jest serwerem pracy grupowej zbudowanym w oparciu o systemy OpenGroupware.org (OGo) oraz SOPE. Głównym celem SOGo jest skalowalność.<br/><br/>
SOGo oferuje bogaty, oparty na technologii AJAX interfejs webowy oraz wspiera wiele aplikacji klienckich dzięki korzystaniu ze standardowych protokołów takich jak CalDAV, CardDAV i GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/>
Tłumaczenie 2010 <a href=\"http://www.ib.pl/\">IB</a><br/><br/>
To oprogramowanie rozpowszechniane jest w oparciu o licencję <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Elementy tego oprogramowania rozpowszechniane są w oparciu o licencję GNU LGPL version 2.<br/><br/>
To oprogramowanie jest wolne: możesz je modyfikować i dystrybuować. Nie ma ŻADNYCH GWARANCJI, w zakresie dozwolonym przez prawo.";
"Your account was locked due to too many failed attempts." = "Twoje konto zostało zablokowane wkutek zbyt wielu nieudanych prób logowania.";
"Your account was locked due to an expired password." = "Twoje konto zostało zblokowane z powodu wygaśnięcia ważności hasła.";
"Login failed due to unhandled error case: " = "Logowanie nie powiodło się z powodu niezidentyfikowanego błędu: ";
"Change your Password" = "Zmień swoje hasło";
"Your password has expired, please enter a new one below:" = "Ważność twojego hasła wygasła, wprowadź niżej nowe hasło:";
"Password must not be empty." = "Hasło nie może być puste.";
"The passwords do not match. Please try again." = "Hasła nie są zgodne. Spróbuj jeszcze raz.";
"Password Grace Period" = "Okres pobłażliwości hasła";
"You have %{0} logins remaining before your account is locked. Please change your password in the preference dialog." = "Pozostało Ci %{0} logowań zanim konto zostanie zablokowane. Zmień swoje hasło w oknie właściwości.";
"Password about to expire" = "Wkrótce wygaśnie ważność hasła";
"Your password is going to expire in %{0} %{1}." = "Ważność twojego hasła wygaśnie za %{0} %{1}.";
"days" = "dni";
"hours" = "godz.";
"minutes" = "min.";
"seconds" = "sek.";
"Password change failed" = "Zmiana hasła nie powiodła się";
"Password change failed - Permission denied" = "Zmiana hasła nie powiodła się - odmowa dostępu";
"Password change failed - Insufficient password quality" = "Zmiana hasła nie powiodła się - niewystarczająca jakość hasła";
"Password change failed - Password is too short" = "Zmiana hasła nie powiodła się - hasło jest zbyt krótkie";
"Password change failed - Password is too young" = "Zmiana hasła nie powiodła się - hasło jest zbyt świeże";
"Password change failed - Password is in history" = "Zmiana hasła nie powiodła się - hasło znajduje się w historii";
"Unhandled policy error: %{0}" = "Niezidentyfikowany błąd zabezpieczeń: %{0}";
"Unhandled error response" = "Niezidentyfikowany błąd";
"Password change is not supported." = "Zmiana hasła nie jest obsługiwana.";
"Unhandled HTTP error code: %{0}" = "Nieobsługiwany kod błędu HTTP: %{0}";
"New password:" = "Nowe hasło:";
"Confirmation:" = "Potwierdzenie:";
"Cancel" = "Anuluj";
"Please wait..." = "Zaczekaj proszę...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "О системе";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "Om";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -28,12 +28,13 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
"About" = "About";
"AboutBox" = "SOGo is a groupware server built around OpenGroupware.org (OGo) and the SOPE application server. It focuses on scalability.<br/><br/>
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV, CardDAV and GroupDAV.<br/><br/>
Copyright © 2006-2010 Inverse inc.<br/>
Copyright © 2006-2009 Inverse inc.<br/>
Copyright © 2002-2005 SKYRIX Software AG<br/><br/>
This software are distributed under the <a href=\"http://gnu.org/licenses/gpl.html\">GNU GPL</a> version 2.<br/>
Parts of this software are distributed under the GNU LGPL version 2.<br/><br/>
@ -67,4 +68,4 @@ This is free software: you are free to change and redistribute it. There is NO W
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"Cancel" = "Cancel";
"Please wait..." = "Please wait...";
"Please wait..." = "Please wait...";

View File

@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -80,10 +80,10 @@
"Day end time :" = "Konec dne :";
"Day start time must be prior to day end time." = "Day start time must be prior to day end time.";
"First week of year :" = "První týden roku :";
"Enable reminders for Calendar items" = "Povolit připomínky pro položky v kalendáři";
"Enable reminders for Calendar items" = "Povolit upomínky pro položky v kalendáři";
"Play a sound when a reminder comes due"
= "Přehrát zvuk s připomenutím";
"Default reminder :" = "Výchozí připomenutí :";
= "Přehrát zvuk s upomínkou";
"Default reminder :" = "Výchozí upomínka :";
"firstWeekOfYear_January1" = "Začíná 1. ledna";
"firstWeekOfYear_First4DayWeek" = "První 4-denní týden";
@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -173,6 +173,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -6,7 +6,7 @@ BUNDLE_NAME = PreferencesUI
PreferencesUI_PRINCIPAL_CLASS = PreferencesUIProduct
PreferencesUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Russian Spanish Swedish Ukrainian Welsh
PreferencesUI_LANGUAGES = BrazilianPortuguese Czech Dutch English French German Hungarian Italian Polish Russian Spanish Swedish Ukrainian Welsh
PreferencesUI_OBJC_FILES = \
PreferencesUIProduct.m \

View File

@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -158,6 +158,7 @@
"BrazilianPortuguese" = "Português brasileiro";
"Russian" = "Русский";
"Spanish" = "Español";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -175,6 +175,7 @@
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Ukrainian" = "Українська";
"Welsh" = "Cymraeg";
/* Filters - UIxPreferences */

View File

@ -0,0 +1,223 @@
/* toolbar */
"Save and Close" = "Zapisz i zamknij";
"Close" = "Zamknij";
/* tabs */
"General" = "Ogólne";
"Calendar Options" = "Opcje kalendarza";
"Mail Options" = "Opcje poczty";
"Signature" = "Podpis";
"Vacation" = "Nieobecność";
"Forward" = "Przekazywanie";
"Identities" = "Tożsamości";
"Password" = "Hasło";
"Categories" = "Kategorie";
"Name" = "Nazwa";
"Color" = "Kolor";
"Add" = "Dodaj";
"Delete" = "Usuń";
/* vacation (auto-reply) */
"Enable vacation auto reply" = "Włącz autoodpowiedź podczas nieobecności";
"Auto reply message :" = "Treść autoodpowiedzi :";
"Email addresses (separated by commas) :" = "Adresy e-mail (oddzielone przecinkami) :";
"Add default email addresses" = "Dodaj domyślne adresy e-mail";
"Days between responses :" = "Dni pomiędzy odpowiedziami :";
"Do not send responses to mailing lists" = "Nie wysyłaj odpowiedzi do grup pocztowych";
"Please specify your message and your email addresses for which you want to enable auto reply."
= "Podaj treść wiadomości i twoje adresy e-mail, dla których chcesz włączyć autoodpowiedź.";
/* forward messages */
"Forward incoming messages" = "Przekaż przychodzące wiadomości";
"Forward to address :" = "Przekaż na adres :";
"Keep a copy" = "Zatrzymaj kopię";
"Please specify an address to which you want to forward your messages."
= "Podaj adres, na który chcesz przekazywać wiadomości.";
/* d & t */
"Current Time Zone :" = "Bieżąca strefa czasowa :";
"Short Date Format :" = "Krótki format daty :";
"Long Date Format :" = "Długi format daty :";
"Time Format :" = "Format czasu :";
"default" = "Domyślne";
"shortDateFmt_0" = "%d-%b-%y";
"shortDateFmt_1" = "%d-%m-%y";
"shortDateFmt_2" = "%d/%m/%y";
"shortDateFmt_3" = "%e/%m/%y";
"shortDateFmt_4" = "%d-%m-%Y";
"shortDateFmt_5" = "%d/%m/%Y";
"shortDateFmt_6" = "%m-%d-%y";
"shortDateFmt_7" = "%m/%d/%y";
"shortDateFmt_8" = "%m/%e/%y";
"shortDateFmt_9" = "%y-%m-%d";
"shortDateFmt_10" = "%y/%m/%d";
"shortDateFmt_11" = "%y.%m.%d";
"shortDateFmt_12" = "%Y-%m-%d";
"shortDateFmt_13" = "%Y/%m/%d";
"shortDateFmt_14" = "%Y.%m.%d";
"shortDateFmt_15" = "";
"longDateFmt_0" = "%A, %B %d, %Y";
"longDateFmt_1" = "%B %d, %Y";
"longDateFmt_2" = "%A, %d %B, %Y";
"longDateFmt_3" = "%d %B, %Y";
"longDateFmt_4" = "";
"timeFmt_0" = "%I:%M %p";
"timeFmt_1" = "%H:%M";
"timeFmt_2" = "";
/* calendar */
"Week begins on :" = "Pierwszy dzień tygodnia :";
"Day start time :" = "Początek dnia :";
"Day end time :" = "Koniec dnia :";
"Day start time must be prior to day end time." = "Początek dnia musi wypadać wcześniej niż koniec dnia.";
"First week of year :" = "Pierwszy tydzień roku :";
"Enable reminders for Calendar items" = "Włącz przypomnienia pozycji kalendarza";
"Play a sound when a reminder comes due"
= "Odtwórz dźwięk w momencie przypomnienia";
"Default reminder :" = "Domyślne przypomnienie :";
"firstWeekOfYear_January1" = "rozpoczyna się 1 stycznia";
"firstWeekOfYear_First4DayWeek" = "pierwszy 4-dniowy tydzień";
"firstWeekOfYear_FirstFullWeek" = "pierwszy pełny tydzień";
"reminderTime_0000" = "0 minut";
"reminderTime_0005" = "5 minut";
"reminderTime_0010" = "10 minut";
"reminderTime_0015" = "15 minut";
"reminderTime_0030" = "30 minut";
"reminderTime_0100" = "1 godzina";
"reminderTime_0200" = "2 godziny";
"reminderTime_0400" = "4 godziny";
"reminderTime_0800" = "8 godzin";
"reminderTime_1200" = "1/2 dnia";
"reminderTime_2400" = "1 dzień";
"reminderTime_4800" = "2 dni";
/* Mailer */
"Show subscribed mailboxes only" = "Pokaż tylko subskrybowane konta pocztowe";
"Check for new mail:" = "Sprawdzaj nowe wiadomości:";
"messagecheck_manually" = "ręcznie";
"messagecheck_every_minute" = "co minutę";
"messagecheck_every_2_minutes" = "co 2 minuty";
"messagecheck_every_5_minutes" = "co 5 minut";
"messagecheck_every_10_minutes" = "co 10 minut";
"messagecheck_every_20_minutes" = "co 20 minut";
"messagecheck_every_30_minutes" = "co 30 minut";
"messagecheck_once_per_hour" = "raz na godzinę";
"Forward messages:" = "Przekaż wiadomości:";
"messageforward_inline" = "w treści";
"messageforward_attached" = "jako załącznik";
/* Identities */
"Default identity:" = "Domyślna tożsamość:";
"Manage identities..." = "Zarządzaj tożsamościami...";
"replyplacement_above" = "Rozpocznij moją odpowiedź powyżej cytatu";
"replyplacement_below" = "Rozpocznij moją odpowiedź poniżej cytatu";
"And place my signature" = "i wstaw mój podpis";
"signatureplacement_above" = "poniżej odpowiedzi";
"signatureplacement_below" = "poniżej cytatu";
"Compose messages in" = "Twórz wiadomości";
"composemessagestype_html" = "HTML";
"composemessagestype_text" = "czysty tekst";
"composeMessageChanged" = "Zmiana konfiguracji tworzenia wiadomości wymaga natychmiastowego zapisania twoich ustawień. Kontynuować?";
/* Additional Parameters */
"Additional Parameters" = "Dodatkowe parametry";
/* password */
"New password:" = "Nowe hasło:";
"Confirmation:" = "Potwierdzenie:";
"Change" = "Zmiana";
/* Event+task categories */
"category_none" = "Brak";
"category_labels" = "Rocznica,Urodziny,Biznes,Telefony,Klienci,Konkurencja,Klient,Ulubione,Nawiązanie,Podarunki,Święta,Idee,Spotkania,Problemy,Różne,Osobiste,Projekty,Święta,Status,Dostawcy,Podróż,Wakacje";
/* Default module */
"Calendar" = "Kalendarz";
"Contacts" = "Książka adresowa";
"Mail" = "Poczta";
"Last" = "Ostatnio używane";
"Default module :" = "Tryb domyślny :";
"Language :" = "Język :";
"choose" = "Wybierz ...";
"Czech" = "Česky";
"Dutch" = "Nederlands";
"English" = "English";
"French" = "Français";
"German" = "Deutsch";
"Hungarian" = "Magyar";
"Italian" = "Italiano";
"BrazilianPortuguese" = "Português brasileiro";
"Russian" = "Русский";
"Spanish" = "Español";
"Swedish" = "Svenska";
"Welsh" = "Cymraeg";
"Polish" = "Polski";
/* Filters - UIxPreferences */
"Filters" = "Filtry";
"Active" = "Aktywny";
"Move Up" = "Przenieś do góry";
"Move Down" = "Przenieś w dół";
/* Filters - UIxFilterEditor */
"Filter name:" = "Nazwa filtra:";
"For incoming messages that" = "Dla przychodzących wiadomości, które";
"match all of the following rules:" = "spełnią wszystkie poniższe reguły:";
"match any of the following rules:" = "spełnią którąkolwiek z poniższych reguł:";
"match all messages" = "dopasowanie wszystkich wiadomości";
"Perform these actions:" = "Wykonaj akcje:";
"Subject" = "Temat";
"From" = "Od";
"To" = "Do";
"Cc" = "DW";
"To or Cc" = "Do lub DW";
"Size (Kb)" = "Rozmiar (KB)";
"Header" = "Nagłówek";
"Flag the message with:" = "Oflaguj wiadomość:";
"Discard the message" = "Odrzuć wiadomość";
"File the message in:" = "Zapisz wiadomość w:";
"Keep the message" = "Zatrzymaj wiadomość";
"Forward the message to:" = "przekaż wiadomość do:";
"Send a reject message:" = "Wyślij odmowę:";
"Send a vacation message" = "Wyślij informację o nieobecności";
"Stop processing filter rules" = "Zakończ przetwarzanie reguł filtra";
"is under" = "jest podniżej";
"is over" = "jest ponad";
"is" = "jest";
"is not" = "nie jest";
"contains" = "zawiera";
"does not contain" = "nie zawiera";
"matches" = "pasuje do";
"does not match" = "nie pasuje do";
"matches regex" = "pasuje do regex";
"does not match regex" = "nie pasuje do regex";
"Seen" = "Obejrzane";
"Deleted" = "Usunięte";
"Answered" = "Odpowiedziane";
"Flagged" = "Oflagowane";
"Junk" = "Śmieć";
"Not Junk" = "Nie śmieć";
"Label 1" = "Etykieta 1";
"Label 2" = "Etykieta 2";
"Label 3" = "Etykieta 3";
"Label 4" = "Etykieta 4";
"Label 5" = "Etykieta 5";

Some files were not shown because too many files have changed in this diff Show More