+2007-03-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Contacts/UIxContactsListViewContainer.m
+ ([UIxContactsListViewContainer -additionalFolders]): take the list
+ of subscribed folders from the new property list used for the user
+ settings. The value of its key is SubscribedFolders for the
+ dictionary entry named "Contacts".
+
+ * UI/Contacts/UIxContactsListView.m ([UIxContactsListView
+ -canAccessContentAction]): new method to override the one from
+ UIxFoldersActions by taking into account the fact that, this time,
+ the clientObject is an ldap folder. Removed many method that used
+ to be related to the handling of the user selector.
+
+ * UI/Scheduler/UIxCalDayView.m: commented out many unused methods
+ to make sure they can be removed.
+
+ * UI/Scheduler/UIxCalView.m ([UIxCalView -_setupCalendarFolders]):
+ populate the calendar entries based on the user settings plist.
+
+ * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+ -selectForMailerAction]): restored method.
+
+ * UI/Scheduler/UIxCalendarSelector.m: new template module derived
+ from a simplified version of the old UIxContactEditor (removed).
+
+ * UI/Contacts/UIxContactsUserFolders.m: new template module for
+ selecting users or user folders through an LDAP search of which
+ the results are displayed as a tree.
+
+ * UI/WebServerResources/UIxMailEditor.js: moved previous generic
+ method "onContactAdd" here since the Mailer is now the only module
+ to use it when composing emails.
+
+ * UI/WebServerResources/generic.js: added code for handling the
+ new scheme used for describing SOGo folders, common code to handle
+ folder addition or removal.
+
+ * UI/Common/UIxFolderActions.m ([UIxFolderActions
+ -activateFolderAction]): new method that change the "active"
+ settings in the folder-related fields in the user settings.
+ ([UIxFolderActions -deactivateFolderAction]): see above.
+
+ * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+ -checkRightsAction]): removed method.
+
+ * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+ -updateAdditionalAddressBooksAction]): removed method.
+
+ * UI/Scheduler/UIxCalMainView.m ([UIxCalMainView
+ -updateCalendarsAction]): removed method.
+
+2007-03-28 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Scheduler/UIxCalMainView.m ([UIxCalMainView
+ -checkRightsAction]): removed method.
+
+ * UI/Common/UIxFolderActions.m ([UIxFolderActions
+ -canAccessContentAction]): new method designed to replace
+ [UIxCalMainView checkRightsAction] in a more universal way.
+
+2007-03-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+ -roleOfUser:uidinContext:context]): take all the subkeys into
+ account, not only the "personal" folder.
+
+ * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+ -takeValuesFromRequest:_rqinContext:_ctx]): append a "uid" field
+ to the new components.
+
+ * SoObjects/SOGo/SOGoUser.m ([SOGoUser -userSettings]): new method
+ (see below).
+
+ * SoObjects/SOGo/AgenorUserManager.m ([AgenorUserManager
+ -getUserDefaultsForUID:uid]): rewrote method to use the "defaults"
+ field of the sogo_user_profile table, where the user-customizable
+ changes will be saved.
+ ([AgenorUserManager -getUserSettingsForUID:uid]): new method
+ similar to the one above, using the "settings" field where the
+ automatic settings will be saved.
+
+ * SoObjects/SOGo/AgenorUserDefaults.m: rewrote a big part of the
+ module to bind the userdefaults to a property list contained in a
+ specified field of the sogo_user_profile table.
+ ([AgenorUserDefaults
+ -initWithTableURL:tableURLuid:userIDfieldName:defaultsFieldName]):
+ added a "fieldName" parameter.
+
+ * UI/Common/UIxFolderActions.m: new module implementing web
+ actions common to all GCS-based folders.
+
+2007-03-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Scheduler/UIxCalDayTable.m ([UIxCalDayTable -labelForDay]):
+ put a carriage return after the day name.
+
+ * UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
+ -readFreeBusyAction]): restored method.
+
2007-03-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MainUI/SOGoUserHomePage.m ([SOGoUserHomePage
if ([traversalPath count] > 2)
{
objectName = [traversalPath objectAtIndex: 2];
- if ([objectName isEqualToString: @"personal"])
- {
- roles = [[context activeUser]
- rolesForObject: [self lookupName: objectName
- inContext: context
- acquire: NO]
- inContext: context];
- if ([roles containsObject: SOGoRole_Assistant]
- || [roles containsObject: SOGoRole_Delegate])
- role = SOGoRole_Assistant;
- }
+ roles = [[context activeUser]
+ rolesForObject: [self lookupName: objectName
+ inContext: context
+ acquire: NO]
+ inContext: context];
+ if ([roles containsObject: SOGoRole_Assistant]
+ || [roles containsObject: SOGoRole_Delegate])
+ role = SOGoRole_Assistant;
}
return role;
superclass = "SOGoObject";
defaultRoles = {
"Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "View" = ( "Owner", "Delegate", "Assistant" );
+ "View" = ( "Owner", "Delegate", "Assistant" );
"WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
"Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
"ReadAcls" = ( "Owner", "Delegate", "Assistant" );
return [self lookupImap4Message:_key inContext:_ctx];
}
- obj = [self lookupImap4Folder:_key inContext:_ctx];
+ obj = [self lookupImap4Folder:_key inContext:_ctx];
if (obj != nil)
return obj;
}
- (NSException *)delete {
- /* Note: overrides SOGoObject -delete */
+ /* Note: overrides SOGoObject -delete */o
return [[self imap4Connection] deleteMailboxAtURL:[self imap4URL]];
}
@class NSString, NSURL, NSUserDefaults, NSArray, NSDictionary, NSData;
@class NSCalendarDate, NSMutableDictionary;
-@interface AgenorUserDefaults : NSObject
+@interface AgenorUserDefaults : NSObject
{
NSUserDefaults *parent;
NSURL *url;
NSString *uid;
+ NSString *fieldName;
- NSArray *fieldNames;
- NSDictionary *attributes;
+ NSArray *fieldNames;
NSMutableDictionary *values;
- NSCalendarDate *lastFetch;
+ NSCalendarDate *lastFetch;
- struct {
- int modified:1;
- int isNew:1;
- int reserved:30;
+ struct
+ {
+ int modified: 1;
+ int isNew: 1;
+ int reserved: 30;
} defFlags;
}
-- (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid;
+- (id) initWithTableURL: (NSURL *) url
+ uid: (NSString *) uid
+ fieldName: (NSString *) fieldName;
/* value access */
-- (void)setObject:(id)_value forKey:(NSString *)_key;
-- (id)objectForKey:(NSString *)_key;
-- (void)removeObjectForKey:(NSString *)_key;
+- (void) setObject: (id) value
+ forKey: (NSString *) key;
+- (id) objectForKey: (NSString *) key;
+- (void) removeObjectForKey: (NSString *) key;
/* typed accessors */
-- (NSArray *)arrayForKey:(NSString *)_key;
-- (NSDictionary *)dictionaryForKey:(NSString *)_key;
-- (NSData *)dataForKey:(NSString *)_key;
-- (NSArray *)stringArrayForKey:(NSString *)_key;
-- (NSString *)stringForKey:(NSString *)_key;
-- (BOOL)boolForKey:(NSString *)_key;
-- (float)floatForKey:(NSString *)_key;
-- (int)integerForKey:(NSString *)_key;
+- (NSArray *) arrayForKey: (NSString *)key;
+- (NSDictionary *) dictionaryForKey: (NSString *)key;
+- (NSData *) dataForKey: (NSString *)key;
+- (NSString *) stringForKey: (NSString *)key;
+- (BOOL) boolForKey: (NSString *) key;
+- (float) floatForKey: (NSString *) key;
+- (int) integerForKey: (NSString *) key;
-- (void)setBool:(BOOL)value forKey:(NSString *)_key;
-- (void)setFloat:(float)value forKey:(NSString *)_key;
-- (void)setInteger:(int)value forKey:(NSString *)_key;
+- (void) setBool: (BOOL) value forKey: (NSString *) key;
+- (void) setFloat: (float) value forKey: (NSString *) key;
+- (void) setInteger: (int) value forKey: (NSString *) key;
/* saving changes */
-- (BOOL)synchronize;
+- (BOOL) synchronize;
@end
-#endif /* __AgenorUserDefaults_H_ */
+#endif /* __AgenorUserDefaults_H__ */
02111-1307, USA.
*/
-#include "AgenorUserDefaults.h"
-#include <GDLContentStore/GCSChannelManager.h>
-#include <GDLContentStore/NSURL+GCS.h>
-#include <GDLAccess/EOAdaptorChannel.h>
-#include <GDLAccess/EOAdaptorContext.h>
-#include <GDLAccess/EOAttribute.h>
-#include "common.h"
+#import <Foundation/NSValue.h>
+#import <GDLContentStore/GCSChannelManager.h>
+#import <GDLContentStore/NSURL+GCS.h>
+#import <GDLAccess/EOAdaptorChannel.h>
+#import <GDLAccess/EOAdaptorContext.h>
+#import <GDLAccess/EOAttribute.h>
+
+#import "common.h"
+#import "AgenorUserDefaults.h"
@implementation AgenorUserDefaults
static NSString *uidColumnName = @"uid";
-- (id)initWithTableURL:(NSURL *)_url uid:(NSString *)_uid {
- if ((self = [super init])) {
- if (_url == nil || [_uid length] < 1) {
- [self errorWithFormat:@"tried to create AgenorUserDefaults w/o args!"];
- [self release];
- return nil;
+- (id) initWithTableURL: (NSURL *) tableURL
+ uid: (NSString *) userID
+ fieldName: (NSString *) defaultsFieldName
+{
+ if ((self = [super init]))
+ {
+ if (tableURL && [userID length] > 0
+ && [defaultsFieldName length] > 0)
+ {
+ parent = [[NSUserDefaults standardUserDefaults] retain];
+ fieldName = [defaultsFieldName copy];
+ url = [tableURL copy];
+ uid = [userID copy];
+ }
+ else
+ {
+ [self errorWithFormat: @"missing arguments"];
+ [self release];
+ self = nil;
+ }
}
- self->parent = [[NSUserDefaults standardUserDefaults] retain];
- self->url = [_url copy];
- self->uid = [_uid copy];
- }
return self;
}
-- (id)init {
- return [self initWithTableURL:nil uid:nil];
+
+- (id) init
+{
+ [self release];
+
+ return nil;
}
-- (void)dealloc {
- [self->attributes release];
- [self->lastFetch release];
- [self->parent release];
- [self->url release];
- [self->uid release];
+- (void) dealloc
+{
+ [values release];
+ [lastFetch release];
+ [parent release];
+ [url release];
+ [uid release];
+ [fieldName release];
[super dealloc];
}
/* accessors */
-- (NSURL *)tableURL {
- return self->url;
-}
-- (NSString *)uid {
- return self->uid;
+- (NSURL *) tableURL
+{
+ return url;
}
-- (NSUserDefaults *)parentDefaults {
- return self->parent;
+- (NSString *) uid
+{
+ return uid;
}
-/* operation */
+- (NSString *) fieldName
+{
+ return fieldName;
+}
-- (void)_loadAttributes:(NSArray *)_attrs {
- NSMutableArray *fields;
- NSMutableDictionary *attrmap;
- unsigned i, count;
-
- fields = [[NSMutableArray alloc] initWithCapacity:16];
- attrmap = [[NSMutableDictionary alloc] initWithCapacity:16];
- for (i = 0, count = [_attrs count]; i < count; i++) {
- EOAttribute *attr;
- NSString *name;
-
- attr = [_attrs objectAtIndex:i];
- name = [attr valueForKey:@"name"];
- [attrmap setObject:attr forKey:name];
-
- if (![name isEqual:uidColumnName])
- [fields addObject:name];
- }
-
- ASSIGNCOPY(self->fieldNames, fields);
- ASSIGNCOPY(self->attributes, attrmap);
- [attrmap release];
- [fields release];
+- (NSUserDefaults *) parentDefaults
+{
+ return parent;
}
-- (BOOL)primaryFetchProfile {
+/* operation */
+
+- (BOOL) primaryFetchProfile
+{
GCSChannelManager *cm;
- EOAdaptorChannel *channel;
- NSDictionary *row;
- NSException *ex;
- NSString *sql;
- NSArray *attrs;
+ EOAdaptorChannel *channel;
+ NSDictionary *row;
+ NSException *ex;
+ NSString *sql;
+ NSArray *attrs;
+ BOOL rc;
+
+ rc = NO;
cm = [GCSChannelManager defaultChannelManager];
- if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
+ channel = [cm acquireOpenChannelForURL: [self tableURL]];
+ if (channel)
+ {
+ /* generate SQL */
+ sql = [NSString stringWithFormat: (@"SELECT %@"
+ @" FROM %@"
+ @" WHERE %@ = '%@'"),
+ fieldName, [[self tableURL] gcsTableName],
+ uidColumnName, [self uid]];
+
+ /* run SQL */
+
+ ex = [channel evaluateExpressionX: sql];
+ if (ex)
+ {
+ [self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
+ values = [NSMutableDictionary new];
+ }
+ else
+ {
+ /* fetch schema */
+ attrs = [channel describeResults: NO /* don't beautify */];
+
+ /* fetch values */
+ row = [channel fetchAttributes: attrs withZone: NULL];
+ defFlags.isNew = (row == nil);
+ [channel cancelFetch];
+
+ /* remember values */
+ [values release];
+ values = [[row objectForKey: fieldName] propertyList];
+ if (values)
+ [values retain];
+ else
+ values = [NSMutableDictionary new];
+
+ ASSIGN(lastFetch, [NSCalendarDate date]);
+ defFlags.modified = NO;
+ rc = YES;
+ }
+
+ [cm releaseChannel:channel];
+ }
+ else
[self errorWithFormat:@"failed to acquire channel for URL: %@",
[self tableURL]];
- return NO;
- }
-
- /* generate SQL */
-
- sql = [[self tableURL] gcsTableName];
- sql = [@"SELECT * FROM " stringByAppendingString:sql];
- sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
- uidColumnName, [self uid]];
-
- /* run SQL */
-
- if ((ex = [channel evaluateExpressionX:sql]) != nil) {
- [self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
- [cm releaseChannel:channel];
- return NO;
- }
- /* fetch schema */
-
- attrs = [channel describeResults:NO /* don't beautify */];
- [self _loadAttributes:attrs];
-
- /* fetch values */
-
- row = [channel fetchAttributes:attrs withZone:NULL];
- self->defFlags.isNew = (row != nil) ? 0 : 1;
- [channel cancelFetch];
-
- /* remember values */
-
- [self->values release]; self->values = nil;
- self->values = (row != nil)
- ? [row mutableCopy]
- : [[NSMutableDictionary alloc] initWithCapacity:8];
- [self->values removeObjectForKey:uidColumnName];
-
- ASSIGN(self->lastFetch, [NSCalendarDate date]);
- self->defFlags.modified = 0;
-
- [cm releaseChannel:channel];
- return YES;
-}
-
-- (NSString *)formatValue:(id)_value forAttribute:(EOAttribute *)_attribute {
- NSString *s;
-
- if (![_value isNotNull])
- return @"NULL";
-
- if ([[_attribute externalType] hasPrefix:@"int"])
- return [_value stringValue];
-
- s = [_value stringValue];
- s = [s stringByReplacingString:@"'" withString:@"''"];
- s = [[@"'" stringByAppendingString:s] stringByAppendingString:@"'"];
- return s;
+ return rc;
}
-- (NSString *)generateSQLForInsert {
+- (NSString *) generateSQLForInsert
+{
NSMutableString *sql;
- unsigned i, count;
-
- if ([self->values count] == 0)
- return nil;
-
- sql = [NSMutableString stringWithCapacity:2048];
-
- [sql appendString:@"INSERT INTO "];
- [sql appendString:[[self tableURL] gcsTableName]];
- [sql appendString:@" ( uid"];
-
- for (i = 0, count = [self->fieldNames count]; i < count; i++) {
- EOAttribute *attr;
-
- attr = [self->attributes objectForKey:[self->fieldNames objectAtIndex:i]];
- [sql appendString:@", "];
- [sql appendString:[attr columnName]];
- }
-
- [sql appendString:@") VALUES ("];
-
- [sql appendString:@"'"];
- [sql appendString:[self uid]]; // TODO: escaping necessary?
- [sql appendString:@"'"];
-
- for (i = 0, count = [self->fieldNames count]; i < count; i++) {
- EOAttribute *attr;
- id value;
-
- attr = [self->attributes objectForKey:[self->fieldNames objectAtIndex:i]];
- value = [self->values objectForKey:[self->fieldNames objectAtIndex:i]];
-
- [sql appendString:@", "];
- [sql appendString:[self formatValue:value forAttribute:attr]];
- }
-
- [sql appendString:@")"];
+ NSString *serializedDefaults;
+
+#if LIB_FOUNDATION_LIBRARY
+ serializedDefaults = [values stringRepresentation];
+
+ sql = [NSString stringWithFormat: (@"INSERT INTO %@"
+ @" (%@, %@)"
+ @" VALUES ('%@', '%@')"),
+ [[self tableURL] gcsTableName], uidColumnName, fieldName,
+ [self uid],
+ [serializedDefaults stringByReplacingString:@"'" withString:@"''"]];
+#else
+ NSData *serializedDefaultsData;
+ NSString *error;
+
+ serializedDefaultsData
+ = [NSPropertyListSerialization dataFromPropertyList: values
+ format: NSPropertyListOpenStepFormat
+ errorDescription: &error];
+
+ if (error)
+ sql = nil;
+ else
+ {
+ serializedDefaults = [[NSString alloc] initWithData: serializedDefaultsData
+ encoding: NSUTF8StringEncoding];
+
+ sql = [NSString stringWithFormat: (@"INSERT INTO %@"
+ @" (%@, %@)"
+ @" VALUES ('%@', '%@')"),
+ [[self tableURL] gcsTableName], uidColumnName, fieldName,
+ [self uid],
+ [serializedDefaults stringByReplacingString:@"'" withString:@"''"]];
+ [serializedDefaults release];
+ }
+#endif
+
return sql;
}
-- (NSString *)generateSQLForUpdate {
+- (NSString *) generateSQLForUpdate
+{
NSMutableString *sql;
- unsigned i, count;
-
- if ([self->values count] == 0)
- return nil;
-
- sql = [NSMutableString stringWithCapacity:2048];
-
- [sql appendString:@"UPDATE "];
- [sql appendString:[[self tableURL] gcsTableName]];
- [sql appendString:@" SET "];
-
- for (i = 0, count = [self->fieldNames count]; i < count; i++) {
- EOAttribute *attr;
- NSString *name;
- id value;
-
- name = [self->fieldNames objectAtIndex:i];
- value = [self->values objectForKey:name];
- attr = [self->attributes objectForKey:name];
-
- if (i != 0) [sql appendString:@", "];
- [sql appendString:[attr columnName]];
- [sql appendString:@" = "];
- [sql appendString:[self formatValue:value forAttribute:attr]];
- }
-
- [sql appendString:@" WHERE "];
- [sql appendString:uidColumnName];
- [sql appendString:@" = '"];
- [sql appendString:[self uid]];
- [sql appendString:@"'"];
+ NSString *serializedDefaults;
+
+#if LIB_FOUNDATION_LIBRARY
+ serializedDefaults = [values stringRepresentation];
+
+ sql = [NSString stringWithFormat: (@"UPDATE %@"
+ @" SET %@ = '%@'"
+ @" WHERE %@ = '%@'"),
+ [[self tableURL] gcsTableName],
+ fieldName,
+ [serializedDefaults stringByReplacingString:@"'" withString:@"''"],
+ uidColumnName, [self uid]];
+#else
+ NSData *serializedDefaultsData;
+ NSString *error;
+
+ serializedDefaultsData
+ = [NSPropertyListSerialization dataFromPropertyList: values
+ format: NSPropertyListOpenStepFormat
+ errorDescription: &error];
+ error = nil;
+ if (error)
+ {
+ sql = nil;
+ [error release];
+ }
+ else
+ {
+ serializedDefaults = [[NSString alloc] initWithData: serializedDefaultsData
+ encoding: NSUTF8StringEncoding];
+
+ sql = [NSString stringWithFormat: (@"UPDATE %@"
+ @" SET %@ = '%@'"
+ @" WHERE %@ = '%@'"),
+ [[self tableURL] gcsTableName],
+ fieldName,
+ [serializedDefaults stringByReplacingString:@"'" withString:@"''"],
+ uidColumnName, [self uid]];
+ [serializedDefaults release];
+ }
+#endif
+
return sql;
}
-- (BOOL)primaryStoreProfile {
+- (BOOL) primaryStoreProfile
+{
GCSChannelManager *cm;
- EOAdaptorChannel *channel;
- NSException *ex;
- NSString *sql;
+ EOAdaptorChannel *channel;
+ NSException *ex;
+ NSString *sql;
+ BOOL rc;
+
+ rc = NO;
cm = [GCSChannelManager defaultChannelManager];
- if ((channel = [cm acquireOpenChannelForURL:[self tableURL]]) == nil) {
- [self errorWithFormat:@"failed to acquire channel for URL: %@",
- [self tableURL]];
- return NO;
- }
-
- /* run SQL */
-
- sql = self->defFlags.isNew
- ? [self generateSQLForInsert]
- : [self generateSQLForUpdate];
- if ((ex = [channel evaluateExpressionX:sql]) != nil) {
- [self errorWithFormat:@"could not run SQL '%@': %@", sql, ex];
- [cm releaseChannel:channel];
- return NO;
- }
-
- /* commit */
-
- ex = nil;
- if ([[channel adaptorContext] hasOpenTransaction])
- ex = [channel evaluateExpressionX:@"COMMIT TRANSACTION"];
-
- [cm releaseChannel:channel];
-
- if (ex != nil) {
- [self errorWithFormat:@"could not commit transaction for update: %@", ex];
- return NO;
- }
-
- self->defFlags.modified = 0;
- self->defFlags.isNew = 0;
- return YES;
-}
-
+ sql = ((defFlags.isNew)
+ ? [self generateSQLForInsert]
+ : [self generateSQLForUpdate]);
+ if (sql)
+ {
+ channel = [cm acquireOpenChannelForURL: [self tableURL]];
+ if (channel)
+ {
+ ex = [channel evaluateExpressionX:sql];
+ if (ex)
+ [self errorWithFormat: @"could not run SQL '%@': %@", sql, ex];
+ else
+ {
+ if ([[channel adaptorContext] hasOpenTransaction])
+ {
+ ex = [channel evaluateExpressionX: @"COMMIT TRANSACTION"];
+ if (ex)
+ [self errorWithFormat:@"could not commit transaction for update: %@", ex];
+ else
+ rc = YES;
+ }
+ else
+ rc = YES;
+
+ defFlags.modified = NO;
+ defFlags.isNew = NO;
+ }
+
+ [cm releaseChannel: channel];
+ }
+ else
+ [self errorWithFormat: @"failed to acquire channel for URL: %@",
+ [self tableURL]];
+ }
+ else
+ [self errorWithFormat: @"failed to generate SQL for storing defaults"];
-- (BOOL)fetchProfile {
- if (self->values != nil)
- return YES;
-
- return [self primaryFetchProfile];
+ return rc;
}
-- (NSArray *)primaryDefaultNames {
- if (![self fetchProfile])
- return nil;
-
- return self->fieldNames;
+- (BOOL) fetchProfile
+{
+ return (values || [self primaryFetchProfile]);
}
/* value access */
-- (void)setObject:(id)_value forKey:(NSString *)_key {
- if (![self fetchProfile])
- return;
+- (void) setObject: (id) value
+ forKey: (NSString *) key
+{
+ id old;
- if (![self->fieldNames containsObject:_key]) {
- [self errorWithFormat:@"tried to write key: '%@'", _key];
+ if (![self fetchProfile])
return;
- }
-
- /* check whether the value is actually modified */
- if (!self->defFlags.modified) {
- id old;
- old = [self->values objectForKey:_key];
- if (old == _value || [old isEqual:_value]) /* value didn't change */
- return;
-
- /* we need to this because our typed accessors convert to strings */
- // TODO: especially problematic with bools
- if ([_value isKindOfClass:[NSString class]]) {
- if (![old isKindOfClass:[NSString class]])
- if ([[old description] isEqualToString:_value])
- return;
+ /* check whether the value is actually modified */
+ if (!defFlags.modified)
+ {
+ old = [values objectForKey: key];
+ if (old == value || [old isEqual: value]) /* value didn't change */
+ return;
+
+ /* we need to this because our typed accessors convert to strings */
+ // TODO: especially problematic with bools
+ if ([value isKindOfClass: [NSString class]]) {
+ if (![old isKindOfClass: [NSString class]])
+ if ([[old description] isEqualToString: value])
+ return;
+ }
}
- }
-
+
/* set in hash and mark as modified */
- [self->values setObject:(_value ? _value : [NSNull null]) forKey:_key];
- self->defFlags.modified = 1;
+ [values setObject: value forKey: key];
+
+ defFlags.modified = YES;
}
-- (id)objectForKey:(NSString *)_key {
+- (id) objectForKey: (NSString *) key
+{
id value;
if (![self fetchProfile])
- return nil;
-
- if (![self->fieldNames containsObject:_key])
- return [self->parent objectForKey:_key];
-
- value = [self->values objectForKey:_key];
- return [value isNotNull] ? value : nil;
+ value = nil;
+ else
+ value = [values objectForKey: key];
+
+ return value;
}
-- (void)removeObjectForKey:(NSString *)_key {
- [self setObject:nil forKey:_key];
+- (void) removeObjectForKey: (NSString *) key
+{
+ [self setObject: nil forKey: key];
}
/* saving changes */
-- (BOOL)synchronize {
- if (!self->defFlags.modified) /* was not modified */
- return YES;
+- (BOOL) synchronize
+{
+// if (!defFlags.modified) /* was not modified */
+// return YES;
/* ensure fetched data (more or less guaranteed by modified!=0) */
if (![self fetchProfile])
return NO;
/* store */
- if (![self primaryStoreProfile]) {
- [self primaryFetchProfile];
- return NO;
- }
-
+ if (![self primaryStoreProfile])
+ {
+ [self primaryFetchProfile];
+ return NO;
+ }
+
/* refetch */
return [self primaryFetchProfile];
}
-- (void)flush {
- [self->values release]; self->values = nil;
- [self->fieldNames release]; self->fieldNames = nil;
- [self->attributes release]; self->attributes = nil;
- [self->lastFetch release]; self->lastFetch = nil;
- self->defFlags.modified = 0;
- self->defFlags.isNew = 0;
+- (void) flush
+{
+ [values release];
+ [lastFetch release];
+ values = nil;
+ lastFetch = nil;
+ defFlags.modified = NO;
+ defFlags.isNew = NO;
}
/* typed accessors */
-- (NSArray *)arrayForKey:(NSString *)_key {
- id obj = [self objectForKey:_key];
- return [obj isKindOfClass:[NSArray class]] ? obj : nil;
+- (NSArray *) arrayForKey: (NSString *) key
+{
+ return [self objectForKey: key];
}
-- (NSDictionary *)dictionaryForKey:(NSString *)_key {
- id obj = [self objectForKey:_key];
- return [obj isKindOfClass:[NSDictionary class]] ? obj : nil;
+- (NSDictionary *) dictionaryForKey: (NSString *) key
+{
+ return [self objectForKey: key];
}
-- (NSData *)dataForKey:(NSString *)_key {
- id obj = [self objectForKey:_key];
- return [obj isKindOfClass:[NSData class]] ? obj : nil;
+- (NSData *) dataForKey: (NSString *) key
+{
+ return [self objectForKey: key];
}
-- (NSArray *)stringArrayForKey:(NSString *)_key {
- id obj = [self objectForKey:_key];
- int n;
- Class strClass = [NSString class];
-
- if (![obj isKindOfClass:[NSArray class]])
- return nil;
-
- for (n = [obj count]-1; n >= 0; n--) {
- if (![[obj objectAtIndex:n] isKindOfClass:strClass])
- return nil;
- }
- return obj;
+- (NSString *) stringForKey: (NSString *) key
+{
+ return [self objectForKey: key];
}
-- (NSString *)stringForKey:(NSString *)_key {
- id obj = [self objectForKey:_key];
- return [obj isKindOfClass:[NSString class]] ? obj : nil;
+- (BOOL) boolForKey: (NSString *) key
+{
+ return [[self objectForKey: key] boolValue];
}
-- (BOOL)boolForKey:(NSString *)_key {
- // TODO: need special support here for int-DB fields
- id obj;
-
- if ((obj = [self objectForKey:_key]) == nil)
- return NO;
- if ([obj isKindOfClass:[NSString class]]) {
- if ([obj compare:@"YES" options:NSCaseInsensitiveSearch] == NSOrderedSame)
- return YES;
- }
- if ([obj respondsToSelector:@selector(intValue)])
- return [obj intValue] ? YES : NO;
- return NO;
+- (float) floatForKey: (NSString *) key
+{
+ return [[self objectForKey: key] floatValue];
}
-- (float)floatForKey:(NSString *)_key {
- id obj = [self stringForKey:_key];
- return (obj != nil) ? [obj floatValue] : 0.0;
-}
-- (int)integerForKey:(NSString *)_key {
- id obj = [self stringForKey:_key];
- return (obj != nil) ? [obj intValue] : 0;
+- (int) integerForKey: (NSString *) key
+{
+ return [[self objectForKey: key] intValue];
}
-- (void)setBool:(BOOL)value forKey:(NSString *)_key {
+- (void) setBool: (BOOL) value
+ forKey: (NSString *) key
+{
// TODO: need special support here for int-DB fields
- [self setObject:(value ? @"YES" : @"NO") forKey:_key];
-}
-- (void)setFloat:(float)value forKey:(NSString *)_key {
- [self setObject:[NSString stringWithFormat:@"%f", value] forKey:_key];
-}
-- (void)setInteger:(int)value forKey:(NSString *)_key {
- [self setObject:[NSString stringWithFormat:@"%d", value] forKey:_key];
+ [self setObject: [NSNumber numberWithBool: value]
+ forKey: key];
}
-/* description */
+- (void) setFloat: (float) value
+ forKey: (NSString *) key
+{
+ [self setObject: [NSNumber numberWithFloat: value]
+ forKey: key];
+}
-- (NSString *)description {
- NSMutableString *ms;
-
- ms = [NSMutableString stringWithCapacity:16];
- [ms appendFormat:@"<0x%08X[%@]>", self, NSStringFromClass([self class])];
- [ms appendFormat:@" uid=%@", self->uid];
- [ms appendFormat:@" url=%@", [self->url absoluteString]];
- [ms appendFormat:@" parent=0x%08X", self->parent];
- [ms appendString:@">"];
- return ms;
+- (void) setInteger: (int) value
+ forKey: (NSString *) key
+{
+ [self setObject: [NSNumber numberWithInt: value]
+ forKey: key];
}
@end /* AgenorUserDefaults */
- (NSURL *)getFreeBusyURLForUID:(NSString *)_uid;
-- (NSUserDefaults *)getUserDefaultsForUID:(NSString *)_uid;
+- (NSUserDefaults *) getUserDefaultsForUID: (NSString *) uid;
+- (NSUserDefaults *) getUserSettingsForUID: (NSString *) uid;
- (BOOL)isUserAllowedToChangeSOGoInternetAccess:(NSString *)_uid;
/* defaults */
-- (NSUserDefaults *)getUserDefaultsForUID:(NSString *)_uid {
+- (NSUserDefaults *) _getUserDefaultsForUID: (NSString *) uid
+ fieldName: (NSString *) fieldName
+{
id defaults;
- if (AgenorProfileURL == nil) {
- [self warnWithFormat:
- @"no profile configured, cannot retrieve defaults for user: '%@'",
- _uid];
- return nil;
- }
-
- /* Note: do not cache, otherwise updates can be quite tricky */
- defaults = [[[AgenorUserDefaults alloc]
- initWithTableURL:AgenorProfileURL uid:_uid] autorelease];
+ if (AgenorProfileURL)
+ {
+ /* Note: do not cache, otherwise updates can be quite tricky */
+ defaults = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
+ uid: uid fieldName: fieldName];
+ [defaults autorelease];
+ }
+ else
+ {
+ [self warnWithFormat:
+ @"no profile configured, cannot retrieve defaults for user: '%@'",
+ uid];
+ return defaults = nil;
+ }
+
return defaults;
}
+- (NSUserDefaults *) getUserDefaultsForUID: (NSString *) uid
+{
+ return [self _getUserDefaultsForUID: uid fieldName: @"defaults"];
+}
+
+- (NSUserDefaults *) getUserSettingsForUID: (NSString *) uid
+{
+ return [self _getUserDefaultsForUID: uid fieldName: @"settings"];
+}
+
/* internet access lock */
- (BOOL)isUserAllowedToChangeSOGoInternetAccess:(NSString *)_uid {
return debugOn;
}
-/* description */
-
-- (NSString *)description {
- NSMutableString *ms;
-
- ms = [NSMutableString stringWithCapacity:16];
- [ms appendFormat:@"<0x%08X[%@]", self, NSStringFromClass([self class])];
- [ms appendString:@">"];
- return ms;
-}
-
@end /* AgenorUserManager */
GCSFolder *ocsFolder;
}
-+ (NSString *)globallyUniqueObjectId;
++ (NSString *) globallyUniqueObjectId;
/* accessors */
-- (void)setOCSPath:(NSString *)_Path;
-- (NSString *)ocsPath;
+- (void) setOCSPath: (NSString *)_Path;
+- (NSString *) ocsPath;
-- (GCSFolder *)ocsFolderForPath:(NSString *)_path;
-- (GCSFolder *)ocsFolder;
+- (GCSFolder *) ocsFolderForPath: (NSString *)_path;
+- (GCSFolder *) ocsFolder;
/* lower level fetches */
- (BOOL) nameExistsInFolder: (NSString *) objectName;
-- (NSArray *)fetchContentObjectNames;
-- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
+- (NSArray *) fetchContentObjectNames;
+- (NSDictionary *) fetchContentStringsAndNamesOfAllObjects;
/* folder type */
-- (NSString *)outlookFolderClass;
+- (NSString *) outlookFolderClass;
- (BOOL) create;
- (NSException *) delete;
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container;
-- (id)initWithName:(NSString *)_name inContainer:(id)_container;
+- (id) initWithName: (NSString *) _name inContainer:(id)_container;
/* accessors */
-- (NSString *)nameInContainer;
-- (id)container;
+- (NSString *) nameInContainer;
+- (id) container;
- (NSTimeZone *) serverTimeZone;
- (NSTimeZone *) userTimeZone;
/* ownership */
- (void) setOwner: (NSString *) newOwner;
-- (NSString *)ownerInContext:(id)_ctx;
+- (NSString *) ownerInContext: (id) _ctx;
/* looking up shared objects */
-- (SOGoUserFolder *)lookupUserFolder;
-- (SOGoGroupsFolder *)lookupGroupsFolder;
+- (SOGoUserFolder *) lookupUserFolder;
+- (SOGoGroupsFolder *) lookupGroupsFolder;
-- (void)sleep;
+- (void) sleep;
/* hierarchy */
-- (NSArray *)fetchSubfolders; /* uses toManyRelationshipKeys */
+- (NSArray *) fetchSubfolders; /* uses toManyRelationshipKeys */
/* operations */
NSString *cn;
NSString *email;
NSUserDefaults *userDefaults;
+ NSUserDefaults *userSettings;
}
/* properties */
/* defaults */
-- (NSUserDefaults *)userDefaults;
+- (NSUserDefaults *) userDefaults;
+- (NSUserDefaults *) userSettings;
/* folders */
@implementation SOGoUser
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ userDefaults = nil;
+ userSettings = nil;
+ }
+
+ return self;
+}
+
- (void)dealloc {
[self->userDefaults release];
+ [self->userSettings release];
[self->cn release];
[self->email release];
[super dealloc];
/* defaults */
-- (NSUserDefaults *)userDefaults {
- if (self->userDefaults == nil) {
- self->userDefaults =
- [[[self userManager] getUserDefaultsForUID:[self login]] retain];
- }
- return self->userDefaults;
+- (NSUserDefaults *) userDefaults
+{
+ if (!userDefaults)
+ {
+ userDefaults = [[self userManager] getUserDefaultsForUID: [self login]];
+ [userDefaults retain];
+ }
+
+ return userDefaults;
+}
+
+- (NSUserDefaults *) userSettings
+{
+ if (!userSettings)
+ {
+ userSettings = [[self userManager] getUserSettingsForUID: [self login]];
+ [userSettings retain];
+ }
+
+ return userSettings;
}
/* folders */
UIxPrintPageFrame.m \
UIxSortButton.m \
UIxAppNavView.m \
- UIxJSClose.m \
\
UIxAclEditor.m \
+ UIxFolderActions.m \
UIxElemBuilder.m \
UIxTabView.m \
UIxTabItem.m \
NSMutableArray *users;
NSMutableArray *assistants;
NSMutableArray *delegates;
- NSString *ownerCN;
+ NSString *currentUser;
+ NSString *ownerLogin;
}
- (NSArray *) aclsForFolder;
-- (NSString *) ownerCN;
- (NSString *) assistantsValue;
- (NSString *) delegatesValue;
+- (NSArray *) usersForFolder;
+- (void) setCurrentUser: (NSString *) newCurrentUser;
+- (NSString *) currentUser;
+
+- (NSString *) ownerLogin;
+- (NSString *) ownerName;
+
@end
#endif /* UIXACLEDITOR_H */
users = [NSMutableArray new];
delegates = [NSMutableArray new];
assistants = [NSMutableArray new];
- ownerCN = nil;
+ ownerLogin = nil;
+ currentUser = nil;
}
return self;
[users release];
[delegates release];
[assistants release];
- if (ownerCN)
- [ownerCN release];
+ [ownerLogin release];
+ [currentUser release];
[super dealloc];
}
return acls;
}
-- (NSString *) ownerCN
+- (NSString *) ownerLogin
{
- if (!ownerCN)
+ if (!ownerLogin)
{
- ownerCN = [[self clientObject] ownerInContext: context];
- [ownerCN retain];
+ ownerLogin = [[self clientObject] ownerInContext: context];
+ [ownerLogin retain];
}
- return ownerCN;
+ return ownerLogin;
+}
+
+- (NSString *) _displayNameForUID: (NSString *) uid
+{
+ AgenorUserManager *um;
+
+ um = [AgenorUserManager sharedUserManager];
+
+ return [NSString stringWithFormat: @"%@ <%@>",
+ [um getCNForUID: uid],
+ [um getEmailForUID: uid]];
+}
+
+- (NSString *) ownerName
+{
+ return [self _displayNameForUID: [self ownerLogin]];
}
- (void) _prepareUsers
NSEnumerator *aclsEnum;
AgenorUserManager *um;
NSDictionary *currentAcl;
- iCalPerson *currentUser;
NSString *currentUID;
aclsEnum = [[self aclsForFolder] objectEnumerator];
publishInFreeBusy = YES;
else
{
- currentUser = [um iCalPersonWithUid: currentUID];
- if (![[currentUser cn] isEqualToString: [self ownerCN]])
+ if (![[um getCNForUID: currentUID]
+ isEqualToString: [self ownerLogin]])
{
if ([[currentAcl objectForKey: @"c_role"]
isEqualToString: SOGoRole_Delegate])
- [delegates addObject: [currentUser cn]];
+ [delegates addObject: currentUID];
else
- [assistants addObject: [currentUser cn]];
- [users addObject: currentUser];
+ [assistants addObject: currentUID];
+ [users addObject: currentUID];
}
}
currentAcl = [aclsEnum nextObject];
return users;
}
+- (void) setCurrentUser: (NSString *) newCurrentUser
+{
+ ASSIGN (currentUser, newCurrentUser);
+}
+
+- (NSString *) currentUser
+{
+ return currentUser;
+}
+
+- (NSString *) currentUserDisplayName
+{
+ return [self _displayNameForUID: currentUser];
+}
+
- (NSArray *) delegates
{
if (!prepared)
- (NSString *) toolbar
{
- return (([[self ownerCN] isEqualToString: [[context activeUser] login]])
+ NSString *currentLogin;
+
+ currentLogin = [[context activeUser] login];
+
+ return (([[self ownerLogin] isEqualToString: currentLogin])
? @"SOGoAclOwner.toolbar" : @"SOGoAclAssistant.toolbar");
}
--- /dev/null
+/* UIxFolderActions.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 UIXFOLDERACTIONS_H
+#define UIXFOLDERACTIONS_H
+
+#import <NGObjWeb/WODirectAction.h>
+
+@class SOGoFolder;
+@class NSString;
+@class NSUserDefaults;
+@class NSMutableString;
+@class NSMutableDictionary;
+
+@interface UIxFolderActions : WODirectAction
+{
+ SOGoFolder *clientObject;
+ AgenorUserManager *um;
+ NSUserDefaults *ud;
+ NSString *owner;
+ NSString *login;
+ NSString *baseFolder;
+ NSMutableString *subscriptionPointer;
+ NSMutableDictionary *moduleSettings;
+}
+
+- (WOResponse *) subscribeAction;
+- (WOResponse *) unsubscribeAction;
+- (WOResponse *) canAccessContentAction;
+- (WOResponse *) activateFolderAction;
+- (WOResponse *) deactivateFolderAction;
+
+@end
+
+#endif /* UIXFOLDERACTIONS_H */
--- /dev/null
+/* UIxFolderActions.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/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSUserDefaults.h>
+#import <Foundation/NSValue.h>
+
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/SoSecurityManager.h>
+
+#import <SOGo/AgenorUserManager.h>
+#import <SOGo/SOGoUser.h>
+#import <SOGo/SOGoObject.h>
+#import <SOGo/SOGoPermissions.h>
+
+#import "UIxFolderActions.h"
+
+@implementation UIxFolderActions
+
+#warning some of this code could probably be moved in one of the \
+ clientObject classes...
+
+- (void) _setupContext
+{
+ NSString *clientClass;
+
+ login = [[context activeUser] login];
+ clientObject = [self clientObject];
+ owner = [clientObject ownerInContext: nil];
+
+ clientClass = NSStringFromClass([clientObject class]);
+ if ([clientClass isEqualToString: @"SOGoContactGCSFolder"])
+ baseFolder = @"Contacts";
+ else if ([clientClass isEqualToString: @"SOGoAppointmentFolder"])
+ baseFolder = @"Calendar";
+ else
+ baseFolder = nil;
+
+ um = [AgenorUserManager sharedUserManager];
+ ud = [um getUserSettingsForUID: login];
+ moduleSettings = [ud objectForKey: baseFolder];
+ if (!moduleSettings)
+ {
+ moduleSettings = [NSMutableDictionary new];
+ [moduleSettings autorelease];
+ }
+ [ud setObject: moduleSettings forKey: baseFolder];
+
+ subscriptionPointer = [NSMutableString stringWithFormat: @"%@:%@",
+ owner, baseFolder];
+ if ([baseFolder isEqualToString: @"Contacts"])
+ [subscriptionPointer appendFormat: @"/%@",
+ [clientObject nameInContainer]];
+}
+
+- (WOResponse *) _realActionWithFolderName: (NSDictionary *) folderDict
+{
+ WOResponse *response;
+ NSMutableDictionary *folderSubscription;
+
+ response = [context response];
+ if ([owner isEqualToString: login])
+ {
+ [response setStatus: 403];
+ [response appendContentString:
+ @"You cannot (un)subscribe to a folder that you own!"];
+ }
+ else
+ {
+ folderSubscription
+ = [moduleSettings objectForKey: @"SubscribedFolders"];
+ if (!folderSubscription)
+ {
+ folderSubscription = [NSMutableDictionary dictionary];
+ [moduleSettings setObject: folderSubscription
+ forKey: @"SubscribedFolders"];
+ }
+ if (folderDict)
+ [folderSubscription setObject: folderDict
+ forKey: subscriptionPointer];
+ else
+ [folderSubscription removeObjectForKey: subscriptionPointer];
+
+ [ud synchronize];
+ [response setStatus: 204];
+ }
+
+ return response;
+}
+
+- (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 new];
+ [folderDict setObject: folderName forKey: @"displayName"];
+ [folderDict setObject: [NSNumber numberWithBool: NO] forKey: @"active"];
+
+ return [self _realActionWithFolderName: folderDict];
+}
+
+- (WOResponse *) unsubscribeAction
+{
+ [self _setupContext];
+
+ return [self _realActionWithFolderName: nil];
+}
+
+- (WOResponse *) canAccessContentAction
+{
+ WOResponse *response;
+ SoSecurityManager *securityManager;
+ BOOL result;
+
+ securityManager = [SoSecurityManager sharedSecurityManager];
+ result = (![securityManager validatePermission: SoPerm_AccessContentsInformation
+ onObject: [self clientObject]
+ inContext: context]);
+
+ response = [context response];
+ [response setStatus: 200];
+ [response setHeader: @"text/plain; charset=\"ascii\""
+ forKey: @"content-type"];
+ [response appendContentString: (result) ? @"1" : @"0"];
+
+ return response;
+}
+
+- (WOResponse *) _realFolderActivation: (BOOL) makeActive
+{
+ WOResponse *response;
+ NSMutableDictionary *folderSubscription, *folderDict;
+ NSNumber *active;
+
+ response = [context response];
+
+ [self _setupContext];
+ active = [NSNumber numberWithBool: makeActive];
+ if ([owner isEqualToString: login])
+ [moduleSettings setObject: active forKey: @"activateUserFolder"];
+ else
+ {
+ folderSubscription
+ = [moduleSettings objectForKey: @"SubscribedFolders"];
+ if (folderSubscription)
+ {
+ folderDict = [folderSubscription objectForKey: subscriptionPointer];
+ if (folderDict)
+ [folderDict setObject: active
+ forKey: @"active"];
+ }
+ }
+
+ [ud synchronize];
+ [response setStatus: 204];
+
+ return response;
+}
+
+- (WOResponse *) activateFolderAction
+{
+ return [self _realFolderActivation: YES];
+}
+
+- (WOResponse *) deactivateFolderAction
+{
+ return [self _realFolderActivation: NO];
+}
+
+@end
{ /* -*-javascript-*- */
- requires = ( MAIN, Mailer );
+ 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 = {
- SOGoFolder = {
- methods = {
- acls = {
- protectedBy = "ReadAcls";
- pageName = "UIxAclEditor";
- };
- saveAcls = {
- protectedBy = "SaveAcls";
- pageName = "UIxAclEditor";
- actionName = "saveAcls";
- };
- };
- };
- };
+ categories = {
+ SOGoFolder = {
+ methods = {
+ subscribe = {
+ protectedBy = "View";
+ actionClass = "UIxFolderActions";
+ actionName = "subscribe";
+ };
+ unsubscribe = {
+ protectedBy = "View";
+ actionClass = "UIxFolderActions";
+ actionName = "unsubscribe";
+ };
+ canAccessContent = {
+ protectedBy = "View";
+ actionClass = "UIxFolderActions";
+ actionName = "canAccessContent";
+ };
+ activateFolder = {
+ protectedBy = "View";
+ actionClass = "UIxFolderActions";
+ actionName = "activateFolder";
+ };
+ deactivateFolder = {
+ protectedBy = "View";
+ actionClass = "UIxFolderActions";
+ actionName = "deactivateFolder";
+ };
+ acls = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxAclEditor";
+ };
+ saveAcls = {
+ protectedBy = "SaveAcls";
+ pageName = "UIxAclEditor";
+ actionName = "saveAcls";
+ };
+ };
+ };
+ };
}
"Recipient" = "Recipient";
"Carbon Copy" = "Carbon Copy";
"Blind Carbon Copy" = "Blind Carbon Copy";
-"Add Attendee..." = "Add Attendee...";
-"Add Assistant" = "Add Assistant";
-"Add Delegate" = "Add Delegate";
"New Addressbook..." = "New Addressbook...";
"Subscribe to an Addressbook..." = "Subscribe to an Addressbook...";
"Name of the Address Book" = "Name of the Address Book";
"Are you sure you want to delete the selected address book?"
= "Are you sure you want to delete the selected address book?";
+
+"You cannot subscribe to a folder that you own!"
+= "You cannot subscribe to a folder that you own!";
+"Unable to subscribe to that folder!"
+= "Unable to subscribe to that folder!";
"Recipient" = "Destinataire";
"Carbon Copy" = "Copie carbone";
"Blind Carbon Copy" = "C. carbone cachée";
-"Add Attendee..." = "Ajouter participant...";
-"Add Calendar..." = "Ajouter agenda...";
-"Add Address Book..." = "Ajouter carnet...";
-"Add Assistant" = "Ajouter comme assistant";
-"Add Delegate" = "Ajouter comme délégué";
"New Addressbook..." = "Nouveau carnet d'adresses...";
"Subscribe to an Addressbook..." = "S'inscrire à un carnet d'adresses...";
"Name of the Address Book" = "Nom du carnet d'adresses";
"Are you sure you want to delete the selected address book?"
= "Voulez-vous vraiment supprimer le carnet d'adresses sélectionné ?";
+
+"You cannot subscribe to a folder that you own!"
+= "Vous ne pouvez pas vous inscrire à un dossier qui vous appartient!";
+"Unable to subscribe to that folder!"
+= "Impossible de vous inscrire à ce dossier!";
ContactsUI_LANGUAGES = English French
ContactsUI_OBJC_FILES = \
- UIxContactsAclsSelection.m \
- UIxContactsAddressBooksSelection.m \
- UIxContactsCalendarsSelection.m \
+ UIxContactsUserFolders.m \
UIxContactsMailerSelection.m \
\
ContactsUIProduct.m \
UIxContactEditor.m \
UIxContactsListView.m \
UIxContactsListViewContainer.m \
- UIxContactSelector.m \
UIxContactFoldersView.m \
ContactsUI_RESOURCE_FILES += \
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/WOContext.h>
+#import <GDLContentStore/GCSFolder.h>
+#import <GDLContentStore/GCSFolderManager.h>
+
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/Contacts/SOGoContactFolders.h>
#import <SoObjects/Contacts/SOGoContactFolder.h>
#import <SoObjects/Contacts/SOGoContactGCSFolder.h>
+#import <SoObjects/Contacts/SOGoContactLDAPFolder.h>
#import "common.h"
return response;
}
-- (id) selectForSchedulerAction
-{
- return [self _selectActionForApplication: @"scheduler-contacts"];
-}
-
- (id) selectForMailerAction
{
return [self _selectActionForApplication: @"mailer-contacts"];
}
-- (id) selectForCalendarsAction
-{
- return [self _selectActionForApplication: @"calendars-contacts"];
-}
-
-- (id) selectForAddressBooksAction
-{
- return [self _selectActionForApplication: @"addressbooks-contacts"];
-}
-
-- (id) selectForAclsAction
-{
- return [self _selectActionForApplication: @"acls-contacts"];
-}
-
- (NSArray *) _searchResults: (NSString *) contact
+ ldapFoldersOnly: (BOOL) ldapFoldersOnly
{
NSMutableArray *results;
SOGoContactFolders *topFolder;
currentFolder = [sogoContactFolders nextObject];
while (currentFolder)
{
- [results addObjectsFromArray: [currentFolder
- lookupContactsWithFilter: contact
- sortBy: @"cn"
- ordering: NSOrderedAscending]];
+ if (!ldapFoldersOnly
+ || [currentFolder isKindOfClass: [SOGoContactLDAPFolder class]])
+ [results addObjectsFromArray: [currentFolder
+ lookupContactsWithFilter: contact
+ sortBy: @"cn"
+ ordering: NSOrderedAscending]];
currentFolder = [sogoContactFolders nextObject];
}
[topFolder release];
{
NSString *contact;
id <WOActionResults> result;
+ BOOL ldapFoldersOnly;
contact = [self queryParameterForKey: @"search"];
- if ([contact length])
- result = [self _responseForResults: [self _searchResults: contact]];
+ ldapFoldersOnly = [[self queryParameterForKey: @"ldap-only"] boolValue];
+ if ([contact length] > 0)
+ result
+ = [self _responseForResults: [self _searchResults: contact
+ ldapFoldersOnly: ldapFoldersOnly]];
else
result = [NSException exceptionWithHTTPStatus: 400
reason: @"missing 'search' parameter"];
-
+
return result;
}
-- (id <WOActionResults>) updateAdditionalAddressBooksAction
+- (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders
+{
+ NSMutableArray *gcsFolders;
+ NSEnumerator *contactSubfolders;
+ SOGoContactGCSFolder *currentContactFolder;
+ NSString *folderName, *displayName;
+ NSMutableDictionary *currentDictionary;
+
+ gcsFolders = [NSMutableArray new];
+ [gcsFolders autorelease];
+
+ contactSubfolders = [[contactFolders contactFolders] objectEnumerator];
+ currentContactFolder = [contactSubfolders nextObject];
+ while (currentContactFolder)
+ {
+ if ([currentContactFolder
+ isKindOfClass: [SOGoContactGCSFolder class]])
+ {
+ folderName = [NSString stringWithFormat: @"/Contacts/%@",
+ [currentContactFolder nameInContainer]];
+ currentDictionary = [NSMutableDictionary new];
+ [currentDictionary autorelease];
+ displayName = [[currentContactFolder ocsFolder] folderName];
+ [currentDictionary setObject: displayName forKey: @"displayName"];
+ [currentDictionary setObject: folderName forKey: @"name"];
+ [currentDictionary setObject: @"contact" forKey: @"type"];
+ [gcsFolders addObject: currentDictionary];
+ }
+ currentContactFolder = [contactSubfolders nextObject];
+ }
+
+ return gcsFolders;
+}
+
+- (NSArray *) _foldersForUID: (NSString *) uid
+ ofType: (NSString *) folderType
+{
+ NSObject *topFolder, *userFolder;
+ SOGoContactFolders *contactFolders;
+ NSMutableArray *folders;
+ NSMutableDictionary *currentDictionary;
+
+ folders = [NSMutableArray new];
+ [folders autorelease];
+
+ topFolder = [[[self clientObject] container] container];
+ 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];
+ }
+ if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
+ {
+ contactFolders = [userFolder lookupName: @"Contacts"
+ inContext: context acquire: NO];
+ [folders
+ addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]];
+ }
+
+ return folders;
+}
+
+- (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
+{
+ NSMutableString *foldersString;
+ NSDictionary *currentFolder;
+
+ foldersString = [NSMutableString new];
+ [foldersString autorelease];
+
+ currentFolder = [folders nextObject];
+ while (currentFolder)
+ {
+ [foldersString appendFormat: @";%@:%@:%@",
+ [currentFolder objectForKey: @"displayName"],
+ [currentFolder objectForKey: @"name"],
+ [currentFolder objectForKey: @"type"]];
+ currentFolder = [folders nextObject];
+ }
+
+ return foldersString;
+}
+
+- (WOResponse *) _foldersResponseForResults: (NSArray *) results
+ withType: (NSString *) folderType
{
WOResponse *response;
- NSUserDefaults *ud;
+ NSString *uid, *foldersString;
+ NSMutableString *responseString;
+ NSDictionary *result;
+ NSEnumerator *resultsEnum;
+ NSArray *folders;
- ud = [[context activeUser] userDefaults];
- [ud setObject: [self queryParameterForKey: @"ids"]
- forKey: @"additionaladdressbooks"];
- [ud synchronize];
response = [context response];
- [response setStatus: 200];
- [response setHeader: @"text/html; charset=\"utf-8\"" forKey: @"content-type"];
+
+ if ([results count])
+ {
+ [response setStatus: 200];
+ [response setHeader: @"text/plain; charset=iso-8859-1"
+ forKey: @"Content-Type"];
+
+ responseString = [NSMutableString new];
+ resultsEnum = [results objectEnumerator];
+ result = [resultsEnum nextObject];
+ while (result)
+ {
+ uid = [result objectForKey: @"c_uid"];
+ folders = [self _foldersForUID: uid ofType: folderType];
+ foldersString
+ = [self _foldersStringForFolders: [folders objectEnumerator]];
+ [responseString appendFormat: @"%@:%@%@\n",
+ uid, [self _emailForResult: result], foldersString];
+ result = [resultsEnum nextObject];
+ }
+ [response appendContentString: responseString];
+ [responseString release];
+ }
+ else
+ [response setStatus: 404];
return response;
}
+- (id <WOActionResults>) foldersSearchAction
+{
+ NSString *contact, *folderType;
+ id <WOActionResults> result;
+ BOOL ldapOnly;
+
+ contact = [self queryParameterForKey: @"search"];
+ if ([contact length] > 0)
+ {
+ ldapOnly = [[self queryParameterForKey: @"ldap-only"] boolValue];
+ folderType = [self queryParameterForKey: @"type"];
+ result = [self _foldersResponseForResults:
+ [self _searchResults: contact
+ ldapFoldersOnly: ldapOnly]
+ withType: folderType];
+ }
+ else
+ result = [NSException exceptionWithHTTPStatus: 400
+ reason: @"missing 'search' parameter"];
+
+ return result;
+}
+
- (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
{
SOGoFolder *upperContainer;
? contactFolder : nil);
}
-- (id <WOActionResults>) checkRightsAction
-{
- WOResponse *response;
- NSUserDefaults *ud;
- NSString *uids;
- NSMutableString *rights;
- NSArray *ids;
- unsigned int count, max;
- BOOL result;
-
- ud = [[context activeUser] userDefaults];
- uids = [ud objectForKey: @"additionaladdressbooks"];
-
- response = [context response];
- [response setStatus: 200];
- [response setHeader: @"text/plain; charset=\"utf-8\""
- forKey: @"content-type"];
- rights = [NSMutableString string];
- if ([uids length] > 0)
- {
- ids = [uids componentsSeparatedByString: @","];
- max = [ids count];
- for (count = 0; count < max; count++)
- {
- result = ([self contactFolderForUID: [ids objectAtIndex: count]] != nil);
- if (count == 0)
- [rights appendFormat: @"%d", result];
- else
- [rights appendFormat: @",%d", result];
- }
- }
- [response appendContentString: rights];
-
- return response;
-}
-
@end
+++ /dev/null
-/*
- 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.
-*/
-
-#import <SOGoUI/UIxComponent.h>
-
-@interface UIxContactsAclsSelection : UIxComponent
-
-@end
-
-@implementation UIxContactsAclsSelection
-
-@end /* UIxContactsAclsSelection */
+++ /dev/null
-/*
- 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.
-*/
-
-#import <SOGoUI/UIxComponent.h>
-
-@interface UIxContactsAddressBooksSelection : UIxComponent
-
-@end
-
-@implementation UIxContactsAddressBooksSelection
-
-@end /* UIxContactsAddressBooksSelection */
+++ /dev/null
-/*
- 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.
-*/
-
-#import <SOGoUI/UIxComponent.h>
-
-@interface UIxContactsCalendarsSelection : UIxComponent
-
-@end
-
-@implementation UIxContactsCalendarsSelection
-
-@end /* UIxContactsCalendarsSelection */
return searchText;
}
-- (NSString *) selectorComponentClass
-{
- return selectorComponentClass;
-}
-
-- (id) mailerContactsAction
+- (id <WOActionResults>) mailerContactsAction
{
selectorComponentClass = @"UIxContactsMailerSelection";
return self;
}
-- (id) calendarsContactsAction
-{
- selectorComponentClass = @"UIxContactsCalendarsSelection";
-
- return self;
-}
-
-- (id) addressBooksContactsAction
-{
- selectorComponentClass = @"UIxContactsAddressBooksSelection";
-
- return self;
-}
-
-- (id) aclsContactsAction
-{
- selectorComponentClass = @"UIxContactsAclsSelection";
-
- return self;
-}
-
- (id <WOActionResults>) deleteAction
{
id <WOActionResults> result;
return YES;
}
+- (WOResponse *) canAccessContentAction
+{
+ WOResponse *response;
+ NSString *clientClass;
+
+ clientClass = NSStringFromClass([[self clientObject] class]);
+
+ response = [context response];
+ [response setStatus: 200];
+ [response setHeader: @"text/plain; charset=\"ascii\""
+ forKey: @"content-type"];
+ [response
+ appendContentString:
+ ([clientClass isEqualToString: @"SOGoContactLDAPFolder"])
+ ? @"1" : @"0"];
+
+ return response;
+}
+
@end /* UIxContactsListView */
NSString *foldersPrefix;
NSString *selectorComponentClass;
NSString *currentAdditionalFolder;
+ NSDictionary *additionalFolders;
id currentFolder;
}
- (NSArray *) contactFolders;
-- (NSString *) contactFolderId;
- (NSString *) currentContactFolderId;
- (NSString *) currentContactFolderName;
-- (NSString *) additionalAddressBooks;
- (NSArray *) additionalFolders;
- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder;
- (NSString *) currentAdditionalFolder;
+- (NSString *) currentAdditionalFolderName;
@end
*/
#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/SoObjects.h>
#import <NGExtensions/NSObject+Values.h>
+#import <SoObjects/SOGo/AgenorUserManager.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/Contacts/SOGoContactFolder.h>
{
foldersPrefix = nil;
selectorComponentClass = nil;
+ additionalFolders = nil;
}
return self;
}
+- (void) dealloc
+{
+ [additionalFolders release];
+ [super dealloc];
+}
+
- (void) setSelectorComponentClass: (NSString *) aComponentClass
{
selectorComponentClass = aComponentClass;
return foldersPrefix;
}
-- (NSString *) contactFolderId
-{
- return [NSString stringWithFormat: @"%@/%@",
- [self foldersPrefix],
- [[self clientObject] nameInContainer]];
-}
-
- (NSArray *) contactFolders
{
SOGoContactFolders *folderContainer;
return [self labelForKey: [currentFolder displayName]];
}
-- (BOOL) isFolderCurrent
-{
- return [[self currentContactFolderId] isEqualToString: [self contactFolderId]];
-}
-
-- (NSString *) additionalAddressBooks
-{
- NSUserDefaults *ud;
-
- ud = [[context activeUser] userDefaults];
-
- return [ud objectForKey: @"additionaladdressbooks"];
-}
-
- (NSArray *) additionalFolders
{
- NSString *folders;
- NSArray *folderNames;
+ AgenorUserManager *um;
+ NSUserDefaults *ud;
+ NSString *login;
- folders = [self additionalAddressBooks];
- if ([folders length] > 0)
- folderNames = [folders componentsSeparatedByString: @","];
- else
- folderNames = nil;
+ if (!additionalFolders)
+ {
+ um = [AgenorUserManager sharedUserManager];
+ login = [[context activeUser] login];
+ ud = [um getUserSettingsForUID: login];
+ additionalFolders
+ = [[ud objectForKey: @"Contacts"] objectForKey: @"SubscribedFolders"];
+ [additionalFolders retain];
+ }
- return folderNames;
+ return [additionalFolders allKeys];
}
- (void) setCurrentAdditionalFolder: (NSString *) newCurrentAdditionalFolder
return currentAdditionalFolder;
}
+- (NSString *) currentAdditionalFolderName
+{
+ return [[additionalFolders objectForKey: currentAdditionalFolder]
+ objectForKey: @"displayName"];
+}
+
- (BOOL) hasContactSelectionButtons
{
return (selectorComponentClass != nil);
-/* UIxCalCalendarsListView.h - this file is part of SOGo
+/* UIxContactsUserFolders.h - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* Boston, MA 02111-1307, USA.
*/
-#ifndef UIXCALCALENDARSLISTVIEW_H
-#define UIXCALCALENDARSLISTVIEW_H
+#ifndef UIXCONTACTSUSERFOLDERS_H
+#define UIXCONTACTSUSERFOLDERS_H
#import <SOGoUI/UIxComponent.h>
-@class NSMutableArray;
-@class NSMutableDictionary;
-@class iCalPerson;
-
-@interface UIxCalCalendarsListView : UIxComponent
-{
- NSMutableArray *checkedContacts;
- NSMutableArray *contacts;
- NSMutableDictionary *colors;
- iCalPerson *currentContactPerson;
-}
+@interface UIxContactsUserFolders : UIxComponent
@end
-#endif /* UIXCALCALENDARSLISTVIEW_H */
+
+#endif /* UIXCONTACTSUSERFOLDERS_H */
--- /dev/null
+/* UIxContactsUserFolders.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 "UIxContactsUserFolders.h"
+
+@implementation UIxContactsUserFolders
+
+@end
{ /* -*-javascript-*- */
- requires = ( MAIN, CommonUI, Contacts );
+ requires = ( MAIN, MainUI, CommonUI, Contacts );
publicResources = ();
pageName = "UIxContactFoldersView";
actionName = "newAb";
};
- scheduler-contacts = {
- protectedBy = "View";
- pageName = "UIxContactFoldersView";
- actionName = "selectForScheduler";
- };
mailer-contacts = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "selectForMailer";
};
- calendars-contacts = {
- protectedBy = "View";
- pageName = "UIxContactFoldersView";
- actionName = "selectForCalendars";
- };
- addressbooks-contacts = {
- protectedBy = "View";
- pageName = "UIxContactFoldersView";
- actionName = "selectForAddressBooks";
- };
- acls-contacts = {
+ contactSearch = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
- actionName = "selectForAcls";
+ actionName = "contactSearch";
};
- contactSearch = {
+ foldersSearch = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
- actionName = "contactSearch";
+ actionName = "foldersSearch";
};
updateAdditionalAddressBooks = {
protectedBy = "View";
saveAcls = {
protectedBy = "SaveAcls";
pageName = "UIxAclEditor";
- actionName = "saveAcls";
+ actionName = "saveAcls";
};
checkRights = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "checkRights";
};
+ userFolders = {
+ protectedBy = "View";
+ pageName = "UIxContactsUserFolders";
+ };
};
};
mailer-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
- actionName = "mailerContacts";
- };
- calendars-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "calendarsContacts";
- };
- acls-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "aclsContacts";
- };
- addressbooks-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "addressBooksContacts";
+ actionName = "mailerContacts";
};
delete = {
protectedBy = "View";
pageName = "UIxContactsListView";
- actionName = "delete";
+ actionName = "delete";
};
};
};
pageName = "UIxContactEditor";
actionName = "new";
};
- scheduler-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "schedulerContacts";
- };
mailer-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "mailerContacts";
};
- calendars-contacts = {
- protectedBy = "View";
+ canAccessContent = {
+ protectedBy = "View";
pageName = "UIxContactsListView";
- actionName = "calendarsContacts";
- };
- acls-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "aclsContacts";
- };
- addressbooks-contacts = {
- protectedBy = "View";
- pageName = "UIxContactsListView";
- actionName = "addressBooksContacts";
- };
+ actionName = "canAccessContent";
+ };
};
};
* Boston, MA 02111-1307, USA.
*/
+#import <Foundation/NSArray.h>
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSValue.h>
#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGExtensions/NSCalendarDate+misc.h>
+
+#import <Appointments/SOGoFreeBusyObject.h>
+#import <SOGo/NSCalendarDate+SOGo.h>
#import <SOGoUI/UIxComponent.h>
@interface SOGoUserHomePage : UIxComponent
return [self redirectToLocation: url];
}
+- (void) _fillFreeBusyItems: (NSMutableArray *) items
+ withRecords: (NSEnumerator *) records
+ fromStartDate: (NSCalendarDate *) startDate
+ toEndDate: (NSCalendarDate *) endDate
+{
+ NSDictionary *record;
+ int count, startInterval, endInterval, value;
+ NSNumber *status;
+ NSCalendarDate *currentDate;
+
+ record = [records nextObject];
+ while (record)
+ {
+ status = [record objectForKey: @"status"];
+
+ value = [[record objectForKey: @"startdate"] intValue];
+ currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
+ if ([currentDate earlierDate: startDate] == currentDate)
+ startInterval = 0;
+ else
+ startInterval
+ = ([currentDate timeIntervalSinceDate: startDate] / 900);
+
+ value = [[record objectForKey: @"enddate"] intValue];
+ currentDate = [NSCalendarDate dateWithTimeIntervalSince1970: value];
+ if ([currentDate earlierDate: endDate] == endDate)
+ endInterval = [items count] - 1;
+ else
+ endInterval = ([currentDate timeIntervalSinceDate: startDate] / 900);
+
+ for (count = startInterval; count < endInterval; count++)
+ [items replaceObjectAtIndex: count withObject: status];
+
+ record = [records nextObject];
+ }
+}
+
+- (NSString *) _freeBusyAsTextFromStartDate: (NSCalendarDate *) startDate
+ toEndDate: (NSCalendarDate *) endDate
+ forFreeBusy: (SOGoFreeBusyObject *) fb
+{
+ NSEnumerator *records;
+ NSMutableArray *freeBusyItems;
+ NSTimeInterval interval;
+ int count, intervals;
+
+ interval = [endDate timeIntervalSinceDate: startDate] + 60;
+ intervals = interval / 900; /* slices of 15 minutes */
+ freeBusyItems = [NSMutableArray arrayWithCapacity: intervals];
+ for (count = 1; count < intervals; count++)
+ [freeBusyItems addObject: @"0"];
+
+ records = [[fb fetchFreeBusyInfosFrom: startDate to: endDate] objectEnumerator];
+ [self _fillFreeBusyItems: freeBusyItems withRecords: records
+ fromStartDate: startDate toEndDate: endDate];
+
+ return [freeBusyItems componentsJoinedByString: @","];
+}
+
+- (NSString *) _freeBusyAsText
+{
+ SOGoFreeBusyObject *co;
+ NSCalendarDate *startDate, *endDate;
+ NSString *queryDay, *additionalDays;
+ NSTimeZone *uTZ;
+
+ co = [self clientObject];
+ uTZ = [co userTimeZone];
+
+ queryDay = [self queryParameterForKey: @"sday"];
+ if ([queryDay length])
+ startDate = [NSCalendarDate dateFromShortDateString: queryDay
+ andShortTimeString: @"0000"
+ inTimeZone: uTZ];
+ else
+ {
+ startDate = [NSCalendarDate calendarDate];
+ [startDate setTimeZone: uTZ];
+ startDate = [startDate hour: 0 minute: 0];
+ }
+
+ queryDay = [self queryParameterForKey: @"eday"];
+ if ([queryDay length])
+ endDate = [NSCalendarDate dateFromShortDateString: queryDay
+ andShortTimeString: @"2359"
+ inTimeZone: uTZ];
+ else
+ endDate = [startDate hour: 23 minute: 59];
+
+ additionalDays = [self queryParameterForKey: @"additional"];
+ if ([additionalDays length] > 0)
+ endDate = [endDate dateByAddingYears: 0 months: 0
+ days: [additionalDays intValue]
+ hours: 0 minutes: 0 seconds: 0];
+
+ return [self _freeBusyAsTextFromStartDate: startDate toEndDate: endDate
+ forFreeBusy: co];
+}
+
+- (id <WOActionResults>) readFreeBusyAction
+{
+ WOResponse *response;
+
+ response = [context response];
+ [response setStatus: 200];
+ [response setHeader: @"text/plain; charset=iso-8859-1"
+ forKey: @"Content-Type"];
+ [response appendContentString: [self _freeBusyAsText]];
+
+ return response;
+}
+
@end
};
SOGoUserFolder = {
superclass = "SOGoFolder";
- protectedBy = "HomePage Access";
+ /* protectedBy = "HomePage Access"; */
defaultRoles = {
"Homepage Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
"WebDAV Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
libSOGoUI_HEADER_FILES += \
\
+ UIxJSClose.h \
UIxComponent.h \
SOGoDateFormatter.h \
SOGoAptFormatter.h \
libSOGoUI_OBJC_FILES += \
\
+ UIxJSClose.m \
UIxComponent.m \
SOGoDateFormatter.m \
SOGoAptFormatter.m \
#import <SOGo/SOGoCustomGroupFolder.h>
#import <SOGo/NSCalendarDate+SOGo.h>
-#import "../Common/UIxJSClose.h"
+#import "UIxJSClose.h"
#import "UIxComponent.h"
"No free-busy information" = "Pas d'information";
/* FreeBusy panel buttons */
-"Previous slot" = "Période précédente";
-"Next slot" = "Période suivante";
+"Suggest time slot:" = "Suggérer un créneau horaire :";
+"Previous slot" = "Précédent";
+"Next slot" = "Prochain";
"Previous hour" = "Heure précédente";
-"Next hour" = "Heure suivante";
+"Next hour" = "Prochaine heure";
"closeThisWindowMessage" = "Merci! Vous pouvez maintenant fermer cette fenêtre.";
"Multicolumn Day View" = "Multicolonne";
\
UIxComponent+Agenor.m \
UIxCalView.m \
- UIxCalCalendarsListView.m \
UIxCalAptListView.m \
UIxCalTasksListView.m \
UIxCalDayView.m \
\
UIxAttendeesEditor.m \
UIxComponentEditor.m \
+ UIxCalendarSelector.m \
UIxAppointmentView.m \
UIxAppointmentEditor.m \
UIxAppointmentProposal.m \
UIxTaskProposal.m \
UIxCalSelectTab.m \
UIxCalDateLabel.m \
- UIxCalBackForthNavView.m \
UIxDatePicker.m \
UIxTimeDateControl.m \
UIxCalInlineAptView.m \
UIxCalInlineMonthAptView.m \
- UIxCalScheduleOverview.m \
UIxCalParticipationStatusView.m \
UIxCalMonthOverview.m
+++ /dev/null
-/*
- Copyright (C) 2004 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.
-*/
-// $Id$
-
-
-#include <NGObjWeb/NGObjWeb.h>
-
-/*
- Associations:
-
- methodName -> maps to href
- prevQueryParameters -> queryDictionary
- currentQueryParameters -> queryDictionary
- nextQueryParameters -> queryDictionary
- label -> user presentable name to display for "this"
- */
-
-@interface UIxCalBackForthNavView : WOComponent
-{
-}
-
-@end
-
-
-@implementation UIxCalBackForthNavView
-
-- (BOOL)synchronizesVariablesWithBindings {
- return NO;
-}
-
-@end
+++ /dev/null
-/* UIxCalCalendarsListView.m - this file is part of SOGo
- *
- * Copyright (C) 2006 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/NSDictionary.h>
-#import <Foundation/NSString.h>
-#import <Foundation/NSUserDefaults.h>
-
-#import <SOGo/AgenorUserManager.h>
-#import <SOGo/SOGoUser.h>
-
-#import "UIxCalCalendarsListView.h"
-
-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;
-
- return newValue;
-}
-
-@implementation UIxCalCalendarsListView
-
-- (id) init
-{
- if ((self = [super init]))
- {
- contacts = nil;
- checkedContacts = nil;
- currentContactPerson = nil;
- colors = nil;
- }
-
- return self;
-}
-
-- (void) dealloc
-{
- if (currentContactPerson)
- [currentContactPerson release];
- if (contacts)
- [contacts release];
- if (checkedContacts)
- [checkedContacts release];
- if (colors)
- [colors release];
- [super dealloc];
-}
-
-- (NSString *) _colorForNumber: (unsigned int) number
-{
- unsigned int index, currentValue;
- unsigned char colorTable[] = { 1, 1, 1 };
- NSString *color;
-
- if (number == 0)
- color = @"#ccf";
- else if (number == NSNotFound)
- color = @"#f00";
- else
- {
- currentValue = number;
- index = 0;
- while (currentValue)
- {
- if (currentValue & 1)
- colorTable[index]++;
- if (index == 3)
- index = 0;
- currentValue >>= 1;
- index++;
- }
- color = [NSString stringWithFormat: @"#%2x%2x%2x",
- (255 / colorTable[2]) - 1,
- (255 / colorTable[1]) - 1,
- (255 / colorTable[0]) - 1];
- }
-
- return color;
-}
-
-- (void) _addContactId: (NSString *) contactId
- withUm: (AgenorUserManager *) um
- andNumber: (unsigned int) count
-{
- NSString *contactRealId;
- iCalPerson *currentContact;
-
- if ([contactId hasPrefix: @"-"])
- contactRealId = [contactId substringFromIndex: 1];
- else
- contactRealId = contactId;
-
- currentContact = [um iCalPersonWithUid: contactRealId];
- [contacts addObject: currentContact];
- if (contactId == contactRealId)
- [checkedContacts addObject: currentContact];
- [colors setObject: [self _colorForNumber: count]
- forKey: contactRealId];
-}
-
-- (void) _setupContacts
-{
- SOGoUser *user;
- NSString *list, *currentId;
- NSEnumerator *rawContacts;
- AgenorUserManager *um;
- unsigned int count;
-
- contacts = [NSMutableArray new];
- checkedContacts = [NSMutableArray new];
- colors = [NSMutableDictionary new];
-
- um = [AgenorUserManager sharedUserManager];
- user = [context activeUser];
- list = [[user userDefaults] stringForKey: @"calendaruids"];
- if ([list length] == 0)
- list = [self shortUserNameForDisplay];
-
- rawContacts
- = [[list componentsSeparatedByString: @","] objectEnumerator];
- currentId = [rawContacts nextObject];
- count = 0;
- while (currentId)
- {
- [self _addContactId: currentId withUm: um andNumber: count];
- currentId = [rawContacts nextObject];
- count++;
- }
-}
-
-- (NSArray *) contacts
-{
- if (!contacts)
- [self _setupContacts];
-
- return contacts;
-}
-
-- (NSArray *) checkedContacts
-{
- if (!checkedContacts)
- [self _setupContacts];
-
- return checkedContacts;
-}
-
-- (void) setCurrentContactPerson: (iCalPerson *) contact
-{
- if (currentContactPerson)
- [currentContactPerson release];
- currentContactPerson = contact;
- if (currentContactPerson)
- [currentContactPerson retain];
-}
-
-- (NSString *) currentContactLogin
-{
- return [currentContactPerson cn];
-}
-
-- (NSString *) currentContactSpanBG
-{
- return [colors objectForKey: [currentContactPerson cn]];
-}
-
-- (NSString *) currentContactAptBorder
-{
- NSString *spanBG;
- char cColor[8];
- unsigned int count;
-
- spanBG = [colors objectForKey: [currentContactPerson cn]];
- [spanBG getCString: cColor];
- cColor[7] = 0;
- for (count = 1; count < 7; count++)
- cColor[count] = darkenedColor(cColor[count]);
-
- return [NSString stringWithCString: cColor];
-}
-
-- (NSDictionary *) colors
-{
- return colors;
-}
-
-@end
- (NSString *) labelForDay
{
- return [NSString stringWithFormat: @"%@ %@",
+ return [NSString stringWithFormat: @"%@<br />%@",
[dateFormatter shortDayOfWeek: [currentTableDay dayOfWeek]],
[dateFormatter stringForObjectValue: currentTableDay]];
}
#define __UIxCalDayView_H_
-#include "UIxCalView.h"
+#import "UIxCalView.h"
@interface UIxCalDayView : UIxCalView
-{
- NSCalendarDate *currentDate;
-}
-- (void)setCurrentDate:(NSCalendarDate *)_date;
-- (NSCalendarDate *)currentDate;
-- (BOOL)isCurrentDateInApt;
-
-- (NSDictionary *)currentDateQueryParameters;
+- (NSDictionary *) dayBeforePrevDayQueryParameters;
+- (NSDictionary *) prevDayQueryParameters;
+- (NSDictionary *) nextDayQueryParameters;
+- (NSDictionary *) dayAfterNextDayQueryParameters;
+- (NSDictionary *) currentDateQueryParameters;
-- (NSArray *)dateRange;
+- (NSCalendarDate *) startDate;
-/* appointments */
-- (NSArray *)aptsForCurrentDate;
-- (BOOL)hasAptsForCurrentDate;
+- (NSString *) dayBeforeYesterdayName;
+- (NSString *) yesterdayName;
+- (NSString *) currentDayName;
+- (NSString *) tomorrowName;
+- (NSString *) dayAfterTomorrowName;
@end
#import "UIxCalDayView.h"
-@interface UIxCalDayView (PrivateAPI)
-- (BOOL)isCurrentDateInApt:(id)_apt;
-- (NSArray *)_getDatesFrom:(NSCalendarDate *)_from to:(NSCalendarDate *)_to;
-@end
+// @interface UIxCalDayView (PrivateAPI)
+// - (BOOL)isCurrentDateInApt:(id)_apt;
+// - (NSArray *)_getDatesFrom:(NSCalendarDate *)_from to:(NSCalendarDate *)_to;
+// @end
@implementation UIxCalDayView
-- (void) dealloc
-{
- [self->currentDate release];
- [super dealloc];
-}
-
-- (void) setCurrentDate: (NSCalendarDate *) _date
-{
- ASSIGN(self->currentDate, _date);
-}
-
-- (NSCalendarDate *) currentDate
-{
- return self->currentDate;
-}
-
-- (BOOL) isCurrentDateInApt
-{
- return [self isCurrentDateInApt: [self appointment]];
-}
-
-- (BOOL) isCurrentDateInApt: (id) _apt
-{
- NSCalendarDate *dateStart, *dateEnd, *aptStart, *aptEnd;
- NGCalendarDateRange *dateRange, *aptRange;
+// - (void) dealloc
+// {
+// [self->currentDate release];
+// [super dealloc];
+// }
+
+// - (void) setCurrentDate: (NSCalendarDate *) _date
+// {
+// ASSIGN(self->currentDate, _date);
+// }
+
+// - (NSCalendarDate *) currentDate
+// {
+// return self->currentDate;
+// }
+
+// - (BOOL) isCurrentDateInApt
+// {
+// return [self isCurrentDateInApt: [self appointment]];
+// }
+
+// - (BOOL) isCurrentDateInApt: (id) _apt
+// {
+// NSCalendarDate *dateStart, *dateEnd, *aptStart, *aptEnd;
+// NGCalendarDateRange *dateRange, *aptRange;
- dateStart = self->currentDate;
- dateEnd = [dateStart dateByAddingYears:0 months:0 days:0
- hours:1 minutes:0 seconds:0];
- dateRange = [NGCalendarDateRange calendarDateRangeWithStartDate:dateStart
- endDate:dateEnd];
- aptStart = [self->appointment valueForKey:@"startDate"];
- aptEnd = [self->appointment valueForKey:@"endDate"];
- aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStart
- endDate:aptEnd];
-
- return [dateRange doesIntersectWithDateRange:aptRange];
-}
-
-- (NSArray *) dateRange
-{
- /* default range is from dayStartHour to dayEndHour. Any values before
- or after are also fine */
-
- NSCalendarDate *min, *max;
- NSArray *aptDateRanges;
-
- min = [[self startDate] hour:[self dayStartHour] minute:0];
- max = [[self startDate] hour:[self dayEndHour] minute:0];
-
- aptDateRanges = [[self appointments] valueForKey: @"startDate"];
- if([aptDateRanges count] != 0) {
- NSCalendarDate *d;
-
- aptDateRanges
- = [aptDateRanges sortedArrayUsingSelector: @selector(compareAscending:)];
- d = [aptDateRanges objectAtIndex:0];
- if ([d isDateOnSameDay:min])
- min = (NSCalendarDate *)[d earlierDate:min];
- d = [aptDateRanges objectAtIndex:[aptDateRanges count] - 1];
- if ([d isDateOnSameDay:max])
- max = (NSCalendarDate *)[d laterDate:max];
- }
+// dateStart = self->currentDate;
+// dateEnd = [dateStart dateByAddingYears:0 months:0 days:0
+// hours:1 minutes:0 seconds:0];
+// dateRange = [NGCalendarDateRange calendarDateRangeWithStartDate:dateStart
+// endDate:dateEnd];
+// aptStart = [self->appointment valueForKey:@"startDate"];
+// aptEnd = [self->appointment valueForKey:@"endDate"];
+// aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStart
+// endDate:aptEnd];
+
+// return [dateRange doesIntersectWithDateRange:aptRange];
+// }
+
+// - (NSArray *) dateRange
+// {
+// /* default range is from dayStartHour to dayEndHour. Any values before
+// or after are also fine */
+
+// NSCalendarDate *min, *max;
+// NSArray *aptDateRanges;
+
+// min = [[self startDate] hour:[self dayStartHour] minute:0];
+// max = [[self startDate] hour:[self dayEndHour] minute:0];
+
+// aptDateRanges = [[self appointments] valueForKey: @"startDate"];
+// if([aptDateRanges count] != 0) {
+// NSCalendarDate *d;
+
+// aptDateRanges
+// = [aptDateRanges sortedArrayUsingSelector: @selector(compareAscending:)];
+// d = [aptDateRanges objectAtIndex:0];
+// if ([d isDateOnSameDay:min])
+// min = (NSCalendarDate *)[d earlierDate:min];
+// d = [aptDateRanges objectAtIndex:[aptDateRanges count] - 1];
+// if ([d isDateOnSameDay:max])
+// max = (NSCalendarDate *)[d laterDate:max];
+// }
- return [self _getDatesFrom:min to:max];
-}
-
-- (NSArray *) _getDatesFrom: (NSCalendarDate *) _from
- to: (NSCalendarDate *) _to
-{
- NSMutableArray *dates;
- unsigned i, count, offset;
-
- offset = [_from hourOfDay];
- count = ([_to hourOfDay] + 1) - offset;
- dates = [[NSMutableArray alloc] initWithCapacity:count];
- for(i = 0; i < count; i++) {
- NSCalendarDate *date;
+// return [self _getDatesFrom:min to:max];
+// }
+
+// - (NSArray *) _getDatesFrom: (NSCalendarDate *) _from
+// to: (NSCalendarDate *) _to
+// {
+// NSMutableArray *dates;
+// unsigned i, count, offset;
+
+// offset = [_from hourOfDay];
+// count = ([_to hourOfDay] + 1) - offset;
+// dates = [[NSMutableArray alloc] initWithCapacity:count];
+// for(i = 0; i < count; i++) {
+// NSCalendarDate *date;
- date = [_from hour:offset + i minute:0];
- [dates addObject:date];
- }
- return [dates autorelease];
-}
+// date = [_from hour:offset + i minute:0];
+// [dates addObject:date];
+// }
+// return [dates autorelease];
+// }
/* URLs */
NSString *hmString;
NSCalendarDate *date;
- date = [self currentDate];
+ date = [self selectedDate];
hmString = [NSString stringWithFormat:@"%.2d%.2d",
[date hourOfDay], [date minuteOfHour]];
qp = [[self queryParameters] mutableCopy];
[self setSelectedDateQueryParameter:date inDictionary:qp];
- [qp setObject:hmString forKey:@"hm"];
+ [qp setObject: hmString forKey:@"hm"];
return [qp autorelease];
}
return [[self selectedDate] beginOfDay];
}
-- (NSCalendarDate *) endDate
-{
- return [[self selectedDate] endOfDay];
-}
-
/* appointments */
-- (NSArray *) appointments
-{
- return [self fetchCoreAppointmentsInfos];
-}
-
-- (NSArray *)aptsForCurrentDate {
- NSArray *apts;
- NSMutableArray *filtered;
- unsigned i, count;
- NSCalendarDate *start, *end;
-
- start = self->currentDate;
- end = [start dateByAddingYears:0
- months:0
- days:0
- hours:0
- minutes:59
- seconds:59];
+// - (NSArray *)allDayApts {
+// NSCalendarDate *start;
+// NSArray *apts;
+// NSMutableArray *filtered;
+// unsigned i, count;
- apts = [self appointments];
- filtered = [[NSMutableArray alloc] initWithCapacity:1];
- count = [apts count];
- for (i = 0; i < count; i++) {
- id apt;
- NSCalendarDate *aptStartDate;
+// if (self->allDayApts)
+// return self->allDayApts;
+
+// start = [self startDate];
+// apts = [self appointments];
+// filtered = [[NSMutableArray alloc] initWithCapacity:1];
+// count = [apts count];
+// for (i = 0; i < count; i++) {
+// id apt;
+// NSNumber *bv;
- apt = [apts objectAtIndex:i];
- aptStartDate = [apt valueForKey:@"startDate"];
- if([aptStartDate isGreaterThanOrEqualTo:start] &&
- [aptStartDate isLessThan:end])
- {
- [filtered addObject:apt];
- }
- }
+// apt = [apts objectAtIndex:i];
+// bv = [apt valueForKey:@"isallday"];
+// if ([bv boolValue]) {
+// [filtered addObject:apt];
+// }
+// else {
+// NSCalendarDate *aptStartDate;
+
+// aptStartDate = [apt valueForKey:@"startDate"];
+// if([aptStartDate isLessThan:start]) {
+// [filtered addObject:apt];
+// }
+// }
+// }
- return [filtered autorelease];
-}
-
-- (NSArray *)allDayApts {
- NSCalendarDate *start;
- NSArray *apts;
- NSMutableArray *filtered;
- unsigned i, count;
-
- if (self->allDayApts)
- return self->allDayApts;
-
- start = [self startDate];
- apts = [self appointments];
- filtered = [[NSMutableArray alloc] initWithCapacity:1];
- count = [apts count];
- for (i = 0; i < count; i++) {
- id apt;
- NSNumber *bv;
-
- apt = [apts objectAtIndex:i];
- bv = [apt valueForKey:@"isallday"];
- if ([bv boolValue]) {
- [filtered addObject:apt];
- }
- else {
- NSCalendarDate *aptStartDate;
-
- aptStartDate = [apt valueForKey:@"startDate"];
- if([aptStartDate isLessThan:start]) {
- [filtered addObject:apt];
- }
- }
- }
-
- ASSIGN(self->allDayApts, filtered);
- [filtered release];
- return self->allDayApts;
-}
-
-- (BOOL) hasAptsForCurrentDate
-{
- return [[self aptsForCurrentDate] count] != 0;
-}
+// ASSIGN(self->allDayApts, filtered);
+// [filtered release];
+// return self->allDayApts;
+// }
+
+// - (BOOL) hasAptsForCurrentDate
+// {
+// return [[self aptsForCurrentDate] count] != 0;
+// }
- (NSString *) _dayNameWithOffsetFromToday: (int) offset
{
return self;
}
-- (id <WOActionResults>) updateCalendarsAction
-{
- WOResponse *response;
- NSUserDefaults *ud;
-
- ud = [[context activeUser] userDefaults];
- [ud setObject: [self queryParameterForKey: @"ids"]
- forKey: @"calendaruids"];
- [ud synchronize];
- response = [context response];
- [response setStatus: 200];
- [response setHeader: @"text/html; charset=\"utf-8\"" forKey: @"content-type"];
-
- return response;
-}
-
-- (NSString *) _rightsForUIDs: (NSString *) uids
-{
- NSEnumerator *ids;
- NSString *uid;
- NSMutableString *rights;
- SOGoAppointmentFolder *refFolder, *currentFolder;
- SoSecurityManager *securityManager;
- BOOL result;
-
- securityManager = [SoSecurityManager sharedSecurityManager];
- refFolder = [self clientObject];
-
- rights = [NSMutableString string];
- if ([uids length] > 0)
- {
- ids = [[uids componentsSeparatedByString: @","] objectEnumerator];
- uid = [ids nextObject];
- while (uid)
- {
- currentFolder
- = [refFolder
- lookupCalendarFolderForUID: (([uid hasPrefix: @"-"])
- ? [uid substringFromIndex: 1]
- : uid)];
- result = (![securityManager validatePermission: SoPerm_AccessContentsInformation
- onObject: currentFolder
- inContext: context]);
- if ([rights length] == 0)
- [rights appendFormat: @"%d", result];
- else
- [rights appendFormat: @",%d", result];
- uid = [ids nextObject];
- }
- }
-
- return rights;
-}
-
-- (id <WOActionResults>) checkRightsAction
-{
- WOResponse *response;
- NSUserDefaults *ud;
- NSString *uids, *rights;
-
- ud = [[context activeUser] userDefaults];
- uids = [ud stringForKey: @"calendaruids"];
-
- response = [context response];
- [response setStatus: 200];
- [response setHeader: @"text/plain; charset=\"utf-8\""
- forKey: @"content-type"];
-
- rights = [self _rightsForUIDs: uids];
- [response appendContentString: rights];
-
- return response;
-}
-
@end
+++ /dev/null
-/*
- Copyright (C) 2004 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.
- */
-
-#include <SOGoUI/UIxComponent.h>
-
-@class NSMutableArray;
-
-@interface UIxCalScheduleOverview : UIxComponent
-{
- NSMutableArray *userApts;
- NSMutableArray *foreignApts;
- id item;
- NSMutableArray *partNames;
- NSMutableArray *partStates;
- NSString *userParticipationStatus;
- unsigned participantIndex;
- unsigned userIndex;
-}
-
-- (NSCalendarDate *)startDate;
-- (NSCalendarDate *)endDate;
-
-- (NSArray *)userAppointments;
-- (NSArray *)foreignAppointments;
-
-- (BOOL)hasUserAppointments;
-- (BOOL)hasForeignAppointments;
-- (BOOL)hasAnyAppointments;
-
-- (void)fetchInfos;
-
-- (NSString *)appointmentBaseURL;
-
-- (unsigned)participantsCount;
-- (unsigned)maxRenderedParticipantsCount;
-- (unsigned)renderedParticipantsCount;
-- (unsigned)truncatedParticipantsCount;
-- (BOOL)didTruncateParticipants;
-
-- (NSString *)getUserPartStateFromApt:(id)_apt;
-
-- (BOOL)shouldIgnoreRejectedAppointments;
-- (BOOL)shouldIgnoreAcceptedAppointments;
-- (BOOL)shouldShowRejectedAndAcceptedAppointments;
-
-@end
-
-#include <NGObjWeb/SoComponent.h>
-#include "UIxComponent+Agenor.h"
-#include "SoObjects/Appointments/SOGoAppointmentFolder.h"
-#include "common.h"
-
-@implementation UIxCalScheduleOverview
-
-- (void)dealloc {
- [self->userApts release];
- [self->foreignApts release];
- [self->item release];
- [self->partNames release];
- [self->partStates release];
- [self->userParticipationStatus release];
- [super dealloc];
-}
-
-
-/* accessors */
-
-- (void)setItem:(id)_item {
- NSString *ps, *email;
- NSArray *partmails;
- unsigned idx;
-
- ASSIGN(self->item, _item);
-
- [self->partNames release];
- [self->partStates release];
- ps = [self->item valueForKey:@"participants"];
- self->partNames = [[ps componentsSeparatedByString:@"\n"] mutableCopy];
- ps = [self->item valueForKey:@"partstates"];
- self->partStates = [[ps componentsSeparatedByString:@"\n"] mutableCopy];
- ps = [self->item valueForKey:@"partmails"];
- partmails = [ps componentsSeparatedByString:@"\n"];
-
- /* reorder partNames/partStates */
-
- /* ensure organizer is first entry */
- email = [self->item valueForKey:@"orgmail"];
- if ([email isNotNull]) {
- idx = [partmails indexOfObject:email];
- if (idx != NSNotFound && idx != 0) {
- id obj;
-
- obj = [self->partNames objectAtIndex:idx];
- [self->partNames insertObject:obj atIndex:0]; /* frontmost */
- [self->partNames removeObjectAtIndex:idx + 1];
- obj = [self->partStates objectAtIndex:idx];
- [self->partStates insertObject:obj atIndex:0]; /* frontmost */
- [self->partStates removeObjectAtIndex:idx + 1];
- }
- }
- /* user is either second, first or none at all */
- [self->userParticipationStatus release];
- email = [self emailForUser];
- idx = [partmails indexOfObject:email];
- if (idx != NSNotFound && idx != 0 && idx != 1) {
- id obj;
-
- self->userIndex = 1;
- obj = [self->partNames objectAtIndex:idx];
- [self->partNames insertObject:obj atIndex:self->userIndex]; /* second */
- [self->partNames removeObjectAtIndex:idx + 1];
- obj = [self->partStates objectAtIndex:idx];
- [self->partStates insertObject:obj atIndex:self->userIndex]; /* second */
- [self->partStates removeObjectAtIndex:idx + 1];
- }
- else {
- self->userIndex = idx;
- }
- if (self->userIndex != NSNotFound)
- self->userParticipationStatus =
- [[self->partStates objectAtIndex:self->userIndex] retain];
- else
- self->userParticipationStatus = nil;
-}
-- (id)item {
- return self->item;
-}
-
-- (void)setParticipantIndex:(unsigned)_participantIndex {
- self->participantIndex = _participantIndex;
-}
-- (unsigned)participantIndex {
- return self->participantIndex;
-}
-
-- (unsigned)userIndex {
- return self->userIndex;
-}
-
-- (BOOL)isFirstParticipant {
- return self->participantIndex == 0 ? YES : NO;
-}
-
-- (BOOL)hasUserAppointments {
- // NOTE: this has been disabled for Agenor 0.8 on client's request
-#if 1
- return NO;
-#else
- return [[self userAppointments] count] > 0;
-#endif
-}
-- (BOOL)hasForeignAppointments {
- return [[self foreignAppointments] count] > 0;
-}
-- (BOOL)hasAnyAppointments {
- return ([self hasUserAppointments] ||
- [self hasForeignAppointments]) ? YES : NO;
-}
-
-- (unsigned)participantsCount {
- return [self->partNames count];
-}
-
-- (NSString *)participant {
- return [self->partNames objectAtIndex:self->participantIndex];
-}
-
-- (NSString *)participationStatus {
- return [self->partStates objectAtIndex:self->participantIndex];
-}
-
-- (unsigned)maxRenderedParticipantsCount {
- return 3;
-}
-
-- (unsigned)renderedParticipantsCount {
- if ([self didTruncateParticipants])
- return [self maxRenderedParticipantsCount];
- return [self participantsCount];
-}
-
-- (unsigned)truncatedParticipantsCount {
- return [self participantsCount] - [self renderedParticipantsCount];
-}
-
-- (BOOL)didTruncateParticipants {
- return [self participantsCount] >
- ([self maxRenderedParticipantsCount] + 1) ? YES : NO;
-}
-
-- (unsigned)rowspan {
- unsigned count;
-
- count = [self renderedParticipantsCount];
- if ([self didTruncateParticipants])
- count += 1;
- return count;
-}
-
-- (NSString *)userParticipationStatus {
- return self->userParticipationStatus;
-}
-
-- (BOOL)shouldIgnoreRejectedAppointments {
- return ![self shouldShowRejectedAndAcceptedAppointments];
-}
-
-- (BOOL)shouldIgnoreAcceptedAppointments {
- return ![self shouldShowRejectedAndAcceptedAppointments];
-}
-
-- (BOOL)shouldShowRejectedAndAcceptedAppointments {
- NSString *value;
-
- value = [[[self context] request] formValueForKey:@"dr"];
- if (!value) return NO;
- return [value boolValue];
-}
-
-- (NSString *)toggleShowHideAptsQueryParameter {
- BOOL shouldShow;
-
- shouldShow = [self shouldShowRejectedAndAcceptedAppointments];
- return shouldShow ? @"0" : @"1";
-}
-
-- (NSString *)toggleShowHideAptsText {
- if ([self shouldShowRejectedAndAcceptedAppointments])
- return @"Hide already accepted and rejected appointments";
- return @"Show already accepted and rejected appointments";
-}
-
-
-- (NSString *)getUserPartStateFromApt:(id)_apt {
- NSString *email;
- NSArray *ps, *pms;
- unsigned idx;
-
- email = [self emailForUser];
- pms = [[_apt valueForKey:@"partmails"]
- componentsSeparatedByString:@"\n"];
- idx = [pms indexOfObject:email];
- if (idx == NSNotFound) return nil;
- ps = [[_apt valueForKey:@"partstates"]
- componentsSeparatedByString:@"\n"];
- return [ps objectAtIndex:idx];
-}
-
-
-/* fetching */
-
-- (NSCalendarDate *)startDate {
- return [[NSCalendarDate date] beginOfDay];
-}
-
-/* ZNeK: is a month ok? */
-- (NSCalendarDate *)endDate {
- NSCalendarDate *date;
-
- date = [NSCalendarDate date];
- date = [date dateByAddingYears:0 months:1 days:0
- hours:0 minutes:0 seconds:0];
- date = [date endOfDay];
- return date;
-}
-
-- (NSArray *)userAppointments {
- if (!self->userApts) {
- [self fetchInfos];
- }
- return self->userApts;
-}
-
-- (NSArray *)foreignAppointments {
- if (!self->foreignApts) {
- [self fetchInfos];
- }
- return self->foreignApts;
-}
-
-- (void) fetchInfos {
- static NSArray *orders = nil;
- id aptFolder;
- NSArray *apts;
- NSString *userEmail;
- unsigned i, count;
-
- if (!orders) {
- EOSortOrdering *so;
- so = [EOSortOrdering sortOrderingWithKey:@"startDate"
- selector:EOCompareAscending];
- orders = [[NSArray alloc] initWithObjects:so, nil];
- }
-
- aptFolder = [self clientObject];
- apts = [aptFolder fetchCoreInfosFrom: [self startDate]
- to: [self endDate]
- component: @"vevent"];
- userEmail = [self emailForUser];
- count = [apts count];
-
- self->userApts = [[NSMutableArray alloc] initWithCapacity:count];
- self->foreignApts = [[NSMutableArray alloc] initWithCapacity:count];
-
- for (i = 0; i < count; i++) {
- id apt;
- NSString *orgEmail;
-
- apt = [apts objectAtIndex:i];
- orgEmail = [(NSDictionary *)apt objectForKey:@"orgmail"];
- if (orgEmail && [orgEmail isEqualToString:userEmail]) {
- [self->userApts addObject:apt];
- }
- else {
- BOOL shouldAdd = YES;
-
- if ([self shouldIgnoreAcceptedAppointments] ||
- [self shouldIgnoreRejectedAppointments])
- {
- NSString *userPartStat;
-
- userPartStat = [self getUserPartStateFromApt:apt];
- if (userPartStat) {
- if ([self shouldIgnoreAcceptedAppointments] &&
- [userPartStat isEqualToString:@"1"])
- shouldAdd = NO;
- else if ([self shouldIgnoreRejectedAppointments] &&
- [userPartStat isEqualToString:@"2"])
- shouldAdd = NO;
- }
- }
- if (shouldAdd)
- [self->foreignApts addObject:apt];
- }
- }
- [self->userApts sortUsingKeyOrderArray:orders];
- [self->foreignApts sortUsingKeyOrderArray:orders];
-}
-
-
-/* URLs */
-
-- (NSString *)appointmentBaseURL {
- id pkey;
-
- if (![(pkey = [self->item valueForKey:@"uid"]) isNotNull])
- return nil;
-
- return [[self clientObject] baseURLForAptWithUID:[pkey stringValue]
- inContext:[self context]];
-}
-- (NSString *)appointmentViewURL {
- return [[self appointmentBaseURL] stringByAppendingPathComponent:@"view"];
-}
-- (NSString *)acceptAppointmentURL {
- return [[self appointmentBaseURL] stringByAppendingPathComponent:@"accept"];
-}
-- (NSString *)declineAppointmentURL {
- return [[self appointmentBaseURL] stringByAppendingPathComponent:@"decline"];
-}
-
-
-/* access protection */
-
-- (BOOL)canAccess {
- NSString *owner;
-
- owner = [[self clientObject] ownerInContext:[self context]];
- if (!owner)
- return NO;
- return [[[[self context] activeUser] login] isEqualToString:owner];
-}
-
-@end
@interface UIxCalView : UIxComponent
{
NSArray *appointments;
+ NSMutableArray *calendarFolders;
NSMutableDictionary *componentsData;
NSArray *tasks;
NSArray *allDayApts;
= [[SOGoAptFormatter alloc] initWithDisplayTimeZone: tz];
[self configureFormatters];
componentsData = [NSMutableDictionary new];
+ calendarFolders = nil;
}
+
return self;
}
- (void) dealloc
{
+ [calendarFolders release];
[componentsData release];
[appointments release];
[allDayApts release];
return [[self startDate] tomorrow];
}
-- (NSArray *) activeCalendarFolders
+#warning We only support ONE calendar per user at this time
+- (BOOL) _appendSubscribedFolders: (NSDictionary *) subscribedFolders
{
- NSUserDefaults *ud;
- NSEnumerator *calendarUIDs;
- SOGoAppointmentFolder *currentFolder;
- NSMutableArray *folders;
- NSString *currentUID;
- SoSecurityManager *securityManager;
-
- securityManager = [SoSecurityManager sharedSecurityManager];
-
- folders = [NSMutableArray array];
- ud = [[context activeUser] userDefaults];
- calendarUIDs = [[[ud stringForKey: @"calendaruids"]
- componentsSeparatedByString: @","] objectEnumerator];
- currentUID = [calendarUIDs nextObject];
- while (currentUID)
+ NSEnumerator *keys;
+ NSString *currentKey;
+ NSMutableDictionary *currentCalendar;
+ BOOL firstShouldBeActive;
+ unsigned int count;
+
+ firstShouldBeActive = YES;
+
+ keys = [[subscribedFolders allKeys] objectEnumerator];
+ currentKey = [keys nextObject];
+ count = 1;
+ while (currentKey)
{
- if (![currentUID hasPrefix: @"-"])
- {
- currentFolder = [[self clientObject] lookupCalendarFolderForUID: currentUID];
- if (currentFolder
- && ![securityManager validatePermission: SoPerm_AccessContentsInformation
- onObject: currentFolder
- inContext: context])
- [folders addObject: currentFolder];
- }
- currentUID = [calendarUIDs nextObject];
+ 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;
+}
+
+- (void) _setupCalendarFolders
+{
+ NSMutableDictionary *userCalendar, *calendarDict;
+ SOGoUser *activeUser;
+ BOOL firstActive;
+
+ calendarFolders = [NSMutableArray new];
+ activeUser = [context activeUser];
+
+ userCalendar = [NSMutableDictionary new];
+ [userCalendar autorelease];
+ [userCalendar setObject: @"/" forKey: @"folder"];
+ [userCalendar setObject: [self labelForKey: @"Calendar"]
+ forKey: @"displayName"];
+ [calendarFolders addObject: userCalendar];
+
+ calendarDict = [[activeUser userSettings] objectForKey: @"Calendar"];
+ firstActive = [[calendarDict objectForKey: @"activateUserFolder"] boolValue];
+ firstActive = ([self _appendSubscribedFolders:
+ [calendarDict objectForKey: @"SubscribedFolders"]]
+ || firstActive);
+ [userCalendar setObject: [NSNumber numberWithBool: firstActive]
+ forKey: @"active"];
+}
+
+- (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder
+ withClientObject: (SOGoAppointmentFolder *) clientObject
+{
+ SOGoAppointmentFolder *aptFolder;
+ NSArray *folderParts;
+
+ if ([folder isEqualToString: @"/"])
+ aptFolder = clientObject;
+ else
+ {
+ folderParts = [folder componentsSeparatedByString: @":"];
+ aptFolder
+ = [clientObject lookupCalendarFolderForUID:
+ [folderParts objectAtIndex: 0]];
+ }
+
+ return aptFolder;
+}
+
+- (NSArray *) calendarFolders
+{
+ if (!calendarFolders)
+ [self _setupCalendarFolders];
+
+ return calendarFolders;
+}
+
+- (NSArray *) _activeCalendarFolders
+{
+ NSMutableArray *activeFolders;
+ NSEnumerator *folders;
+ NSDictionary *currentFolderDict;
+ SOGoAppointmentFolder *currentFolder, *clientObject;
+
+ activeFolders = [NSMutableArray new];
+ [activeFolders autorelease];
+
+ if (!calendarFolders)
+ [self _setupCalendarFolders];
+
+ clientObject = [self clientObject];
+
+ folders = [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 folders;
+ return activeFolders;
}
- (NSArray *) _fetchCoreInfosForComponent: (NSString *) component
if (!infos)
{
infos = [NSMutableArray array];
- folders = [[self activeCalendarFolders] objectEnumerator];
+ folders = [[self _activeCalendarFolders] objectEnumerator];
currentFolder = [folders nextObject];
while (currentFolder)
{
inContext: (WOContext *) _ctx
{
NSCalendarDate *now;
+ SOGoCalendarComponent *clientObject;
[super takeValuesFromRequest: _rq inContext: _ctx];
[component setUrl: url];
[self _handleAttendeesEdition];
[self _handleOrganizer];
- if ([[self clientObject] isNew])
+ clientObject = [self clientObject];
+ if ([clientObject isNew])
{
+ [component setUid: [clientObject nameInContainer]];
[component setCreated: now];
[component setTimeStampAsDate: now];
[component setPriority: @"0"];
else
{
[todo setCompleted: nil];
- [todo setPercentComplete: 0];
+ [todo setPercentComplete: @"0"];
[todo setStatus: @"IN-PROCESS"];
}
{
- requires = ( MAIN, CommonUI, Appointments, Contacts, ContactsUI );
+ requires = ( MAIN, MainUI, CommonUI, Appointments, Contacts, ContactsUI );
publicResources = (
previous_week.gif,
pageName = "UIxCalMainView";
actionName = "updateCalendars";
};
- checkRights = {
- protectedBy = "View";
- pageName = "UIxCalMainView";
- actionName = "checkRights";
- };
editAttendees = {
protectedBy = "View";
pageName = "UIxAttendeesEditor";
+++ /dev/null
-<?xml version='1.0' standalone='yes'?>
- <div
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:uix="OGo:uix"
- xmlns:label="OGo:label"
- xmlns:rsrc="OGo:url"
- class="calendar"
- >
- <input type="submit"
- class="button"
- label:value="Add Assistant"
- name="validate"
- onclick="return onConfirmContactSelection('assistant');" /><br />
- <input type="submit"
- class="button"
- label:value="Add Delegate"
- name="validate"
- onclick="return onConfirmContactSelection('delegate');" />
- </div>
+++ /dev/null
-<?xml version='1.0' standalone='yes'?>
- <div
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:uix="OGo:uix"
- xmlns:label="OGo:label"
- xmlns:rsrc="OGo:url"
- class="calendar"
- >
- <input type="submit"
- class="button"
- label:value="Add Address Book..."
- name="validate"
- onclick="return onConfirmAddressBookSelection();" />
- </div>
+++ /dev/null
-<?xml version='1.0' standalone='yes'?>
- <div
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:uix="OGo:uix"
- xmlns:label="OGo:label"
- xmlns:rsrc="OGo:url"
- class="calendar"
- >
- <input type="submit"
- class="button"
- label:value="Add Calendar..."
- name="validate"
- onclick="return onConfirmContactSelection(null);" />
- </div>
<div id="filterPanel">
<span class="searchBox" style="float: right">
<input id="searchCriteria" name="criteria" type="hidden" var:value="searchCriteria" />
- <input id="searchValue" class="textField" autocomplete="off" name="search" type="text" var:value="searchText" onmousedown="onSearchMouseDown(event, this);" onclick="popupSearchMenu(event, 'searchMenu');" onblur="onSearchBlur(this);" onfocus="onSearchFocus(this);" onkeydown="onSearchKeyDown(this);" />
+ <input id="searchValue" class="textField" autocomplete="off" name="search"
+ menuid="searchMenu"
+ type="text" var:value="searchText" />
</span>
</div>
</container>
/></span></a
></div><!-- var:if -->
- <ul id="contactFolders"
- var:additional-addressbooks="additionalAddressBooks">
+ <ul id="contactFolders">
<var:foreach list="contactFolders" item="currentFolder"
- ><var:if condition="isFolderCurrent"
- ><li var:id="currentContactFolderId" class="_selected"
- ><var:string value="currentContactFolderName" /></li
- ></var:if
- ><var:if condition="isFolderCurrent" const:negate="YES"
- ><li var:id="currentContactFolderId"
- ><var:string value="currentContactFolderName" /></li
- ></var:if>
- </var:foreach
+ ><li var:id="currentContactFolderId"
+ ><var:string value="currentContactFolderName" /></li
+ ></var:foreach
><var:foreach list="additionalFolders"
item="currentAdditionalFolder"
- ><li var:id="currentAdditionalFolder"
- var:external-addressbook="currentAdditionalFolder"
- ><var:string value="currentAdditionalFolder" /></li
+ ><li var:id="currentAdditionalFolder" class="denied"
+ ><var:string value="currentAdditionalFolderName" /></li
></var:foreach>
</ul>
<var:if condition="hideFrame">
<var:component-content />
</var:if>
-
- <script type="text/javascript">
- currentContactFolder = '<var:string value="contactFolderId" />';
- </script>
</var:component>
<?xml version='1.0' standalone='yes'?>
- <span
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:uix="OGo:uix"
- xmlns:label="OGo:label"
- xmlns:rsrc="OGo:url"
- >
- <span id="selectionLabel"><var:string label:value="Add as..." /></span><br />
- <input type="submit"
+<!DOCTYPE span>
+<span
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ xmlns:rsrc="OGo:url"
+ id="contactSelectionButtons">
+ <span id="selectionLabel"><var:string label:value="Add as..."/></span><br/>
+ <input type="submit"
+ class="button"
+ label:value="Recipient"
+ name="to"/><br/>
+ <input type="submit"
class="button"
- label:value="Recipient"
- name="to"
- onclick="return onConfirmContactSelection('to');" /><br />
- <input type="submit"
- class="button"
- label:value="Carbon Copy"
- name="cc"
- onclick="return onConfirmContactSelection('cc');" /><br />
- <input type="submit"
- class="button"
- label:value="Blind Carbon Copy"
- name="bcc"
- onclick="return onConfirmContactSelection('bcc');" />
- </span>
+ label:value="Carbon Copy"
+ name="cc"/><br/>
+ <input type="submit"
+ class="button"
+ label:value="Blind Carbon Copy"
+ name="bcc"/>
+</span>
--- /dev/null
+<?xml version='1.0' standalone='yes'?>
+<!DOCTYPE var:component>
+<var:component
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:rsrc="OGo:url"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ className="UIxPageFrame"
+ title="name"
+ const:toolbar="none"
+ const:popup="YES">
+ <script type="text/javascript" rsrc:src="dtree.js"><!-- space --></script>
+ <var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
+ <div id="folders">
+ </div>
+ <div id="buttons">
+ <input type="submit" id="addButton" class="button" label:value="Add..."/>
+ </div>
+</var:component>
<input id="searchValue"
class="textField"
autocomplete="off" name="search" type="text" var:value="searchText"
- onmousedown="onSearchMouseDown(event, this);"
- onclick="popupSearchMenu(event, 'searchMenu');"
- onchange="onSearchChange();"
- onblur="onSearchBlur(this);"
- onfocus="onSearchFocus(this);"
- onkeydown="onSearchKeyDown(this);" />
+ menuid="searchMenu" />
</span>
<var:string label:value="View:" />
+++ /dev/null
-<?xml version='1.0' standalone='yes'?>
-
-<table xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:rsrc="OGo:url"
- border="0"
- >
- <tr>
- <td align="right" valign="middle">
- <a var:href="^methodName" var:queryDictionary="^prevQueryParameters"><img rsrc:src="previous_week.gif" alt="previous" border="0"/></a>
- </td>
- <td align="right" valign="middle" class="button_auto_env">
- <a var:href="^methodName" var:queryDictionary="^currentQueryParameters" class="button_auto"><var:string value="^label" /></a>
- </td>
- <td align="right" valign="middle">
- <a var:href="^methodName" var:queryDictionary="^nextQueryParameters"><img rsrc:src="next_week.gif" alt="next" border="0"/></a>
- </td>
- </tr>
-</table>
+++ /dev/null
-<?xml version="1.0" standalone="yes"?>
- <container
- xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:rsrc="OGo:url"
- xmlns:label="OGo:label">
- <style type="text/css">
- <var:foreach list="contacts" item="currentContactPerson">
- .ownerIs<var:string value="currentContactLogin" />
- {
- background-color: <var:string value="currentContactSpanBG" /> !important;
- }
- </var:foreach>
- </style>
- <var:component className="UIxContactSelector"
- const:selectorId="calendarsList"
- const:hasCheckBoxes="YES"
- colors="colors"
- contacts="contacts"
- checkedBoxes="checkedContacts"
- />
- </container>
<var:foreach list="daysToDisplay" item="currentTableDay"
><div var:class="dayClasses"
var:day="currentTableDay.shortDateString"
- ><div class="header"><var:string value="labelForDay" /></div>
+ ><div class="header"><var:string value="labelForDay"
+ const:escapeHTML="NO"/></div>
<div class="appointments">
<var:foreach list="hoursToDisplay" item="currentTableHour"
><div var:class="clickableHourCellClass"
<input id="searchValue"
class="textField"
autocomplete="off" name="search" type="text" var:value="searchText"
- onmousedown="onSearchMouseDown(event, this);"
- onclick="popupSearchMenu(event, 'searchMenu');"
- onchange="onSearchChange();"
- onblur="onSearchBlur(this);"
- onfocus="onSearchFocus(this);"
- onkeydown="onSearchKeyDown(this);" />
+ menuid="searchMenu" />
</span>
<var:string label:value="View:" />
><var:component className="UIxCalDateSelector"
selectedDate="thisMonth"
/></div>
- <div id="calendarSelectorView"
- class="tab"
- ><var:component className="UIxCalCalendarsListView"
- /></div>
+ <div id="calendarSelectorView" class="tab"
+ ><var:component className="UIxCalendarSelector"
+ var:calendarFolders="calendarFolders" /></div>
</div>
<div id="tasksListView"
+++ /dev/null
-<?xml version='1.0' standalone='yes'?>
-
-<span xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:rsrc="OGo:url"
- xmlns:label="OGo:label"
->
- <table border="0"
- width="100%"
- cellpadding="2"
- cellspacing="0"
- class="schedoverview"
- >
- <tr>
- <th colspan="5" class="schedoverview titlefont titleheader">
- <var:string label:value="Schedule"/>
- <var:string value="startDate" label:dateformat="dayLabelFormat" /> -
- <var:string value="endDate" label:dateformat="dayLabelFormat" />
- </th>
- <!-- TODO: maybe enable this at a later stage
- <th colspan="2"
- class="titleheader button_auto_env defaultfont buttonheader">
- <a var:href="ownMethodName"
- var:queryDictionary="context.request.formValues"
- var:_dr="toggleShowHideAptsQueryParameter"
- class="button_auto"
- ><var:string label:value="$toggleShowHideAptsText"
- /></a>
- </th>
- -->
- </tr>
- <var:if condition="hasAnyAppointments" const:negate="YES">
- <tr>
- <td colspan="5">
- <var:string label:value="No appointments found"
- const:style="schedoverview"
- />
- </td>
- </tr>
- </var:if>
- <var:if condition="hasAnyAppointments">
- <var:if condition="hasUserAppointments">
- <tr>
- <!-- meetings proposed by user -->
- <th colspan="5" class="schedoverview_title">
- <var:string label:value="Meetings proposed by you" />
- </th>
- </tr>
- <tr>
- <th class="schedoverview"
- ><var:string label:value="Start date" /></th>
- <th class="schedoverview"
- ><var:string label:value="Title" /></th>
- <th class="schedoverview"
- colspan="2"
- ><var:string label:value="participants"/></th>
- </tr>
- <var:foreach list="userAppointments"
- item="item"
- >
- <var:foreach count="renderedParticipantsCount"
- index="participantIndex"
- >
- <tr>
- <var:if condition="isFirstParticipant">
- <td class="schedoverview"
- var:rowspan="rowspan"
- >
- <var:string value="item.startDate"
- label:dateformat="sched_startDateFormat"
- />
- </td>
- <td class="schedoverview"
- var:rowspan="rowspan"
- >
- <a var:href="appointmentViewURL"
- class="schedoverview"
- ><var:string value="item.title"
- const:escapeHTML="YES"
- /></a>
- </td>
- </var:if>
- <td class="schedoverview">
- <var:string value="participant" />
- </td>
- <td class="schedoverview">
- <var:component className="UIxCalParticipationStatusView"
- partStat="participationStatus"
- />
- </td>
- </tr>
- </var:foreach>
- <var:if condition="didTruncateParticipants">
- <tr>
- <td colspan="2" class="schedoverview">
- <a var:href="appointmentViewURL"
- class="schedoverview"
- ><var:string value="truncatedParticipantsCount" />
- <var:string label:value="more participants" />...
- </a>
- </td>
- </tr>
- </var:if>
- </var:foreach>
- </var:if>
- <var:if condition="hasForeignAppointments">
- <var:if condition="hasUserAppointments">
- <tr>
- <td><var:entity const:name="nbsp" /></td>
- </tr>
- </var:if>
- <!-- ZNeK: removed for Agenor 0.8 on client's request
- <tr>
- <th colspan="5" class="schedoverview_title">
- <var:string label:value="Meetings proposed to you" />
- </th>
- </tr>
- -->
- <tr>
- <th class="schedoverview"
- ><var:string label:value="Start date" /></th>
- <th class="schedoverview"
- ><var:string label:value="Title" /></th>
- <th class="schedoverview"
- colspan="2"
- ><var:string label:value="participants" /></th>
- <th class="schedoverview"
- ><var:string label:value="action" /></th>
- </tr>
- <var:foreach list="foreignAppointments"
- item="item"
- >
- <var:foreach count="renderedParticipantsCount"
- index="participantIndex"
- >
- <tr>
- <var:if condition="isFirstParticipant">
- <td class="schedoverview"
- var:rowspan="rowspan"
- >
- <var:string value="item.startDate"
- label:dateformat="sched_startDateFormat"
- />
- </td>
- <td class="schedoverview"
- var:rowspan="rowspan"
- >
- <a var:href="appointmentViewURL"
- class="schedoverview"
- ><var:string value="item.title"
- const:escapeHTML="YES"
- /></a>
- </td>
- </var:if>
- <td class="schedoverview">
- <var:string value="participant" />
- </td>
- <td class="schedoverview">
- <var:component className="UIxCalParticipationStatusView"
- partStat="participationStatus"
- />
- </td>
- <td class="schedoverview">
- <var:if-key const:key="participantIndex"
- value="userIndex"
- >
- <!-- TODO: exchange with inline updates -->
- <var:if-key const:key="userParticipationStatus"
- const:value="1"
- const:negate="YES"
- >
- <a var:href="acceptAppointmentURL"
- class="button_auto"
- ><var:string label:value="accept" /></a>
- </var:if-key>
- <!-- TODO: exchange with inline updates -->
- <var:if-key const:key="userParticipationStatus"
- const:value="2"
- const:negate="YES"
- >
- <a var:href="declineAppointmentURL"
- class="button_auto"
- ><var:string label:value="decline" /></a>
- </var:if-key>
- </var:if-key>
- </td>
- </tr>
- </var:foreach>
- <var:if condition="didTruncateParticipants">
- <tr>
- <td colspan="3" class="schedoverview">
- <a var:href="appointmentViewURL"
- class="schedoverview"
- ><var:string value="truncatedParticipantsCount" />
- <var:string label:value="more participants" />...
- </a>
- </td>
- </tr>
- </var:if>
- </var:foreach>
- </var:if>
- </var:if>
- </table>
-</span>
\ No newline at end of file
<?xml version="1.0" standalone="yes"?>
- <var:component xmlns="http://www.w3.org/1999/xhtml"
- xmlns:var="http://www.skyrix.com/od/binding"
- xmlns:const="http://www.skyrix.com/od/constant"
- xmlns:uix="OGo:uix"
- xmlns:label="OGo:label"
- className="UIxPageFrame"
- title="title"
- var:toolbar="toolbar"
- const:popup="YES">
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ xmlns:rsrc="OGo:url"
+ className="UIxPageFrame"
+ title="title"
+ var:toolbar="toolbar"
+ const:popup="YES">
- <form id="aclForm" const:href="saveAcls">
- <div class="acls">
- <input type="hidden" name="action" value="saveAcls" />
- <input type="hidden" name="delegates" var:value="delegatesValue"
- id="delegates" />
- <input type="hidden" name="assistants" var:value="assistantsValue"
- id="assistants" />
- <label><var:string label:value="Owner:" />
- <span class="value"><strong><var:string value="ownerCN" /></strong></span></label><br />
- <var:component className="UIxContactSelector"
- const:selectorId="userRoles"
- const:checkBoxOnChange="return updateAclStatus(this);"
- contacts="usersForFolder" />
- <select id="userRoleDropDown" name="currentUserRole">
- <option value="assistant"><var:string label:value="Assistant" /></option>
- <option value="delegate"><var:string label:value="Delegate" /></option>
- </select><br />
- <var:if condition="clientIsCalendar"
- ><label id="freeBusyLabel"><input type="checkbox"
- var:checked="publishInFreeBusy"
- class="checkBox" name="freebusy" id="freebusy"
- /><var:string label:value="Localizable/Publish the Free/Busy information"
- /></label></var:if>
+ <form id="aclForm" const:href="saveAcls">
+ <div class="acls">
+ <input type="hidden" name="action" value="saveAcls"/>
+ <input type="hidden" name="delegates" var:value="delegatesValue"
+ id="delegates"/>
+ <input type="hidden" name="assistants" var:value="assistantsValue"
+ id="assistants"/>
+ <label><var:string label:value="Owner:"/><br/>
+ <span class="value"><strong><var:string value="ownerName"/></strong></span></label><br/>
+
+ <!-- var:component className="UIxContactSelector"
+ const:checkBoxOnChange="return updateAclStatus(this);"
+ contacts="usersForFolder" -->
+
+ <div class="userSelector" id="userRoles">
+ <span id="userSelectorButtons">
+ <a href="#"
+ class="button"><img rsrc:src="add-contact.gif"
+ label:title="Add..."
+ /></a>
+ <a href="#"
+ class="button"><img rsrc:src="remove-contact.gif"
+ label:title="Remove"
+ /></a>
+ </span>
+ <input type="hidden"
+ var:id="selectorIdList"
+ var:name="selectorId"
+ var:value="initialContactsAsString"/>
+ <ul id="userList" multiselect="yes">
+ <var:foreach list="usersForFolder" item="currentUser"
+ ><li var:id="currentUser">
+ <img rsrc:src="abcard.gif"/>
+ <var:string value="currentUserDisplayName"/></li>
+ </var:foreach>
+ </ul>
</div>
- </form>
- </var:component>
+
+ <select id="userRoleDropDown" name="currentUserRole">
+ <option value="assistant"><var:string label:value="Assistant"/></option>
+ <option value="delegate"><var:string label:value="Delegate"/></option>
+ </select><br/>
+ <var:if condition="clientIsCalendar"
+ ><label id="freeBusyLabel"><input type="checkbox"
+ var:checked="publishInFreeBusy"
+ class="checkBox" name="freebusy" id="freebusy"
+ /><var:string label:value="Localizable/Publish the Free/Busy information"
+ /></label></var:if>
+ </div>
+ </form>
+</var:component>
-/*
- Copyright (C) 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.
-*/
-/* JavaScript for SOGo Mailer */
-
-/*
- DOM ids available in mail list view:
- row_$msgid
- div_$msgid
- readdiv_$msgid
- unreaddiv_$msgid
-
- Window Properties:
- width, height
- bool: resizable, scrollbars, toolbar, location, directories, status,
- menubar, copyhistory
-*/
+/* JavaScript for SOGoContacts */
var cachedContacts = new Array();
-var currentContactFolder = '';
-var currentFolderIsExternal = false;
-var contactSelectorAction = 'addressbooks-contacts';
+var currentContactFolder = '/personal';
function openContactWindow(sender, url) {
var msgWin = window.open(url, null, "width=450,height=600,resizable=0");
msgWin.focus();
}
-function clickedUid(sender, contactuid) {
- resetSelection(window);
- openContactWindow(sender, contactuid,
- CurrentContactFolderURL()
- + "/" + contactuid + "/edit");
- return true;
-}
-
-function doubleClickedUid(sender, contactuid) {
- alert("DOUBLE Clicked " + contactuid);
-
- return false;
-}
-
-function toggleMailSelect(sender) {
- var row;
- row = $(sender.name);
- row.className = sender.checked ? "tableview_selected" : "tableview";
-}
-
-/* mail editor */
-
function validateEditorInput(sender) {
var errortext = "";
var field;
return true;
}
-function onContactsFolderTreeItemClick(element) {
- var topNode = $('d');
- var contactsFolder = element.parentNode.getAttribute("dataname");
-
- if (topNode.selectedEntry)
- topNode.selectedEntry.deselect();
- element.select();
- topNode.selectedEntry = element;
-
- openContactsFolder(contactsFolder);
-}
-
-function CurrentContactFolderURL() {
- return ((currentFolderIsExternal)
- ? UserFolderURL + "../" + currentContactFolder + "/Contacts/personal"
- : ApplicationBaseURL + currentContactFolder);
-}
-
-function openContactsFolder(contactsFolder, params, external) {
+function openContactsFolder(contactsFolder, params) {
if (contactsFolder != currentContactFolder || params) {
if (contactsFolder == currentContactFolder) {
var contactsList = $("contactsList");
selection = null;
currentContactFolder = contactsFolder;
- if (external)
- currentFolderIsExternal = true;
- else
- currentFolderIsExternal = false;
- var url = CurrentContactFolderURL() + "/view?noframe=1&sort=cn&desc=0";
+ var url = URLForFolderID(currentContactFolder) +
+ "/view?noframe=1&sort=cn&desc=0";
if (params)
url += '&' + params;
function openContactsFolderAtIndex(element) {
var idx = element.getAttribute("idx");
- var url = CurrentContactFolderURL() + "/view?noframe=1&idx=" + idx;
+ var url = URLForFolderID(currentContactFolder) + "/view?noframe=1&idx=" + idx;
if (document.contactsListAjaxRequest) {
document.contactsListAjaxRequest.aborted = true;
div.innerHTML = cachedContacts[currentContactFolder + "/" + idx];
}
else {
- var url = (CurrentContactFolderURL() + "/"
- + idx + "/view?noframe=1");
+ var url = (URLForFolderID(currentContactFolder)
+ + "/" + idx + "/view?noframe=1");
document.contactAjaxRequest
= triggerAjaxRequest(url, contactLoadCallback, idx);
}
var contactId = node.getAttribute('id');
openContactWindow(null,
- CurrentContactFolderURL()
+ URLForFolderID(currentContactFolder)
+ "/" + contactId + "/edit");
return false;
var contactId = node.getAttribute('id');
openContactWindow(null,
- CurrentContactFolderURL()
+ URLForFolderID(currentContactFolder)
+ "/" + contactId + "/edit");
return false;
var node = getParentMenu(node).menuTarget.parentNode;
var contactId = node.getAttribute('id');
- openMailComposeWindow(CurrentContactFolderURL()
+ openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+ "/" + contactId + "/write");
return false;
for (var i = 0; i < rows.length; i++) {
openContactWindow(null,
- CurrentContactFolderURL()
+ URLForFolderID(currentContactFolder)
+ "/" + rows[i] + "/edit");
}
var rows = contactsList.getSelectedRowsId();
for (var i = 0; i < rows.length; i++)
- openMailComposeWindow(CurrentContactFolderURL()
+ openMailComposeWindow(ApplicationBaseURL + currentContactFolder
+ "/" + rows[i] + "/write");
return false;
/* send AJAX request (synchronously) */
- url = (CurrentContactFolderURL() + "/"
+ url = (URLForFolderID(currentContactFolder) + "/"
+ rows[i] + "/delete");
http = createHTTPClient();
http.open("POST", url, false /* not async */);
}
if (failCount > 0)
- alert("Could not delete " + failCount + " messages!");
+ alert("Could not delete the selected contacts!");
return false;
}
document.contactsListAjaxRequest.aborted = true;
document.contactsListAjaxRequest.abort();
}
- url = CurrentContactFolderURL() + "/" + this.link;
+ url = URLForFolderID(currentContactFolder) + "/" + this.link;
if (!this.link.match(/noframe=/))
url += "&noframe=1";
document.contactsListAjaxRequest
function newContact(sender) {
openContactWindow(sender,
- CurrentContactFolderURL() + "/new");
+ URLForFolderID(currentContactFolder) + "/new");
return false; /* stop following the link */
}
function onFolderSelectionChange() {
- var folderList = $("contactFolders");
- var nodes = folderList.getSelectedNodes();
- $("contactView").innerHTML = '';
-
- if (nodes[0].hasClassName("denied")) {
- var div = $("contactsListContent");
- div.innerHTML = "";
- }
- else {
- var newFolder;
- var externalFolder = nodes[0].getAttribute("external-addressbook");
- if (externalFolder)
- newFolder = externalFolder;
- else
- newFolder = nodes[0].getAttribute("id");
-
- openContactsFolder(newFolder, null, externalFolder);
- }
+ var folderList = $("contactFolders");
+ var nodes = folderList.getSelectedNodes();
+ $("contactView").innerHTML = '';
+
+ if (nodes[0].hasClassName("denied")) {
+ var div = $("contactsListContent");
+ div.innerHTML = "";
+ }
+ else
+ openContactsFolder(nodes[0].getAttribute("id"), null);
}
function onSearchFormSubmit() {
var searchValue = $("searchValue");
- openContactsFolder(currentContactFolder, "search=" + searchValue.value);
+ openContactsFolder(URLForFolderID(currentContactFolder),
+ "search=" + searchValue.value);
return false;
}
-function onConfirmContactSelection(tag) {
- var folderLi = $(currentContactFolder);
- var currentContactFolderName = folderLi.innerHTML;
- var selectorList = null;
- var initialValues = null;
+function onConfirmContactSelection(event) {
+ var tag = this.getAttribute("name");
+ var folderLi = $(currentContactFolder);
+ var currentContactFolderName = folderLi.innerHTML;
+ var selectorList = null;
+ var initialValues = null;
- if (selector)
- {
+ if (selector) {
var selectorId = selector.getAttribute("id");
selectorList = opener.window.document.getElementById('uixselector-'
+ selectorId
+ '-uidList');
initialValues = selectorList.value;
- }
-
- var contactsList = $("contactsList");
- var rows = contactsList.getSelectedRows();
- for (i = 0; i < rows.length; i++) {
- var cid = rows[i].getAttribute("contactid");
- var cname = '' + rows[i].getAttribute("contactname");
- var email = '' + rows[i].cells[1].innerHTML;
- opener.window.addContact(tag, currentContactFolderName + '/' + cname,
- cid, cname, email);
- }
-
- if (selector && selector.changeNotification
- && selectorList.value != initialValues)
- selector.changeNotification("addition");
-
- return false;
-}
-
-function onConfirmAddressBookSelection() {
- var folderLi = $(currentContactFolder);
- var currentContactFolderName = folderLi.innerHTML;
-
- var selector = window.opener.document.getElementById("contactFolders");
- var initialValues = selector.getAttribute("additional-addressbooks");
- if (!initialValues)
- initialValues = "";
- var newValues = initialValues;
-
- var contactsList = $("contactsList");
- var rows = contactsList.getSelectedRows();
- for (i = 0; i < rows.length; i++) {
- var cid = rows[i].getAttribute("contactid");
- var cname = '' + rows[i].getAttribute("contactname");
- var email = '' + rows[i].cells[1].innerHTML;
- var re = new RegExp("(^|,)" + cid + "($|,)");
- if (!re.test(newValues)) {
- if (newValues.length)
- newValues += "," + cid;
- else
- newValues = cid;
- }
- }
-
- if (newValues != initialValues)
- window.opener.setTimeout("setAdditionalAddressBooks(\""
- + newValues + "\");", 100);
+ }
- return false;
-}
+ var contactsList = $("contactsList");
+ var rows = contactsList.getSelectedRows();
+ for (i = 0; i < rows.length; i++) {
+ var cid = rows[i].getAttribute("contactid");
+ var cname = '' + rows[i].getAttribute("contactname");
+ var email = '' + rows[i].cells[1].innerHTML;
+ opener.window.addContact(tag, currentContactFolderName + '/' + cname,
+ cid, cname, email);
+ }
-function setAdditionalAddressBooks(additionalAddressBooks) {
- var urlstr = (ApplicationBaseURL + "/updateAdditionalAddressBooks?ids="
- + additionalAddressBooks);
- if (document.addressBooksAjaxRequest) {
- document.addressBooksAjaxRequest.aborted = true;
- document.addressBooksAjaxRequest.abort();
- }
- document.addressBooksAjaxRequest
- = triggerAjaxRequest(urlstr,
- addressBooksCallback, additionalAddressBooks);
-}
+ if (selector && selector.changeNotification
+ && selectorList.value != initialValues)
+ selector.changeNotification("addition");
-function addressBooksCallback(http) {
- if (http.readyState == 4) {
- if (http.status == 200) {
- var ul = $("contactFolders");
-
- var children = ul.childNodesWithTag("li");
- for (var i = 0; i < children.length; i++)
- if (children[i].getAttribute("external-addressbook"))
- ul.removeChild(children[i]);
-
- ul.setAttribute("additional-addressbooks", http.callbackData);
- if (http.callbackData.length > 0) {
- var list = http.callbackData.split(",");
- var newCode = "";
- for (var i = 0; i < list.length; i++) {
- var username = list[i];
- newCode += ( "<li external-addressbook=\"" + username + "\""
- + " onmousedown=\"return false;\""
- + " onclick=\"return onRowClick(event);\""
- + " oncontextmenu=\"return onContactFolderContextMenu(event);\">" );
- newCode += ( username + "</li>" );
- }
- ul.innerHTML += newCode;
- }
- }
- document.addressBooksAjaxRequest = null;
- }
- else
- log ("ajax fuckage 3");
+ event.preventDefault();
}
function onContactMailTo(node) {
}
function refreshContacts(contactId) {
- openContactsFolder(currentContactFolder, "reload=true", currentFolderIsExternal);
+ openContactsFolder(currentContactFolder, "reload=true");
cachedContacts[currentContactFolder + "/" + contactId] = null;
loadContact(contactId);
event.preventDefault();
}
+function appendAddressBook(name, folder) {
+ var li = document.createElement("li");
+ li.setAttribute("id", folder);
+ li.appendChild(document.createTextNode(name));
+ li.addEventListener("mousedown", listRowMouseDownHandler, false);
+ li.addEventListener("click", onRowClick, false);
+ li.addEventListener("contextmenu", onContactFoldersContextMenu, false);
+ $("contactFolders").appendChild(li);
+}
+
function newAbCallback(http) {
if (http.readyState == 4
&& http.status == 201) {
- var ul = $("contactFolders");
var name = http.callbackData;
- var li = document.createElement("li");
- li.setAttribute("id", "/" + name);
- li.appendChild(document.createTextNode(name));
- li.addEventListener("mousedown", listRowMouseDownHandler, false);
- li.addEventListener("click", onRowClick, false);
- li.addEventListener("contextmenu", onContactFoldersContextMenu, false);
- ul.appendChild(li);
+ appendAddressBook(name, "/" + name);
}
else
log ("ajax fuckage 4:" + http.status);
}
+function newUserFolderCallback(folderData) {
+ var folder = $(folderData["folder"]);
+ if (!folder)
+ appendAddressBook(folderData["folderName"], folderData["folder"]);
+}
+
function onAddressBookAdd(event) {
- var selector = $("contactFolders");
- var selectorURL = '?popup=YES&selectorId=contactFolders';
-
- urlstr = ApplicationBaseURL;
- if (urlstr[urlstr.length-1] != '/')
- urlstr += '/';
- urlstr += ("../../" + UserLogin + "/Contacts/"
- + contactSelectorAction + selectorURL);
-// log (urlstr);
- var w = window.open(urlstr, "Addressbook",
- "width=640,height=400,resizable=1,scrollbars=0");
- w.selector = selector;
- w.opener = window;
- w.focus();
+ openUserFolderSelector(newUserFolderCallback, "contact");
- event.preventDefault();
+ event.preventDefault();
+}
+
+function onFolderUnsubscribeCB(folderId) {
+ var node = $(folderId);
+ node.parentNode.removeChild(node);
+ var personal = $("/personal");
+ personal.select();
+ onFolderSelectionChange();
}
function onAddressBookRemove(event) {
var selector = $("contactFolders");
var nodes = selector.getSelectedNodes();
- if (nodes.length > 0) {
- var cid = nodes[0].getAttribute("external-addressbook");
- if (cid) {
- var initialValues = selector.getAttribute("additional-addressbooks");
- var re = new RegExp("(^|,)" + cid + "($|,)");
- var newValues = initialValues.replace(re, "");
- if (initialValues != newValues)
- setAdditionalAddressBooks(newValues);
- }
- else {
- nodes[0].deselect();
- var folderId = nodes[0].getAttribute("id").substr(1);
- deletePersonalAddressBook(folderId);
- }
-
- var personal = $("/personal");
- personal.select();
- onFolderSelectionChange();
+ 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();
+ }
}
event.preventDefault();
}
function lookupDeniedFolders() {
- var rights;
- var http = createHTTPClient();
- if (http) {
- http.url = ApplicationBaseURL + "/checkRights";
- http.open("GET", http.url, false /* not async */);
- http.send("");
- if (http.status == 200
- && http.responseText.length > 0) {
- rights = http.responseText.split(",");
- }
+ var list = $("contactFolders").childNodesWithTag("li");
+ for (var i = 0; i < list.length; i++) {
+ var folderID = list[i].getAttribute("id");
+ var url = URLForFolderID(folderID) + "/canAccessContent";
+ triggerAjaxRequest(url, deniedFoldersLookupCallback, folderID);
}
+}
- return rights;
+function deniedFoldersLookupCallback(http) {
+ if (http.readyState == 4) {
+ var denied = true;
+
+ if (http.status == 200)
+ denied = (http.responseText == "0");
+ var entry = $(http.callbackData);
+ if (denied)
+ entry.addClassName("denied");
+ else
+ entry.removeClassName("denied");
+ }
}
function configureAbToolbar() {
lis[i].addEventListener("contextmenu", onContactFoldersContextMenu, false);
}
- var denieds = lookupDeniedFolders();
- if (denieds) {
- var start = (lis.length - denieds.length);
- for (var i = start; i < lis.length; i++) {
- if (denieds[i-start] == "1")
- lis[i].removeClassName("denied");
- else
- lis[i].addClassName("denied");
- }
- }
+ lookupDeniedFolders();
contactFolders.style.visibility = "visible;";
+
+ var personalFolder = $("/personal");
+ personalFolder.select();
}
}
function onAccessRightsMenuEntryMouseUp(event) {
var folders = $("contactFolders");
var selected = folders.getSelectedNodes()[0];
- var external = selected.getAttribute("external-addressbook");
var title = this.innerHTML;
- if (external)
- url = UserFolderURL + "../" + external + "/Contacts/personal/acls";
- else
- url = ApplicationBaseURL + selected.getAttribute("id") + "/acls";
+ var url = URLForFolderID(selected.getAttribute("id"))
- openAclWindow(url, title);
+ openAclWindow(url + "/acls", title);
}
function initializeMenus() {
menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
}
+function configureSearchField() {
+ var searchValue = $("searchValue");
+
+ searchValue.addEventListener("mousedown", onSearchMouseDown, false);
+ searchValue.addEventListener("click", popupSearchMenu, false);
+ searchValue.addEventListener("blur", onSearchBlur, false);
+ searchValue.addEventListener("focus", onSearchFocus, false);
+ searchValue.addEventListener("keydown", onSearchKeyDown, false);
+}
+
+function configureSelectionButtons() {
+ var container = $("contactSelectionButtons");
+ if (container) {
+ var buttons = container.childNodesWithTag("input");
+ for (var i = 0; i < buttons.length; i++)
+ buttons[i].addEventListener("click", onConfirmContactSelection,
+ false);
+ }
+}
+
var initContacts = {
handleEvent: function (event) {
if (!document.body.hasClassName("popup")) {
configureAbToolbar();
+ configureSearchField();
}
+ else
+ configureSelectionButtons();
configureContactFolders();
// initDnd();
}
font-style: italic;
}
-/* folder tree (js) )*/
-DIV.dTreeNode A SPAN.nodeName
-{
- margin: 0px .2em;
- padding-left: .2em;
- padding-right: .2em;
-}
-
-DIV.dTreeNode A._selected SPAN.nodeName
-{
- background: #4b6983;
- color: #fff;
-}
-
-DIV.dTreeNode SPAN._dragOver
-{
- background: #4b6983;
- color: #fff;
-}
-
/* drag-n-drop */
IMG.dragMessage
{
-/*
- Copyright (C) 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.
-*/
-/* JavaScript for SOGo Mailer */
-
-/*
- DOM ids available in mail list view:
- row_$msgid
- div_$msgid
- readdiv_$msgid
- unreaddiv_$msgid
-
- Window Properties:
- width, height
- bool: resizable, scrollbars, toolbar, location, directories, status,
- menubar, copyhistory
-*/
+/* JavaScript for SOGoMail */
var currentMessages = new Array();
var maxCachedMessages = 20;
}
}
-var initMailer = {
- handleEvent: function (event) {
- if (!document.body.hasClassName("popup")) {
- var inboxFound = false;
- configureMessageListEvents();
- initDnd();
- var tree = $("d");
- var nodes = document.getElementsByClassName("node", tree);
- for (i = 0; i < nodes.length; i++) {
- nodes[i].addEventListener("click", onMailboxTreeItemClick, false);
- nodes[i].addEventListener("contextmenu", onFolderMenuClick, false);
- if (!inboxFound
- && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
- openInbox(nodes[i]);
- inboxFound = true;
- }
- }
- }
-
- /*
-, 'onMailboxTreeItemClick(this);'
-<!-- if (typeof(node.datatype) != "undefined") str += ' oncontextmenu="onFolderMenuClick(event, this);"';
+function configureSearchField() {
+ var searchValue = $("searchValue");
- */
+ searchValue.addEventListener("mousedown", onSearchMouseDown, false);
+ searchValue.addEventListener("click", popupSearchMenu, false);
+ searchValue.addEventListener("blur", onSearchBlur, false);
+ searchValue.addEventListener("focus", onSearchFocus, false);
+ searchValue.addEventListener("keydown", onSearchKeyDown, false);
+}
- }
+var initMailer = {
+ handleEvent: function (event) {
+ if (!document.body.hasClassName("popup")) {
+ configureSearchField();
+ var inboxFound = false;
+ configureMessageListEvents();
+ initDnd();
+ var tree = $("d");
+ var nodes = document.getElementsByClassName("node", tree);
+ for (i = 0; i < nodes.length; i++) {
+ nodes[i].addEventListener("click", onMailboxTreeItemClick, false);
+ nodes[i].addEventListener("contextmenu", onFolderMenuClick, false);
+ if (!inboxFound
+ && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
+ openInbox(nodes[i]);
+ inboxFound = true;
+ }
+ }
+ }
+
+ /*
+ , 'onMailboxTreeItemClick(this);'
+ <!-- if (typeof(node.datatype) != "undefined") str += ' oncontextmenu="onFolderMenuClick(event, this);"';
+
+ */
+ }
}
function initializeMenus() {
+++ /dev/null
-/*
- Copyright (C) 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.
- */
-/* JavaScript for SOGo Homepage */
-
-function toggleInternetAccessState(sender) {
-// var form = document.getElementById("syncDefaultsForm");
-// document.syncDefaultsForm.action="saveInternetAccessState:method";
-// form.submit();
- this.postInternetAccessState(sender, sender.value);
- return true;
-}
-
-function postInternetAccessState(sender, state) {
- var url;
- var http = createHTTPClient();
-
- url = "edit?allowinternet=" + state;
-
- if (http) {
- http.open("POST", url, false);
- http.send("");
- if (http.status != 200) {
- alert("Failed to change state: " + http.statusText);
- window.location.reload();
- }
- }
- else {
- alert("Unable to retrieve HTTPClient object!");
- window.location.href = url;
- }
-}
+
DIV#leftPanel
{
position: absolute;
DIV#tasksListView LABEL
{ margin: .25em; }
+DIV#calendarSelectorView
+{ top: 0px; }
+
DIV#calendarsList
{ height: 100%;
padding: 0px;
margin: 0px; }
-SPAN.colorBox
-{ display: block;
- float: right;
+DIV.colorBox
+{ display: inline;
border: 1px solid #333;
- margin: .12em;
+ font-weight: normal;
+ margin: 0px;
+ font-size: 80%;
width: 1em;
height: .75em; }
-UL#tasksList, UL#uixselector-calendarsList-display
+UL#tasksList, UL#calendarList
{ cursor: default;
margin: .25px;
padding: 0px;
list-style-type: none;
list-style-image: none; }
-UL#uixselector-calendarsList-display
-{ height: 10.5em;
+UL#calendarList
+{ clear: both;
+ height: 10.5em;
margin: 0px; }
-UL#uixselector-calendarsList-display LI.denied
-{ background: #fefefe;
+UL#calendarList LI
+{ white-space: nowrap; }
+
+UL#calendarList LI.denied
+{ background-color: #fefefe;
font-style: italic;
color: #f33; }
{ cursor: default;
position: absolute;
left: 0px;
- right: 0px;
+ right: 1px;
padding: 1px; }
DIV[class~="appointment"]._selected > DIV.appointmentInside
cursor: default;
white-space: nowrap;
margin: 2px;
+ margin-right: 3px;
padding: 1px;
height: 1.5em; }
-DIV.monthView DIV.appointment DIV.text
+DIV.appointment DIV.text
{ font-size: 80%; }
DIV.daysView DIV[class~="appointment"].starts0
+/* JavaScript for SOGoCalendar */
+
var sortOrder = '';
var sortKey = '';
var listFilter = 'view_today';
return false;
}
-function updateCalendarStatus() {
+function updateCalendarStatus(event) {
var list = new Array();
- var clist = $("calendarsList");
- var nodes = clist.childNodesWithTag("ul")[0].childNodesWithTag("li");
+ var nodes = $("calendarList").childNodesWithTag("li");
for (var i = 0; i < nodes.length; i++) {
var input = nodes[i].childNodesWithTag("input")[0];
- if (input.checked)
- list.push(nodes[i].getAttribute("uid"));
+ if (input.checked) {
+ var folderId = nodes[i].getAttribute("id");
+ var elems = folderId.split(":");
+ if (elems.length > 1)
+ list.push(elems[0]);
+ else
+ list.push(UserLogin);
+ }
}
if (!list.length) {
- list.push(nodes[0].getAttribute("uid"));
- nodes[0].childNodesWithTag("input")[0].checked = true;
+ list.push(UserLogin);
+ nodes[0].childNodesWithTag("input")[0].checked = true;
}
// ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
-// + list.join(",") + "/Calendar/");
-
- updateCalendarsList();
- refreshAppointments();
- refreshTasks();
- changeCalendarDisplay();
+// + list.join(",") + "/Calendar/");
+
+ if (event) {
+ var folderID = this.parentNode.getAttribute("id");
+ var urlstr = URLForFolderID(folderID);
+ if (this.checked)
+ urlstr += "/activateFolder";
+ else
+ urlstr += "/deactivateFolder";
+ triggerAjaxRequest(urlstr, calendarStatusCallback, folderID);
+ }
+ else {
+ updateCalendarsList();
+ refreshAppointments();
+ refreshTasks();
+ changeCalendarDisplay();
+ }
return false;
}
-function calendarUidsList() {
- var list = "";
-
- var nodes = $("uixselector-calendarsList-display").childNodesWithTag("li");
- for (var i = 0; i < nodes.length; i++) {
- var currentNode = nodes[i];
- var input = currentNode.childNodesWithTag("input")[0];
- if (!input.checked)
- list += "-";
- list += currentNode.getAttribute("uid") + ",";
- }
-
- return list.substr(0, list.length - 1);
-}
-
-// function updateCalendarContacts(contacts)
-// {
-// var list = contacts.split(",");
-
-// var clist = $("calendarsList");
-// var nodes = clist.childNodes[5].childNodes;
-// for (var i = 0; i < nodes.length; i++) {
-// var currentNode = nodes[i];
-// if (currentNode instanceof HTMLLIElement) {
-// var input = currentNode.childNodes[3];
-// if (!input.checked)
-// list += "-";
-// list += currentNode.getAttribute("uid") + ",";
-// }
-// }
-// }
-
-function inhibitMyCalendarEntry() {
- var clist = $("calendarsList");
- var nodes = clist.childNodes[5].childNodes;
- var done = false;
-
- var i = 0;
- while (!done && i < nodes.length) {
- var currentNode = nodes[i];
- if (currentNode instanceof HTMLLIElement) {
- var input = currentNode.childNodes[3];
- if (currentNode.getAttribute("uid") == UserLogin) {
- done = true;
-// currentNode.style.color = "#999;";
- currentNode.style.fontWeight = "bold;";
-// currentNode.setAttribute("onclick", "");
+function calendarStatusCallback(http) {
+ if (http.readyState == 4) {
+ if (http.status == 204) {
+ refreshAppointments();
+ refreshTasks();
+ changeCalendarDisplay();
}
- }
- i++;
- }
+ else {
+ var folder = $(http.callbackData);
+ var input = folder.childNodesWithTag("input")[0];
+ input.checked = (!input.checked);
+ }
+ }
}
-function userCalendarEntry(user, color) {
- var li = document.createElement("li");
- li.setAttribute("uid", user);
- li.addEventListener("mousedown", listRowMouseDownHandler, false);
- li.addEventListener("click", onRowClick, false);
- var colorBox = document.createElement("span");
- colorBox.addClassName("colorBox");
- if (color) {
- log("color: " + color);
- colorBox.style.backgroundColor = color + ";";
- }
- li.appendChild(colorBox);
- var checkBox = document.createElement("input");
- checkBox.addClassName("checkBox");
- checkBox.type = "checkbox";
- checkBox.addEventListener("change", updateCalendarStatus, false);
- li.appendChild(checkBox);
- var text = document.createTextNode(" " + user);
- li.appendChild(text);
-
- return li;
-}
-
-function ensureSelfIfPresent() {
- var ul = $("uixselector-calendarsList-display");
- var list = ul.childNodesWithTag("li");
- var selfEntry = userCalendarEntry(UserLogin, indexColor(0));
- selfEntry.style.fontWeight = "bold;";
- if (list.length < 1) {
- ul.appendChild(selfEntry);
- } else if (list[0].getAttribute("uid") != UserLogin) {
- ul.insertBefore(selfEntry, list[0]);
- }
+function calendarEntryCallback(http) {
+ var disabled = true;
+
+ if (http.readyState == 4) {
+ if (http.status == 200)
+ disabled = (http.responseText == "0");
+ var entry = $(http.callbackData);
+ var input = entry.childNodesWithTag("input")[0];
+ input.disabled = disabled;
+ if (disabled) {
+ input.checked = false;
+ entry.addClassName("denied");
+ }
+ else
+ entry.removeClassName("denied");
+ }
}
function updateCalendarsList(method) {
- ensureSelfIfPresent();
- var url = (ApplicationBaseURL + "updateCalendars?ids="
- + calendarUidsList());
- if (document.calendarsListAjaxRequest) {
- document.calendarsListAjaxRequest.aborted = true;
- document.calendarsListAjaxRequest.abort();
- }
- var http = createHTTPClient();
- if (http) {
- http.url = url;
- http.open("GET", url, false);
- http.send("");
-
- if (method == "removal")
- updateCalendarStatus();
-
- http = createHTTPClient();
- http.url = ApplicationBaseURL + "checkRights";
- http.open("GET", http.url, false /* not async */);
- http.send("");
- if (http.status == 200
- && http.responseText.length > 0) {
- rights = http.responseText.split(",");
- var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
- for (var i = 0; i < list.length; i++) {
- var input = list[i].childNodesWithTag("input")[0];
- if (rights[i] == "1") {
- list[i].removeClassName("denied");
- input.disabled = false;
- }
- else {
- input.checked = false;
- input.disabled = true;
- list[i].addClassName("denied");
- }
- }
- }
+ var list = $("calendarList").childNodesWithTag("li");
+ for (var i = 0; i < list.length; i++) {
+ var folderID = list[i].getAttribute("id");
+ var url = URLForFolderID(folderID) + "/canAccessContent";
+ triggerAjaxRequest(url, calendarEntryCallback, folderID);
}
}
uids.value += ',' + contactId;
else
uids.value = contactId;
- var names = $("uixselector-calendarsList-display");
+ var names = $("calendarList");
var listElems = names.childNodesWithTag("li");
var colorDef = indexColor(listElems.length);
names.appendChild(userCalendarEntry(contactId, colorDef));
- var styles = document.getElementsByTagName("style");
- styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
- + ' background-color: '
- + colorDef
- + ' !important; }');
}
}
"appointmentsListMenu", "calendarsMenu", "searchMenu");
initMenusNamed(menus);
- $("calendarsList").attachMenu("calendarsMenu");
+ $("calendarSelector").attachMenu("calendarsMenu");
var accessRightsMenuEntry = $("accessRightsMenuEntry");
accessRightsMenuEntry.addEventListener("mouseup",
}
function onAccessRightsMenuEntryMouseUp(event) {
- var folders = $("uixselector-calendarsList-display");
+ var folders = $("calendarList");
var selected = folders.getSelectedNodes()[0];
- var uid = selected.getAttribute("uid");
- log("application base url: " + ApplicationBaseURL);
- if (uid == UserLogin)
- url = ApplicationBaseURL + "acls";
- else
- url = UserFolderURL + "../" + uid + "/Calendar/acls";
+ var folderID = selected.getAttribute("id");
+ var urlstr = URLForFolderID(folderID) + "/acls";
- openAclWindow(url, uid);
+ openAclWindow(urlstr);
}
function configureDragHandles() {
}
}
-function initCalendarContactsSelector() {
- var selector = $("calendarsList");
- inhibitMyCalendarEntry();
+function initCalendarSelector() {
+ var selector = $("calendarSelector");
updateCalendarStatus();
selector.changeNotification = updateCalendarsList;
- var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
+ var list = $("calendarList").childNodesWithTag("li");
for (var i = 0; i < list.length; i++) {
var input = list[i].childNodesWithTag("input")[0];
input.addEventListener("change", updateCalendarStatus, false);
+ list[i].addEventListener("mousedown", listRowMouseDownHandler, false);
+ list[i].addEventListener("click", onRowClick, false);
+// list[i].addEventListener("contextmenu", onContactFoldersContextMenu, false);
+ }
+
+ var links = $("calendarSelectorButtons").childNodesWithTag("a");
+ links[0].addEventListener("click", onCalendarAdd, false);
+ links[1].addEventListener("click", onCalendarRemove, false);
+}
+
+function onCalendarAdd(event) {
+ openUserFolderSelector(onFolderSubscribeCB, "calendar");
+
+ event.preventDefault();
+}
+
+function appendCalendar(folderName, folder) {
+ var calendarList = $("calendarList");
+ var lis = calendarList.childNodesWithTag("li");
+ var color = indexColor(lis.length);
+ log ("color: " + color);
+ var li = document.createElement("li");
+ li.setAttribute("id", folder);
+ li.addEventListener("mousedown", listRowMouseDownHandler, false);
+ li.addEventListener("click", onRowClick, false);
+ var checkBox = document.createElement("input");
+ checkBox.addClassName("checkBox");
+ checkBox.type = "checkbox";
+ checkBox.addEventListener("change", updateCalendarStatus, false);
+ li.appendChild(checkBox);
+ var colorBox = document.createElement("div");
+ colorBox.appendChild(document.createTextNode("OO"));
+ colorBox.addClassName("colorBox");
+ if (color) {
+ colorBox.style.color = color + ";";
+ colorBox.style.backgroundColor = color + ";";
+ }
+ li.appendChild(colorBox);
+ li.appendChild(document.createTextNode(folderName));
+
+ calendarList.appendChild(li);
+
+ var contactId = folder.split(":")[0];
+ var styles = document.getElementsByTagName("style");
+ styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
+ + ' color: '
+ + color + ';'
+ + ' background-color: '
+ + color
+ + ' !important; }');
+}
+
+function onFolderSubscribeCB(folderData) {
+ var folder = $(folderData["folder"]);
+ if (!folder)
+ appendCalendar(folderData["folderName"], folderData["folder"]);
+}
+
+function onFolderUnsubscribeCB(folderId) {
+ var node = $(folderId);
+ node.parentNode.removeChild(node);
+}
+
+function onCalendarRemove(event) {
+ var nodes = $("calendarList").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);
+ }
}
+
+ event.preventDefault();
}
-function initCalendars() {
- if (!document.body.hasClassName("popup"))
- initCalendarContactsSelector();
+function configureSearchField() {
+ var searchValue = $("searchValue");
+
+ searchValue.addEventListener("mousedown", onSearchMouseDown, false);
+ searchValue.addEventListener("click", popupSearchMenu, false);
+ searchValue.addEventListener("blur", onSearchBlur, false);
+ searchValue.addEventListener("focus", onSearchFocus, false);
+ searchValue.addEventListener("keydown", onSearchKeyDown, false);
}
-function onSchedulerBodyKeyUp(event) {
- if (event.which == 46) {
- window.alert("coucou");
- deleteEvent();
- event.cancelBubble = true;
+function initCalendars() {
+ if (!document.body.hasClassName("popup")) {
+ initCalendarSelector();
+ configureSearchField();
}
}
window.addEventListener("load", initCalendars, false);
-// document.body.addEventListener("keyup", onSchedulerBodyKeyUp, false);
{ padding: 1em; }
DIV.acls LABEL
-{ position: relative;
- white-space: normal;
+{ white-space: nowrap;
width: 100%; }
-DIV.acls LABEL > SPAN.value
-{ position: absolute;
- top: 0px;
- left: 11em; }
-
DIV.acls UL
{ height: 100%;
width: 100%; }
{ height: 7em;
padding-bottom: 2em; }
-UL#uixselector-userRoles-display
+UL#userList
{ cursor: default;
margin: .25px;
padding: 0px;
list-style-type: none;
list-style-image: none; }
-UL#uixselector-userRoles-display > LI._selected
+UL#userList > LI._selected
{
background: #4b6983 !important;
color: #fff !important;
var contactSelectorAction = 'acls-contacts';
-function addContact(tag, fullContactName, contactId, contactName,
- contactEmail) {
- if (tag == "assistant")
- addUser(contactName, contactId, false);
- else if (tag == "delegate")
- addUser(contactName, contactId, true);
-}
-
-function addUser(userName, userId, delegate) {
- var uidList = $("uixselector-userRoles-uidList");
- var uids;
-
- if (uidList.value.length > 0) {
- uids = uidList.value.split(",");
- } else {
- uids = new Array();
- }
-
- if (uids.indexOf(userId) < 0) {
- uids.push(userId);
- var ul = $("uixselector-userRoles-display");
- ul.appendChild(nodeForUser(userName, userId));
- uidList.value = uids.join(",");
- var roleList;
- if (delegate)
- roleList = $("delegates");
- else
- roleList = $("assistants");
+function addUser(userName, userID) {
+ if (!$(userID)) {
+ var ul = $("userList");
+ ul.appendChild(nodeForUser(userName, userID));
+ var roleList = $("assistants");
if (roleList.value.length > 0) {
- uids = roleList.value.split(",");
- uids.push(userId);
- roleList.value = uids.join(",");
+ var uids = roleList.value.split(",");
+ uids.push(userID);
+ roleList.value = uids.join(",");
}
else
- roleList.value = userId;
+ roleList.value = userID;
}
}
function nodeForUser(userName, userId) {
var node = document.createElement("li");
- node.setAttribute("uid", userId);
+ node.setAttribute("id", userId);
node.setAttribute("class", "");
node.addEventListener("mousedown", listRowMouseDownHandler, true);
node.addEventListener("click", onRowClick, true);
select.style.visibility = "visible;";
var selected = selection[0];
var assistantsValue = $("assistants");
- var uid = selected.getAttribute("uid");
+ var uid = selected.getAttribute("id");
var regexp = new RegExp("(^|,)" + uid + "(,|$)","i");
if (regexp.test(assistantsValue.value))
select.selectedIndex = 0;
updateSelectedRole(this);
}
-function onUsersChange(type) {
- var select = $("userRoleDropDown");
- if (type == "removal") {
- var list;
- if (select.selectedIndex == 0)
- list = $("assistants");
- else
- list = $("delegates");
-
- var uids = $("uixselector-userRoles-uidList");
- var listArray = list.value.split(",");
- var newListArray = new Array();
- for (var i = 0; i < listArray.length; i++) {
- var regexp = new RegExp("(^|,)" + listArray[i] + "($|,)");
- if (regexp.test(uids.value))
- newListArray.push(listArray[i]);
- }
- if (newListArray.length > 0)
- list.value = newListArray.join(",");
- else
- list.value = "";
- }
-
- updateSelectedRole($("uixselector-userRoles-display"));
-}
-
function onUserRoleDropDownChange() {
var oldList;
var newList;
newList = $("delegates");
}
- var uid = $("uixselector-userRoles-display").getSelectedRows()[0].getAttribute("uid");
+ var uid = $("userList").getSelectedRows()[0].getAttribute("id");
var newListArray;
if (newList.value.length > 0) {
newListArray = newList.value.split(",");
log("delegates: " + $("delegates").value);
}
-function onAclLoadHandler() {
- $("userRoles").changeNotification = onUsersChange;
+function onUserAdd(event) {
+ openUserFolderSelector(null, "user");
+
+ event.preventDefault();
+}
+
+function onUserRemove(event) {
+ var userlist = $("userList");
+ var node = userlist.getSelectedRows()[0];
+ var uid = node.getAttribute("id");
+ var regexp = new RegExp("(^|,)" + uid + "($|,)");
+ var uids = $("assistants");
+ if (!regexp.test(uids.value))
+ uids = $("delegates");
+ if (regexp.test(uids.value)) {
+ var list = uids.value.split(",");
+ var newList = new Array();
+ for (var i = 0; i < list.length; i++) {
+ if (list[i] != uid)
+ newList.push(list[i]);
+ }
+ uids.value = newList.join(",");
+ node.parentNode.removeChild(node);
+ }
+ updateSelectedRole(userlist);
+ event.preventDefault();
+}
- var ul = $("uixselector-userRoles-display");
+function subscribeToFolder(refreshCallback, refreshCallbackData) {
+ addUser(refreshCallbackData["folderName"],
+ refreshCallbackData["folder"]);
+}
+
+function onAclLoadHandler() {
+ var ul = $("userList");
ul.addEventListener("selectionchange",
onAclSelectionChange, false);
+ var lis = ul.childNodesWithTag("li");
+ for (var i = 0; i < lis.length; i++) {
+ lis[i].addEventListener("mousedown", listRowMouseDownHandler, false);
+ lis[i].addEventListener("click", onRowClick, false);
+ }
+
var select = $("userRoleDropDown");
select.addEventListener("change", onUserRoleDropDownChange, false);
+
+ var buttons = $("userSelectorButtons").childNodesWithTag("a");
+ buttons[0].addEventListener("click", onUserAdd, false);
+ buttons[1].addEventListener("click", onUserRemove, false);
}
window.addEventListener("load", onAclLoadHandler, false);
--- /dev/null
+DIV#filterPanel
+{ position: absolute;
+ text-align: center;
+ width: auto;
+ top: 1em;
+ left: 1em;
+ right: 1em; }
+
+SPAN.searchBox
+{ float: none !important; }
+
+INPUT#searchValue
+{ margin: 0px; }
+
+DIV#folders
+{ position: absolute;
+ left: 1em;
+ right: 1em;
+ top: 3em;
+ bottom: 3em;
+ background-color: #fff;
+ padding: .5em;
+ padding-top: 0px;
+ overflow: auto;
+ border-bottom: 1px solid #fff;
+ border-right: 1px solid #fff;
+ border-top: 2px solid #222;
+ border-left: 2px solid #222;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent; }
+
+DIV#folders DIV
+{ width: auto; }
+
+DIV#buttons
+{ position: absolute;
+ text-align: center;
+ height: 1.5em;
+ left: 1em;
+ right: 1em;
+ bottom: 1em; }
--- /dev/null
+function onSearchFormSubmit() {
+ var searchValue = $("searchValue");
+
+ var url = (ApplicationBaseURL
+ + "/foldersSearch?ldap-only=YES&search=" + searchValue.value
+ + "&type=" + window.userFolderType);
+ if (document.userFoldersRequest) {
+ document.userFoldersRequest.aborted = true;
+ document.userFoldersRequest.abort();
+ }
+ document.userFoldersRequest
+ = triggerAjaxRequest(url, userFoldersCallback);
+
+ return false;
+}
+
+function addLineToTree(tree, parent, line) {
+ var offset = 0;
+
+ var nodes = line.split(";");
+ if (window.userFolderType == "user"
+ || nodes.length > 1) {
+ var parentNode = nodes[0];
+ var userInfos = parentNode.split(":");
+ var email = userInfos[1].replace("<", "<");
+ tree.add(parent, 0, email, 0, '#', userInfos[0], 'person',
+ '', '',
+ ResourcesURL + '/abcard.gif',
+ ResourcesURL + '/abcard.gif');
+ for (var i = 1; i < nodes.length; i++) {
+ var folderInfos = nodes[i].split(":");
+ var icon = ResourcesURL + '/';
+ if (folderInfos[2] == 'contact')
+ icon += 'tb-mail-addressbook-flat-16x16.png';
+ else
+ icon += 'calendar-folder-16x16.png';
+ var folderId = userInfos[0] + ":" + folderInfos[1];
+ tree.add(parent + i, parent, folderInfos[0], 0, '#', folderId,
+ folderInfos[2] + '-folder', '', '', icon, icon);
+ }
+ offset = nodes.length - 1;
+ }
+ else
+ window.alert("nope:" + window.userFolderType);
+
+ return offset;
+}
+
+function buildTree(response) {
+ d = new dTree("d");
+ d.config.folderLlinks = true;
+ d.config.hideRoot = true;
+ d.icon.root = ResourcesURL + '/tbtv_account_17x17.gif';
+ d.icon.folder = ResourcesURL + '/tbtv_leaf_corner_17x17.gif';
+ d.icon.folderOpen = ResourcesURL + '/tbtv_leaf_corner_17x17.gif';
+ d.icon.node = ResourcesURL + '/tbtv_leaf_corner_17x17.gif';
+ d.icon.line = ResourcesURL + '/tbtv_line_17x17.gif';
+ d.icon.join = ResourcesURL + '/tbtv_junction_17x17.gif';
+ d.icon.joinBottom = ResourcesURL + '/tbtv_corner_17x17.gif';
+ d.icon.plus = ResourcesURL + '/tbtv_plus_17x17.gif';
+ d.icon.plusBottom = ResourcesURL + '/tbtv_corner_plus_17x17.gif';
+ d.icon.minus = ResourcesURL + '/tbtv_minus_17x17.gif';
+ d.icon.minusBottom = ResourcesURL + '/tbtv_corner_minus_17x17.gif';
+ d.icon.nlPlus = ResourcesURL + '/tbtv_corner_plus_17x17.gif';
+ d.icon.nlMinus = ResourcesURL + '/tbtv_corner_minus_17x17.gif';
+ d.icon.empty = ResourcesURL + '/empty.gif';
+ d.add(0, -1, '');
+
+ var lines = response.split("\n");
+ var offset = 0;
+ for (var i = 0; i < lines.length; i++) {
+ if (lines[i].length > 0)
+ offset += addLineToTree(d, i + 1 + offset, lines[i]);
+ }
+
+ return d;
+}
+
+function onFolderTreeItemClick(event) {
+ event.preventDefault();
+
+ var topNode = $("d");
+ if (topNode.selectedEntry)
+ topNode.selectedEntry.deselect();
+ this.select();
+ topNode.selectedEntry = this;
+}
+
+function userFoldersCallback(http) {
+ if (http.readyState == 4) {
+ document.userFoldersRequest = null;
+ if (http.status == 200) {
+ var div = $("folders");
+ var response = http.responseText;
+ div.innerHTML = buildTree(http.responseText);
+ var nodes = document.getElementsByClassName("node", $("d"));
+ for (i = 0; i < nodes.length; i++)
+ nodes[i].addEventListener("click",
+ onFolderTreeItemClick, false);
+ }
+ }
+}
+
+function onConfirmFolderSelection(event) {
+ var topNode = $("d");
+ if (topNode.selectedEntry) {
+ var node = topNode.selectedEntry.parentNode;
+ var folder = node.getAttribute("dataname");
+ var folderName;
+ if (window.userFolderType == "user") {
+ var spans = document.getElementsByClassName("nodeName",
+ topNode.selectedEntry);
+ var email = spans[0].innerHTML;
+ email = email.replace("<", "<");
+ email = email.replace(">", ">");
+ folderName = email;
+ }
+ else {
+ var spans1 = document.getElementsByClassName("nodeName",
+ node);
+ var spans2 = document.getElementsByClassName("nodeName",
+ node.parentNode.previousSibling);
+ var email = spans2[0].innerHTML;
+ email = email.replace("<", "<");
+ email = email.replace(">", ">");
+ folderName = spans1[0].innerHTML + ' (' + email + ')';
+ }
+ var data = { folderName: folderName, folder: folder };
+ window.opener.subscribeToFolder(window.userFolderCallback, data);
+ }
+}
+
+function initUserFoldersWindow() {
+ configureSearchField();
+ $("addButton").addEventListener("click", onConfirmFolderSelection, false);
+}
+
+window.addEventListener("load", initUserFoldersWindow, false);
var contactSelectorAction = 'mailer-contacts';
+function onContactAdd() {
+ var selector = null;
+ var selectorURL = '?popup=YES&selectorId=mailer-contacts';
+
+ urlstr = ApplicationBaseURL;
+ if (urlstr[urlstr.length-1] != '/')
+ urlstr += '/';
+ urlstr += ("../../" + UserLogin + "/Contacts/"
+ + contactSelectorAction + selectorURL);
+// log (urlstr);
+ var w = window.open(urlstr, "Addressbook",
+ "width=640,height=400,resizable=1,scrollbars=0");
+ w.selector = selector;
+ w.opener = this;
+ w.focus();
+
+ return false;
+ }
+
function addContact(tag, fullContactName, contactId, contactName, contactEmail) {
if (!mailIsRecipient(contactEmail)) {
var neededOptionValue = 0;
{ color: #999;
background: inherit; }
+/* folder tree (js) )*/
+DIV.dTreeNode A SPAN.nodeName
+{
+ margin: 0px .2em;
+ padding-left: .2em;
+ padding-right: .2em;
+}
+
+DIV.dTreeNode A._selected SPAN.nodeName
+{
+ background: #4b6983;
+ color: #fff;
+}
+
+DIV.dTreeNode SPAN._dragOver
+{
+ background: #4b6983;
+ color: #fff;
+}
+
/* tabs */
DIV.tabsContainer
{
return url;
}
+function URLForFolderID(folderID) {
+ var folderInfos = folderID.split(":");
+ var url;
+ if (folderInfos.length > 1) {
+ url = UserFolderURL + "../" + folderInfos[0];
+ if (folderInfos[1][0] != '/')
+ url += '/';
+ url += folderInfos[1];
+ }
+ else
+ url = ApplicationBaseURL + folderInfos[0];
+
+ if (url[url.length-1] == '/')
+ url = url.substr(0, url.length-1);
+
+ return url;
+}
+
function extractEmailAddress(mailTo) {
var email = "";
return mailto;
}
+function openUserFolderSelector(callback, type) {
+ var urlstr = ApplicationBaseURL;
+ if (urlstr[urlstr.length-1] != '/')
+ urlstr += '/';
+ urlstr += ("../../" + UserLogin + "/Contacts/userFolders");
+ var w = window.open(urlstr, "User Selector",
+ "width=322,height=250,resizable=1,scrollbars=0");
+ w.opener = window;
+ w.userFolderCallback = callback;
+ w.userFolderType = type;
+ w.focus();
+}
+
function openMailComposeWindow(url) {
var w = window.open(url, null,
"width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
}
/* search field */
-function popupSearchMenu(event, menuId) {
+function popupSearchMenu(event) {
var node = event.target;
+
+ var menuId = this.getAttribute("menuid");
relX = event.pageX - node.cascadeLeftOffset();
relY = event.pageY - node.cascadeTopOffset();
log ("onSearchChange()...");
}
-function onSearchMouseDown(event, searchValue) {
- superNode = searchValue.parentNode.parentNode.parentNode;
- relX = (event.pageX - superNode.offsetLeft - searchValue.offsetLeft);
- relY = (event.pageY - superNode.offsetTop - searchValue.offsetTop);
+function onSearchMouseDown(event) {
+ var superNode = this.parentNode.parentNode.parentNode;
+ relX = (event.pageX - superNode.offsetLeft - this.offsetLeft);
+ relY = (event.pageY - superNode.offsetTop - this.offsetTop);
- if (relY < 24) {
- event.cancelBubble = true;
- event.returnValue = false;
- }
+ if (relY < 24) {
+ event.cancelBubble = true;
+ event.returnValue = false;
+ }
}
-function onSearchFocus(searchValue) {
- ghostPhrase = searchValue.getAttribute("ghost-phrase");
- if (searchValue.value == ghostPhrase) {
- searchValue.value = "";
- searchValue.setAttribute("modified", "");
+function onSearchFocus() {
+ ghostPhrase = this.getAttribute("ghost-phrase");
+ if (this.value == ghostPhrase) {
+ this.value = "";
+ this.setAttribute("modified", "");
} else {
- searchValue.select();
+ this.select();
}
- searchValue.style.color = "#000";
+ this.style.color = "#000";
}
-function onSearchBlur(searchValue) {
- var ghostPhrase = searchValue.getAttribute("ghost-phrase");
-// log ("search blur: '" + searchValue.value + "'");
- if (!searchValue.value) {
- searchValue.setAttribute("modified", "");
- searchValue.style.color = "#aaa";
- searchValue.value = ghostPhrase;
- } else if (searchValue.value == ghostPhrase) {
- searchValue.setAttribute("modified", "");
- searchValue.style.color = "#aaa";
+function onSearchBlur(event) {
+ var ghostPhrase = this.getAttribute("ghost-phrase");
+// log ("search blur: '" + this.value + "'");
+ if (!this.value) {
+ this.setAttribute("modified", "");
+ this.style.color = "#aaa";
+ this.value = ghostPhrase;
+ } else if (this.value == ghostPhrase) {
+ this.setAttribute("modified", "");
+ this.style.color = "#aaa";
} else {
- searchValue.setAttribute("modified", "yes");
- searchValue.style.color = "#000";
+ this.setAttribute("modified", "yes");
+ this.style.color = "#000";
}
}
-function onSearchKeyDown(searchValue) {
- if (searchValue.timer)
- clearTimeout(searchValue.timer);
+function onSearchKeyDown(event) {
+ if (this.timer)
+ clearTimeout(this.timer);
- searchValue.timer = setTimeout("onSearchFormSubmit()", 1000);
+ this.timer = setTimeout("onSearchFormSubmit()", 1000);
}
function initCriteria() {
/* contact selector */
-function onContactAdd(node) {
- var selector = null;
- var selectorURL = '?popup=YES';
- if (node) {
- selector = node.parentNode.parentNode;
- selectorURL += ("&selectorId=" + selector.getAttribute("id"));
- }
-
- urlstr = ApplicationBaseURL;
- if (urlstr[urlstr.length-1] != '/')
- urlstr += '/';
- urlstr += ("../../" + UserLogin + "/Contacts/"
- + contactSelectorAction + selectorURL);
-// log (urlstr);
- var w = window.open(urlstr, "Addressbook",
- "width=640,height=400,resizable=1,scrollbars=0");
- w.selector = selector;
- w.opener = this;
- w.focus();
-
- return false;
+function folderSubscriptionCallback(http) {
+ if (http.readyState == 4) {
+ if (http.status == 204) {
+ if (http.callbackData)
+ http.callbackData["method"](http.callbackData["data"]);
+ }
+ else
+ window.alert(labels["Unable to subscribe to that folder!"].decodeEntities());
+ document.subscriptionAjaxRequest = null;
+ }
+ else
+ log ("ajax fuckage");
+}
+
+function subscribeToFolder(refreshCallback, refreshCallbackData) {
+ var folderData = refreshCallbackData["folder"].split(":");
+ var username = folderData[0];
+ var folderPath = folderData[1];
+ if (username != UserLogin) {
+ var url = (UserFolderURL + "../" + username
+ + "/" + folderPath + "/subscribe");
+ if (document.subscriptionAjaxRequest) {
+ document.subscriptionAjaxRequest.aborted = true;
+ document.subscriptionAjaxRequest.abort();
+ }
+ var rfCbData = { method: refreshCallback, data: refreshCallbackData };
+ document.subscriptionAjaxRequest = triggerAjaxRequest(url,
+ folderSubscriptionCallback,
+ rfCbData);
+ }
+ else
+ window.alert(labels["You cannot subscribe to a folder that you own!"].decodeEntities());
}
-function onContactRemove(node) {
- var selector = node.parentNode.parentNode;
- var selectorId = selector.getAttribute("id");
- var hasChanged = false;
-
- var names = $('uixselector-' + selectorId + '-display');
- var nodes = names.getSelectedNodes();
- hasChanged = (nodes.length > 0);
- for (var i = 0; i < nodes.length; i++) {
- var currentNode = nodes[i];
- currentNode.parentNode.removeChild(currentNode);
- }
-
- var uids = $('uixselector-' + selectorId + '-uidList');
- nodes = node.parentNode.childNodes;
- var ids = new Array();
- for (var i = 0; i < nodes.length; i++)
- if (nodes[i] instanceof HTMLLIElement)
- ids.push(nodes[i].getAttribute("uid"));
- uids.value = ids.join(",");
-
- if (selector.changeNotification && hasChanged)
- selector.changeNotification("removal");
+function folderUnsubscriptionCallback(http) {
+ if (http.readyState == 4) {
+ if (http.status == 204) {
+ if (http.callbackData)
+ http.callbackData["method"](http.callbackData["data"]);
+ }
+ else
+ window.alert(labels["Unable to unsubscribe from that folder!"].decodeEntities());
+ document.unsubscriptionAjaxRequest = null;
+ }
+}
- return false;
+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);
+ }
+ else
+ window.alert(labels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
+ }
}
function listRowMouseDownHandler(event) {
return false;
}
-function openAclWindow(url, objectTitle) {
+function openAclWindow(url) {
var w = window.open(url, "aclWindow",
"width=300,height=300,resizable=1,scrollbars=1,toolbar=0,"
+ "location=0,directories=0,status=0,menubar=0"
+ ",copyhistory=0");
+ w.opener = window;
w.focus();
- w.title = "Poil: " + objectTitle;
return w;
}