From 309dd45161f1ca71a534a0cb2c2d7b3c3631d41e Mon Sep 17 00:00:00 2001 From: wolfgang Date: Thu, 17 May 2007 23:16:40 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1067 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 37 + .../Appointments/SOGoAppointmentFolder.m | 4 +- SoObjects/Appointments/SOGoFreeBusyObject.m | 20 +- SoObjects/Appointments/product.plist | 6 +- SoObjects/SOGo/NSString+Utilities.m | 63 +- SoObjects/SOGo/SOGoFolder.m | 57 +- SoObjects/SOGo/SOGoObject.h | 2 + SoObjects/SOGo/SOGoObject.m | 6 +- SoObjects/SOGo/SOGoPermissions.h | 1 + SoObjects/SOGo/SOGoPermissions.m | 1 + UI/Common/English.lproj/Localizable.strings | 3 + UI/Common/French.lproj/Localizable.strings | 5 +- UI/Common/UIxAclEditor.m | 6 + UI/Common/UIxObjectActions.m | 10 +- UI/Common/UIxUserRightsEditor.m | 26 +- UI/Contacts/English.lproj/Localizable.strings | 1 + UI/Contacts/French.lproj/Localizable.strings | 1 + UI/MainUI/product.plist | 2 +- .../English.lproj/Localizable.strings | 1 + UI/Scheduler/French.lproj/Localizable.strings | 1 + .../ContactsUI/UIxContactsListView.wox | 4 +- .../UIxContactsUserRightsEditor.wox | 9 +- UI/Templates/MailerUI/UIxMailView.wox | 15 +- .../SchedulerUI/UIxCalUserRightsEditor.wox | 9 +- UI/Templates/UIxAclEditor.wox | 4 + UI/WebServerResources/ContactsUI.css | 11 +- UI/WebServerResources/MailerUI.css | 6 +- UI/WebServerResources/MailerUI.js | 53 +- UI/WebServerResources/SchedulerUI.css | 23 +- UI/WebServerResources/UIxAclEditor.css | 7 +- UI/WebServerResources/UIxAclEditor.js | 70 +- UI/WebServerResources/generic.css | 4 +- UI/WebServerResources/generic.js | 2 +- UI/WebServerResources/prototype.js | 2332 ++++++++++++++--- 34 files changed, 2220 insertions(+), 582 deletions(-) diff --git a/ChangeLog b/ChangeLog index 912c9c48..06b9a6f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2007-05-17 Wolfgang Sourdeau + + * UI/Common/UIxObjectActions.m ([UIxObjectActions + -addUserInAclsAction]): save the previous roles of the user + (unlikely) or the default roles, or None instead of saving the + roles that should appear the first time in the role editor when no + default has been set... + + * SoObjects/SOGo/SOGoObject.m: defined a new constant + "SOGoDefaultUserID". + + * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder + -setRoles:rolesforUser:uidforObjectAtPath:objectPathArray]): + ignore the "AuthorizedSubscriber" role and add the "None" role + when no other role is found. + + * UI/Common/UIxAclEditor.m: added a button for the new default + user roles feature. + + * UI/Common/UIxUserRightsEditor.m ([UIxUserRightsEditor + -_initRights]): don't take the "None" role into account when + initializing the list of current roles. + + * SoObjects/SOGo/SOGoPermissions.m: added a new void role + "SOGoRole_None". + +2007-05-16 Wolfgang Sourdeau + + * SoObjects/SOGo/NSString+Utilities.m ([NSString + -_rangeOfURLInRange:refRange]): urls cannot end with "&" nor "=". + There is no need to subscract the start from the length if a space + is not found since the range has not changed either. Finally, the + first character before the url might also be a tab or a cr, so we + match it against the "urlAfterEndingChars" custom NSCharacterSet. + ([NSString -stringByDetectingURLs]): modified to handle email + addresses and add a correct "mailto:" link. + 2007-05-15 Wolfgang Sourdeau * SoObjects/Appointments/SOGoAppointmentFolder.m diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 2300c7e1..5d708c38 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -1268,9 +1268,9 @@ static NSNumber *sharedYes = nil; today = [[NSCalendarDate calendarDate] beginOfDay]; [today setTimeZone: timeZone]; - startDate = [today dateByAddingYears: 0 months: 0 days: -14 + startDate = [today dateByAddingYears: 0 months: 0 days: -1 hours: 0 minutes: 0 seconds: 0]; - endDate = [startDate dateByAddingYears: 0 months: 1 days: 0 + endDate = [startDate dateByAddingYears: 0 months: 0 days: 2 hours: 0 minutes: 0 seconds: 0]; records = [self fetchFields: [NSArray arrayWithObject: @"c_name"] from: startDate to: endDate diff --git a/SoObjects/Appointments/SOGoFreeBusyObject.m b/SoObjects/Appointments/SOGoFreeBusyObject.m index 4476c0e9..724821d5 100644 --- a/SoObjects/Appointments/SOGoFreeBusyObject.m +++ b/SoObjects/Appointments/SOGoFreeBusyObject.m @@ -75,21 +75,21 @@ to: (NSCalendarDate *) _endDate { id calFolder; - SoSecurityManager *sm; +// SoSecurityManager *sm; NSArray *infos; calFolder = [container lookupName: @"Calendar" inContext: nil acquire: NO]; - sm = [SoSecurityManager sharedSecurityManager]; - if (![sm validatePermission: SOGoPerm_FreeBusyLookup - onObject: calFolder - inContext: context]) +// sm = [SoSecurityManager sharedSecurityManager]; +// if (![sm validatePermission: SOGoPerm_FreeBusyLookup +// onObject: calFolder +// inContext: context]) infos = [calFolder fetchFreeBusyInfosFrom: _startDate to: _endDate]; - else - { - infos = [NSArray new]; - [infos autorelease]; - } +// else +// { +// infos = [NSArray new]; +// [infos autorelease]; +// } return infos; } diff --git a/SoObjects/Appointments/product.plist b/SoObjects/Appointments/product.plist index 91f693d4..ff9831d0 100644 --- a/SoObjects/Appointments/product.plist +++ b/SoObjects/Appointments/product.plist @@ -46,11 +46,7 @@ }; SOGoFreeBusyObject = { superclass = "SOGoContentObject"; - protectedBy = "View"; - defaultRoles = { - "View" = ( "Authenticated", "FreeBusy" ); - "WebDAV Access" = ( "Authenticated", "FreeBusy" ); - }; + protectedBy = ""; }; }; } diff --git a/SoObjects/SOGo/NSString+Utilities.m b/SoObjects/SOGo/NSString+Utilities.m index 4d8acf86..987ad47c 100644 --- a/SoObjects/SOGo/NSString+Utilities.m +++ b/SoObjects/SOGo/NSString+Utilities.m @@ -108,63 +108,78 @@ static NSMutableCharacterSet *urlAfterEndingChars = nil; - (NSRange) _rangeOfURLInRange: (NSRange) refRange { int start, length; - NSRange endRange; + NSRange workRange; if (!urlNonEndingChars) { urlNonEndingChars = [NSMutableCharacterSet new]; - [urlNonEndingChars addCharactersInString: @",.:;\t \r\n"]; + [urlNonEndingChars addCharactersInString: @">&=,.:;\t \r\n"]; } if (!urlAfterEndingChars) { urlAfterEndingChars = [NSMutableCharacterSet new]; - [urlAfterEndingChars addCharactersInString: @"\t \r\n"]; + [urlAfterEndingChars addCharactersInString: @"&;<\t \r\n"]; } start = refRange.location; while (start > -1 - && [self characterAtIndex: start] != ' ') + && ![urlAfterEndingChars characterIsMember: + [self characterAtIndex: start]]) start--; start++; length = [self length] - start; - endRange = NSMakeRange (start, length); - endRange = [self rangeOfCharacterFromSet: urlAfterEndingChars - options: NSLiteralSearch range: endRange]; - if (endRange.location != NSNotFound) - length = endRange.location; - length -= start; + workRange = NSMakeRange (start, length); + workRange = [self rangeOfCharacterFromSet: urlAfterEndingChars + options: NSLiteralSearch range: workRange]; + if (workRange.location != NSNotFound) + length = workRange.location - start; while - ([urlNonEndingChars characterIsMember: - [self characterAtIndex: (start + length - 1)]]) + (length > 0 + && [urlNonEndingChars characterIsMember: + [self characterAtIndex: (start + length - 1)]]) length--; return NSMakeRange (start, length); } -- (NSString *) stringByDetectingURLs +- (void) _handleURLs: (NSMutableString *) selfCopy + textToMatch: (NSString *) match + prefix: (NSString *) prefix { - NSMutableString *selfCopy; NSRange httpRange, currentURL, rest; NSString *urlText, *newUrlText; - unsigned int length; - - selfCopy = [NSMutableString stringWithString: self]; + unsigned int length, matchLength; - httpRange = [selfCopy rangeOfString: @"://"]; + matchLength = [match length]; + httpRange = [selfCopy rangeOfString: match]; while (httpRange.location != NSNotFound) { currentURL = [selfCopy _rangeOfURLInRange: httpRange]; urlText = [selfCopy substringFromRange: currentURL]; - newUrlText = [NSString stringWithFormat: @"%@", - urlText, urlText]; - [selfCopy replaceCharactersInRange: currentURL - withString: newUrlText]; + if ([urlText length] > matchLength) + { + newUrlText = [NSString stringWithFormat: @"%@", + prefix, urlText, urlText]; + [selfCopy replaceCharactersInRange: currentURL + withString: newUrlText]; + rest.location = currentURL.location + [newUrlText length]; + } + else + rest.location = currentURL.location + currentURL.length; length = [selfCopy length]; - rest.location = currentURL.location + [newUrlText length]; rest.length = length - rest.location; - httpRange = [selfCopy rangeOfString: @"://" + httpRange = [selfCopy rangeOfString: match options: 0 range: rest]; } +} + +- (NSString *) stringByDetectingURLs +{ + NSMutableString *selfCopy; + + selfCopy = [NSMutableString stringWithString: self]; + [self _handleURLs: selfCopy textToMatch: @"://" prefix: @""]; + [self _handleURLs: selfCopy textToMatch: @"@" prefix: @"mailto:"]; return selfCopy; } diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 43bc8e1c..a55c3dad 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -31,8 +31,6 @@ #import #import -static NSString *defaultUser = @""; - @implementation SOGoFolder + (int) version @@ -341,8 +339,9 @@ static NSString *defaultUser = @""; [self _cacheRoles: acls forUser: uid forObjectAtPath: objectPath]; } - if (!([acls count] || [uid isEqualToString: defaultUser])) - acls = [self aclsForUser: defaultUser forObjectAtPath: objectPathArray]; + if (!([acls count] || [uid isEqualToString: SOGoDefaultUserID])) + acls = [self aclsForUser: SOGoDefaultUserID + forObjectAtPath: objectPathArray]; return acls; } @@ -369,19 +368,14 @@ static NSString *defaultUser = @""; } } -- (void) setRoles: (NSArray *) roles - forUser: (NSString *) uid - forObjectAtPath: (NSArray *) objectPathArray +- (void) _commitRoles: (NSArray *) roles + forUID: (NSString *) uid + forObject: (NSString *) objectPath { EOAdaptorChannel *channel; GCSFolder *folder; NSEnumerator *userRoles; - NSString *SQL, *currentRole, *objectPath; - - [self removeAclsForUsers: [NSArray arrayWithObject: uid] - forObjectAtPath: objectPathArray]; - objectPath = [objectPathArray componentsJoinedByString: @"/"]; - [self _cacheRoles: roles forUser: uid forObjectAtPath: objectPath]; + NSString *SQL, *currentRole; folder = [self ocsFolder]; channel = [folder acquireAclChannel]; @@ -389,21 +383,40 @@ static NSString *defaultUser = @""; currentRole = [userRoles nextObject]; while (currentRole) { - if (![currentRole isEqualToString: SOGoRole_AuthorizedSubscriber]) - { - SQL = [NSString stringWithFormat: @"INSERT INTO %@" - @" (c_object, c_uid, c_role)" - @" VALUES ('/%@', '%@', '%@')", - [folder aclTableName], - objectPath, uid, currentRole]; - [channel evaluateExpressionX: SQL]; - } + SQL = [NSString stringWithFormat: @"INSERT INTO %@" + @" (c_object, c_uid, c_role)" + @" VALUES ('/%@', '%@', '%@')", + [folder aclTableName], + objectPath, uid, currentRole]; + [channel evaluateExpressionX: SQL]; currentRole = [userRoles nextObject]; } [folder releaseChannel: channel]; } +- (void) setRoles: (NSArray *) roles + forUser: (NSString *) uid + forObjectAtPath: (NSArray *) objectPathArray +{ + NSString *objectPath; + NSMutableArray *newRoles; + + [self removeAclsForUsers: [NSArray arrayWithObject: uid] + forObjectAtPath: objectPathArray]; + + newRoles = [NSMutableArray arrayWithArray: roles]; + [newRoles removeObject: SOGoRole_AuthorizedSubscriber]; + [newRoles removeObject: SOGoRole_None]; + objectPath = [objectPathArray componentsJoinedByString: @"/"]; + [self _cacheRoles: newRoles forUser: uid + forObjectAtPath: objectPath]; + if (![newRoles count]) + [newRoles addObject: SOGoRole_None]; + + [self _commitRoles: newRoles forUID: uid forObject: objectPath]; +} + /* acls */ - (NSArray *) defaultAclRoles { diff --git a/SoObjects/SOGo/SOGoObject.h b/SoObjects/SOGo/SOGoObject.h index 5b4eecce..e5a77e73 100644 --- a/SoObjects/SOGo/SOGoObject.h +++ b/SoObjects/SOGo/SOGoObject.h @@ -52,6 +52,8 @@ #define $(class) NSClassFromString(class) +extern NSString *SOGoDefaultUserID; + @interface SOGoObject : NSObject { WOContext *context; diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index 5a0e5015..57b13cd7 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -20,8 +20,8 @@ */ #if LIB_FOUNDATION_LIBRARY -#error SOGo won't work properly with libFoundation. Please use gnustep-base \ - instead. +#error SOGo will not work properly with libFoundation. \ + Please use gnustep-base instead. #endif #import @@ -47,6 +47,8 @@ #import "SOGoObject.h" +NSString *SOGoDefaultUserID = @""; + @interface SOGoObject(Content) - (NSString *)contentAsString; @end diff --git a/SoObjects/SOGo/SOGoPermissions.h b/SoObjects/SOGo/SOGoPermissions.h index e6825554..67ee64be 100644 --- a/SoObjects/SOGo/SOGoPermissions.h +++ b/SoObjects/SOGo/SOGoPermissions.h @@ -32,6 +32,7 @@ extern NSString *SOGoRole_ObjectEraser; extern NSString *SOGoRole_ObjectViewer; extern NSString *SOGoRole_ObjectEditor; extern NSString *SOGoRole_AuthorizedSubscriber; +extern NSString *SOGoRole_None; extern NSString *SOGoRole_FreeBusy; extern NSString *SOGoRole_FreeBusyLookup; diff --git a/SoObjects/SOGo/SOGoPermissions.m b/SoObjects/SOGo/SOGoPermissions.m index a071f019..e750ef31 100644 --- a/SoObjects/SOGo/SOGoPermissions.m +++ b/SoObjects/SOGo/SOGoPermissions.m @@ -28,6 +28,7 @@ NSString *SOGoRole_ObjectEraser = @"ObjectEraser"; NSString *SOGoRole_ObjectViewer = @"ObjectViewer"; NSString *SOGoRole_ObjectEditor = @"ObjectEditor"; NSString *SOGoRole_AuthorizedSubscriber = @"AuthorizedSubscriber"; +NSString *SOGoRole_None = @"None"; NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user */ diff --git a/UI/Common/English.lproj/Localizable.strings b/UI/Common/English.lproj/Localizable.strings index 119c9c32..4ac925e1 100644 --- a/UI/Common/English.lproj/Localizable.strings +++ b/UI/Common/English.lproj/Localizable.strings @@ -3,6 +3,7 @@ /* toolbars */ "Save" = "Save"; "Close" = "Close"; +"Edit User Rights" = "Edit User Rights"; "Home" = "Home"; "Calendar" = "Calendar"; @@ -21,4 +22,6 @@ "Publish the Free/Busy information" = "Publish the Free/Busy information"; +"Default Roles" = "Default Roles"; + "Sorry, the user rights can not be configured for that object." = "Sorry, the user rights can not be configured for that object."; diff --git a/UI/Common/French.lproj/Localizable.strings b/UI/Common/French.lproj/Localizable.strings index dcf84ce1..c18c4068 100644 --- a/UI/Common/French.lproj/Localizable.strings +++ b/UI/Common/French.lproj/Localizable.strings @@ -1,8 +1,7 @@ -/* this file is in UTF-8 format! */ - /* toolbars */ "Save" = "Sauver"; "Close" = "Fermer"; +"Edit User Rights" = "Édition des droits"; "Home" = "Accueil"; "Calendar" = "Agenda"; @@ -24,4 +23,6 @@ "(Unchecked = assistant, checked = delegate)" = "(Coché = assistant, décoché = délégué)"; "Publish the Free/Busy information" = "Publier l'occupation du temps"; +"Default Roles" = "Rôles par défaut"; + "Sorry, the user rights can not be configured for that object." = "Sorry, the user rights can not be configured for that object."; diff --git a/UI/Common/UIxAclEditor.m b/UI/Common/UIxAclEditor.m index 12a45f50..e0328ace 100644 --- a/UI/Common/UIxAclEditor.m +++ b/UI/Common/UIxAclEditor.m @@ -84,6 +84,11 @@ return [self _displayNameForUID: ownerLogin]; } +- (NSString *) defaultUserID +{ + return SOGoDefaultUserID; +} + - (void) _prepareUsers { NSEnumerator *aclsEnum; @@ -98,6 +103,7 @@ { currentUID = [currentAcl objectForKey: @"c_uid"]; if (!([currentUID isEqualToString: ownerLogin] + || [currentUID isEqualToString: SOGoDefaultUserID] || [users containsObject: currentUID])) [users addObject: currentUID]; currentAcl = [aclsEnum nextObject]; diff --git a/UI/Common/UIxObjectActions.m b/UI/Common/UIxObjectActions.m index 1d154a66..f3cf9930 100644 --- a/UI/Common/UIxObjectActions.m +++ b/UI/Common/UIxObjectActions.m @@ -27,6 +27,7 @@ #import #import #import +#import #import "UIxObjectActions.h" @@ -49,9 +50,9 @@ um = [LDAPUserManager sharedUserManager]; if ([um contactInfosForUserWithUIDorEmail: uid]) { - clientObject = [self clientObject]; - [clientObject setRoles: [clientObject defaultAclRoles] - forUser: uid]; + clientObject = [self clientObject]; + [clientObject setRoles: [clientObject aclsForUser: uid] + forUser: uid]; code = 204; } } @@ -78,7 +79,8 @@ um = [LDAPUserManager sharedUserManager]; if ([um contactInfosForUserWithUIDorEmail: uid]) { - [[self clientObject] removeAclsForUsers: [NSArray arrayWithObject: uid]]; + [[self clientObject] removeAclsForUsers: + [NSArray arrayWithObject: uid]]; code = 204; } } diff --git a/UI/Common/UIxUserRightsEditor.m b/UI/Common/UIxUserRightsEditor.m index 35b69761..8ec44dd4 100644 --- a/UI/Common/UIxUserRightsEditor.m +++ b/UI/Common/UIxUserRightsEditor.m @@ -24,6 +24,7 @@ #import #import #import +#import #import "UIxUserRightsEditor.h" @@ -52,10 +53,15 @@ return uid; } +- (BOOL) userIsDefaultUser +{ + return [uid isEqualToString: SOGoDefaultUserID]; +} + - (NSString *) userDisplayName { LDAPUserManager *um; - + um = [LDAPUserManager sharedUserManager]; return [NSString stringWithFormat: @"%@ <%@>", @@ -66,9 +72,10 @@ - (BOOL) _initRights { BOOL response; - NSString *newUID, *email; + NSString *newUID; LDAPUserManager *um; SOGoObject *clientObject; + unsigned int count; response = NO; @@ -76,15 +83,17 @@ if ([newUID length] > 0) { um = [LDAPUserManager sharedUserManager]; - email = [um getEmailForUID: newUID]; - if ([email length] > 0) + if ([newUID isEqualToString: SOGoDefaultUserID] + || [[um getEmailForUID: newUID] length] > 0) { ASSIGN (uid, newUID); clientObject = [self clientObject]; [userRights addObjectsFromArray: [clientObject aclsForUser: uid]]; - if (![userRights count]) - [userRights addObjectsFromArray: [clientObject defaultAclRoles]]; - + count = [userRights count]; + if (!count || (count == 1 && [[userRights objectAtIndex: 0] + isEqualToString: SOGoRole_None])) + [userRights setArray: [clientObject defaultAclRoles]]; + response = YES; } } @@ -118,8 +127,7 @@ else { [self updateRights]; - [[self clientObject] setRoles: userRights - forUser: uid]; + [[self clientObject] setRoles: userRights forUser: uid]; response = [self jsCloseWithRefreshMethod: nil]; } diff --git a/UI/Contacts/English.lproj/Localizable.strings b/UI/Contacts/English.lproj/Localizable.strings index 4233453d..cca322a0 100644 --- a/UI/Contacts/English.lproj/Localizable.strings +++ b/UI/Contacts/English.lproj/Localizable.strings @@ -102,6 +102,7 @@ "Unable to subscribe to that folder!" = "Unable to subscribe to that folder!"; +"Default Roles" = "Default Roles"; "User rights for:" = "User rights for:"; "This person can add cards to this addressbook." diff --git a/UI/Contacts/French.lproj/Localizable.strings b/UI/Contacts/French.lproj/Localizable.strings index 46f66571..aaf6e207 100644 --- a/UI/Contacts/French.lproj/Localizable.strings +++ b/UI/Contacts/French.lproj/Localizable.strings @@ -115,6 +115,7 @@ "Unable to subscribe to that folder!" = "Impossible de vous inscrire à ce dossier!"; +"Default Roles" = "Rôles par défaut"; "User rights for:" = "Autorisations pour :"; "This person can add cards to this addressbook." diff --git a/UI/MainUI/product.plist b/UI/MainUI/product.plist index 44b3503d..2ce04921 100644 --- a/UI/MainUI/product.plist +++ b/UI/MainUI/product.plist @@ -74,7 +74,7 @@ SOGoFreeBusyObject = { methods = { ajaxRead = { - protectedBy = "View"; + protectedBy = ""; pageName = "SOGoUserHomePage"; actionName = "readFreeBusy"; }; diff --git a/UI/Scheduler/English.lproj/Localizable.strings b/UI/Scheduler/English.lproj/Localizable.strings index 1a370a3f..050f12de 100644 --- a/UI/Scheduler/English.lproj/Localizable.strings +++ b/UI/Scheduler/English.lproj/Localizable.strings @@ -82,6 +82,7 @@ "Forbidden" = "Forbidden"; /* acls */ +"Default Roles" = "Default Roles"; "User rights for:" = "User rights for:"; "label_Public" = "Public"; "label_Private" = "Private"; diff --git a/UI/Scheduler/French.lproj/Localizable.strings b/UI/Scheduler/French.lproj/Localizable.strings index 266d9dfe..46b02d33 100644 --- a/UI/Scheduler/French.lproj/Localizable.strings +++ b/UI/Scheduler/French.lproj/Localizable.strings @@ -83,6 +83,7 @@ "Forbidden" = "Accès non autorisée"; /* acls */ +"Default Roles" = "Rôles par défaut"; "User rights for:" = "Autorisations pour :"; "label_Public" = "Public"; "label_Private" = "Privé"; diff --git a/UI/Templates/ContactsUI/UIxContactsListView.wox b/UI/Templates/ContactsUI/UIxContactsListView.wox index 2b007b12..49349d8c 100644 --- a/UI/Templates/ContactsUI/UIxContactsListView.wox +++ b/UI/Templates/ContactsUI/UIxContactsListView.wox @@ -13,7 +13,7 @@ - + - +
- + + + +