merge of '36df3bcfd6c56f483f2676ceb6b6757a6506dbb7'
and 'f12c75a72aac13edc9728fe5a656c622487836dd' Monotone-Parent: 36df3bcfd6c56f483f2676ceb6b6757a6506dbb7 Monotone-Parent: f12c75a72aac13edc9728fe5a656c622487836dd Monotone-Revision: 0c622c14bea584c75539ec4bf9d8ca29899745ef Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-09-14T22:05:54 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
commit
d4c43b432e
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
2007-09-14 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoObject.m ([SOGoObject -labelForKey:key]): new
|
||||
method that returns translated strings for controller bundles
|
||||
(same as what UIxComponent does for view bundles).
|
||||
([SOGoObject -pathArrayToSOGoObject]): new method that returns
|
||||
the real path to a subscribed folder (if subscribed).
|
||||
([SOGoObject +globallyUniqueObjectId]): move method from SOGoFolder.
|
||||
([SOGoObject -globallyUniqueObjectId]): new instance method
|
||||
calling its class equivalent.
|
||||
|
||||
2007-09-12 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/MainUI/SOGoRootPage.m ([SOGoRootPage -defaultAction]): test
|
||||
whether the user is logged in and if so, redirect to his/her
|
||||
homepage.
|
||||
([SOGoRootPage -appendToResponse:inContext:]): removed useless
|
||||
method.
|
||||
|
||||
2007-09-11 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
|
||||
|
|
2
NEWS
2
NEWS
|
@ -4,6 +4,8 @@
|
|||
- fixed a bug where a false positive happening whenever a wrong user login was
|
||||
given during an indirect bind;
|
||||
- deleting a message no longer expunges its parent folder;
|
||||
- implemented support for multiple calendars;
|
||||
- it is not possible to rename folders;
|
||||
- fixed search in message content;
|
||||
- added tooltips for toolbar buttons (English and French);
|
||||
- added checkmarks in live search options popup menus;
|
||||
|
|
1
SoObjects/Appointments/English.lproj/Localizable.strings
Normal file
1
SoObjects/Appointments/English.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Calendar" = "Personal Calendar";
|
1
SoObjects/Appointments/French.lproj/Localizable.strings
Normal file
1
SoObjects/Appointments/French.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Calendar" = "Agenda personnel";
|
|
@ -6,7 +6,9 @@ WOBUNDLE_NAME = Appointments
|
|||
|
||||
Appointments_PRINCIPAL_CLASS = SOGoAppointmentsProduct
|
||||
|
||||
# Appointments_LANGUAGES = English French
|
||||
Appointments_LANGUAGES = English French German
|
||||
|
||||
Appointments_LOCALIZED_RESOURCE_FILES=Localizable.strings
|
||||
|
||||
Appointments_OBJC_FILES = \
|
||||
Product.m \
|
||||
|
@ -17,6 +19,7 @@ Appointments_OBJC_FILES = \
|
|||
SOGoAppointmentObject.m \
|
||||
SOGoTaskObject.m \
|
||||
SOGoAppointmentFolder.m \
|
||||
SOGoAppointmentFolders.m \
|
||||
SOGoGroupAppointmentFolder.m \
|
||||
SOGoFreeBusyObject.m \
|
||||
\
|
||||
|
|
1
SoObjects/Appointments/German.lproj/Localizable.strings
Normal file
1
SoObjects/Appointments/German.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Calendar" = "Personal Calendar";
|
|
@ -53,6 +53,8 @@
|
|||
NSMutableDictionary *uidToFilename;
|
||||
}
|
||||
|
||||
- (BOOL) isActive;
|
||||
|
||||
/* selection */
|
||||
|
||||
- (NSArray *) calendarUIDs;
|
||||
|
@ -113,8 +115,6 @@
|
|||
|
||||
- (NSArray *) fetchAllSOGoAppointments;
|
||||
|
||||
- (NSArray *) calendarFolders;
|
||||
|
||||
- (NSString *) roleForComponentsWithAccessClass: (iCalAccessClass) accessClass
|
||||
forUser: (NSString *) uid;
|
||||
|
||||
|
|
|
@ -125,11 +125,6 @@ static NSNumber *sharedYes = nil;
|
|||
return logger;
|
||||
}
|
||||
|
||||
- (BOOL) folderIsMandatory
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* selection */
|
||||
|
||||
- (NSArray *) calendarUIDs
|
||||
|
@ -746,7 +741,7 @@ static NSNumber *sharedYes = nil;
|
|||
privacySqlString = @"and (c_isopaque = 1)";
|
||||
else
|
||||
{
|
||||
#warning we do not manage all the user's possible emails
|
||||
#warning we do not manage all the possible user emails
|
||||
email = [[activeUser primaryIdentity] objectForKey: @"email"];
|
||||
|
||||
privacySqlString
|
||||
|
@ -905,7 +900,6 @@ static NSNumber *sharedYes = nil;
|
|||
component: _component];
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
|
||||
to: (NSCalendarDate *) _endDate
|
||||
{
|
||||
|
@ -1041,21 +1035,28 @@ static NSNumber *sharedYes = nil;
|
|||
/* Note: can return NSNull objects in the array! */
|
||||
NSMutableArray *folders;
|
||||
NSEnumerator *e;
|
||||
NSString *uid;
|
||||
|
||||
NSString *uid, *ownerLogin;
|
||||
id folder;
|
||||
|
||||
ownerLogin = [self ownerInContext: context];
|
||||
|
||||
if ([_uids count] == 0) return nil;
|
||||
folders = [NSMutableArray arrayWithCapacity:16];
|
||||
e = [_uids objectEnumerator];
|
||||
while ((uid = [e nextObject])) {
|
||||
id folder;
|
||||
while ((uid = [e nextObject]))
|
||||
{
|
||||
if ([uid isEqualToString: ownerLogin])
|
||||
folder = self;
|
||||
else
|
||||
{
|
||||
folder = [self lookupCalendarFolderForUID: uid];
|
||||
if (![folder isNotNull])
|
||||
[self logWithFormat:@"Note: did not find folder for uid: '%@'", uid];
|
||||
}
|
||||
|
||||
folder = [self lookupCalendarFolderForUID: uid];
|
||||
if (![folder isNotNull])
|
||||
[self logWithFormat:@"Note: did not find folder for uid: '%@'", uid];
|
||||
|
||||
/* Note: intentionally add 'null' folders to allow a mapping */
|
||||
[folders addObject:folder ? folder : [NSNull null]];
|
||||
}
|
||||
[folders addObject: folder];
|
||||
}
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -1196,67 +1197,67 @@ static NSNumber *sharedYes = nil;
|
|||
return events;
|
||||
}
|
||||
|
||||
#warning We only support ONE calendar per user at this time
|
||||
- (BOOL) _appendSubscribedFolders: (NSDictionary *) subscribedFolders
|
||||
toFolderList: (NSMutableArray *) calendarFolders
|
||||
{
|
||||
NSEnumerator *keys;
|
||||
NSString *currentKey;
|
||||
NSMutableDictionary *currentCalendar;
|
||||
BOOL firstShouldBeActive;
|
||||
unsigned int count;
|
||||
// #warning We only support ONE calendar per user at this time
|
||||
// - (BOOL) _appendSubscribedFolders: (NSDictionary *) subscribedFolders
|
||||
// toFolderList: (NSMutableArray *) calendarFolders
|
||||
// {
|
||||
// NSEnumerator *keys;
|
||||
// NSString *currentKey;
|
||||
// NSMutableDictionary *currentCalendar;
|
||||
// BOOL firstShouldBeActive;
|
||||
// unsigned int count;
|
||||
|
||||
firstShouldBeActive = YES;
|
||||
// firstShouldBeActive = YES;
|
||||
|
||||
keys = [[subscribedFolders allKeys] objectEnumerator];
|
||||
currentKey = [keys nextObject];
|
||||
count = 1;
|
||||
while (currentKey)
|
||||
{
|
||||
currentCalendar = [NSMutableDictionary new];
|
||||
[currentCalendar autorelease];
|
||||
[currentCalendar
|
||||
setDictionary: [subscribedFolders objectForKey: currentKey]];
|
||||
[currentCalendar setObject: currentKey forKey: @"folder"];
|
||||
[calendarFolders addObject: currentCalendar];
|
||||
if ([[currentCalendar objectForKey: @"active"] boolValue])
|
||||
firstShouldBeActive = NO;
|
||||
count++;
|
||||
currentKey = [keys nextObject];
|
||||
}
|
||||
// keys = [[subscribedFolders allKeys] objectEnumerator];
|
||||
// currentKey = [keys nextObject];
|
||||
// count = 1;
|
||||
// while (currentKey)
|
||||
// {
|
||||
// currentCalendar = [NSMutableDictionary new];
|
||||
// [currentCalendar autorelease];
|
||||
// [currentCalendar
|
||||
// setDictionary: [subscribedFolders objectForKey: currentKey]];
|
||||
// [currentCalendar setObject: currentKey forKey: @"folder"];
|
||||
// [calendarFolders addObject: currentCalendar];
|
||||
// if ([[currentCalendar objectForKey: @"active"] boolValue])
|
||||
// firstShouldBeActive = NO;
|
||||
// count++;
|
||||
// currentKey = [keys nextObject];
|
||||
// }
|
||||
|
||||
return firstShouldBeActive;
|
||||
}
|
||||
// return firstShouldBeActive;
|
||||
// }
|
||||
|
||||
- (NSArray *) calendarFolders
|
||||
{
|
||||
NSMutableDictionary *userCalendar, *calendarDict;
|
||||
NSMutableArray *calendarFolders;
|
||||
SOGoUser *calendarUser;
|
||||
BOOL firstActive;
|
||||
// - (NSArray *) calendarFolders
|
||||
// {
|
||||
// NSMutableDictionary *userCalendar, *calendarDict;
|
||||
// NSMutableArray *calendarFolders;
|
||||
// SOGoUser *calendarUser;
|
||||
// BOOL firstActive;
|
||||
|
||||
calendarFolders = [NSMutableArray new];
|
||||
[calendarFolders autorelease];
|
||||
// calendarFolders = [NSMutableArray new];
|
||||
// [calendarFolders autorelease];
|
||||
|
||||
calendarUser = [SOGoUser userWithLogin: [self ownerInContext: context]
|
||||
roles: nil];
|
||||
userCalendar = [NSMutableDictionary new];
|
||||
[userCalendar autorelease];
|
||||
[userCalendar setObject: @"/" forKey: @"folder"];
|
||||
[userCalendar setObject: @"Calendar" forKey: @"displayName"];
|
||||
[calendarFolders addObject: userCalendar];
|
||||
// calendarUser = [SOGoUser userWithLogin: [self ownerInContext: context]
|
||||
// roles: nil];
|
||||
// userCalendar = [NSMutableDictionary new];
|
||||
// [userCalendar autorelease];
|
||||
// [userCalendar setObject: @"/" forKey: @"folder"];
|
||||
// [userCalendar setObject: @"Calendar" forKey: @"displayName"];
|
||||
// [calendarFolders addObject: userCalendar];
|
||||
|
||||
calendarDict = [[calendarUser userSettings] objectForKey: @"Calendar"];
|
||||
firstActive = [[calendarDict objectForKey: @"activateUserFolder"] boolValue];
|
||||
firstActive = ([self _appendSubscribedFolders:
|
||||
[calendarDict objectForKey: @"SubscribedFolders"]
|
||||
toFolderList: calendarFolders]
|
||||
|| firstActive);
|
||||
[userCalendar setObject: [NSNumber numberWithBool: firstActive]
|
||||
forKey: @"active"];
|
||||
// calendarDict = [[calendarUser userSettings] objectForKey: @"Calendar"];
|
||||
// firstActive = [[calendarDict objectForKey: @"activateUserFolder"] boolValue];
|
||||
// firstActive = ([self _appendSubscribedFolders:
|
||||
// [calendarDict objectForKey: @"SubscribedFolders"]
|
||||
// toFolderList: calendarFolders]
|
||||
// || firstActive);
|
||||
// [userCalendar setObject: [NSNumber numberWithBool: firstActive]
|
||||
// forKey: @"active"];
|
||||
|
||||
return calendarFolders;
|
||||
}
|
||||
// return calendarFolders;
|
||||
// }
|
||||
|
||||
// - (NSArray *) fetchContentObjectNames
|
||||
// {
|
||||
|
@ -1297,49 +1298,16 @@ static NSNumber *sharedYes = nil;
|
|||
return @"IPF.Appointment";
|
||||
}
|
||||
|
||||
/* hack until we permit more than 1 cal per user */
|
||||
- (NSArray *) _fixedPath: (NSArray *) objectPath
|
||||
- (BOOL) isActive
|
||||
{
|
||||
NSMutableArray *newPath;
|
||||
NSUserDefaults *settings;
|
||||
NSArray *activeFolders;
|
||||
|
||||
newPath = [NSMutableArray arrayWithArray: objectPath];
|
||||
if ([newPath count] > 2)
|
||||
{
|
||||
if (![[newPath objectAtIndex: 2] isEqualToString: @"personal"])
|
||||
[newPath insertObject: @"personal" atIndex: 2];
|
||||
}
|
||||
else
|
||||
[newPath addObject: @"personal"];
|
||||
settings = [[context activeUser] userSettings];
|
||||
activeFolders
|
||||
= [[settings objectForKey: @"Calendar"] objectForKey: @"ActiveFolders"];
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
return [super aclUsersForObjectAtPath: [self _fixedPath: objectPathArray]];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
return [super aclsForUser: uid
|
||||
forObjectAtPath: [self _fixedPath: objectPathArray]];
|
||||
}
|
||||
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
[super setRoles: roles
|
||||
forUser: uid
|
||||
forObjectAtPath: [self _fixedPath: objectPathArray]];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) users
|
||||
forObjectAtPath: (NSArray *) objectPathArray
|
||||
{
|
||||
[super removeAclsForUsers: users
|
||||
forObjectAtPath: [self _fixedPath: objectPathArray]];
|
||||
return [activeFolders containsObject: nameInContainer];
|
||||
}
|
||||
|
||||
@end /* SOGoAppointmentFolder */
|
||||
|
|
|
@ -46,13 +46,6 @@
|
|||
|
||||
@interface SOGoAppointmentObject : SOGoCalendarComponent
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (id) lookupHomeFolderForUID: (NSString *) _uid
|
||||
inContext: (id) _ctx;
|
||||
- (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids
|
||||
inContext: (id) _ctx;
|
||||
|
||||
/* "iCal multifolder saves" */
|
||||
|
||||
- (NSException *) saveContentString: (NSString *) _iCal
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "NSArray+Appointments.h"
|
||||
#import "SOGoAppointmentFolder.h"
|
||||
|
||||
#import "SOGoAppointmentObject.h"
|
||||
|
||||
@implementation SOGoAppointmentObject
|
||||
|
@ -96,16 +98,6 @@
|
|||
return uids;
|
||||
}
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx {
|
||||
// TODO: what does this do? lookup the home of the organizer?
|
||||
return [[self container] lookupHomeFolderForUID:_uid inContext:_ctx];
|
||||
}
|
||||
- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx {
|
||||
return [[self container] lookupCalendarFoldersForUIDs:_uids inContext:_ctx];
|
||||
}
|
||||
|
||||
/* store in all the other folders */
|
||||
|
||||
- (NSException *) saveContentString: (NSString *) _iCal
|
||||
|
@ -115,8 +107,8 @@
|
|||
id folder;
|
||||
NSException *allErrors = nil;
|
||||
|
||||
e = [[self lookupCalendarFoldersForUIDs:_uids inContext: context]
|
||||
objectEnumerator];
|
||||
e = [[container lookupCalendarFoldersForUIDs:_uids inContext: context]
|
||||
objectEnumerator];
|
||||
while ((folder = [e nextObject]) != nil) {
|
||||
NSException *error;
|
||||
SOGoAppointmentObject *apt;
|
||||
|
@ -160,8 +152,8 @@
|
|||
id folder;
|
||||
NSException *allErrors = nil;
|
||||
|
||||
e = [[self lookupCalendarFoldersForUIDs:_uids inContext: context]
|
||||
objectEnumerator];
|
||||
e = [[container lookupCalendarFoldersForUIDs:_uids inContext: context]
|
||||
objectEnumerator];
|
||||
while ((folder = [e nextObject])) {
|
||||
NSException *error;
|
||||
SOGoAppointmentObject *apt;
|
||||
|
|
|
@ -44,13 +44,6 @@
|
|||
|
||||
@interface SOGoTaskObject : SOGoCalendarComponent
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (id) lookupHomeFolderForUID: (NSString *) _uid
|
||||
inContext: (id) _ctx;
|
||||
- (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids
|
||||
inContext: (id) _ctx;
|
||||
|
||||
/* "iCal multifolder saves" */
|
||||
|
||||
- (NSException *) saveContentString: (NSString *) _iCal
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#import "NSArray+Appointments.h"
|
||||
#import "SOGoAptMailNotification.h"
|
||||
#import "SOGoAppointmentFolder.h"
|
||||
|
||||
#import "SOGoTaskObject.h"
|
||||
|
||||
|
@ -118,17 +119,6 @@ static NSString *mailTemplateDefaultLanguage = nil;
|
|||
return uids;
|
||||
}
|
||||
|
||||
/* folder management */
|
||||
|
||||
- (id)lookupHomeFolderForUID:(NSString *)_uid inContext:(id)_ctx {
|
||||
// TODO: what does this do? lookup the home of the organizer?
|
||||
return [[self container] lookupHomeFolderForUID:_uid inContext:_ctx];
|
||||
}
|
||||
|
||||
- (NSArray *)lookupCalendarFoldersForUIDs:(NSArray *)_uids inContext:(id)_ctx {
|
||||
return [[self container] lookupCalendarFoldersForUIDs:_uids inContext:_ctx];
|
||||
}
|
||||
|
||||
/* store in all the other folders */
|
||||
|
||||
- (NSException *)saveContentString:(NSString *)_iCal inUIDs:(NSArray *)_uids {
|
||||
|
@ -136,7 +126,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
|
|||
id folder;
|
||||
NSException *allErrors = nil;
|
||||
|
||||
e = [[self lookupCalendarFoldersForUIDs: _uids inContext: context]
|
||||
e = [[container lookupCalendarFoldersForUIDs: _uids inContext: context]
|
||||
objectEnumerator];
|
||||
while ((folder = [e nextObject]) != nil) {
|
||||
NSException *error;
|
||||
|
@ -175,7 +165,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
|
|||
id folder;
|
||||
NSException *allErrors = nil;
|
||||
|
||||
e = [[self lookupCalendarFoldersForUIDs: _uids inContext: context]
|
||||
e = [[container lookupCalendarFoldersForUIDs: _uids inContext: context]
|
||||
objectEnumerator];
|
||||
while ((folder = [e nextObject])) {
|
||||
NSException *error;
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
};
|
||||
|
||||
classes = {
|
||||
SOGoAppointmentFolder = {
|
||||
superclass = "SOGoParentFolder";
|
||||
};
|
||||
SOGoAppointmentFolder = {
|
||||
superclass = "SOGoFolder";
|
||||
defaultRoles = {
|
||||
|
|
1
SoObjects/Contacts/English.lproj/Localizable.strings
Normal file
1
SoObjects/Contacts/English.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Address Book" = "Personal Address Book";
|
1
SoObjects/Contacts/French.lproj/Localizable.strings
Normal file
1
SoObjects/Contacts/French.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Address Book" = "Carnet d'adresses personnel";
|
1
SoObjects/Contacts/German.lproj/Localizable.strings
Normal file
1
SoObjects/Contacts/German.lproj/Localizable.strings
Normal file
|
@ -0,0 +1 @@
|
|||
"Personal Calendar" = "Personal Calendar";
|
|
@ -27,25 +27,11 @@
|
|||
TaskItems IPF.Task
|
||||
JournalItems IPF.Journal */
|
||||
|
||||
// #import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
|
||||
// #import <NGObjWeb/NSException+HTTP.h>
|
||||
// #import <NGObjWeb/WOApplication.h>
|
||||
// #import <NGObjWeb/WOContext.h>
|
||||
// #import <NGObjWeb/WOContext+SoObjects.h>
|
||||
// #import <NGObjWeb/WOResponse.h>
|
||||
// #import <NGObjWeb/SoUser.h>
|
||||
|
||||
// #import <GDLContentStore/GCSFolderManager.h>
|
||||
// #import <GDLContentStore/GCSChannelManager.h>
|
||||
// #import <GDLAccess/EOAdaptorChannel.h>
|
||||
// #import <GDLContentStore/NSURL+GCS.h>
|
||||
|
||||
#import <SoObjects/SOGo/LDAPUserManager.h>
|
||||
// #import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "SOGoContactGCSFolder.h"
|
||||
#import "SOGoContactLDAPFolder.h"
|
||||
|
@ -85,4 +71,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString *) defaultFolderName
|
||||
{
|
||||
return @"Personal Address Book";
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/SoObject+SoDAV.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
|
@ -41,11 +42,6 @@
|
|||
|
||||
@implementation SOGoContactGCSFolder
|
||||
|
||||
- (BOOL) folderIsMandatory
|
||||
{
|
||||
return [nameInContainer isEqualToString: @"personal"];
|
||||
}
|
||||
|
||||
/* name lookup */
|
||||
|
||||
- (id <SOGoContactObject>) lookupContactWithId: (NSString *) recordId
|
||||
|
|
|
@ -257,6 +257,11 @@
|
|||
}
|
||||
|
||||
/* acls */
|
||||
- (NSString *) ownerInContext: (WOContext *) noContext
|
||||
{
|
||||
return @"nobody";
|
||||
}
|
||||
|
||||
/* TODO: this might change one day when we support LDAP acls */
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
|
|
|
@ -9,12 +9,7 @@
|
|||
|
||||
classes = {
|
||||
SOGoContactFolders = {
|
||||
superclass = "SOGoFolder";
|
||||
protectedBy = "Access Contents Information";
|
||||
defaultRoles = {
|
||||
"Access Contents Information" = ( "Authenticated" );
|
||||
"WebDAV Access" = ( "Authenticated" );
|
||||
};
|
||||
superclass = "SOGoParentFolder";
|
||||
};
|
||||
SOGoContactGCSFolder = {
|
||||
superclass = "SOGoFolder";
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
@interface NSDictionary (SOGoDictionaryUtilities)
|
||||
|
||||
+ (NSDictionary *) dictionaryFromStringsFile: (NSString *) file;
|
||||
|
||||
- (NSString *) jsonRepresentation;
|
||||
- (NSString *) keysWithFormat: (NSString *) keyFormat;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "NSArray+Utilities.h"
|
||||
|
@ -29,6 +30,25 @@
|
|||
|
||||
@implementation NSDictionary (SOGoDictionaryUtilities)
|
||||
|
||||
+ (NSDictionary *) dictionaryFromStringsFile: (NSString *) file
|
||||
{
|
||||
NSString *serialized;
|
||||
NSMutableData *content;
|
||||
NSDictionary *newDictionary;
|
||||
|
||||
content = [NSMutableData new];
|
||||
[content appendBytes: "{" length: 1];
|
||||
[content appendData: [NSData dataWithContentsOfFile: file]];
|
||||
[content appendBytes: "}" length: 1];
|
||||
serialized = [[NSString alloc] initWithData: content
|
||||
encoding: NSUTF8StringEncoding];
|
||||
[content release];
|
||||
newDictionary = [serialized propertyList];
|
||||
[serialized release];
|
||||
|
||||
return newDictionary;
|
||||
}
|
||||
|
||||
- (NSString *) jsonRepresentation
|
||||
{
|
||||
NSMutableArray *values;
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
needsLocation = NO;
|
||||
tmp = [[self nameInContainer] stringByDeletingPathExtension];
|
||||
if ([tmp isEqualToString:@"new"]) {
|
||||
tmp = [[[self container] class] globallyUniqueObjectId];
|
||||
tmp = [self globallyUniqueObjectId];
|
||||
needsLocation = YES;
|
||||
|
||||
[self debugWithFormat:
|
||||
|
@ -359,7 +359,7 @@
|
|||
|
||||
- (NSArray *) aclUsers
|
||||
{
|
||||
return [container aclUsersForObjectAtPath: [self pathArrayToSoObject]];
|
||||
return [container aclUsersForObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
|
@ -369,7 +369,7 @@
|
|||
|
||||
acls = [NSMutableArray array];
|
||||
ownAcls = [container aclsForUser: uid
|
||||
forObjectAtPath: [self pathArrayToSoObject]];
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
[acls addObjectsFromArray: ownAcls];
|
||||
containerAcls = [container aclsForUser: uid];
|
||||
if ([containerAcls count] > 0)
|
||||
|
|
|
@ -43,23 +43,18 @@
|
|||
|
||||
@interface SOGoFolder : SOGoObject
|
||||
{
|
||||
NSString *displayName;
|
||||
NSMutableString *displayName;
|
||||
NSString *ocsPath;
|
||||
GCSFolder *ocsFolder;
|
||||
NSMutableDictionary *aclCache;
|
||||
}
|
||||
|
||||
+ (NSString *) globallyUniqueObjectId;
|
||||
+ (id) folderWithSubscriptionReference: (NSString *) reference
|
||||
inContainer: (id) aContainer;
|
||||
|
||||
/* accessors */
|
||||
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer;
|
||||
- (id) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer;
|
||||
|
||||
- (void) setDisplayName: (NSString *) newDisplayName;
|
||||
- (NSString *) displayName;
|
||||
|
||||
- (void) setOCSPath: (NSString *)_Path;
|
||||
|
@ -79,10 +74,11 @@
|
|||
- (NSString *) outlookFolderClass;
|
||||
|
||||
- (BOOL) folderIsMandatory;
|
||||
- (NSString *) folderType;
|
||||
|
||||
- (BOOL) create;
|
||||
- (NSException *) delete;
|
||||
|
||||
- (void) renameTo: (NSString *) newName;
|
||||
/* dav */
|
||||
- (NSArray *) davNamespaces;
|
||||
|
||||
|
|
|
@ -19,9 +19,6 @@
|
|||
02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <unistd.h>
|
||||
#import <stdlib.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
@ -38,9 +35,11 @@
|
|||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
#import <GDLContentStore/GCSChannelManager.h>
|
||||
#import <GDLContentStore/GCSFolderManager.h>
|
||||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <GDLContentStore/GCSFolderType.h>
|
||||
#import <GDLContentStore/NSURL+GCS.h>
|
||||
#import <SaxObjC/XMLNamespaces.h>
|
||||
|
||||
#import "NSArray+Utilities.h"
|
||||
|
@ -67,40 +66,29 @@ static NSString *defaultUserID = @"<default>";
|
|||
NSStringFromClass([self superclass]), [super version]);
|
||||
}
|
||||
|
||||
+ (NSString *) globallyUniqueObjectId
|
||||
{
|
||||
/*
|
||||
4C08AE1A-A808-11D8-AC5A-000393BBAFF6
|
||||
SOGo-Web-28273-18283-288182
|
||||
printf( "%x", *(int *) &f);
|
||||
*/
|
||||
static int pid = 0;
|
||||
static int sequence = 0;
|
||||
static float rndm = 0;
|
||||
float f;
|
||||
|
||||
if (pid == 0)
|
||||
{ /* break if we fork ;-) */
|
||||
pid = getpid();
|
||||
rndm = random();
|
||||
}
|
||||
sequence++;
|
||||
f = [[NSDate date] timeIntervalSince1970];
|
||||
|
||||
return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
|
||||
pid, (int) f, sequence++, random];
|
||||
}
|
||||
|
||||
+ (id) folderWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer
|
||||
+ (id) folderWithSubscriptionReference: (NSString *) reference
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
id newFolder;
|
||||
NSArray *elements, *pathElements;
|
||||
NSString *ocsPath, *objectPath, *owner, *ocsName, *folderName;
|
||||
|
||||
newFolder = [[self alloc] initWithName: aName
|
||||
andDisplayName: aDisplayName
|
||||
elements = [reference componentsSeparatedByString: @":"];
|
||||
owner = [elements objectAtIndex: 0];
|
||||
objectPath = [elements objectAtIndex: 1];
|
||||
pathElements = [objectPath componentsSeparatedByString: @"/"];
|
||||
if ([pathElements count] > 1)
|
||||
ocsName = [pathElements objectAtIndex: 1];
|
||||
else
|
||||
ocsName = @"personal";
|
||||
|
||||
ocsPath = [NSString stringWithFormat: @"/Users/%@/%@/%@",
|
||||
owner, [pathElements objectAtIndex: 0], ocsName];
|
||||
folderName = [NSString stringWithFormat: @"%@_%@", owner, ocsName];
|
||||
newFolder = [[self alloc] initWithName: folderName
|
||||
inContainer: aContainer];
|
||||
[newFolder autorelease];
|
||||
[newFolder setOCSPath: ocsPath];
|
||||
[newFolder setOwner: owner];
|
||||
|
||||
return newFolder;
|
||||
}
|
||||
|
@ -118,17 +106,6 @@ static NSString *defaultUserID = @"<default>";
|
|||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithName: (NSString *) aName
|
||||
andDisplayName: (NSString *) aDisplayName
|
||||
inContainer: (id) aContainer
|
||||
{
|
||||
if ((self = [self initWithName: aName
|
||||
inContainer: aContainer]))
|
||||
ASSIGN (displayName, aDisplayName);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[ocsFolder release];
|
||||
|
@ -147,13 +124,12 @@ static NSString *defaultUserID = @"<default>";
|
|||
|
||||
- (void) setOCSPath: (NSString *) _path
|
||||
{
|
||||
if ([ocsPath isEqualToString:_path])
|
||||
return;
|
||||
|
||||
if (ocsPath)
|
||||
[self warnWithFormat:@"GCS path is already set! '%@'", _path];
|
||||
|
||||
ASSIGNCOPY(ocsPath, _path);
|
||||
if (![ocsPath isEqualToString:_path])
|
||||
{
|
||||
if (ocsPath)
|
||||
[self warnWithFormat: @"GCS path is already set! '%@'", _path];
|
||||
ASSIGN (ocsPath, _path);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) ocsPath
|
||||
|
@ -178,16 +154,75 @@ static NSString *defaultUserID = @"<default>";
|
|||
|
||||
- (BOOL) folderIsMandatory
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return [nameInContainer isEqualToString: @"personal"];
|
||||
}
|
||||
|
||||
return NO;
|
||||
- (void) _setDisplayNameFromRow: (NSDictionary *) row
|
||||
{
|
||||
NSString *currentLogin, *ownerLogin;
|
||||
NSDictionary *ownerIdentity;
|
||||
|
||||
displayName
|
||||
= [NSMutableString stringWithString: [row objectForKey: @"c_foldername"]];
|
||||
currentLogin = [[context activeUser] login];
|
||||
ownerLogin = [self ownerInContext: context];
|
||||
if (![currentLogin isEqualToString: ownerLogin])
|
||||
{
|
||||
ownerIdentity = [[SOGoUser userWithLogin: ownerLogin roles: nil]
|
||||
primaryIdentity];
|
||||
[displayName appendFormat: @" (%@ <%@>)",
|
||||
[ownerIdentity objectForKey: @"fullName"],
|
||||
[ownerIdentity objectForKey: @"email"]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _fetchDisplayName
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql;
|
||||
NSArray *attrs;
|
||||
NSDictionary *row;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"SELECT c_foldername FROM %@"
|
||||
@" WHERE c_path = '%@'"),
|
||||
[folderLocation gcsTableName], ocsPath];
|
||||
[fc evaluateExpressionX: sql];
|
||||
attrs = [fc describeResults: NO];
|
||||
row = [fc fetchAttributes: attrs withZone: NULL];
|
||||
if (row)
|
||||
[self _setDisplayNameFromRow: row];
|
||||
[fc cancelFetch];
|
||||
[cm releaseChannel: fc];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setDisplayName: (NSString *) newDisplayName
|
||||
{
|
||||
ASSIGN (displayName, newDisplayName);
|
||||
}
|
||||
|
||||
- (NSString *) displayName
|
||||
{
|
||||
if (!displayName)
|
||||
[self _fetchDisplayName];
|
||||
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (NSString *) davDisplayName
|
||||
{
|
||||
return [self displayName];
|
||||
}
|
||||
|
||||
- (GCSFolder *) ocsFolder
|
||||
{
|
||||
GCSFolder *folder;
|
||||
|
@ -222,7 +257,9 @@ static NSString *defaultUserID = @"<default>";
|
|||
{
|
||||
NSException *result;
|
||||
|
||||
// [self dieHard];
|
||||
result = [[self folderManager] createFolderOfType: [self folderType]
|
||||
withName: displayName
|
||||
atPath: ocsPath];
|
||||
|
||||
return (result == nil);
|
||||
|
@ -234,13 +271,40 @@ static NSString *defaultUserID = @"<default>";
|
|||
|
||||
if ([nameInContainer isEqualToString: @"personal"])
|
||||
error = [NSException exceptionWithHTTPStatus: 403
|
||||
reason: @"the 'personal' folder cannot be deleted"];
|
||||
reason: @"folder 'personal' cannot be deleted"];
|
||||
else
|
||||
error = [[self folderManager] deleteFolderAtPath: ocsPath];
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
- (void) renameTo: (NSString *) newName
|
||||
{
|
||||
GCSChannelManager *cm;
|
||||
EOAdaptorChannel *fc;
|
||||
NSURL *folderLocation;
|
||||
NSString *sql;
|
||||
|
||||
[displayName release];
|
||||
displayName = nil;
|
||||
|
||||
cm = [GCSChannelManager defaultChannelManager];
|
||||
folderLocation
|
||||
= [[GCSFolderManager defaultFolderManager] folderInfoLocation];
|
||||
fc = [cm acquireOpenChannelForURL: folderLocation];
|
||||
if (fc)
|
||||
{
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"UPDATE %@ SET c_foldername = '%@'"
|
||||
@" WHERE c_path = '%@'"),
|
||||
[folderLocation gcsTableName], newName, ocsPath];
|
||||
[fc evaluateExpressionX: sql];
|
||||
[cm releaseChannel: fc];
|
||||
// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
|
||||
// uidColumnName, [self uid]];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) fetchContentObjectNames
|
||||
{
|
||||
NSArray *fields, *records;
|
||||
|
@ -512,7 +576,7 @@ static NSString *defaultUserID = @"<default>";
|
|||
/* acls */
|
||||
- (NSArray *) aclUsers
|
||||
{
|
||||
return [self aclUsersForObjectAtPath: [self pathArrayToSoObject]];
|
||||
return [self aclUsersForObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
|
@ -522,7 +586,7 @@ static NSString *defaultUserID = @"<default>";
|
|||
|
||||
acls = [NSMutableArray array];
|
||||
ownAcls = [self aclsForUser: uid
|
||||
forObjectAtPath: [self pathArrayToSoObject]];
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
[acls addObjectsFromArray: ownAcls];
|
||||
if ([container respondsToSelector: @selector (aclsForUser:)])
|
||||
{
|
||||
|
@ -545,13 +609,13 @@ static NSString *defaultUserID = @"<default>";
|
|||
{
|
||||
return [self setRoles: roles
|
||||
forUser: uid
|
||||
forObjectAtPath: [self pathArrayToSoObject]];
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) users
|
||||
{
|
||||
return [self removeAclsForUsers: users
|
||||
forObjectAtPath: [self pathArrayToSoObject]];
|
||||
forObjectAtPath: [self pathArrayToSOGoObject]];
|
||||
}
|
||||
|
||||
- (NSString *) defaultUserID
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
id container;
|
||||
}
|
||||
|
||||
+ (NSString *) globallyUniqueObjectId;
|
||||
- (NSString *) globallyUniqueObjectId;
|
||||
|
||||
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container;
|
||||
|
||||
- (id) initWithName: (NSString *) _name inContainer:(id)_container;
|
||||
|
@ -70,11 +73,15 @@
|
|||
- (NSString *) nameInContainer;
|
||||
- (id) container;
|
||||
|
||||
- (NSArray *) pathArrayToSOGoObject;
|
||||
|
||||
- (NSURL *) davURL;
|
||||
- (NSURL *) soURL;
|
||||
- (NSURL *) soURLToBaseContainerForUser: (NSString *) uid;
|
||||
- (NSURL *) soURLToBaseContainerForCurrentUser;
|
||||
|
||||
- (NSString *) labelForKey: (NSString *) key;
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (void) setOwner: (NSString *) newOwner;
|
||||
|
@ -100,7 +107,7 @@
|
|||
|
||||
/* etag support */
|
||||
|
||||
- (NSException *)matchesRequestConditionInContext:(id)_ctx;
|
||||
- (NSException *) matchesRequestConditionInContext:(id)_ctx;
|
||||
|
||||
/* acls */
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
Please use gnustep-base instead.
|
||||
#endif
|
||||
|
||||
#import <unistd.h>
|
||||
|
||||
#import <Foundation/NSBundle.h>
|
||||
#import <Foundation/NSClassDescription.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
@ -35,6 +38,7 @@
|
|||
#import <NGObjWeb/WEClientCapabilities.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOResourceManager.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <NGObjWeb/WORequest.h>
|
||||
#import <NGObjWeb/WORequest+So.h>
|
||||
|
@ -52,6 +56,7 @@
|
|||
#import "SOGoDAVRendererTypes.h"
|
||||
|
||||
#import "NSArray+Utilities.h"
|
||||
#import "NSDictionary+Utilities.h"
|
||||
#import "NSString+Utilities.h"
|
||||
|
||||
#import "SOGoObject.h"
|
||||
|
@ -179,6 +184,35 @@ static BOOL kontactGroupDAV = YES;
|
|||
// asDefaultForPermission: SoPerm_WebDAVAccess];
|
||||
}
|
||||
|
||||
+ (NSString *) globallyUniqueObjectId
|
||||
{
|
||||
/*
|
||||
4C08AE1A-A808-11D8-AC5A-000393BBAFF6
|
||||
SOGo-Web-28273-18283-288182
|
||||
printf( "%x", *(int *) &f);
|
||||
*/
|
||||
static int pid = 0;
|
||||
static int sequence = 0;
|
||||
static float rndm = 0;
|
||||
float f;
|
||||
|
||||
if (pid == 0)
|
||||
{ /* break if we fork ;-) */
|
||||
pid = getpid();
|
||||
rndm = random();
|
||||
}
|
||||
sequence++;
|
||||
f = [[NSDate date] timeIntervalSince1970];
|
||||
|
||||
return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
|
||||
pid, (int) f, sequence++, random];
|
||||
}
|
||||
|
||||
- (NSString *) globallyUniqueObjectId
|
||||
{
|
||||
return [[self class] globallyUniqueObjectId];
|
||||
}
|
||||
|
||||
+ (void) _fillDictionary: (NSMutableDictionary *) dictionary
|
||||
withDAVMethods: (NSString *) firstMethod, ...
|
||||
{
|
||||
|
@ -447,6 +481,30 @@ static BOOL kontactGroupDAV = YES;
|
|||
return container;
|
||||
}
|
||||
|
||||
- (NSArray *) pathArrayToSOGoObject
|
||||
{
|
||||
NSMutableArray *realPathArray;
|
||||
NSString *objectName;
|
||||
NSArray *objectDescription;
|
||||
|
||||
realPathArray
|
||||
= [NSMutableArray arrayWithArray: [self pathArrayToSoObject]];
|
||||
if ([realPathArray count] > 2)
|
||||
{
|
||||
objectName = [realPathArray objectAtIndex: 2];
|
||||
objectDescription = [objectName componentsSeparatedByString: @"_"];
|
||||
if ([objectDescription count] > 1)
|
||||
{
|
||||
[realPathArray replaceObjectAtIndex: 0
|
||||
withObject: [objectDescription objectAtIndex: 0]];
|
||||
[realPathArray replaceObjectAtIndex: 2
|
||||
withObject: [objectDescription objectAtIndex: 1]];
|
||||
}
|
||||
}
|
||||
|
||||
return realPathArray;
|
||||
}
|
||||
|
||||
/* ownership */
|
||||
|
||||
- (void) setOwner: (NSString *) newOwner
|
||||
|
@ -493,14 +551,16 @@ static BOOL kontactGroupDAV = YES;
|
|||
|
||||
/* looking up shared objects */
|
||||
|
||||
- (SOGoUserFolder *)lookupUserFolder {
|
||||
- (SOGoUserFolder *) lookupUserFolder
|
||||
{
|
||||
if (![container respondsToSelector:_cmd])
|
||||
return nil;
|
||||
|
||||
return [container lookupUserFolder];
|
||||
}
|
||||
|
||||
- (SOGoGroupsFolder *)lookupGroupsFolder {
|
||||
- (SOGoGroupsFolder *) lookupGroupsFolder
|
||||
{
|
||||
return [[self lookupUserFolder] lookupGroupsFolder];
|
||||
}
|
||||
|
||||
|
@ -905,6 +965,34 @@ static BOOL kontactGroupDAV = YES;
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) labelForKey: (NSString *) key
|
||||
{
|
||||
NSString *userLanguage, *label;
|
||||
NSArray *paths;
|
||||
NSBundle *bundle;
|
||||
NSDictionary *strings;
|
||||
|
||||
bundle = [NSBundle bundleForClass: [self class]];
|
||||
if (!bundle)
|
||||
bundle = [NSBundle mainBundle];
|
||||
|
||||
userLanguage = [[context activeUser] language];
|
||||
paths = [bundle pathsForResourcesOfType: @"strings"
|
||||
inDirectory: [NSString stringWithFormat: @"%@.lproj", userLanguage]
|
||||
forLocalization: userLanguage];
|
||||
if ([paths count] > 0)
|
||||
{
|
||||
strings = [NSDictionary dictionaryFromStringsFile: [paths objectAtIndex: 0]];
|
||||
label = [strings objectForKey: key];
|
||||
if (!label)
|
||||
label = key;
|
||||
}
|
||||
else
|
||||
label = key;
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
/* description */
|
||||
|
||||
- (void)appendAttributesToDescription:(NSMutableString *)_ms {
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
|
||||
- (NSArray *) subFolders;
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name;
|
||||
- (NSException *) newFolderWithName: (NSString *) name
|
||||
nameInContainer: (NSString **) newNameInContainer;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -22,14 +22,17 @@
|
|||
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
|
||||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <GDLContentStore/GCSChannelManager.h>
|
||||
#import <GDLContentStore/GCSFolderManager.h>
|
||||
#import <GDLContentStore/NSURL+GCS.h>
|
||||
#import <GDLAccess/EOAdaptorChannel.h>
|
||||
|
||||
#import "SOGoFolder.h"
|
||||
#import "SOGoUser.h"
|
||||
|
||||
#import "SOGoParentFolder.h"
|
||||
|
||||
|
@ -73,6 +76,11 @@
|
|||
ASSIGN (OCSPath, newOCSPath);
|
||||
}
|
||||
|
||||
- (NSString *) defaultFolderName
|
||||
{
|
||||
return @"Personal";
|
||||
}
|
||||
|
||||
- (void) _fetchPersonalFolders: (NSString *) sql
|
||||
withChannel: (EOAdaptorChannel *) fc
|
||||
{
|
||||
|
@ -80,7 +88,7 @@
|
|||
NSDictionary *row;
|
||||
SOGoFolder *folder;
|
||||
BOOL hasPersonal;
|
||||
NSString *key, *path;
|
||||
NSString *key, *path, *personalName;
|
||||
|
||||
if (!subFolderClass)
|
||||
subFolderClass = [[self class] subFolderClass];
|
||||
|
@ -92,8 +100,7 @@
|
|||
while (row)
|
||||
{
|
||||
folder
|
||||
= [subFolderClass folderWithName: [row objectForKey: @"c_path4"]
|
||||
andDisplayName: [row objectForKey: @"c_foldername"]
|
||||
= [subFolderClass objectWithName: [row objectForKey: @"c_path4"]
|
||||
inContainer: self];
|
||||
key = [row objectForKey: @"c_path4"];
|
||||
hasPersonal = (hasPersonal || [key isEqualToString: @"personal"]);
|
||||
|
@ -105,9 +112,9 @@
|
|||
|
||||
if (!hasPersonal)
|
||||
{
|
||||
folder = [subFolderClass folderWithName: @"personal"
|
||||
andDisplayName: @"personal"
|
||||
inContainer: self];
|
||||
folder = [subFolderClass objectWithName: @"personal" inContainer: self];
|
||||
personalName = [self labelForKey: [self defaultFolderName]];
|
||||
[folder setDisplayName: personalName];
|
||||
path = [NSString stringWithFormat: @"/Users/%@/%@/personal",
|
||||
[self ownerInContext: context],
|
||||
nameInContainer];
|
||||
|
@ -132,7 +139,7 @@
|
|||
gcsFolderType = [[self class] gcsFolderType];
|
||||
|
||||
sql
|
||||
= [NSString stringWithFormat: (@"SELECT c_path4, c_foldername FROM %@"
|
||||
= [NSString stringWithFormat: (@"SELECT c_path4 FROM %@"
|
||||
@" WHERE c_path2 = '%@'"
|
||||
@" AND c_folder_type = '%@'"),
|
||||
[folderLocation gcsTableName],
|
||||
|
@ -149,25 +156,58 @@
|
|||
{
|
||||
}
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name
|
||||
- (void) appendSubscribedSources
|
||||
{
|
||||
NSArray *subscribedReferences;
|
||||
NSUserDefaults *settings;
|
||||
NSEnumerator *allKeys;
|
||||
NSString *currentKey;
|
||||
SOGoFolder *subscribedFolder;
|
||||
|
||||
settings = [[context activeUser] userSettings];
|
||||
subscribedReferences = [[settings objectForKey: nameInContainer]
|
||||
objectForKey: @"SubscribedFolders"];
|
||||
if ([subscribedReferences isKindOfClass: [NSArray class]])
|
||||
{
|
||||
allKeys = [subscribedReferences objectEnumerator];
|
||||
currentKey = [allKeys nextObject];
|
||||
while (currentKey)
|
||||
{
|
||||
subscribedFolder
|
||||
= [subFolderClass folderWithSubscriptionReference: currentKey
|
||||
inContainer: self];
|
||||
[subFolders setObject: subscribedFolder
|
||||
forKey: [subscribedFolder nameInContainer]];
|
||||
currentKey = [allKeys nextObject];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSException *) newFolderWithName: (NSString *) name
|
||||
nameInContainer: (NSString **) newNameInContainer
|
||||
{
|
||||
NSString *newFolderID;
|
||||
SOGoFolder *newFolder;
|
||||
NSException *error;
|
||||
|
||||
if (!subFolderClass)
|
||||
subFolderClass = [[self class] subFolderClass];
|
||||
|
||||
newFolder = [subFolderClass folderWithName: name
|
||||
andDisplayName: name
|
||||
inContainer: self];
|
||||
*newNameInContainer = nil;
|
||||
newFolderID = [self globallyUniqueObjectId];
|
||||
newFolder = [subFolderClass objectWithName: newFolderID inContainer: self];
|
||||
if ([newFolder isKindOfClass: [NSException class]])
|
||||
error = (NSException *) newFolder;
|
||||
else
|
||||
{
|
||||
[newFolder setDisplayName: name];
|
||||
[newFolder setOCSPath: [NSString stringWithFormat: @"%@/%@",
|
||||
OCSPath, name]];
|
||||
OCSPath, newFolderID]];
|
||||
if ([newFolder create])
|
||||
error = nil;
|
||||
{
|
||||
error = nil;
|
||||
*newNameInContainer = newFolderID;
|
||||
}
|
||||
else
|
||||
error = [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"The new folder could not be created"];
|
||||
|
@ -178,11 +218,16 @@
|
|||
|
||||
- (void) initSubFolders
|
||||
{
|
||||
NSString *login;
|
||||
|
||||
if (!subFolders)
|
||||
{
|
||||
subFolders = [NSMutableDictionary new];
|
||||
[self appendPersonalSources];
|
||||
[self appendSystemSources];
|
||||
login = [[context activeUser] login];
|
||||
if ([login isEqualToString: owner])
|
||||
[self appendSubscribedSources];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#import <NGObjWeb/SoClassSecurityInfo.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <Appointments/SOGoFreeBusyObject.h>
|
||||
#import <Contacts/SOGoContactFolders.h>
|
||||
#import <Mailer/SOGoMailAccounts.h>
|
||||
|
@ -117,7 +117,7 @@
|
|||
|
||||
- (NSString *) ocsPrivateCalendarPath
|
||||
{
|
||||
return [[self ocsUserPath] stringByAppendingString:@"/Calendar/personal"];
|
||||
return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
|
||||
}
|
||||
|
||||
- (NSString *) ocsPrivateContactsPath
|
||||
|
@ -134,15 +134,15 @@
|
|||
// : [super permissionForKey: key]);
|
||||
// }
|
||||
|
||||
- (SOGoAppointmentFolder *) privateCalendar: (NSString *) _key
|
||||
inContext: (WOContext *) _ctx
|
||||
- (SOGoAppointmentFolders *) privateCalendars: (NSString *) _key
|
||||
inContext: (WOContext *) _ctx
|
||||
{
|
||||
SOGoAppointmentFolder *calendar;
|
||||
SOGoAppointmentFolders *calendars;
|
||||
|
||||
calendar = [$(@"SOGoAppointmentFolder") objectWithName: _key inContainer: self];
|
||||
[calendar setOCSPath: [self ocsPrivateCalendarPath]];
|
||||
calendars = [$(@"SOGoAppointmentFolders") objectWithName: _key inContainer: self];
|
||||
[calendars setBaseOCSPath: [self ocsPrivateCalendarPath]];
|
||||
|
||||
return calendar;
|
||||
return calendars;
|
||||
}
|
||||
|
||||
- (SOGoContactFolders *) privateContacts: (NSString *) _key
|
||||
|
@ -185,7 +185,7 @@
|
|||
if (!obj)
|
||||
{
|
||||
if ([_key isEqualToString: @"Calendar"])
|
||||
obj = [self privateCalendar: @"Calendar" inContext: _ctx];
|
||||
obj = [self privateCalendars: @"Calendar" inContext: _ctx];
|
||||
// if (![_key isEqualToString: @"Calendar"])
|
||||
// obj = [obj lookupName: [_key pathExtension]
|
||||
// inContext: _ctx acquire: NO];
|
||||
|
|
|
@ -32,3 +32,4 @@
|
|||
"You cannot subscribe to a folder that you own!" = "You cannot subscribe to a folder that you own!";
|
||||
"Unable to unsubscribe from that folder!" = "Unable to unsubscribe from that folder!";
|
||||
"You cannot unsubscribe from a folder that you own!" = "You cannot unsubscribe from a folder that you own!";
|
||||
"Unable to rename that folder!" = "Unable to rename that folder!";
|
||||
|
|
|
@ -33,3 +33,4 @@
|
|||
"You cannot subscribe to a folder that you own!" = "Impossible de vous abonner à un dossier qui vous appartient.";
|
||||
"Unable to unsubscribe from that folder!" = "Impossible de se désabonner de ce dossier.";
|
||||
"You cannot unsubscribe from a folder that you own!" = "Impossible de vous désabonner d'un dossier qui vous appartient.";
|
||||
"Unable to rename that folder!" = "Impossible de renommer ce dossier.";
|
||||
|
|
|
@ -17,6 +17,7 @@ CommonUI_OBJC_FILES += \
|
|||
UIxAclEditor.m \
|
||||
UIxObjectActions.m \
|
||||
UIxFolderActions.m \
|
||||
UIxParentFolderActions.m \
|
||||
UIxElemBuilder.m \
|
||||
UIxTabView.m \
|
||||
UIxTabItem.m \
|
||||
|
|
|
@ -35,3 +35,4 @@
|
|||
"You cannot subscribe to a folder that you own!" = "Unmöglich sich an einem Ordner zu abonnieren, der Ihnen selbst gehört.";
|
||||
"Unable to unsubscribe from that folder!" = "Unmöglich sich von diesem Ordner zu des-abonnieren.";
|
||||
"You cannot unsubscribe from a folder that you own!" = "Unmöglich sich von einem Ordner zu des-abonnieren, der Ihnen selbst gehört.";
|
||||
"Unable to rename that folder!" = "Unable to rename that folder!";
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
NSString *owner;
|
||||
NSString *login;
|
||||
NSString *baseFolder;
|
||||
NSMutableString *subscriptionPointer;
|
||||
NSString *subscriptionPointer;
|
||||
NSMutableDictionary *moduleSettings;
|
||||
BOOL isMailInvitation;
|
||||
}
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
#import <NGObjWeb/SoSecurityManager.h>
|
||||
|
||||
#import <SoObjects/SOGo/LDAPUserManager.h>
|
||||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoObject.h>
|
||||
#import <SoObjects/SOGo/SOGoFolder.h>
|
||||
#import <SoObjects/SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "WODirectAction+SOGo.h"
|
||||
|
@ -74,21 +75,19 @@
|
|||
}
|
||||
[ud setObject: moduleSettings forKey: baseFolder];
|
||||
|
||||
subscriptionPointer = [NSMutableString stringWithFormat: @"%@:%@",
|
||||
owner, baseFolder];
|
||||
if ([baseFolder isEqualToString: @"Contacts"])
|
||||
[subscriptionPointer appendFormat: @"/%@",
|
||||
[clientObject nameInContainer]];
|
||||
subscriptionPointer = [NSString stringWithFormat: @"%@:%@/%@",
|
||||
owner, baseFolder,
|
||||
[clientObject nameInContainer]];
|
||||
|
||||
mailInvitationParam
|
||||
= [[context request] formValueForKey: @"mail-invitation"];
|
||||
isMailInvitation = [mailInvitationParam boolValue];
|
||||
}
|
||||
|
||||
- (WOResponse *) _realActionWithFolderName: (NSDictionary *) folderDict
|
||||
- (WOResponse *) _realSubscribe: (BOOL) reallyDo
|
||||
{
|
||||
WOResponse *response;
|
||||
NSMutableDictionary *folderSubscription;
|
||||
NSMutableArray *folderSubscription;
|
||||
NSString *mailInvitationURL;
|
||||
|
||||
if ([owner isEqualToString: login])
|
||||
|
@ -101,17 +100,17 @@
|
|||
{
|
||||
folderSubscription
|
||||
= [moduleSettings objectForKey: @"SubscribedFolders"];
|
||||
if (!folderSubscription)
|
||||
if (!(folderSubscription
|
||||
&& [folderSubscription isKindOfClass: [NSMutableArray class]]))
|
||||
{
|
||||
folderSubscription = [NSMutableDictionary dictionary];
|
||||
folderSubscription = [NSMutableArray array];
|
||||
[moduleSettings setObject: folderSubscription
|
||||
forKey: @"SubscribedFolders"];
|
||||
}
|
||||
if (folderDict)
|
||||
[folderSubscription setObject: folderDict
|
||||
forKey: subscriptionPointer];
|
||||
if (reallyDo)
|
||||
[folderSubscription addObjectUniquely: subscriptionPointer];
|
||||
else
|
||||
[folderSubscription removeObjectForKey: subscriptionPointer];
|
||||
[folderSubscription removeObject: subscriptionPointer];
|
||||
|
||||
[ud synchronize];
|
||||
|
||||
|
@ -133,32 +132,16 @@
|
|||
|
||||
- (WOResponse *) subscribeAction
|
||||
{
|
||||
NSString *email;
|
||||
NSMutableDictionary *folderDict;
|
||||
NSString *folderName;
|
||||
|
||||
[self _setupContext];
|
||||
email = [NSString stringWithFormat: @"%@ <%@>",
|
||||
[um getCNForUID: owner],
|
||||
[um getEmailForUID: owner]];
|
||||
if ([baseFolder isEqualToString: @"Contacts"])
|
||||
folderName = [NSString stringWithFormat: @"%@ (%@)",
|
||||
[clientObject nameInContainer], email];
|
||||
else
|
||||
folderName = email;
|
||||
|
||||
folderDict = [NSMutableDictionary dictionary];
|
||||
[folderDict setObject: folderName forKey: @"displayName"];
|
||||
[folderDict setObject: [NSNumber numberWithBool: NO] forKey: @"active"];
|
||||
|
||||
return [self _realActionWithFolderName: folderDict];
|
||||
return [self _realSubscribe: YES];
|
||||
}
|
||||
|
||||
- (WOResponse *) unsubscribeAction
|
||||
{
|
||||
[self _setupContext];
|
||||
|
||||
return [self _realActionWithFolderName: nil];
|
||||
return [self _realSubscribe: NO];
|
||||
}
|
||||
|
||||
- (WOResponse *) canAccessContentAction
|
||||
|
@ -168,26 +151,24 @@
|
|||
|
||||
- (WOResponse *) _realFolderActivation: (BOOL) makeActive
|
||||
{
|
||||
NSMutableDictionary *folderSubscription, *folderDict;
|
||||
NSNumber *active;
|
||||
|
||||
NSMutableArray *folderSubscription;
|
||||
NSString *folderName;
|
||||
|
||||
[self _setupContext];
|
||||
active = [NSNumber numberWithBool: makeActive];
|
||||
if ([owner isEqualToString: login])
|
||||
[moduleSettings setObject: active forKey: @"activateUserFolder"];
|
||||
else
|
||||
folderSubscription
|
||||
= [moduleSettings objectForKey: @"ActiveFolders"];
|
||||
if (!folderSubscription)
|
||||
{
|
||||
folderSubscription
|
||||
= [moduleSettings objectForKey: @"SubscribedFolders"];
|
||||
if (folderSubscription)
|
||||
{
|
||||
folderDict = [folderSubscription objectForKey: subscriptionPointer];
|
||||
if (folderDict)
|
||||
[folderDict setObject: active
|
||||
forKey: @"active"];
|
||||
}
|
||||
folderSubscription = [NSMutableArray array];
|
||||
[moduleSettings setObject: folderSubscription forKey: @"ActiveFolders"];
|
||||
}
|
||||
|
||||
folderName = [clientObject nameInContainer];
|
||||
if (makeActive)
|
||||
[folderSubscription addObjectUniquely: folderName];
|
||||
else
|
||||
[folderSubscription removeObject: folderName];
|
||||
|
||||
[ud synchronize];
|
||||
|
||||
return [self responseWith204];
|
||||
|
@ -203,4 +184,36 @@
|
|||
return [self _realFolderActivation: NO];
|
||||
}
|
||||
|
||||
- (WOResponse *) deleteFolderAction
|
||||
{
|
||||
WOResponse *response;
|
||||
|
||||
response = (WOResponse *) [[self clientObject] delete];
|
||||
if (!response)
|
||||
response = [self responseWith204];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (WOResponse *) renameFolderAction
|
||||
{
|
||||
WOResponse *response;
|
||||
NSString *folderName;
|
||||
|
||||
folderName = [[context request] formValueForKey: @"name"];
|
||||
if ([folderName length] > 0)
|
||||
{
|
||||
clientObject = [self clientObject];
|
||||
[clientObject renameTo: folderName];
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
{
|
||||
response = [self responseWithStatus: 500];
|
||||
[response appendContentString: @"Missing 'name' parameter."];
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,95 +1,114 @@
|
|||
{ /* -*-javascript-*- */
|
||||
requires = ( MAIN, Mailer );
|
||||
{ /* -*-java-*- */
|
||||
requires = ( MAIN, Mailer );
|
||||
|
||||
publicResources = (
|
||||
calendar.css,
|
||||
uix.css,
|
||||
menu_logo_top.gif,
|
||||
line_left.gif,
|
||||
line_stretch.gif,
|
||||
line_right.gif,
|
||||
box_topleft.gif,
|
||||
box_top.gif,
|
||||
box_topright.gif,
|
||||
box_left.gif,
|
||||
box_right.gif,
|
||||
box_botleft.gif,
|
||||
box_bottom.gif,
|
||||
box_botright.gif,
|
||||
tab_selected.gif,
|
||||
tab_.gif,
|
||||
corner_right.gif,
|
||||
closewindow.gif,
|
||||
OGoLogo.gif,
|
||||
upward_sorted.gif,
|
||||
downward_sorted.gif,
|
||||
non_sorted.gif
|
||||
);
|
||||
|
||||
publicResources = (
|
||||
calendar.css,
|
||||
uix.css,
|
||||
menu_logo_top.gif,
|
||||
line_left.gif,
|
||||
line_stretch.gif,
|
||||
line_right.gif,
|
||||
box_topleft.gif,
|
||||
box_top.gif,
|
||||
box_topright.gif,
|
||||
box_left.gif,
|
||||
box_right.gif,
|
||||
box_botleft.gif,
|
||||
box_bottom.gif,
|
||||
box_botright.gif,
|
||||
tab_selected.gif,
|
||||
tab_.gif,
|
||||
corner_right.gif,
|
||||
closewindow.gif,
|
||||
OGoLogo.gif,
|
||||
upward_sorted.gif,
|
||||
downward_sorted.gif,
|
||||
non_sorted.gif
|
||||
);
|
||||
factories = {
|
||||
};
|
||||
|
||||
factories = {
|
||||
};
|
||||
|
||||
categories = {
|
||||
SOGoObject = {
|
||||
methods = {
|
||||
addUserInAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
actionClass = "UIxObjectActions";
|
||||
actionName = "addUserInAcls";
|
||||
};
|
||||
removeUserFromAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
actionClass = "UIxObjectActions";
|
||||
actionName = "removeUserFromAcls";
|
||||
};
|
||||
acls = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxAclEditor";
|
||||
};
|
||||
saveAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
pageName = "UIxAclEditor";
|
||||
actionName = "saveAcls";
|
||||
};
|
||||
userRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxUserRightsEditor";
|
||||
};
|
||||
saveUserRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxUserRightsEditor";
|
||||
actionName = "saveUserRights";
|
||||
};
|
||||
};
|
||||
categories = {
|
||||
SOGoObject = {
|
||||
methods = {
|
||||
addUserInAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
actionClass = "UIxObjectActions";
|
||||
actionName = "addUserInAcls";
|
||||
};
|
||||
removeUserFromAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
actionClass = "UIxObjectActions";
|
||||
actionName = "removeUserFromAcls";
|
||||
};
|
||||
acls = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxAclEditor";
|
||||
};
|
||||
saveAcls = {
|
||||
protectedBy = "SaveAcls";
|
||||
pageName = "UIxAclEditor";
|
||||
actionName = "saveAcls";
|
||||
};
|
||||
userRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxUserRightsEditor";
|
||||
};
|
||||
saveUserRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxUserRightsEditor";
|
||||
actionName = "saveUserRights";
|
||||
};
|
||||
};
|
||||
SOGoFolder = {
|
||||
methods = {
|
||||
subscribe = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "subscribe";
|
||||
};
|
||||
unsubscribe = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "unsubscribe";
|
||||
};
|
||||
canAccessContent = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "canAccessContent";
|
||||
};
|
||||
activateFolder = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "activateFolder";
|
||||
};
|
||||
deactivateFolder = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "deactivateFolder";
|
||||
};
|
||||
};
|
||||
};
|
||||
SOGoParentFolder = {
|
||||
methods = {
|
||||
createFolder = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxParentFolderActions";
|
||||
actionName = "createFolder";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
SOGoFolder = {
|
||||
methods = {
|
||||
subscribe = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "subscribe";
|
||||
};
|
||||
unsubscribe = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "unsubscribe";
|
||||
};
|
||||
canAccessContent = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "canAccessContent";
|
||||
};
|
||||
activateFolder = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "activateFolder";
|
||||
};
|
||||
deactivateFolder = {
|
||||
protectedBy = "<public>";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "deactivateFolder";
|
||||
};
|
||||
deleteFolder = {
|
||||
protectedBy = "SaveAcls"; /* a hack to force "owner" */
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "deleteFolder";
|
||||
};
|
||||
renameFolder = {
|
||||
protectedBy = "SaveAcls";
|
||||
actionClass = "UIxFolderActions";
|
||||
actionName = "renameFolder";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -105,6 +105,8 @@
|
|||
"Are you sure you want to delete the selected address book?"
|
||||
= "Are you sure you want to delete the selected address book?";
|
||||
|
||||
"Address Book Name" = "Address Book Name";
|
||||
|
||||
"You cannot subscribe to a folder that you own!"
|
||||
= "You cannot subscribe to a folder that you own!";
|
||||
"Unable to subscribe to that folder!"
|
||||
|
@ -125,4 +127,4 @@
|
|||
= "This person can erase cards from this addressbook.";
|
||||
|
||||
"The selected contact has no email address."
|
||||
= "The selected contact has no email address.";
|
||||
= "The selected contact has no email address.";
|
||||
|
|
|
@ -118,6 +118,8 @@
|
|||
"Are you sure you want to delete the selected address book?"
|
||||
= "Voulez-vous vraiment supprimer le carnet d'adresses sélectionné ?";
|
||||
|
||||
"Address Book Name" = "Nom du carnet d'adresses";
|
||||
|
||||
"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!"
|
||||
|
@ -138,4 +140,4 @@
|
|||
= "Cette personne peut effacer des fiches de ce carnet d'adresses.";
|
||||
|
||||
"The selected contact has no email address."
|
||||
= "Cette personne n'a pas d'adresse courriel."
|
||||
= "Cette personne n'a pas d'adresse courriel."
|
||||
|
|
|
@ -109,6 +109,8 @@
|
|||
"Are you sure you want to delete the selected address book?"
|
||||
= "Voulez-vous vraiment supprimer le carnet d'adresses sélectionné ?";
|
||||
|
||||
"Address Book Name" = "Address Book Name";
|
||||
|
||||
"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!"
|
||||
|
|
|
@ -584,8 +584,8 @@
|
|||
id <SOGoContactFolder> co;
|
||||
|
||||
co = [self clientObject];
|
||||
if ([[co class] respondsToSelector: @selector (globallyUniqueObjectId)])
|
||||
objectId = [[[self clientObject] class] globallyUniqueObjectId];
|
||||
if ([co respondsToSelector: @selector (globallyUniqueObjectId)])
|
||||
objectId = [co globallyUniqueObjectId];
|
||||
else
|
||||
objectId = nil;
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@
|
|||
WORequest *request;
|
||||
|
||||
folders = [self clientObject];
|
||||
action = [NSString stringWithFormat: @"../personal/%@",
|
||||
actionName];
|
||||
action = [NSString stringWithFormat: @"../personal/%@", actionName];
|
||||
|
||||
request = [[self context] request];
|
||||
|
||||
|
@ -74,25 +73,6 @@
|
|||
return [self _selectActionForApplication: @"new"];
|
||||
}
|
||||
|
||||
- (id <WOActionResults>) newAbAction
|
||||
{
|
||||
id <WOActionResults> response;
|
||||
NSString *name;
|
||||
|
||||
name = [self queryParameterForKey: @"name"];
|
||||
if ([name length] > 0)
|
||||
{
|
||||
response = [[self clientObject] newFolderWithName: name];
|
||||
if (!response)
|
||||
response = [self responseWith204];
|
||||
}
|
||||
else
|
||||
response = [NSException exceptionWithHTTPStatus: 400
|
||||
reason: @"The name is missing"];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
- (id) selectForMailerAction
|
||||
{
|
||||
return [self _selectActionForApplication: @"mailer-contacts"];
|
||||
|
@ -193,50 +173,55 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
- (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders
|
||||
- (NSArray *) _subFoldersFromFolder: (SOGoParentFolder *) parentFolder
|
||||
{
|
||||
NSMutableArray *gcsFolders;
|
||||
NSEnumerator *contactSubfolders;
|
||||
SOGoContactGCSFolder *currentContactFolder;
|
||||
NSString *folderName, *displayName;
|
||||
NSMutableArray *folders;
|
||||
NSEnumerator *subfolders;
|
||||
SOGoFolder *currentFolder;
|
||||
NSString *folderName;
|
||||
NSMutableDictionary *currentDictionary;
|
||||
SoSecurityManager *securityManager;
|
||||
|
||||
gcsFolders = [NSMutableArray new];
|
||||
[gcsFolders autorelease];
|
||||
securityManager = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
// return (([securityManager validatePermission: SoPerm_AccessContentsInformation
|
||||
// onObject: contactFolder
|
||||
// inContext: context] == nil)
|
||||
|
||||
contactSubfolders = [[contactFolders subFolders] objectEnumerator];
|
||||
currentContactFolder = [contactSubfolders nextObject];
|
||||
while (currentContactFolder)
|
||||
folders = [NSMutableArray new];
|
||||
[folders autorelease];
|
||||
|
||||
subfolders = [[parentFolder subFolders] objectEnumerator];
|
||||
currentFolder = [subfolders nextObject];
|
||||
while (currentFolder)
|
||||
{
|
||||
if ([currentContactFolder
|
||||
isKindOfClass: [SOGoContactGCSFolder class]])
|
||||
if (![securityManager validatePermission: SOGoPerm_AccessObject
|
||||
onObject: currentFolder inContext: context])
|
||||
{
|
||||
displayName = [[currentContactFolder ocsFolder] folderName];
|
||||
if (displayName)
|
||||
{
|
||||
folderName = [NSString stringWithFormat: @"/Contacts/%@",
|
||||
[currentContactFolder nameInContainer]];
|
||||
currentDictionary
|
||||
= [NSMutableDictionary dictionaryWithCapacity: 3];
|
||||
[currentDictionary setObject: displayName forKey: @"displayName"];
|
||||
[currentDictionary setObject: folderName forKey: @"name"];
|
||||
[currentDictionary setObject: @"contact" forKey: @"type"];
|
||||
[gcsFolders addObject: currentDictionary];
|
||||
}
|
||||
folderName = [NSString stringWithFormat: @"/%@/%@",
|
||||
[parentFolder nameInContainer],
|
||||
[currentFolder nameInContainer]];
|
||||
currentDictionary
|
||||
= [NSMutableDictionary dictionaryWithCapacity: 3];
|
||||
[currentDictionary setObject: [currentFolder displayName]
|
||||
forKey: @"displayName"];
|
||||
[currentDictionary setObject: folderName forKey: @"name"];
|
||||
[currentDictionary setObject: [currentFolder folderType]
|
||||
forKey: @"type"];
|
||||
[folders addObject: currentDictionary];
|
||||
}
|
||||
currentContactFolder = [contactSubfolders nextObject];
|
||||
currentFolder = [subfolders nextObject];
|
||||
}
|
||||
|
||||
return gcsFolders;
|
||||
return folders;
|
||||
}
|
||||
|
||||
- (NSArray *) _foldersForUID: (NSString *) uid
|
||||
ofType: (NSString *) folderType
|
||||
{
|
||||
NSObject *topFolder, *userFolder;
|
||||
SOGoContactFolders *contactFolders;
|
||||
SOGoParentFolder *parentFolder;
|
||||
NSMutableArray *folders;
|
||||
NSMutableDictionary *currentDictionary;
|
||||
|
||||
folders = [NSMutableArray new];
|
||||
[folders autorelease];
|
||||
|
@ -245,23 +230,19 @@
|
|||
userFolder = [topFolder lookupName: uid inContext: context acquire: NO];
|
||||
|
||||
/* FIXME: should be moved in the SOGo* classes. Maybe by having a SOGoFolderManager. */
|
||||
#warning this might need adjustments whenever we permit multiple calendar folders per-user
|
||||
if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"])
|
||||
{
|
||||
currentDictionary = [NSMutableDictionary new];
|
||||
[currentDictionary autorelease];
|
||||
[currentDictionary setObject: [self labelForKey: @"Calendar"]
|
||||
forKey: @"displayName"];
|
||||
[currentDictionary setObject: @"/Calendar" forKey: @"name"];
|
||||
[currentDictionary setObject: @"calendar" forKey: @"type"];
|
||||
[folders addObject: currentDictionary];
|
||||
parentFolder = [userFolder lookupName: @"Calendar"
|
||||
inContext: context acquire: NO];
|
||||
[folders
|
||||
addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
|
||||
}
|
||||
if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
|
||||
{
|
||||
contactFolders = [userFolder lookupName: @"Contacts"
|
||||
inContext: context acquire: NO];
|
||||
parentFolder = [userFolder lookupName: @"Contacts"
|
||||
inContext: context acquire: NO];
|
||||
[folders
|
||||
addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]];
|
||||
addObjectsFromArray: [self _subFoldersFromFolder: parentFolder]];
|
||||
}
|
||||
|
||||
return folders;
|
||||
|
@ -352,31 +333,30 @@
|
|||
return result;
|
||||
}
|
||||
|
||||
- (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
|
||||
{
|
||||
SOGoFolder *upperContainer;
|
||||
SOGoUserFolder *userFolder;
|
||||
SOGoContactFolders *contactFolders;
|
||||
SOGoContactGCSFolder *contactFolder;
|
||||
SoSecurityManager *securityManager;
|
||||
// - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
|
||||
// {
|
||||
// SOGoFolder *upperContainer;
|
||||
// SOGoUserFolder *userFolder;
|
||||
// SOGoContactFolders *contactFolders;
|
||||
// SOGoContactGCSFolder *contactFolder;
|
||||
// SoSecurityManager *securityManager;
|
||||
|
||||
upperContainer = [[[self clientObject] container] container];
|
||||
userFolder = [SOGoUserFolder objectWithName: uid
|
||||
inContainer: upperContainer];
|
||||
contactFolders = [SOGoContactFolders objectWithName: @"Contacts"
|
||||
inContainer: userFolder];
|
||||
contactFolder = [SOGoContactGCSFolder objectWithName: @"personal"
|
||||
inContainer: contactFolders];
|
||||
[contactFolder
|
||||
setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]];
|
||||
[contactFolder setOwner: uid];
|
||||
// upperContainer = [[[self clientObject] container] container];
|
||||
// userFolder = [SOGoUserFolder objectWithName: uid
|
||||
// inContainer: upperContainer];
|
||||
// contactFolders = [SOGoUserFolder lookupName: @"Contacts"
|
||||
// inContext: context
|
||||
// acquire: NO];
|
||||
// contactFolder = [contactFolders lookupName: @"personal"
|
||||
// inContext: context
|
||||
// acquire: NO];
|
||||
|
||||
securityManager = [SoSecurityManager sharedSecurityManager];
|
||||
// securityManager = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
return (([securityManager validatePermission: SoPerm_AccessContentsInformation
|
||||
onObject: contactFolder
|
||||
inContext: context] == nil)
|
||||
? contactFolder : nil);
|
||||
}
|
||||
// return (([securityManager validatePermission: SoPerm_AccessContentsInformation
|
||||
// onObject: contactFolder
|
||||
// inContext: context] == nil)
|
||||
// ? contactFolder : nil);
|
||||
// }
|
||||
|
||||
@end
|
||||
|
|
|
@ -81,25 +81,6 @@
|
|||
return selectorComponentClass;
|
||||
}
|
||||
|
||||
- (id <WOActionResults>) deleteAction
|
||||
{
|
||||
id <WOActionResults> result;
|
||||
NSException <WOActionResults> *ex;
|
||||
WOResponse *response;
|
||||
|
||||
ex = [[self clientObject] delete];
|
||||
if (ex)
|
||||
result = ex;
|
||||
else
|
||||
{
|
||||
response = [context response];
|
||||
[response setStatus: 200];
|
||||
result = response;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *) defaultSortKey
|
||||
{
|
||||
return @"displayName";
|
||||
|
|
|
@ -31,28 +31,18 @@
|
|||
|
||||
@interface UIxContactsListViewContainer : UIxComponent
|
||||
{
|
||||
NSString *foldersPrefix;
|
||||
NSString *selectorComponentClass;
|
||||
NSString *currentAdditionalFolder;
|
||||
NSDictionary *additionalFolders;
|
||||
id currentFolder;
|
||||
}
|
||||
|
||||
- (void) setCurrentFolder: (id) folder;
|
||||
|
||||
- (NSString *) foldersPrefix;
|
||||
|
||||
- (NSArray *) contactFolders;
|
||||
|
||||
- (NSString *) currentContactFolderId;
|
||||
- (NSString *) currentContactFolderOwner;
|
||||
- (NSString *) currentContactFolderName;
|
||||
|
||||
- (NSArray *) additionalFolders;
|
||||
|
||||
- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder;
|
||||
- (NSString *) currentAdditionalFolder;
|
||||
- (NSString *) currentAdditionalFolderName;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* UIXCONTACTSLISTVIEWCONTAINERBASE_H */
|
||||
|
|
|
@ -41,20 +41,12 @@
|
|||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
foldersPrefix = nil;
|
||||
selectorComponentClass = nil;
|
||||
additionalFolders = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[additionalFolders release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setSelectorComponentClass: (NSString *) aComponentClass
|
||||
{
|
||||
selectorComponentClass = aComponentClass;
|
||||
|
@ -86,30 +78,6 @@
|
|||
currentFolder = folder;
|
||||
}
|
||||
|
||||
- (NSString *) foldersPrefix
|
||||
{
|
||||
NSMutableArray *folders;
|
||||
SOGoObject *currentObject;
|
||||
|
||||
if (!foldersPrefix)
|
||||
{
|
||||
folders = [NSMutableArray new];
|
||||
[folders autorelease];
|
||||
|
||||
currentObject = [[self clientObject] container];
|
||||
while (![currentObject isKindOfClass: [SOGoContactFolders class]])
|
||||
{
|
||||
[folders insertObject: [currentObject nameInContainer] atIndex: 0];
|
||||
currentObject = [currentObject container];
|
||||
}
|
||||
|
||||
foldersPrefix = [folders componentsJoinedByString: @"/"];
|
||||
[foldersPrefix retain];
|
||||
}
|
||||
|
||||
return foldersPrefix;
|
||||
}
|
||||
|
||||
- (NSArray *) contactFolders
|
||||
{
|
||||
SOGoContactFolders *folderContainer;
|
||||
|
@ -121,8 +89,7 @@
|
|||
|
||||
- (NSString *) currentContactFolderId
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@/%@",
|
||||
[self foldersPrefix],
|
||||
return [NSString stringWithFormat: @"/%@",
|
||||
[currentFolder nameInContainer]];
|
||||
}
|
||||
|
||||
|
@ -131,35 +98,9 @@
|
|||
return [currentFolder displayName];
|
||||
}
|
||||
|
||||
- (NSArray *) additionalFolders
|
||||
- (NSString *) currentContactFolderOwner
|
||||
{
|
||||
NSUserDefaults *ud;
|
||||
|
||||
if (!additionalFolders)
|
||||
{
|
||||
ud = [[context activeUser] userSettings];
|
||||
additionalFolders
|
||||
= [[ud objectForKey: @"Contacts"] objectForKey: @"SubscribedFolders"];
|
||||
[additionalFolders retain];
|
||||
}
|
||||
|
||||
return [additionalFolders allKeys];
|
||||
}
|
||||
|
||||
- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder
|
||||
{
|
||||
currentAdditionalFolder = newCurrentAdditionalFolder;
|
||||
}
|
||||
|
||||
- (NSString *) currentAdditionalFolder
|
||||
{
|
||||
return currentAdditionalFolder;
|
||||
}
|
||||
|
||||
- (NSString *) currentAdditionalFolderName
|
||||
{
|
||||
return [[additionalFolders objectForKey: currentAdditionalFolder]
|
||||
objectForKey: @"displayName"];
|
||||
return [currentFolder ownerInContext: context];
|
||||
}
|
||||
|
||||
- (BOOL) hasContactSelectionButtons
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
pageName = "UIxContactFoldersView";
|
||||
actionName = "new";
|
||||
};
|
||||
newAb = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxContactFoldersView";
|
||||
actionName = "newAb";
|
||||
};
|
||||
mailer-contacts = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxContactFoldersView";
|
||||
|
@ -87,11 +82,6 @@
|
|||
pageName = "UIxContactsListView";
|
||||
actionName = "mailerContacts";
|
||||
};
|
||||
delete = {
|
||||
protectedBy = "SaveAcls"; /* a hack to force "owner" */
|
||||
pageName = "UIxContactsListView";
|
||||
actionName = "delete";
|
||||
};
|
||||
userRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxContactsUserRightsEditor";
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
cookieString = [NSString stringWithFormat: @"%@:%@",
|
||||
[self queryParameterForKey: @"userName"],
|
||||
[self queryParameterForKey: @"password"]];
|
||||
cookieValue = [NSString stringWithFormat: @"basic%@",
|
||||
cookieValue = [NSString stringWithFormat: @"basic %@",
|
||||
[cookieString stringByEncodingBase64]];
|
||||
authCookie = [WOCookie cookieWithName: [auth cookieNameInContext: context]
|
||||
value: cookieValue];
|
||||
|
@ -83,88 +83,24 @@
|
|||
return response;
|
||||
}
|
||||
|
||||
// - (id <WOActionResults>) defaultAction
|
||||
// {
|
||||
// WOResponse *r;
|
||||
// NSString *login, *rhk;
|
||||
// SOGoWebAuthenticator *auth;
|
||||
// SOGoUser *user;
|
||||
// SOGoUserFolder *home;
|
||||
// WOApplication *base;
|
||||
- (id <WOActionResults>) defaultAction
|
||||
{
|
||||
id <WOActionResults> response;
|
||||
NSString *login, *oldLocation;
|
||||
|
||||
// /*
|
||||
// Note: ctx.activeUser is NOT set here. Don't know why, so we retrieve
|
||||
// the user from the authenticator.
|
||||
// */
|
||||
|
||||
// auth = [[self clientObject] authenticatorInContext: context];
|
||||
// user = [auth userInContext: context];
|
||||
// login = [user login];
|
||||
login = [[context activeUser] login];
|
||||
if ([login isEqualToString: @"anonymous"])
|
||||
response = self;
|
||||
else
|
||||
{
|
||||
oldLocation = [[self clientObject] baseURLInContext: context];
|
||||
response
|
||||
= [self redirectToLocation: [NSString stringWithFormat: @"%@/%@",
|
||||
oldLocation, login]];
|
||||
}
|
||||
|
||||
// if ([login isEqualToString:@"anonymous"]) {
|
||||
// /* use root page for unauthenticated users */
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// /* check base */
|
||||
|
||||
// base = [self application];
|
||||
// rhk = [[context request] requestHandlerKey];
|
||||
// if (([rhk length] == 0) || ([base requestHandlerForKey:rhk] == nil)) {
|
||||
// base = [base lookupName: @"so" inContext: context acquire: NO];
|
||||
|
||||
// if (![base isNotNull] || [base isKindOfClass:[NSException class]]) {
|
||||
// /* use root page if home could not be found */
|
||||
// [self errorWithFormat:@"Did not find 'so' request handler!"];
|
||||
// return self;
|
||||
// }
|
||||
// }
|
||||
|
||||
// /* lookup home-page */
|
||||
|
||||
// home = [base lookupName: login inContext: context acquire: NO];
|
||||
// if (![home isNotNull] || [home isKindOfClass:[NSException class]]) {
|
||||
// /* use root page if home could not be found */
|
||||
// return self;
|
||||
// }
|
||||
|
||||
// /* redirect to home-page */
|
||||
|
||||
// r = [context response];
|
||||
// [r setStatus: 302 /* moved */];
|
||||
// [r setHeader: [home baseURLInContext: context]
|
||||
// forKey: @"location"];
|
||||
|
||||
// return r;
|
||||
// }
|
||||
|
||||
/* response generation */
|
||||
|
||||
// - (void) appendToResponse: (WOResponse *) response
|
||||
// inContext: (WOContext *) ctx
|
||||
// {
|
||||
// NSString *rhk;
|
||||
|
||||
// // TODO: we might also want to look into the HTTP basic-auth to redirect to
|
||||
// // the login URL!
|
||||
|
||||
// rhk = [[ctx request] requestHandlerKey];
|
||||
// if ([rhk length] == 0
|
||||
// || [[self application] requestHandlerForKey: rhk] == nil)
|
||||
// {
|
||||
// /* a small hack to redirect to a valid URL */
|
||||
// NSString *url;
|
||||
|
||||
// url = [ctx urlWithRequestHandlerKey: @"so" path: @"/" queryString: nil];
|
||||
// [response setStatus: 302 /* moved */];
|
||||
// [response setHeader: url forKey: @"location"];
|
||||
// [self logWithFormat: @"URL: %@", url];
|
||||
// return;
|
||||
// }
|
||||
|
||||
// [response setHeader: @"text/html" forKey: @"content-type"];
|
||||
// [super appendToResponse: response inContext: ctx];
|
||||
// }
|
||||
return response;
|
||||
}
|
||||
|
||||
- (BOOL) isPublicInContext: (WOContext *) localContext
|
||||
{
|
||||
|
|
|
@ -46,6 +46,14 @@
|
|||
"Access Contents Information" = ( "Owner", "ObjectViewer" );
|
||||
};
|
||||
};
|
||||
SOGoParentFolder = {
|
||||
superclass = "SOGoObject";
|
||||
protectedBy = "Access Contents Information";
|
||||
defaultRoles = {
|
||||
"Access Contents Information" = ( "Authenticated" );
|
||||
"WebDAV Access" = ( "Authenticated" );
|
||||
};
|
||||
};
|
||||
SOGoUserFolder = {
|
||||
superclass = "SOGoFolder";
|
||||
protectedBy = "Access Contents Information";
|
||||
|
|
|
@ -125,7 +125,8 @@ static BOOL shouldDisplayPasswordChange = NO;
|
|||
|
||||
- (NSArray *) timeZonesList
|
||||
{
|
||||
return [NSTimeZone knownTimeZoneNames];
|
||||
return [[NSTimeZone knownTimeZoneNames]
|
||||
sortedArrayUsingSelector: @selector (localizedCaseInsensitiveCompare:)];
|
||||
}
|
||||
|
||||
- (NSString *) userTimeZone
|
||||
|
|
|
@ -110,8 +110,11 @@
|
|||
|
||||
/* Button Titles */
|
||||
|
||||
"Add..." = "Add...";
|
||||
"Remove" = "Remove";
|
||||
"New Calendar..." = "New Calendar...";
|
||||
"Subscribe to a Calendar..." = "Subscribe to a Calendar...";
|
||||
"Remove the selected Calendar" = "Remove the selected Calendar";
|
||||
|
||||
"Name of the Calendar" = "Name of the Calendar";
|
||||
|
||||
"new" = "New";
|
||||
"printview" = "Print View";
|
||||
|
|
|
@ -111,8 +111,11 @@
|
|||
|
||||
/* Button Titles */
|
||||
|
||||
"Add..." = "Ajouter...";
|
||||
"Remove" = "Enlever";
|
||||
"New Calendar..." = "Nouvel agenda...";
|
||||
"Subscribe to a Calendar..." = "S'inscrire à un agenda...";
|
||||
"Remove the selected Calendar" = "Enlever l'agenda sélectionné";
|
||||
|
||||
"Name of the Calendar" = "Nom de l'agenda";
|
||||
|
||||
"new" = "Nouveau";
|
||||
"printview" = "Version imprimable";
|
||||
|
|
|
@ -48,7 +48,7 @@ SchedulerUI_RESOURCE_FILES += \
|
|||
product.plist
|
||||
|
||||
SchedulerUI_RESOURCE_FILES += \
|
||||
Toolbars/SOGoAppointmentFolder.toolbar \
|
||||
Toolbars/SOGoAppointmentFolders.toolbar \
|
||||
Toolbars/SOGoAppointmentObject.toolbar \
|
||||
Toolbars/SOGoAppointmentObjectAccept.toolbar \
|
||||
Toolbars/SOGoAppointmentObjectDecline.toolbar \
|
||||
|
|
|
@ -100,8 +100,11 @@
|
|||
|
||||
/* Button Titles */
|
||||
|
||||
"Add..." = "Hinzufügen...";
|
||||
"Remove" = "Löschen";
|
||||
"New Calendar..." = "New Calendar...";
|
||||
"Subscribe to a Calendar..." = "Subscribe to a Calendar...";
|
||||
"Remove the selected Calendar" = "Remove the selected Calendar";
|
||||
|
||||
"Name of the Calendar" = "Name of the Calendar";
|
||||
|
||||
"new" = "Neu";
|
||||
"printview" = "Version imprimable";
|
||||
|
|
|
@ -286,14 +286,14 @@
|
|||
{
|
||||
NSString *objectId, *method, *uri;
|
||||
id <WOActionResults> result;
|
||||
Class clientKlazz;
|
||||
SOGoAppointmentFolder *co;
|
||||
|
||||
clientKlazz = [[self clientObject] class];
|
||||
objectId = [clientKlazz globallyUniqueObjectId];
|
||||
co = [self clientObject];
|
||||
objectId = [co globallyUniqueObjectId];
|
||||
if ([objectId length] > 0)
|
||||
{
|
||||
method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsAppointment",
|
||||
[self userFolderPath], objectId];
|
||||
method = [NSString stringWithFormat:@"%@/%@/editAsAppointment",
|
||||
[co soURL], objectId];
|
||||
uri = [self completeHrefForMethod: method];
|
||||
result = [self redirectToLocation: uri];
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSNull.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
@ -38,6 +39,7 @@
|
|||
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
||||
#import <SoObjects/SOGo/NSObject+Utilities.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolders.h>
|
||||
|
||||
#import <UI/Common/WODirectAction+SOGo.h>
|
||||
|
||||
|
@ -214,36 +216,6 @@
|
|||
return aptFolder;
|
||||
}
|
||||
|
||||
- (NSArray *) _activeCalendarFolders
|
||||
{
|
||||
NSMutableArray *activeFolders;
|
||||
NSEnumerator *folders;
|
||||
NSDictionary *currentFolderDict;
|
||||
SOGoAppointmentFolder *currentFolder, *clientObject;
|
||||
|
||||
activeFolders = [NSMutableArray new];
|
||||
[activeFolders autorelease];
|
||||
|
||||
clientObject = [self clientObject];
|
||||
|
||||
folders = [[clientObject calendarFolders] objectEnumerator];
|
||||
currentFolderDict = [folders nextObject];
|
||||
while (currentFolderDict)
|
||||
{
|
||||
if ([[currentFolderDict objectForKey: @"active"] boolValue])
|
||||
{
|
||||
currentFolder
|
||||
= [self _aptFolder: [currentFolderDict objectForKey: @"folder"]
|
||||
withClientObject: clientObject];
|
||||
[activeFolders addObject: currentFolder];
|
||||
}
|
||||
|
||||
currentFolderDict = [folders nextObject];
|
||||
}
|
||||
|
||||
return activeFolders;
|
||||
}
|
||||
|
||||
- (NSArray *) _fetchFields: (NSArray *) fields
|
||||
forComponentOfType: (NSString *) component
|
||||
{
|
||||
|
@ -252,34 +224,42 @@
|
|||
NSMutableDictionary *infos, *currentInfo, *newInfo;
|
||||
NSString *owner, *uid;
|
||||
NSNull *marker;
|
||||
SOGoAppointmentFolders *clientObject;
|
||||
|
||||
marker = [NSNull null];
|
||||
|
||||
infos = [NSMutableDictionary dictionary];
|
||||
folders = [[self _activeCalendarFolders] objectEnumerator];
|
||||
clientObject = [self clientObject];
|
||||
|
||||
folders = [[clientObject subFolders] objectEnumerator];
|
||||
currentFolder = [folders nextObject];
|
||||
while (currentFolder)
|
||||
{
|
||||
owner = [currentFolder ownerInContext: context];
|
||||
currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
component: component] objectEnumerator];
|
||||
newInfo = [currentInfos nextObject];
|
||||
while (newInfo)
|
||||
if ([currentFolder isActive])
|
||||
{
|
||||
uid = [newInfo objectForKey: @"c_uid"];
|
||||
currentInfo = [infos objectForKey: uid];
|
||||
if (!currentInfo
|
||||
|| [owner isEqualToString: userLogin])
|
||||
{
|
||||
[self _updatePrivacyInComponent: newInfo
|
||||
fromFolder: currentFolder];
|
||||
[newInfo setObject: owner forKey: @"c_owner"];
|
||||
[infos setObject: [newInfo objectsForKeys: fields
|
||||
notFoundMarker: marker]
|
||||
forKey: uid];
|
||||
}
|
||||
owner = [currentFolder ownerInContext: context];
|
||||
currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
component: component] objectEnumerator];
|
||||
newInfo = [currentInfos nextObject];
|
||||
while (newInfo)
|
||||
{
|
||||
uid = [newInfo objectForKey: @"c_uid"];
|
||||
currentInfo = [infos objectForKey: uid];
|
||||
if (!currentInfo
|
||||
|| [owner isEqualToString: userLogin])
|
||||
{
|
||||
[self _updatePrivacyInComponent: newInfo
|
||||
fromFolder: currentFolder];
|
||||
[newInfo setObject: [currentFolder nameInContainer]
|
||||
forKey: @"c_folder"];
|
||||
// [newInfo setObject: owner forKey: @"c_owner"];
|
||||
[infos setObject: [newInfo objectsForKeys: fields
|
||||
notFoundMarker: marker]
|
||||
forKey: uid];
|
||||
}
|
||||
newInfo = [currentInfos nextObject];
|
||||
}
|
||||
}
|
||||
currentFolder = [folders nextObject];
|
||||
}
|
||||
|
@ -326,7 +306,7 @@
|
|||
[self _setupContext];
|
||||
|
||||
newEvents = [NSMutableArray array];
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_owner", @"c_status",
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
||||
@"c_title", @"c_startdate", @"c_enddate", @"c_location",
|
||||
@"c_isallday", nil];
|
||||
events = [[self _fetchFields: fields
|
||||
|
@ -397,7 +377,7 @@
|
|||
|
||||
[self _setupContext];
|
||||
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_owner", @"c_status",
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
||||
@"c_title", @"c_enddate", nil];
|
||||
|
||||
tasks = [[self _fetchFields: fields
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
|
@ -41,6 +42,15 @@ static NSMutableArray *yearMenuItems = nil;
|
|||
|
||||
@implementation UIxCalMainView
|
||||
|
||||
- (NSString *) userUTCOffset
|
||||
{
|
||||
NSTimeZone *userTZ;
|
||||
|
||||
userTZ = [[context activeUser] timeZone];
|
||||
|
||||
return [NSString stringWithFormat: @"%d", [userTZ secondsFromGMT]];
|
||||
}
|
||||
|
||||
- (NSArray *) monthMenuItems
|
||||
{
|
||||
unsigned int count;
|
||||
|
|
|
@ -23,29 +23,23 @@
|
|||
#ifndef UIXCALENDARSELECTOR_H
|
||||
#define UIXCALENDARSELECTOR_H
|
||||
|
||||
#import <UI/SOGoUI/UIxComponent.h>
|
||||
|
||||
@class NSArray;
|
||||
@class NSMutableArray;
|
||||
@class NSDictionary;
|
||||
@class NSMutableDictionary;
|
||||
@class NSString;
|
||||
@class iCalPerson;
|
||||
|
||||
@interface UIxCalendarSelector : UIxComponent
|
||||
{
|
||||
NSMutableDictionary *colors;
|
||||
|
||||
NSDictionary *currentCalendarFolder;
|
||||
NSString *currentCalendarLogin;
|
||||
NSMutableArray *calendars;
|
||||
NSDictionary *currentCalendar;
|
||||
}
|
||||
|
||||
- (NSArray *) calendarFolders;
|
||||
- (NSArray *) calendars;
|
||||
|
||||
- (void) setCurrentCalendarFolder: (NSDictionary *) newCurrentCalendarFolder;
|
||||
- (NSDictionary *) currentCalendarFolder;
|
||||
|
||||
- (NSString *) currentCalendarSpanBG;
|
||||
- (NSString *) currentCalendarLogin;
|
||||
- (NSString *) currentCalendarStyle;
|
||||
- (void) setCurrentCalendar: (NSDictionary *) newCalendar;
|
||||
- (NSDictionary *) currentCalendar;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -22,34 +22,30 @@
|
|||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGExtensions/NGExtensions.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
#import <SOGo/NSDictionary+Utilities.h>
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
|
||||
#import "UIxCalendarSelector.h"
|
||||
|
||||
static inline char
|
||||
darkenedColor (const char value)
|
||||
{
|
||||
char newValue;
|
||||
// static inline char
|
||||
// darkenedColor (const char value)
|
||||
// {
|
||||
// char newValue;
|
||||
|
||||
if (value >= '0' && value <= '9')
|
||||
newValue = ((value - '0') / 2) + '0';
|
||||
else if (value >= 'a' && value <= 'f')
|
||||
newValue = ((value + 10 - 'a') / 2) + '0';
|
||||
else if (value >= 'A' && value <= 'F')
|
||||
newValue = ((value + 10 - 'A') / 2) + '0';
|
||||
else
|
||||
newValue = value;
|
||||
// if (value >= '0' && value <= '9')
|
||||
// newValue = ((value - '0') / 2) + '0';
|
||||
// else if (value >= 'a' && value <= 'f')
|
||||
// newValue = ((value + 10 - 'a') / 2) + '0';
|
||||
// else if (value >= 'A' && value <= 'F')
|
||||
// newValue = ((value + 10 - 'A') / 2) + '0';
|
||||
// else
|
||||
// newValue = value;
|
||||
|
||||
return newValue;
|
||||
}
|
||||
// return newValue;
|
||||
// }
|
||||
|
||||
static inline NSString *
|
||||
colorForNumber (unsigned int number)
|
||||
|
@ -90,8 +86,8 @@ colorForNumber (unsigned int number)
|
|||
{
|
||||
if ((self = [super init]))
|
||||
{
|
||||
colors = nil;
|
||||
currentCalendarFolder = nil;
|
||||
calendars = nil;
|
||||
currentCalendar = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -99,82 +95,61 @@ colorForNumber (unsigned int number)
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[currentCalendarFolder release];
|
||||
[colors release];
|
||||
[calendars release];
|
||||
[currentCalendar release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray *) calendarFolders
|
||||
- (NSArray *) calendars
|
||||
{
|
||||
NSArray *calendarFolders;
|
||||
NSEnumerator *newFolders;
|
||||
NSDictionary *currentFolder;
|
||||
unsigned int count;
|
||||
NSArray *folders;
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSMutableDictionary *calendar;
|
||||
unsigned int count, max;
|
||||
NSString *folderId, *folderName;
|
||||
NSNumber *isActive;
|
||||
|
||||
calendarFolders = [[self clientObject] calendarFolders];
|
||||
if (!colors)
|
||||
if (!calendars)
|
||||
{
|
||||
colors = [NSMutableDictionary new];
|
||||
count = 0;
|
||||
newFolders = [calendarFolders objectEnumerator];
|
||||
currentFolder = [newFolders nextObject];
|
||||
while (currentFolder)
|
||||
folders = [[self clientObject] subFolders];
|
||||
max = [folders count];
|
||||
calendars = [[NSMutableArray alloc] initWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
[colors setObject: colorForNumber (count)
|
||||
forKey: [currentFolder objectForKey: @"folder"]];
|
||||
count++;
|
||||
currentFolder = [newFolders nextObject];
|
||||
folder = [folders objectAtIndex: count];
|
||||
calendar = [NSMutableDictionary dictionary];
|
||||
folderName = [folder nameInContainer];
|
||||
[calendar setObject:
|
||||
[NSString stringWithFormat: @"/%@", folderName]
|
||||
forKey: @"id"];
|
||||
[calendar setObject: [folder displayName]
|
||||
forKey: @"displayName"];
|
||||
[calendar setObject: folderName forKey: @"folder"];
|
||||
[calendar setObject: colorForNumber (count)
|
||||
forKey: @"color"];
|
||||
isActive = [NSNumber numberWithBool: [folder isActive]];
|
||||
[calendar setObject: isActive forKey: @"active"];
|
||||
[calendars addObject: calendar];
|
||||
}
|
||||
}
|
||||
|
||||
return calendarFolders;
|
||||
return calendars;
|
||||
}
|
||||
|
||||
- (void) setCurrentCalendarFolder: (NSDictionary *) newCurrentCalendarFolder
|
||||
- (void) setCurrentCalendar: (NSDictionary *) newCalendar
|
||||
{
|
||||
ASSIGN (currentCalendarFolder, newCurrentCalendarFolder);
|
||||
ASSIGN (currentCalendar, newCalendar);
|
||||
}
|
||||
|
||||
- (NSDictionary *) currentCalendarFolder
|
||||
- (NSDictionary *) currentCalendar
|
||||
{
|
||||
return currentCalendarFolder;
|
||||
}
|
||||
|
||||
- (NSString *) currentCalendarSpanBG
|
||||
{
|
||||
NSString *colorKey;
|
||||
|
||||
colorKey = [currentCalendarFolder objectForKey: @"folder"];
|
||||
|
||||
return [colors objectForKey: colorKey];
|
||||
}
|
||||
|
||||
- (NSString *) currentCalendarLogin
|
||||
{
|
||||
NSArray *parts;
|
||||
NSMutableString *login;
|
||||
|
||||
login = [NSMutableString string];
|
||||
parts = [[currentCalendarFolder objectForKey: @"folder"]
|
||||
componentsSeparatedByString: @":"];
|
||||
[login appendString: (([parts count] > 1)
|
||||
? [parts objectAtIndex: 0]
|
||||
: [[context activeUser] login])];
|
||||
[login replaceString: @"." withString: @"_"];
|
||||
[login replaceString: @"#" withString: @"_"];
|
||||
[login replaceString: @"@" withString: @"_"];
|
||||
|
||||
return login;
|
||||
return currentCalendar;
|
||||
}
|
||||
|
||||
- (NSString *) currentCalendarStyle
|
||||
{
|
||||
NSString *color;
|
||||
|
||||
color = [self currentCalendarSpanBG];
|
||||
|
||||
return [NSString stringWithFormat: @"color: %@; background-color: %@;",
|
||||
color, color];
|
||||
return [currentCalendar
|
||||
keysWithFormat: @"color: %{color}; background-color: %{color};"];
|
||||
}
|
||||
|
||||
@end /* UIxCalendarSelector */
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentFolders.h>
|
||||
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
|
||||
#import <SoObjects/Appointments/SOGoTaskObject.h>
|
||||
#import <SoObjects/SOGo/NSString+Utilities.h>
|
||||
|
@ -331,19 +332,20 @@
|
|||
|
||||
- (NSArray *) calendarList
|
||||
{
|
||||
SOGoAppointmentFolder *folder;
|
||||
SOGoAppointmentFolder *calendar, *currentCalendar;
|
||||
SOGoAppointmentFolders *calendarParent;
|
||||
NSEnumerator *allCalendars;
|
||||
NSDictionary *currentCalendar;
|
||||
|
||||
if (!calendarList)
|
||||
{
|
||||
calendarList = [NSMutableArray new];
|
||||
folder = [[self clientObject] container];
|
||||
allCalendars = [[folder calendarFolders] objectEnumerator];
|
||||
calendar = [[self clientObject] container];
|
||||
calendarParent = [calendar container];
|
||||
allCalendars = [[calendarParent subFolders] objectEnumerator];
|
||||
currentCalendar = [allCalendars nextObject];
|
||||
while (currentCalendar)
|
||||
{
|
||||
if ([[currentCalendar objectForKey: @"active"] boolValue])
|
||||
if ([currentCalendar isActive])
|
||||
[calendarList addObject: currentCalendar];
|
||||
currentCalendar = [allCalendars nextObject];
|
||||
}
|
||||
|
|
|
@ -324,14 +324,14 @@
|
|||
{
|
||||
NSString *objectId, *method, *uri;
|
||||
id <WOActionResults> result;
|
||||
Class clientKlazz;
|
||||
SOGoAppointmentFolder *co;
|
||||
|
||||
clientKlazz = [[self clientObject] class];
|
||||
objectId = [clientKlazz globallyUniqueObjectId];
|
||||
co = [self clientObject];
|
||||
objectId = [co globallyUniqueObjectId];
|
||||
if ([objectId length] > 0)
|
||||
{
|
||||
method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsTask",
|
||||
[self userFolderPath], objectId];
|
||||
method = [NSString stringWithFormat:@"%@/%@/editAsTask",
|
||||
[co soURL], objectId];
|
||||
uri = [self completeHrefForMethod: method];
|
||||
result = [self redirectToLocation: uri];
|
||||
}
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
};
|
||||
|
||||
categories = {
|
||||
SOGoAppointmentFolder = {
|
||||
SOGoAppointmentFolders = {
|
||||
slots = {
|
||||
toolbar = {
|
||||
protectedBy = "View";
|
||||
value = "SOGoAppointmentFolder.toolbar";
|
||||
value = "SOGoAppointmentFolders.toolbar";
|
||||
};
|
||||
};
|
||||
methods = {
|
||||
|
@ -70,16 +70,6 @@
|
|||
protectedBy = "View";
|
||||
pageName = "UIxCalMonthView";
|
||||
};
|
||||
newevent = {
|
||||
protectedBy = "Add Documents, Images, and Files";
|
||||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "new";
|
||||
};
|
||||
newtask = {
|
||||
protectedBy = "Add Documents, Images, and Files";
|
||||
pageName = "UIxTaskEditor";
|
||||
actionName = "new";
|
||||
};
|
||||
show = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxCalView";
|
||||
|
@ -94,15 +84,45 @@
|
|||
pageName = "UIxAppointmentProposal";
|
||||
actionName = "proposalSearch";
|
||||
};
|
||||
userRights = {
|
||||
protectedBy = "ReadAcls";
|
||||
pageName = "UIxCalUserRightsEditor";
|
||||
};
|
||||
saveUserRights = {
|
||||
protectedBy = "SaveAcls";
|
||||
pageName = "UIxCalUserRightsEditor";
|
||||
actionName = "saveUserRights";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
SOGoAppointmentFolder = {
|
||||
methods = {
|
||||
newevent = {
|
||||
protectedBy = "Add Documents, Images, and Files";
|
||||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "new";
|
||||
};
|
||||
newtask = {
|
||||
protectedBy = "Add Documents, Images, and Files";
|
||||
pageName = "UIxTaskEditor";
|
||||
actionName = "new";
|
||||
};
|
||||
batchDelete = {
|
||||
protectedBy = "Delete Objects";
|
||||
pageName = "UIxCalMainView";
|
||||
actionName = "batchDelete";
|
||||
};
|
||||
updateCalendars = {
|
||||
|
||||
show = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxCalView";
|
||||
actionName = "redirectForUIDs";
|
||||
};
|
||||
batchDelete = {
|
||||
protectedBy = "Delete Objects";
|
||||
pageName = "UIxCalMainView";
|
||||
actionName = "updateCalendars";
|
||||
actionName = "batchDelete";
|
||||
};
|
||||
editAttendees = {
|
||||
protectedBy = "View";
|
||||
|
@ -119,6 +139,7 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
SOGoCalendarComponent = {
|
||||
};
|
||||
|
||||
|
@ -158,6 +179,10 @@
|
|||
pageName = "UIxAppointmentEditor";
|
||||
actionName = "decline";
|
||||
};
|
||||
editAttendees = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxAttendeesEditor";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -62,13 +62,10 @@
|
|||
<ul id="contactFolders">
|
||||
<var:foreach list="contactFolders" item="currentFolder"
|
||||
><li var:id="currentContactFolderId"
|
||||
><var:string value="currentContactFolderName" /></li
|
||||
var:owner="currentContactFolderOwner"
|
||||
><var:string value="currentContactFolderName" /></li
|
||||
></var:foreach
|
||||
><var:foreach list="additionalFolders"
|
||||
item="currentAdditionalFolder"
|
||||
><li var:id="currentAdditionalFolder" class="denied"
|
||||
><var:string value="currentAdditionalFolderName" /></li
|
||||
></var:foreach>
|
||||
>
|
||||
</ul>
|
||||
|
||||
<var:if condition="hasContactSelectionButtons">
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
className="UIxPageFrame"
|
||||
title="title"
|
||||
>
|
||||
<script type="text/javascript">
|
||||
var UTCOffset = <var:string value="userUTCOffset"/>;
|
||||
</script>
|
||||
<div class="preload" style="visibility: hidden;">
|
||||
<img rsrc:src="event-gradient.png"/>
|
||||
</div>
|
||||
|
|
|
@ -7,30 +7,34 @@
|
|||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<style type="text/css">
|
||||
<var:foreach list="calendarFolders" item="currentCalendarFolder">
|
||||
.ownerIs<var:string value="currentCalendarLogin" />
|
||||
{ background-color: <var:string value="currentCalendarSpanBG" /> !important; }
|
||||
<var:foreach list="calendars" item="currentCalendar">
|
||||
.calendarFolder<var:string value="currentCalendar.folder" />
|
||||
{ background-color: <var:string value="currentCalendar.color" /> !important; }
|
||||
</var:foreach>
|
||||
</style>
|
||||
<div id="calendarSelector">
|
||||
<span id="calendarSelectorButtons">
|
||||
<a href="#" class="toolbarButton"
|
||||
><span class="toolbarButton"><img rsrc:src="add-calendar.png"
|
||||
label:title="Add..."
|
||||
label:title="New Calendar..."
|
||||
/></span></a>
|
||||
<a href="#" class="toolbarButton"
|
||||
><span class="toolbarButton"><img rsrc:src="add-user-calendar.png"
|
||||
label:title="Subscribe to a Calendar..."
|
||||
/></span></a>
|
||||
<a href="#" class="toolbarButton"
|
||||
><span class="toolbarButton"><img rsrc:src="remove-calendar.png"
|
||||
label:title="Remove"
|
||||
label:title="Remove the selected Calendar"
|
||||
/></span></a>
|
||||
</span>
|
||||
<ul id="calendarList" multiselect="yes">
|
||||
<var:foreach list="calendarFolders" item="currentCalendarFolder"
|
||||
><li class="denied" var:id="currentCalendarFolder.folder">
|
||||
<var:foreach list="calendars" item="currentCalendar"
|
||||
><li class="denied" var:id="currentCalendar.id">
|
||||
<input type="checkbox" class="checkBox"
|
||||
const:disabled="disabled"
|
||||
var:checked="currentCalendarFolder.active" />
|
||||
var:checked="currentCalendar.active" />
|
||||
<div class="colorBox" var:style="currentCalendarStyle">OO</div>
|
||||
<var:string value="currentCalendarFolder.displayName"
|
||||
<var:string value="currentCalendar.displayName"
|
||||
/></li>
|
||||
</var:foreach>
|
||||
</ul>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:const="http://www.skyrix.com/od/constant"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
xmlns:label="OGo:label"
|
||||
><var:string var:value="doctype" const:escapeHTML="NO" />
|
||||
<var:if condition="hideFrame" const:negate="YES"
|
||||
><html>
|
||||
|
|
|
@ -19,8 +19,8 @@ function validateEditorInput(sender) {
|
|||
errortext = errortext + labels.error_missingrecipients + "\n";
|
||||
|
||||
if (errortext.length > 0) {
|
||||
alert(labels.error_validationfailed.decodeEntities() + ":\n"
|
||||
+ errortext.decodeEntities());
|
||||
alert(labels.error_validationfailed + ":\n"
|
||||
+ errortext);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -497,28 +497,24 @@ function refreshContacts(contactId) {
|
|||
}
|
||||
|
||||
function onAddressBookNew(event) {
|
||||
var name = window.prompt(labels["Name of the Address Book"].decodeEntities());
|
||||
if (name) {
|
||||
if (document.newAbAjaxRequest) {
|
||||
document.newAbAjaxRequest.aborted = true;
|
||||
document.newAbAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/newAb?name=" + name;
|
||||
document.newAbAjaxRequest
|
||||
= triggerAjaxRequest(url, newAbCallback, name);
|
||||
}
|
||||
createFolder(window.prompt(labels["Name of the Address Book"]),
|
||||
appendAddressBook);
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function appendAddressBook(name, folder) {
|
||||
var li = document.createElement("li");
|
||||
$("contactFolders").appendChild(li);
|
||||
li.setAttribute("id", folder);
|
||||
li.appendChild(document.createTextNode(name));
|
||||
setEventsOnContactFolder(li);
|
||||
if (folder)
|
||||
folder = accessToSubscribedFolder(folder);
|
||||
else
|
||||
folder = "/" + name;
|
||||
var li = document.createElement("li");
|
||||
$("contactFolders").appendChild(li);
|
||||
li.setAttribute("id", folder);
|
||||
li.appendChild(document.createTextNode(name));
|
||||
setEventsOnContactFolder(li);
|
||||
}
|
||||
|
||||
function newAbCallback(http) {
|
||||
function newFolderCallback(http) {
|
||||
if (http.readyState == 4
|
||||
&& http.status == 201) {
|
||||
var name = http.callbackData;
|
||||
|
@ -552,60 +548,60 @@ function onAddressBookRemove(event) {
|
|||
var selector = $("contactFolders");
|
||||
var nodes = selector.getSelectedNodes();
|
||||
if (nodes.length > 0) {
|
||||
nodes[0].deselect();
|
||||
var folderId = nodes[0].getAttribute("id");
|
||||
var folderIdElements = folderId.split(":");
|
||||
if (folderIdElements.length > 1)
|
||||
unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
|
||||
else {
|
||||
var abId = folderIdElements[0].substr(1);
|
||||
deletePersonalAddressBook(abId);
|
||||
var personal = $("/personal");
|
||||
personal.select();
|
||||
onFolderSelectionChange();
|
||||
}
|
||||
nodes[0].deselect();
|
||||
var folderId = nodes[0].getAttribute("id");
|
||||
var folderIdElements = folderId.split("_");
|
||||
if (folderIdElements.length > 1)
|
||||
unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
|
||||
else {
|
||||
var abId = folderIdElements[0].substr(1);
|
||||
deletePersonalAddressBook(abId);
|
||||
var personal = $("/personal");
|
||||
personal.select();
|
||||
onFolderSelectionChange();
|
||||
}
|
||||
}
|
||||
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function deletePersonalAddressBook(folderId) {
|
||||
var label
|
||||
= labels["Are you sure you want to delete the selected address book?"];
|
||||
if (window.confirm(label.decodeEntities())) {
|
||||
if (document.deletePersonalABAjaxRequest) {
|
||||
document.deletePersonalABAjaxRequest.aborted = true;
|
||||
document.deletePersonalABAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/" + folderId + "/delete";
|
||||
document.deletePersonalABAjaxRequest
|
||||
= triggerAjaxRequest(url, deletePersonalAddressBookCallback,
|
||||
folderId);
|
||||
}
|
||||
var label
|
||||
= labels["Are you sure you want to delete the selected address book?"];
|
||||
if (window.confirm(label)) {
|
||||
if (document.deletePersonalABAjaxRequest) {
|
||||
document.deletePersonalABAjaxRequest.aborted = true;
|
||||
document.deletePersonalABAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/" + folderId + "/deleteFolder";
|
||||
document.deletePersonalABAjaxRequest
|
||||
= triggerAjaxRequest(url, deletePersonalAddressBookCallback,
|
||||
folderId);
|
||||
}
|
||||
}
|
||||
|
||||
function deletePersonalAddressBookCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
if (http.status == 200) {
|
||||
var ul = $("contactFolders");
|
||||
if (isHttpStatus204(http.status)) {
|
||||
var ul = $("contactFolders");
|
||||
|
||||
var children = ul.childNodesWithTag("li");
|
||||
var i = 0;
|
||||
var done = false;
|
||||
while (!done && i < children.length) {
|
||||
var currentFolderId = children[i].getAttribute("id").substr(1);
|
||||
if (currentFolderId == http.callbackData) {
|
||||
ul.removeChild(children[i]);
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
var children = ul.childNodesWithTag("li");
|
||||
var i = 0;
|
||||
var done = false;
|
||||
while (!done && i < children.length) {
|
||||
var currentFolderId = children[i].getAttribute("id").substr(1);
|
||||
if (currentFolderId == http.callbackData) {
|
||||
ul.removeChild(children[i]);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
document.deletePersonalABAjaxRequest = null;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
document.deletePersonalABAjaxRequest = null;
|
||||
}
|
||||
else
|
||||
log ("ajax problem 5: " + http.status);
|
||||
log ("ajax problem 5: " + http.status);
|
||||
}
|
||||
|
||||
function configureDragHandles() {
|
||||
|
@ -677,6 +673,34 @@ function setEventsOnContactFolder(node) {
|
|||
onContactFoldersContextMenu.bindAsEventListener(node), false);
|
||||
}
|
||||
|
||||
function onMenuModify(event) {
|
||||
var folders = $("contactFolders");
|
||||
var selected = folders.getSelectedNodes()[0];
|
||||
|
||||
if (UserLogin == selected.getAttribute("owner")) {
|
||||
var currentName = selected.innerHTML;
|
||||
var newName = window.prompt(labels["Address Book Name"],
|
||||
currentName);
|
||||
if (newName && newName.length > 0
|
||||
&& newName != currentName) {
|
||||
var url = (URLForFolderID(selected.getAttribute("id"))
|
||||
+ "/renameFolder?name=" + escape(newName.utf8encode()));
|
||||
triggerAjaxRequest(url, folderRenameCallback,
|
||||
{node: selected, name: newName});
|
||||
}
|
||||
} else
|
||||
window.alert(clabels["Unable to rename that folder!"]);
|
||||
}
|
||||
|
||||
function folderRenameCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
if (isHttpStatus204(http.status)) {
|
||||
var dict = http.callbackData;
|
||||
dict["node"].innerHTML = dict["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMenuSharing(event) {
|
||||
var folders = $("contactFolders");
|
||||
var selected = folders.getSelectedNodes()[0];
|
||||
|
@ -688,7 +712,7 @@ function onMenuSharing(event) {
|
|||
|
||||
function getMenus() {
|
||||
var menus = {};
|
||||
menus["contactFoldersMenu"] = new Array(null, "-", null,
|
||||
menus["contactFoldersMenu"] = new Array(onMenuModify, "-", null,
|
||||
null, "-", null, "-",
|
||||
onMenuSharing);
|
||||
menus["contactMenu"] = new Array(onMenuEditContact, "-",
|
||||
|
|
|
@ -207,7 +207,7 @@ function ctxFolderAdd(sender) {
|
|||
}
|
||||
|
||||
function ctxFolderDelete(sender) {
|
||||
if (!confirm("Delete current folder?").decodeEntities())
|
||||
if (!confirm("Delete current folder?"))
|
||||
return false;
|
||||
|
||||
// TODO: should use a form-POST or AJAX
|
||||
|
@ -306,10 +306,10 @@ function onMenuDeleteMessage(event) {
|
|||
function onPrintCurrentMessage(event) {
|
||||
var rowIds = $("messageList").getSelectedRowsId();
|
||||
if (rowIds.length == 0) {
|
||||
window.alert(labels["Please select a message to print."].decodeEntities());
|
||||
window.alert(labels["Please select a message to print."]);
|
||||
}
|
||||
else if (rowIds.length > 1) {
|
||||
window.alert(labels["Please select only one message to print."].decodeEntities());
|
||||
window.alert(labels["Please select only one message to print."]);
|
||||
}
|
||||
else
|
||||
window.print();
|
||||
|
@ -492,7 +492,7 @@ function quotasCallback(http) {
|
|||
var used = mbQuotas["usedSpace"];
|
||||
var max = mbQuotas["maxQuota"];
|
||||
var percents = (Math.round(used * 10000 / max) / 100);
|
||||
var format = labels["quotasFormat"].decodeEntities();
|
||||
var format = labels["quotasFormat"];
|
||||
var text = format.formatted(used, max, percents);
|
||||
window.status = text;
|
||||
}
|
||||
|
@ -1265,7 +1265,7 @@ function buildMailboxes(accountName, encoded) {
|
|||
}
|
||||
|
||||
function onMenuCreateFolder(event) {
|
||||
var name = window.prompt(labels["Name :"].decodeEntities(), "");
|
||||
var name = window.prompt(labels["Name :"], "");
|
||||
if (name && name.length > 0) {
|
||||
var folderID = document.menuTarget.getAttribute("dataname");
|
||||
var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name;
|
||||
|
@ -1275,7 +1275,7 @@ function onMenuCreateFolder(event) {
|
|||
|
||||
function onMenuRenameFolder(event) {
|
||||
var name = window.prompt(labels["Enter the new name of your folder :"]
|
||||
.decodeEntities(),
|
||||
,
|
||||
"");
|
||||
if (name && name.length > 0) {
|
||||
var folderID = document.menuTarget.getAttribute("dataname");
|
||||
|
@ -1285,7 +1285,7 @@ function onMenuRenameFolder(event) {
|
|||
}
|
||||
|
||||
function onMenuDeleteFolder(event) {
|
||||
var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"].decodeEntities());
|
||||
var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"]);
|
||||
if (answer) {
|
||||
var folderID = document.menuTarget.getAttribute("dataname");
|
||||
var urlstr = URLForFolderID(folderID) + "/deleteFolder";
|
||||
|
@ -1320,7 +1320,7 @@ function folderOperationCallback(http) {
|
|||
&& http.status == 204)
|
||||
initMailboxTree();
|
||||
else
|
||||
window.alert(labels["Operation failed"].decodeEntities());
|
||||
window.alert(labels["Operation failed"]);
|
||||
}
|
||||
|
||||
function folderRefreshCallback(http) {
|
||||
|
@ -1331,7 +1331,7 @@ function folderRefreshCallback(http) {
|
|||
refreshCurrentFolder();
|
||||
}
|
||||
else
|
||||
window.alert(labels["Operation failed"].decodeEntities());
|
||||
window.alert(labels["Operation failed"]);
|
||||
}
|
||||
|
||||
function getMenus() {
|
||||
|
|
|
@ -12,10 +12,10 @@ DIV#loginScreen
|
|||
background-color: #d4d0c8;
|
||||
margin: 0px auto;
|
||||
margin-top: 5em;
|
||||
padding: 10px;
|
||||
padding: 5px;
|
||||
border: 2px solid transparent;
|
||||
width: 197px;
|
||||
height: 300px;
|
||||
width: 200px;
|
||||
height: 315px;
|
||||
-moz-border-top-colors: #efebe7 #fff;
|
||||
-moz-border-left-colors: #efebe7 #fff;
|
||||
-moz-border-right-colors: #000 #9c9a94 transparent;
|
||||
|
@ -26,8 +26,8 @@ DIV#loginScreen IMG
|
|||
{ border: 0px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
height: 192px;
|
||||
width: 192px; }
|
||||
height: 200px;
|
||||
width: 200px; }
|
||||
|
||||
DIV#loginScreen INPUT.textField
|
||||
{ width: 187px; }
|
||||
|
|
|
@ -17,7 +17,7 @@ var cachedDateSelectors = new Array();
|
|||
var contactSelectorAction = 'calendars-contacts';
|
||||
|
||||
var eventsToDelete = new Array();
|
||||
var ownersOfEventsToDelete = new Array();
|
||||
var calendarsOfEventsToDelete = new Array();
|
||||
|
||||
var usersRightsWindowHeight = 250;
|
||||
var usersRightsWindowWidth = 502;
|
||||
|
@ -27,15 +27,11 @@ function newEvent(sender, type) {
|
|||
if (!day)
|
||||
day = currentDay;
|
||||
|
||||
var user = UserLogin;
|
||||
if (sender.parentNode.getAttribute("id") != "toolbar"
|
||||
&& currentView == "multicolumndayview" && type == "event")
|
||||
user = sender.parentNode.parentNode.getAttribute("user");
|
||||
|
||||
var hour = sender.hour;
|
||||
if (!hour)
|
||||
hour = sender.getAttribute("hour");
|
||||
var urlstr = UserFolderURL + "../" + user + "/Calendar/new" + type;
|
||||
var folderID = getSelectedFolder();
|
||||
var urlstr = ApplicationBaseURL + folderID + "/new" + type;
|
||||
var params = new Array();
|
||||
if (day)
|
||||
params.push("day=" + day);
|
||||
|
@ -49,6 +45,18 @@ function newEvent(sender, type) {
|
|||
return false; /* stop following the link */
|
||||
}
|
||||
|
||||
function getSelectedFolder() {
|
||||
var folder;
|
||||
|
||||
var nodes = $("calendarList").getSelectedRows();
|
||||
if (nodes.length > 0)
|
||||
folder = nodes[0].getAttribute("id");
|
||||
else
|
||||
folder = "/personal";
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
function onMenuNewEventClick(event) {
|
||||
newEvent(this, "event");
|
||||
}
|
||||
|
@ -57,13 +65,8 @@ function onMenuNewTaskClick(event) {
|
|||
newEvent(this, "task");
|
||||
}
|
||||
|
||||
function _editEventId(id, owner) {
|
||||
var urlBase;
|
||||
if (owner)
|
||||
urlBase = UserFolderURL + "../" + owner + "/";
|
||||
urlBase += "Calendar/"
|
||||
|
||||
var urlstr = urlBase + id + "/edit";
|
||||
function _editEventId(id, calendar) {
|
||||
var urlstr = ApplicationBaseURL + "/" + calendar + "/" + id + "/edit";
|
||||
var targetname = "SOGo_edit_" + id;
|
||||
var win = window.open(urlstr, "_blank",
|
||||
"width=490,height=470,resizable=0");
|
||||
|
@ -76,10 +79,10 @@ function editEvent() {
|
|||
|
||||
for (var i = 0; i < nodes.length; i++)
|
||||
_editEventId(nodes[i].getAttribute("id"),
|
||||
nodes[i].owner);
|
||||
nodes[i].calendar);
|
||||
} else if (selectedCalendarCell) {
|
||||
_editEventId(selectedCalendarCell[0].cname,
|
||||
selectedCalendarCell[0].owner);
|
||||
selectedCalendarCell[0].calendar);
|
||||
}
|
||||
|
||||
return false; /* stop following the link */
|
||||
|
@ -87,9 +90,9 @@ function editEvent() {
|
|||
|
||||
function _batchDeleteEvents() {
|
||||
var events = eventsToDelete.shift();
|
||||
var owner = ownersOfEventsToDelete.shift();
|
||||
var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids="
|
||||
+ events.join('/'));
|
||||
var calendar = calendarsOfEventsToDelete.shift();
|
||||
var urlstr = (ApplicationBaseURL + "/" + calendar
|
||||
+ "/batchDelete?ids=" + events.join('/'));
|
||||
document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
|
||||
deleteEventCallback,
|
||||
events);
|
||||
|
@ -102,9 +105,9 @@ function deleteEvent() {
|
|||
if (nodes.length > 0) {
|
||||
var label = "";
|
||||
if (listOfSelection == $("tasksList"))
|
||||
label = labels["taskDeleteConfirmation"].decodeEntities();
|
||||
label = labels["taskDeleteConfirmation"];
|
||||
else
|
||||
label = labels["eventDeleteConfirmation"].decodeEntities();
|
||||
label = labels["eventDeleteConfirmation"];
|
||||
|
||||
if (confirm(label)) {
|
||||
if (document.deleteEventAjaxRequest) {
|
||||
|
@ -112,33 +115,33 @@ function deleteEvent() {
|
|||
document.deleteEventAjaxRequest.abort();
|
||||
}
|
||||
var sortedNodes = new Array();
|
||||
var owners = new Array();
|
||||
var calendars = new Array();
|
||||
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
var owner = nodes[i].owner;
|
||||
if (!sortedNodes[owner]) {
|
||||
sortedNodes[owner] = new Array();
|
||||
owners.push(owner);
|
||||
var calendar = nodes[i].calendar;
|
||||
if (!sortedNodes[calendar]) {
|
||||
sortedNodes[calendar] = new Array();
|
||||
calendars.push(calendar);
|
||||
}
|
||||
sortedNodes[owner].push(nodes[i].cname);
|
||||
sortedNodes[calendar].push(nodes[i].cname);
|
||||
}
|
||||
for (var i = 0; i < owners.length; i++) {
|
||||
ownersOfEventsToDelete.push(owners[i]);
|
||||
eventsToDelete.push(sortedNodes[owners[i]]);
|
||||
for (var i = 0; i < calendars.length; i++) {
|
||||
calendarsOfEventsToDelete.push(calendars[i]);
|
||||
eventsToDelete.push(sortedNodes[calendars[i]]);
|
||||
}
|
||||
_batchDeleteEvents();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selectedCalendarCell) {
|
||||
var label = labels["eventDeleteConfirmation"].decodeEntities();
|
||||
var label = labels["eventDeleteConfirmation"];
|
||||
if (confirm(label)) {
|
||||
if (document.deleteEventAjaxRequest) {
|
||||
document.deleteEventAjaxRequest.aborted = true;
|
||||
document.deleteEventAjaxRequest.abort();
|
||||
}
|
||||
eventsToDelete.push([selectedCalendarCell[0].cname]);
|
||||
ownersOfEventsToDelete.push(selectedCalendarCell[0].owner);
|
||||
calendarsOfEventsToDelete.push(selectedCalendarCell[0].calendar);
|
||||
_batchDeleteEvents();
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +171,7 @@ function closeInvitationWindow() {
|
|||
closePseudoWin.style.top = "0px;";
|
||||
closePseudoWin.style.left = "0px;";
|
||||
closePseudoWin.style.right = "0px;";
|
||||
closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"].decodeEntities()));
|
||||
closePseudoWin.appendChild(document.createTextNode(labels["closeThisWindowMessage"]));
|
||||
document.body.appendChild(closeDiv);
|
||||
document.body.appendChild(closePseudoWin);
|
||||
}
|
||||
|
@ -215,7 +218,7 @@ function deleteEventCallback(http) {
|
|||
}
|
||||
|
||||
function editDoubleClickedEvent(event) {
|
||||
_editEventId(this.cname, this.owner);
|
||||
_editEventId(this.cname, this.calendar);
|
||||
|
||||
preventDefault(event);
|
||||
event.cancelBubble = true;
|
||||
|
@ -316,7 +319,7 @@ function eventsListCallback(http) {
|
|||
$(row).addClassName("eventRow");
|
||||
row.setAttribute("id", escape(data[i][0]));
|
||||
row.cname = escape(data[i][0]);
|
||||
row.owner = data[i][1];
|
||||
row.calendar = data[i][1];
|
||||
|
||||
var startDate = new Date();
|
||||
startDate.setTime(data[i][4] * 1000);
|
||||
|
@ -372,9 +375,8 @@ function tasksListCallback(http) {
|
|||
Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
|
||||
listItem.setAttribute("id", data[i][0]);
|
||||
$(listItem).addClassName(data[i][5]);
|
||||
var owner = data[i][1];
|
||||
listItem.owner = owner;
|
||||
$(listItem).addClassName("ownerIs" + owner.cssSafeString());
|
||||
listItem.calendar = data[i][1];
|
||||
$(listItem).addClassName("calendarFolder" + data[i][1]);
|
||||
listItem.cname = escape(data[i][0]);
|
||||
var input = document.createElement("input");
|
||||
input.setAttribute("type", "checkbox");
|
||||
|
@ -429,7 +431,7 @@ function restoreCurrentDaySelection(div) {
|
|||
}
|
||||
|
||||
function changeDateSelectorDisplay(day, keepCurrentDay) {
|
||||
var url = ApplicationBaseURL + "dateselector";
|
||||
var url = ApplicationBaseURL + "/dateselector";
|
||||
if (day)
|
||||
url += "?day=" + day;
|
||||
|
||||
|
@ -457,7 +459,7 @@ function changeDateSelectorDisplay(day, keepCurrentDay) {
|
|||
}
|
||||
|
||||
function changeCalendarDisplay(time, newView) {
|
||||
var url = ApplicationBaseURL + ((newView) ? newView : currentView);
|
||||
var url = ApplicationBaseURL + "/" + ((newView) ? newView : currentView);
|
||||
|
||||
selectedCalendarCell = null;
|
||||
|
||||
|
@ -583,7 +585,7 @@ function refreshCalendarEvents() {
|
|||
document.refreshCalendarEventsAjaxRequest.aborted = true;
|
||||
document.refreshCalendarEventsAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "eventslist?sd=" + sd + "&ed=" + ed;
|
||||
var url = ApplicationBaseURL + "/eventslist?sd=" + sd + "&ed=" + ed;
|
||||
document.refreshCalendarEventsAjaxRequest
|
||||
= triggerAjaxRequest(url, refreshCalendarEventsCallback,
|
||||
{"startDate": sd, "endDate": ed});
|
||||
|
@ -608,9 +610,9 @@ function drawCalendarEvent(eventData, sd, ed) {
|
|||
var viewEndDate = ed.asDate();
|
||||
|
||||
var startDate = new Date();
|
||||
startDate.setTime(eventData[4] * 1000);
|
||||
startDate.setTime(eventData[4] * 1000 + (1000 * UTCOffset));
|
||||
var endDate = new Date();
|
||||
endDate.setTime(eventData[5] * 1000);
|
||||
endDate.setTime(eventData[5] * 1000 + (1000 * UTCOffset));
|
||||
|
||||
var days = startDate.daysUpTo(endDate);
|
||||
|
||||
|
@ -636,8 +638,8 @@ function drawCalendarEvent(eventData, sd, ed) {
|
|||
|
||||
// log("day: " + days[i]);
|
||||
if (i == 0) {
|
||||
var quarters = (startDate.getHours() * 4
|
||||
+ Math.floor(startDate.getMinutes() / 15));
|
||||
var quarters = (startDate.getUTCHours() * 4
|
||||
+ Math.floor(startDate.getUTCMinutes() / 15));
|
||||
starts = quarters;
|
||||
startHour = startDate.getDisplayHoursString();
|
||||
endHour = endDate.getDisplayHoursString();
|
||||
|
@ -648,8 +650,8 @@ function drawCalendarEvent(eventData, sd, ed) {
|
|||
var ends;
|
||||
var lasts;
|
||||
if (i == days.length - 1) {
|
||||
var quarters = (endDate.getHours() * 4
|
||||
+ Math.ceil(endDate.getMinutes() / 15));
|
||||
var quarters = (endDate.getUTCHours() * 4
|
||||
+ Math.ceil(endDate.getUTCMinutes() / 15));
|
||||
ends = quarters;
|
||||
}
|
||||
else
|
||||
|
@ -706,11 +708,11 @@ function drawCalendarEvent(eventData, sd, ed) {
|
|||
}
|
||||
}
|
||||
|
||||
function newEventDIV(cname, owner, starts, lasts,
|
||||
function newEventDIV(cname, calendar, starts, lasts,
|
||||
startHour, endHour, title) {
|
||||
var eventDiv = document.createElement("div");
|
||||
eventDiv.cname = escape(cname);
|
||||
eventDiv.owner = owner;
|
||||
eventDiv.calendar = calendar;
|
||||
$(eventDiv).addClassName("event");
|
||||
$(eventDiv).addClassName("starts" + starts);
|
||||
$(eventDiv).addClassName("lasts" + lasts);
|
||||
|
@ -723,7 +725,7 @@ function newEventDIV(cname, owner, starts, lasts,
|
|||
var innerDiv = document.createElement("div");
|
||||
eventDiv.appendChild(innerDiv);
|
||||
$(innerDiv).addClassName("eventInside");
|
||||
$(innerDiv).addClassName("ownerIs" + owner.cssSafeString());
|
||||
$(innerDiv).addClassName("calendarFolder" + calendar);
|
||||
|
||||
var gradientDiv = document.createElement("div");
|
||||
innerDiv.appendChild(gradientDiv);
|
||||
|
@ -881,7 +883,7 @@ function _loadEventHref(href) {
|
|||
document.eventsListAjaxRequest.aborted = true;
|
||||
document.eventsListAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + href;
|
||||
var url = ApplicationBaseURL + "/" + href;
|
||||
document.eventsListAjaxRequest
|
||||
= triggerAjaxRequest(url, eventsListCallback, href);
|
||||
|
||||
|
@ -897,7 +899,7 @@ function _loadTasksHref(href) {
|
|||
document.tasksListAjaxRequest.aborted = true;
|
||||
document.tasksListAjaxRequest.abort();
|
||||
}
|
||||
url = ApplicationBaseURL + href;
|
||||
url = ApplicationBaseURL + "/" + href;
|
||||
|
||||
var tasksList = $("tasksList");
|
||||
var selectedIds;
|
||||
|
@ -1119,7 +1121,6 @@ function onShowCompletedTasks(event) {
|
|||
|
||||
function updateTaskStatus(event) {
|
||||
var taskId = this.parentNode.getAttribute("id");
|
||||
var taskOwner = this.parentNode.owner;
|
||||
var newStatus = (this.checked ? 1 : 0);
|
||||
var http = createHTTPClient();
|
||||
|
||||
|
@ -1128,9 +1129,8 @@ function updateTaskStatus(event) {
|
|||
//log("update task status: " + taskId + " to " + this.checked);
|
||||
event.cancelBubble = true;
|
||||
|
||||
url = (UserFolderURL + "../" + taskOwner
|
||||
+ "/Calendar/" + taskId
|
||||
+ "/changeStatus?status=" + newStatus);
|
||||
url = (ApplicationBaseURL + "/" + this.parentNode.calendar
|
||||
+ "/" + taskId + "/changeStatus?status=" + newStatus);
|
||||
|
||||
if (http) {
|
||||
// log ("url: " + url);
|
||||
|
@ -1162,10 +1162,11 @@ function updateCalendarStatus(event) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!list.length) {
|
||||
list.push(UserLogin);
|
||||
nodes[0].childNodesWithTag("input")[0].checked = true;
|
||||
}
|
||||
// if (!list.length) {
|
||||
// list.push(UserLogin);
|
||||
// nodes[0].childNodesWithTag("input")[0].checked = true;
|
||||
// }
|
||||
|
||||
// ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
|
||||
// + list.join(",") + "/Calendar/");
|
||||
|
||||
|
@ -1207,7 +1208,7 @@ function calendarStatusCallback(http) {
|
|||
}
|
||||
|
||||
function calendarEntryCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
if (http.readyState == 4) {
|
||||
var denied = !isHttpStatus204(http.status);
|
||||
var entry = $(http.callbackData);
|
||||
if (denied)
|
||||
|
@ -1339,79 +1340,94 @@ function initCalendarSelector() {
|
|||
}
|
||||
|
||||
var links = $("calendarSelectorButtons").childNodesWithTag("a");
|
||||
Event.observe(links[0], "click", onCalendarAdd);
|
||||
Event.observe(links[1], "click", onCalendarRemove);
|
||||
Event.observe(links[0], "click", onCalendarNew);
|
||||
Event.observe(links[1], "click", onCalendarAdd);
|
||||
Event.observe(links[2], "click", onCalendarRemove);
|
||||
}
|
||||
|
||||
function onCalendarNew(event) {
|
||||
createFolder(window.prompt(labels["Name of the Calendar"]),
|
||||
appendCalendar);
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function onCalendarAdd(event) {
|
||||
openUserFolderSelector(onFolderSubscribeCB, "calendar");
|
||||
|
||||
preventDefault(event);
|
||||
openUserFolderSelector(onFolderSubscribeCB, "calendar");
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function appendCalendar(folderName, folder) {
|
||||
var calendarList = $("calendarList");
|
||||
var lis = calendarList.childNodesWithTag("li");
|
||||
var color = indexColor(lis.length);
|
||||
//log ("color: " + color);
|
||||
if (folder)
|
||||
folder = accessToSubscribedFolder(folder);
|
||||
else
|
||||
folder = "/" + folderName;
|
||||
|
||||
var li = document.createElement("li");
|
||||
calendarList.appendChild(li);
|
||||
// log ("append: " + folderName + "; folder: " + folder);
|
||||
|
||||
var checkBox = document.createElement("input");
|
||||
checkBox.setAttribute("type", "checkbox");
|
||||
li.appendChild(checkBox);
|
||||
var calendarList = $("calendarList");
|
||||
var lis = calendarList.childNodesWithTag("li");
|
||||
var color = indexColor(lis.length + 100);
|
||||
//log ("color: " + color);
|
||||
|
||||
var li = document.createElement("li");
|
||||
calendarList.appendChild(li);
|
||||
|
||||
var checkBox = document.createElement("input");
|
||||
checkBox.setAttribute("type", "checkbox");
|
||||
li.appendChild(checkBox);
|
||||
|
||||
li.appendChild(document.createTextNode(" "));
|
||||
li.appendChild(document.createTextNode(" "));
|
||||
|
||||
var colorBox = document.createElement("div");
|
||||
li.appendChild(colorBox);
|
||||
li.appendChild(document.createTextNode(" " + folderName));
|
||||
colorBox.appendChild(document.createTextNode("OO"));
|
||||
var colorBox = document.createElement("div");
|
||||
li.appendChild(colorBox);
|
||||
li.appendChild(document.createTextNode(" " + folderName));
|
||||
colorBox.appendChild(document.createTextNode("OO"));
|
||||
|
||||
li.setAttribute("id", folder);
|
||||
Event.observe(li, "mousedown", listRowMouseDownHandler);
|
||||
Event.observe(li, "click", onRowClick);
|
||||
$(checkBox).addClassName("checkBox");
|
||||
li.setAttribute("id", folder);
|
||||
Event.observe(li, "mousedown", listRowMouseDownHandler);
|
||||
Event.observe(li, "click", onRowClick);
|
||||
$(checkBox).addClassName("checkBox");
|
||||
|
||||
Event.observe(checkBox, "click", updateCalendarStatus.bindAsEventListener(checkBox));
|
||||
Event.observe(checkBox, "click",
|
||||
updateCalendarStatus.bindAsEventListener(checkBox));
|
||||
|
||||
$(colorBox).addClassName("colorBox");
|
||||
if (color) {
|
||||
$(colorBox).setStyle({ color: color,
|
||||
backgroundColor: color });
|
||||
}
|
||||
$(colorBox).addClassName("colorBox");
|
||||
if (color)
|
||||
$(colorBox).setStyle({color: color,
|
||||
backgroundColor: color});
|
||||
|
||||
var contactId = folder.split(":")[0];
|
||||
var url = URLForFolderID(folder) + "/canAccessContent";
|
||||
triggerAjaxRequest(url, calendarEntryCallback, folder);
|
||||
var url = URLForFolderID(folder) + "/canAccessContent";
|
||||
triggerAjaxRequest(url, calendarEntryCallback, folder);
|
||||
|
||||
if (!document.styleSheets) return;
|
||||
var theRules = new Array();
|
||||
var lastSheet = document.styleSheets[document.styleSheets.length - 1];
|
||||
if (lastSheet.insertRule) { // Mozilla
|
||||
lastSheet.insertRule('.ownerIs' + contactId.cssSafeString() + ' {'
|
||||
+ ' background-color: '
|
||||
+ color
|
||||
+ ' !important; }', 0);
|
||||
}
|
||||
else { // IE
|
||||
lastSheet.addRule('.ownerIs' + contactId.cssSafeString(),
|
||||
' background-color: '
|
||||
+ color
|
||||
+ ' !important; }');
|
||||
}
|
||||
if (!document.styleSheets) return;
|
||||
var theRules = new Array();
|
||||
var lastSheet = document.styleSheets[document.styleSheets.length - 1];
|
||||
if (lastSheet.insertRule) { // Mozilla
|
||||
lastSheet.insertRule('.calendarFolder' + folder.substr(1) + ' {'
|
||||
+ ' background-color: '
|
||||
+ color
|
||||
+ ' !important; }', 0);
|
||||
}
|
||||
else { // IE
|
||||
lastSheet.addRule('.calendarFolder' + folder.substr(1),
|
||||
' background-color: '
|
||||
+ color
|
||||
+ ' !important; }');
|
||||
}
|
||||
}
|
||||
|
||||
function onFolderSubscribeCB(folderData) {
|
||||
var folder = $(folderData["folder"]);
|
||||
if (!folder)
|
||||
appendCalendar(folderData["folderName"], folderData["folder"]);
|
||||
appendCalendar(folderData["folderName"], folderData["folder"]);
|
||||
}
|
||||
|
||||
function onFolderUnsubscribeCB(folderId) {
|
||||
var node = $(folderId);
|
||||
node.parentNode.removeChild(node);
|
||||
var node = $(folderId);
|
||||
node.parentNode.removeChild(node);
|
||||
refreshEvents();
|
||||
refreshTasks();
|
||||
changeCalendarDisplay();
|
||||
}
|
||||
|
||||
function onCalendarRemove(event) {
|
||||
|
@ -1419,15 +1435,59 @@ function onCalendarRemove(event) {
|
|||
if (nodes.length > 0) {
|
||||
nodes[0].deselect();
|
||||
var folderId = nodes[0].getAttribute("id");
|
||||
var folderIdElements = folderId.split(":");
|
||||
var folderIdElements = folderId.split("_");
|
||||
if (folderIdElements.length > 1) {
|
||||
unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
|
||||
unsubscribeFromFolder(folderId, onFolderUnsubscribeCB, folderId);
|
||||
}
|
||||
else {
|
||||
var calId = folderIdElements[0].substr(1);
|
||||
deletePersonalCalendar(calId);
|
||||
}
|
||||
}
|
||||
|
||||
preventDefault(event);
|
||||
}
|
||||
|
||||
function deletePersonalCalendar(folderId) {
|
||||
var label
|
||||
= labels["Are you sure you want to delete the selected calendar?"];
|
||||
if (window.confirm(label)) {
|
||||
if (document.deletePersonalCalendarAjaxRequest) {
|
||||
document.deletePersonalCalendarAjaxRequest.aborted = true;
|
||||
document.deletePersonalCalendarAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/" + folderId + "/deleteFolder";
|
||||
document.deletePersonalCalendarAjaxRequest
|
||||
= triggerAjaxRequest(url, deletePersonalCalendarCallback, folderId);
|
||||
}
|
||||
}
|
||||
|
||||
function deletePersonalCalendarCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
if (isHttpStatus204(http.status)) {
|
||||
var ul = $("calendarList");
|
||||
var children = ul.childNodesWithTag("li");
|
||||
var i = 0;
|
||||
var done = false;
|
||||
while (!done && i < children.length) {
|
||||
var currentFolderId = children[i].getAttribute("id").substr(1);
|
||||
if (currentFolderId == http.callbackData) {
|
||||
ul.removeChild(children[i]);
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
refreshEvents();
|
||||
refreshTasks();
|
||||
changeCalendarDisplay();
|
||||
}
|
||||
document.deletePersonalCalendarAjaxRequest = null;
|
||||
}
|
||||
else
|
||||
log ("ajax problem 5: " + http.status);
|
||||
}
|
||||
|
||||
function configureLists() {
|
||||
var list = $("tasksList");
|
||||
list.multiselect = true;
|
||||
|
|
|
@ -88,8 +88,7 @@ function subscribeToFolder(refreshCallback, refreshCallbackData) {
|
|||
refreshCallbackData["folder"]);
|
||||
}
|
||||
else
|
||||
refreshCallbackData["window"].alert(clabels["You cannot subscribe to a folder that you own!"]
|
||||
.decodeEntities());
|
||||
refreshCallbackData["window"].alert(clabels["You cannot subscribe to a folder that you own!"]);
|
||||
}
|
||||
|
||||
function openRightsForUserID(userID) {
|
||||
|
|
|
@ -43,36 +43,36 @@ function validateAptEditor() {
|
|||
|
||||
e = $('summary');
|
||||
if (e.value.length == 0) {
|
||||
if (!confirm(labels.validate_notitle.decodeEntities()))
|
||||
if (!confirm(labels.validate_notitle))
|
||||
return false;
|
||||
}
|
||||
|
||||
e = $('startTime_date');
|
||||
if (e.value.length != 10) {
|
||||
alert(labels.validate_invalid_startdate.decodeEntities());
|
||||
alert(labels.validate_invalid_startdate);
|
||||
return false;
|
||||
}
|
||||
startdate = e.calendar.prs_date(e.value);
|
||||
if (startdate == null) {
|
||||
alert(labels.validate_invalid_startdate.decodeEntities());
|
||||
alert(labels.validate_invalid_startdate);
|
||||
return false;
|
||||
}
|
||||
|
||||
e = $('endTime_date');
|
||||
if (e.value.length != 10) {
|
||||
alert(labels.validate_invalid_enddate.decodeEntities());
|
||||
alert(labels.validate_invalid_enddate);
|
||||
return false;
|
||||
}
|
||||
enddate = e.calendar.prs_date(e.value);
|
||||
if (enddate == null) {
|
||||
alert(labels.validate_invalid_enddate.decodeEntities());
|
||||
alert(labels.validate_invalid_enddate);
|
||||
return false;
|
||||
}
|
||||
// cuicui = '';
|
||||
tmpdate = uixEarlierDate(startdate, enddate);
|
||||
if (tmpdate == enddate) {
|
||||
// window.alert(cuicui);
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
else if (tmpdate == null /* means: same date */) {
|
||||
|
@ -83,14 +83,14 @@ function validateAptEditor() {
|
|||
end = parseInt(document.forms[0]['endTime_time_hour'].value);
|
||||
|
||||
if (start > end) {
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
else if (start == end) {
|
||||
start = parseInt(document.forms[0]['startTime_time_minute'].value);
|
||||
end = parseInt(document.forms[0]['endTime_time_minute'].value);
|
||||
if (start > end) {
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ function onPopupUrlWindow(event) {
|
|||
preventDefault(event);
|
||||
|
||||
var urlInput = document.getElementById("url");
|
||||
var newUrl = window.prompt(labels["Target:"].decodeEntities(), urlInput.value);
|
||||
var newUrl = window.prompt(labels["Target:"], urlInput.value);
|
||||
if (newUrl != null) {
|
||||
var documentHref = $("documentHref");
|
||||
var documentLabel = $("documentLabel");
|
||||
|
|
|
@ -84,13 +84,13 @@ function validateContactEditor() {
|
|||
if (e.value.length == 0)
|
||||
return true;
|
||||
if (uixEmailRegex.test(e.value) != true)
|
||||
return confirm(labels.invalidemailwarn.decodeEntities());
|
||||
return confirm(labels.invalidemailwarn);
|
||||
|
||||
e = $('homeMail');
|
||||
if (e.value.length == 0)
|
||||
return true;
|
||||
if (uixEmailRegex.test(e.value) != true)
|
||||
return confirm(labels.invalidemailwarn.decodeEntities());
|
||||
return confirm(labels.invalidemailwarn);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ function addLineToTree(tree, parent, line) {
|
|||
for (var i = 1; i < nodes.length; i++) {
|
||||
var folderInfos = nodes[i].split(":");
|
||||
var icon = ResourcesURL + '/';
|
||||
if (folderInfos[2] == 'contact')
|
||||
if (folderInfos[2] == 'Contacts')
|
||||
icon += 'tb-mail-addressbook-flat-16x16.png';
|
||||
else
|
||||
icon += 'calendar-folder-16x16.png';
|
||||
|
|
|
@ -133,8 +133,7 @@ function validateEditorInput(sender) {
|
|||
errortext = errortext + labels.error_missingrecipients + "\n";
|
||||
|
||||
if (errortext.length > 0) {
|
||||
alert(labels.error_validationfailed.decodeEntities() + ":\n"
|
||||
+ errortext.decodeEntities());
|
||||
alert(labels.error_validationfailed + ":\n" + errortext);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -24,7 +24,7 @@ function validateDate(date, label) {
|
|||
|
||||
dateValue = date.calendar.prs_date(date.value);
|
||||
if (date.value.length != 10 || !dateValue) {
|
||||
alert(label.decodeEntities());
|
||||
alert(label);
|
||||
result = false;
|
||||
} else
|
||||
result = dateValue;
|
||||
|
@ -37,7 +37,7 @@ function validateTaskEditor() {
|
|||
|
||||
e = document.getElementById('summary');
|
||||
if (e.value.length == 0
|
||||
&& !confirm(labels.validate_notitle.decodeEntities()))
|
||||
&& !confirm(labels.validate_notitle))
|
||||
return false;
|
||||
|
||||
e = document.getElementById('startTime_date');
|
||||
|
@ -58,7 +58,7 @@ function validateTaskEditor() {
|
|||
tmpdate = uixEarlierDate(startdate, enddate);
|
||||
if (tmpdate == enddate) {
|
||||
// window.alert(cuicui);
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
else if (tmpdate == null /* means: same date */) {
|
||||
|
@ -69,14 +69,14 @@ function validateTaskEditor() {
|
|||
end = parseInt(document.forms[0]['dueTime_time_hour'].value);
|
||||
|
||||
if (start > end) {
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
else if (start == end) {
|
||||
start = parseInt(document.forms[0]['startTime_time_minute'].value);
|
||||
end = parseInt(document.forms[0]['dueTime_time_minute'].value);
|
||||
if (start > end) {
|
||||
alert(labels.validate_endbeforestart.decodeEntities());
|
||||
alert(labels.validate_endbeforestart);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
BIN
UI/WebServerResources/add-user-calendar.png
Normal file
BIN
UI/WebServerResources/add-user-calendar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -983,6 +983,7 @@ function subscribeToFolder(refreshCallback, refreshCallbackData) {
|
|||
document.subscriptionAjaxRequest.aborted = true;
|
||||
document.subscriptionAjaxRequest.abort();
|
||||
}
|
||||
|
||||
var rfCbData = { method: refreshCallback, data: refreshCallbackData };
|
||||
document.subscriptionAjaxRequest = triggerAjaxRequest(url,
|
||||
folderSubscriptionCallback,
|
||||
|
@ -1006,29 +1007,42 @@ function folderUnsubscriptionCallback(http) {
|
|||
}
|
||||
|
||||
function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) {
|
||||
if (document.body.hasClassName("popup")) {
|
||||
window.opener.unsubscribeFromFolder(folder, refreshCallback,
|
||||
refreshCallbackData);
|
||||
}
|
||||
else {
|
||||
var folderData = folder.split(":");
|
||||
var username = folderData[0];
|
||||
var folderPath = folderData[1];
|
||||
if (username != UserLogin) {
|
||||
var url = (UserFolderURL + "../" + username
|
||||
+ "/" + folderPath + "/unsubscribe");
|
||||
if (document.unsubscriptionAjaxRequest) {
|
||||
document.unsubscriptionAjaxRequest.aborted = true;
|
||||
document.unsubscriptionAjaxRequest.abort();
|
||||
}
|
||||
var rfCbData = { method: refreshCallback, data: refreshCallbackData };
|
||||
document.unsubscriptionAjaxRequest
|
||||
= triggerAjaxRequest(url, folderUnsubscriptionCallback,
|
||||
rfCbData);
|
||||
if (document.body.hasClassName("popup")) {
|
||||
window.opener.unsubscribeFromFolder(folder, refreshCallback,
|
||||
refreshCallbackData);
|
||||
}
|
||||
else {
|
||||
var folderData = folder.split("+");
|
||||
var username = folderData[0];
|
||||
var folderPath = folderData[1];
|
||||
if (username != UserLogin) {
|
||||
var url = (ApplicationBaseURL + folder + "/unsubscribe");
|
||||
if (document.unsubscriptionAjaxRequest) {
|
||||
document.unsubscriptionAjaxRequest.aborted = true;
|
||||
document.unsubscriptionAjaxRequest.abort();
|
||||
}
|
||||
else
|
||||
window.alert(clabels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
|
||||
}
|
||||
var rfCbData = { method: refreshCallback, data: refreshCallbackData };
|
||||
document.unsubscriptionAjaxRequest
|
||||
= triggerAjaxRequest(url, folderUnsubscriptionCallback,
|
||||
rfCbData);
|
||||
}
|
||||
else
|
||||
window.alert(clabels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
|
||||
}
|
||||
}
|
||||
|
||||
function accessToSubscribedFolder(serverFolder) {
|
||||
var folder;
|
||||
|
||||
var parts = serverFolder.split(":");
|
||||
if (parts.length > 1) {
|
||||
var paths = parts[1].split("/");
|
||||
folder = "/" + parts[0] + "_" + paths[2];
|
||||
}
|
||||
else
|
||||
folder = serverFolder;
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
function listRowMouseDownHandler(event) {
|
||||
|
@ -1289,12 +1303,25 @@ function onLoadHandler(event) {
|
|||
configureDragHandles();
|
||||
configureSortableTableHeaders();
|
||||
configureLinkBanner();
|
||||
translateLabels();
|
||||
var progressImage = $("progressIndicator");
|
||||
if (progressImage)
|
||||
progressImage.parentNode.removeChild(progressImage);
|
||||
Event.observe(document.body, "contextmenu", onBodyClickContextMenu);
|
||||
}
|
||||
|
||||
function translateLabels() {
|
||||
if (typeof labels != "undefined") {
|
||||
for (var key in labels)
|
||||
labels[key] = labels[key].decodeEntities();
|
||||
}
|
||||
|
||||
if (typeof clabels != "undefined") {
|
||||
for (var key in clabels)
|
||||
clabels[key] = clabels[key].decodeEntities();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyClickContextMenu(event) {
|
||||
preventDefault(event);
|
||||
}
|
||||
|
@ -1340,6 +1367,38 @@ function configureLinkBanner() {
|
|||
}
|
||||
}
|
||||
|
||||
/* folder creation */
|
||||
function createFolder(name, okCB, notOkCB) {
|
||||
if (name) {
|
||||
if (document.newFolderAjaxRequest) {
|
||||
document.newFolderAjaxRequest.aborted = true;
|
||||
document.newFolderAjaxRequest.abort();
|
||||
}
|
||||
var url = ApplicationBaseURL + "/createFolder?name=" + name;
|
||||
document.newFolderAjaxRequest
|
||||
= triggerAjaxRequest(url, createFolderCallback,
|
||||
{name: name,
|
||||
okCB: okCB,
|
||||
notOkCB: notOkCB});
|
||||
}
|
||||
}
|
||||
|
||||
function createFolderCallback(http) {
|
||||
if (http.readyState == 4) {
|
||||
var data = http.callbackData;
|
||||
if (http.status == 201) {
|
||||
if (data.okCB)
|
||||
data.okCB(data.name, "/" + http.responseText);
|
||||
}
|
||||
else {
|
||||
if (data.notOkCB)
|
||||
data.notOkCB(name);
|
||||
else
|
||||
log("ajax problem:" + http.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEvent(window, 'load', onLoadHandler);
|
||||
|
||||
function parent$(element) {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.7 KiB |
Loading…
Reference in a new issue