+2007-11-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/SOGo/SOGoParentFolder.m: no longer a subclass of
+ SOGoObject, but of SOGoFolder instead.
+
+ * SoObjects/SOGo/SOGoUserFolder.m: no longer a subclass of
+ SOGoGCSFolder, but of SOGoFolder instead.
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -lookupCalendarFolderForUID:uid]): fixed
+ to take the new SOGoParentFolder class into account. Also, create
+ the personal folder if it doesn't exist.
+
+ * SoObjects/SOGo/SOGoFolder.[hm]: new class module implementing
+ the parent of all SOGo containers.
+
+ * SoObjects/SOGo/SOGoGCSFolder.[hm]: SOGoFolder class renamed to
+ SOGoGCSFolder.
+
2007-11-06 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailerUI/UIxMailToSelection.m ([UIxMailToSelection
create two different vevent-files with the same uid in the store.
*/
-#import "SOGo/SOGoFolder.h"
+#import "SOGo/SOGoGCSFolder.h"
@class NSArray;
@class NSCalendarDate;
@class GCSFolder;
#import <NGCards/iCalEntityObject.h>
-@interface SOGoAppointmentFolder : SOGoFolder
+@interface SOGoAppointmentFolder : SOGoGCSFolder
{
NSTimeZone *timeZone;
NSMutableDictionary *uidToFilename;
#import <SOGo/SOGoUser.h>
#import "SOGoAppointmentObject.h"
+#import "SOGoAppointmentFolders.h"
#import "SOGoTaskObject.h"
#import "SOGoAppointmentFolder.h"
- (SOGoAppointmentFolder *) lookupCalendarFolderForUID: (NSString *) uid
{
- SOGoFolder *upperContainer;
- SOGoUserFolder *userFolder;
- SOGoAppointmentFolder *calendarFolder;
-
- upperContainer = [[self container] container];
- userFolder = [SOGoUserFolder objectWithName: uid
- inContainer: upperContainer];
- calendarFolder = [SOGoAppointmentFolder objectWithName: @"Calendar"
- inContainer: userFolder];
- [calendarFolder
- setOCSPath: [NSString stringWithFormat: @"/Users/%@/Calendar/personal", uid]];
- [calendarFolder setOwner: uid];
-
- return calendarFolder;
+ SOGoFolder *currentContainer;
+ SOGoAppointmentFolders *parent;
+ NSException *error;
+
+ currentContainer = [[container container] container];
+ currentContainer = [currentContainer lookupName: uid
+ inContext: context
+ acquire: NO];
+ parent = [currentContainer lookupName: @"Calendar" inContext: context
+ acquire: NO];
+ currentContainer = [parent lookupName: @"personal" inContext: context
+ acquire: NO];
+ if (!currentContainer)
+ {
+ error = [parent newFolderWithName: [parent defaultFolderName]
+ andNameInContainer: @"personal"];
+ if (!error)
+ currentContainer = [parent lookupName: @"personal"
+ inContext: context
+ acquire: NO];
+ }
+
+ return (SOGoAppointmentFolder *) currentContainer;
}
- (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids
if (![folder isNotNull])
[self logWithFormat:@"Note: did not find folder for uid: '%@'", uid];
}
-
- [folders addObject: folder];
+
+ if (folder)
+ [folders addObject: folder];
}
return folders;
return allErrors;
}
-- (NSException *)deleteInUIDs:(NSArray *)_uids {
+- (NSException *) deleteInUIDs: (NSArray *) _uids
+{
NSEnumerator *e;
id folder;
NSException *allErrors = nil;
+ NSException *error;
+ SOGoAppointmentObject *apt;
e = [[container lookupCalendarFoldersForUIDs:_uids inContext: context]
objectEnumerator];
- while ((folder = [e nextObject])) {
- NSException *error;
- SOGoAppointmentObject *apt;
-
- apt = [folder lookupName:[self nameInContainer] inContext: context
- acquire:NO];
- if ([apt isKindOfClass: [NSException class]]) {
- [self logWithFormat: @"%@", [(NSException *) apt reason]];
- continue;
- }
+ while ((folder = [e nextObject]))
+ {
+ apt = [folder lookupName: [self nameInContainer]
+ inContext: context
+ acquire:NO];
+ if ([apt isKindOfClass: [NSException class]]) {
+ [self logWithFormat: @"%@", [(NSException *) apt reason]];
+ continue;
+ }
- if ((error = [apt primaryDelete]) != nil) {
- [self logWithFormat:@"Note: failed to delete in folder: %@", folder];
- // TODO: make compound
- allErrors = error;
+ if ((error = [apt primaryDelete]) != nil) {
+ [self logWithFormat:@"Note: failed to delete in folder: %@", folder];
+ // TODO: make compound
+ allErrors = error;
+ }
}
- }
+
return allErrors;
}
recipient = email;
language = [[context activeUser] language];
-#warning this could be optimized in a class hierarchy common with the \
- SOGoObject's acl notification mechanism
+#warning this could be optimized in a class hierarchy common with the \
+ SOGoObject acl notification mechanism
/* create page name */
// TODO: select user's default language?
pageName = [NSString stringWithFormat: @"SOGoAptMail%@%@",
#ifndef __Appointments_SOGoFreeBusyObject_H_
#define __Appointments_SOGoFreeBusyObject_H_
-#include <SOGo/SOGoContentObject.h>
+#include <SOGo/SOGoObject.h>
/*
SOGoFreeBusyObject
@class NSArray, NSCalendarDate;
-@interface SOGoFreeBusyObject : SOGoContentObject
+@interface SOGoFreeBusyObject : SOGoObject
{
}
@implementation SOGoFreeBusyObject
-- (NSString *) iCalString
-{
- // for UI-X appointment viewer
- return [self contentAsString];
-}
-
- (NSString *) contentAsString
{
NSCalendarDate *today, *startDate, *endDate;
return infos;
}
+- (NSString *) iCalString
+{
+ // for UI-X appointment viewer
+ return [self contentAsString];
+}
+
/* Private API */
- (iCalFreeBusyType) _fbTypeForEventStatus: (NSNumber *) eventStatus
{
WOResponse *r;
NSData *contentData;
- contentData = [[self contentAsString] dataUsingEncoding: NSUTF8StringEncoding];
+ contentData = [[self contentAsString]
+ dataUsingEncoding: NSUTF8StringEncoding];
r = [(WOContext *) _ctx response];
[r setHeader: @"text/calendar" forKey: @"content-type"];
return @"text/calendar";
}
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
+}
+
@end
superclass = "SOGoParentFolder";
};
SOGoAppointmentFolder = {
- superclass = "SOGoFolder";
+ superclass = "SOGoGCSFolder";
defaultRoles = {
/* "FreeBusyLookup" = ( "Owner", "FreeBusy", "AuthorizedSubscriber" ); */
"ViewWholePublicRecords" = ( "Owner", "PublicResponder", "PublicModifier", "PublicViewer" );
* Boston, MA 02111-1307, USA.
*/
-#import "SOGoContactFolder.h"
-#import "SOGoContactGCSEntry.h"
-
-#import <DOM/DOMProtocols.h>
#import <Foundation/NSArray.h>
-#import <NGExtensions/NSString+misc.h>
-#import <SaxObjC/SaxObjC.h>
-#import <SaxObjC/XMLNamespaces.h>
+
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
+#import <NGExtensions/NSString+misc.h>
+#import <DOM/DOMProtocols.h>
+#import <SaxObjC/SaxObjC.h>
+#import <SaxObjC/XMLNamespaces.h>
+
+#import "SOGoContactFolder.h"
+#import "SOGoContactGCSEntry.h"
@implementation NSObject (CardDAV)
NSDictionary *currentFilter, *contact;
NSEnumerator *contacts;
NSString *baseURL;
- id<SOGoContactFolder> o;
+ SOGoObject <SOGoContactFolder> *o;
o = (id<SOGoContactFolder>)self;
baseURL = [o baseURLInContext: context];
#ifndef __Contacts_SOGoContactGCSFolder_H__
#define __Contacts_SOGoContactGCSFolder_H__
-#import <SoObjects/SOGo/SOGoFolder.h>
+#import <SoObjects/SOGo/SOGoGCSFolder.h>
#import "SOGoContactFolder.h"
#import "NSObject+CardDAV.h"
@class NSArray;
@class NSString;
-@interface SOGoContactGCSFolder : SOGoFolder <SOGoContactFolder>
+@interface SOGoContactGCSFolder : SOGoGCSFolder <SOGoContactFolder>
@end
@class WOContext;
-
-
@implementation SOGoContactLDAPFolder
- (void) appendObject: (NSDictionary *) object
componentClass = [SOGoContactLDIFEntry class];
- component = [componentClass contactEntryWithName: name withLDIFEntry: object inContainer: self];
+ component = [componentClass contactEntryWithName: name
+ withLDIFEntry: object inContainer: self];
[r appendContentString: @" <D:response>\r\n"];
[r appendContentString: @" <D:href>"];
superclass = "SOGoParentFolder";
};
SOGoContactGCSFolder = {
- superclass = "SOGoFolder";
+ superclass = "SOGoGCSFolder";
};
SOGoContactGCSEntry = {
superclass = "SOGoContentObject";
};
SOGoContactLDAPFolder = {
- superclass = "SOGoFolder";
+ superclass = "SOGoGCSFolder";
protectedBy = "Access Contents Information";
defaultRoles = {
"Access Contents Information" = ( "Authenticated" );
s = [self nameInContainer];
r = [s rangeOfString:@"@"];
- if (r.length > 0) {
- login = [s substringToIndex:r.location];
- host = [s substringFromIndex:(r.location + r.length)];
- }
- else {
- login = nil;
- host = s;
- }
+ if (r.length > 0)
+ {
+ login = [s substringToIndex:r.location];
+ host = [s substringFromIndex:(r.location + r.length)];
+ }
+ else
+ {
+ login = nil;
+ host = s;
+ }
r = [host rangeOfString:@"."];
if (r.length > 0)
#ifndef __Mailer_SOGoMailAccounts_H__
#define __Mailer_SOGoMailAccounts_H__
-#import <SOGo/SOGoObject.h>
+#import <SoObjects/SOGo/SOGoFolder.h>
/*
SOGoMailAccounts
@class NSArray;
-@interface SOGoMailAccounts : SOGoObject
+@interface SOGoMailAccounts : SOGoFolder
@end
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
}
-/* WebDAV */
-
-- (BOOL) davIsCollection
-{
- return YES;
-}
-
-- (NSString *) davContentType
-{
- return @"httpd/unix-directory";
-}
-
-/* acls */
-
-- (NSArray *) aclsForUser: (NSString *) uid
-{
- return nil;
-}
-
-
@end /* SOGoMailAccounts */
superclass = "SOGoObject";
};
SOGoMailAccounts = {
- superclass = "SOGoMailBaseObject";
+ superclass = "SOGoFolder";
defaultRoles = {
"View" = ( "Owner", "AuthorizedSubscriber" );
"Access Contents Information" = ( "Owner", "AuthorizedSubscriber" );
SOGoObject.m \
SOGoContentObject.m \
SOGoFolder.m \
+ SOGoGCSFolder.m \
SOGoParentFolder.m \
SOGoUserFolder.m \
SOGoGroupsFolder.m \
#import <NGExtensions/NSObject+Logs.h>
#import <GDLContentStore/GCSFolder.h>
-#import "SOGoFolder.h"
+#import "SOGoGCSFolder.h"
#import "SOGoUser.h"
#import "SOGoPermissions.h"
#import "SOGoContentObject.h"
-/*
- Copyright (C) 2004-2005 SKYRIX Software AG
-
- This file is part of OpenGroupware.org.
-
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-*/
-
-#ifndef __SOGo_SOGoFolder_H__
-#define __SOGo_SOGoFolder_H__
+/* SOGoFolder.h - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef SOGOFOLDER_H
+#define SOGOFOLDER_H
#import "SOGoObject.h"
-@class NSArray;
-@class NSDictionary;
-@class NSMutableDictionary;
-@class NSString;
-
-@class GCSFolder;
-
-/*
- SOGoFolder
-
- A common superclass for folders stored in GCS. Already deals with all GCS
- folder specific things.
-
- Important: folders should NOT retain the context! Otherwise you might get
- cyclic references.
-*/
-
@interface SOGoFolder : SOGoObject
{
NSMutableString *displayName;
- NSString *ocsPath;
- GCSFolder *ocsFolder;
- NSMutableDictionary *aclCache;
}
-+ (id) folderWithSubscriptionReference: (NSString *) reference
- inContainer: (id) aContainer;
-
-/* accessors */
-
- (void) setDisplayName: (NSString *) newDisplayName;
- (NSString *) displayName;
-- (void) setOCSPath: (NSString *)_Path;
-- (NSString *) ocsPath;
-
-- (GCSFolder *) ocsFolderForPath: (NSString *)_path;
-- (GCSFolder *) ocsFolder;
-
-/* lower level fetches */
-- (BOOL) nameExistsInFolder: (NSString *) objectName;
-
-- (void) deleteEntriesWithIds: (NSArray *) ids;
-
-- (NSArray *) fetchContentObjectNames;
-- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects;
-
-/* folder type */
-
-- (NSString *) outlookFolderClass;
-
-- (BOOL) folderIsMandatory;
- (NSString *) folderType;
-/* sorting */
-- (NSComparisonResult) compare: (SOGoFolder *) otherFolder;
-
-- (BOOL) create;
-- (NSException *) delete;
-- (void) renameTo: (NSString *) newName;
/* dav */
- (NSArray *) davNamespaces;
-/* acls as a container */
-- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
-- (NSArray *) aclsForUser: (NSString *) uid
- forObjectAtPath: (NSArray *) objectPathArray;
-- (void) setRoles: (NSArray *) roles
- forUser: (NSString *) uid
- forObjectAtPath: (NSArray *) objectPathArray;
-- (void) removeAclsForUsers: (NSArray *) users
- forObjectAtPath: (NSArray *) objectPathArray;
-
-@end
-
-@interface SOGoFolder (GroupDAVExtensions)
-
-- (NSString *) groupDavResourceType;
+/* outlook */
+- (NSString *) outlookFolderClass;
@end
-#endif /* __SOGo_SOGoFolder_H__ */
+#endif /* SOGOFOLDER_H */
-/*
- Copyright (C) 2004-2005 SKYRIX Software AG
-
- This file is part of OpenGroupware.org.
-
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-*/
+/* SOGoFolder.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
#import <Foundation/NSArray.h>
-#import <Foundation/NSDate.h>
-#import <Foundation/NSDictionary.h>
-#import <Foundation/NSException.h>
-#import <Foundation/NSKeyValueCoding.h>
+#import <Foundation/NSString.h>
#import <Foundation/NSURL.h>
-#import <NGObjWeb/NSException+HTTP.h>
-#import <NGObjWeb/SoObject.h>
-#import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/SoSelectorInvocation.h>
-#import <NGObjWeb/WOContext+SoObjects.h>
-#import <NGObjWeb/WOApplication.h>
-#import <NGExtensions/NSNull+misc.h>
-#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 <UI/SOGoUI/SOGoFolderAdvisory.h>
-#import "NSArray+Utilities.h"
#import "NSString+Utilities.h"
-#import "SOGoContentObject.h"
-#import "SOGoPermissions.h"
-#import "SOGoUser.h"
-
#import "SOGoFolder.h"
-static NSString *defaultUserID = @"<default>";
-
@implementation SOGoFolder
-+ (int) version
-{
- return [super version] + 0 /* v0 */;
-}
-
-+ (void) initialize
-{
- NSAssert2([super version] == 0,
- @"invalid superclass (%@) version %i !",
- NSStringFromClass([self superclass]), [super version]);
-}
-
-+ (id) folderWithSubscriptionReference: (NSString *) reference
- inContainer: (id) aContainer
-{
- id newFolder;
- NSArray *elements, *pathElements;
- NSString *ocsPath, *objectPath, *owner, *ocsName, *folderName;
-
- 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 setOCSPath: ocsPath];
- [newFolder setOwner: owner];
-
- return newFolder;
-}
-
- (id) init
{
if ((self = [super init]))
- {
- displayName = nil;
- ocsPath = nil;
- ocsFolder = nil;
- aclCache = [NSMutableDictionary new];
- }
+ displayName = nil;
return self;
}
- (void) dealloc
{
- [ocsFolder release];
- [ocsPath release];
- [aclCache release];
[displayName release];
[super dealloc];
}
-/* accessors */
-
-- (BOOL) isFolderish
-{
- return YES;
-}
-
-- (void) setOCSPath: (NSString *) _path
-{
- if (![ocsPath isEqualToString:_path])
- {
- if (ocsPath)
- [self warnWithFormat: @"GCS path is already set! '%@'", _path];
- ASSIGN (ocsPath, _path);
- }
-}
-
-- (NSString *) ocsPath
-{
- return ocsPath;
-}
-
-- (GCSFolderManager *) folderManager
-{
- static GCSFolderManager *folderManager = nil;
-
- if (!folderManager)
- folderManager = [GCSFolderManager defaultFolderManager];
-
- return folderManager;
-}
-
-- (GCSFolder *) ocsFolderForPath: (NSString *) _path
-{
- return [[self folderManager] folderAtPath: _path];
-}
-
-- (BOOL) folderIsMandatory
-{
- return [nameInContainer isEqualToString: @"personal"];
-}
-
-- (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"]];
- }
- [displayName retain];
-}
-
-- (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;
- NSString *userLogin;
-
- if (!ocsFolder)
- {
- ocsFolder = [self ocsFolderForPath: [self ocsPath]];
- userLogin = [[context activeUser] login];
- if (!ocsFolder
-/* && [userLogin isEqualToString: [self ownerInContext: context]] */
- && [self folderIsMandatory]
- && [self create])
- ocsFolder = [self ocsFolderForPath: [self ocsPath]];
- [ocsFolder retain];
- }
-
- if ([ocsFolder isNotNull])
- folder = ocsFolder;
- else
- folder = nil;
-
- return folder;
+ return ((displayName) ? displayName : nameInContainer);
}
- (NSString *) folderType
{
- return @"";
-}
-
-- (void) sendFolderAdvisoryTemplate: (NSString *) template
-{
- NSString *pageName;
- SOGoUser *user;
- SOGoFolderAdvisory *page;
-
- user = [context activeUser];
- pageName = [NSString stringWithFormat: @"SOGoFolder%@%@Advisory",
- [user language], template];
-
- page = [[WOApplication application] pageWithName: pageName
- inContext: context];
- [page setFolderObject: self];
- [page setRecipientUID: [user login]];
- [page send];
-}
-
-
-// if (!result) [self sendFolderAdvisoryTemplate: @"Addition"];
-
-- (BOOL) create
-{
- NSException *result;
-
- result = [[self folderManager] createFolderOfType: [self folderType]
- withName: displayName
- atPath: ocsPath];
-
- return (result == nil);
-}
-
-- (NSException *) delete
-{
- NSException *error;
-
- // We just fetch our displayName since our table will use it!
- [self displayName];
-
- if ([nameInContainer isEqualToString: @"personal"])
- error = [NSException exceptionWithHTTPStatus: 403
- reason: @"folder 'personal' cannot be deleted"];
- else
- error = [[self folderManager] deleteFolderAtPath: ocsPath];
-
- return error;
-}
-
-// if (!error) [self sendFolderAdvisoryTemplate: @"Removal"];
-
-- (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;
-
- fields = [NSArray arrayWithObject: @"c_name"];
- records = [[self ocsFolder] fetchFields:fields matchingQualifier:nil];
- if (![records isNotNull])
- {
- [self errorWithFormat: @"(%s): fetch failed!", __PRETTY_FUNCTION__];
- return nil;
- }
- if ([records isKindOfClass: [NSException class]])
- return records;
- return [records objectsForKey: @"c_name"];
-}
-
-- (BOOL) nameExistsInFolder: (NSString *) objectName
-{
- NSArray *fields, *records;
- EOQualifier *qualifier;
-
- qualifier
- = [EOQualifier qualifierWithQualifierFormat:
- [NSString stringWithFormat: @"c_name='%@'", objectName]];
-
- fields = [NSArray arrayWithObject: @"c_name"];
- records = [[self ocsFolder] fetchFields: fields
- matchingQualifier: qualifier];
- return (records
- && ![records isKindOfClass:[NSException class]]
- && [records count] > 0);
-}
-
-- (void) deleteEntriesWithIds: (NSArray *) ids
-{
- unsigned int count, max;
- NSString *currentID;
- SOGoContentObject *deleteObject;
-
- max = [ids count];
- for (count = 0; count < max; count++)
- {
- currentID = [ids objectAtIndex: count];
- deleteObject = [self lookupName: currentID
- inContext: context acquire: NO];
- if (![deleteObject isKindOfClass: [NSException class]])
- [deleteObject delete];
- }
-}
-
-- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects
-{
- NSDictionary *files;
-
- files = [[self ocsFolder] fetchContentsOfAllFiles];
- if (![files isNotNull])
- {
- [self errorWithFormat:@"(%s): fetch failed!", __PRETTY_FUNCTION__];
- return nil;
- }
- if ([files isKindOfClass:[NSException class]])
- return files;
- return files;
-}
-
-/* reflection */
+ [self subclassResponsibility: _cmd];
-- (NSString *) defaultFilenameExtension
-{
- /*
- Override to add an extension to a filename
-
- Note: be careful with that, needs to be consistent with object lookup!
- */
return nil;
}
-- (NSArray *) davResourceType
-{
- NSArray *rType, *groupDavCollection;
-
- if ([self respondsToSelector: @selector (groupDavResourceType)])
- {
- groupDavCollection
- = [NSArray arrayWithObjects: [self groupDavResourceType],
- XMLNS_GROUPDAV, nil];
- rType = [NSArray arrayWithObjects: @"collection", groupDavCollection,
- nil];
- }
- else
- rType = [NSArray arrayWithObject: @"collection"];
-
- return rType;
-}
-
-- (NSString *) davContentType
-{
- return @"httpd/unix-directory";
-}
-
-- (NSArray *) toOneRelationshipKeys
-{
- /* toOneRelationshipKeys are the 'files' contained in a folder */
- NSMutableArray *ma;
- NSArray *names;
- NSString *name, *ext;
- unsigned i, count;
- NSRange r;
-
- names = [self fetchContentObjectNames];
- count = [names count];
- ext = [self defaultFilenameExtension];
- if (count && [ext length] > 0)
- {
- ma = [NSMutableArray arrayWithCapacity: count];
- for (i = 0; i < count; i++)
- {
- name = [names objectAtIndex: i];
- r = [name rangeOfString: @"."];
- if (r.length == 0)
- name = [NSMutableString stringWithFormat: @"%@.%@", name, ext];
- [ma addObject: name];
- }
-
- names = ma;
- }
-
- return names;
-}
-
-/* acls as a container */
-
-- (NSArray *) aclUsersForObjectAtPath: (NSArray *) objectPathArray;
-{
- EOQualifier *qualifier;
- NSString *qs;
- NSArray *records;
-
- qs = [NSString stringWithFormat: @"c_object = '/%@'",
- [objectPathArray componentsJoinedByString: @"/"]];
- qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
- records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
-
- return [records valueForKey: @"c_uid"];
-}
-
-- (NSArray *) _fetchAclsForUser: (NSString *) uid
- forObjectAtPath: (NSString *) objectPath
-{
- EOQualifier *qualifier;
- NSArray *records;
- NSMutableArray *acls;
- NSString *qs;
-
- qs = [NSString stringWithFormat: @"(c_object = '/%@') AND (c_uid = '%@')",
- objectPath, uid];
- qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
- records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
-
- acls = [NSMutableArray array];
- if ([records count] > 0)
- {
- [acls addObject: SOGoRole_AuthorizedSubscriber];
- [acls addObjectsFromArray: [records valueForKey: @"c_role"]];
- }
-
- return acls;
-}
-
-- (void) _cacheRoles: (NSArray *) roles
- forUser: (NSString *) uid
- forObjectAtPath: (NSString *) objectPath
-{
- NSMutableDictionary *aclsForObject;
-
- aclsForObject = [aclCache objectForKey: objectPath];
- if (!aclsForObject)
- {
- aclsForObject = [NSMutableDictionary dictionary];
- [aclCache setObject: aclsForObject
- forKey: objectPath];
- }
- if (roles)
- [aclsForObject setObject: roles forKey: uid];
- else
- [aclsForObject removeObjectForKey: uid];
-}
-
-- (NSArray *) aclsForUser: (NSString *) uid
- forObjectAtPath: (NSArray *) objectPathArray
-{
- NSArray *acls;
- NSString *objectPath;
- NSDictionary *aclsForObject;
-
- objectPath = [objectPathArray componentsJoinedByString: @"/"];
- aclsForObject = [aclCache objectForKey: objectPath];
- if (aclsForObject)
- acls = [aclsForObject objectForKey: uid];
- else
- acls = nil;
- if (!acls)
- {
- acls = [self _fetchAclsForUser: uid forObjectAtPath: objectPath];
- [self _cacheRoles: acls forUser: uid forObjectAtPath: objectPath];
- }
-
- if (!([acls count] || [uid isEqualToString: defaultUserID]))
- acls = [self aclsForUser: defaultUserID
- forObjectAtPath: objectPathArray];
-
- return acls;
-}
-
-- (void) removeAclsForUsers: (NSArray *) users
- forObjectAtPath: (NSArray *) objectPathArray
-{
- EOQualifier *qualifier;
- NSString *uids, *qs, *objectPath;
- NSMutableDictionary *aclsForObject;
-
- if ([users count] > 0)
- {
- objectPath = [objectPathArray componentsJoinedByString: @"/"];
- aclsForObject = [aclCache objectForKey: objectPath];
- if (aclsForObject)
- [aclsForObject removeObjectsForKeys: users];
- uids = [users componentsJoinedByString: @"') OR (c_uid = '"];
- qs = [NSString
- stringWithFormat: @"(c_object = '/%@') AND ((c_uid = '%@'))",
- objectPath, uids];
- qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
- [[self ocsFolder] deleteAclMatchingQualifier: qualifier];
- }
-}
-
-- (void) _commitRoles: (NSArray *) roles
- forUID: (NSString *) uid
- forObject: (NSString *) objectPath
-{
- EOAdaptorChannel *channel;
- GCSFolder *folder;
- NSEnumerator *userRoles;
- NSString *SQL, *currentRole;
-
- folder = [self ocsFolder];
- channel = [folder acquireAclChannel];
- userRoles = [roles objectEnumerator];
- currentRole = [userRoles nextObject];
- while (currentRole)
- {
- SQL = [NSString stringWithFormat: @"INSERT INTO %@"
- @" (c_object, c_uid, c_role)"
- @" VALUES ('/%@', '%@', '%@')",
- [folder aclTableName],
- objectPath, uid, currentRole];
- [channel evaluateExpressionX: SQL];
- currentRole = [userRoles nextObject];
- }
-
- [folder releaseChannel: channel];
-}
-
-- (void) setRoles: (NSArray *) roles
- forUser: (NSString *) uid
- forObjectAtPath: (NSArray *) objectPathArray
-{
- NSString *objectPath;
- NSMutableArray *newRoles;
-
- [self removeAclsForUsers: [NSArray arrayWithObject: uid]
- forObjectAtPath: objectPathArray];
-
- newRoles = [NSMutableArray arrayWithArray: roles];
- [newRoles removeObject: SOGoRole_AuthorizedSubscriber];
- [newRoles removeObject: SOGoRole_None];
- objectPath = [objectPathArray componentsJoinedByString: @"/"];
- [self _cacheRoles: newRoles forUser: uid
- forObjectAtPath: objectPath];
- if (![newRoles count])
- [newRoles addObject: SOGoRole_None];
-
- [self _commitRoles: newRoles forUID: uid forObject: objectPath];
-}
-
-/* acls */
-- (NSArray *) aclUsers
-{
- return [self aclUsersForObjectAtPath: [self pathArrayToSOGoObject]];
-}
-
-- (NSArray *) aclsForUser: (NSString *) uid
-{
- NSMutableArray *acls;
- NSArray *ownAcls, *containerAcls;
-
- acls = [NSMutableArray array];
- ownAcls = [self aclsForUser: uid
- forObjectAtPath: [self pathArrayToSOGoObject]];
- [acls addObjectsFromArray: ownAcls];
- if ([container respondsToSelector: @selector (aclsForUser:)])
- {
- containerAcls = [container aclsForUser: uid];
- if ([containerAcls count] > 0)
- {
- if ([containerAcls containsObject: SOGoRole_ObjectReader])
- [acls addObject: SOGoRole_ObjectViewer];
-#warning this should be checked
- if ([containerAcls containsObject: SOGoRole_ObjectEraser])
- [acls addObject: SOGoRole_ObjectEraser];
- }
- }
-
- return acls;
-}
-
-- (void) setRoles: (NSArray *) roles
- forUser: (NSString *) uid
-{
- return [self setRoles: roles
- forUser: uid
- forObjectAtPath: [self pathArrayToSOGoObject]];
-}
-
-- (void) removeAclsForUsers: (NSArray *) users
-{
- return [self removeAclsForUsers: users
- forObjectAtPath: [self pathArrayToSOGoObject]];
-}
-
-- (NSString *) defaultUserID
-{
- return defaultUserID;
-}
-
-- (NSString *) httpURLForAdvisoryToUser: (NSString *) uid
-{
- return [[self soURL] absoluteString];
-}
-
-- (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid
-{
- return [[self davURL] absoluteString];
-}
-
- (id) lookupName: (NSString *) lookupName
inContext: (id) localContext
acquire: (BOOL) acquire
return obj;
}
-- (NSComparisonResult) _compareByOrigin: (SOGoFolder *) otherFolder
+- (BOOL) isFolderish
{
- NSArray *thisElements, *otherElements;
- unsigned thisCount, otherCount;
- NSComparisonResult comparison;
-
- thisElements = [nameInContainer componentsSeparatedByString: @"_"];
- otherElements = [[otherFolder nameInContainer]
- componentsSeparatedByString: @"_"];
- thisCount = [thisElements count];
- otherCount = [otherElements count];
- if (thisCount == otherCount)
- {
- if (thisCount == 1)
- comparison = NSOrderedSame;
- else
- comparison = [[thisElements objectAtIndex: 0]
- compare: [otherElements objectAtIndex: 0]];
- }
- else
- {
- if (thisCount > otherCount)
- comparison = NSOrderedDescending;
- else
- comparison = NSOrderedAscending;
- }
-
- return comparison;
+ return YES;
}
-- (NSComparisonResult) _compareByNameInContainer: (SOGoFolder *) otherFolder
+- (NSString *) httpURLForAdvisoryToUser: (NSString *) uid
{
- NSString *otherName;
- NSComparisonResult comparison;
-
- otherName = [otherFolder nameInContainer];
- if ([nameInContainer hasSuffix: @"personal"])
- {
- if ([otherName hasSuffix: @"personal"])
- comparison = [nameInContainer compare: otherName];
- else
- comparison = NSOrderedAscending;
- }
- else
- {
- if ([otherName hasSuffix: @"personal"])
- comparison = NSOrderedDescending;
- else
- comparison = NSOrderedSame;
- }
-
- return comparison;
+ return [[self soURL] absoluteString];
}
-- (NSComparisonResult) compare: (SOGoFolder *) otherFolder
+- (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid
{
- NSComparisonResult comparison;
-
- comparison = [self _compareByOrigin: otherFolder];
- if (comparison == NSOrderedSame)
- {
- comparison = [self _compareByNameInContainer: otherFolder];
- if (comparison == NSOrderedSame)
- comparison
- = [[self displayName]
- localizedCaseInsensitiveCompare: [otherFolder displayName]];
- }
-
- return comparison;
+ return [[self davURL] absoluteString];
}
/* WebDAV */
return [self isFolderish];
}
+- (NSString *) davContentType
+{
+ return @"httpd/unix-directory";
+}
+
/* folder type */
- (NSString *) outlookFolderClass
return nil;
}
-/* description */
-
-- (void) appendAttributesToDescription: (NSMutableString *) _ms
-{
- [super appendAttributesToDescription:_ms];
-
- [_ms appendFormat:@" ocs=%@", [self ocsPath]];
-}
+/* acls */
-- (NSString *) loggingPrefix
+- (NSArray *) aclsForUser: (NSString *) uid
{
- return [NSString stringWithFormat:@"<0x%08X[%@]:%@>",
- self, NSStringFromClass([self class]),
- [self nameInContainer]];
+ return nil;
}
-@end /* SOGoFolder */
+@end
return ms;
}
+- (NSString *) loggingPrefix
+{
+ return [NSString stringWithFormat:@"<0x%08X[%@]:%@>",
+ self, NSStringFromClass([self class]),
+ [self nameInContainer]];
+}
+
@end /* SOGoObject */
#ifndef SOGOPARENTFOLDERS_H
#define SOGOPARENTFOLDERS_H
-#import "SOGoObject.h"
+#import "SOGoFolder.h"
@class NSMutableDictionary;
@class NSString;
@class WOResponse;
-@interface SOGoParentFolder : SOGoObject
+@interface SOGoParentFolder : SOGoFolder
{
NSMutableDictionary *subFolders;
NSString *OCSPath;
+ (NSString *) gcsFolderType;
+ (Class) subFolderClass;
+- (NSString *) defaultFolderName;
+
- (void) setBaseOCSPath: (NSString *) newOCSPath;
- (NSArray *) subFolders;
+- (NSException *) newFolderWithName: (NSString *) name
+ andNameInContainer: (NSString *) newNameInContainer;
- (NSException *) newFolderWithName: (NSString *) name
nameInContainer: (NSString **) newNameInContainer;
#import <GDLContentStore/NSURL+GCS.h>
#import <GDLAccess/EOAdaptorChannel.h>
-#import "SOGoFolder.h"
+#import "SOGoGCSFolder.h"
#import "SOGoUser.h"
#import "SOGoParentFolder.h"
{
NSArray *attrs;
NSDictionary *row;
- SOGoFolder *folder;
+ SOGoGCSFolder *folder;
BOOL hasPersonal;
- NSString *key, *path, *personalName;
+ NSString *key;
if (!subFolderClass)
subFolderClass = [[self class] subFolderClass];
row = [fc fetchAttributes: attrs withZone: NULL];
}
- if (!hasPersonal)
- {
- folder = [subFolderClass objectWithName: @"personal" inContainer: self];
- personalName = [self labelForKey: [self defaultFolderName]];
- [folder setDisplayName: personalName];
- path = [NSString stringWithFormat: @"/Users/%@/%@/personal",
- [self ownerInContext: context],
- nameInContainer];
- [folder setOCSPath: path];
- [subFolders setObject: folder forKey: @"personal"];
- }
+// if (!hasPersonal)
+// {
+// folder = [subFolderClass objectWithName: @"personal" inContainer: self];
+// personalName = [self labelForKey: [self defaultFolderName]];
+// [folder setDisplayName: personalName];
+// path = [NSString stringWithFormat: @"/Users/%@/%@/personal",
+// [self ownerInContext: context],
+// nameInContainer];
+// [folder setOCSPath: path];
+// [subFolders setObject: folder forKey: @"personal"];
+// }
}
- (void) appendPersonalSources
NSUserDefaults *settings;
NSEnumerator *allKeys;
NSString *currentKey;
- SOGoFolder *subscribedFolder;
+ SOGoGCSFolder *subscribedFolder;
settings = [[context activeUser] userSettings];
subscribedReferences = [[settings objectForKey: nameInContainer]
}
- (NSException *) newFolderWithName: (NSString *) name
- nameInContainer: (NSString **) newNameInContainer
+ andNameInContainer: (NSString *) newNameInContainer
{
NSString *newFolderID;
- SOGoFolder *newFolder;
+ SOGoGCSFolder *newFolder;
NSException *error;
if (!subFolderClass)
subFolderClass = [[self class] subFolderClass];
- *newNameInContainer = nil;
- newFolderID = [self globallyUniqueObjectId];
newFolder = [subFolderClass objectWithName: newFolderID inContainer: self];
if ([newFolder isKindOfClass: [NSException class]])
error = (NSException *) newFolder;
[newFolder setOCSPath: [NSString stringWithFormat: @"%@/%@",
OCSPath, newFolderID]];
if ([newFolder create])
- {
- error = nil;
- *newNameInContainer = newFolderID;
- }
+ error = nil;
else
error = [NSException exceptionWithHTTPStatus: 400
reason: @"The new folder could not be created"];
return error;
}
+- (NSException *) newFolderWithName: (NSString *) name
+ nameInContainer: (NSString **) newNameInContainer
+{
+ NSString *newFolderID;
+ NSException *error;
+
+ newFolderID = [self globallyUniqueObjectId];
+ error = [self newFolderWithName: name
+ andNameInContainer: newFolderID];
+ if (error)
+ *newNameInContainer = nil;
+ else
+ *newNameInContainer = newFolderID;
+
+ return error;
+}
+
- (void) initSubFolders
{
NSString *login;
sortedArrayUsingSelector: @selector (compare:)];
}
-/* acls */
-- (NSArray *) aclsForUser: (NSString *) uid
-{
- return nil;
-}
-
-- (BOOL) davIsCollection
-{
- return YES;
-}
-
-- (NSString *) davContentType
-{
- return @"httpd/unix-directory";
-}
-
@end
- (NSString *) ownerInContext: (WOContext *) _ctx;
-/* pathes */
-
-- (NSString *) ocsUserPath;
-- (NSString *) ocsPrivateCalendarPath;
-
/* TODO: not implemented, bad bad */
// - (id)lookupFreeBusyObject;
if (!children)
children = [[NSArray alloc] initWithObjects:
- @"Calendar", @"Contacts", @"Mail", nil];
+ @"Calendar", @"Contacts", @"Mail",
+ @"Preferences", nil];
return children;
}
// return [self lookupName: @"Groups" inContext: nil acquire: NO];
// }
-/* pathes */
-
-- (void) setOCSPath: (NSString *) _path
-{
- [self warnWithFormat:
- @"rejected attempt to reset user-folder path: '%@'", _path];
-}
-
-- (NSString *) ocsPath
-{
- return [NSString stringWithFormat: @"/Users/%@", nameInContainer];
-}
-
-- (NSString *) ocsUserPath
-{
- return [self ocsPath];
-}
-
-- (BOOL) folderIsMandatory
-{
- return NO;
-}
-
-- (NSString *) ocsPrivateCalendarPath
-{
- return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
-}
-
-- (NSString *) ocsPrivateContactsPath
-{
- return [[self ocsUserPath] stringByAppendingString:@"/Contacts"];
-}
-
/* name lookup */
// - (NSString *) permissionForKey: (NSString *) key
SOGoAppointmentFolders *calendars;
calendars = [$(@"SOGoAppointmentFolders") objectWithName: _key inContainer: self];
- [calendars setBaseOCSPath: [self ocsPrivateCalendarPath]];
+ [calendars setBaseOCSPath: [NSString stringWithFormat: @"/Users/%@/Calendar",
+ nameInContainer]];
return calendars;
}
SOGoContactFolders *contacts;
contacts = [$(@"SOGoContactFolders") objectWithName:_key inContainer: self];
- [contacts setBaseOCSPath: [self ocsPrivateContactsPath]];
+ [contacts setBaseOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts",
+ nameInContainer]];
return contacts;
}
// obj = [self groupsFolder: _key inContext: _ctx];
else if ([_key isEqualToString: @"Mail"])
obj = [self mailAccountsFolder: _key inContext: _ctx];
+ else if ([_key isEqualToString: @"Preferences"])
+ obj = [$(@"SOGoPreferencesFolder") objectWithName: _key
+ inContainer: self];
else if ([_key isEqualToString: @"freebusy.ifb"])
obj = [self freeBusyObject:_key inContext: _ctx];
else
@class NSMutableDictionary;
@class LDAPUserManager;
-@class SOGoFolder;
+@class SOGoGCSFolder;
@interface UIxFolderActions : WODirectAction
{
- SOGoFolder *clientObject;
+ SOGoGCSFolder *clientObject;
LDAPUserManager *um;
NSUserDefaults *ud;
NSString *owner;
#import <SoObjects/SOGo/LDAPUserManager.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
-#import <SoObjects/SOGo/SOGoUser.h>
-#import <SoObjects/SOGo/SOGoFolder.h>
+#import <SoObjects/SOGo/SOGoGCSFolder.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/SOGoUser.h>
#import "WODirectAction+SOGo.h"
};
};
};
- SOGoFolder = {
+ SOGoGCSFolder = {
methods = {
subscribe = {
protectedBy = "<public>";
Update: remember that there are group folders as well.
*/
NSString *uri, *objectId, *nextMethod;
- id <SOGoContactFolder> co;
+ SOGoObject <SOGoContactFolder> *co;
co = [self clientObject];
if ([co respondsToSelector: @selector (globallyUniqueObjectId)])
{
NSMutableArray *folders;
NSEnumerator *subfolders;
- SOGoFolder *currentFolder;
+ SOGoGCSFolder *currentFolder;
NSString *folderName;
NSMutableDictionary *currentDictionary;
SoSecurityManager *securityManager;
actionName = "delete";
};
edit = {
- protectedBy = "Change Images And Files";
+ protectedBy = "Access Contents Information";
pageName = "UIxContactEditor";
};
save = {
protectedBy = "<public>";
pageName = "UIxContactView";
};
- delete = {
+/* delete = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "delete";
- };
+ }; */
edit = {
- protectedBy = "View";
+ protectedBy = "Access Contents Information";
pageName = "UIxContactEditor";
};
- save = {
+/* save = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "save";
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "write";
- };
+ }; */
};
};
};
};
};
SOGoParentFolder = {
- superclass = "SOGoObject";
+ superclass = "SOGoFolder";
protectedBy = "Access Contents Information";
defaultRoles = {
"Access Contents Information" = ( "Authenticated" );
"General" = "General";
"Calendar Options" = "Calendar Options";
"Mail Options" = "Mail Options";
+"Identities" = "Identities";
"Password" = "Password";
/* ooo */
"messageforward_inline" = "Inline";
"messageforward_attached" = "As Attachment";
+"Default identity:" = "Default identity:";
+"Manage identities..." = "Manage identities...";
+
/* password */
"New password:" = "New password:";
"Confirmation:" = "Confirmation:";
"General" = "Général";
"Calendar Options" = "Calendrier";
"Mail Options" = "Courrier";
+"Identities" = "Identités";
"Password" = "Mot de passe";
/* ooo */
"messageforward_inline" = "intégrés";
"messageforward_attached" = "en pièces jointes";
+/* Identities */
+"Default identity:" = "Identité par défaut :";
+"Manage identities..." = "Gérer les identitiés...";
+
/* password */
"New password:" = "Nouveau mot de passe :";
"Confirmation:" = "Confirmation :";
"General" = "Allgemein";
"Calendar Options" = "Kalender";
"Mail Options" = "E-Mail";
+"Identities" = "Identities";
"Password" = "Passwort";
/* ooo */
"messageforward_inline" = "Eingebunden";
"messageforward_attached" = "Als Anhang";
+"Default identity:" = "Default identity:";
+"Manage identities..." = "Manage identities...";
+
/* password */
"New password:" = "Neues Passwort:";
"Confirmation:" = "Bestätigung:";
@implementation UIxJSONPreferences
-- (WOResponse *) _makeResponse: (NSString *) jsonText
+- (WOResponse *) _makeResponse: (NSUserDefaults *) defaults
{
WOResponse *response;
response = [context response];
[response setHeader: @"text/plain; charset=utf-8"
forKey: @"content-type"];
- [response appendContentString: jsonText];
+ [response appendContentString: [defaults jsonRepresentation]];
return response;
}
defaults = [[context activeUser] userDefaults];
- return [self _makeResponse: [defaults jsonRepresentation]];
+ return [self _makeResponse: defaults];
}
- (WOResponse *) jsonSettingsAction
settings = [[context activeUser] userSettings];
- return [self _makeResponse: [settings jsonRepresentation]];
+ return [self _makeResponse: settings];
}
@end
@interface UIxPreferences : UIxComponent
{
- NSString *item;
+ id item;
SOGoUser *user;
NSUserDefaults *userDefaults;
NSCalendarDate *today;
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WORequest.h>
+#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import "UIxPreferences.h"
[userDefaults setObject: newMessageForwarding forKey: @"MessageForwarding"];
}
+// <label><var:string label:value="Default identity:"/>
+// <var:popup list="identitiesList" item="item"
+// string="itemIdentityText" selection="defaultIdentity"/></label>
+- (NSArray *) identitiesList
+{
+ return [user allIdentities];
+}
+
+- (NSString *) itemIdentityText
+{
+ return [item keysWithFormat: @"%{fullName} <%{email}>"];
+}
+
+- (NSDictionary *) defaultIdentity
+{
+ NSDictionary *currentIdentity, *defaultIdentity;
+ NSEnumerator *identities;
+
+ defaultIdentity = nil;
+
+ identities = [[user allIdentities] objectEnumerator];
+ while (!defaultIdentity
+ && (currentIdentity = [identities nextObject]))
+ if ([[currentIdentity objectForKey: @"isDefault"] boolValue])
+ defaultIdentity = currentIdentity;
+
+ return defaultIdentity;
+}
+
- (id <WOActionResults>) defaultAction
{
id <WOActionResults> results;
protectedBy = "View";
pageName = "UIxPreferences";
};
+ identities = {
+ protectedBy = "View";
+ pageName = "UIxIdentities";
+ };
jsonDefaults = {
protectedBy = "View";
actionClass = "UIxJSONPreferences";
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:label="OGo:label"
>
+ <span id="toolbar">
+ </span>
+
<div class="menu" id="searchMenu">
<ul id="searchOptions" class="choiceMenu">
<li id="name_or_address"><var:string
label:value="Calendar Options"/></li>
<li target="mailOptionsView"><var:string
label:value="Mail Options"/></li>
+<!-- <li target="identitiesView"><var:string
+ label:value="Identities"/></li> -->
<var:if condition="shouldDisplayPasswordChange">
<li target="passwordView"><var:string label:value="Password"/></li>
</var:if>
<textarea const:name="autoReplyText" var:value="autoReplyText"/>
</label> -->
</div>
+ <div id="identitiesView" class="tab">
+ <var:multiselection id="identitiesList" item="item"
+ string="itemIdentityText" selection="defaultIdentity">
+ </var:multiselection>
+ <br/>
+ </div>
<var:if condition="shouldDisplayPasswordChange">
<div id="passwordView" class="tab">
<label><var:string label:value="New password:"
var rows = contactsList.getSelectedRowsId();
var rowsWithEmail = 0;
+ if (rows.length == 0)
+ return false;
+
for (var i = 0; i < rows.length; i++) {
var emailCell = $(rows[i]).down('td', 1);
if (emailCell.firstChild) { // .nodeValue is the contact email address
+ "/" + rows[i] + "/write");
}
}
-
+
if (rowsWithEmail == 0) {
window.alert(labels["The selected contact has no email address."]);
}
if (table) {
// Update table
var thead = table.tHead;
+ var addressHeaderCell = thead.rows[0].cells[3];
var tbody = table.tBodies[0];
var tmp = document.createElement('div');
$(tmp).update(http.responseText);
thead.rows[1].parentNode.replaceChild(tmp.firstChild.tHead.rows[1], thead.rows[1]);
+ addressHeaderCell.replaceChild(tmp.firstChild.tHead.rows[0].cells[3].lastChild,
+ addressHeaderCell.lastChild);
table.replaceChild(tmp.firstChild.tBodies[0], tbody);
}
else {
mailboxTree.pendingRequests = mailAccounts.length;
activeAjaxRequests += mailAccounts.length;
for (var i = 0; i < mailAccounts.length; i++) {
- var url = ApplicationBaseURL + "/" + mailAccounts[i] + "/mailboxes";
+ var url = ApplicationBaseURL + mailAccounts[i] + "/mailboxes";
triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
}
}
list.appendChild(listItem);
Event.observe(listItem, "mousedown", listRowMouseDownHandler);
Event.observe(listItem, "click", onRowClick);
- Event.observe(listItem, "dblclick", editDoubleClickedEvent.bindAsEventListener(listItem));
+ Event.observe(listItem, "dblclick",
+ editDoubleClickedEvent.bindAsEventListener(listItem));
listItem.setAttribute("id", data[i][0]);
$(listItem).addClassName(data[i][5]);
listItem.calendar = data[i][1];
}
}
-function changeCalendarDisplay(time, newView) {
+function changeCalendarDisplay(data, newView) {
var url = ApplicationBaseURL + "/" + ((newView) ? newView : currentView);
selectedCalendarCell = null;
var day = null;
- var hour = null;
- if (time) {
- day = time['day'];
- hour = time['hour'];
+ var scrollEvent = null;
+ if (data) {
+ day = data['day'];
+ scrollEvent = data['scrollEvent'];
}
if (!day)
}
document.dayDisplayAjaxRequest
= triggerAjaxRequest(url, calendarDisplayCallback,
- { "view": newView, "day": day, "hour": hour });
+ { "view": newView,
+ "day": day,
+ "scrollEvent": scrollEvent });
return false;
}
return _ensureView("monthview");
}
-function scrollDayView(hour) {
- var rowNumber;
- if (hour) {
- if (hour.length == 3)
- rowNumber = parseInt(hour.substr(0, 1));
- else {
- if (hour.substr(0, 1) == "0")
- rowNumber = parseInt(hour.substr(1, 1));
- else
- rowNumber = parseInt(hour.substr(0, 2));
- }
- } else
- rowNumber = 8;
-
+function scrollDayView(scrollEvent) {
+ var offset = 0;
var daysView = $("daysView");
var hours =
- $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
- if (hours.length > 0)
- daysView.scrollTop = hours[rowNumber].offsetTop;
+ $(daysView.childNodesWithTag("div")[0]).childNodesWithTag("div");
+
+ if (scrollEvent && scrollEvent.siblings) {
+ var classes = scrollEvent.siblings[0].getAttribute("class").split(" ");
+ for (var i = 0; i < classes.length; i++) {
+ if (classes[i].startsWith("starts")) {
+ var starts = parseInt(classes[i].substr(6)) / 4;
+ offset = hours[starts].offsetTop;
+ }
+ }
+ }
+ else {
+ offset = hours[8].offsetTop;
+ }
+
+ daysView.scrollTop = offset - 5;
}
function onClickableCellsDblClick(event) {
var days = startDate.daysUpTo(endDate);
- var divs = new Array();
-
var title;
if (currentView == "monthview"
&& (eventData[7] == 0))
}
}
if (parentDiv)
- parentDiv.appendChild(eventDiv);
+ parentDiv.appendChild(eventDiv);
}
+
+ var eventTR = $(eventData[0]);
+ if (eventTR)
+ eventTR.siblings = siblings;
}
function newEventDIV(cname, calendar, starts, lasts,
if (http.callbackData["day"])
currentDay = http.callbackData["day"];
- var hour = null;
- if (http.callbackData["hour"])
- hour = http.callbackData["hour"];
var contentView;
if (currentView == "monthview")
contentView = $("calendarContent");
else {
- scrollDayView(hour);
+ var scrollEvent = http.callbackData.scrollEvent;
+ scrollDayView($(scrollEvent));
contentView = $("daysView");
}
refreshCalendarEvents();
var days = document.getElementsByClassName("day", contentView);
if (currentView == "monthview")
for (var i = 0; i < days.length; i++) {
- Event.observe(days[i], "click", onCalendarSelectDay.bindAsEventListener(days[i]));
- Event.observe(days[i], "dblclick", onClickableCellsDblClick.bindAsEventListener(days[i]));
+ Event.observe(days[i], "click",
+ onCalendarSelectDay.bindAsEventListener(days[i]));
+ Event.observe(days[i], "dblclick",
+ onClickableCellsDblClick.bindAsEventListener(days[i]));
}
else {
var headerDivs = $("calendarHeader").childNodesWithTag("div");
return refreshEvents();
}
-function onEventClick(event) { log ("onEventClick");
- var day = this.day;
- var hour = this.hour;
-
- changeCalendarDisplay( { "day": day, "hour": hour} );
- changeDateSelectorDisplay(day);
+function onEventClick(event) {
+ changeCalendarDisplay( { "day": this.day,
+ "scrollEvent": this.getAttribute("id") } );
+ changeDateSelectorDisplay(this.day);
return onRowClick(event);
}
// Update CSS for events color
if (!document.styleSheets) return;
- var theRules = new Array();
- var lastSheet = document.styleSheets[document.styleSheets.length - 1];
- if (lastSheet.insertRule) { // Mozilla
- lastSheet.insertRule('.calendarFolder' + folderPath.substr(1) + ' {'
- + ' background-color: '
- + color
- + ' !important; }', 0);
- lastSheet.insertRule('div.colorBox.calendarFolder' + folderPath.substr(1) + ' {'
- + ' color: '
- + color
- + ' !important; }', 0);
- }
- else { // IE
- lastSheet.addRule('.calendarFolder' + folderPath.substr(1),
- ' background-color: '
- + color
- + ' !important; }');
- lastSheet.addRule('div.colorBox.calendarFolder' + folderPath.substr(1),
- ' color: '
- + color
- + ' !important; }');
- }
+
+ var styleElement = document.createElement("style");
+ styleElement.type = "text/css";
+ var selectors = [
+ '.calendarFolder' + folderPath.substr(1),
+ 'div.colorBox.calendarFolder' + folderPath.substr(1)
+ ];
+ var rules = [
+ ' { background-color: ' + color + ' !important; }',
+ ' { color: ' + color + ' !important; }'
+ ];
+ for (var i = 0; i < rules.length; i++)
+ if (styleElement.styleSheet && styleElement.styleSheet.addRule)
+ styleElement.styleSheet.addRule(selectors[i], rules[i]); // IE
+ else
+ styleElement.appendChild(document.createTextNode(selectors[i] + rules[i])); // Mozilla _+ Safari
+ document.getElementsByTagName("head")[0].appendChild(styleElement);
}
}
margin-top: 1.5em;
margin-right: 1em; }
+SPAN#toolbar IMG#progressIndicator
+{ margin-top: 0.75em; }
+
DIV#pageContent
{ clear: both; }
var url;
if (folderInfos.length > 1) {
url = UserFolderURL + "../" + folderInfos[0];
- if (!folderInfos[1].startsWith('/'))
+ if (!(folderInfos[0].endsWith('/')
+ || folderInfos[1].startsWith('/')))
url += '/';
url += folderInfos[1];
}
var http = createHTTPClient();
activeAjaxRequests += 1;
- document.animTimer = setTimeout("checkAjaxRequestsState();", 200);
+ document.animTimer = setTimeout("checkAjaxRequestsState();", 50);
//url = appendDifferentiator(url);
if (http) {