Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
686b32d78b | ||
|
|
6b322e6b75 | ||
|
|
29d004c4a4 | ||
|
|
1a8b82d75d | ||
|
|
ca87ac05a2 | ||
|
|
0c33bc58b6 | ||
|
|
6319007631 | ||
|
|
156a83046b | ||
|
|
84e170a601 | ||
|
|
5ada0024af | ||
|
|
7daa6728a1 | ||
|
|
1cbced4965 | ||
|
|
323bc50f10 | ||
|
|
8c81d55061 | ||
|
|
36fb9c138e | ||
|
|
81aee49555 | ||
|
|
ed4c2b3dca | ||
|
|
677df619fd | ||
|
|
40cd481ec0 | ||
|
|
cfcc4922ac | ||
|
|
1cf85475d7 | ||
|
|
83ce0f01b4 | ||
|
|
d1dcb820bd | ||
|
|
e098b3d050 | ||
|
|
18f7bc7e69 | ||
|
|
1a1afb7b95 | ||
|
|
44f7fdc50a | ||
|
|
3de6e0fc5a | ||
|
|
928b18890c | ||
|
|
828fed54a0 | ||
|
|
1b88d17e01 | ||
|
|
3d54bfb882 | ||
|
|
96914b39fb | ||
|
|
ec11b8abb4 | ||
|
|
2fbe6e8429 | ||
|
|
ac6b60c4c9 | ||
|
|
76eeef2541 | ||
|
|
086b905215 | ||
|
|
713e0d5ecb | ||
|
|
58732e316b | ||
|
|
9199d42e51 | ||
|
|
8c217103f8 | ||
|
|
ab5fd9fef1 | ||
|
|
165d866cfc | ||
|
|
8ba6c6d9f5 | ||
|
|
960962f92f | ||
|
|
cbb23bd536 | ||
|
|
196e36acb2 | ||
|
|
6c05576e53 | ||
|
|
9449b0df27 | ||
|
|
9ecee32d08 | ||
|
|
199c9d9237 | ||
|
|
d95b90281b | ||
|
|
8545f89b2f | ||
|
|
c827b62f7f | ||
|
|
16356aaf36 | ||
|
|
4c4d3e4c25 | ||
|
|
f638113d53 |
No files matched your search
+11
@@ -30,6 +30,7 @@ trans.pt_BR = UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/MailerUI/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/MailerUI/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/MailerUI/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/MailerUI/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/MailerUI/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/MailerUI/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/MailerUI/Ukrainian.lproj/Localizable.strings
|
||||
@@ -64,6 +65,7 @@ trans.pt_BR = UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/PreferencesUI/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/PreferencesUI/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/PreferencesUI/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/PreferencesUI/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/PreferencesUI/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/PreferencesUI/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/PreferencesUI/Ukrainian.lproj/Localizable.strings
|
||||
@@ -98,6 +100,7 @@ trans.pt_BR = UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/Scheduler/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/Scheduler/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/Scheduler/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/Scheduler/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/Scheduler/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/Scheduler/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/Scheduler/Ukrainian.lproj/Localizable.strings
|
||||
@@ -132,6 +135,7 @@ trans.pt_BR = UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/Contacts/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/Contacts/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/Contacts/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/Contacts/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/Contacts/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/Contacts/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/Contacts/Ukrainian.lproj/Localizable.strings
|
||||
@@ -166,6 +170,7 @@ trans.pt_BR = UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/MainUI/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/MainUI/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/MainUI/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/MainUI/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/MainUI/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/MainUI/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/MainUI/Ukrainian.lproj/Localizable.strings
|
||||
@@ -200,6 +205,7 @@ trans.pt_BR = UI/Common/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/Common/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/Common/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/Common/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/Common/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/Common/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/Common/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/Common/Ukrainian.lproj/Localizable.strings
|
||||
@@ -234,6 +240,7 @@ trans.pt_BR = UI/AdministrationUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/AdministrationUI/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/AdministrationUI/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/AdministrationUI/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/AdministrationUI/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/AdministrationUI/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/AdministrationUI/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/AdministrationUI/Ukrainian.lproj/Localizable.strings
|
||||
@@ -268,6 +275,7 @@ trans.pt_BR = SoObjects/Appointments/BrazilianPortuguese.lproj/Localizable.strin
|
||||
trans.ru = SoObjects/Appointments/Russian.lproj/Localizable.strings
|
||||
trans.sk = SoObjects/Appointments/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = SoObjects/Appointments/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = SoObjects/Appointments/Serbian.lproj/Localizable.strings
|
||||
trans.sv = SoObjects/Appointments/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = SoObjects/Appointments/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = SoObjects/Appointments/Ukrainian.lproj/Localizable.strings
|
||||
@@ -302,6 +310,7 @@ trans.pt_BR = SoObjects/Contacts/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = SoObjects/Contacts/Russian.lproj/Localizable.strings
|
||||
trans.sk = SoObjects/Contacts/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = SoObjects/Contacts/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = SoObjects/Contacts/Serbian.lproj/Localizable.strings
|
||||
trans.sv = SoObjects/Contacts/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = SoObjects/Contacts/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = SoObjects/Contacts/Ukrainian.lproj/Localizable.strings
|
||||
@@ -336,6 +345,7 @@ trans.pt_BR = SoObjects/Mailer/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = SoObjects/Mailer/Russian.lproj/Localizable.strings
|
||||
trans.sk = SoObjects/Mailer/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = SoObjects/Mailer/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = SoObjects/Mailer/Serbian.lproj/Localizable.strings
|
||||
trans.sv = SoObjects/Mailer/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = SoObjects/Mailer/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = SoObjects/Mailer/Ukrainian.lproj/Localizable.strings
|
||||
@@ -370,6 +380,7 @@ trans.pt_BR = UI/MailPartViewers/BrazilianPortuguese.lproj/Localizable.strings
|
||||
trans.ru = UI/MailPartViewers/Russian.lproj/Localizable.strings
|
||||
trans.sk = UI/MailPartViewers/Slovak.lproj/Localizable.strings
|
||||
trans.sl_SI = UI/MailPartViewers/Slovenian.lproj/Localizable.strings
|
||||
trans.sr = UI/MailPartViewers/Serbian.lproj/Localizable.strings
|
||||
trans.sv = UI/MailPartViewers/Swedish.lproj/Localizable.strings
|
||||
trans.tr_TR = UI/MailPartViewers/TurkishTurkey.lproj/Localizable.strings
|
||||
trans.uk = UI/MailPartViewers/Ukrainian.lproj/Localizable.strings
|
||||
|
||||
@@ -142,7 +142,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[s appendFormat: @"<JobTitle xmlns=\"Contacts:\">%@</JobTitle>", [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
if ((o = [self preferredEMail]))
|
||||
[s appendFormat: @"<Email1Address xmlns=\"Contacts:\">%@</Email1Address>", o];
|
||||
[s appendFormat: @"<Email1Address xmlns=\"Contacts:\">%@</Email1Address>", [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
|
||||
// Secondary email addresses (2 and 3)
|
||||
@@ -152,7 +152,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
o = [[emails objectAtIndex: i] flattenedValuesForKey: @""];
|
||||
|
||||
[s appendFormat: @"<Email%dAddress xmlns=\"Contacts:\">%@</Email%dAddress>", i+2, o, i+2];
|
||||
[s appendFormat: @"<Email%dAddress xmlns=\"Contacts:\">%@</Email%dAddress>", i+2, [o activeSyncRepresentationInContext: context], i+2];
|
||||
|
||||
if (i == 1)
|
||||
break;
|
||||
@@ -185,10 +185,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
a = [NSMutableString string];
|
||||
|
||||
if ((o = [homeAdr flattenedValueAtIndex: 2 forKey: @""]))
|
||||
[a appendString: o];
|
||||
[a appendString: [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
if ((o = [homeAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
|
||||
[a appendFormat: @"\n%@", o];
|
||||
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
[s appendFormat: @"<HomeStreet xmlns=\"Contacts:\">%@</HomeStreet>", [a activeSyncRepresentationInContext: context]];
|
||||
|
||||
@@ -216,10 +216,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
a = [NSMutableString string];
|
||||
|
||||
if ((o = [workAdr flattenedValueAtIndex: 2 forKey: @""]))
|
||||
[a appendString: o];
|
||||
[a appendString: [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
if ((o = [workAdr flattenedValueAtIndex: 1 forKey: @""]) && [o length])
|
||||
[a appendFormat: @"\n%@", o];
|
||||
[a appendFormat: @"\n%@", [o activeSyncRepresentationInContext: context]];
|
||||
|
||||
[s appendFormat: @"<BusinessStreet xmlns=\"Contacts:\">%@</BusinessStreet>", [a activeSyncRepresentationInContext: context]];
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Mailer/SOGoMailNamespace.h>
|
||||
|
||||
#include "iCalEvent+ActiveSync.h"
|
||||
#include "iCalToDo+ActiveSync.h"
|
||||
@@ -114,11 +115,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@implementation SOGoActiveSyncDispatcher (Sync)
|
||||
|
||||
- (void) _setOrUnsetSyncRequest: (BOOL) set
|
||||
collections: (NSArray *) collections
|
||||
collections: (NSArray *) collections
|
||||
{
|
||||
SOGoCacheGCSObject *o;
|
||||
NSNumber *processIdentifier;
|
||||
NSString *key;
|
||||
NSString *key, *collectionId;;
|
||||
int i;
|
||||
|
||||
processIdentifier = [NSNumber numberWithInt: [[NSProcessInfo processInfo] processIdentifier]];
|
||||
@@ -138,7 +139,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
for (i = 0; i < [collections count]; i++)
|
||||
{
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", [[[(id)[[collections objectAtIndex: i] getElementsByTagName: @"CollectionId"] lastObject] textValue] stringByUnescapingURL]];
|
||||
if ([[collections objectAtIndex: i] isKindOfClass: [NSString class]])
|
||||
collectionId = [collections objectAtIndex: i];
|
||||
else
|
||||
collectionId = [[[(id)[[collections objectAtIndex: i] getElementsByTagName: @"CollectionId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", collectionId];
|
||||
|
||||
[[o properties] setObject: processIdentifier forKey: key];
|
||||
}
|
||||
}
|
||||
@@ -147,7 +154,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[[o properties] removeObjectForKey: @"SyncRequest"];
|
||||
for (i = 0; i < [collections count]; i++)
|
||||
{
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", [[[(id)[[collections objectAtIndex: i] getElementsByTagName: @"CollectionId"] lastObject] textValue] stringByUnescapingURL]];
|
||||
if ([[collections objectAtIndex: i] isKindOfClass: [NSString class]])
|
||||
collectionId = [collections objectAtIndex: i];
|
||||
else
|
||||
collectionId = [[[(id)[[collections objectAtIndex: i] getElementsByTagName: @"CollectionId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", collectionId];
|
||||
|
||||
[[o properties] removeObjectForKey: key];
|
||||
}
|
||||
}
|
||||
@@ -161,7 +174,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
NSNumber *processIdentifier, *processIdentifierInCache;
|
||||
SOGoCacheGCSObject *o;
|
||||
NSDictionary *values;
|
||||
NSString *key;
|
||||
NSString *key, *pkey;
|
||||
NSArray *a;
|
||||
|
||||
if ([theFolderKey hasPrefix: @"folder"])
|
||||
key = [NSString stringWithFormat: @"SyncRequest+mail/%@", [theFolderKey substringFromIndex: 6]];
|
||||
@@ -172,7 +186,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
processIdentifierInCache = [[self globalMetadataForDevice] objectForKey: key];
|
||||
|
||||
// Don't update the cache if another request is processing the same collection.
|
||||
if (!([processIdentifierInCache isEqual: processIdentifier]))
|
||||
// I case of a merged folder we have to check personal folder's lock.
|
||||
a = [key componentsSeparatedByString: @"/"];
|
||||
pkey = [NSString stringWithFormat: @"%@/personal", [a objectAtIndex:0]];
|
||||
|
||||
if (!([processIdentifierInCache isEqual: processIdentifier] || [[[self globalMetadataForDevice] objectForKey: pkey] isEqual: processIdentifier]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - We lost our lock - discard folder cache update %@ %@ <> %@", key, processIdentifierInCache, processIdentifier];
|
||||
@@ -191,13 +209,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"FolderPermissions"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
[[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[[o properties] addEntriesFromDictionary: values];
|
||||
[o save];
|
||||
@@ -285,8 +308,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
withType: (SOGoMicrosoftActiveSyncFolderType) theFolderType
|
||||
inBuffer: (NSMutableString *) theBuffer
|
||||
{
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *allValues;
|
||||
NSString *clientId, *serverId;
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *uidCache, *allValues;
|
||||
NSString *clientId, *serverId, *easId;
|
||||
NSArray *additions;
|
||||
|
||||
id anAddition, sogoObject, o;
|
||||
@@ -364,23 +387,54 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[sogoObject setIsNew: is_new];
|
||||
[sogoObject saveComponent: o];
|
||||
|
||||
// Everything is fine, lets generate our response
|
||||
[theBuffer appendString: @"<Add>"];
|
||||
[theBuffer appendFormat: @"<ClientId>%@</ClientId>", clientId];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Add>"];
|
||||
|
||||
// Update syncCache
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
dateCache = [folderMetadata objectForKey: @"DateCache"];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
if (uidCache)
|
||||
{
|
||||
if (is_new && [serverId length] > 64)
|
||||
{
|
||||
easId = [theCollection globallyUniqueObjectId];
|
||||
[uidCache setObject: easId forKey: serverId];
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Generated new easId: %@ for serverId: %@", easId, serverId];
|
||||
}
|
||||
else
|
||||
{
|
||||
easId = [uidCache objectForKey: serverId];
|
||||
if (easId)
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Reuse easId: %@ for serverId: %@", easId, serverId];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Use original serverId: %@ %@", serverId, easId];
|
||||
|
||||
easId = serverId;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
easId = serverId;
|
||||
|
||||
[syncCache setObject: [NSString stringWithFormat:@"%f", [[sogoObject lastModified] timeIntervalSince1970]] forKey: serverId];
|
||||
[dateCache setObject: [NSCalendarDate date] forKey: serverId];
|
||||
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
// Everything is fine, lets generate our response
|
||||
[theBuffer appendString: @"<Add>"];
|
||||
[theBuffer appendFormat: @"<ClientId>%@</ClientId>", clientId];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", easId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Add>"];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,10 +481,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
inBuffer: (NSMutableString *) theBuffer
|
||||
{
|
||||
NSDictionary *allChanges;
|
||||
NSString *serverId;
|
||||
NSArray *changes;
|
||||
NSString *serverId, *easId, *origServerId, *mergedFolder;
|
||||
NSArray *changes, *a;
|
||||
id aChange, o, sogoObject;
|
||||
NSMutableDictionary *folderMetadata, *syncCache;
|
||||
NSMutableDictionary *folderMetadata, *syncCache, *uidCache;
|
||||
|
||||
int i;
|
||||
|
||||
@@ -440,14 +494,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
for (i = 0; i < [changes count]; i++)
|
||||
{
|
||||
aChange = [changes objectAtIndex: i];
|
||||
|
||||
serverId = [[(id)[aChange getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
origServerId = [[(id)[aChange getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
easId = origServerId;
|
||||
|
||||
a = [origServerId componentsSeparatedByString: @"{+}"];
|
||||
if ([a count] > 1)
|
||||
{
|
||||
easId = [a objectAtIndex: 1];
|
||||
mergedFolder = [a objectAtIndex: 0];
|
||||
|
||||
// Make sure that the change goes to the target folder and not to personal.
|
||||
if ([[theCollection nameInContainer] isEqualToString: @"personal"])
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Change - Target folder %@, easId %@", mergedFolder, easId];
|
||||
|
||||
[self processSyncChangeCommand: theDocumentElement
|
||||
inCollection: [self collectionFromId: mergedFolder type: theFolderType]
|
||||
withType: theFolderType
|
||||
inBuffer: theBuffer];
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Change - Process change for folder %@ easId %@", [theCollection nameInContainer],easId];
|
||||
|
||||
allChanges = [[(id)[aChange getElementsByTagName: @"ApplicationData"] lastObject] applicationData];
|
||||
|
||||
if (uidCache && (serverId = [[uidCache allKeysForObject: easId] objectAtIndex: 0]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found serverId: %@ for easId: %@", serverId, easId];
|
||||
|
||||
}
|
||||
else
|
||||
serverId = easId;
|
||||
|
||||
// Fetch the object and apply the changes
|
||||
sogoObject = [theCollection lookupName: [serverId sanitizedServerIdWithType: theFolderType]
|
||||
inContext: context
|
||||
@@ -456,7 +546,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// Object was removed inbetween sync/commands?
|
||||
if ([sogoObject isKindOfClass: [NSException class]])
|
||||
{
|
||||
// FIXME - return status == 8
|
||||
[theBuffer appendString: @"<Change>"];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", origServerId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 8];
|
||||
[theBuffer appendString: @"</Change>"];
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -512,7 +605,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
[theBuffer appendString: @"<Change>"];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", origServerId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Change>"];
|
||||
}
|
||||
@@ -551,8 +644,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
|
||||
id aDelete, sogoObject, value;
|
||||
NSArray *deletions;
|
||||
NSString *serverId;
|
||||
NSArray *deletions, *a;
|
||||
NSString *serverId, *easId, *origServerId, *mergedFolder;
|
||||
|
||||
BOOL deletesAsMoves, useTrash;
|
||||
int i;
|
||||
@@ -561,6 +654,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
if ([deletions count])
|
||||
{
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *uidCache;
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
dateCache = [folderMetadata objectForKey: @"DateCache"];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
// From the documention, if DeletesAsMoves is missing, we must assume it's a YES.
|
||||
// See https://msdn.microsoft.com/en-us/library/gg675480(v=exchg.80).aspx for all details.
|
||||
value = [theDocumentElement getElementsByTagName: @"DeletesAsMoves"];
|
||||
@@ -574,8 +674,41 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
aDelete = [deletions objectAtIndex: i];
|
||||
|
||||
serverId = [[(id)[aDelete getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
origServerId = [[(id)[aDelete getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
easId = origServerId;
|
||||
|
||||
a = [origServerId componentsSeparatedByString: @"{+}"];
|
||||
if ([a count] > 1)
|
||||
{
|
||||
easId = [a objectAtIndex: 1];
|
||||
mergedFolder = [a objectAtIndex: 0];
|
||||
|
||||
// Make sure that the delete goes to the target folder and not to personal.
|
||||
if ([[theCollection nameInContainer] isEqualToString: @"personal"])
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Delete - Target folder %@, easId %@", mergedFolder, easId];
|
||||
|
||||
[self processSyncDeleteCommand: theDocumentElement
|
||||
inCollection: [self collectionFromId: mergedFolder type: theFolderType]
|
||||
withType: theFolderType
|
||||
inBuffer: theBuffer];
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Delete - Process delete for folder %@ easId %@", [theCollection nameInContainer],easId];
|
||||
|
||||
if (uidCache && (serverId = [[uidCache allKeysForObject: easId] objectAtIndex: 0]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found serverId: %@ for easId: %@", serverId, easId];
|
||||
}
|
||||
else
|
||||
serverId = easId;
|
||||
|
||||
sogoObject = [theCollection lookupName: [serverId sanitizedServerIdWithType: theFolderType]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
@@ -592,24 +725,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
else
|
||||
[sogoObject delete];
|
||||
}
|
||||
|
||||
[theBuffer appendString: @"<Delete>"];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Delete>"];
|
||||
[syncCache removeObjectForKey: serverId];
|
||||
[dateCache removeObjectForKey: serverId];
|
||||
//[uidCache removeObjectForKey: serverId];
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
// update syncCache
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache;
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
dateCache = [folderMetadata objectForKey: @"DateCache"];
|
||||
|
||||
[syncCache removeObjectForKey: serverId];
|
||||
[dateCache removeObjectForKey: serverId];
|
||||
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
[theBuffer appendString: @"<Delete>"];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", origServerId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Delete>"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -662,8 +788,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
inBuffer: (NSMutableString *) theBuffer
|
||||
lastServerKey: (NSString **) theLastServerKey
|
||||
defaultInterval: (unsigned int) theDefaultInterval
|
||||
mergeFolders: (BOOL) theMergeFolder
|
||||
{
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache;
|
||||
NSMutableDictionary *folderMetadata, *dateCache, *syncCache, *uidCache;
|
||||
NSString *davCollectionTagToStore;
|
||||
NSAutoreleasePool *pool;
|
||||
NSMutableString *s;
|
||||
@@ -681,6 +808,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"SyncCache"];
|
||||
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"DateCache"];
|
||||
if (theFolderType != ActiveSyncMailFolder)
|
||||
{
|
||||
[folderMetadata setObject: [NSCalendarDate date] forKey: @"CleanoutDate"];
|
||||
[folderMetadata setObject: [NSMutableDictionary dictionary] forKey: @"UidCache"];
|
||||
}
|
||||
}
|
||||
else if ([folderMetadata objectForKey: @"SyncKey"] && !([theSyncKey isEqualToString: [folderMetadata objectForKey: @"SyncKey"]]))
|
||||
{
|
||||
@@ -692,6 +824,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
dateCache = [folderMetadata objectForKey: @"DateCache"];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
if (!cleanup_needed && -[[folderMetadata objectForKey: @"CleanoutDate"] timeIntervalSinceNow] > 3600)
|
||||
{
|
||||
NSArray *allKeys;
|
||||
NSString *key;
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Cleanout UidCache of folder %@", [theCollection nameInContainer]];
|
||||
|
||||
allKeys = [uidCache allKeys];
|
||||
for (i = 0; i < [allKeys count]; i++)
|
||||
{
|
||||
key = [allKeys objectAtIndex: i];
|
||||
if (![syncCache objectForKey:key] && ![syncCache objectForKey:key])
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Delete UidCache entry %@", key];
|
||||
|
||||
[uidCache removeObjectForKey: key];
|
||||
}
|
||||
}
|
||||
|
||||
[folderMetadata setObject: [NSCalendarDate date] forKey: @"CleanoutDate"];
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
}
|
||||
|
||||
if ((theFolderType == ActiveSyncMailFolder || theFolderType == ActiveSyncEventFolder || theFolderType == ActiveSyncTaskFolder) &&
|
||||
(cleanup_needed ||
|
||||
@@ -743,6 +901,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Now we are save to remove the dateCache entry.
|
||||
[dateCache removeObjectForKey: key];
|
||||
//[uidCache removeObjectForKey: key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,7 +940,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
case ActiveSyncTaskFolder:
|
||||
{
|
||||
id sogoObject, componentObject;
|
||||
NSString *uid, *component_name;
|
||||
NSString *uid, *easId, *component_name;
|
||||
NSDictionary *component;
|
||||
NSArray *allComponents;
|
||||
|
||||
@@ -860,7 +1019,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[syncCache removeObjectForKey: uid];
|
||||
[dateCache removeObjectForKey: uid];
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Cache cleanup: CHANGE %@", uid];
|
||||
@@ -901,13 +1060,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
|
||||
uid = [[component objectForKey: @"c_name"] sanitizedServerIdWithType: theFolderType];
|
||||
|
||||
if (uidCache)
|
||||
{
|
||||
easId = [uidCache objectForKey: uid];
|
||||
|
||||
if (!easId)
|
||||
{
|
||||
if ([uid length] > 64)
|
||||
{
|
||||
easId = [theCollection globallyUniqueObjectId];
|
||||
[uidCache setObject: easId forKey: uid];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Generated new easId: %@ for serverId: %@", easId, uid];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Use original serverId: %@ %@", uid, easId];
|
||||
|
||||
easId = uid;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Reuse easId: %@ for serverId: %@", easId, uid];
|
||||
}
|
||||
}
|
||||
else
|
||||
easId = uid;
|
||||
|
||||
if (deleted)
|
||||
{
|
||||
if ([syncCache objectForKey: uid])
|
||||
{
|
||||
[s appendString: @"<Delete xmlns=\"AirSync:\">"];
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
|
||||
|
||||
if (![[theCollection nameInContainer] isEqualToString: @"personal"] && theMergeFolder)
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@{+}%@</ServerId>", [theCollection nameInContainer], easId];
|
||||
else
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", easId];
|
||||
|
||||
[s appendString: @"</Delete>"];
|
||||
|
||||
[syncCache removeObjectForKey: uid];
|
||||
@@ -960,7 +1155,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
else
|
||||
[s appendString: @"<Add xmlns=\"AirSync:\">"];
|
||||
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", uid];
|
||||
if (![[theCollection nameInContainer] isEqualToString: @"personal"] && theMergeFolder)
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@{+}%@</ServerId>", [theCollection nameInContainer], easId];
|
||||
else
|
||||
[s appendFormat: @"<ServerId xmlns=\"AirSync:\">%@</ServerId>", easId];
|
||||
|
||||
[s appendString: @"<ApplicationData xmlns=\"AirSync:\">"];
|
||||
|
||||
[s appendString: [componentObject activeSyncRepresentationInContext: context]];
|
||||
@@ -1497,6 +1696,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
folderKey = [self _getNameInCache: collection withType: folderType];
|
||||
folderMetadata = [self _folderMetadataForKey: folderKey];
|
||||
|
||||
if (![folderMetadata count])
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - processSyncCollection: no folderMetadata found: %@", [collection nameInContainer]];
|
||||
|
||||
// We request foldersync to initialize the missing metadata.
|
||||
// We skip root-folders for shared mailboxes (shared and shared/jdoe@example.com).
|
||||
if (![collection isKindOfClass: [SOGoMailNamespace class]])
|
||||
{
|
||||
[theBuffer appendString: @"<Collection>"];
|
||||
[theBuffer appendFormat: @"<SyncKey>%@</SyncKey>", syncKey];
|
||||
[theBuffer appendFormat: @"<CollectionId>%@</CollectionId>", collectionId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 12];
|
||||
[theBuffer appendString: @"</Collection>"];
|
||||
|
||||
*changeDetected = YES;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We check for a window size, default to 100 if not specfied or out of bounds
|
||||
windowSize = [[[(id)[theDocumentElement getElementsByTagName: @"WindowSize"] lastObject] textValue] intValue];
|
||||
|
||||
@@ -1677,11 +1897,215 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
withFilterType: [NSCalendarDate dateFromFilterType: [[(id)[theDocumentElement getElementsByTagName: @"FilterType"] lastObject] textValue]]
|
||||
inBuffer: changeBuffer
|
||||
lastServerKey: &lastServerKey
|
||||
defaultInterval: [[SOGoSystemDefaults sharedSystemDefaults] maximumSyncInterval]];
|
||||
defaultInterval: [[SOGoSystemDefaults sharedSystemDefaults] maximumSyncInterval]
|
||||
mergeFolders: NO];
|
||||
}
|
||||
|
||||
folderMetadata = [self _folderMetadataForKey: folderKey];
|
||||
|
||||
// We only check for changes in other folders if we got nothing back from personal folder and
|
||||
// MergedFolder is set (sogo-tool manage-eas mergeVCard).
|
||||
if (getChanges && !first_sync &&
|
||||
([[collection nameInContainer] isEqualToString: @"personal"]) &&
|
||||
([folderMetadata objectForKey: @"MergedFolder"]))
|
||||
{
|
||||
NSArray *unsortedArray;
|
||||
NSMutableDictionary *mergedFolderMetadata, *mergedFoldersSyncKeys;
|
||||
NSString *mergedFolderSyncKey, *component_name, *mfLastServerKey;
|
||||
id mfCollection;
|
||||
BOOL cacheUpdateNeeded;
|
||||
|
||||
mfLastServerKey = nil;
|
||||
cacheUpdateNeeded=NO;
|
||||
|
||||
if (folderType == ActiveSyncContactFolder)
|
||||
component_name = @"vcard";
|
||||
else if (folderType == ActiveSyncEventFolder)
|
||||
component_name = @"vevent";
|
||||
else
|
||||
component_name = @"vtodo";
|
||||
|
||||
mergedFoldersSyncKeys = [folderMetadata objectForKey: @"MergedFoldersSyncKeys"];
|
||||
|
||||
// Initialize if MergedFoldersSyncKeys doesn't exists.
|
||||
// We user MergedFoldersSyncKeys to store the SyncKey for merged folders:
|
||||
// MergedFoldersSyncKeys = { 1447166580 = {"vcard/34B2-543AB980-D-DB9ECF0" = 1447157519; "vcard/5DE4-5640BC80-3-37E3EE00" = 1447166074; }
|
||||
// 1447166638 = {"vcard/34B2-543AB980-D-DB9ECF0" = 1447157519; "vcard/5DE4-5640BC80-3-37E3EE00" = 1447166074; } }
|
||||
if (!mergedFoldersSyncKeys || [syncKey isEqualToString: @"-1"])
|
||||
{
|
||||
[folderMetadata setObject: [NSMutableDictionary dictionaryWithObject: [NSMutableDictionary dictionary] forKey: syncKey]
|
||||
forKey: @"MergedFoldersSyncKeys"];
|
||||
mergedFoldersSyncKeys = [folderMetadata objectForKey: @"MergedFoldersSyncKeys"];
|
||||
|
||||
cacheUpdateNeeded=YES;
|
||||
}
|
||||
|
||||
// Copy the MergedFoldersSyncKeys entry. Later we update this entry with new SyncKeys if there are changes.
|
||||
if (![syncKey isEqualToString: [folderMetadata objectForKey: @"SyncKey"]])
|
||||
{
|
||||
[mergedFoldersSyncKeys setObject: [mergedFoldersSyncKeys objectForKey: syncKey] forKey: [folderMetadata objectForKey: @"SyncKey"]];
|
||||
cacheUpdateNeeded=YES;
|
||||
}
|
||||
|
||||
// We only keep 5 entries in MergedFoldersSyncKeys.
|
||||
unsortedArray = [mergedFoldersSyncKeys allKeys];
|
||||
if ([unsortedArray count] > 5)
|
||||
[mergedFoldersSyncKeys removeObjectForKey: [[unsortedArray sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:0]];
|
||||
|
||||
// Don't check for changes in other folders if personal folder has changes.
|
||||
if (![changeBuffer length])
|
||||
{
|
||||
NSArray *foldersInCache;
|
||||
SOGoCacheGCSObject *o;
|
||||
NSString *folderName, *realCollectionId;
|
||||
NSArray *a, *folderNames;
|
||||
SOGoMicrosoftActiveSyncFolderType mergedFolderType;
|
||||
|
||||
o = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil];
|
||||
[o setObjectType: ActiveSyncFolderCacheObject];
|
||||
[o setTableUrl: folderTableURL];
|
||||
|
||||
foldersInCache = [o cacheEntriesForDeviceId: [context objectForKey: @"DeviceId"] newerThanVersion: -1];
|
||||
|
||||
// Add folders to MergedFoldersSyncKeys.
|
||||
for (i = 0; i < [foldersInCache count]; i++)
|
||||
{
|
||||
a = [[foldersInCache objectAtIndex: i] componentsSeparatedByString: @"+"];
|
||||
folderName = [a objectAtIndex: 1];
|
||||
|
||||
if (![folderName hasPrefix: component_name] || [folderName hasSuffix: @"/personal"])
|
||||
continue;
|
||||
|
||||
mergedFolderSyncKey = [[mergedFoldersSyncKeys objectForKey: [folderMetadata objectForKey: @"SyncKey"]] objectForKey: folderName ];
|
||||
|
||||
if (!mergedFolderSyncKey)
|
||||
{
|
||||
realCollectionId = [folderName realCollectionIdWithFolderType: &mergedFolderType];
|
||||
mfCollection = [self collectionFromId: realCollectionId type: mergedFolderType];
|
||||
|
||||
// Cache-entry still exists but folder doesn't exists or synchronize flag is not set.
|
||||
// We ignore the folder and wait for foldersync to do the cleanup.
|
||||
if (!(mfCollection && [mfCollection synchronize]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Folder %@ not found. Ignoring ...", folderName];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
mergedFolderMetadata = [self _folderMetadataForKey: folderName];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Add folder %@ for merging into personal folder", folderName];
|
||||
|
||||
// Initialize MergedFoldersSyncKeys entry. e.g. "vcard/34B2-543AB980-D-DB9ECF0" = -1
|
||||
[[mergedFoldersSyncKeys objectForKey: [folderMetadata objectForKey: @"SyncKey"]] setObject: @"-1" forKey: folderName];
|
||||
cacheUpdateNeeded = YES;
|
||||
|
||||
// Flag folder as a merged folder.
|
||||
if (![[mergedFolderMetadata objectForKey: @"MergedFolder"] isEqualToString: @"2"])
|
||||
{
|
||||
[mergedFolderMetadata setObject: @"1" forKey: @"MergedFolder"];
|
||||
[self _setFolderMetadata: mergedFolderMetadata forKey: folderName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check merged folders for changes.
|
||||
folderNames = [[mergedFoldersSyncKeys objectForKey: [folderMetadata objectForKey: @"SyncKey"]] allKeys];
|
||||
for (i = 0; i < [folderNames count]; i++)
|
||||
{
|
||||
folderName = [folderNames objectAtIndex: i];
|
||||
realCollectionId = [folderName realCollectionIdWithFolderType: &mergedFolderType];
|
||||
mfCollection = [self collectionFromId: realCollectionId type: mergedFolderType];
|
||||
|
||||
if (!(mfCollection && [mfCollection synchronize]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Folder %@ not found. Reset peronal folder to cleanup", folderName];
|
||||
|
||||
davCollectionTag = @"0";
|
||||
*changeDetected = YES;
|
||||
status = 3;
|
||||
|
||||
// Reset personal folder - Cleanup metadata of personal folder.
|
||||
[folderMetadata removeObjectForKey: @"SyncKey"];
|
||||
[folderMetadata removeObjectForKey: @"SyncCache"];
|
||||
[folderMetadata removeObjectForKey: @"DateCache"];
|
||||
[folderMetadata removeObjectForKey: @"UidCache"];
|
||||
[folderMetadata removeObjectForKey: @"MoreAvailable"];
|
||||
[folderMetadata removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[self _setFolderMetadata: folderMetadata forKey: folderKey];
|
||||
break;
|
||||
}
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Merging folder %@ into personal folder", folderName];
|
||||
|
||||
mergedFolderSyncKey = [[mergedFoldersSyncKeys objectForKey: [folderMetadata objectForKey: @"SyncKey"]] objectForKey: folderName ];
|
||||
|
||||
[self processSyncGetChanges: theDocumentElement
|
||||
inCollection: mfCollection
|
||||
withWindowSize: windowSize
|
||||
withMaxSyncResponseSize: theMaxSyncResponseSize
|
||||
withSyncKey: mergedFolderSyncKey
|
||||
withFolderType: folderType
|
||||
withFilterType: [NSCalendarDate dateFromFilterType: [[(id)[theDocumentElement getElementsByTagName: @"FilterType"] lastObject] textValue]]
|
||||
inBuffer: changeBuffer
|
||||
lastServerKey: &mfLastServerKey
|
||||
defaultInterval: [[SOGoSystemDefaults sharedSystemDefaults] maximumSyncInterval]
|
||||
mergeFolders: YES];
|
||||
|
||||
mergedFolderMetadata = [self _folderMetadataForKey: folderName];
|
||||
|
||||
if ([changeBuffer length] || [commandsBuffer length])
|
||||
{
|
||||
if (mfLastServerKey)
|
||||
mergedFolderSyncKey = mfLastServerKey;
|
||||
else
|
||||
{
|
||||
mergedFolderSyncKey = [mergedFolderMetadata objectForKey: @"SyncKey"];
|
||||
|
||||
if (!mergedFolderSyncKey)
|
||||
mergedFolderSyncKey = [mfCollection davCollectionTag];
|
||||
}
|
||||
|
||||
*changeDetected = YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make sure that client is updated with the right syncKey. - This keeps vtodo's and vevent's syncKey in sync.
|
||||
syncKeyInCache = [mergedFolderMetadata objectForKey: @"SyncKey"];
|
||||
if (syncKeyInCache && !([mergedFolderSyncKey isEqualToString:syncKeyInCache]) && !first_sync)
|
||||
{
|
||||
mergedFolderSyncKey = syncKeyInCache;
|
||||
*changeDetected = YES;
|
||||
}
|
||||
}
|
||||
|
||||
// Update MergedFoldersSyncKeys with new SyncKey.
|
||||
[[mergedFoldersSyncKeys objectForKey: [folderMetadata objectForKey: @"SyncKey"]] setObject: mergedFolderSyncKey forKey: folderName];
|
||||
|
||||
if (*changeDetected)
|
||||
{
|
||||
// Set MoreAvailable to make sure we come back and check remaining folders.
|
||||
[folderMetadata setObject: [NSNumber numberWithBool: YES] forKey: @"MoreAvailable"];
|
||||
|
||||
break;
|
||||
}
|
||||
else if ([folderMetadata objectForKey: @"MoreAvailable"])
|
||||
{
|
||||
[folderMetadata removeObjectForKey: @"MoreAvailable"];
|
||||
cacheUpdateNeeded = YES;
|
||||
}
|
||||
}
|
||||
} // end if
|
||||
|
||||
if (*changeDetected || cacheUpdateNeeded)
|
||||
[self _setFolderMetadata: folderMetadata forKey: folderKey];
|
||||
}
|
||||
|
||||
// If we got any changes or if we have applied any commands
|
||||
// let's regenerate our SyncKey based on the collection tag.
|
||||
if ([changeBuffer length] || [commandsBuffer length])
|
||||
|
||||
@@ -102,6 +102,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/WORequest+SOGo.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
@@ -119,6 +120,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <Mailer/SOGoMailObject+Draft.h>
|
||||
#import <Mailer/NSString+Mail.h>
|
||||
#import <Mailer/SOGoSentFolder.h>
|
||||
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
@@ -157,6 +159,9 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
- (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey;
|
||||
- (void) _setFolderMetadata: (NSDictionary *) theFolderMetadata forKey: (NSString *) theFolderKey;
|
||||
- (void) _setOrUnsetSyncRequest: (BOOL) set
|
||||
collections: (NSArray *) collections;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -285,8 +290,6 @@ void handle_eas_terminate(int signum)
|
||||
return theIdToTranslate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -823,7 +826,7 @@ void handle_eas_terminate(int signum)
|
||||
[o setObjectType: ActiveSyncFolderCacheObject];
|
||||
[o setTableUrl: folderTableURL];
|
||||
|
||||
foldersInCache = [o cacheEntriesForDeviceId: [context objectForKey: @"DeviceId"] newerThanVersion: -1];
|
||||
foldersInCache = [o cacheEntriesForDeviceId: [context objectForKey: @"DeviceId"] newerThanVersion: -1];
|
||||
|
||||
// get guids of folders stored in cache
|
||||
for (i = 0; i < [foldersInCache count]; i++)
|
||||
@@ -853,7 +856,7 @@ void handle_eas_terminate(int signum)
|
||||
if ([key rangeOfString: @"+folder" options: NSCaseInsensitiveSearch].location != NSNotFound)
|
||||
[cachedGUIDs setObject: [NSString stringWithFormat: @"folder%@", [[o properties] objectForKey: @"displayName"]] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+folderINBOX
|
||||
forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]];
|
||||
else
|
||||
else
|
||||
[cachedGUIDs setObject: [key substringFromIndex: [key rangeOfString: @"+"].location+1] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+vcard/personal
|
||||
forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]];
|
||||
}
|
||||
@@ -896,12 +899,26 @@ void handle_eas_terminate(int signum)
|
||||
if ([cKey rangeOfString: @"/"].location != NSNotFound)
|
||||
currentFolder = [[[[context activeUser] homeFolderInContext: context] lookupName: folderType inContext: context acquire: NO]
|
||||
lookupName: [cKey substringFromIndex: [cKey rangeOfString: @"/"].location+1] inContext: context acquire: NO];
|
||||
else
|
||||
currentFolder = nil;
|
||||
|
||||
// We skip personal GCS folders - we always want to synchronize these
|
||||
if ([currentFolder isKindOfClass: [SOGoGCSFolder class]] &&
|
||||
[[currentFolder nameInContainer] isEqualToString: @"personal"])
|
||||
continue;
|
||||
|
||||
// We remove the folder from device but keep the cache entry,
|
||||
// otherwise the user would see duplication objects, one in personal folder and one in the merged folder.
|
||||
// MergedFolder=1 - Folder need to be removed from device.
|
||||
// MergedFolder=2 - Folder has been removed from device; i.e. <Delete> has been sent already.
|
||||
if ([[[o properties] objectForKey: @"MergedFolder"] isEqualToString: @"1"])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
[[o properties] setObject: @"2" forKey: @"MergedFolder"];
|
||||
[o save];
|
||||
}
|
||||
|
||||
// Remove the folder from device if it doesn't exist, we don't want to sync it, or it doesn't have the proper permissions
|
||||
if (!currentFolder ||
|
||||
![currentFolder synchronize] ||
|
||||
@@ -912,10 +929,16 @@ void handle_eas_terminate(int signum)
|
||||
onObject: currentFolder
|
||||
inContext: context])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
// Don't send a delete when MergedFoler is set, we have done it above.
|
||||
// Windows Phones don't like when a <Delete>-folder is sent twice.
|
||||
if (![[[o properties] objectForKey: @"MergedFolder"] isEqualToString: @"2"])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
}
|
||||
[o destroy];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1004,6 +1027,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1011,6 +1035,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[o save];
|
||||
|
||||
@@ -1069,7 +1096,7 @@ void handle_eas_terminate(int signum)
|
||||
operation = @"Add";
|
||||
else if (![[[o properties ] objectForKey: @"displayName"] isEqualToString: [[folders objectAtIndex:fi] displayName]])
|
||||
operation = @"Update";
|
||||
else
|
||||
else
|
||||
operation = nil;
|
||||
|
||||
if (operation)
|
||||
@@ -1105,6 +1132,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1112,6 +1140,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
}
|
||||
|
||||
[o save];
|
||||
@@ -1132,6 +1163,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1139,6 +1171,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
}
|
||||
|
||||
[o save];
|
||||
@@ -1349,13 +1384,13 @@ void handle_eas_terminate(int signum)
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *fileReference, *realCollectionId, *serverId, *bodyPreferenceType, *mimeSupport, *collectionId;
|
||||
NSMutableString *s;
|
||||
NSArray *fetchRequests;
|
||||
id aFetch;
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
int i;
|
||||
id aFetch;
|
||||
|
||||
SOGoMicrosoftActiveSyncFolderType folderType;
|
||||
int i;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
@@ -1382,6 +1417,20 @@ void handle_eas_terminate(int signum)
|
||||
aFetch = [fetchRequests objectAtIndex: i];
|
||||
fileReference = [[[(id)[aFetch getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL];
|
||||
collectionId = [[(id)[theDocumentElement getElementsByTagName: @"CollectionId"] lastObject] textValue];
|
||||
serverId = nil;
|
||||
|
||||
// We might not have a CollectionId in our request if the ItemOperation (Fetch) is for getting
|
||||
// Search results with a LongId. Apple iOS does that.
|
||||
if (!collectionId)
|
||||
{
|
||||
NSString *longId;
|
||||
NSRange r;
|
||||
|
||||
longId = [[(id)[theDocumentElement getElementsByTagName: @"LongId"] lastObject] textValue];
|
||||
r = [longId rangeOfString: @"+" options: NSBackwardsSearch];
|
||||
collectionId = [longId substringToIndex: r.location];
|
||||
serverId = [longId substringFromIndex: r.location+1];
|
||||
}
|
||||
|
||||
// its either a itemOperation to fetch an attachment or an email
|
||||
if ([fileReference length])
|
||||
@@ -1459,7 +1508,12 @@ void handle_eas_terminate(int signum)
|
||||
{
|
||||
// fetch mail
|
||||
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
|
||||
serverId = [[(id)[theDocumentElement getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
|
||||
// ServerId might have been set if LongId was defined in the initial request. If not, it is
|
||||
// a normal ItemOperations (Fetch) to get a complete email
|
||||
if (!serverId)
|
||||
serverId = [[(id)[theDocumentElement getElementsByTagName: @"ServerId"] lastObject] textValue];
|
||||
|
||||
bodyPreferenceType = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"BodyPreference"] lastObject] getElementsByTagName: @"Type"] lastObject] textValue];
|
||||
[context setObject: bodyPreferenceType forKey: @"BodyPreferenceType"];
|
||||
mimeSupport = [[(id)[theDocumentElement getElementsByTagName: @"MIMESupport"] lastObject] textValue];
|
||||
@@ -1606,10 +1660,11 @@ void handle_eas_terminate(int signum)
|
||||
- (void) processMeetingResponse: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *realCollectionId, *requestId, *participationStatus, *calendarId;
|
||||
NSString *realCollectionId, *requestId, *easRequestId, *participationStatus, *calendarId;
|
||||
SOGoAppointmentObject *appointmentObject;
|
||||
SOGoMailObject *mailObject;
|
||||
NSMutableString *s;
|
||||
NSMutableDictionary *uidCache, *folderMetadata;
|
||||
NSMutableString *s, *nameInCache;
|
||||
NSData *d;
|
||||
|
||||
id collection;
|
||||
@@ -1624,7 +1679,7 @@ void handle_eas_terminate(int signum)
|
||||
realCollectionId = [[[(id)[theDocumentElement getElementsByTagName: @"CollectionId"] lastObject] textValue] realCollectionIdWithFolderType: &folderType];
|
||||
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
|
||||
userResponse = [[[(id)[theDocumentElement getElementsByTagName: @"UserResponse"] lastObject] textValue] intValue];
|
||||
requestId = [[(id)[theDocumentElement getElementsByTagName: @"RequestId"] lastObject] textValue];
|
||||
easRequestId = [[(id)[theDocumentElement getElementsByTagName: @"RequestId"] lastObject] textValue];
|
||||
appointmentObject = nil;
|
||||
calendarId = nil;
|
||||
|
||||
@@ -1643,10 +1698,35 @@ void handle_eas_terminate(int signum)
|
||||
if (folderType == ActiveSyncEventFolder)
|
||||
{
|
||||
collection = [[context activeUser] personalCalendarFolderInContext: context];
|
||||
|
||||
nameInCache = [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]];
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
if (uidCache)
|
||||
{
|
||||
requestId = [[uidCache allKeysForObject: easRequestId] objectAtIndex: 0];
|
||||
|
||||
if (requestId)
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found requestId: %@ for easRequestId: %@", requestId, easRequestId];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Use original requestId: %@", easRequestId];
|
||||
|
||||
requestId = easRequestId;
|
||||
}
|
||||
}
|
||||
else
|
||||
requestId = easRequestId;
|
||||
|
||||
appointmentObject = [collection lookupName: [requestId sanitizedServerIdWithType: ActiveSyncEventFolder]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
calendarId = requestId;
|
||||
calendarId = easRequestId;
|
||||
|
||||
// Object not found, let's fallback on the INBOX folder
|
||||
if ([appointmentObject isKindOfClass: [NSException class]])
|
||||
@@ -1666,7 +1746,7 @@ void handle_eas_terminate(int signum)
|
||||
// We fetch the calendar information based on the email (requestId) in the user's INBOX (or elsewhere)
|
||||
//
|
||||
// FIXME: that won't work too well for external invitations...
|
||||
mailObject = [collection lookupName: requestId
|
||||
mailObject = [collection lookupName: easRequestId
|
||||
inContext: context
|
||||
acquire: 0];
|
||||
|
||||
@@ -1681,6 +1761,12 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
// Fetch the SOGoAppointmentObject
|
||||
collection = [[context activeUser] personalCalendarFolderInContext: context];
|
||||
nameInCache = [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]];
|
||||
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObject: nameInCache]];
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
appointmentObject = [collection lookupName: [NSString stringWithFormat: @"%@.ics", [event uid]]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
@@ -1692,6 +1778,27 @@ void handle_eas_terminate(int signum)
|
||||
inContainer: collection];
|
||||
[appointmentObject saveComponent: event];
|
||||
}
|
||||
|
||||
if (uidCache && [calendarId length] > 64)
|
||||
{
|
||||
calendarId = [uidCache objectForKey: [event uid]];
|
||||
|
||||
if (![calendarId length])
|
||||
{
|
||||
calendarId = [collection globallyUniqueObjectId];
|
||||
[uidCache setObject: calendarId forKey: [event uid]];
|
||||
|
||||
[self _setFolderMetadata: folderMetadata forKey: nameInCache];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Generated new calendarId: %@ for serverId: %@", calendarId, [event uid]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Reuse calendarId: %@ for serverId: %@", calendarId, [event uid]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1715,7 +1822,7 @@ void handle_eas_terminate(int signum)
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<MeetingResponse xmlns=\"MeetingResponse:\">"];
|
||||
[s appendString: @"<Result>"];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", requestId];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", easRequestId];
|
||||
[s appendFormat: @"<CalendarId>%@</CalendarId>", calendarId];
|
||||
[s appendFormat: @"<Status>%d</Status>", status];
|
||||
[s appendString: @"</Result>"];
|
||||
@@ -1731,7 +1838,7 @@ void handle_eas_terminate(int signum)
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<MeetingResponse xmlns=\"MeetingResponse:\">"];
|
||||
[s appendString: @"<Result>"];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", requestId];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", easRequestId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
[s appendString: @"</Result>"];
|
||||
[s appendString: @"</MeetingResponse>"];
|
||||
@@ -1756,8 +1863,8 @@ void handle_eas_terminate(int signum)
|
||||
- (void) processMoveItems: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *nameInCache, *currentFolder;
|
||||
NSMutableDictionary *folderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps;
|
||||
NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *srcNameInCache, *dstNameInCache, *currentSrcFolder, *currentDstFolder;
|
||||
NSMutableDictionary *srcFolderMetadata, *dstFolderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps;
|
||||
SOGoMicrosoftActiveSyncFolderType srcFolderType, dstFolderType;
|
||||
id <DOMElement> aMoveOperation;
|
||||
NSArray *moveOperations;
|
||||
@@ -1766,12 +1873,17 @@ void handle_eas_terminate(int signum)
|
||||
NSData *d;
|
||||
int i;
|
||||
|
||||
currentSrcFolder = nil;
|
||||
currentDstFolder = nil;
|
||||
|
||||
moveOperations = (id)[theDocumentElement getElementsByTagName: @"Move"];
|
||||
|
||||
newSuccessfulMoveItemsOps = [NSMutableDictionary dictionary];
|
||||
prevSuccessfulMoveItemsOps = nil;
|
||||
folderMetadata = nil;
|
||||
currentFolder = nil;
|
||||
srcFolderMetadata = nil;
|
||||
dstFolderMetadata = nil;
|
||||
currentSrcFolder = nil;
|
||||
currentDstFolder = nil;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
@@ -1787,18 +1899,33 @@ void handle_eas_terminate(int signum)
|
||||
srcFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType];
|
||||
dstFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType];
|
||||
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObjects:
|
||||
[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL],
|
||||
[[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL], nil ]];
|
||||
|
||||
if (srcFolderType == ActiveSyncMailFolder)
|
||||
nameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
srcNameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
else
|
||||
nameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
srcNameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
if (![nameInCache isEqualToString: currentFolder])
|
||||
if (![srcNameInCache isEqualToString: currentSrcFolder])
|
||||
{
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
prevSuccessfulMoveItemsOps = [folderMetadata objectForKey: @"SuccessfulMoveItemsOps"];
|
||||
currentFolder = nameInCache;
|
||||
srcFolderMetadata = [self _folderMetadataForKey: srcNameInCache];
|
||||
prevSuccessfulMoveItemsOps = [srcFolderMetadata objectForKey: @"SuccessfulMoveItemsOps"];
|
||||
currentSrcFolder = srcNameInCache;
|
||||
}
|
||||
|
||||
|
||||
if (dstFolderType == ActiveSyncMailFolder)
|
||||
dstNameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
else
|
||||
dstNameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
if (![dstNameInCache isEqualToString: currentDstFolder])
|
||||
{
|
||||
dstFolderMetadata = [self _folderMetadataForKey: dstNameInCache];
|
||||
currentDstFolder = dstNameInCache;
|
||||
}
|
||||
|
||||
[s appendString: @"<Response>"];
|
||||
|
||||
if (srcFolderType == ActiveSyncMailFolder && dstFolderType == ActiveSyncMailFolder)
|
||||
@@ -1903,14 +2030,43 @@ void handle_eas_terminate(int signum)
|
||||
{
|
||||
id srcCollection, dstCollection, srcSogoObject, dstSogoObject;
|
||||
NSArray *elements;
|
||||
NSString *newUID;
|
||||
NSString *newUID, *origSrcMessageId;
|
||||
NSMutableDictionary *srcUidCache, *dstUidCache, *dstSyncCache;
|
||||
NSException *ex;
|
||||
|
||||
unsigned int count, max;
|
||||
|
||||
srcCollection = [self collectionFromId: srcFolderId type: srcFolderType];
|
||||
|
||||
if ([srcCollection isKindOfClass: [NSException class]])
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
dstCollection = [self collectionFromId: dstFolderId type: srcFolderType];
|
||||
|
||||
|
||||
if ([dstCollection isKindOfClass: [NSException class]])
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
continue;
|
||||
}
|
||||
|
||||
origSrcMessageId = srcMessageId;
|
||||
srcUidCache = [srcFolderMetadata objectForKey: @"UidCache"];
|
||||
dstUidCache = [dstFolderMetadata objectForKey: @"UidCache"];
|
||||
dstSyncCache = [dstFolderMetadata objectForKey: @"SyncCache"];
|
||||
|
||||
if (srcUidCache && (srcMessageId = [[srcUidCache allKeysForObject: origSrcMessageId] objectAtIndex: 0]))
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found serverId: %@ for easId: %@", srcMessageId, origSrcMessageId];
|
||||
}
|
||||
else
|
||||
srcMessageId = origSrcMessageId;
|
||||
|
||||
srcSogoObject = [srcCollection lookupName: [srcMessageId sanitizedServerIdWithType: srcFolderType]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
@@ -1918,7 +2074,8 @@ void handle_eas_terminate(int signum)
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
if (![sm validatePermission: SoPerm_DeleteObjects
|
||||
onObject: srcCollection
|
||||
inContext: context])
|
||||
inContext: context] &&
|
||||
![srcSogoObject isKindOfClass: [NSException class]])
|
||||
{
|
||||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: dstCollection
|
||||
@@ -1936,7 +2093,18 @@ void handle_eas_terminate(int signum)
|
||||
if (!ex)
|
||||
{
|
||||
ex = [srcSogoObject delete];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
|
||||
if (dstUidCache)
|
||||
{
|
||||
[dstUidCache setObject: newUID forKey: newUID];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Saved new easId: %@ for serverId: %@", newUID, newUID];
|
||||
}
|
||||
|
||||
[dstSyncCache setObject: [dstFolderMetadata objectForKey: @"SyncKey"] forKey: newUID];
|
||||
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", newUID];
|
||||
[s appendFormat: @"<Status>%d</Status>", 3];
|
||||
|
||||
@@ -1948,36 +2116,45 @@ void handle_eas_terminate(int signum)
|
||||
if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId])
|
||||
{
|
||||
// Move failed but we can recover the dstMessageId from previous request
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] ];
|
||||
[s appendFormat: @"<Status>%d</Status>", 3];
|
||||
[newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId];
|
||||
|
||||
if (dstUidCache)
|
||||
{
|
||||
[dstUidCache setObject: newUID forKey: newUID];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Saved new easId: %@ for serverId: %@", newUID, newUID];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
}
|
||||
}
|
||||
|
||||
[s appendString: @"</Response>"];
|
||||
|
||||
[folderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[folderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"];
|
||||
[self _setFolderMetadata: folderMetadata forKey: nameInCache];
|
||||
[srcFolderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[srcFolderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"];
|
||||
[self _setFolderMetadata: srcFolderMetadata forKey: srcNameInCache];
|
||||
[self _setFolderMetadata: dstFolderMetadata forKey: dstNameInCache];
|
||||
}
|
||||
|
||||
[s appendString: @"</MoveItems>"];
|
||||
@@ -2155,7 +2332,7 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
if (folderType == ActiveSyncMailFolder)
|
||||
folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"folder%@", [[collectionId stringByUnescapingURL] substringFromIndex:5]]];
|
||||
else
|
||||
else
|
||||
folderMetadata = [self _folderMetadataForKey: [collectionId stringByUnescapingURL]];
|
||||
|
||||
collection = [self collectionFromId: realCollectionId type: folderType];
|
||||
@@ -2523,31 +2700,23 @@ void handle_eas_terminate(int signum)
|
||||
// </Store>
|
||||
// </Search>
|
||||
//
|
||||
- (void) processSearch: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
- (void) processSearchGAL: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
SOGoContactSourceFolder *currentFolder;
|
||||
NSArray *allKeys, *allContacts, *mails;
|
||||
NSDictionary *systemSources, *contact;
|
||||
NSString *name, *query, *current_mail;
|
||||
SOGoContactFolders *contactFolders;
|
||||
NSString *current_mail, *query;
|
||||
SOGoUserFolder *userFolder;
|
||||
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
id o;
|
||||
|
||||
int i, j, total;
|
||||
|
||||
name = [[(id)[theDocumentElement getElementsByTagName: @"Name"] lastObject] textValue];
|
||||
|
||||
query = [[(id)[theDocumentElement getElementsByTagName: @"Query"] lastObject] textValue];
|
||||
|
||||
// FIXME: for now, we only search in the GAL
|
||||
if (![name isEqualToString: @"GAL"])
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
userFolder = [[context activeUser] homeFolderInContext: context];
|
||||
contactFolders = [userFolder privateContacts: @"Contacts" inContext: context];
|
||||
@@ -2633,7 +2802,7 @@ void handle_eas_terminate(int signum)
|
||||
}
|
||||
}
|
||||
|
||||
[s appendFormat: @"<Range>0-%d</Range>", total-1];
|
||||
[s appendFormat: @"<Range>0-%d</Range>", (total ? total-1 : 0)];
|
||||
[s appendFormat: @"<Total>%d</Total>", total];
|
||||
[s appendString: @"</Store>"];
|
||||
[s appendString: @"</Response>"];
|
||||
@@ -2644,6 +2813,220 @@ void handle_eas_terminate(int signum)
|
||||
[theResponse setContent: d];
|
||||
}
|
||||
|
||||
- (EOQualifier *) _qualifierFromMailboxSearchQuery: (id <DOMElement>) theDocumentElement
|
||||
{
|
||||
id <DOMElement> andElement, freeTextElement, greaterThanElement;
|
||||
|
||||
andElement = [(id)[theDocumentElement getElementsByTagName: @"And"] lastObject];
|
||||
if (andElement)
|
||||
{
|
||||
EOQualifier *qualifier, *fetchQualifier, *notDeleted, *greaterThanQualifier;
|
||||
NSString *query;
|
||||
id o;
|
||||
|
||||
freeTextElement = [(id)[andElement getElementsByTagName: @"FreeText"] lastObject];
|
||||
query = [(id)freeTextElement textValue];
|
||||
greaterThanQualifier = nil;
|
||||
|
||||
if (!query)
|
||||
return nil;
|
||||
|
||||
// We check for the date ranges - we only support the GreaterThan since
|
||||
// the IMAP protocol is limited in this regard
|
||||
greaterThanElement = [(id)[andElement getElementsByTagName: @"GreaterThan"] lastObject];
|
||||
if (greaterThanElement && [(id)[greaterThanElement getElementsByTagName: @"DateReceived"] lastObject])
|
||||
{
|
||||
o = [[(id)[greaterThanElement getElementsByTagName: @"Value"] lastObject] textValue];
|
||||
greaterThanQualifier = [EOQualifier qualifierWithQualifierFormat:
|
||||
@"(DATE >= %@)", [o calendarDate]];
|
||||
}
|
||||
|
||||
notDeleted = [EOQualifier qualifierWithQualifierFormat: @"(not (flags = %@))", @"deleted"];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: [NSString stringWithFormat: @"(%@ doesContain: '%@')", @"subject", query]];
|
||||
fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers: notDeleted, qualifier, greaterThanQualifier, nil];
|
||||
|
||||
return [fetchQualifier autorelease];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
//
|
||||
// <!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
|
||||
// <Search xmlns="Search:">
|
||||
// <Store>
|
||||
// <Name>Mailbox</Name>
|
||||
// <Query>
|
||||
// <And>
|
||||
// <CollectionId xmlns="AirSync:">mail%2Fsogo_7f53_1c63c93c_1</CollectionId>
|
||||
// <FreeText>aaa;bbb;09/12/2016-09/19/2016;ccc;ddd;</FreeText>
|
||||
// <GreaterThan>
|
||||
// <DateReceived xmlns="Email:"/>
|
||||
// <Value>2015-09-19T04:00:00.000Z</Value>
|
||||
// </GreaterThan>
|
||||
// <LessThan>
|
||||
// <DateReceived xmlns="Email:"/>
|
||||
// <Value>2016-09-19T14:26:00.000Z</Value>
|
||||
// </LessThan>
|
||||
// </And>
|
||||
// </Query>
|
||||
// <Options>
|
||||
// <RebuildResults/>
|
||||
// <Range>0-99</Range>
|
||||
// <BodyPreference xmlns="AirSyncBase:">
|
||||
// <Type>1</Type>
|
||||
// <TruncationSize>51200</TruncationSize>
|
||||
// </BodyPreference>
|
||||
// <MIMESupport xmlns="AirSync:">2</MIMESupport>
|
||||
// <RightsManagementSupport xmlns="RightsManagement:">1</RightsManagementSupport>
|
||||
// </Options>
|
||||
// </Store>
|
||||
// </Search>
|
||||
//
|
||||
- (void) processSearchMailbox: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *folderId, *realCollectionId, *itemId;
|
||||
NSMutableArray *folderIdentifiers;
|
||||
SOGoMailAccounts *accountsFolder;
|
||||
SOGoMailAccount *accountFolder;
|
||||
SOGoMailFolder *currentFolder;
|
||||
SOGoMailObject *mailObject;
|
||||
SOGoUserFolder *userFolder;
|
||||
EOQualifier *qualifier;
|
||||
NSArray *sortedUIDs;
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
|
||||
SOGoMicrosoftActiveSyncFolderType folderType;
|
||||
int i, j, total;
|
||||
|
||||
// We build the qualifier and we launch our search operation
|
||||
qualifier = [self _qualifierFromMailboxSearchQuery: [(id)[theDocumentElement getElementsByTagName: @"Query"] lastObject]];
|
||||
|
||||
if (!qualifier)
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: support more than one CollectionId tag + DeepTraversal
|
||||
folderId = [[(id)[[(id)[theDocumentElement getElementsByTagName: @"Query"] lastObject] getElementsByTagName: @"CollectionId"] lastObject] textValue];
|
||||
folderIdentifiers = [NSMutableArray array];
|
||||
|
||||
// Android 6 will send search requests with no collection ID - so we search in all folders.
|
||||
if (!folderId)
|
||||
{
|
||||
NSArray *foldersInCache;
|
||||
SOGoCacheGCSObject *o;
|
||||
NSString *prefix;
|
||||
|
||||
o = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil];
|
||||
[o setObjectType: ActiveSyncFolderCacheObject];
|
||||
[o setTableUrl: folderTableURL];
|
||||
|
||||
foldersInCache = [o cacheEntriesForDeviceId: [context objectForKey: @"DeviceId"] newerThanVersion: -1];
|
||||
prefix = [NSString stringWithFormat: @"/%@+folder", [context objectForKey: @"DeviceId"]];
|
||||
|
||||
for (i = 0; i < [foldersInCache count]; i++)
|
||||
{
|
||||
folderId = [foldersInCache objectAtIndex: i];
|
||||
if ([folderId hasPrefix: prefix])
|
||||
{
|
||||
folderId = [NSString stringWithFormat: @"mail/%@", [folderId substringFromIndex: [prefix length]]];
|
||||
[folderIdentifiers addObject: folderId];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[folderIdentifiers addObject: folderId];
|
||||
}
|
||||
|
||||
userFolder = [[context activeUser] homeFolderInContext: context];
|
||||
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
|
||||
accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
|
||||
|
||||
// Prepare the response
|
||||
s = [NSMutableString string];
|
||||
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<Search xmlns=\"Search:\">"];
|
||||
[s appendFormat: @"<Status>1</Status>"];
|
||||
[s appendFormat: @"<Response>"];
|
||||
[s appendFormat: @"<Store>"];
|
||||
[s appendFormat: @"<Status>1</Status>"];
|
||||
|
||||
for (i = 0; i < [folderIdentifiers count]; i++)
|
||||
{
|
||||
folderId = [folderIdentifiers objectAtIndex: i];
|
||||
realCollectionId = [folderId realCollectionIdWithFolderType: &folderType];
|
||||
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
|
||||
|
||||
currentFolder = [accountFolder lookupName: [NSString stringWithFormat: @"folder%@", realCollectionId]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
|
||||
sortedUIDs = [currentFolder fetchUIDsMatchingQualifier: qualifier
|
||||
sortOrdering: @"REVERSE ARRIVAL"
|
||||
threaded: NO];
|
||||
total = [sortedUIDs count];
|
||||
for (j = 0; j < total; j++)
|
||||
{
|
||||
itemId = [[sortedUIDs objectAtIndex: j] stringValue];
|
||||
mailObject = [currentFolder lookupName: itemId inContext: context acquire: NO];
|
||||
|
||||
if ([mailObject isKindOfClass: [NSException class]])
|
||||
continue;
|
||||
|
||||
[s appendString: @"<Result xmlns=\"Search:\">"];
|
||||
[s appendFormat: @"<LongId>%@+%@</LongId>", folderId, itemId];
|
||||
[s appendFormat: @"<CollectionId xmlns=\"AirSyncBase:\">%@</CollectionId>", folderId];
|
||||
[s appendString: @"<Properties>"];
|
||||
[s appendFormat: [mailObject activeSyncRepresentationInContext: context]];
|
||||
[s appendString: @"</Properties>"];
|
||||
[s appendFormat: @"</Result>"];
|
||||
}
|
||||
}
|
||||
|
||||
[s appendFormat: @"<Range>0-%d</Range>",(total ? total-1 : 0)];
|
||||
[s appendFormat: @"<Total>%d</Total>", total];
|
||||
[s appendString: @"</Store>"];
|
||||
[s appendString: @"</Response>"];
|
||||
[s appendString: @"</Search>"];
|
||||
|
||||
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
|
||||
|
||||
[theResponse setContent: d];
|
||||
}
|
||||
|
||||
//
|
||||
// We support EAS Search on the GAL and Mailbox.
|
||||
//
|
||||
// We do NOT support it on the DocumentLibrary.
|
||||
//
|
||||
- (void) processSearch: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *name;
|
||||
|
||||
name = [[(id)[theDocumentElement getElementsByTagName: @"Name"] lastObject] textValue];
|
||||
|
||||
if ([name isEqualToString: @"GAL"])
|
||||
{
|
||||
return [self processSearchGAL: theDocumentElement
|
||||
inResponse: theResponse];
|
||||
}
|
||||
else if ([name isEqualToString: @"Mailbox"])
|
||||
{
|
||||
return [self processSearchMailbox: theDocumentElement
|
||||
inResponse: theResponse];
|
||||
}
|
||||
|
||||
[theResponse setStatus: 500];
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -2851,8 +3234,28 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
if (error)
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
[theResponse appendContentString: @"FATAL ERROR occured during SendMail"];
|
||||
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.0)
|
||||
{
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<SendMail xmlns=\"ComposeMail:\">"];
|
||||
[s appendString: @"<Status>120</Status>"];
|
||||
[s appendString: @"</SendMail>"];
|
||||
|
||||
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
|
||||
|
||||
[theResponse setContent: d];
|
||||
}
|
||||
else
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
[theResponse appendContentString: @"FATAL ERROR occured during SendMail"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3209,7 +3612,7 @@ void handle_eas_terminate(int signum)
|
||||
textPart = apart;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if ([[[part contentType] type] isEqualToString: @"text"] && [[[part contentType] subType] isEqualToString: @"html"])
|
||||
htmlPart = part;
|
||||
@@ -3242,7 +3645,7 @@ void handle_eas_terminate(int signum)
|
||||
charset = [[htmlPart contentType] valueOfParameter: @"charset"];
|
||||
isHTML = YES;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
bodyFromSmartForward = [textPart body];
|
||||
charset = [[textPart contentType] valueOfParameter: @"charset"];
|
||||
@@ -3359,8 +3762,28 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
if (error)
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
[theResponse appendContentString: @"FATAL ERROR occured during SmartForward"];
|
||||
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 14.0)
|
||||
{
|
||||
NSMutableString *s;
|
||||
NSData *d;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendFormat: @"<%@ xmlns=\"ComposeMail:\">", (isSmartForward) ? @"SmartForward" : @"SmartReply"];
|
||||
[s appendString: @"<Status>120</Status>"];
|
||||
[s appendFormat: @"</%@>", (isSmartForward) ? @"SmartForward" : @"SmartReply"];
|
||||
|
||||
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
|
||||
|
||||
[theResponse setContent: d];
|
||||
}
|
||||
else
|
||||
{
|
||||
[theResponse setStatus: 500];
|
||||
[theResponse appendContentString: @"FATAL ERROR occured during SmartForward"];
|
||||
}
|
||||
}
|
||||
else if (!isSmartForward)
|
||||
{
|
||||
@@ -3559,7 +3982,7 @@ void handle_eas_terminate(int signum)
|
||||
if (([cmdName rangeOfString: @"ItemOperations" options: NSCaseInsensitiveSearch].location != NSNotFound) &&
|
||||
([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"] || [[theRequest uri] acceptsMultiPart]))
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.multipart" forKey: @"Content-Type"];
|
||||
else
|
||||
else
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
|
||||
|
||||
[self performSelector: aSelector withObject: documentElement withObject: theResponse];
|
||||
@@ -3568,7 +3991,7 @@ void handle_eas_terminate(int signum)
|
||||
[theResponse setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
|
||||
[theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
|
||||
|
||||
if (debugOn && [[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.wbxml"] && [[theResponse content] length])
|
||||
if (debugOn && [[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.wbxml"] && [[theResponse content] length] && !([(WOResponse *)theResponse status] == 500))
|
||||
[self logWithFormat: @"EAS - response for device %@: %@", [context objectForKey: @"DeviceId"], [[[NSString alloc] initWithData: [[theResponse content] wbxml2xml] encoding: NSUTF8StringEncoding] autorelease]];
|
||||
|
||||
RELEASE(context);
|
||||
|
||||
@@ -70,7 +70,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
- (int) _attendeeStatus: (iCalPerson *) attendee
|
||||
{
|
||||
int attendee_status;
|
||||
|
||||
|
||||
attendee_status = 5;
|
||||
if ([[attendee partStat] caseInsensitiveCompare: @"ACCEPTED"] == NSOrderedSame)
|
||||
attendee_status = 3;
|
||||
@@ -82,6 +82,29 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
return attendee_status;
|
||||
}
|
||||
|
||||
//
|
||||
// Possible values are:
|
||||
// 0 Free
|
||||
// 1 Tentative
|
||||
// 2 Busy
|
||||
// 3 Out of Office
|
||||
// 4 Working elsewhere
|
||||
//
|
||||
- (int) _busyStatus: (iCalPerson *) attendee
|
||||
{
|
||||
int attendee_status;
|
||||
|
||||
attendee_status = 2;
|
||||
|
||||
if ([[attendee partStat] caseInsensitiveCompare: @"DECLINED"] == NSOrderedSame)
|
||||
attendee_status = 0;
|
||||
else if ([[attendee partStat] caseInsensitiveCompare: @"TENTATIVE"] == NSOrderedSame)
|
||||
attendee_status = 1;
|
||||
|
||||
return attendee_status;
|
||||
}
|
||||
|
||||
|
||||
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context
|
||||
{
|
||||
NSMutableString *s;
|
||||
@@ -190,7 +213,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
else
|
||||
{
|
||||
meetingStatus = 0; // appointment
|
||||
meetingStatus = 0; // The event is an appointment, which has no attendees.
|
||||
}
|
||||
|
||||
// This depends on the 'NEEDS-ACTION' parameter.
|
||||
@@ -211,6 +234,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[s appendFormat: @"<DisallowNewTimeProposal xmlns=\"Calendar:\">%d</DisallowNewTimeProposal>", 1];
|
||||
|
||||
// BusyStatus -- http://msdn.microsoft.com/en-us/library/ee202290(v=exchg.80).aspx
|
||||
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", [self _busyStatus: attendee]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's a normal event (ie, with no organizer/attendee) or we are the organizer to an event
|
||||
// invitation, we set the busy status to 2 (Busy)
|
||||
[s appendFormat: @"<BusyStatus xmlns=\"Calendar:\">%d</BusyStatus>", 2];
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
}
|
||||
else
|
||||
type = 5;
|
||||
{
|
||||
type = 5;
|
||||
[s appendFormat: @"<Recurrence_DayOfMonth xmlns=\"Calendar:\">%d</Recurrence_DayOfMonth>",
|
||||
(int)[[[self parent] startDate] dayOfMonth]];
|
||||
[s appendFormat: @"<Recurrence_MonthOfYear xmlns=\"Calendar:\">%d</Recurrence_MonthOfYear>",
|
||||
(int)[[[self parent] startDate] monthOfYear]];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[s appendFormat: @"<Recurrence_Type xmlns=\"Calendar:\">%d</Recurrence_Type>", type];
|
||||
|
||||
@@ -1,3 +1,723 @@
|
||||
commit 6b322e6b75f08d7e3302f71917dffda632d4b82d
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Sep 28 10:37:14 2016 -0400
|
||||
|
||||
Fix Serbian translation
|
||||
|
||||
A SoObjects/Appointments/Serbian.lproj/Localizable.strings
|
||||
A SoObjects/Contacts/Serbian.lproj/Localizable.strings
|
||||
A SoObjects/Mailer/SOGoMailSerbianForward.wo/SOGoMailSerbianForward.html
|
||||
A SoObjects/Mailer/SOGoMailSerbianForward.wo/SOGoMailSerbianForward.wod
|
||||
A SoObjects/Mailer/SOGoMailSerbianReply.wo/SOGoMailSerbianReply.html
|
||||
A SoObjects/Mailer/SOGoMailSerbianReply.wo/SOGoMailSerbianReply.wod
|
||||
A SoObjects/Mailer/Serbian.lproj/Localizable.strings
|
||||
A UI/AdministrationUI/Serbian.lproj/Localizable.strings
|
||||
A UI/Common/Serbian.lproj/Localizable.strings
|
||||
A UI/Contacts/Serbian.lproj/Localizable.strings
|
||||
A UI/MailPartViewers/Serbian.lproj/Localizable.strings
|
||||
A UI/MailerUI/Serbian.lproj/Localizable.strings
|
||||
A UI/MainUI/Serbian.lproj/Locale
|
||||
A UI/MainUI/Serbian.lproj/Localizable.strings
|
||||
A UI/PreferencesUI/Serbian.lproj/Localizable.strings
|
||||
A UI/Scheduler/Serbian.lproj/Localizable.strings
|
||||
A UI/Templates/SOGoACLSerbianAdditionAdvisory.wox
|
||||
A UI/Templates/SOGoACLSerbianModificationAdvisory.wox
|
||||
A UI/Templates/SOGoACLSerbianRemovalAdvisory.wox
|
||||
A UI/Templates/SOGoFolderSerbianAdditionAdvisory.wox
|
||||
A UI/Templates/SOGoFolderSerbianRemovalAdvisory.wox
|
||||
|
||||
commit 29d004c4a4e71750671f0fa8515f3e6dfeecfecf
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Sep 28 10:02:25 2016 -0400
|
||||
|
||||
Add Serbian translation and update translations
|
||||
|
||||
M .tx/config
|
||||
M NEWS
|
||||
M SoObjects/Appointments/TurkishTurkey.lproj/Localizable.strings
|
||||
M SoObjects/Mailer/GNUmakefile
|
||||
M SoObjects/Mailer/SOGoMailForward.h
|
||||
M SoObjects/Mailer/SOGoMailForward.m
|
||||
M SoObjects/Mailer/SOGoMailReply.h
|
||||
M SoObjects/Mailer/SOGoMailReply.m
|
||||
M SoObjects/SOGo/SOGoDefaults.plist
|
||||
M Tests/Integration/preferences.py
|
||||
M UI/AdministrationUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/Common/English.lproj/Localizable.strings
|
||||
M UI/Common/French.lproj/Localizable.strings
|
||||
M UI/Common/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/Contacts/English.lproj/Localizable.strings
|
||||
M UI/Contacts/French.lproj/Localizable.strings
|
||||
M UI/Contacts/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/MailPartViewers/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MailerUI/English.lproj/Localizable.strings
|
||||
M UI/MailerUI/French.lproj/Localizable.strings
|
||||
M UI/MailerUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/MainUI/Arabic.lproj/Localizable.strings
|
||||
M UI/MainUI/Basque.lproj/Localizable.strings
|
||||
M UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MainUI/Catalan.lproj/Localizable.strings
|
||||
M UI/MainUI/ChineseTaiwan.lproj/Localizable.strings
|
||||
M UI/MainUI/Croatian.lproj/Localizable.strings
|
||||
M UI/MainUI/Czech.lproj/Localizable.strings
|
||||
M UI/MainUI/Danish.lproj/Localizable.strings
|
||||
M UI/MainUI/Dutch.lproj/Localizable.strings
|
||||
M UI/MainUI/English.lproj/Localizable.strings
|
||||
M UI/MainUI/Finnish.lproj/Localizable.strings
|
||||
M UI/MainUI/French.lproj/Localizable.strings
|
||||
M UI/MainUI/German.lproj/Localizable.strings
|
||||
M UI/MainUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MainUI/Icelandic.lproj/Localizable.strings
|
||||
M UI/MainUI/Italian.lproj/Localizable.strings
|
||||
M UI/MainUI/Lithuanian.lproj/Localizable.strings
|
||||
M UI/MainUI/Macedonian.lproj/Localizable.strings
|
||||
M UI/MainUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/MainUI/NorwegianNynorsk.lproj/Localizable.strings
|
||||
M UI/MainUI/Polish.lproj/Localizable.strings
|
||||
M UI/MainUI/Portuguese.lproj/Localizable.strings
|
||||
M UI/MainUI/Russian.lproj/Localizable.strings
|
||||
M UI/MainUI/Slovak.lproj/Localizable.strings
|
||||
M UI/MainUI/Slovenian.lproj/Localizable.strings
|
||||
M UI/MainUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/MainUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/MainUI/Swedish.lproj/Localizable.strings
|
||||
M UI/MainUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/MainUI/Ukrainian.lproj/Localizable.strings
|
||||
M UI/MainUI/Welsh.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Arabic.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Basque.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Catalan.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/ChineseTaiwan.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Croatian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Czech.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Dutch.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/English.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Finnish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/French.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/German.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Icelandic.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Italian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Lithuanian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Macedonian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/NorwegianBokmal.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/NorwegianNynorsk.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Polish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Portuguese.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Russian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Slovak.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Slovenian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/SpanishArgentina.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/SpanishSpain.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Swedish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Ukrainian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Welsh.lproj/Localizable.strings
|
||||
M UI/Scheduler/English.lproj/Localizable.strings
|
||||
M UI/Scheduler/French.lproj/Localizable.strings
|
||||
M UI/Scheduler/TurkishTurkey.lproj/Localizable.strings
|
||||
M configure
|
||||
|
||||
commit 1a8b82d75d8776e50355d878310d7178fa2ee140
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Sep 28 09:34:22 2016 -0400
|
||||
|
||||
Update NEWS file
|
||||
|
||||
M NEWS
|
||||
|
||||
commit ca87ac05a25f53b78bc0f955ae5c6cd256933032
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Sep 28 09:24:26 2016 -0400
|
||||
|
||||
Update CKEditor to version 4.5.11
|
||||
|
||||
M NEWS
|
||||
M UI/WebServerResources/ckeditor/build-config.js
|
||||
M UI/WebServerResources/ckeditor/ckeditor.js
|
||||
M UI/WebServerResources/ckeditor/lang/ar.js
|
||||
M UI/WebServerResources/ckeditor/lang/ca.js
|
||||
M UI/WebServerResources/ckeditor/lang/cs.js
|
||||
M UI/WebServerResources/ckeditor/lang/cy.js
|
||||
M UI/WebServerResources/ckeditor/lang/da.js
|
||||
M UI/WebServerResources/ckeditor/lang/de.js
|
||||
M UI/WebServerResources/ckeditor/lang/en.js
|
||||
M UI/WebServerResources/ckeditor/lang/es.js
|
||||
M UI/WebServerResources/ckeditor/lang/eu.js
|
||||
M UI/WebServerResources/ckeditor/lang/fi.js
|
||||
M UI/WebServerResources/ckeditor/lang/fr.js
|
||||
M UI/WebServerResources/ckeditor/lang/hr.js
|
||||
M UI/WebServerResources/ckeditor/lang/hu.js
|
||||
M UI/WebServerResources/ckeditor/lang/is.js
|
||||
M UI/WebServerResources/ckeditor/lang/it.js
|
||||
M UI/WebServerResources/ckeditor/lang/lt.js
|
||||
M UI/WebServerResources/ckeditor/lang/mk.js
|
||||
M UI/WebServerResources/ckeditor/lang/nb.js
|
||||
M UI/WebServerResources/ckeditor/lang/nl.js
|
||||
M UI/WebServerResources/ckeditor/lang/no.js
|
||||
M UI/WebServerResources/ckeditor/lang/pl.js
|
||||
M UI/WebServerResources/ckeditor/lang/pt-br.js
|
||||
M UI/WebServerResources/ckeditor/lang/pt.js
|
||||
M UI/WebServerResources/ckeditor/lang/ru.js
|
||||
M UI/WebServerResources/ckeditor/lang/sk.js
|
||||
M UI/WebServerResources/ckeditor/lang/sl.js
|
||||
A UI/WebServerResources/ckeditor/lang/sr.js
|
||||
M UI/WebServerResources/ckeditor/lang/sv.js
|
||||
M UI/WebServerResources/ckeditor/lang/tr.js
|
||||
M UI/WebServerResources/ckeditor/lang/uk.js
|
||||
M UI/WebServerResources/ckeditor/lang/zh-cn.js
|
||||
M UI/WebServerResources/ckeditor/lang/zh.js
|
||||
M UI/WebServerResources/ckeditor/plugins/about/dialogs/about.js
|
||||
M UI/WebServerResources/ckeditor/plugins/link/dialogs/link.js
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_gecko.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie7.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie8.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_iequirks.css
|
||||
|
||||
commit 0c33bc58b664c4de4e1dfffecfddb7eadc529dc9
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 28 08:56:00 2016 -0400
|
||||
|
||||
Removed old file
|
||||
|
||||
D ChangeLog.skyrix
|
||||
|
||||
commit 6319007631b0181a816fe60bffb6f02f8388f7a4
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 27 19:51:39 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 156a83046b6a1dbe3c013bb4b5a90d4738f6ba31
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 27 19:49:58 2016 -0400
|
||||
|
||||
(fix) make sure new cards always have a UID (fixes #3819)
|
||||
|
||||
M SoObjects/Contacts/SOGoContactGCSEntry.m
|
||||
|
||||
commit 84e170a601f4c6b4ac8cc96c8a621acfa36d6c56
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 27 13:43:21 2016 -0400
|
||||
|
||||
(fix) correctly set percent-complete for tasks from the list view (fixes #3197)
|
||||
|
||||
M NEWS
|
||||
M UI/Scheduler/UIxTaskEditor.m
|
||||
|
||||
commit 5ada0024afbfbcb0af8e6f37356acb6c7a6ba411
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Sep 26 16:22:44 2016 -0400
|
||||
|
||||
Caching expiration of ACLs assigned to LDAP groups
|
||||
|
||||
Fixes #2867
|
||||
|
||||
M NEWS
|
||||
M SoObjects/SOGo/SOGoGCSFolder.m
|
||||
|
||||
commit 7daa6728a16f50c4271eca82f672710284ceead6
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 26 15:25:07 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 1cbced4965575671288719f41d421ba8f289ef08
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Sep 26 15:22:49 2016 -0400
|
||||
|
||||
(fix) search in all domain sources for Apple Calendar and properly handle groups
|
||||
|
||||
M Main/SOGo+DAV.m
|
||||
M SoObjects/Appointments/SOGoAppointmentFolders.m
|
||||
M SoObjects/Appointments/SOGoCalendarProxy.h
|
||||
M SoObjects/Appointments/SOGoCalendarProxy.m
|
||||
M SoObjects/Appointments/SOGoUser+Appointments.h
|
||||
M SoObjects/Appointments/SOGoUser+Appointments.m
|
||||
M SoObjects/SOGo/SOGoGCSFolder.m
|
||||
M SoObjects/SOGo/SOGoUserFolder.h
|
||||
M SoObjects/SOGo/SOGoUserFolder.m
|
||||
|
||||
commit 323bc50f10f3649b06b11b61feef467f86f1375d
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 23 11:30:34 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 8c81d5506121132d79398f04de649594542060c3
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Sep 23 11:28:15 2016 -0400
|
||||
|
||||
(fix) handle 120 EAS status code when message submission fails (fixes #3774)
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit 36fb9c138e4b1947dd071d2d35d6e58dd61e06ac
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Sep 22 14:22:44 2016 -0400
|
||||
|
||||
(fix) added global search for Android 6
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit 81aee49555c2d24217afd4c64429a2f2ad35bc2f
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Sep 22 12:57:01 2016 -0400
|
||||
|
||||
(fix) avoid generating invalid response if mail isn't found
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit ed4c2b3dca8a8d5031a2e14081314911e56eac4a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Sep 22 12:54:37 2016 -0400
|
||||
|
||||
(fix) fixed EAS search for iOS devices
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit 677df619fdd271b960c73829c4a57e7bc01db21a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Sep 22 11:42:28 2016 -0400
|
||||
|
||||
(fix) compiler fixes + first round of iOS fixes
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit 40cd481ec071d3ec897efe13e8f484d66d1b7e51
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 21 09:22:26 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit cfcc4922acc28bb3b421874ba1ee6fd3d06dc44a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 21 09:20:37 2016 -0400
|
||||
|
||||
(feat) initial EAS support for server-side mailbox search operations
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
|
||||
commit 1cf85475d71c3c1b54858eb8734a9f51c1c55bc3
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 14 09:27:29 2016 -0400
|
||||
|
||||
Updates for the release
|
||||
|
||||
M ChangeLog
|
||||
M Documentation/docinfo.xml
|
||||
M Documentation/includes/global-attributes.asciidoc
|
||||
M NEWS
|
||||
M Version
|
||||
|
||||
commit 83ce0f01b4a5519def236a3121ef0222c7ad72cc
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 14 09:20:45 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit d1dcb820bd76c2aed3f78a4c6f62264e2809450c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Sep 14 09:19:30 2016 -0400
|
||||
|
||||
(fix) EAS yearly rrule generation + small EAS MoveItems fix
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
M ActiveSync/iCalRecurrenceRule+ActiveSync.m
|
||||
|
||||
commit e098b3d050bebc2d338c56cae39b499e88fd6ac9
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 13 11:06:32 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 18f7bc7e69b8c7d2b86b946e45ef6b94233fde27
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Sep 13 11:02:26 2016 -0400
|
||||
|
||||
(fix) handle binary just like 7 and 8bit
|
||||
|
||||
M SoObjects/Mailer/SOGoMailBodyPart.m
|
||||
|
||||
commit 1a1afb7b95c5df19808f1ec03248dcd96db2d2dc
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Aug 29 16:13:33 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 44f7fdc50a1514c3106c1fe86794f38a3e9dbb20
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Aug 29 15:01:47 2016 -0400
|
||||
|
||||
(fix) make sure to escape email and all address fields
|
||||
|
||||
M ActiveSync/NGVCard+ActiveSync.m
|
||||
|
||||
commit 3de6e0fc5aeb95f34cd5a7d941fe430703420927
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Mon Aug 29 14:36:04 2016 -0400
|
||||
|
||||
Until date of repeat must end after first event
|
||||
|
||||
M NEWS
|
||||
M UI/Scheduler/English.lproj/Localizable.strings
|
||||
M UI/Scheduler/UIxAppointmentEditor.m
|
||||
|
||||
commit 928b18890c22a45462409e87780f55cca4a8e87c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Aug 19 14:13:21 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 828fed54a0983cc92c91026dcf5269ff0de30b0c
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Aug 19 14:11:53 2016 -0400
|
||||
|
||||
(fix) properly generate the BusyStatus for normal events
|
||||
|
||||
M ActiveSync/iCalEvent+ActiveSync.m
|
||||
|
||||
commit 1b88d17e015bfd7d8ee6e4a84c11bb06b2a43cb9
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Aug 19 11:45:15 2016 -0400
|
||||
|
||||
(fix) allow multiple space-delimited addresses in the MailFieldNames column
|
||||
|
||||
M SoObjects/SOGo/SQLSource.m
|
||||
|
||||
commit 3d54bfb882cb060eff1db631e3f891d923d8869d
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 18 15:41:39 2016 -0400
|
||||
|
||||
(doc) updated regarding previous commit
|
||||
|
||||
M Documentation/SOGoInstallationGuide.asciidoc
|
||||
|
||||
commit 96914b39fb547b2bc6b7af860b87575d4ddfae59
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 18 15:38:33 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit ec11b8abb4ba33b7e5965bddc549168f81d6be1a
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 18 15:34:13 2016 -0400
|
||||
|
||||
(fix) strip protocol value from proxyAddresses (fixes #3182)
|
||||
|
||||
M SoObjects/SOGo/LDAPSource.m
|
||||
|
||||
commit 2fbe6e84290ac586c5a712132a47a7f61b3ed4b9
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Aug 17 08:18:50 2016 -0400
|
||||
|
||||
Version bump to 2.3.14
|
||||
|
||||
M ChangeLog
|
||||
M Documentation/docinfo.xml
|
||||
M Documentation/includes/global-attributes.asciidoc
|
||||
M NEWS
|
||||
M Version
|
||||
|
||||
commit ac6b60c4c98b2f2f3f9f2a5138d5fc6c709d6223
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Aug 12 14:31:28 2016 -0400
|
||||
|
||||
(js,css) Style cancelled events in Calendar module
|
||||
|
||||
Fixes #2800
|
||||
|
||||
M NEWS
|
||||
M UI/WebServerResources/SchedulerUI.css
|
||||
M UI/WebServerResources/SchedulerUI.js
|
||||
|
||||
commit 76eeef2541d02be9704a662108c4ccbee03e91bd
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Aug 12 11:14:30 2016 -0400
|
||||
|
||||
(i18n) Update translations
|
||||
|
||||
M UI/Common/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/Contacts/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/Contacts/English.lproj/Localizable.strings
|
||||
M UI/Contacts/Hungarian.lproj/Localizable.strings
|
||||
M UI/MailerUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MailerUI/English.lproj/Localizable.strings
|
||||
M UI/MailerUI/Finnish.lproj/Localizable.strings
|
||||
M UI/MailerUI/French.lproj/Localizable.strings
|
||||
M UI/MailerUI/German.lproj/Localizable.strings
|
||||
M UI/MailerUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Italian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Macedonian.lproj/Localizable.strings
|
||||
M UI/MailerUI/Polish.lproj/Localizable.strings
|
||||
M UI/MailerUI/Russian.lproj/Localizable.strings
|
||||
M UI/MailerUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/MainUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/MainUI/English.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/BrazilianPortuguese.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Finnish.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Hungarian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/Macedonian.lproj/Localizable.strings
|
||||
M UI/PreferencesUI/TurkishTurkey.lproj/Localizable.strings
|
||||
M UI/Scheduler/BrazilianPortuguese.lproj/Localizable.strings
|
||||
|
||||
commit 086b90521505367814923718bdaaa421901dc846
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Fri Aug 12 10:47:13 2016 -0400
|
||||
|
||||
Update CKEditor to version 4.5.10
|
||||
|
||||
M NEWS
|
||||
M UI/WebServerResources/ckeditor/build-config.js
|
||||
M UI/WebServerResources/ckeditor/ckeditor.js
|
||||
M UI/WebServerResources/ckeditor/config.js
|
||||
M UI/WebServerResources/ckeditor/lang/ar.js
|
||||
M UI/WebServerResources/ckeditor/lang/ca.js
|
||||
M UI/WebServerResources/ckeditor/lang/cs.js
|
||||
M UI/WebServerResources/ckeditor/lang/cy.js
|
||||
M UI/WebServerResources/ckeditor/lang/da.js
|
||||
M UI/WebServerResources/ckeditor/lang/de.js
|
||||
M UI/WebServerResources/ckeditor/lang/en.js
|
||||
M UI/WebServerResources/ckeditor/lang/es.js
|
||||
M UI/WebServerResources/ckeditor/lang/eu.js
|
||||
M UI/WebServerResources/ckeditor/lang/fi.js
|
||||
M UI/WebServerResources/ckeditor/lang/fr.js
|
||||
M UI/WebServerResources/ckeditor/lang/hr.js
|
||||
M UI/WebServerResources/ckeditor/lang/hu.js
|
||||
M UI/WebServerResources/ckeditor/lang/is.js
|
||||
M UI/WebServerResources/ckeditor/lang/it.js
|
||||
M UI/WebServerResources/ckeditor/lang/lt.js
|
||||
M UI/WebServerResources/ckeditor/lang/mk.js
|
||||
M UI/WebServerResources/ckeditor/lang/nb.js
|
||||
M UI/WebServerResources/ckeditor/lang/nl.js
|
||||
M UI/WebServerResources/ckeditor/lang/no.js
|
||||
M UI/WebServerResources/ckeditor/lang/pl.js
|
||||
M UI/WebServerResources/ckeditor/lang/pt-br.js
|
||||
M UI/WebServerResources/ckeditor/lang/pt.js
|
||||
M UI/WebServerResources/ckeditor/lang/ru.js
|
||||
M UI/WebServerResources/ckeditor/lang/sk.js
|
||||
M UI/WebServerResources/ckeditor/lang/sl.js
|
||||
M UI/WebServerResources/ckeditor/lang/sv.js
|
||||
M UI/WebServerResources/ckeditor/lang/tr.js
|
||||
M UI/WebServerResources/ckeditor/lang/uk.js
|
||||
M UI/WebServerResources/ckeditor/lang/zh-cn.js
|
||||
M UI/WebServerResources/ckeditor/lang/zh.js
|
||||
M UI/WebServerResources/ckeditor/plugins/icons.png
|
||||
M UI/WebServerResources/ckeditor/plugins/icons_hidpi.png
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_gecko.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie7.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_ie8.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/editor_iequirks.css
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/icons.png
|
||||
M UI/WebServerResources/ckeditor/skins/minimalist/icons_hidpi.png
|
||||
|
||||
commit 713e0d5ecb819044894d202d5b4e765f19d7d70d
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Aug 10 10:09:21 2016 -0400
|
||||
|
||||
(fix) also purge repetitive events that have an old end date
|
||||
|
||||
M Tools/SOGoToolTruncateCalendar.m
|
||||
|
||||
commit 58732e316b3d5b3a2f7f6b4c4657231bd33cf95e
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Wed Aug 10 09:47:49 2016 -0400
|
||||
|
||||
(fix) minor improvement to SQL query
|
||||
|
||||
M Tools/SOGoToolTruncateCalendar.m
|
||||
|
||||
commit 9199d42e51b3edb002c43a50e2c7ca18f348f8fe
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Aug 9 16:22:09 2016 -0400
|
||||
|
||||
Minor improvement over previous commit
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit 8c217103f8854fd060c75949bdabe89c1a61b587
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Aug 9 16:20:59 2016 -0400
|
||||
|
||||
Updated NEWS
|
||||
|
||||
M NEWS
|
||||
|
||||
commit ab5fd9fef1a4f64a0941f29b12da8e5f6ca54107
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Aug 9 16:17:17 2016 -0400
|
||||
|
||||
(fix) check if the SENT-BY has access to organizer's calendar before modifying attendees' calendar (fixes #3759)
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit 165d866cfc8aeef9cad5e3e35c634815123b8271
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Aug 5 15:01:21 2016 -0400
|
||||
|
||||
(fix) correctly calculate recurrence exceptions when not overlapping the recurrence id
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
|
||||
commit 8ba6c6d9f59c277d0477db0552f5c37981c14a6d
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Fri Aug 5 08:43:41 2016 -0400
|
||||
|
||||
(fix) updated tests for 403 -> 409
|
||||
|
||||
M Tests/Integration/test-caldav-scheduling.py
|
||||
|
||||
commit 960962f92f18f69d2460f6bc9b6f7152976ccd69
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 4 14:12:09 2016 -0400
|
||||
|
||||
Fixed typo
|
||||
|
||||
M NEWS
|
||||
|
||||
commit cbb23bd536de594a0281ff14b3a70e4ab4862d47
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 4 14:11:35 2016 -0400
|
||||
|
||||
Updated changelog
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 196e36acb222fed93106fa3b340d670fa6357836
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 4 14:09:11 2016 -0400
|
||||
|
||||
(fix) change 403 to 409 error codes so Lightning doesn't silently fails
|
||||
|
||||
M SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
|
||||
commit 6c05576e533e74279e4ce397fb35f13daeb62575
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 4 12:51:30 2016 -0400
|
||||
|
||||
Updated NEWS file
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 9449b0df27204afe1071f5df66c99e4e65b0e7af
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Aug 4 11:28:57 2016 -0400
|
||||
|
||||
(fix) handle domain-less-login case with multi-domain on during backups
|
||||
|
||||
M Tools/SOGoToolBackup.m
|
||||
|
||||
commit 9ecee32d08507741e9a4aec13f0d9337f85314ea
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Tue Feb 9 15:46:52 2016 -0500
|
||||
|
||||
(fix) delete mailbox from the Trash folder
|
||||
|
||||
Fixes #595, #1189, #641
|
||||
|
||||
M NEWS
|
||||
M UI/MailerUI/UIxMailFolderActions.m
|
||||
|
||||
commit 199c9d92373e91abc09f9dad6603f5e0e9bde93d
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Jul 27 14:01:22 2016 -0400
|
||||
|
||||
(js) Improve extraction of HTML signature
|
||||
|
||||
M NEWS
|
||||
M UI/WebServerResources/UIxPreferences.js
|
||||
|
||||
commit d95b90281b8d42246186d6a112cbfad9d7c5a119
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Jul 27 12:02:00 2016 -0400
|
||||
|
||||
Expunge drafts mailbox when a draft is sent
|
||||
|
||||
M NEWS
|
||||
M SoObjects/Mailer/SOGoDraftObject.m
|
||||
|
||||
commit 8545f89b2ff6b0a3398d0f292dd4cf6a982576cd
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Mon Jul 25 06:17:17 2016 -0400
|
||||
|
||||
Correctly get the collection/key IDs (fixes #3775)
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
|
||||
|
||||
commit c827b62f7fd1bcf4368d2ad98af9c2bc1decb150
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Jul 21 14:13:47 2016 -0400
|
||||
|
||||
Updated NEWS file
|
||||
|
||||
M NEWS
|
||||
|
||||
commit 16356aaf3677d809f3843a4a9f6cbd337fe264bc
|
||||
Author: Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
Date: Thu Jul 21 14:06:11 2016 -0400
|
||||
|
||||
Added EAS folder merge support and fixed long GUID issue (fixes #3460)
|
||||
|
||||
Conflicts:
|
||||
|
||||
ActiveSync/SOGoActiveSyncDispatcher+Sync.m
|
||||
|
||||
M ActiveSync/SOGoActiveSyncDispatcher+Sync.m
|
||||
M ActiveSync/SOGoActiveSyncDispatcher.m
|
||||
M Tools/SOGoToolManageEAS.m
|
||||
|
||||
commit 4c4d3e4c25cbf00149547add84a1d5444bafbf38
|
||||
Author: ethoms <euan@potensol.com>
|
||||
Date: Wed Jul 13 02:47:54 2016 +0800
|
||||
|
||||
Convert configure script shebang back to /bin/sh for cross-platform compatability (#215)
|
||||
|
||||
M configure
|
||||
|
||||
commit f638113d53195df8b567b53b19a251f90072d8e2
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Jul 6 15:35:09 2016 -0400
|
||||
|
||||
Improve handling of mail delegates
|
||||
|
||||
M SoObjects/Mailer/SOGoMailAccount.m
|
||||
M SoObjects/SOGo/SOGoUserManager.m
|
||||
M UI/MailerUI/UIxMailUserDelegationEditor.m
|
||||
|
||||
commit 09bda83bc835f985d23c782599ac830be82c7c67
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Jul 6 07:23:37 2016 -0400
|
||||
|
||||
Update ChangeLog
|
||||
|
||||
M ChangeLog
|
||||
|
||||
commit 04bba82d2e13592275e75b977cb970db60df82bb
|
||||
Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
Date: Wed Jul 6 07:20:45 2016 -0400
|
||||
|
||||
-5655
File diff suppressed because it is too large.
Load diff
@@ -907,7 +907,8 @@ table.
|
||||
|
||||
|MailFieldNames
|
||||
|An array of fields that returns the user's email addresses (defaults to
|
||||
`mail` when unset).
|
||||
`mail` when unset). Note that SOGo will always automatically strip the
|
||||
protocol value from the attribute if the attribute name is `proxyAddresses`.
|
||||
|
||||
|SearchFieldNames
|
||||
|An array of fields to to match against the search string when filtering
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- TODO have the build system take care of this -->
|
||||
<releaseinfo>Version 2.3.13 - July 2016</releaseinfo>
|
||||
<subtitle>for version 2.3.13</subtitle>
|
||||
<date>2016-07-06</date>
|
||||
<releaseinfo>Version 2.3.16 - September 2016</releaseinfo>
|
||||
<subtitle>for version 2.3.16</subtitle>
|
||||
<date>2016-09-28</date>
|
||||
|
||||
<legalnotice>
|
||||
<para>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".</para>
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
|
||||
// TODO have the build system take care of this
|
||||
|
||||
:release_version: 2.3.13
|
||||
:release_version: 2.3.16
|
||||
|
||||
// vim: set syntax=asciidoc tabstop=2 shiftwidth=2 expandtab:
|
||||
+14
-19
@@ -42,6 +42,7 @@
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserFolder.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
||||
#import "SOGo+DAV.h"
|
||||
|
||||
@@ -365,31 +366,26 @@
|
||||
withEmailAddressSetMatching: (NSString *) value
|
||||
inContext: (WOContext *) localContext
|
||||
{
|
||||
id <SOGoSource> authenticationSource;
|
||||
SOGoUser *activeUser;
|
||||
SOGoUserManager *um;
|
||||
NSArray *records;
|
||||
NSUInteger count, max;
|
||||
NSString *uid;
|
||||
SOGoUserFolder *collection;
|
||||
|
||||
activeUser = [localContext activeUser];
|
||||
if ([activeUser respondsToSelector: @selector (authenticationSource)])
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
records = [um fetchUsersMatching: value
|
||||
inDomain: [[localContext activeUser] domain]];
|
||||
|
||||
max = [records count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
authenticationSource = [[localContext activeUser] authenticationSource];
|
||||
records = [authenticationSource
|
||||
fetchContactsMatching: value
|
||||
inDomain: [activeUser domain]];
|
||||
max = [records count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
uid = [[records objectAtIndex: count] objectForKey: @"c_uid"];
|
||||
if ([uid length] > 0)
|
||||
{
|
||||
collection = [[SOGoUser userWithLogin: uid]
|
||||
uid = [[records objectAtIndex: count] objectForKey: @"c_uid"];
|
||||
if ([uid length] > 0)
|
||||
{
|
||||
collection = [[SOGoUser userWithLogin: uid]
|
||||
homeFolderInContext: localContext];
|
||||
[collections addObject: collection];
|
||||
}
|
||||
}
|
||||
[collections addObject: collection];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,7 +581,6 @@
|
||||
@"addressbook", @"calendar-access",
|
||||
@"calendar-schedule", @"calendar-auto-schedule",
|
||||
@"calendar-proxy",
|
||||
|
||||
@"calendar-query-extended",
|
||||
@"extended-mkcol",
|
||||
@"calendarserver-principal-property-search",
|
||||
|
||||
@@ -1,3 +1,54 @@
|
||||
2.3.16 (2016-09-28)
|
||||
-------------------
|
||||
|
||||
New features
|
||||
- [eas] initial support for server-side mailbox search operations
|
||||
|
||||
Enhancements
|
||||
- [eas] propagate message submission errors to EAS clients (#3774)
|
||||
- [web] updated CKEditor to version 4.5.11
|
||||
- [web] added Serbian (sr) translation - thanks to Bogdanović Bojan
|
||||
|
||||
Bug fixes
|
||||
- [web] correctly set percent-complete for tasks from the list view (#3197)
|
||||
- [core] fixed caching expiration of ACLs assigned to LDAP groups (#2867)
|
||||
- [core] we now search in all domain sources for Apple Calendar
|
||||
- [core] properly handle groups in Apple Calendar's delegation
|
||||
- [core] make sure new cards always have a UID (#3819)
|
||||
|
||||
2.3.15 (2016-09-14)
|
||||
------------------
|
||||
|
||||
Enhancements
|
||||
- [web] don't allow a recurrence rule to end before the first occurrence
|
||||
|
||||
Bug fixes
|
||||
- [eas] properly generate the BusyStatus for normal events
|
||||
- [eas] properly escape all email and address fields
|
||||
- [eas] properly generate yearly rrule
|
||||
- [core] strip protocol value from proxyAddresses attribute (#3182)
|
||||
- [web] handle binary content transfer encoding when displaying mails
|
||||
|
||||
2.3.14 (2016-08-17)
|
||||
-------------------
|
||||
|
||||
New features
|
||||
- [eas] added folder merging capabilities
|
||||
|
||||
Enhancements
|
||||
- [web] expunge drafts mailbox when a draft is sent and deleted
|
||||
- [web] style cancelled events in Calendar module (#2800)
|
||||
- [web] updated CKEditor to version 4.5.10
|
||||
|
||||
Bug fixes
|
||||
- [eas] fixed long GUID issue preventing sometimes synchronisation (#3460)
|
||||
- [web] improved extraction of HTML signature in Preferences module
|
||||
- [web] really delete mailboxes being deleted from the Trash folder (#595, #1189, #641)
|
||||
- [core] fixing sogo-tool backup with multi-domain configuration but domain-less logins
|
||||
- [core] during event scheduling, use 409 instead of 403 so Lightning doesn't fail silently
|
||||
- [core] correctly calculate recurrence exceptions when not overlapping the recurrence id
|
||||
- [core] prevent invalid SENT-BY handling during event invitations (#3759)
|
||||
|
||||
2.3.13 (2016-07-06)
|
||||
-------------------
|
||||
|
||||
|
||||
@@ -979,12 +979,16 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
withTimeZone: (NSTimeZone *) tz
|
||||
toArray: (NSMutableArray *) ma
|
||||
{
|
||||
NGCalendarDateRange *recurrenceIdRange;
|
||||
NSCalendarDate *recurrenceId;
|
||||
NSMutableDictionary *newRecord;
|
||||
NGCalendarDateRange *newRecordRange;
|
||||
NSComparisonResult compare;
|
||||
int recordIndex, secondsOffsetFromGMT;
|
||||
NSNumber *dateSecs;
|
||||
id master;
|
||||
|
||||
int recordIndex, secondsOffsetFromGMT;
|
||||
NSTimeInterval delta;
|
||||
|
||||
newRecord = nil;
|
||||
recurrenceId = [component recurrenceId];
|
||||
@@ -1006,17 +1010,20 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
[recurrenceId setTimeZone: tz];
|
||||
}
|
||||
|
||||
compare = [[dateRange startDate] compare: recurrenceId];
|
||||
if ((compare == NSOrderedAscending || compare == NSOrderedSame) &&
|
||||
[[dateRange endDate] compare: recurrenceId] == NSOrderedDescending)
|
||||
master = [[[component parent] events] objectAtIndex: 0];
|
||||
delta = [[master endDate] timeIntervalSinceDate: [master startDate]];
|
||||
recurrenceIdRange = [NGCalendarDateRange calendarDateRangeWithStartDate: recurrenceId
|
||||
endDate: [recurrenceId dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds: delta]];
|
||||
if ([dateRange doesIntersectWithDateRange: recurrenceIdRange])
|
||||
{
|
||||
// The recurrence exception intersects with the date range;
|
||||
// find the occurence and replace it with the new record
|
||||
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId inArray: ma];
|
||||
if (recordIndex > -1)
|
||||
{
|
||||
if ([dateRange containsDate: [component startDate]])
|
||||
{
|
||||
if ([dateRange containsDate: [component startDate]] ||
|
||||
[dateRange containsDate: [component endDate]])
|
||||
{
|
||||
// We must pass nil to :container here in order to avoid re-entrancy issues.
|
||||
newRecord = [self _fixupRecord: [component quickRecordFromContent: nil container: nil]];
|
||||
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/* SOGoAppointmentFolders.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
* Copyright (C) 2007-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -740,9 +740,14 @@ static SoSecurityManager *sm = nil;
|
||||
aclUser = [aclUsers objectAtIndex: userCount];
|
||||
if (![subscribers containsObject: aclUser])
|
||||
{
|
||||
currentUser = [SOGoUser userWithLogin: aclUser];
|
||||
if ([currentUser hasSubscribedToCalendar: currentFolder])
|
||||
[subscribers addObject: aclUser];
|
||||
if ([aclUser hasPrefix: @"@"])
|
||||
[subscribers addObject: aclUser];
|
||||
else
|
||||
{
|
||||
currentUser = [SOGoUser userWithLogin: aclUser];
|
||||
if ([currentUser hasSubscribedToCalendar: currentFolder])
|
||||
[subscribers addObject: aclUser];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
}
|
||||
|
||||
- (SOGoAppointmentObject *) _lookupEvent: (NSString *) eventUID
|
||||
forUID: (NSString *) uid
|
||||
forUID: (NSString *) uid
|
||||
{
|
||||
SOGoAppointmentFolder *folder;
|
||||
SOGoAppointmentObject *object;
|
||||
@@ -569,7 +569,7 @@
|
||||
[user cn], @"Cn",
|
||||
[user systemEmail], @"SystemEmail"], nil;
|
||||
reason = [values keysWithFormat: [self labelForKey: @"Cannot access resource: \"%{Cn} %{SystemEmail}\""]];
|
||||
return [NSException exceptionWithHTTPStatus:403 reason: reason];
|
||||
return [NSException exceptionWithHTTPStatus:409 reason: reason];
|
||||
}
|
||||
|
||||
fbInfo = [NSMutableArray arrayWithArray: [folder fetchFreeBusyInfosFrom: start
|
||||
@@ -676,7 +676,7 @@
|
||||
|
||||
reason = [values keysWithFormat: [self labelForKey: @"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}."]];
|
||||
|
||||
return [NSException exceptionWithHTTPStatus: 403
|
||||
return [NSException exceptionWithHTTPStatus: 409
|
||||
reason: reason];
|
||||
}
|
||||
}
|
||||
@@ -1469,14 +1469,14 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
if (delegatedUid)
|
||||
delegatedUser = [SOGoUser userWithLogin: delegatedUid];
|
||||
if (delegatedUser != nil && [event userIsOrganizer: delegatedUser])
|
||||
ex = [NSException exceptionWithHTTPStatus: 403
|
||||
ex = [NSException exceptionWithHTTPStatus: 409
|
||||
reason: @"delegate is organizer"];
|
||||
if ([event isAttendee: [[delegate email] rfc822Email]])
|
||||
ex = [NSException exceptionWithHTTPStatus: 403
|
||||
ex = [NSException exceptionWithHTTPStatus: 409
|
||||
reason: @"delegate is a participant"];
|
||||
else if ([SOGoGroup groupWithEmail: [[delegate email] rfc822Email]
|
||||
inDomain: [ownerUser domain]])
|
||||
ex = [NSException exceptionWithHTTPStatus: 403
|
||||
ex = [NSException exceptionWithHTTPStatus: 409
|
||||
reason: @"delegate is a group"];
|
||||
}
|
||||
if (ex == nil)
|
||||
@@ -1962,7 +1962,7 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
// TODO: send out a no-uid-conflict (DAV:href) xml element (rfc4791 section 5.3.2.1)
|
||||
if ([container resourceNameForEventUID: eventUID])
|
||||
{
|
||||
return [NSException exceptionWithHTTPStatus: 403
|
||||
return [NSException exceptionWithHTTPStatus: 409
|
||||
reason: [NSString stringWithFormat: @"Event UID already in use. (%@)", eventUID]];
|
||||
}
|
||||
|
||||
@@ -2122,6 +2122,26 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
|
||||
if (userIsOrganizer)
|
||||
{
|
||||
// We check ACLs of the 'organizer' - in case someone forges the SENT-BY
|
||||
NSString *uid;
|
||||
|
||||
uid = [[oldEvent organizer] uidInContext: context];
|
||||
|
||||
if (uid && [[[context activeUser] login] caseInsensitiveCompare: uid] != NSOrderedSame)
|
||||
{
|
||||
SOGoAppointmentObject *organizerObject;
|
||||
|
||||
organizerObject = [self _lookupEvent: [oldEvent uid] forUID: uid];
|
||||
roles = [[context activeUser] rolesForObject: organizerObject
|
||||
inContext: context];
|
||||
|
||||
if (![roles containsObject: @"ComponentModifier"])
|
||||
{
|
||||
return [NSException exceptionWithHTTPStatus: 409
|
||||
reason: @"Not allowed to perform this action. Wrong SENT-BY being used regarding access rights on organizer's calendar."];
|
||||
}
|
||||
}
|
||||
|
||||
// A RECCURENCE-ID was removed
|
||||
if (!newEvent && oldEvent)
|
||||
[self prepareDeleteOccurence: oldEvent];
|
||||
@@ -2170,9 +2190,9 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
}
|
||||
|
||||
// We first check of the sequences are alright. We don't accept attendees
|
||||
// accepting "old" invitations. If that's the case, we return a 403
|
||||
// accepting "old" invitations. If that's the case, we return a 409
|
||||
if ([[newEvent sequence] intValue] < [[oldEvent sequence] intValue])
|
||||
return [NSException exceptionWithHTTPStatus: 403
|
||||
return [NSException exceptionWithHTTPStatus: 409
|
||||
reason: @"sequences don't match"];
|
||||
|
||||
// Remove the RSVP attribute, as an action from the attendee
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoCalendarProxy.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2009-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoCalendarProxy.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2009-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoUser+Appointments.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2010-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/* SOGoUser+Appointments.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
* Copyright (C) 2010-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
"Inviting the following persons is prohibited:" = "Забрањено да је позовете следеће особе:";
|
||||
"Personal Calendar" = "Лични календар";
|
||||
vevent_class0 = "(Јавни догађај)";
|
||||
vevent_class1 = "(Приватни догађај)";
|
||||
vevent_class2 = "(Поверљиви догађај)";
|
||||
|
||||
vtodo_class0 = "(Јавни задатак)";
|
||||
vtodo_class1 = "(Приватни задатак)";
|
||||
vtodo_class2 = "(Поверљиви задатак)";
|
||||
/* Receipts */
|
||||
"The event \"%{Summary}\" was created" = "Догађај \"%{Summary}\" је креиран";
|
||||
"The event \"%{Summary}\" was deleted" = "Догађај \"%{Summary}\" је обрисан";
|
||||
"The event \"%{Summary}\" was updated" = "Догађај \"%{Summary}\" је ажуриран";
|
||||
"The following attendees(s) were notified" = "Следећи полазник(ци) су обавештени";
|
||||
"The following attendees(s) were added" = "Следећи полазник(ци) су додати";
|
||||
"The following attendees(s) were removed" = "Следећи полазник(ци) су уклоњени";
|
||||
/* IMIP messages */
|
||||
"calendar_label" = "Календар";
|
||||
"startDate_label" = "Почетак";
|
||||
"endDate_label" = "Завршетак";
|
||||
"due_label" = "Рок";
|
||||
"location_label" = "Локација";
|
||||
"summary_label" = "Резиме";
|
||||
"comment_label" = "Коментар";
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Позивница за догађај: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(послао %{SentBy}) ";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}вас је позвао на %{Summary}.\n\nПочетак: %{StartDate}\nЗавршетак: %{EndDate}\nОпис: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}вас је позвао на %{Summary}.\n\nПочетак: %{StartDate} у %{StartTime}\nЗавршетак: %{EndDate} у %{EndTime}\nОпис: %{Description}";
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Отказан је догађај: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}је отказао догађај: %{Summary}.\n\nПочетак: %{StartDate}\nЗавршетак: %{EndDate}\nОпис: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}је отказао догађај: %{Summary}.\n\nПочетак: %{StartDate} у %{StartTime}\nЗавршетак: %{EndDate} у %{EndTime}\nОпис: %{Description}";
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "Заказани састанак \"%{Summary}\" %{OldStartDate} је измењен";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "Заказани састанак \"%{Summary}\" %{OldStartDate} у %{OldStartTime} је измењен";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "Следећи параметри су имењени за састанак \"%{Summary}\":";
|
||||
"Please accept or decline those changes."
|
||||
= "Молимо да прихватите или откажете ове измене.";
|
||||
/* Reply */
|
||||
"Accepted invitation: \"%{Summary}\"" = "Прихваћена позивница: \"%{Summary}\"";
|
||||
"Declined invitation: \"%{Summary}\"" = "Одбијена позивница: \"%{Summary}\"";
|
||||
"Delegated invitation: \"%{Summary}\"" = "Делегирана позивница: \"%{Summary}\"";
|
||||
"Not yet decided on invitation: \"%{Summary}\"" = "Нисам још одлучио за позивницу: \"%{Summary}\"";
|
||||
"%{Attendee} %{SentByText}has accepted your event invitation."
|
||||
= "%{Attendee} %{SentByText}је прихватио вашу позивницу за догађај.";
|
||||
"%{Attendee} %{SentByText}has declined your event invitation."
|
||||
= "%{Attendee} %{SentByText}је одбио вашу позивницу за догађај.";
|
||||
"%{Attendee} %{SentByText}has delegated the invitation to %{Delegate}."
|
||||
= "%{Attendee} %{SentByText}је делегирао позивницу %{Delegate}.";
|
||||
"%{Attendee} %{SentByText}has not yet decided upon your event invitation."
|
||||
= "%{Attendee} %{SentByText}није још одлучио у вези са вашом позивницом за догађај.";
|
||||
/* Resources */
|
||||
"Cannot access resource: \"%{Cn} %{SystemEmail}\"" = "Не могу приступити ресурсу: \"%{Cn} %{SystemEmail}\"";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Максимални број истовремених резервација (%{NumberOfSimultaneousBookings}) достигнут је за ресурс \"%{Cn} %{SystemEmail}\". Конфликтни догађај је \"%{EventTitle}\", и почиње %{StartDate}.";
|
||||
@@ -18,26 +18,26 @@ vtodo_class2 = "(Gizli görev)";
|
||||
"calendar_label" = "Takvim";
|
||||
"startDate_label" = "Başlangıç";
|
||||
"endDate_label" = "Bitiş";
|
||||
"due_label" = "Son Tarihi";
|
||||
"due_label" = "Son Tarih";
|
||||
"location_label" = "Konum";
|
||||
"summary_label" = "Özet";
|
||||
"comment_label" = "Açıklama";
|
||||
/* Invitation */
|
||||
"Event Invitation: \"%{Summary}\"" = "Etkinlik Daveti: \"%{Summary}\"";
|
||||
"(sent by %{SentBy}) " = "(%{SentBy} tarafından gönderilidi) ";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}sizi %{Summary} etkinliğine davet etti.\n\n\nBaşlangıç: %{StartDate}\n\nBitiş: %{EndDate}\n\nTanım: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}sizi %{Summary} etkinliğine davet etti.\n\n\nBaşlangıç: %{StartDate} saat %{StartTime}\n\nBitiş: %{EndDate} saat %{EndTime}\n\nTanım: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}sizi %{Summary} etkinliğine davet etti.\n\nBaşlangıç: %{StartDate}\nBitiş: %{EndDate}\nTanım: %{Description}";
|
||||
"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}sizi %{Summary} etkinliğine davet etti.\n\nBaşlangıç: %{StartDate} saat %{StartTime}\nBitiş: %{EndDate} saat %{EndTime}\nTanım: %{Description}";
|
||||
/* Deletion */
|
||||
"Event Cancelled: \"%{Summary}\"" = "Etkinlik İptal Edildi: \"%{Summary}\"";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}şu etkiliği iptal etti: %{Summary}.\n\n\nBaşlangıç: %{StartDate}\n\nBitiş: %{EndDate}\n\nTanım: %{Description}";
|
||||
= "%{Organizer} %{SentByText}şu etkiliği iptal etti: %{Summary}.\n\nBaşlangıç: %{StartDate}\nBitiş: %{EndDate}\nTanım: %{Description}";
|
||||
"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"
|
||||
= "%{Organizer} %{SentByText}şu etkinliği iptal etti: %{Summary}.\n\n\nBaşlangıç: %{StartDate} saat %{StartTime}\n\nBitiş: %{EndDate} saat %{EndTime}\n\nTanım: %{Description}";
|
||||
= "%{Organizer} %{SentByText}şu etkinliği iptal etti: %{Summary}.\n\nBaşlangıç: %{StartDate} saat %{StartTime}\nBitiş: %{EndDate} saat %{EndTime}\nTanım: %{Description}";
|
||||
/* Update */
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} has changed"
|
||||
= "%{OldStartDate} tarihli \"%{Summary}\" buluşması değişti.";
|
||||
= "%{OldStartDate} tarihli \"%{Summary}\" randevu değişti.";
|
||||
"The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"
|
||||
= "%{OldStartDate} tarihli ve %{OldStartTime} saatli \"%{Summary}\" buluşması değişti";
|
||||
= "%{OldStartDate} tarihli ve %{OldStartTime} saatli \"%{Summary}\" randevu değişti";
|
||||
"The following parameters have changed in the \"%{Summary}\" meeting:"
|
||||
= "\"%{Summary}\" buluşmasının şu özellikleri değişti:";
|
||||
"Please accept or decline those changes."
|
||||
|
||||
@@ -187,6 +187,10 @@
|
||||
{
|
||||
NSException *ex;
|
||||
|
||||
// We make sure new cards always have a UID - see #3819
|
||||
if (![[newCard uid] length])
|
||||
[newCard setUid: [self globallyUniqueObjectId]];
|
||||
|
||||
ex = [super saveComponent: newCard baseVersion: newVersion];
|
||||
[card release];
|
||||
card = nil;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
"Personal Address Book" = "Лични адресар";
|
||||
"Collected Address Book" = "Прикупљени адресар";
|
||||
@@ -88,7 +88,9 @@ Mailer_RESOURCE_FILES += \
|
||||
SOGoMailPortugueseForward.wo \
|
||||
SOGoMailPortugueseReply.wo \
|
||||
SOGoMailRussianForward.wo \
|
||||
SOGoMailSerbianForward.wo \
|
||||
SOGoMailRussianReply.wo \
|
||||
SOGoMailSerbianReply.wo \
|
||||
SOGoMailSlovakForward.wo \
|
||||
SOGoMailSlovakReply.wo \
|
||||
SOGoMailSlovenianForward.wo \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2007-2014 Inverse inc.
|
||||
Copyright (C) 2007-2016 Inverse inc.
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo.
|
||||
@@ -15,7 +15,7 @@
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
License along with SOGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
*/
|
||||
@@ -73,6 +73,7 @@
|
||||
|
||||
#import "NSData+Mail.h"
|
||||
#import "NSString+Mail.h"
|
||||
#import "SOGoDraftsFolder.h"
|
||||
#import "SOGoMailAccount.h"
|
||||
#import "SOGoMailFolder.h"
|
||||
#import "SOGoMailObject.h"
|
||||
@@ -1979,8 +1980,16 @@ static NSString *userAgent = nil;
|
||||
}
|
||||
}
|
||||
|
||||
if (!error && ![dd mailKeepDraftsAfterSend])
|
||||
[self delete];
|
||||
// Expunge Drafts mailbox if
|
||||
// - message was sent and saved to Sent mailbox if necessary;
|
||||
// - SOGoMailKeepDraftsAfterSend is not set;
|
||||
// - draft is successfully deleted;
|
||||
// - drafts mailbox exists.
|
||||
if (!error &&
|
||||
![dd mailKeepDraftsAfterSend] &&
|
||||
![self delete] &&
|
||||
[imap4 doesMailboxExistAtURL: [container imap4URL]])
|
||||
[(SOGoDraftsFolder *) container expunge];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -1022,7 +1022,7 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
max = [newDelegates count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentDelegate = [newDelegates objectAtIndex: 0];
|
||||
currentDelegate = [newDelegates objectAtIndex: count];
|
||||
delegateUser = [SOGoUser userWithLogin: currentDelegate];
|
||||
if (delegateUser)
|
||||
{
|
||||
@@ -1049,7 +1049,7 @@ static NSString *inboxFolderName = @"INBOX";
|
||||
max = [oldDelegates count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentDelegate = [oldDelegates objectAtIndex: 0];
|
||||
currentDelegate = [oldDelegates objectAtIndex: count];
|
||||
delegateUser = [SOGoUser userWithLogin: currentDelegate];
|
||||
if (delegateUser)
|
||||
{
|
||||
|
||||
@@ -278,7 +278,8 @@ static BOOL debugOn = NO;
|
||||
else if ([enc isEqualToString: @"quoted-printable"])
|
||||
data = [data dataByDecodingQuotedPrintableTransferEncoding];
|
||||
else if ([enc isEqualToString: @"7bit"]
|
||||
|| [enc isEqualToString: @"8bit"])
|
||||
|| [enc isEqualToString: @"8bit"]
|
||||
|| [enc isEqualToString: @"binary"])
|
||||
; /* keep data as is */ // TODO: do we need to change encodings?
|
||||
else
|
||||
{
|
||||
|
||||
@@ -106,6 +106,9 @@
|
||||
@interface SOGoMailRussianForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
@interface SOGoMailSerbianForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
@interface SOGoMailSlovakForward : SOGoMailForward
|
||||
@end
|
||||
|
||||
|
||||
@@ -317,6 +317,9 @@
|
||||
@implementation SOGoMailRussianForward
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSerbianForward
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSlovakForward
|
||||
@end
|
||||
|
||||
|
||||
@@ -105,6 +105,9 @@
|
||||
@interface SOGoMailRussianReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
@interface SOGoMailSerbianReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
@interface SOGoMailSlovakReply : SOGoMailReply
|
||||
@end
|
||||
|
||||
|
||||
@@ -153,6 +153,9 @@
|
||||
@implementation SOGoMailRussianReply
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSerbianReply
|
||||
@end
|
||||
|
||||
@implementation SOGoMailSlovakReply
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<#newLine/>
|
||||
<#newLine/>
|
||||
<#signaturePlacementOnTop><#newLine/>
|
||||
<#signature/><#newLine/></#signaturePlacementOnTop>
|
||||
-------- Оригинална порука --------<#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/>
|
||||
<#signaturePlacementOnBottom><#newLine/>
|
||||
<#newLine/>
|
||||
<#signature/></#signaturePlacementOnBottom>
|
||||
<#newLine/>
|
||||
@@ -0,0 +1,88 @@
|
||||
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;
|
||||
}
|
||||
|
||||
signaturePlacementOnTop: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
}
|
||||
|
||||
signaturePlacementOnBottom: WOConditional {
|
||||
condition = signaturePlacementOnTop;
|
||||
negate = YES;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<#replyPlacementOnTop><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnTop><#signaturePlacementOnTop><#newLine/>
|
||||
<#signature/><#newLine/>
|
||||
</#signaturePlacementOnTop><#outlookMode>-------- Оригинална порука --------<#newLine/>
|
||||
Тема: <#subject/><#newLine/>
|
||||
Датум: <#date/><#newLine/>
|
||||
Од: <#from/><#newLine/>
|
||||
<#hasReplyTo>Одговори: <#replyTo/></#hasReplyTo><#hasOrganization>Организација: <#organization/></#hasOrganization>За: <#to/><#newLine/>
|
||||
<#hasCc>ЦЦ: <#cc/></#hasCc><#hasNewsGroups>Група новости: <#newsgroups/></#hasNewsGroups><#hasReferences>Референце: <#references/></#hasReferences></#outlookMode><#newLine/>
|
||||
<#standardMode>Дана <#date/>, <#from/> је написао/ла:</#standardMode><#newLine/>
|
||||
<#newLine/>
|
||||
<#messageBody/><#newLine/>
|
||||
<#replyPlacementOnBottom><#newLine/>
|
||||
<#newLine/>
|
||||
</#replyPlacementOnBottom><#signaturePlacementOnBottom><#signature/></#signaturePlacementOnBottom><#newLine/>
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
"OtherUsersFolderName" = "Остали корисници";
|
||||
"SharedFoldersName" = "Дељени директоријуми";
|
||||
+42
-20
@@ -913,7 +913,29 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
||||
{
|
||||
allValues = [[ldapEntry attributeWithName: currentFieldName]
|
||||
allStringValues];
|
||||
[emails addObjectsFromArray: allValues];
|
||||
|
||||
// Special case handling for Microsoft Active Directory. proxyAddresses
|
||||
// is generally prefixed with smtp: - if we find this (or any value preceeding
|
||||
// the semi-colon), we strip it. See https://msdn.microsoft.com/en-us/library/ms679424(v=vs.85).aspx
|
||||
if ([currentFieldName caseInsensitiveCompare: @"proxyAddresses"] == NSOrderedSame)
|
||||
{
|
||||
NSRange r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < [allValues count]; i++)
|
||||
{
|
||||
ldapValue = [allValues objectAtIndex: i];
|
||||
r = [ldapValue rangeOfString: @":"];
|
||||
if (r.length)
|
||||
{
|
||||
[emails addObject: [ldapValue substringFromIndex: r.location+1]];
|
||||
}
|
||||
else
|
||||
[emails addObject: ldapValue];
|
||||
}
|
||||
}
|
||||
else
|
||||
[emails addObjectsFromArray: allValues];
|
||||
}
|
||||
[ldifRecord setObject: emails forKey: @"c_emails"];
|
||||
[emails release];
|
||||
@@ -1702,25 +1724,25 @@ _makeLDAPChanges (NGLdapConnection *ldapConnection,
|
||||
ab = [LDAPSource new];
|
||||
[ab setSourceID: [sourceRec objectForKey: @"ou"]];
|
||||
[ab setDisplayName: [sourceRec objectForKey: @"description"]];
|
||||
[ab setBindDN: bindDN
|
||||
password: password
|
||||
hostname: hostname
|
||||
port: [NSString stringWithFormat: @"%d", port]
|
||||
encryption: encryption
|
||||
bindAsCurrentUser: [NSString stringWithFormat: @"%d", NO]];
|
||||
[ab setBaseDN: [entry dn]
|
||||
IDField: @"cn"
|
||||
CNField: @"displayName"
|
||||
UIDField: @"cn"
|
||||
mailFields: nil
|
||||
searchFields: nil
|
||||
groupObjectClasses: nil
|
||||
IMAPHostField: nil
|
||||
IMAPLoginField: nil
|
||||
SieveHostField: nil
|
||||
bindFields: nil
|
||||
kindField: nil
|
||||
andMultipleBookingsField: nil];
|
||||
[ab setBindDN: bindDN
|
||||
password: password
|
||||
hostname: hostname
|
||||
port: [NSString stringWithFormat: @"%d", port]
|
||||
encryption: encryption
|
||||
bindAsCurrentUser: [NSString stringWithFormat: @"%d", NO]];
|
||||
[ab setBaseDN: [entry dn]
|
||||
IDField: @"cn"
|
||||
CNField: @"displayName"
|
||||
UIDField: @"cn"
|
||||
mailFields: nil
|
||||
searchFields: nil
|
||||
groupObjectClasses: nil
|
||||
IMAPHostField: nil
|
||||
IMAPLoginField: nil
|
||||
SieveHostField: nil
|
||||
bindFields: nil
|
||||
kindField: nil
|
||||
andMultipleBookingsField: nil];
|
||||
[ab setListRequiresDot: NO];
|
||||
[ab setModifiers: modifier];
|
||||
[sources addObject: ab];
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
SOGoSupportedLanguages = ( "Arabic", "Basque", "BrazilianPortuguese", "Catalan", "ChineseTaiwan", "Croatian",
|
||||
"Czech", "Danish", "Dutch", "English", "Finnish", "French", "German", "Hungarian",
|
||||
"Icelandic", "Italian", "Lithuanian", "Macedonian", "NorwegianBokmal",
|
||||
"NorwegianNynorsk", "Polish", "Portuguese", "Russian", "Slovak", "Slovenian",
|
||||
"NorwegianNynorsk", "Polish", "Portuguese", "Russian", "Serbian", "Slovak", "Slovenian",
|
||||
"SpanishArgentina", "SpanishSpain", "Swedish", "TurkishTurkey", "Ukrainian", "Welsh" );
|
||||
|
||||
SOGoTimeZone = "UTC";
|
||||
|
||||
@@ -1740,7 +1740,7 @@ static NSArray *childRecordFields = nil;
|
||||
{
|
||||
EOQualifier *qualifier;
|
||||
NSString *uid, *uids, *qs, *objectPath, *domain;
|
||||
NSMutableArray *usersAndGroups;
|
||||
NSMutableArray *usersAndGroups, *groupsMembers;
|
||||
NSMutableDictionary *aclsForObject;
|
||||
SOGoGroup *group;
|
||||
unsigned int i;
|
||||
@@ -1749,23 +1749,40 @@ static NSArray *childRecordFields = nil;
|
||||
{
|
||||
domain = [[context activeUser] domain];
|
||||
usersAndGroups = [NSMutableArray arrayWithArray: users];
|
||||
groupsMembers = [NSMutableArray array];
|
||||
for (i = 0; i < [usersAndGroups count]; i++)
|
||||
{
|
||||
uid = [usersAndGroups objectAtIndex: i];
|
||||
if (![uid hasPrefix: @"@"])
|
||||
{
|
||||
// Prefix the UID with the character "@" when dealing with a group
|
||||
group = [SOGoGroup groupWithIdentifier: uid inDomain: domain];
|
||||
if (group)
|
||||
[usersAndGroups replaceObjectAtIndex: i
|
||||
withObject: [NSString stringWithFormat: @"@%@", uid]];
|
||||
{
|
||||
NSArray *members;
|
||||
SOGoUser *user;
|
||||
unsigned int j;
|
||||
|
||||
// Fetch members to remove them from the cache along the group
|
||||
members = [group members];
|
||||
for (j = 0; j < [members count]; j++)
|
||||
{
|
||||
user = [members objectAtIndex: j];
|
||||
[groupsMembers addObject: [user login]];
|
||||
}
|
||||
|
||||
// Prefix the UID with the character "@" when dealing with a group
|
||||
[usersAndGroups replaceObjectAtIndex: i
|
||||
withObject: [NSString stringWithFormat: @"@%@", uid]];
|
||||
}
|
||||
}
|
||||
}
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aclsForObject = [[SOGoCache sharedCache] aclsForPath: objectPath];
|
||||
if (aclsForObject)
|
||||
{
|
||||
// Remove users, groups and groups members from the cache
|
||||
[aclsForObject removeObjectsForKeys: usersAndGroups];
|
||||
[aclsForObject removeObjectsForKeys: groupsMembers];
|
||||
[[SOGoCache sharedCache] setACLs: aclsForObject
|
||||
forPath: objectPath];
|
||||
}
|
||||
@@ -1813,6 +1830,7 @@ static NSArray *childRecordFields = nil;
|
||||
NSMutableArray *newRoles;
|
||||
SOGoGroup *group;
|
||||
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
aUID = uid;
|
||||
if (![uid hasPrefix: @"@"])
|
||||
{
|
||||
@@ -1820,7 +1838,12 @@ static NSArray *childRecordFields = nil;
|
||||
domain = [[context activeUser] domain];
|
||||
group = [SOGoGroup groupWithIdentifier: uid inDomain: domain];
|
||||
if (group)
|
||||
aUID = [NSString stringWithFormat: @"@%@", uid];
|
||||
{
|
||||
aUID = [NSString stringWithFormat: @"@%@", uid];
|
||||
// Remove all roles when defining ACLs for a group
|
||||
[[SOGoCache sharedCache] setACLs: nil
|
||||
forPath: objectPath];
|
||||
}
|
||||
}
|
||||
[self removeAclsForUsers: [NSArray arrayWithObject: aUID]
|
||||
forObjectAtPath: objectPathArray];
|
||||
@@ -1831,12 +1854,11 @@ static NSArray *childRecordFields = nil;
|
||||
[newRoles removeObject: SOGoRole_PublicUser];
|
||||
[newRoles removeObject: SOGoRole_AuthorizedSubscriber];
|
||||
[newRoles removeObject: SOGoRole_None];
|
||||
objectPath = [objectPathArray componentsJoinedByString: @"/"];
|
||||
|
||||
if (![newRoles count])
|
||||
[newRoles addObject: SOGoRole_None];
|
||||
|
||||
[self _cacheRoles: newRoles forUser: uid
|
||||
[self _cacheRoles: newRoles forUser: aUID
|
||||
forObjectAtPath: objectPath];
|
||||
|
||||
[self _commitRoles: newRoles forUID: aUID forObject: objectPath];
|
||||
@@ -1873,9 +1895,9 @@ static NSArray *childRecordFields = nil;
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
return [self setRoles: roles
|
||||
forUser: uid
|
||||
forObjectAtPath: [self pathArrayToFolder]];
|
||||
return [self setRoles: roles
|
||||
forUser: uid
|
||||
forObjectAtPath: [self pathArrayToFolder]];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) users
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2006-2014 Inverse inc.
|
||||
Copyright (C) 2006-2016 Inverse inc.
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo.
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
/*
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
Copyright (C) 2007-2011 Inverse inc.
|
||||
Copyright (C) 2007-2016 Inverse inc.
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
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.
|
||||
|
||||
@@ -358,18 +358,22 @@ static Class NSNullK;
|
||||
NSDictionary *contactInfos;
|
||||
NSString *cn, *email, *fullEmail;
|
||||
|
||||
fullEmail = nil;
|
||||
contactInfos = [self contactInfosForUserWithUIDorEmail: uid];
|
||||
email = [contactInfos objectForKey: @"c_email"];
|
||||
cn = [contactInfos objectForKey: @"cn"];
|
||||
if ([cn length] > 0)
|
||||
if (contactInfos)
|
||||
{
|
||||
if ([email length] > 0)
|
||||
fullEmail = [NSString stringWithFormat: @"%@ <%@>", cn, email];
|
||||
email = [contactInfos objectForKey: @"c_email"];
|
||||
cn = [contactInfos objectForKey: @"cn"];
|
||||
if ([cn length] > 0)
|
||||
{
|
||||
if ([email length] > 0)
|
||||
fullEmail = [NSString stringWithFormat: @"%@ <%@>", cn, email];
|
||||
else
|
||||
fullEmail = cn;
|
||||
}
|
||||
else
|
||||
fullEmail = cn;
|
||||
fullEmail = email;
|
||||
}
|
||||
else
|
||||
fullEmail = email;
|
||||
|
||||
return fullEmail;
|
||||
}
|
||||
|
||||
@@ -520,7 +520,7 @@
|
||||
for (i = 0; i < [_mailFields count]; i++)
|
||||
if ((s = [response objectForKey: [_mailFields objectAtIndex: i]]) &&
|
||||
[[s stringByTrimmingSpaces] length] > 0)
|
||||
[emails addObject: s];
|
||||
[emails addObjectsFromArray: [s componentsSeparatedByString: @" "]];
|
||||
}
|
||||
|
||||
[response setObject: emails forKey: @"c_emails"];
|
||||
|
||||
@@ -13,7 +13,7 @@ import sogoLogin
|
||||
SOGoSupportedLanguages = [ "Arabic", "Basque", "Catalan", "ChineseTaiwan", "Croatian", "Czech", "Dutch", "Danish", "Welsh", "English", "Finnish",
|
||||
"SpanishSpain", "SpanishArgentina", "French", "German",
|
||||
"Icelandic", "Italian", "Lithuanian", "Macedonian", "Hungarian", "Portuguese", "BrazilianPortuguese",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Slovak",
|
||||
"NorwegianBokmal", "NorwegianNynorsk", "Polish", "Russian", "Serbian", "Slovak",
|
||||
"Slovenian", "Swedish", "TurkishTurkey", "Ukrainian" ];
|
||||
daysBetweenResponseList=[1,2,3,5,7,14,21,30]
|
||||
|
||||
|
||||
@@ -400,8 +400,8 @@ class CalDAVSchedulingTest(unittest.TestCase):
|
||||
attendee.partstat_param = "NEEDS-ACTION"
|
||||
attendee.value = self.res_no_ob_email
|
||||
|
||||
# put the event - should trigger a 403
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, ob_ics_name), event, exp_status=403)
|
||||
# put the event - should trigger a 409
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, ob_ics_name), event, exp_status=409)
|
||||
|
||||
def testResourceCanOverbook(self):
|
||||
""" try to overbook a resource - multiplebookings=0"""
|
||||
@@ -515,7 +515,7 @@ class CalDAVSchedulingTest(unittest.TestCase):
|
||||
attendee.partstat_param = "NEEDS-ACTION"
|
||||
attendee.value = self.res_no_ob_email
|
||||
# should fail
|
||||
self._putEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, overlap_ics_name), event, exp_status=403)
|
||||
self._putEvent(self.attendee1_client, "%s%s" % (self.attendee1_calendar, overlap_ics_name), event, exp_status=409)
|
||||
|
||||
# 3. Create recurring event which _doesn't_ overlap the first event
|
||||
# (should be OK, used to fail pre1.3.17)
|
||||
@@ -528,12 +528,12 @@ class CalDAVSchedulingTest(unittest.TestCase):
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, nooverlap_recurring_ics_name), nooverlap_event)
|
||||
|
||||
# 4. Create recurring event overlapping the previous recurring event
|
||||
# should fail
|
||||
# should fail with a 409
|
||||
nstartdate = nooverlap_event.vevent.dtstart.value + datetime.timedelta(0, 300)
|
||||
nooverlap_event.vevent.dtstart.value = nstartdate
|
||||
nooverlap_event.vevent.dtend.value = nstartdate + datetime.timedelta(0, 3600)
|
||||
nooverlap_event.vevent.uid.value = "recurring - overlap"
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, overlap_recurring_ics_name), nooverlap_event, exp_status=403)
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, overlap_recurring_ics_name), nooverlap_event, exp_status=409)
|
||||
|
||||
|
||||
def testRruleExceptionInvitationDance(self):
|
||||
@@ -813,8 +813,8 @@ class CalDAVSchedulingTest(unittest.TestCase):
|
||||
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, ics_name), event)
|
||||
|
||||
# PUT the same event with a new filename - should trigger a 403
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, conflict_ics_name), event, exp_status=403)
|
||||
# PUT the same event with a new filename - should trigger a 409
|
||||
self._putEvent(self.client, "%s%s" % (self.user_calendar, conflict_ics_name), event, exp_status=409)
|
||||
|
||||
def testInvitationDelegation(self):
|
||||
""" invitation delegation """
|
||||
|
||||
+22
-4
@@ -1,6 +1,6 @@
|
||||
/* SOGoToolBackup.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009-2015 Inverse inc.
|
||||
* Copyright (C) 2009-2016 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -141,7 +141,6 @@
|
||||
|
||||
lm = [SOGoUserManager sharedUserManager];
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
max = [users count];
|
||||
user = [users objectAtIndex: 0];
|
||||
@@ -194,7 +193,27 @@
|
||||
if (infos)
|
||||
[allUsers addObject: infos];
|
||||
else
|
||||
NSLog (@"user '%@' unknown", user);
|
||||
{
|
||||
// We haven't found the user based on the GCS table name
|
||||
// Let's try to strip the domain part and search again.
|
||||
// This can happen when using SOGoEnableDomainBasedUID (YES)
|
||||
// but login in SOGo using a UID without domain (DomainLessLogin gets set)
|
||||
NSRange r;
|
||||
|
||||
r = [user rangeOfString: @"@"];
|
||||
|
||||
if (r.location != NSNotFound)
|
||||
{
|
||||
user = [user substringToIndex: r.location];
|
||||
infos = [lm contactInfosForUserWithUIDorEmail: user];
|
||||
if (infos)
|
||||
[allUsers addObject: infos];
|
||||
else
|
||||
NSLog (@"user '%@' unknown", user);
|
||||
}
|
||||
else
|
||||
NSLog (@"user '%@' unknown", user);
|
||||
}
|
||||
}
|
||||
[allUsers autorelease];
|
||||
|
||||
@@ -427,7 +446,6 @@
|
||||
if ([sd enableDomainBasedUID] && [gcsUID rangeOfString: @"@"].location == NSNotFound)
|
||||
gcsUID = [NSString stringWithFormat: @"%@@%@", gcsUID, [theUser objectForKey: @"c_domain"]];
|
||||
|
||||
|
||||
return ([self extractUserFolders: gcsUID
|
||||
intoRecord: userRecord]
|
||||
&& [self extractUserLDIFRecord: ldapUID
|
||||
|
||||
+189
-12
@@ -25,6 +25,8 @@
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSProcessInfo.h>
|
||||
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
@@ -52,6 +54,8 @@ typedef enum
|
||||
ManageEASListFolders = 2,
|
||||
ManageEASResetDevice = 3,
|
||||
ManageEASRestFolder = 4,
|
||||
ManageEASVCard = 5,
|
||||
ManageEASVEvent = 6,
|
||||
} SOGoManageEASCommand;
|
||||
|
||||
@interface SOGoToolManageEAS : SOGoTool
|
||||
@@ -59,6 +63,8 @@ typedef enum
|
||||
|
||||
@implementation SOGoToolManageEAS
|
||||
|
||||
NSURL *folderTableURL;
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
}
|
||||
@@ -73,15 +79,58 @@ typedef enum
|
||||
return @"manage EAS folders";
|
||||
}
|
||||
|
||||
- (void) _setOrUnsetSyncRequest: (BOOL) set
|
||||
collections: (NSArray *) collections
|
||||
{
|
||||
SOGoCacheGCSObject *o;
|
||||
NSNumber *processIdentifier;
|
||||
NSString *key;
|
||||
NSArray *a;
|
||||
int i;
|
||||
|
||||
processIdentifier = [NSNumber numberWithInt: [[NSProcessInfo processInfo] processIdentifier]];
|
||||
|
||||
o = [SOGoCacheGCSObject objectWithName: [[[collections objectAtIndex: 0] componentsSeparatedByString: @"+"] objectAtIndex: 0] inContainer: nil useCache: NO];
|
||||
[o setObjectType: ActiveSyncGlobalCacheObject];
|
||||
[o setTableUrl: folderTableURL];
|
||||
[o reloadIfNeeded];
|
||||
|
||||
if (set)
|
||||
{
|
||||
[[o properties] setObject: [NSNumber numberWithUnsignedInt: [[NSCalendarDate date] timeIntervalSince1970]] forKey: @"SyncRequest"];
|
||||
|
||||
for (i = 0; i < [collections count]; i++)
|
||||
{
|
||||
a = [[collections objectAtIndex: i] componentsSeparatedByString: @"+"];
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", [a objectAtIndex: 1]];
|
||||
[[o properties] setObject: processIdentifier forKey: key];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[[o properties] removeObjectForKey: @"SyncRequest"];
|
||||
for (i = 0; i < [collections count]; i++)
|
||||
{
|
||||
a = [[collections objectAtIndex: i] componentsSeparatedByString: @"+"];
|
||||
key = [NSString stringWithFormat: @"SyncRequest+%@", [a objectAtIndex: 1]];
|
||||
[[o properties] removeObjectForKey: key];
|
||||
}
|
||||
}
|
||||
|
||||
[o save];
|
||||
}
|
||||
|
||||
- (void) usage
|
||||
{
|
||||
fprintf (stderr, "manage-eas listdevices|resetdevice|resetfolder user <devinceId | folderId> \n\n"
|
||||
fprintf (stderr, "manage-eas listdevices|resetdevice|resetfolder|mergevcard|mergevevent user <devinceId | folderId> <YES | NO>\n\n"
|
||||
" user the user of whom to reset the whole device or a single folder\n"
|
||||
" Examples:\n"
|
||||
" sogo-tool manage-eas listdevices janedoe\n"
|
||||
" sogo-tool manage-eas listfolders janedoe androidc316986417\n"
|
||||
" sogo-tool manage-eas resetdevice janedoe androidc316986417\n"
|
||||
" sogo-tool manage-eas resetfolder janedow androidc316986417+folderlala-dada-sasa_7a13_1a2386e0_e\n") ;
|
||||
" sogo-tool manage-eas resetfolder janedow androidc316986417+folderlala-dada-sasa_7a13_1a2386e0_e\n"
|
||||
" sogo-tool manage-eas mergevcard janedow androidc316986417 YES\n"
|
||||
" sogo-tool manage-eas mergevevent janedow androidc316986417 YES\n") ;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +146,10 @@ typedef enum
|
||||
return ManageEASResetDevice;
|
||||
else if ([theString caseInsensitiveCompare: @"resetfolder"] == NSOrderedSame)
|
||||
return ManageEASRestFolder;
|
||||
else if ([theString caseInsensitiveCompare: @"mergevcard"] == NSOrderedSame)
|
||||
return ManageEASVCard;
|
||||
else if ([theString caseInsensitiveCompare: @"mergevevent"] == NSOrderedSame)
|
||||
return ManageEASVEvent;
|
||||
}
|
||||
|
||||
return ManageEASUnknown;
|
||||
@@ -107,7 +160,6 @@ typedef enum
|
||||
NSString *urlString, *deviceId, *userId;
|
||||
NSMutableString *ocFSTableName;
|
||||
SOGoCacheGCSObject *oc, *foc;
|
||||
NSURL *folderTableURL;
|
||||
NSMutableArray *parts;
|
||||
NSArray *entries;
|
||||
id cacheEntry;
|
||||
@@ -169,6 +221,7 @@ typedef enum
|
||||
}
|
||||
|
||||
rc = YES;
|
||||
|
||||
break;
|
||||
|
||||
case ManageEASListFolders:
|
||||
@@ -195,6 +248,8 @@ typedef enum
|
||||
[foc reloadIfNeeded];
|
||||
|
||||
fprintf(stdout, " Folder Name: %s\n\n", [[[foc properties] objectForKey: @"displayName"] UTF8String]);
|
||||
if ([[foc properties] objectForKey: @"MergedFolder"])
|
||||
fprintf(stdout, " MergedFolder = YES\n\n");
|
||||
|
||||
if (verbose)
|
||||
fprintf(stdout, " metadata Name: %s\n\n", [[[foc properties] description] UTF8String]);
|
||||
@@ -227,7 +282,7 @@ typedef enum
|
||||
|
||||
NSMutableString *sql;
|
||||
|
||||
sql = [NSMutableString stringWithFormat: @"DELETE FROM %@ WHERE c_path like '/%@'", [oc tableName], deviceId];
|
||||
sql = [NSMutableString stringWithFormat: @"DELETE FROM %@ WHERE c_path like '/%@%'", [oc tableName], deviceId];
|
||||
|
||||
[oc performBatchSQLQueries: [NSArray arrayWithObject: sql]];
|
||||
rc = YES;
|
||||
@@ -260,16 +315,138 @@ typedef enum
|
||||
fprintf(stderr, "ERROR: Folder with ID \"%s\" not found\n", [deviceId UTF8String]);
|
||||
return rc;
|
||||
}
|
||||
[[oc properties] removeObjectForKey: @"SyncKey"];
|
||||
[[oc properties] removeObjectForKey: @"SyncCache"];
|
||||
[[oc properties] removeObjectForKey: @"DateCache"];
|
||||
[[oc properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[oc properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[oc properties] removeObjectForKey: @"LastIdInCache"];
|
||||
|
||||
[oc save];
|
||||
if ((![deviceId hasSuffix: @"/personal"]) && [[oc properties] objectForKey: @"MergedFolder"])
|
||||
{
|
||||
fprintf(stderr, "ERROR: MergedFolder = true; only personal folder can be reset");
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObject: deviceId]];
|
||||
|
||||
[[oc properties] removeObjectForKey: @"SyncKey"];
|
||||
[[oc properties] removeObjectForKey: @"SyncCache"];
|
||||
[[oc properties] removeObjectForKey: @"DateCache"];
|
||||
[[oc properties] removeObjectForKey: @"UidCache"];
|
||||
[[oc properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[oc properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[oc properties] removeObjectForKey: @"SupportedElements"];
|
||||
[[oc properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[[oc properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[oc properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[oc properties] removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[oc save];
|
||||
rc = YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\nERROR: folderId not specified\n\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ManageEASVCard:
|
||||
case ManageEASVEvent:
|
||||
if (max > 3)
|
||||
{
|
||||
NSString *folderType;
|
||||
|
||||
if (cmd == ManageEASVCard)
|
||||
folderType = @"vcard";
|
||||
else
|
||||
folderType = @"vevent";
|
||||
|
||||
/* value specified on command line */
|
||||
deviceId = [sanitizedArguments objectAtIndex: 2];
|
||||
|
||||
oc = [SOGoCacheGCSObject objectWithName: @"0" inContainer: nil];
|
||||
[oc setObjectType: ActiveSyncFolderCacheObject];
|
||||
|
||||
[oc setTableUrl: folderTableURL];
|
||||
entries = [oc cacheEntriesForDeviceId: deviceId newerThanVersion: -1];
|
||||
|
||||
vtodo:
|
||||
|
||||
for (i = 0; i < [entries count]; i++)
|
||||
{
|
||||
cacheEntry = [entries objectAtIndex: i];
|
||||
|
||||
if ([[cacheEntry substringFromIndex: 1] hasPrefix: [NSString stringWithFormat: @"%@+%@/", deviceId, folderType]])
|
||||
{
|
||||
fprintf(stdout,"Folder Key: %s\n", [[cacheEntry substringFromIndex: 1] UTF8String]);
|
||||
|
||||
foc = [SOGoCacheGCSObject objectWithName: [cacheEntry substringFromIndex: 1] inContainer: nil];
|
||||
[foc setObjectType: ActiveSyncFolderCacheObject];
|
||||
[foc setTableUrl: folderTableURL];
|
||||
|
||||
[foc reloadIfNeeded];
|
||||
|
||||
if ([foc isNew])
|
||||
continue;
|
||||
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObject: [cacheEntry substringFromIndex: 1]]];
|
||||
|
||||
if (![[cacheEntry substringFromIndex: 1] hasPrefix: [NSString stringWithFormat: @"%@+%@/personal", deviceId, folderType]] &&
|
||||
[[sanitizedArguments objectAtIndex: 3] isEqualToString: @"NO"] &&
|
||||
[[[foc properties] objectForKey: @"MergedFolder"] isEqualToString: @"2"])
|
||||
{
|
||||
[foc destroy];
|
||||
continue;
|
||||
}
|
||||
else if ([[sanitizedArguments objectAtIndex: 3] isEqualToString: @"NO"])
|
||||
{
|
||||
[[foc properties] removeObjectForKey: @"SyncKey"];
|
||||
[[foc properties] removeObjectForKey: @"SyncCache"];
|
||||
[[foc properties] removeObjectForKey: @"DateCache"];
|
||||
[[foc properties] removeObjectForKey: @"UidCache"];
|
||||
[[foc properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[foc properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[foc properties] removeObjectForKey: @"SupportedElements"];
|
||||
[[foc properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[[foc properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[foc properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[foc properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[foc properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[foc properties] removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[[foc properties] removeObjectForKey: @"MergedFolder"];
|
||||
}
|
||||
else if ([[sanitizedArguments objectAtIndex: 3] isEqualToString: @"YES"] && ![[foc properties] objectForKey: @"MergedFolder"])
|
||||
{
|
||||
if (![[cacheEntry substringFromIndex: 1] hasPrefix: [NSString stringWithFormat: @"%@+%@/personal", deviceId, folderType]])
|
||||
{
|
||||
[[foc properties] removeObjectForKey: @"SyncKey"];
|
||||
[[foc properties] removeObjectForKey: @"SyncCache"];
|
||||
[[foc properties] removeObjectForKey: @"DateCache"];
|
||||
[[foc properties] removeObjectForKey: @"UidCache"];
|
||||
[[foc properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[foc properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[foc properties] removeObjectForKey: @"SupportedElements"];
|
||||
[[foc properties] removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[[foc properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[foc properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[foc properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[foc properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[foc properties] removeObjectForKey: @"CleanoutDate"];
|
||||
}
|
||||
|
||||
[[foc properties] setObject: @"1" forKey: @"MergedFolder"];
|
||||
}
|
||||
|
||||
[foc save];
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == ManageEASVEvent && [folderType isEqualToString: @"vevent"])
|
||||
{
|
||||
folderType = @"vtodo";
|
||||
goto vtodo;
|
||||
}
|
||||
|
||||
rc = YES;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -114,15 +114,24 @@
|
||||
- (BOOL) truncateEntriesFromFolder: (GCSFolder *) folder
|
||||
usingDate: (NSCalendarDate *) date
|
||||
{
|
||||
NSArray *fields, *records;
|
||||
NSMutableArray *records;
|
||||
EOQualifier *qualifier;
|
||||
NSArray *fields;
|
||||
NSString *qs;
|
||||
BOOL rc;
|
||||
|
||||
records = [NSMutableArray array];
|
||||
fields = [NSArray arrayWithObjects: @"c_name", nil];
|
||||
qs = [NSString stringWithFormat: @"c_enddate <= %d c_iscycle == 0 AND c_component == 'vevent'", (int)[date timeIntervalSince1970]];
|
||||
|
||||
// We fetch non-repetitive events
|
||||
qs = [NSString stringWithFormat: @"c_enddate <= %d AND c_iscycle == 0 AND c_component == 'vevent'", (int)[date timeIntervalSince1970]];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
records = [folder fetchFields: fields matchingQualifier: qualifier];
|
||||
[records addObjectsFromArray: [folder fetchFields: fields matchingQualifier: qualifier]];
|
||||
|
||||
// We fetch repetitive events with a cycle end date
|
||||
qs = [NSString stringWithFormat: @"c_cycleenddate <= %d AND c_iscycle == 1 AND c_component == 'vevent'", (int)[date timeIntervalSince1970]];
|
||||
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
|
||||
[records addObjectsFromArray: [folder fetchFields: fields matchingQualifier: qualifier]];
|
||||
|
||||
if (records)
|
||||
{
|
||||
@@ -189,10 +198,9 @@
|
||||
// in the default timezone.
|
||||
s = [NSString stringWithFormat: @"%@ GMT", date];
|
||||
d = [NSCalendarDate dateWithString: s calendarFormat: @"%Y-%m-%dT%H:%M:%S %Z"];
|
||||
|
||||
|
||||
fom = [GCSFolderManager defaultFolderManager];
|
||||
if (fom)
|
||||
|
||||
if (d && fom)
|
||||
rc = [self processFolder: folder
|
||||
ofUser: username
|
||||
date: d
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Help" = "Помоћ";
|
||||
"Close" = "Затвори";
|
||||
"Modules" = "Модули";
|
||||
/* Modules short names */
|
||||
"ACLs" = "АЦЛе";
|
||||
/* Modules titles */
|
||||
"ACLs_title" = "Управљање АЦЛма корисничких директоријума";
|
||||
/* Modules descriptions */
|
||||
"ACLs_description" = "<p>Администрациони модул Контролних Листа Приступа дозвољава вам да мењате АЦЛе за сваки кориснички Календар и Адресар.</p><p>Да измените АЦЛе корисничког директоријума, откуцајте име корисника у пољу за претрагу на врху прозора и направите дупли клик на жељени директоријум.</p>";
|
||||
"Name or Email" = "Име или Епошта";
|
||||
/* Rights module: initial search message */
|
||||
"Start a search to edit the rights" = "Започните претрагу да измените права";
|
||||
/* Rights module: Empty search result */
|
||||
"No matching user" = "Нема подударајућег корисника";
|
||||
/* Rights module: no selection */
|
||||
"No resource selected" = "Нема одабраног ресурса";
|
||||
"Add User" = "Додај корисника";
|
||||
"Subscribe User" = "Претплати корисника";
|
||||
"Rights" = "Права";
|
||||
"Search Users" = "Претражи кориснике";
|
||||
"users found" = "корисници пронађени";
|
||||
"No resource" = "Нема ресурса";
|
||||
"Any Authenticated User" = "Било који аутентификовани корисник";
|
||||
"Public Access" = "Јавни приступ";
|
||||
@@ -9,7 +9,7 @@
|
||||
"ACLs_title" = "Kullanıcı klasörleri Erişim Denetim Listeleri yönetimi";
|
||||
/* Modules descriptions */
|
||||
"ACLs_description" = "<p> Erişim Denetim Listesi yönetim modülü, her kullanıcı için Takvim ve Adres defterlerinin EDL'lerin değiştirilmesini sağlar. </p><p>Bir kullanıcı klasörünün EDL'sini değiştirmek için, pencerenin üst kısmındaki arama alanına kullanıcının adını yazın ve ilgili klasöre çift tıklayın.</p>";
|
||||
"Name or Email" = "Ad Soyad veya E-posta";
|
||||
"Name or Email" = "İsim veya E-posta";
|
||||
/* Rights module: initial search message */
|
||||
"Start a search to edit the rights" = "yetkileri düzenlemek için bir arama başlatın";
|
||||
/* Rights module: Empty search result */
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
= "Qualquer pessoa na Internet será capaz de acessar seu catálogo de endereços \"% {0}\", mesmo se não tiver uma conta no sistema. Esta informação pode ser tornar pública na Internet?";
|
||||
"Give Access" = "Conceder Acesso";
|
||||
"Keep Private" = "Manter Privado";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Não foi possível inscrever-se nesta pasta!";
|
||||
@@ -76,16 +77,19 @@
|
||||
"45 minutes" = "45 minutos";
|
||||
"1 hour" = "1 hora";
|
||||
"1 day" = "1 dia";
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "OK";
|
||||
"Cancel" = "Cancelar";
|
||||
"Yes" = "Sim";
|
||||
"No" = "Não";
|
||||
|
||||
/* alarms */
|
||||
"Reminder" = "Lembrete";
|
||||
"Start" = "Inicio";
|
||||
"Due Date" = "Data";
|
||||
"Location" = "Localização";
|
||||
|
||||
/* mail labels */
|
||||
"Important" = "Importante";
|
||||
"Work" = "Trabalho";
|
||||
@@ -105,5 +109,14 @@
|
||||
"No such user." = "Usuário não existe.";
|
||||
"You cannot (un)subscribe to a folder that you own!" = "Você não pode (des)inscrever uma pasta que você é dono!";
|
||||
|
||||
/* Authentication username */
|
||||
"Username" = "Usuário";
|
||||
|
||||
/* Authentication password */
|
||||
"Password" = "Senha";
|
||||
|
||||
/* Authentication failed */
|
||||
"Wrong username or password." = "Usuário ou Senha Inválido.";
|
||||
|
||||
/* Error message display bellow search field when the search string has less than the required number of characters */
|
||||
"Enter at least %{minimumSearchLength} characters" = "Digite pelo menos %{minimumSearchLength} caracteres";
|
||||
@@ -119,4 +119,52 @@
|
||||
"Wrong username or password." = "Wrong username or password.";
|
||||
|
||||
/* Error message display bellow search field when the search string has less than the required number of characters */
|
||||
"Enter at least %{minimumSearchLength} characters" = "Enter at least %{minimumSearchLength} characters";
|
||||
"Enter at least %{minimumSearchLength} characters" = "Enter at least %{minimumSearchLength} characters";
|
||||
|
||||
/* Question mark shows list of hotkeys */
|
||||
"Show or hide this help" = "Show or hide this help";
|
||||
|
||||
/* Space key */
|
||||
"key_space" = "space";
|
||||
|
||||
/* Up arrow key */
|
||||
"key_up" = "↑";
|
||||
|
||||
/* Down arrow key */
|
||||
"key_down" = "↓";
|
||||
|
||||
/* Left arrow key */
|
||||
"key_left" = "←";
|
||||
|
||||
/* Right arrow key */
|
||||
"key_right" = "→";
|
||||
|
||||
/* Shift and up arrow combo keys */
|
||||
"key_shift+up" = "shift + ↑";
|
||||
|
||||
/* Shift and down arrow combo keys */
|
||||
"key_shift+down" = "shift + ↓";
|
||||
|
||||
/* Backspace key */
|
||||
"key_backspace" = "backspace";
|
||||
|
||||
/* Hotkey to start a search */
|
||||
"hotkey_search" = "s";
|
||||
|
||||
/* Hotkey description to select next list item */
|
||||
"View next item" = "View next item";
|
||||
|
||||
/* Hotkey description to select previous list item */
|
||||
"View previous item" = "View previous item";
|
||||
|
||||
/* Hotkey description to add next list item to selection */
|
||||
"Add next item to selection" = "Add next item to selection";
|
||||
|
||||
/* Hotkey description to add previous list item to selection */
|
||||
"Add previous item to selection" = "Add previous item to selection";
|
||||
|
||||
/* Hotkey description to move backward in current view */
|
||||
"Move backward" = "Move backward";
|
||||
|
||||
/* Hotkey description to move forward in current view */
|
||||
"Move forward" = "Move forward";
|
||||
@@ -119,4 +119,52 @@
|
||||
"Wrong username or password." = "Mauvais nom d'utilisateur ou mot de passe.";
|
||||
|
||||
/* Error message display bellow search field when the search string has less than the required number of characters */
|
||||
"Enter at least %{minimumSearchLength} characters" = "Entrez au moins %{minimumSearchLength} caractères";
|
||||
"Enter at least %{minimumSearchLength} characters" = "Entrez au moins %{minimumSearchLength} caractères";
|
||||
|
||||
/* Question mark shows list of hotkeys */
|
||||
"Show or hide this help" = "Afficher ou cache cette aide";
|
||||
|
||||
/* Space key */
|
||||
"key_space" = "space";
|
||||
|
||||
/* Up arrow key */
|
||||
"key_up" = "↑";
|
||||
|
||||
/* Down arrow key */
|
||||
"key_down" = "↓";
|
||||
|
||||
/* Left arrow key */
|
||||
"key_left" = "←";
|
||||
|
||||
/* Right arrow key */
|
||||
"key_right" = "→";
|
||||
|
||||
/* Shift and up arrow combo keys */
|
||||
"key_shift+up" = "shift + ↑";
|
||||
|
||||
/* Shift and down arrow combo keys */
|
||||
"key_shift+down" = "shift + ↓";
|
||||
|
||||
/* Backspace key */
|
||||
"key_backspace" = "backspace";
|
||||
|
||||
/* Hotkey to start a search */
|
||||
"hotkey_search" = "s";
|
||||
|
||||
/* Hotkey description to select next list item */
|
||||
"View next item" = "Voir l'item suivant";
|
||||
|
||||
/* Hotkey description to select previous list item */
|
||||
"View previous item" = "Voir l'item précédant";
|
||||
|
||||
/* Hotkey description to add next list item to selection */
|
||||
"Add next item to selection" = "Ajouter l'item suivant à la sélection";
|
||||
|
||||
/* Hotkey description to add previous list item to selection */
|
||||
"Add previous item to selection" = "Ajouter l'item précédant à la section";
|
||||
|
||||
/* Hotkey description to move backward in current view */
|
||||
"Move backward" = "Avancer";
|
||||
|
||||
/* Hotkey description to move forward in current view */
|
||||
"Move forward" = "Reculer";
|
||||
@@ -0,0 +1,122 @@
|
||||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* toolbars */
|
||||
"Save" = "Сачувај";
|
||||
"Close" = "Затвори";
|
||||
"Edit User Rights" = "Измени права корисника";
|
||||
"Home" = "Почетна";
|
||||
"Calendar" = "Календар";
|
||||
"Address Book" = "Адресар";
|
||||
"Mail" = "Пошта";
|
||||
"Preferences" = "Подешавање";
|
||||
"Administration" = "Администрација";
|
||||
"Disconnect" = "Прекини";
|
||||
"Toggle Menu" = "Искључи мени";
|
||||
"Right Administration" = "Администрација права";
|
||||
"Log Console (dev.)" = "Конзола дневника (раз.)";
|
||||
"User" = "Корисник";
|
||||
"Vacation message is enabled" = "Омогућена је порука за Одмор";
|
||||
"Help" = "Помоћ";
|
||||
"noJavascriptError" = "SOGo захтева Javascript за рад. Молимо да се уверите да је ова опција доступна и омогућена у подешавањима вашег прегледача.";
|
||||
"noJavascriptRetry" = "Покушај поново";
|
||||
"Owner" = "Власник";
|
||||
"Publish the Free/Busy information" = "Објави информацију Слободан/Заузет";
|
||||
"Add..." = "Додај...";
|
||||
"Remove" = "Уклони...";
|
||||
"Subscribe User" = "Претплати корисника";
|
||||
"Any Authenticated User" = "Било који аутентификовани корисник";
|
||||
"Public Access" = "Јавни приступ";
|
||||
"Any user not listed above" = "Било који корисник који није излистан изнад";
|
||||
"Anybody accessing this resource from the public area" = "Било ко може да приступи овом ресурсу са јавне зоне";
|
||||
"Sorry, the user rights can not be configured for that object." = "Жао нам је, права корисника не могу бити подешена за овај објекат.";
|
||||
"Any user with an account on this system will be able to access your mailbox \"%{0}\". Are you certain you trust them all?"
|
||||
= "Сваки корисник са налогом на овом систему моћи ће да приступи вашем поштанском сандучету \"%{0}\". Да ли сте сигурни да верујете свима?";
|
||||
"Any user with an account on this system will be able to access your calendar \"%{0}\". Are you certain you trust them all?"
|
||||
= "Сваки корисник са налогом на овом систему моћи ће да приступи вашем календару \"%{0}\". Да ли сте сигурни да верујете свима?";
|
||||
"Potentially anyone on the Internet will be able to access your calendar \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
= "Потенцијално би свако на интернету могао да приступи вашем календару \"%{0}\", чак и ако немају налог на овом систему. Да ли је ова информација погодна за јавни интернет?";
|
||||
"Any user with an account on this system will be able to access your address book \"%{0}\". Are you certain you trust them all?"
|
||||
= "Сваки корисник са налогом на овом систему моћи ће да приступи вашем адресару \"%{0}\". Да ли сте сигурни да верујете свима?";
|
||||
"Potentially anyone on the Internet will be able to access your address book \"%{0}\", even if they do not have an account on this system. Is this information suitable for the public Internet?"
|
||||
= "Потенцијално би свако на интернету могао да приступи вашем адресару \"%{0}\", чак и ако немају налог на овом систему. Да ли је ова информација погодна за јавни интернет?";
|
||||
"Give Access" = "Додели приступ";
|
||||
"Keep Private" = "Задржи приватним";
|
||||
|
||||
/* generic.js */
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Не могу да се претплатим на тај директоријум!";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Не можете се претплатити на директоијум чији сте власник!";
|
||||
"Unable to unsubscribe from that folder!"
|
||||
= "Не могу да се одјавим са овог директоријума!";
|
||||
"You cannot unsubscribe from a folder that you own!"
|
||||
= "Не можете да се одјавите са директоријума чији сте власник!";
|
||||
"Unable to rename that folder!" = "Не могу да преименујем овај директоријум!";
|
||||
"You have already subscribed to that folder!"
|
||||
= "Већ сте претплаћени на овај директоријум!";
|
||||
"The user rights cannot be edited for this object!"
|
||||
= "Права корисника не могу бити измењена за овај објекат!";
|
||||
"A folder by that name already exists." = "Директоријум са тим именом већ постоји.";
|
||||
"You cannot create a list in a shared address book."
|
||||
= "Не можете креирати листу у дељеном адресару.";
|
||||
"Warning" = "Упозорење";
|
||||
"Can't contact server" = "Десила се грешка приликом контактирања сервера. Молимо покушајте касније.";
|
||||
"You are not allowed to access this module or this system. Please contact your system administrator."
|
||||
= "Није вам дозвољено да приступите овом модулу или овом систему. Моломо да контактирате вашег систем администратора.";
|
||||
"You don't have the required privileges to perform the operation."
|
||||
= "Немате захтевана овлашћења да извршите ову операцију.";
|
||||
"noEmailForDelegation" = "Морате навести адресу коме желите да делегирате позивницу.";
|
||||
"delegate is organizer" = "Делегирали сте организатору. Молимо наведите неког другог за делегирање.";
|
||||
"delegate is a participant" = "Делегирали сте већ постојећем учеснику.";
|
||||
"delegate is a group" = "Наведена адреса представља групу. Можете само делегирати једној особи.";
|
||||
"Snooze for " = "Одложи за";
|
||||
"5 minutes" = "5 минута";
|
||||
"10 minutes" = "10 минута";
|
||||
"15 minutes" = "15 минута";
|
||||
"30 minutes" = "30 минута";
|
||||
"45 minutes" = "45 минута";
|
||||
"1 hour" = "1 сат";
|
||||
"1 day" = "1 дан";
|
||||
|
||||
/* common buttons */
|
||||
"OK" = "У реду";
|
||||
"Cancel" = "Откажи";
|
||||
"Yes" = "Да";
|
||||
"No" = "Не";
|
||||
|
||||
/* alarms */
|
||||
"Reminder" = "Подсетник";
|
||||
"Start" = "Почетак";
|
||||
"Due Date" = "Рок";
|
||||
"Location" = "Локација";
|
||||
|
||||
/* mail labels */
|
||||
"Important" = "Важно";
|
||||
"Work" = "Посао";
|
||||
"Personal" = "Лично";
|
||||
"To Do" = "Урадити";
|
||||
"Later" = "Касније";
|
||||
"a2_Sunday" = "Не";
|
||||
"a2_Monday" = "По";
|
||||
"a2_Tuesday" = "Ут";
|
||||
"a2_Wednesday" = "Ср";
|
||||
"a2_Thursday" = "Че";
|
||||
"a2_Friday" = "Пе";
|
||||
"a2_Saturday" = "Су";
|
||||
"Access Rights" = "Права приступа";
|
||||
"Add User" = "Додај корисника";
|
||||
"Loading" = "Учитавање";
|
||||
"No such user." = "Нема таквог корисника.";
|
||||
"You cannot (un)subscribe to a folder that you own!" = "Не можете се претплатити(одјавити) из директоријума чији сте власник!";
|
||||
|
||||
/* Authentication username */
|
||||
"Username" = "Корисничко име";
|
||||
|
||||
/* Authentication password */
|
||||
"Password" = "Лозинка";
|
||||
|
||||
/* Authentication failed */
|
||||
"Wrong username or password." = "Погрешно корисничко име и лозинка.";
|
||||
|
||||
/* Error message display bellow search field when the search string has less than the required number of characters */
|
||||
"Enter at least %{minimumSearchLength} characters" = "Унестите најмање %{minimumSearchLength} карактера";
|
||||
@@ -10,7 +10,7 @@
|
||||
"Mail" = "E-posta";
|
||||
"Preferences" = "Tercihler";
|
||||
"Administration" = "Yönetim";
|
||||
"Disconnect" = "Bağlantıyı Kes";
|
||||
"Disconnect" = "Güvenli Çıkış";
|
||||
"Toggle Menu" = "Menüde Geçiş Yap";
|
||||
"Right Administration" = "Yetki Yönetimi";
|
||||
"Log Console (dev.)" = "Seyir Defteri (geliştirici)";
|
||||
@@ -87,7 +87,7 @@
|
||||
/* alarms */
|
||||
"Reminder" = "Hatırlatıcı";
|
||||
"Start" = "Başlangıç";
|
||||
"Due Date" = "Son Tarihi";
|
||||
"Due Date" = "Son Tarih";
|
||||
"Location" = "Konum";
|
||||
|
||||
/* mail labels */
|
||||
@@ -119,4 +119,52 @@
|
||||
"Wrong username or password." = "Kullanıcı adı veya şifre yanlış.";
|
||||
|
||||
/* Error message display bellow search field when the search string has less than the required number of characters */
|
||||
"Enter at least %{minimumSearchLength} characters" = "En az %{minimumSearchLength} harf girin";
|
||||
"Enter at least %{minimumSearchLength} characters" = "En az %{minimumSearchLength} harf girin";
|
||||
|
||||
/* Question mark shows list of hotkeys */
|
||||
"Show or hide this help" = "Bu yardımı gizle veya göster";
|
||||
|
||||
/* Space key */
|
||||
"key_space" = "space";
|
||||
|
||||
/* Up arrow key */
|
||||
"key_up" = "↑";
|
||||
|
||||
/* Down arrow key */
|
||||
"key_down" = "↓";
|
||||
|
||||
/* Left arrow key */
|
||||
"key_left" = "←";
|
||||
|
||||
/* Right arrow key */
|
||||
"key_right" = "→";
|
||||
|
||||
/* Shift and up arrow combo keys */
|
||||
"key_shift+up" = "shift + ↑";
|
||||
|
||||
/* Shift and down arrow combo keys */
|
||||
"key_shift+down" = "shift + ↓";
|
||||
|
||||
/* Backspace key */
|
||||
"key_backspace" = "backspace";
|
||||
|
||||
/* Hotkey to start a search */
|
||||
"hotkey_search" = "s";
|
||||
|
||||
/* Hotkey description to select next list item */
|
||||
"View next item" = "Sonraki görünüm";
|
||||
|
||||
/* Hotkey description to select previous list item */
|
||||
"View previous item" = "Önceki görünüm";
|
||||
|
||||
/* Hotkey description to add next list item to selection */
|
||||
"Add next item to selection" = "Sonraki maddeyi seçime ekle";
|
||||
|
||||
/* Hotkey description to add previous list item to selection */
|
||||
"Add previous item to selection" = "Önceki maddeyi seçime ekle";
|
||||
|
||||
/* Hotkey description to move backward in current view */
|
||||
"Move backward" = "Geriye taşı";
|
||||
|
||||
/* Hotkey description to move forward in current view */
|
||||
"Move forward" = "Öne taşı";
|
||||
@@ -73,7 +73,7 @@
|
||||
"New List" = "Nova Lista";
|
||||
"Edit" = "Editar";
|
||||
"Properties" = "Propriedades";
|
||||
"Sharing..." = "Localizando...";
|
||||
"Sharing..." = "Compartilhamento...";
|
||||
"Write" = "Escrever";
|
||||
"Delete" = "Apagar";
|
||||
"Instant Message" = "Mensagem Instantânea";
|
||||
@@ -199,10 +199,6 @@
|
||||
"Back" = "Voltar";
|
||||
"Select All" = "Selecionar Tudo";
|
||||
"Copy contacts" = "Copiar contatos";
|
||||
|
||||
/* Notification on the number of messages successfully copied */
|
||||
"%{0} cards copied" = "%{0} cartões copiados";
|
||||
|
||||
"More messages options" = "Mais opções de mensagens";
|
||||
"New Contact" = "Novo Contato";
|
||||
"Close" = "Fechar";
|
||||
|
||||
@@ -41,20 +41,28 @@
|
||||
"Move To" = "Move To";
|
||||
"Copy To" = "Copy To";
|
||||
"Add to" = "Add to";
|
||||
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "No contact";
|
||||
|
||||
/* Subheader of system addressbook */
|
||||
"Start a search to browse this address book" = "Start a search to browse this address book";
|
||||
|
||||
/* Number of contacts in addressbook; string is prefixed by number */
|
||||
"contacts" = "contacts";
|
||||
|
||||
/* No contact matching search criteria */
|
||||
"No matching contact" = "No matching contact";
|
||||
|
||||
/* Number of contacts matching search criteria; string is prefixed by number */
|
||||
"matching contacts" = "matching contacts";
|
||||
|
||||
/* Number of selected contacts in list */
|
||||
"selected" = "selected";
|
||||
|
||||
/* Empty right pane */
|
||||
"No contact selected" = "No contact selected";
|
||||
|
||||
/* Tooltips */
|
||||
"Create a new address book card" = "Create a new address book card";
|
||||
"Create a new list" = "Create a new list";
|
||||
@@ -95,9 +103,11 @@
|
||||
"Work" = "Work";
|
||||
"Mobile" = "Mobile";
|
||||
"Pager" = "Pager";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Colleague, Competitor, Customer, Friend, Family, Business Partner, Provider, Press, VIP";
|
||||
"New category" = "New category";
|
||||
|
||||
/* adresses */
|
||||
"Title" = "Title";
|
||||
"Service" = "Service";
|
||||
@@ -134,12 +144,14 @@
|
||||
= "You cannot remove nor unsubscribe from your personal addressbook.";
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Are you sure you want to delete the selected contacts?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "Are you sure you want to delete the card of %{0}?";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "You cannot delete the card of \"%{0}\".";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "You cannot subscribe to a folder that you own.";
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Unable to subscribe to that folder.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Access rights to";
|
||||
"For user" = "For user";
|
||||
@@ -158,11 +170,15 @@
|
||||
"The selected contact has no email address."
|
||||
= "The selected contact has no email address.";
|
||||
"Please select a contact." = "Please select a contact.";
|
||||
/* Error messages for move and copy */
|
||||
|
||||
/* Messages for move and copy */
|
||||
"%{0} card(s) copied" = "%{0} card(s) copied";
|
||||
"%{0} card(s) moved" = "%{0} card(s) moved";
|
||||
"SoAccessDeniedException" = "You cannot write to this address book.";
|
||||
"Forbidden" = "You cannot write to this address book.";
|
||||
"Invalid Contact" = "The selected contact no longer exists.";
|
||||
"Unknown Destination Folder" = "The chosen destination address book no longer exists.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "List details";
|
||||
"List name" = "List name";
|
||||
@@ -175,6 +191,8 @@
|
||||
"Export" = "Export";
|
||||
"Export Address Book..." = "Export Address Book...";
|
||||
"View Raw Source" = "View Raw Source";
|
||||
|
||||
/* Import */
|
||||
"Import Cards" = "Import Cards";
|
||||
"Select a vCard or LDIF file." = "Select a vCard or LDIF file.";
|
||||
"Upload" = "Upload";
|
||||
@@ -184,6 +202,7 @@
|
||||
"No card was imported." = "No card was imported.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "A total of %{0} cards were imported in the addressbook.";
|
||||
"Reload" = "Reload";
|
||||
|
||||
/* Properties window */
|
||||
"Address Book Name" = "Address Book Name";
|
||||
"Links to this Address Book" = "Links to this Address Book";
|
||||
@@ -230,4 +249,13 @@
|
||||
"Sucessfully subscribed to address book" = "Sucessfully subscribed to address book";
|
||||
|
||||
/* Aria label for scope of search on contacts */
|
||||
"Search scope" = "Search scope";
|
||||
"Search scope" = "Search scope";
|
||||
|
||||
/* Aria label for avatar button to select and unselect a card */
|
||||
"Toggle item" = "Toggle item";
|
||||
|
||||
/* Hotkey to create a new card */
|
||||
"key_create_card" = "c";
|
||||
|
||||
/* Hotkey to create a new list */
|
||||
"key_create_list" = "l";
|
||||
@@ -41,20 +41,28 @@
|
||||
"Move To" = "Déplacer vers";
|
||||
"Copy To" = "Copier vers";
|
||||
"Add to" = "Ajouter à";
|
||||
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "Aucun contact";
|
||||
|
||||
/* Subheader of system addressbook */
|
||||
"Start a search to browse this address book" = "Effectuez une recherche pour naviguer dans ce carnet";
|
||||
|
||||
/* Number of contacts in addressbook; string is prefixed by number */
|
||||
"contacts" = "contacts";
|
||||
|
||||
/* No contact matching search criteria */
|
||||
"No matching contact" = "Aucun contact retourné";
|
||||
|
||||
/* Number of contacts matching search criteria; string is prefixed by number */
|
||||
"matching contacts" = "contacts retournés";
|
||||
|
||||
/* Number of selected contacts in list */
|
||||
"selected" = "sélectionné(s)";
|
||||
|
||||
/* Empty right pane */
|
||||
"No contact selected" = "Aucun contact sélectionné";
|
||||
|
||||
/* Tooltips */
|
||||
"Create a new address book card" = "Créer une nouvelle fiche";
|
||||
"Create a new list" = "Créer une nouvelle liste de diffusion";
|
||||
@@ -95,9 +103,11 @@
|
||||
"Work" = "Travail";
|
||||
"Mobile" = "Portable";
|
||||
"Pager" = "Téléavertisseur";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Ami, Client, Collègue, Concurrent, Famille, Fournisseur, Partenaire d'affaire, Presse, VIP";
|
||||
"New category" = "Nouvelle catégorie";
|
||||
|
||||
/* adresses */
|
||||
"Title" = "Fonction ";
|
||||
"Service" = "Service";
|
||||
@@ -134,12 +144,14 @@
|
||||
= "Vous ne pouvez pas supprimer ni vous désabonner de votre carnet personnel.";
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Voulez-vous vraiment supprimer les contacts sélectionnés ?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "Voulez-vous vraiment supprimer la fiche de %{0}?";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "Vous ne pouvez pas supprimer la fiche de \"%{0}\".";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Vous ne pouvez pas vous inscrire à un dossier qui vous appartient.";
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Impossible de vous inscrire à ce dossier.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Droits d'accès à";
|
||||
"For user" = "Pour l'utilisateur";
|
||||
@@ -158,11 +170,15 @@
|
||||
"The selected contact has no email address."
|
||||
= "Cette personne n'a pas d'adresse courriel.";
|
||||
"Please select a contact." = "Veuillez sélectionner un contact.";
|
||||
/* Error messages for move and copy */
|
||||
|
||||
/* Messages for move and copy */
|
||||
"%{0} card(s) copied" = "%{0} fiche(s) copiée(s)";
|
||||
"%{0} card(s) moved" = "%{0} fiche(s) déplacée(s)";
|
||||
"SoAccessDeniedException" = "Vous ne pouvez pas ajouter de fiches à ce carnet.";
|
||||
"Forbidden" = "Vous ne pouvez pas ajouter de fiches à ce carnet.";
|
||||
"Invalid Contact" = "La fiche sélectionnée n'existe plus.";
|
||||
"Unknown Destination Folder" = "Le carnet d'adresses choisi n'existe plus.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "Détails";
|
||||
"List name" = "Liste";
|
||||
@@ -175,6 +191,8 @@
|
||||
"Export" = "Exporter";
|
||||
"Export Address Book..." = "Exporter le carnet d'adresses...";
|
||||
"View Raw Source" = "Afficher le contenu original";
|
||||
|
||||
/* Import */
|
||||
"Import Cards" = "Importer des contacts";
|
||||
"Select a vCard or LDIF file." = "Sélectionner un fichier LDIF ou vCard.";
|
||||
"Upload" = "Ajouter";
|
||||
@@ -184,6 +202,7 @@
|
||||
"No card was imported." = "Aucun contact n'a été importé.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "Un total de %{0} contacts ont été importés dans le carnet.";
|
||||
"Reload" = "Actualiser";
|
||||
|
||||
/* Properties window */
|
||||
"Address Book Name" = "Nom";
|
||||
"Links to this Address Book" = "Liens vers ce carnet";
|
||||
@@ -230,4 +249,13 @@
|
||||
"Sucessfully subscribed to address book" = "Abonnement au carnet d'adresses complété";
|
||||
|
||||
/* Aria label for scope of search on contacts */
|
||||
"Search scope" = "Étendue de la recherche";
|
||||
"Search scope" = "Étendue de la recherche";
|
||||
|
||||
/* Aria label for avatar button to select and unselect a card */
|
||||
"Toggle item" = "Basculer la sélection";
|
||||
|
||||
/* Hotkey to create a new card */
|
||||
"key_create_card" = "c";
|
||||
|
||||
/* Hotkey to create a new list */
|
||||
"key_create_list" = "l";
|
||||
@@ -38,8 +38,8 @@
|
||||
"invalidemailwarn" = "A megadott email cím érvénytelen";
|
||||
"new" = "új";
|
||||
"Preferred Phone" = "Preferált telefon";
|
||||
"Move To" = "Move To";
|
||||
"Copy To" = "Copy To";
|
||||
"Move To" = "Áthelyezés";
|
||||
"Copy To" = "Másolás";
|
||||
"Add to" = "Add to";
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "Nincs kapcsolat";
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/* this file is in UTF-8 format! */
|
||||
|
||||
"Contact" = "Контакт";
|
||||
"Address" = "Адреса";
|
||||
"Photos" = "Слике";
|
||||
"Other" = "Друго";
|
||||
"Address Books" = "Адресари";
|
||||
"Addressbook" = "Адресар";
|
||||
"Addresses" = "Адресе";
|
||||
"Update" = "Ажурирај";
|
||||
"Cancel" = "Откажи";
|
||||
"Common" = "Опште";
|
||||
"Contact editor" = "Уређивач контакта";
|
||||
"Contact viewer" = "Прегледач контакта";
|
||||
"Email" = "Епошта";
|
||||
"Screen Name" = "Надимак";
|
||||
"Extended" = "Продужен";
|
||||
"Fax" = "Факс";
|
||||
"Firstname" = "Име";
|
||||
"Home" = "Кућа";
|
||||
"HomePhone" = "Кућни телефон";
|
||||
"Lastname" = "Презиме";
|
||||
"Location" = "Локација";
|
||||
"Add a category" = "Додај категорију";
|
||||
"MobilePhone" = "Мобилни телефон";
|
||||
"Name" = "Име";
|
||||
"OfficePhone" = "Канцеларијски телефон";
|
||||
"Organization" = "Организација";
|
||||
"Work Phone" = "Пословни телефон";
|
||||
"Phone" = "Телефон";
|
||||
"Phones" = "Телефони";
|
||||
"Postal" = "Поштански";
|
||||
"Save" = "Сачувај";
|
||||
"Internet" = "Интернет";
|
||||
"Unit" = "Јединица";
|
||||
"delete" = "обриши";
|
||||
"edit" = "измени";
|
||||
"invalidemailwarn" = "Наведена епошта је неважећа";
|
||||
"new" = "нов";
|
||||
"Preferred Phone" = "Преферирани телефон";
|
||||
"Move To" = "Премести у";
|
||||
"Copy To" = "Копирај у";
|
||||
"Add to" = "Додај у";
|
||||
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "Нема контакта";
|
||||
|
||||
/* Subheader of system addressbook */
|
||||
"Start a search to browse this address book" = "Започни претрагу да прегледаш овај адресар";
|
||||
|
||||
/* Number of contacts in addressbook; string is prefixed by number */
|
||||
"contacts" = "контакти";
|
||||
|
||||
/* No contact matching search criteria */
|
||||
"No matching contact" = "Нема подаударајућег контакта";
|
||||
|
||||
/* Number of contacts matching search criteria; string is prefixed by number */
|
||||
"matching contacts" = "подударајући контакти";
|
||||
|
||||
/* Number of selected contacts in list */
|
||||
"selected" = "изабрани";
|
||||
|
||||
/* Empty right pane */
|
||||
"No contact selected" = "Нема изабраног контакта";
|
||||
|
||||
/* Tooltips */
|
||||
"Create a new address book card" = "Креирај нови адресну картицу";
|
||||
"Create a new list" = "Креирај нову листу";
|
||||
"Edit the selected card" = "Измени одабрану картицу";
|
||||
"Send a mail message" = "Пошаљи поштанску поруку";
|
||||
"Delete selected card or address book" = "Обриши изабрану картицу или адресар";
|
||||
"Reload all contacts" = "Учитај поново све контакте";
|
||||
"htmlMailFormat_UNKNOWN" = "Непознат";
|
||||
"htmlMailFormat_FALSE" = "Обичан текст";
|
||||
"htmlMailFormat_TRUE" = "ХТМЛ";
|
||||
"Name or Email" = "Име или Епошта";
|
||||
"Category" = "Категорија";
|
||||
"Personal Addressbook" = "Лични адресар";
|
||||
"Search in Addressbook" = "Потражи у адресару";
|
||||
"New Card" = "Нова картица";
|
||||
"New List" = "Нова листа";
|
||||
"Edit" = "Измени";
|
||||
"Properties" = "Својства";
|
||||
"Sharing..." = "Дељење...";
|
||||
"Write" = "Писање";
|
||||
"Delete" = "Обриши";
|
||||
"Instant Message" = "Брза порука";
|
||||
"Add..." = "Додај...";
|
||||
"Remove" = "Уклони";
|
||||
"Please wait..." = "Молимо сачекајте...";
|
||||
"No possible subscription" = "Не постоји могућа претплата";
|
||||
"Preferred" = "Префериран";
|
||||
"Display" = "Прикажи";
|
||||
"Display Name" = "Прикажи име";
|
||||
"Additional Email" = "Додатна епошта";
|
||||
"Phone Number" = "Телефонски број";
|
||||
"Prefers to receive messages formatted as" = "Преферира да прима поруке форматиране као";
|
||||
"Categories" = "Категорије";
|
||||
"First" = "Први";
|
||||
"Last" = "Последњи";
|
||||
"Nickname" = "Надимак";
|
||||
"Telephone" = "Телефон";
|
||||
"Work" = "Посао";
|
||||
"Mobile" = "Мобилни";
|
||||
"Pager" = "Пејџер";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Колега, Конкурент, Клијент, Пријатељ, Породица, Пословни Партнер, Провајдер, Новинар, ВИП";
|
||||
"New category" = "Нова категорија";
|
||||
|
||||
/* adresses */
|
||||
"Title" = "Наслов";
|
||||
"Service" = "Сервис";
|
||||
"Company" = "Компанија";
|
||||
"Department" = "Одељење";
|
||||
"City" = "Град";
|
||||
"State_Province" = "Држава/Провинција";
|
||||
"ZIP_Postal Code" = "ЗИП/Поштански број";
|
||||
"Country" = "Земља";
|
||||
"Web Page" = "Интернет страница";
|
||||
"Other Infos" = "Остале информације";
|
||||
"Note" = "Забелешка";
|
||||
"Timezone" = "Временска зона";
|
||||
"Birthday" = "Рођендан";
|
||||
"Birthday (yyyy-mm-dd)" = "Рођендан (гггг-мм-дд)";
|
||||
"Freebusy URL" = "Линк Заузет/Слободан";
|
||||
"Add as..." = "Додај као...";
|
||||
"Recipient" = "Прималац";
|
||||
"Carbon Copy" = "Карбон копи";
|
||||
"Blind Carbon Copy" = "Скривена карбон копија";
|
||||
"New Addressbook..." = "Нови адресар...";
|
||||
"Subscribe to an Addressbook..." = "Претплати се на Адресар...";
|
||||
"Remove the selected Addressbook" = "Уклони одабрани адресар";
|
||||
"Subscribe to a shared folder" = "Претплати се на дељени директоријум";
|
||||
"Search User" = "Потражи корисника";
|
||||
"Name of the Address Book" = "Име адресара";
|
||||
"Are you sure you want to delete the selected address book?"
|
||||
= "Да ли сте сигурни да желите да обришете одабрани адресар?";
|
||||
"Are you sure you want to delete the addressbook \"%{0}\"?"
|
||||
= "Да ли сте сигурни да желите да обришете адресар \"%{0}\"?";
|
||||
"You cannot remove nor unsubscribe from a public addressbook."
|
||||
= "Не можете уклонити нити се одјавити са јавног адресара.";
|
||||
"You cannot remove nor unsubscribe from your personal addressbook."
|
||||
= "Не можете уклонити нити се одјавити из вашег личног адресара.";
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Да ли сте сигурни да желите да обришете одабране контакте?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "Да ли сте сигурни да желите да обришете картицу \"%{0}\"?";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "Не можете обрисати картицу \"%{0}\".";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Не можете се претплатити на директорјиум чији сте власник.";
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Не могу да се претплатим на овај директоријум.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Права приступа у";
|
||||
"For user" = "За корисника";
|
||||
"Any Authenticated User" = "Било који аутентификовани корисник";
|
||||
"Public Access" = "Јавни приступ";
|
||||
"This person can add cards to this addressbook."
|
||||
= "Ова особа може додати картице у овај адресар.";
|
||||
"This person can edit the cards of this addressbook."
|
||||
= "Ова особа може мењати картице у овом адресару.";
|
||||
"This person can list the content of this addressbook."
|
||||
= "Ова особа може прегледати садржај овог адресара.";
|
||||
"This person can read the cards of this addressbook."
|
||||
= "Ова особа може читати картице из овог адресара.";
|
||||
"This person can erase cards from this addressbook."
|
||||
= "Ова особа може брисати картице из овог адресара.";
|
||||
"The selected contact has no email address."
|
||||
= "Одабрани контакт нема адресу епоште.";
|
||||
"Please select a contact." = "Молимо одаберите контакт.";
|
||||
|
||||
/* Messages for move and copy */
|
||||
"%{0} card(s) copied" = "%{0} картица(е) прекопирано";
|
||||
"%{0} card(s) moved" = "%{0} картица(е) премештено";
|
||||
"SoAccessDeniedException" = "Не можете писати у овај адресар.";
|
||||
"Forbidden" = "Не можете писати у овај адресар.";
|
||||
"Invalid Contact" = "Одабрани контакт више не постоји.";
|
||||
"Unknown Destination Folder" = "Одабрани адресар више не постоји.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "Прикажи детаље";
|
||||
"List name" = "Прикажи име";
|
||||
"List nickname" = "Прикажи надимак";
|
||||
"List description" = "Прикажи опис";
|
||||
"Members" = "Чланови";
|
||||
"Contacts" = "Контакти";
|
||||
"Add" = "Додај";
|
||||
"Lists can't be moved or copied." = "Листе не могу бити премештене или копиране.";
|
||||
"Export" = "Извези";
|
||||
"Export Address Book..." = "Извези адресар...";
|
||||
"View Raw Source" = "Погледај извнорни код";
|
||||
|
||||
/* Import */
|
||||
"Import Cards" = "Увези картице";
|
||||
"Select a vCard or LDIF file." = "Одабери vCard или LDIF датотеку.";
|
||||
"Upload" = "Отпреми";
|
||||
"Uploading" = "Отпремање";
|
||||
"Done" = "Урађено";
|
||||
"An error occured while importing contacts." = "Догодила се грешка при увозу контаката.";
|
||||
"No card was imported." = "Нису увезене картице.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "Укупно %{0} картица је увезено у адресар.";
|
||||
"Reload" = "Поново учитај";
|
||||
|
||||
/* Properties window */
|
||||
"Address Book Name" = "Име адресара";
|
||||
"Links to this Address Book" = "Линкови ка овом адресару";
|
||||
"Authenticated User Access" = "Приступ аутентификованим корисницима";
|
||||
"CardDAV URL" = "CardDAV линк";
|
||||
"Options" = "Опције";
|
||||
"Rename" = "Преименуј";
|
||||
"Subscriptions" = "Претплате";
|
||||
"Global Addressbooks" = "Глобални адресари";
|
||||
"Search" = "Претражи";
|
||||
"Sort" = "Поређај";
|
||||
"Descending Order" = "Опадајући ред";
|
||||
"Back" = "Назад";
|
||||
"Select All" = "Одабери све";
|
||||
"Copy contacts" = "Копирај контакте";
|
||||
"More messages options" = "Више опција порука";
|
||||
"New Contact" = "Нови контакт";
|
||||
"Close" = "Затвори";
|
||||
"More contact options" = "Више опција контакта";
|
||||
"Organization Unit" = "Организациона јединица";
|
||||
"Add Organizational Unit" = "Додај организациону јединицу";
|
||||
"Type" = "Тип";
|
||||
"Email Address" = "Адреса епоште";
|
||||
"New Email Address" = "Нова дреса епоште";
|
||||
"New Phone Number" = "Нови телефонски број";
|
||||
"URL" = "Линк";
|
||||
"New URL" = "Нови линк";
|
||||
"street" = "улица";
|
||||
"Postoffice" = "Пошта";
|
||||
"Region" = "Регион";
|
||||
"Postal Code" = "Поштански број";
|
||||
"New Address" = "Нова адреса";
|
||||
"Reset" = "Врати на подразумевано";
|
||||
"Description" = "Опис";
|
||||
"Add Member" = "Додај члана";
|
||||
"Subscribe" = "Пртплати се";
|
||||
"Add Birthday" = "Додај рођендан";
|
||||
"Import" = "Увези";
|
||||
"More options" = "Више опција";
|
||||
"Role" = "Улога";
|
||||
"Add Screen Name" = "Додај надимак";
|
||||
"Synchronization" = "Синхронизација";
|
||||
"Synchronize" = "Синхронизуј";
|
||||
"Sucessfully subscribed to address book" = "Успешно претплаћен на адресар";
|
||||
|
||||
/* Aria label for scope of search on contacts */
|
||||
"Search scope" = "Претражи опсег";
|
||||
|
||||
/* Aria label for avatar button to select and unselect a card */
|
||||
"Toggle item" = "Искључи ставку";
|
||||
@@ -23,7 +23,7 @@
|
||||
"Location" = "Konum";
|
||||
"Add a category" = "Bir kategori ekle";
|
||||
"MobilePhone" = "CepTelefonu";
|
||||
"Name" = "Ad ve Soyad";
|
||||
"Name" = "İsim";
|
||||
"OfficePhone" = "OfisTelefonu";
|
||||
"Organization" = "Organizasyon";
|
||||
"Work Phone" = "İş Telefonu";
|
||||
@@ -39,33 +39,41 @@
|
||||
"new" = "yeni";
|
||||
"Preferred Phone" = "Tercih Edilen Telefon";
|
||||
"Move To" = "Taşı";
|
||||
"Copy To" = "Şuraya Kopyala";
|
||||
"Add to" = "Şuraya Ekle";
|
||||
"Copy To" = "Kopyala";
|
||||
"Add to" = "Ekle";
|
||||
|
||||
/* Subheader of empty addressbook */
|
||||
"No contact" = "Adres defteri boş";
|
||||
|
||||
/* Subheader of system addressbook */
|
||||
"Start a search to browse this address book" = "Bu adres defterini taramak için bir arama başlatın";
|
||||
|
||||
/* Number of contacts in addressbook; string is prefixed by number */
|
||||
"contacts" = "kişi";
|
||||
|
||||
/* No contact matching search criteria */
|
||||
"No matching contact" = "Eşleşen kişi yok";
|
||||
"No matching contact" = "Eşleşen bir kişi yok";
|
||||
|
||||
/* Number of contacts matching search criteria; string is prefixed by number */
|
||||
"matching contacts" = "eşleşen kişiler";
|
||||
|
||||
/* Number of selected contacts in list */
|
||||
"selected" = "seçili";
|
||||
|
||||
/* Empty right pane */
|
||||
"No contact selected" = "Seçili bir kişi yok";
|
||||
|
||||
/* Tooltips */
|
||||
"Create a new address book card" = "Yeni adres defteri kartı oluştur";
|
||||
"Create a new list" = "Yeni liste oluştu";
|
||||
"Create a new address book card" = "Yeni adres kartı oluştur";
|
||||
"Create a new list" = "Yeni liste oluştur";
|
||||
"Edit the selected card" = "Seçili kartı düzenle";
|
||||
"Send a mail message" = "Bir e-posta iletisi gönder";
|
||||
"Delete selected card or address book" = "Seçili kartı veya adres defterini sil";
|
||||
"Reload all contacts" = "Tüm kişileri tazele";
|
||||
"Reload all contacts" = "Adresleri tazele";
|
||||
"htmlMailFormat_UNKNOWN" = "Bilinmiyor";
|
||||
"htmlMailFormat_FALSE" = "Düz Metin";
|
||||
"htmlMailFormat_TRUE" = "HTML";
|
||||
"Name or Email" = "Ad Soyad veya E-posta";
|
||||
"Name or Email" = "İsim veya E-posta";
|
||||
"Category" = "Kategori";
|
||||
"Personal Addressbook" = "Kişisel Adres Defteri";
|
||||
"Search in Addressbook" = "Adres Defterinde Ara";
|
||||
@@ -82,12 +90,12 @@
|
||||
"Please wait..." = "Lütfen bekleyin...";
|
||||
"No possible subscription" = "Mümkün olan bir üyelik yok";
|
||||
"Preferred" = "Tercih edilen";
|
||||
"Display" = "Görünen";
|
||||
"Display" = "Görünen İsim";
|
||||
"Display Name" = "Görünen İsim";
|
||||
"Additional Email" = "Diğer E-posta";
|
||||
"Phone Number" = "Telefon Numarası";
|
||||
"Prefers to receive messages formatted as" = "Almayı tercih ettiği ileti formatı";
|
||||
"Categories" = "Kategoriler";
|
||||
"Categories" = "Kategori";
|
||||
"First" = "İlk";
|
||||
"Last" = "Son";
|
||||
"Nickname" = "Takma ad";
|
||||
@@ -95,9 +103,11 @@
|
||||
"Work" = "İş";
|
||||
"Mobile" = "Cep";
|
||||
"Pager" = "Çağrı cihazı";
|
||||
|
||||
/* categories */
|
||||
"contacts_category_labels" = "Meslektaş, Rakip, Müşteri, Arkadaş, Aile, İş Ortağı, Tedarikçi, Basın, VIP";
|
||||
"New category" = "Yeni kategori";
|
||||
|
||||
/* adresses */
|
||||
"Title" = "Ünvan";
|
||||
"Service" = "Servis";
|
||||
@@ -134,14 +144,16 @@
|
||||
= "Kişisel adres defterinizden çıkamaz ve üyeliğinizi kaldıramazsınız.";
|
||||
"Are you sure you want to delete the selected contacts?"
|
||||
= "Seçili kişileri silmek istediğinizden emin misiniz?";
|
||||
"Are you sure you want to delete the card of %{0}?" = "%{0} kartını silmek istediğinizden emin misiniz?";
|
||||
"You cannot delete the card of \"%{0}\"."
|
||||
= "\"%{0}\" kartını silemezsiniz.";
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "Size ait bir klasöre üye olamazsınız.";
|
||||
"Unable to subscribe to that folder!"
|
||||
= "Bu klasöre üye olunamıyor.";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Aşağıdaki adres defterine erişim yetkileri";
|
||||
"Access rights to" = "Adres defterinin erişim yetkileri";
|
||||
"For user" = "Aşağıdaki kullanıcı için";
|
||||
"Any Authenticated User" = "Kimliği doğrulanmış her kullanıcı";
|
||||
"Public Access" = "Herkese Açık Erişim";
|
||||
@@ -158,32 +170,39 @@
|
||||
"The selected contact has no email address."
|
||||
= "Seçili kişinin e-posta adresi yok.";
|
||||
"Please select a contact." = "Lütfen bir kişi seçin.";
|
||||
/* Error messages for move and copy */
|
||||
|
||||
/* Messages for move and copy */
|
||||
"%{0} card(s) copied" = "%{0} kart kopyalandı";
|
||||
"%{0} card(s) moved" = "%{0} kart taşındı";
|
||||
"SoAccessDeniedException" = "Bu adres defterine yazamazsınız.";
|
||||
"Forbidden" = "Bu adres defterine yazamazsınız.";
|
||||
"Invalid Contact" = "Seçili kişi artık mevcut değil.";
|
||||
"Unknown Destination Folder" = "Seçilen hedef adres defteri artık mevcut değil.";
|
||||
|
||||
/* Lists */
|
||||
"List details" = "Ayrıntıları listele";
|
||||
"List name" = "Liste adı";
|
||||
"List nickname" = "Listenin takma adı";
|
||||
"List nickname" = "Liste takma adı";
|
||||
"List description" = "Liste tanımı";
|
||||
"Members" = "Üyeler";
|
||||
"Contacts" = "Kişiler";
|
||||
"Contacts" = "Adresler";
|
||||
"Add" = "Ekle";
|
||||
"Lists can't be moved or copied." = "Listeler taşınamaz ve kopyalanamaz.";
|
||||
"Export" = "Dışarı Aktar";
|
||||
"Export Address Book..." = "Adres Defterini Dışarı Aktar...";
|
||||
"View Raw Source" = "Kaynak Kodunu Görüntüle";
|
||||
|
||||
/* Import */
|
||||
"Import Cards" = "Kartları İçeri Aktar";
|
||||
"Select a vCard or LDIF file." = "Bir vCard veya LDIF dosyası seçin.";
|
||||
"Upload" = "Yükle";
|
||||
"Uploading" = "Yükleniyor";
|
||||
"Done" = "Tamam";
|
||||
"An error occured while importing contacts." = "Kişileri içeri aktarırken bir hata oluştu.";
|
||||
"An error occured while importing contacts." = "Adresleri içeri aktarırken bir hata oluştu.";
|
||||
"No card was imported." = "Hiç bir kart içeri aktarılmadı.";
|
||||
"A total of %{0} cards were imported in the addressbook." = "Toplam %{0} kart adres defterinine aktarıldı.";
|
||||
"Reload" = "Tazele";
|
||||
|
||||
/* Properties window */
|
||||
"Address Book Name" = "Adres Defteri Adı";
|
||||
"Links to this Address Book" = "Adres Defteri Bağlantıları";
|
||||
@@ -230,4 +249,13 @@
|
||||
"Sucessfully subscribed to address book" = "Adres defterine başarıyla abone";
|
||||
|
||||
/* Aria label for scope of search on contacts */
|
||||
"Search scope" = "Arama kapsamı";
|
||||
"Search scope" = "Arama kapsamı";
|
||||
|
||||
/* Aria label for avatar button to select and unselect a card */
|
||||
"Toggle item" = "Ögede Geçiş Yap";
|
||||
|
||||
/* Hotkey to create a new card */
|
||||
"key_create_card" = "c";
|
||||
|
||||
/* Hotkey to create a new list */
|
||||
"key_create_list" = "l";
|
||||
@@ -0,0 +1,50 @@
|
||||
ACCEPTED = "прихваћено";
|
||||
COMPLETED = "завршено";
|
||||
DECLINED = "одбијено";
|
||||
DELEGATED = "делегирано";
|
||||
"IN-PROCESS" = "у току";
|
||||
"NEEDS-ACTION" = "потребна акција";
|
||||
TENTATIVE = "на чекању";
|
||||
organized_by_you = "ви сте организатор";
|
||||
you_are_an_attendee = "ви сте полазник";
|
||||
add_info_text = "iMIP 'ADD' још увек није подржан у SOGo-у.";
|
||||
publish_info_text = "Пошиљалац вас обавештава о догађају у прилогу.";
|
||||
cancel_info_text = "Ваша позивница или комплетан догађај је отказан.";
|
||||
request_info_no_attendee = "предлаже састанак полазницима. Примили сте пошту као обавештење, нисте у распореду као учесник.";
|
||||
Appointment = "Састанак";
|
||||
"Status Update" = "Ажуриран статус";
|
||||
was = "је био";
|
||||
|
||||
Organizer = "Организатор";
|
||||
Time = "Време";
|
||||
Attendees = "Полазници";
|
||||
request_info = "вас позива да учествујете на састанку.";
|
||||
"Add to calendar" = "Додај у календар.";
|
||||
"Delete from calendar" = "Обриши из календара.";
|
||||
"Update status" = "Ажурирај статус";
|
||||
Accept = "Прихвати";
|
||||
Decline = "Одбиј";
|
||||
Tentative = "На чекању";
|
||||
"Delegate ..." = "Делегирај...";
|
||||
"Delegated to" = "Делегирај";
|
||||
"Update status in calendar" = "Ажурирај статус у календару";
|
||||
"delegated from" = "делегирај од";
|
||||
reply_info_no_attendee = "Добили сте одговор на заказани догађај али пошиљалац одговора није и полазник.";
|
||||
reply_info = "Овај одговор на позивницу за догађај је ваш.";
|
||||
"to" = "за";
|
||||
"Untitled" = "Без наслова";
|
||||
"Size" = "Величина";
|
||||
"Digital signature is not valid" = "Дгитални потпис није валидан";
|
||||
"Message is signed" = "Порука је потписана";
|
||||
"Subject" = "Тема";
|
||||
"From" = "Од";
|
||||
"Date" = "Датум";
|
||||
"To" = "За";
|
||||
"Issuer" = "Издавач";
|
||||
/* Tooltips */
|
||||
"View Attachment" = "Види прилог";
|
||||
"Save Attachment" = "Сачувај прилог";
|
||||
"CC" = "ЦЦ";
|
||||
"Cancel" = "Откажи";
|
||||
"OK" = "У реду";
|
||||
"Comment" = "Коментар";
|
||||
@@ -9,9 +9,9 @@ organized_by_you = "tarafınızdan düzenlendi";
|
||||
you_are_an_attendee = "siz bir katılımcısınız";
|
||||
add_info_text = "iMIP 'ADD' istekleri SOGo tarafından henüz desteklenmiyor.";
|
||||
publish_info_text = "Gönderici sizi ekteki etkinlik hakında bilgilendiriyor.";
|
||||
cancel_info_text = "Davetiniz veya tüm etkinlik iptal edildi.";
|
||||
cancel_info_text = "Sizin davetiniz veya tüm etkinlik iptal edildi.";
|
||||
request_info_no_attendee = "katılımcılara bir toplantı teklif ediyor. Bu iletiyi bilgilendirme amacıyla aldınız, siz iştirakçi olarak eklenmediniz.";
|
||||
Appointment = "Buluşma";
|
||||
Appointment = "Randevu";
|
||||
"Status Update" = "Durum Güncellemesi";
|
||||
was = "önceden";
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
"Body" = "Corpo";
|
||||
"Open" = "Abrir";
|
||||
"Select All" = "Selecionar Tudo";
|
||||
"Select Message" = "Selecionar Mensagem";
|
||||
"Attach Web Page..." = "Anexar Página Web...";
|
||||
"file" = "arquivo";
|
||||
"files" = "arquivos";
|
||||
@@ -156,7 +157,7 @@
|
||||
/* Tree */
|
||||
"SentFolderName" = "Enviados";
|
||||
"TrashFolderName" = "Lixeira";
|
||||
"InboxFolderName" = "Entrada";
|
||||
"InboxFolderName" = "Caixa de Entrada";
|
||||
"DraftsFolderName" = "Rascunhos";
|
||||
"JunkFolderName" = "Lixo Eletrônico";
|
||||
"SieveFolderName" = "Filtros";
|
||||
@@ -266,10 +267,17 @@
|
||||
"Operation failed" = "Falha na Operação";
|
||||
"Quota" = "Quota:";
|
||||
"quotasFormat" = "%{0}% usado em %{1} MB";
|
||||
"Unable to move/delete folder." = "Não foi possível mover/deletar esta pasta";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Tem certeza que quer excluir a mensagem selecionada?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} mensagem(ns) copiadas";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} mensagem(ns) movidas";
|
||||
|
||||
"Please select a message." = "Por favor, selecione uma mensagem.";
|
||||
"Please select a message to print." = "Por favor, selecione a mensagem para imprimir.";
|
||||
"Please select only one message to print." = "Por favor, selecione somente uma mensagem para imprimir.";
|
||||
@@ -304,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Erro ao carregar o arquivo \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Este arquivo está sendo carregado. Fechando a janela irá interromper o processo.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Enviando";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Enviado";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Não é possível enviar a mensagem: todos os destinatários são inválidos.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Não é possível enviar a mensagem. Os seguintes endereços estão inválidos";
|
||||
"cannot send message: (smtp) error when connecting" = "Não é possível enviar a mensagem: erro ao conectar ao servidor SMTP.";
|
||||
@@ -321,7 +334,7 @@
|
||||
"No" = "No";
|
||||
"Location" = "Localização";
|
||||
"Rename" = "Renomear";
|
||||
"Compact" = "Compacto";
|
||||
"Compact" = "Compactar";
|
||||
"Export" = "Exportar";
|
||||
"Set as Drafts" = "Definir como Rascunho";
|
||||
"Set as Sent" = "Definir como Enviado";
|
||||
@@ -348,4 +361,10 @@
|
||||
"Folder compacted" = "Pasta compactada";
|
||||
|
||||
/* Aria label for scope of search on messages */
|
||||
"Search scope" = "Escopo de pesquisa";
|
||||
"Search scope" = "Escopo de pesquisa";
|
||||
|
||||
/* Subscriptions Dialog */
|
||||
"Manage Subscriptions" = "Gerenciar Inscrições";
|
||||
|
||||
/* Hotkey to write a new message */
|
||||
"hotkey_compose" = "w";
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Operation failed";
|
||||
"Quota" = "Quota:";
|
||||
"quotasFormat" = "%{0}% used on %{1} MB";
|
||||
"Unable to move/delete folder." = "Unable to move/delete folder.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Are you sure you want to delete the selected messages?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} message(s) copied";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} message(s) moved";
|
||||
|
||||
"Please select a message." = "Please select a message.";
|
||||
"Please select a message to print." = "Please select a message to print.";
|
||||
"Please select only one message to print." = "Please select only one message to print.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Error while uploading the file \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "There is an active file upload. Closing the window will interrupt it.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Sending";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Sent";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Cannot send message: all recipients are invalid.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Cannot send message. The following addresses are invalid";
|
||||
"cannot send message: (smtp) error when connecting" = "Cannot send message: error when connecting to the SMTP server.";
|
||||
@@ -332,6 +344,7 @@
|
||||
"Set as Junk" = "Set as Junk";
|
||||
|
||||
"Sort" = "Sort";
|
||||
"Order Received" = "Order Received";
|
||||
"Descending Order" = "Descending Order";
|
||||
"Back" = "Back";
|
||||
"Copy messages" = "Copy messages";
|
||||
@@ -349,4 +362,10 @@
|
||||
"Folder compacted" = "Folder compacted";
|
||||
|
||||
/* Aria label for scope of search on messages */
|
||||
"Search scope" = "Search scope";
|
||||
"Search scope" = "Search scope";
|
||||
|
||||
/* Subscriptions Dialog */
|
||||
"Manage Subscriptions" = "Manage Subscriptions";
|
||||
|
||||
/* Hotkey to write a new message */
|
||||
"hotkey_compose" = "w";
|
||||
@@ -141,7 +141,7 @@
|
||||
"Date" = "Päiväys";
|
||||
"View" = "Näytä";
|
||||
"All" = "Kaikki";
|
||||
"No message" = "Ei viestiä";
|
||||
"No message" = "Ei viestejä";
|
||||
"messages" = "viestit";
|
||||
"Yesterday" = "Eilen";
|
||||
"first" = "Ensimmäinen";
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Toiminto epäonnistui";
|
||||
"Quota" = "Kokorajoitus:";
|
||||
"quotasFormat" = "%{0}% käytetty %{1} Mt:sta";
|
||||
"Unable to move/delete folder." = "Hakemiston siirto/poisto ei onnistu.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Haluatko varmasti poistaa valitut viestit?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} viesti(ä) kopioitu";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} viesti(ä) siirretty";
|
||||
|
||||
"Please select a message." = "Ole hyvä ja valitse viesti.";
|
||||
"Please select a message to print." = "Ole hyvä ja valitse tulostettava viesti.";
|
||||
"Please select only one message to print." = "Ole hyvä ja valitse vain yksi viesti tulostettavaksi.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Virhe tiedoston \"%{0}\" latauksessa: ";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Tiedoston lataus on käynnissä. Ikkunan sulkeminen pysäyttää latauksen.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Lähettää";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Lähetetty";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Viestiä ei voi lähettää: kaikki vastaanottajat ovat virheellisiä.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Viestiä ei voi lähettää: seuraavat osoitteet ovat virheellisiä";
|
||||
"cannot send message: (smtp) error when connecting" = "Viestiä ei voi lähettää: virhe yhdistettäessä SMTP -palvelimeen.";
|
||||
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "L'opération a échoué.";
|
||||
"Quota" = "Quota";
|
||||
"quotasFormat" = "%{0}% utilisé sur %{1} MO";
|
||||
"Unable to move/delete folder." = "Impossible de déplacer ou supprimer le dossier.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Voulez-vous vraiment supprimer les messages sélectionnés?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} message(s) copié(s)";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} message(s) déplacé(s)";
|
||||
|
||||
"Please select a message." = "Veuillez sélectionner un message.";
|
||||
"Please select a message to print." = "Veuillez sélectionner un message à imprimer.";
|
||||
"Please select only one message to print." = "Veuillez ne sélectionner qu'un seul message à imprimer.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Une erreur est survenue lors du téléversement du fichier « %{0} » :";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Un transfert est actif. La fermeture de la fenêtre causera son interruption.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Envoi en cours";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Envoyé";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Le message n'a pas pu être envoyé car aucune adresse n'est valide.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Le message n'a pas pu être envoyé car les adresses suivantes sont invalides";
|
||||
"cannot send message: (smtp) error when connecting" = "Le message n'a pas pu être envoyé: une erreur est survenue en tentant de rejoindre le serveur SMTP.";
|
||||
@@ -349,4 +361,10 @@
|
||||
"Folder compacted" = "Dossier compressé";
|
||||
|
||||
/* Aria label for scope of search on messages */
|
||||
"Search scope" = "Étendue de la recherche";
|
||||
"Search scope" = "Étendue de la recherche";
|
||||
|
||||
/* Subscriptions Dialog */
|
||||
"Manage Subscriptions" = "Abonnements";
|
||||
|
||||
/* Hotkey to write a new message */
|
||||
"hotkey_compose" = "w";
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Operation fehlgeschlagen.";
|
||||
"Quota" = "Quota:";
|
||||
"quotasFormat" = "%{0}% von %{1} MB verwendet";
|
||||
"Unable to move/delete folder." = "Kann den Ordner nicht verschieben/löschen.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Wollen Sie wirklich die ausgewählten Nachrichten löschen?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} Nachrichten kopiert";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} Nachrichten verschoben";
|
||||
|
||||
"Please select a message." = "Sie müssen eine Nachricht auswählen.";
|
||||
"Please select a message to print." = "Sie müssen eine Nachricht zum Drucken auswählen.";
|
||||
"Please select only one message to print." = "Bitte wählen Sie nur eine Nachricht zum Drucken aus.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Fehler beim Hochladen der Datei \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Es wird gerade eine Datei hochgeladen. Das Schließen des Fensters wird dies abbrechen.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Sende";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Gesendet";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Kann Nachricht nicht versenden: Alle Empfänger sind ungültig.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Kann Nachricht nicht versenden: Die folgenden Adressen sind ungültig";
|
||||
"cannot send message: (smtp) error when connecting" = "Kann Nachricht nicht versenden: Fehler beim Verbinden mit dem SMTP-Server.";
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
"Thread As Read" = "Olvasott témacsoportonként";
|
||||
"As Read By Date..." = "Olvasás dátuma szerint...";
|
||||
"All Read" = "Mindet olvasottként";
|
||||
"Flag" = "Csillagozottként";
|
||||
"Flag" = "Csillag hozzáadása";
|
||||
"As Junk" = "Szemétként";
|
||||
"As Not Junk" = "Nem szemétként";
|
||||
"Run Junk Mail Controls" = "Levélszemétgyűjtő futtatása";
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "A művelet megszakadt";
|
||||
"Quota" = "Tárhely:";
|
||||
"quotasFormat" = "Felhasznált: %{0}%,összes: %{1} MB";
|
||||
"Unable to move/delete folder." = "Nem lehet mappát átmozgatni/törölni .";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Biztosan törölni kívánja a kijelölt üzeneteket?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} üzenet másolva";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) copied" = "%{0} üzenet másolva";
|
||||
|
||||
"Please select a message." = "Kérem válasszon egy üzenetet.";
|
||||
"Please select a message to print." = "Kérem válasszon ki egy üzenetet a nyomtatáshoz.";
|
||||
"Please select only one message to print." = "Kérem csak egy üzenetet válasszon a nyomtatáshoz.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Hiba történt a \"%{0}\" állomány feltöltésekor:";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Állomány feltöltés folyamatban. Az ablak bezárása megszakítja ezt a folyamatot.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Küldés";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Elküldve";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Az üzenetet nem lehetett elküldeni: az összes címzett érvénytelen.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Az üzenetet nem lehetett elküldeni: az alábbi címzettek érvénytelenek";
|
||||
"cannot send message: (smtp) error when connecting" = "Az üzenetet nem lehetett elküldeni: hiba az SMTP kiszolgálóhoz történő csatlakozáskor.";
|
||||
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Operazione non riuscita";
|
||||
"Quota" = "Spazio usato";
|
||||
"quotasFormat" = "%{0}% usato su %{1} MB";
|
||||
"Unable to move/delete folder." = "Impossibile spostare/cancellare la cartella.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Sei sicuro di voler cancellare il messaggio selezionato?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} messaggi copiati";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} messaggi spostati";
|
||||
|
||||
"Please select a message." = "Per favore seleziona un messaggio.";
|
||||
"Please select a message to print." = "Per favore seleziona un messaggio da stampare.";
|
||||
"Please select only one message to print." = "Per favore seleziona un solo messaggio da stampare.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Errore durante l'upload del file \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Caricamento in corso. Chiudendo la finestra verrà interrotto.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Invio";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Inviato";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Impossibile inviare il messaggio: tutti i destinatari non sono validi.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Impossibile inviare il messaggio. Il seguente indirizzo non è valido";
|
||||
"cannot send message: (smtp) error when connecting" = "Impossibile inviare il messaggio: si è verificato un errore durante la connessione al server SMTP.";
|
||||
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Неуспешна операција";
|
||||
"Quota" = "Квота:";
|
||||
"quotasFormat" = "%{0}% used on %{1} MB";
|
||||
"Unable to move/delete folder." = "Не е можно да ја префрлите/избришете папката.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Дали сте сигуни дека сакате да ги избришете селектираните пораки?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} порака(и) се ископирани";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) copied" = "%{0} порака(и) се ископирани";
|
||||
|
||||
"Please select a message." = "Одберете порака.";
|
||||
"Please select a message to print." = "Одберете ја пораката што ќе се печати.";
|
||||
"Please select only one message to print." = "Одберете само една порака да ја печатите.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Грешка при прикажување на фајл \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Во тек е активно прикачување на фајл. Затварањето на прозорецот ќе го прекине прикачувањето.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Испраќам";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Испратени";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Не моѓам да ја пратам пораката: сите приматели се невалидни.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Не можам да ја испратам пораката. Следните адреси се невалидни";
|
||||
"cannot send message: (smtp) error when connecting" = "Не можам да ја испртам пораката: грешка при поврзувањето со SMPT серверот.";
|
||||
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Operacja nie powiodła się";
|
||||
"Quota" = "Limit:";
|
||||
"quotasFormat" = "użyte %{0}% z %{1} MB";
|
||||
"Unable to move/delete folder." = "Nie można przenieść/usunąć folderu.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Czy na pewno chcesz usunąć wskazane wiadomości?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "Skopiowano %{0} wiadomości";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "Przeniesiono %{0} wiadomości";
|
||||
|
||||
"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.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Błąd w trakcie wysyłania pliku \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Trwa przesyłanie pliku. Zamknięcie okna przerwie tą transmisję.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Wysyłanie";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Wysłano";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Nie można wysłać wiadomości - wszyscy odbiorcy zostali odrzuceni.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Nie można wysłać wiadomości - poniżsi odbiorcy zostali odrzuceni";
|
||||
"cannot send message: (smtp) error when connecting" = "Nie można wysłać wiadomości - błąd połączenia z serwerem SMTP";
|
||||
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "Операция завершилась неудачно";
|
||||
"Quota" = "Квота:";
|
||||
"quotasFormat" = "Занято %{0}% из %{1}МБ";
|
||||
"Unable to move/delete folder." = "Невозможно переместить/удалить эту папку.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Вы уверены, что вы хотите удалить выбранные сообщения?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} сообщений скопировано";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) copied" = "%{0} сообщений скопировано";
|
||||
|
||||
"Please select a message." = "Пожалуйста выберите сообщение.";
|
||||
"Please select a message to print." = "Пожалуйста выберите сообщение для отправки на печать.";
|
||||
"Please select only one message to print." = "Пожалуйста выберите только одно сообщение для печати.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = "Ошибка при загрузке файла \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Сейчас выполняется загрузка файла. Закрытие окна прервет её.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Отправляется";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Отправлено";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Не удается отправить сообщение: всем получателям, все получатели являются недействительными.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Не удается отправить сообщение. Следующие адреса неверны";
|
||||
"cannot send message: (smtp) error when connecting" = "Не удается отправить сообщение: ошибка при соединении с сервером SMTP.";
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
/* this file is in UTF-8 format! */
|
||||
|
||||
/* Icon's label */
|
||||
"Create" = "Креирај";
|
||||
"Empty Trash" = "Испразни канту";
|
||||
"Delete" = "Обриши";
|
||||
"Expunge" = "Избриши";
|
||||
"Forward" = "Проследи";
|
||||
"Get Mail" = "Преузми пошту";
|
||||
"Junk" = "Нежељено";
|
||||
"Not junk" = "Није нежељено";
|
||||
"Reply" = "Одговори";
|
||||
"Reply All" = "Одговори свима";
|
||||
"Print" = "Штампај";
|
||||
"Stop" = "Заустави";
|
||||
"Write" = "Писање";
|
||||
"Search" = "Претрага";
|
||||
"Send" = "Пошаљи";
|
||||
"Contacts" = "Контакти";
|
||||
"Attach" = "Приложи";
|
||||
"Save" = "Сачувај";
|
||||
"Options" = "Опције";
|
||||
"Close" = "Затвори";
|
||||
"Size" = "Величина";
|
||||
|
||||
/* Tooltips */
|
||||
"Send this message now" = "Пошаљи ову поруку сада";
|
||||
"Select a recipient from an Address Book" = "Одабери примаоца из адресара";
|
||||
"Include an attachment" = "Укључи прилог";
|
||||
"Save this message" = "Сачувај ову поруку";
|
||||
"Get new messages" = "Преузми нове поруке";
|
||||
"Create a new message" = "Креирај нову поруку";
|
||||
"Go to address book" = "Иди у адресар";
|
||||
"Reply to the message" = "Одговори на поруку";
|
||||
"Reply to sender and all recipients" = "Одговори пошињаоцу и свим примаоцима";
|
||||
"Forward selected message" = "Проследи одабрану поруку";
|
||||
"Delete selected message or folder" = "Обриши одабрану поруку или директоријум";
|
||||
"Print this message" = "Одштампај ову поруку";
|
||||
"Stop the current transfer" = "Заусти тренутни пренос";
|
||||
"Attachment" = "Прилог";
|
||||
"Unread" = "Непрочитано";
|
||||
"Flagged" = "Означено заставицом";
|
||||
"Search multiple mailboxes" = "Претражи више поштанских сандучића";
|
||||
|
||||
/* Main Frame */
|
||||
"Home" = "Почетна";
|
||||
"Calendar" = "Календар";
|
||||
"Addressbook" = "Адресар";
|
||||
"Mail" = "Пошта";
|
||||
"Right Administration" = "Администрација права";
|
||||
"Help" = "Помоћ";
|
||||
|
||||
/* Mail account main windows */
|
||||
"Welcome to the SOGo Mailer. Use the folder tree on the left to browse your mail accounts!" = "Добродошли у SOGo Пошту. Користите стабло директоријума са леве стране да претражите ваше поштанске налоге!";
|
||||
"Read messages" = "Прочитај поруке";
|
||||
"Write a new message" = "Напиши нову поруку";
|
||||
"Share" = "Дели";
|
||||
"Account" = "Налог";
|
||||
"Shared Account" = "Дељени налог";
|
||||
|
||||
/* A mailbox is selected, but no message (only shown on large screens) */
|
||||
"No message selected" = "Нема одабране поруке";
|
||||
|
||||
/* No mailbox is selected (usually resulting from an IMAP connection problem) */
|
||||
"No mailbox selected" = "Нема одабраног поштанског сандучета";
|
||||
|
||||
/* Mailbox actions */
|
||||
/* Compact Folder success message */
|
||||
"Folder compacted" = "Директоријум је сабијен";
|
||||
/* Empty Trash success message */
|
||||
"Trash emptied" = "Канта за отпатке је испражњена";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Права приступа у";
|
||||
"For user" = "За корисника";
|
||||
"Any Authenticated User" = "Било који аутентификовани корисник";
|
||||
"List and see this folder" = "Прикажи и погледај овај директоријум";
|
||||
"Read mails from this folder" = "Прочитај пошту из овог директоријума";
|
||||
"Mark mails read and unread" = "Означи пошту прочитаном или непрочитаном";
|
||||
"Modify the flags of the mails in this folder" = "Измени заставице поште у овом директоријуму";
|
||||
"Insert, copy and move mails into this folder" = "Убаци, копирај или премести пошту у овај директоријум";
|
||||
"Post mails" = "Пошаљи пошту";
|
||||
"Add subfolders to this folder" = "Додај поддиректоријуме овом директоријуму";
|
||||
"Remove this folder" = "Уклони овај директоријум";
|
||||
"Erase mails from this folder" = "Обриши пошту из овог директоријума";
|
||||
"Expunge this folder" = "Очисти овај директоријум";
|
||||
"Export This Folder" = "Извези овај директоријум";
|
||||
"Modify the acl of this folder" = "Измени АЦЛ овог директоријума";
|
||||
"Saved Messages.zip" = "Сачуване Поруке.zip";
|
||||
"Update" = "Ажурирај";
|
||||
"Cancel" = "Откажи";
|
||||
|
||||
/* Mail edition */
|
||||
"From" = "Од";
|
||||
"Subject" = "Тема";
|
||||
"To" = "За";
|
||||
"Cc" = "Цц";
|
||||
"Bcc" = "Бцц";
|
||||
"Reply-To" = "Одговори";
|
||||
"Add address" = "Додај адресу";
|
||||
"Body" = "Тело";
|
||||
"Open" = "Отвори";
|
||||
"Select All" = "Одабери све";
|
||||
"Select Message" = "Одабери поруку";
|
||||
"Attach Web Page..." = "Приложи Веб страницу...";
|
||||
"file" = "документ";
|
||||
"files" = "документа";
|
||||
"Save all" = "Сачувај све";
|
||||
"to" = "За";
|
||||
"cc" = "Цц";
|
||||
"bcc" = "Бцц";
|
||||
"Add a recipient" = "Додај примаоца";
|
||||
"Edit Draft..." = "Измени нацрт...";
|
||||
"Load Images" = "Учитај слике";
|
||||
"Return Receipt" = "Потврда о пријему";
|
||||
"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "Пошиљалац ове поруке је питао да буде обавештен када прочитате ову поруку. Да ли желите да обавестите пошиљаоца?";
|
||||
"Return Receipt (displayed) - %@"= "Потврда о пријему (приказана) - %@";
|
||||
"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Ово је Потврда о пријему за пошту коју сте послали %@.\n\nБелешка: Ова потврда о пријему је само потврда да је порука приказана на рачунару примаоца. Нема гаранције да је прималац прочитао поруку или разумео садржај поруке.";
|
||||
"Priority" = "Приоритет";
|
||||
"highest" = "Највиши";
|
||||
"high" = "Висок";
|
||||
"normal" = "Нормалан";
|
||||
"low" = "Низак";
|
||||
"lowest" = "Најнижи";
|
||||
"This mail is being sent from an unsecure network!" = "Ова порука је послата са несигурне мреже!";
|
||||
"Address Book" = "Адресар";
|
||||
"Search For" = "Претражи";
|
||||
|
||||
/* Popup "show" */
|
||||
"all" = "све";
|
||||
"read" = "прочитано";
|
||||
"unread" = "непрочитано";
|
||||
"deleted" = "обрисано";
|
||||
"flagged" = "означено заставицом";
|
||||
|
||||
/* MailListView */
|
||||
"Sender" = "Пошиљалац";
|
||||
"Subject or Sender" = "Тема или Пошиљалац";
|
||||
"To or Cc" = "За или Цц";
|
||||
"Entire Message" = "Комплетна порука";
|
||||
"Date" = "Датум";
|
||||
"View" = "Преглед";
|
||||
"All" = "Све";
|
||||
"No message" = "Нема порука";
|
||||
"messages" = "поруке";
|
||||
"Yesterday" = "Јуче";
|
||||
"first" = "Прва";
|
||||
"previous" = "Претходна";
|
||||
"next" = "Следећа";
|
||||
"last" = "Последња";
|
||||
"msgnumber_to" = "за";
|
||||
"msgnumber_of" = "од";
|
||||
"Mark Unread" = "Обележи непрочитано";
|
||||
"Mark Read" = "Обележи прочитано";
|
||||
"Untitled" = "Без наслова";
|
||||
|
||||
/* Tree */
|
||||
"SentFolderName" = "Послато";
|
||||
"TrashFolderName" = "Канта";
|
||||
"InboxFolderName" = "Примљене";
|
||||
"DraftsFolderName" = "Недовршене";
|
||||
"JunkFolderName" = "Непожељне";
|
||||
"SieveFolderName" = "Филтери";
|
||||
"Folders" = "Директоријуми"; /* title line */
|
||||
|
||||
/* MailMoveToPopUp */
|
||||
"MoveTo" = "Премести у …";
|
||||
|
||||
/* Address Popup menu */
|
||||
"Add to Address Book..." = "Додај у адресар...";
|
||||
"Compose Mail To" = "Састави поруку за";
|
||||
"Create Filter From Message..." = "Креирај филтер од поруке...";
|
||||
|
||||
/* Image Popup menu */
|
||||
"Save Image" = "Сачувај слику";
|
||||
"Save Attachment" = "Сачувај прилог";
|
||||
|
||||
/* Mailbox popup menus */
|
||||
"Open in New Mail Window" = "Отовори у новом прозору поште";
|
||||
"Copy Folder Location" = "Умножи локацију директоријума";
|
||||
"Subscribe..." = "Пртплати се";
|
||||
"Mark Folder Read" = "Означи директоријум прочитан";
|
||||
"New Folder..." = "Нови директоријум...";
|
||||
"Compact This Folder" = "Компресуј овај директоријум";
|
||||
"Search Messages..." = "Претражи поруке...";
|
||||
"Sharing..." = "Дељење...";
|
||||
"New Subfolder..." = "Нови поддиректоријум...";
|
||||
"Rename Folder..." = "Преименуј директоријум...";
|
||||
"Delete Folder" = "Обриши директоријум...";
|
||||
"Use This Folder For" = "Користи овај директоријум за";
|
||||
"Get Messages for Account" = "Преузми поруке за налог";
|
||||
"Properties..." = "Својства...";
|
||||
"Delegation..." = "Делегирање...";
|
||||
|
||||
/* Use This Folder menu */
|
||||
"Sent Messages" = "Послате поруке...";
|
||||
"Drafts" = "Недовршене";
|
||||
"Deleted Messages" = "Обрисане поруке";
|
||||
"Junk Messages" = "Непожељне поруке";
|
||||
|
||||
/* Message list popup menu */
|
||||
"Open Message In New Window" = "Отвори поруке у новом прозору";
|
||||
"Reply to Sender Only" = "Одговори само пошиљаоцу";
|
||||
"Reply to All" = "Одговори свима";
|
||||
"Edit As New..." = "Измени као нову...";
|
||||
"Move To" = "Премести у";
|
||||
"Copy To" = "Копирај у";
|
||||
"Label" = "Ознака";
|
||||
"Mark" = "Обележи";
|
||||
"Save As..." = "Сачувај као...";
|
||||
"Print Preview" = "Преглед пре штампања";
|
||||
"View Message Source" = "Погледај извнорни код поруке";
|
||||
|
||||
/* Message view "more" menu: create an event from message */
|
||||
"Convert To Event" = "Претвори у догађај";
|
||||
|
||||
/* Message view "more" menu: create a task from message */
|
||||
"Convert To Task" = "Претвори у задатак";
|
||||
|
||||
"Print..." = "Штампај...";
|
||||
"Delete Message" = "Обриши поруку";
|
||||
"Delete Selected Messages" = "Обриши одабране поруке";
|
||||
"Mark the selected messages as junk" = "Обележи одабране поруке као непожељне";
|
||||
"Mark the selected messages as not junk" = "Обележи одабране поруке као пожељне";
|
||||
|
||||
/* Text appended to the recipients list when there are too many recipients */
|
||||
"and %{0} more..." = "и %{0} још...";
|
||||
|
||||
/* Button label to hide extended list of recipients */
|
||||
"Hide" = "Сакриј";
|
||||
|
||||
/* Number of selected messages in list */
|
||||
"selected" = "изабрано";
|
||||
|
||||
"This Folder" = "Овај директоријум";
|
||||
|
||||
/* Label popup menu */
|
||||
"None" = "Ништа";
|
||||
|
||||
/* Mark popup menu */
|
||||
"As Read" = "Као прочитано";
|
||||
"Thread As Read" = "Тема као прочитана";
|
||||
"As Read By Date..." = "Као прочизтан датума...";
|
||||
"All Read" = "Све прочитано";
|
||||
"Flag" = "Заставица";
|
||||
"As Junk" = "Као непожељно";
|
||||
"As Not Junk" = "Као пожељно";
|
||||
"Run Junk Mail Controls" = "Покрени контроле непожељне поште";
|
||||
"Search messages in" = "Претражи поруке у";
|
||||
"Search" = "Претрага";
|
||||
"Search subfolders" = "Претражи поддиректоријуме";
|
||||
"Match any of the following" = "Подудари са било чим од следећег";
|
||||
"Match all of the following" = "Подудари са свим од следећег";
|
||||
"contains" = "садржи";
|
||||
"does not contain" = "не садржи";
|
||||
"No matches found" = "Нема пронађених подударања";
|
||||
"results found" = "пронађени резултати";
|
||||
"result found" = "пронађени резултат";
|
||||
"Please specify at least one filter" = "Молимо наведите барем један филтер";
|
||||
|
||||
/* Folder operations */
|
||||
"Name" = "Име";
|
||||
"Enter the new name of your folder"
|
||||
="Унесите име вашег директоријума";
|
||||
"Do you really want to move this folder into the trash ?"
|
||||
= "Да ли заиста желите да померите овај директоријум у канту?";
|
||||
"Operation failed" = "Операција није успела";
|
||||
"Quota" = "Квота:";
|
||||
"quotasFormat" = "%{0}% искоришћено од %{1} МБ";
|
||||
"Unable to move/delete folder." = "Не могу да преместим/обришем директоријум.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Да ли сте сигурни да желите да обришете одабране поруке?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} порука(е) прекопирано";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} порука(е) премештено";
|
||||
|
||||
"Please select a message." = "Молимо одаберите поруку.";
|
||||
"Please select a message to print." = "Молимо одаберите поруку за штампање.";
|
||||
"Please select only one message to print." = "Молимо одаберите само једну поруку за штампање.";
|
||||
"The message you have selected doesn't exist anymore." = "Порука коју сте одабрали више не постоји.";
|
||||
"The folder with name \"%{0}\" could not be created."
|
||||
= "Директоријум са именом \"%{0}\" не може бити креиран.";
|
||||
"This folder could not be renamed to \"%{0}\"."
|
||||
= "Овај директоријум не може бити преименован у \"%{0}\".";
|
||||
"The folder could not be deleted."
|
||||
= "Директоријум не може бити обрисан.";
|
||||
"The trash could not be emptied."
|
||||
= "Канта не може бити испражњена.";
|
||||
"The folder functionality could not be changed."
|
||||
= "Функционалност директоријума не може бити промењена.";
|
||||
"You need to choose a non-virtual folder!" = "Морате одабрати директоријум који није виртуелни!";
|
||||
"Moving a message into its own folder is impossible!"
|
||||
= "Премештање порука у сопствени директоријум није могуће!";
|
||||
"Copying a message into its own folder is impossible!"
|
||||
= "Копирање порука у сопствени директоријум није могуће!";
|
||||
|
||||
/* Message operations */
|
||||
"The messages could not be moved to the trash folder. Would you like to delete them immediately?"
|
||||
= "Поруке не могу бити премештене у директоријум канте. Да ли желите да их одмах обришете?";
|
||||
|
||||
/* Message editing */
|
||||
"error_missingsubject" = "Порука нема тему. Да ли сте сигурни да желите да је пошаљете?";
|
||||
"error_missingrecipients" = "Молимо наведите барем једног примаоца.";
|
||||
"Send Anyway" = "Свеједно пошаљи";
|
||||
"Error while saving the draft" = "Грешка при чувању недовршене поруке";
|
||||
|
||||
/* Error when uploading a file attachment */
|
||||
"Error while uploading the file \"%{0}\":" = "Грешка при отпремаљу документа \"%{0}\":";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "У току је отпремање документа. Ако затворите прозор прекинућете отпремање.";
|
||||
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Слање";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Послато";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "Не могу послати поруку: ни један прималац није валидан.";
|
||||
"cannot send message (smtp) - recipients discarded" = "Не могу послати поруку. Следеће адресе нису валидне";
|
||||
"cannot send message: (smtp) error when connecting" = "Не могу послати поруку: грешка при повезивању на СМТП сервер.";
|
||||
|
||||
/* Contacts list in mail editor */
|
||||
"Email" = "Епошта";
|
||||
"More mail options" = "Више опција поште";
|
||||
"Delegation" = "Делегирање";
|
||||
"Add User" = "Додај корисника";
|
||||
"Add a tag" = "Додај ознаку";
|
||||
"reply" = "одговори";
|
||||
"Edit" = "Измени";
|
||||
"Yes" = "Да";
|
||||
"No" = "Не";
|
||||
"Location" = "Локација";
|
||||
"Rename" = "Преименуј";
|
||||
"Compact" = "Компресуј";
|
||||
"Export" = "Извези";
|
||||
"Set as Drafts" = "Постави као недовршено";
|
||||
"Set as Sent" = "Постави као послато";
|
||||
"Set as Trash" = "Постави као канта";
|
||||
|
||||
/* Set the folder as the one holding Junk mails */
|
||||
"Set as Junk" = "Постави као непожељно";
|
||||
|
||||
"Sort" = "Поређај";
|
||||
"Descending Order" = "Опадајући ред";
|
||||
"Back" = "Назад";
|
||||
"Copy messages" = "Копирај поруке";
|
||||
"More messages options" = "Више опција порука";
|
||||
"Mark as Unread" = "Означи као непрочитано";
|
||||
"Closing Window ..." = "Затварам прозор...";
|
||||
"Tried to send too many mails. Please wait." = "Покушавам да пошаљем превише поште. Молимо сачекајте.";
|
||||
"View Mail" = "Види пошту";
|
||||
"This message contains external images." = "Ова порука садржи спољне слике.";
|
||||
"Expanded" = "Проширено";
|
||||
"Add a Criteria" = "Додај критеријум";
|
||||
"More search options" = "Више опција претраге";
|
||||
"Your email has been saved" = "Ваше еписмо је сачувано";
|
||||
"Your email has been sent" = "Ваше еписмо је послато";
|
||||
"Folder compacted" = "Директоријум је сабијен";
|
||||
|
||||
/* Aria label for scope of search on messages */
|
||||
"Search scope" = "Претражи опсег";
|
||||
@@ -6,40 +6,40 @@
|
||||
"Delete" = "Sil";
|
||||
"Expunge" = "Silip At";
|
||||
"Forward" = "İlet";
|
||||
"Get Mail" = "E-posta Al";
|
||||
"Get Mail" = "İletileri Al";
|
||||
"Junk" = "İstenmeyen";
|
||||
"Not junk" = "İstenen";
|
||||
"Reply" = "Yanıtla";
|
||||
"Reply All" = "Hepsini Yanıtla";
|
||||
"Reply All" = "Herkesi Yanıtla";
|
||||
"Print" = "Yazdır";
|
||||
"Stop" = "Durdur";
|
||||
"Write" = "Yaz";
|
||||
"Search" = "Ara";
|
||||
"Send" = "Gönder";
|
||||
"Contacts" = "Kişiler";
|
||||
"Attach" = "Ekle";
|
||||
"Contacts" = "Adresler";
|
||||
"Attach" = "Dosya Ekle";
|
||||
"Save" = "Kaydet";
|
||||
"Options" = "Seçenekler";
|
||||
"Close" = "Kapat";
|
||||
"Size" = "Boyut";
|
||||
|
||||
/* Tooltips */
|
||||
"Send this message now" = "Bu iletiyi şimdi gönder";
|
||||
"Select a recipient from an Address Book" = "Bir Adres Defterinden Bir Alıcı Seçin";
|
||||
"Send this message now" = "İletiyi gönder";
|
||||
"Select a recipient from an Address Book" = "Adres Defterinden Alıcı Seç";
|
||||
"Include an attachment" = "Dosya Ekle";
|
||||
"Save this message" = "Bu iletiyi kaydet";
|
||||
"Get new messages" = "Yeni iletileri al";
|
||||
"Save this message" = "İletiyi kaydet";
|
||||
"Get new messages" = "Yeni gelen iletileri al";
|
||||
"Create a new message" = "Yeni ileti oluştur";
|
||||
"Go to address book" = "Adres defterine git";
|
||||
"Reply to the message" = "İletiyi yanıtla";
|
||||
"Reply to sender and all recipients" = "Göndereni ve tüm alıcıları yanıtla";
|
||||
"Forward selected message" = "Seçili e-postayı başkasına ilet";
|
||||
"Reply to sender and all recipients" = "Göndereni ve diğer tüm alıcıları yanıtla";
|
||||
"Forward selected message" = "E-postayı başkasına ilet";
|
||||
"Delete selected message or folder" = "Seçili ileti veya klasörü sil";
|
||||
"Print this message" = "Bu iletiyi yazdır";
|
||||
"Print this message" = "İletiyi yazdır";
|
||||
"Stop the current transfer" = "Geçerli aktarımı durdur";
|
||||
"Attachment" = "Eklenti";
|
||||
"Unread" = "Okunmamış";
|
||||
"Flagged" = "Bayraklı";
|
||||
"Flagged" = "Yıldızlı";
|
||||
"Search multiple mailboxes" = "Birden fazla klasörde ara";
|
||||
|
||||
/* Main Frame */
|
||||
@@ -71,21 +71,21 @@
|
||||
"Trash emptied" = "Çöp Kutusu boşaltıldı";
|
||||
|
||||
/* acls */
|
||||
"Access rights to" = "Aşağıdaki klasöre erişim yetkileri";
|
||||
"Access rights to" = "Klasörün erişim yetkileri";
|
||||
"For user" = "Şu kullanıcı için";
|
||||
"Any Authenticated User" = "Kimliği doğrulanmış her kullanıcı";
|
||||
"List and see this folder" = "Bu klasörü listele ve görüntüle";
|
||||
"Read mails from this folder" = "Bu klasördeki iletileri okur";
|
||||
"List and see this folder" = "Klasörü listele ve görüntüle";
|
||||
"Read mails from this folder" = "Klasördeki iletileri okur";
|
||||
"Mark mails read and unread" = "İletileri okumuş ve okunmamış olarak işaretler";
|
||||
"Modify the flags of the mails in this folder" = "Bu klasördeki iletilerin bayraklarını değiştirir";
|
||||
"Modify the flags of the mails in this folder" = "Bu klasördeki iletilerin yıldızlarını değiştirir";
|
||||
"Insert, copy and move mails into this folder" = "İletiler bu klasöre yerleştirir, kopyalar ve taşır";
|
||||
"Post mails" = "İletileri postalar";
|
||||
"Add subfolders to this folder" = "Bu klasöre alt klasörler ekler";
|
||||
"Remove this folder" = "Bu klasörü kaldırır";
|
||||
"Erase mails from this folder" = "Bu klasörden iletileri siler";
|
||||
"Expunge this folder" = "Bu klasörü temizler";
|
||||
"Export This Folder" = "Bu klasörü dışa aktar";
|
||||
"Modify the acl of this folder" = "Bu klasörün erişim denetimi listesini değiştirir";
|
||||
"Add subfolders to this folder" = "Klasöre alt klasörler ekler";
|
||||
"Remove this folder" = "Klasörü kaldırır";
|
||||
"Erase mails from this folder" = "Klasörden iletileri siler";
|
||||
"Expunge this folder" = "Klasörü boşaltır";
|
||||
"Export This Folder" = "Klasörü dışa aktar";
|
||||
"Modify the acl of this folder" = "Klasörün erişim denetimi listesini değiştirir";
|
||||
"Saved Messages.zip" = "Messages.zip olarak kaydedildi";
|
||||
"Update" = "Güncelle";
|
||||
"Cancel" = "İptal";
|
||||
@@ -115,7 +115,7 @@
|
||||
"Return Receipt" = "Alındı Raporu";
|
||||
"The sender of this message has asked to be notified when you read this message. Do you with to notify the sender?" = "Bu iletiyi gönderen kişi, iletiyi okuduğunuzdan haberdar olmak istedi. Gönderene alındı raporu yollamak ister misiniz?";
|
||||
"Return Receipt (displayed) - %@"= "Alındı Raporu (görüntülendi) - %@";
|
||||
"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Şuraya gönderdiğiniz iletinin Alındı Raporudur: %@\n\nBilgi Notu: Bu Alındı Raporu gönderdiğiniz iletinin yalnızca, alıcının bilgisayarında görüntülendiğini belirtir. İleti içeriğinin alıcı tarafından okunduğunu veya anlaşıldığını garanti etmez.";
|
||||
"This is a Return Receipt for the mail that you sent to %@.\n\nNote: This Return Receipt only acknowledges that the message was displayed on the recipient's computer. There is no guarantee that the recipient has read or understood the message contents." = "Şu adrese gönderdiğiniz iletinin Alındı Raporudur: %@\nBilgi Notu: Bu Alındı Raporu gönderdiğiniz iletinin yalnızca, alıcının bilgisayarında görüntülendiğini belirtir. İleti içeriğinin alıcı tarafından okunduğunu veya anlaşıldığını garanti etmez.";
|
||||
"Priority" = "Öncelik";
|
||||
"highest" = "En yüksek";
|
||||
"high" = "Yüksek";
|
||||
@@ -131,13 +131,13 @@
|
||||
"read" = "okunmuş";
|
||||
"unread" = "okunmamış";
|
||||
"deleted" = "silinmiş";
|
||||
"flagged" = "bayraklı";
|
||||
"flagged" = "yıldızlı";
|
||||
|
||||
/* MailListView */
|
||||
"Sender" = "Gönderen";
|
||||
"Subject or Sender" = "Konu veya Gönderen";
|
||||
"To or Cc" = "Alıcı veya Karbon Kopya";
|
||||
"Entire Message" = "Tüm İleti";
|
||||
"Entire Message" = "İletinin Tamamı";
|
||||
"Date" = "Tarih";
|
||||
"View" = "Görüntüle";
|
||||
"All" = "Hepsi";
|
||||
@@ -176,12 +176,12 @@
|
||||
"Save Attachment" = "Eklentiyi Kaydet";
|
||||
|
||||
/* Mailbox popup menus */
|
||||
"Open in New Mail Window" = "Yeni İleti Penceresinde Aç";
|
||||
"Open in New Mail Window" = "Yeni Pencerede Aç";
|
||||
"Copy Folder Location" = "Klasörün Konumunu Kopyala";
|
||||
"Subscribe..." = "Üye ol...";
|
||||
"Mark Folder Read" = "Klasörü Okunmuş Olarak İşretle";
|
||||
"New Folder..." = "Yeni Klasör...";
|
||||
"Compact This Folder" = "Bu Klasörü Sıkıştır";
|
||||
"Compact This Folder" = "Klasörü Sıkıştır";
|
||||
"Search Messages..." = "İletileri Ara...";
|
||||
"Sharing..." = "Paylaş...";
|
||||
"New Subfolder..." = "Yeni Alt Klasör...";
|
||||
@@ -203,19 +203,19 @@
|
||||
"Reply to Sender Only" = "Sadece Göndereni Yanıtla";
|
||||
"Reply to All" = "Herkesi Yanıtla";
|
||||
"Edit As New..." = "Yeni Olarak Düzenle...";
|
||||
"Move To" = "Şuraya Taşı";
|
||||
"Copy To" = "Şuraya Kopyala";
|
||||
"Label" = "Etiket";
|
||||
"Move To" = "Taşı";
|
||||
"Copy To" = "Kopyala";
|
||||
"Label" = "Etiketle";
|
||||
"Mark" = "İşaretle";
|
||||
"Save As..." = "Farklı Kaydet...";
|
||||
"Print Preview" = "Baskı Önizleme";
|
||||
"View Message Source" = "İletinin Kaynak Kodunu Göster";
|
||||
|
||||
/* Message view "more" menu: create an event from message */
|
||||
"Convert To Event" = "Etkinliğe Çevir";
|
||||
"Convert To Event" = "Etkinliğe Dönüştür";
|
||||
|
||||
/* Message view "more" menu: create a task from message */
|
||||
"Convert To Task" = "Göreve Çevir";
|
||||
"Convert To Task" = "Göreve Dönüştür";
|
||||
|
||||
"Print..." = "Yazdır...";
|
||||
"Delete Message" = "İletiyi Sil";
|
||||
@@ -238,19 +238,19 @@
|
||||
"None" = "Hiç biri";
|
||||
|
||||
/* Mark popup menu */
|
||||
"As Read" = "Okunmuş Olarak";
|
||||
"As Read" = "Okunmuş";
|
||||
"Thread As Read" = "Okunmuşları Zincirleme Sırala";
|
||||
"As Read By Date..." = "Okunma Tarihi...";
|
||||
"All Read" = "Hepsi Okunmuş";
|
||||
"Flag" = "Bayrak";
|
||||
"Flag" = "Yıldız";
|
||||
"As Junk" = "İstenmeyen Olarak";
|
||||
"As Not Junk" = "İstenen Olarak";
|
||||
"Run Junk Mail Controls" = "İstenmeyen İleti Denetimi Yap";
|
||||
"Search messages in" = "Aşağıdaki klasörde ara";
|
||||
"Search messages in" = "Aranacak klasör";
|
||||
"Search" = "Ara";
|
||||
"Search subfolders" = "Alt klasörlerde ara";
|
||||
"Match any of the following" = "ifadelerden birini ara";
|
||||
"Match all of the following" = "hepsini ara";
|
||||
"Match any of the following" = "ifadelerden herhangi birini ara";
|
||||
"Match all of the following" = "ifadelerin bütününü ara";
|
||||
"contains" = "içeren";
|
||||
"does not contain" = "içermeyen";
|
||||
"No matches found" = "Eşleşme bulunamadı";
|
||||
@@ -259,7 +259,7 @@
|
||||
"Please specify at least one filter" = "Lütfen en az bir süzgeç belirtin";
|
||||
|
||||
/* Folder operations */
|
||||
"Name" = "Ad ve Soyad";
|
||||
"Name" = "İsim";
|
||||
"Enter the new name of your folder"
|
||||
="Yeni klasörünüzün adını yazın";
|
||||
"Do you really want to move this folder into the trash ?"
|
||||
@@ -267,10 +267,17 @@
|
||||
"Operation failed" = "İşlem başarısiz oldu";
|
||||
"Quota" = "Kota:";
|
||||
"quotasFormat" = "%{0}% kullanılıyor, toplam %{1} MB";
|
||||
"Unable to move/delete folder." = "Klasör taşınamıyor/silinemiyor.";
|
||||
|
||||
/* Confirmation message when deleting multiple messages */
|
||||
"Are you sure you want to delete the selected messages?" = "Seçili iletileri silmek istediğinizden emin misiniz?";
|
||||
|
||||
/* Notification on the number of messages successfuly copied */
|
||||
"%{0} message(s) copied" = "%{0} ileti kopyalandı";
|
||||
|
||||
/* Notification on the number of messages successfuly movied */
|
||||
"%{0} message(s) moved" = "%{0} ileti taşındı";
|
||||
|
||||
"Please select a message." = "Lütfen bir ileti seçin.";
|
||||
"Please select a message to print." = "Lütfen yazdırılacak iletiyi seçin.";
|
||||
"Please select only one message to print." = "Lütfen yazdırmak için sadece bir ileti seçin.";
|
||||
@@ -305,7 +312,12 @@
|
||||
"Error while uploading the file \"%{0}\":" = " \"%{0}\" dosyasını yüklerken hata oluştu:";
|
||||
"There is an active file upload. Closing the window will interrupt it." = "Devam eden bir dosya yükleme işlemi var. Pencereyi kapanırsa yükleme işlemi duracak.";
|
||||
|
||||
/* Message sending */
|
||||
/* Appears while sending the message */
|
||||
"Sending" = "Gönderiliyor";
|
||||
|
||||
/* Appears when the message is successfuly sent */
|
||||
"Sent" = "Gönderildi";
|
||||
|
||||
"cannot send message: (smtp) all recipients discarded" = "İleti gönderilemiyor: tüm alıcılar geçersiz.";
|
||||
"cannot send message (smtp) - recipients discarded" = "İleti gönderilemiyor. Şu adresler geçersiz";
|
||||
"cannot send message: (smtp) error when connecting" = "İleti gönderilemiyor: SMTP sunucusuna erişirken hata ile karşılaşıldı.";
|
||||
@@ -315,7 +327,7 @@
|
||||
"More mail options" = "Diğer e-posta seçenekleri";
|
||||
"Delegation" = "Temsilci Atama";
|
||||
"Add User" = "Kullanıcı Ekleyin";
|
||||
"Add a tag" = "Bir etiket ekle";
|
||||
"Add a tag" = "Etiket ekle";
|
||||
"reply" = "yanıtla";
|
||||
"Edit" = "Düzenle";
|
||||
"Yes" = "Evet";
|
||||
@@ -342,11 +354,17 @@
|
||||
"View Mail" = "İletiyi Görüntüle";
|
||||
"This message contains external images." = "İleti harici konumlarda bulunan resimler içeriyor.";
|
||||
"Expanded" = "Genişletildi";
|
||||
"Add a Criteria" = "Bir Arama Kriteri Ekleyin";
|
||||
"Add a Criteria" = "Aranacak Kriteri Seçin";
|
||||
"More search options" = "Diğer arama tercihleri";
|
||||
"Your email has been saved" = "İletiniz kaydedildi";
|
||||
"Your email has been sent" = "İletiniz gönderildi";
|
||||
"Folder compacted" = "Klasör sıkıştırıldı";
|
||||
|
||||
/* Aria label for scope of search on messages */
|
||||
"Search scope" = "Arama kapsamı";
|
||||
"Search scope" = "Arama kapsamı";
|
||||
|
||||
/* Subscriptions Dialog */
|
||||
"Manage Subscriptions" = "Abonelikleri Yönet";
|
||||
|
||||
/* Hotkey to write a new message */
|
||||
"hotkey_compose" = "w";
|
||||
@@ -132,22 +132,23 @@
|
||||
}
|
||||
|
||||
- (NSURL *) _trashedURLOfFolder: (NSURL *) srcURL
|
||||
withCO: (SOGoMailFolder *) co
|
||||
withObject: (SOGoMailFolder *) co
|
||||
{
|
||||
NSURL *destURL;
|
||||
NSString *trashFolderName, *folderName, *path, *testPath;
|
||||
NGImap4Connection *connection;
|
||||
int i = 1;
|
||||
NSURL *destURL;
|
||||
id test;
|
||||
int i;
|
||||
|
||||
connection = [co imap4Connection];
|
||||
|
||||
folderName = [[srcURL path] lastPathComponent];
|
||||
trashFolderName
|
||||
= [[co mailAccountFolder] trashFolderNameInContext: context];
|
||||
path = [NSString stringWithFormat: @"/%@/%@",
|
||||
trashFolderName, folderName];
|
||||
testPath = path;
|
||||
i = 1;
|
||||
|
||||
while ( i < 10 )
|
||||
{
|
||||
test = [[connection client] select: testPath];
|
||||
@@ -163,7 +164,7 @@
|
||||
}
|
||||
}
|
||||
destURL = [[NSURL alloc] initWithScheme: [srcURL scheme]
|
||||
host: [srcURL host] path: path];
|
||||
host: [srcURL host] path: path];
|
||||
[destURL autorelease];
|
||||
|
||||
return destURL;
|
||||
@@ -171,60 +172,76 @@
|
||||
|
||||
- (WOResponse *) deleteAction
|
||||
{
|
||||
NSString *currentMailbox, *currentAccount, *keyForMsgUIDs;
|
||||
NSMutableDictionary *moduleSettings, *threadsCollapsed;
|
||||
NGImap4Connection *connection;
|
||||
SOGoMailFolder *co, *inbox;
|
||||
NSURL *srcURL, *destURL;
|
||||
SOGoUserSettings *us;
|
||||
WOResponse *response;
|
||||
NGImap4Connection *connection;
|
||||
NSException *error;
|
||||
NSURL *srcURL, *destURL;
|
||||
NSMutableDictionary *moduleSettings, *threadsCollapsed;
|
||||
NSString *currentMailbox, *currentAccount, *keyForMsgUIDs;
|
||||
|
||||
BOOL moved;
|
||||
|
||||
co = [self clientObject];
|
||||
if ([co ensureTrashFolder])
|
||||
{
|
||||
connection = [co imap4Connection];
|
||||
srcURL = [co imap4URL];
|
||||
destURL = [self _trashedURLOfFolder: srcURL withCO: co];
|
||||
connection = [co imap4Connection];
|
||||
inbox = [[co mailAccountFolder] inboxFolderInContext: context];
|
||||
[[connection client] select: [inbox absoluteImap4Name]];
|
||||
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
|
||||
if (error)
|
||||
{
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to move folder."];
|
||||
}
|
||||
else
|
||||
{
|
||||
// We unsubscribe to the old one, and subscribe back to the new one
|
||||
[[connection client] subscribe: [destURL path]];
|
||||
[[connection client] unsubscribe: [srcURL path]];
|
||||
|
||||
// Verify if the current folder have any collapsed threads save under it name and erase it
|
||||
us = [[context activeUser] userSettings];
|
||||
moduleSettings = [us objectForKey: @"Mail"];
|
||||
threadsCollapsed = [moduleSettings objectForKey:@"threadsCollapsed"];
|
||||
currentMailbox = [co nameInContainer];
|
||||
currentAccount = [[co container] nameInContainer];
|
||||
keyForMsgUIDs = [NSString stringWithFormat:@"/%@/%@", currentAccount, currentMailbox];
|
||||
moved = YES;
|
||||
|
||||
if (threadsCollapsed)
|
||||
{
|
||||
if ([threadsCollapsed objectForKey:keyForMsgUIDs])
|
||||
{
|
||||
[threadsCollapsed removeObjectForKey:keyForMsgUIDs];
|
||||
if ([co ensureTrashFolder])
|
||||
{
|
||||
connection = [co imap4Connection];
|
||||
srcURL = [co imap4URL];
|
||||
destURL = [self _trashedURLOfFolder: srcURL withObject: co];
|
||||
connection = [co imap4Connection];
|
||||
inbox = [[co mailAccountFolder] inboxFolderInContext: context];
|
||||
[[connection client] select: [inbox absoluteImap4Name]];
|
||||
|
||||
// If srcURL is a prefix of destURL, that means we are deleting
|
||||
// the folder within the 'Trash' folder, as it's getting renamed
|
||||
// over and over with an integer suffix (in trashedURLOfFolder:...)
|
||||
// If that is the case, we simple delete the folder, instead of renaming it
|
||||
if ([[destURL path] hasPrefix: [srcURL path]])
|
||||
{
|
||||
error = [connection deleteMailboxAtURL: srcURL];
|
||||
moved = NO;
|
||||
}
|
||||
else
|
||||
error = [connection moveMailboxAtURL: srcURL toURL: destURL];
|
||||
if (error)
|
||||
{
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: [self labelForKey: @"Unable to move/delete folder." inContext: context]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// We unsubscribe to the old one, and subscribe back to the new one
|
||||
if (moved)
|
||||
[[connection client] subscribe: [destURL path]];
|
||||
[[connection client] unsubscribe: [srcURL path]];
|
||||
|
||||
// Verify if the current folder have any collapsed threads save under it name and erase it
|
||||
us = [[context activeUser] userSettings];
|
||||
moduleSettings = [us objectForKey: @"Mail"];
|
||||
threadsCollapsed = [moduleSettings objectForKey: @"threadsCollapsed"];
|
||||
currentMailbox = [co nameInContainer];
|
||||
currentAccount = [[co container] nameInContainer];
|
||||
keyForMsgUIDs = [NSString stringWithFormat:@"/%@/%@", currentAccount, currentMailbox];
|
||||
|
||||
if (threadsCollapsed)
|
||||
{
|
||||
if ([threadsCollapsed objectForKey: keyForMsgUIDs])
|
||||
{
|
||||
[threadsCollapsed removeObjectForKey: keyForMsgUIDs];
|
||||
[us synchronize];
|
||||
}
|
||||
}
|
||||
response = [self responseWith204];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
response = [self responseWith204];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Unable to move folder."];
|
||||
}
|
||||
{
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: [self labelForKey: @"Unable to move/delete folder." inContext: context]];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -716,7 +733,6 @@
|
||||
WOResponse *response;
|
||||
WORequest *request;
|
||||
SOGoMailFolder *co;
|
||||
NSException *error;
|
||||
NSArray *msgUIDs;
|
||||
NSMutableArray *flags;
|
||||
NSString *operation;
|
||||
|
||||
@@ -84,14 +84,15 @@
|
||||
- (NSString *) currentDelegateDisplayName
|
||||
{
|
||||
SOGoUserManager *um;
|
||||
NSString *s;
|
||||
NSString *s, *fullEmail;
|
||||
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
s = ([currentDelegate hasPrefix: @"@"]
|
||||
? [currentDelegate substringFromIndex: 1]
|
||||
: currentDelegate);
|
||||
fullEmail = [um getFullEmailForUID: s];
|
||||
|
||||
return [um getFullEmailForUID: s];
|
||||
return fullEmail? fullEmail : currentDelegate;
|
||||
}
|
||||
|
||||
- (id) defaultAction
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
"Catalan" = "Català";
|
||||
"ChineseTaiwan" = "Chinese (Taiwan)";
|
||||
"Croatian" = "Hrvatski";
|
||||
"Croatian" = "Hrvatski";
|
||||
"Czech" = "Česky";
|
||||
"Danish" = "Dansk (Danmark)";
|
||||
"Dutch" = "Nederlands";
|
||||
@@ -32,11 +31,14 @@
|
||||
"Icelandic" = "Íslenska";
|
||||
"Italian" = "Italiano";
|
||||
"Lithuanian" = "Lietuvių";
|
||||
"Macedonian" = "Македонски";
|
||||
"NorwegianBokmal" = "Norsk bokmål";
|
||||
"NorwegianNynorsk" = "Norsk nynorsk";
|
||||
"Polish" = "Polski";
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
@@ -77,7 +79,6 @@
|
||||
"Confirmation" = "Confirmação";
|
||||
"Cancel" = "Cancelar";
|
||||
"Please wait..." = "Por favor, aguarde...";
|
||||
"AboutBox" = "Desenvolvido por Inverse, Sogo é um servidor de groupware cheio de recursos com foco em escalabilidade e simplicidade.\nSogo fornece uma interface Web baseada em AJAX ricos e suporta vários clientes nativos através da utilização de protocolos padrão como CalDAV e CardDAV.\nSogo é distribuído sob a GNU GPL <a href=\"http://gnu.org/licenses/gpl.html\"> </a> versão 2 ou posterior e as partes são distribuídos sob a GNU LGPL versão 2. Este é um software livre: você é livre para mudar e redistribuí-lo. Não há NENHUMA GARANTIA, até o limite permitido por lei.\nVeja <a href=\"http://www.sogo.nu/en/support/community.html\"> desta página</a> para várias opções de suporte.";
|
||||
"Close" = "Fechar";
|
||||
"Missing search parameter" = "Faltando parâmetro de pesquisa";
|
||||
"Missing type parameter" = "Faltando tipo de parâmetro";
|
||||
@@ -35,6 +35,7 @@
|
||||
"Polish" = "Polski";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"Polish" = "Polski";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
"Domain" = "Domain";
|
||||
"Remember username" = "Remember username";
|
||||
"Connect" = "Connect";
|
||||
|
||||
/* Appears while authentication is in progress */
|
||||
"Authenticating" = "Authenticating";
|
||||
|
||||
/* Appears when authentication succeeds */
|
||||
"Welcome" = "Welcome";
|
||||
|
||||
"Authentication Failed" = "Authentication Failed";
|
||||
"Wrong username or password." = "Wrong username or password.";
|
||||
"cookiesNotEnabled" = "You cannot login because your browser's cookies are disabled. Please enable cookies in your browser's settings and try again.";
|
||||
@@ -38,6 +45,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
@@ -46,6 +54,7 @@
|
||||
"TurkishTurkey" = "Türkçe (Türkiye)";
|
||||
"Ukrainian" = "Українська";
|
||||
"Welsh" = "Cymraeg";
|
||||
|
||||
"About" = "About";
|
||||
"AboutBox" = "Developed by Inverse, SOGo is a fully-featured groupware server with a focus on scalability and simplicity.<br/><br/>
|
||||
SOGo provides a rich AJAX-based Web interface and supports multiple native clients through the use of standard protocols such as CalDAV and CardDAV.<br/><br/>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
"Domain" = "Domaine";
|
||||
"Remember username" = "Se souvenir de moi";
|
||||
"Connect" = "Connexion";
|
||||
|
||||
/* Appears while authentication is in progress */
|
||||
"Authenticating" = "Authentification en cours";
|
||||
|
||||
/* Appears when authentication succeeds */
|
||||
"Welcome" = "Bienvenue";
|
||||
|
||||
"Authentication Failed" = "L'authentification a échoué";
|
||||
"Wrong username or password." = "Mauvais nom d'utilisateur ou mot de passe.";
|
||||
"cookiesNotEnabled" = "Vous ne pouvez vous authentifier car les témoins (cookies) de votre navigateur Web sont désactivés. Activez les témoins dans votre navigateur Web et essayez de nouveau.";
|
||||
@@ -38,6 +45,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
@@ -46,6 +54,7 @@
|
||||
"TurkishTurkey" = "Türkçe (Türkiye)";
|
||||
"Ukrainian" = "Українська";
|
||||
"Welsh" = "Cymraeg";
|
||||
|
||||
"About" = "À propos";
|
||||
"AboutBox" = "Développé par la compagnie Inverse, SOGo est un collecticiel complet mettant l'emphase sur la simplicité et l'extensibilité.<br/><br/>\nSOGo propose une interface Web moderne basée sur AJAX ainsi qu'un accès par de nombreux clients natifs (comme Mozilla Thunderbird et Lightning et Apple iCal) par l'utilisation de protocoles standards tel que CalDAV et CardDAV.<br/><br/>\nCe programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformément aux dispositions de la <a href=\"http://gnu.org/licenses/gpl.html\">Licence Publique Générale GNU</a>, telle que publiée par la Free Software Foundation ; version 2 de la licence, ou encore (à votre choix) toute version ultérieure. Ce programme est distribué dans l’espoir qu’il sera utile, mais SANS AUCUNE GARANTIE.<br/><br/>\nPlusieurs <a href=\"http://www.sogo.nu/en/support/community.html\">types de soutien</a> sont offerts.";
|
||||
"Your account was locked due to too many failed attempts." = "Votre compte a été bloqué suite à un nombre élevé de tentatives d'authentification infructueuses.";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
"Polish" = "Polski";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovėnų";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"Portuguese" = "Português";
|
||||
"BrazilianPortuguese" = "Português brasileiro";
|
||||
"Russian" = "Русский";
|
||||
"Serbian" = "Српски";
|
||||
"Slovak" = "Slovensky";
|
||||
"Slovenian" = "Slovenščina";
|
||||
"SpanishSpain" = "Español (España)";
|
||||
|
||||
Loaded 100 of 206 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user