+2007-02-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+ -appendPersonalSourcesInContext:context]): release connectoin
+ channel when everything is done.
+
+ * UI/Contacts/UIxContactFoldersView.m ([UIxContactFoldersView
+ -newAbAction]): new action method to crate a new contact folder
+ from the web UI.
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -create]): new method
+ that requests the folder manager to create a folder table with the
+ specified type at the specified path. The type is taken from [self
+ folderType].
+
+ * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder
+ -folderType]): implemented.
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -folderType]): implemented.
+
+ * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+ -appendPersonalSourcesInContext:context]): we now fetch all
+ folders with type "Contact" that belong to the current user.
+ ([SOGoContactFolders -newFolderWithName:name]): new method to
+ create a new contact folder.
+
+ * UI/SOGoUI/UIxComponent.m ([UIxComponent -userFolderPath]): treat
+ resulting url with [NSString+Utilities hostlessURL] instead of
+ using NSURL. This is because the url in question sometimes has a
+ hostname and sometimes not. "hostlessURL" ensure the hostname is
+ removed anyway.
+ ([UIxComponent -applicationPath]): same as above.
+
+2007-02-08 Ludovic Marcotte <ludovic@inverse.ca>
+
+ * SoObjects/Mailer/SOGoMailFolder.m: priorize the lookup of
+ folders before doing the one on messages.
+
2007-02-08 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/NSArray+Utilities.m: added an implementation of
2007-02-07 Ludovic Marcotte <ludovic@inverse.ca>
- * UI/Scheduler/English.lproj/Localizable.strings
- Fixed typo for "Agendas"
-
+ * UI/Scheduler/English.lproj/Localizable.strings: fixed typo for
+ "Agendas"
2007-02-05 Wolfgang Sourdeau <wsourdeau@inverse.ca>
extractorClassName = "OCSiCalFieldExtractor";
fields = (
+ {
+ columnName = c_name;
+ sqlType = "VARCHAR(256)";
+ allowsNull = NO;
+ },
{
columnName = uid;
sqlType = "VARCHAR(256)";
extractorClassName= "OCSContactFieldExtractor";
fields = (
+ {
+ columnName = c_name;
+ sqlType = "VARCHAR(256)";
+ allowsNull = NO;
+ },
{
columnName = givenname;
sqlType = "VARCHAR(256)";
+++ /dev/null
---
--- (C) 2005 SKYRIX Software AG
---
--- TODO:
--- add a unique constraints on path
-
--- DROP TABLE SOGo_folder_info;
-
-CREATE TABLE SOGo_folder_info (
- c_folder_id INTEGER PRIMARY KEY,
- c_path VARCHAR(255) NOT NULL, /* the full path to the folder */
- c_path1 VARCHAR(255) NOT NULL, /* parts (for fast queries) */
- c_path2 VARCHAR(255) NULL, /* parts (for fast queries) */
- c_path3 VARCHAR(255) NULL, /* parts (for fast queries) */
- c_path4 VARCHAR(255) NULL, /* parts (for fast queries) */
- c_foldername VARCHAR(255) NOT NULL, /* last path component */
- c_location VARCHAR(2048) NOT NULL, /* URL to folder */
- c_quick_location VARCHAR(2048) NULL, /* URL to quicktable of folder */
- c_folder_type VARCHAR(255) NOT NULL /* the folder type ... */
-);
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users',
- 'Users',
- NULL,
- NULL,
- NULL,
- 'Users',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_user_folder_blob',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_user_folder_quick',
- 'Container' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/helge',
- 'Users',
- 'helge',
- NULL,
- NULL,
- 'helge',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_user_folder_blob',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_user_folder_quick',
- 'Container' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/helge/Calendar',
- 'Users',
- 'helge',
- 'Calendar',
- NULL,
- 'Calendar',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_helge_privcal_blob',
- 'sqlite://localhost/tmp/sogo-registry.sqlite/SOGo_helge_privcal_quick',
- 'Appointment' );
+++ /dev/null
-/*
- (C) 2005 SKYRIX Software AG
-*/
-
-DROP TABLE SOGo_helge_privcal_quick;
-DROP TABLE SOGo_helge_privcal;
-
-CREATE TABLE SOGo_helge_privcal_quick (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- uid VARCHAR(256) NOT NULL,
- startdate INT NOT NULL,
- enddate INT NOT NULL,
- cycleenddate INT NULL, /* enddate for cyclic events */
- title VARCHAR(1000) NOT NULL,
- cycleinfo VARCHAR(1000) NULL, /* property list with cycle infos */
- participants VARCHAR(100000) NOT NULL, /* the CNs of the participants */
- isallday INT NULL,
- iscycle INT NULL, /* client needs to fetch to resolve */
- ispublic INT NOT NULL,
- status INT NOT NULL,
- isopaque INT NULL,
- priority INT NOT NULL, -- for marking high prio apts
- location VARCHAR(256) NULL,
- orgmail VARCHAR(256) NULL,
- partmails VARCHAR(100000) NOT NULL, /* the emails of the participants */
- partstates VARCHAR(256) NOT NULL, /* the status of each participant */
- sequence INT NULL /* the iCal sequence */
-);
-
-CREATE TABLE SOGo_helge_privcal_blob (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- c_content VARCHAR(100000) NOT NULL, /* the BLOB */
- c_creationdate INT NOT NULL, /* creation date */
- c_lastmodified INT NOT NULL, /* last modification (UPDATE) */
- c_version INT NOT NULL /* version counter */
-);
+++ /dev/null
-#!/bin/bash
-#
-# Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...]
-#
-
-DB="/tmp/sogo-registry.sqlite"
-
-while [ "$1" != "" ]; do
-USER_ID=$1
-USER_TABLE=`echo $USER_ID | tr -s [:punct:] _`
-cat << EOF
-DELETE FROM SOGo_folder_info WHERE c_path2 = '${USER_ID}';
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}',
- 'Users',
- '${USER_ID}',
- NULL,
- NULL,
- '${USER_ID}',
- 'sqlite://localhost${DB}/SOGo_user_folder_blob',
- 'sqlite://localhost${DB}/SOGo_user_folder_quick',
- 'Container' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}/Calendar',
- 'Users',
- '${USER_ID}',
- 'Calendar',
- NULL,
- 'Calendar',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_privcal_blob',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_privcal_quick',
- 'Appointment' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}/Contacts',
- 'Users',
- '${USER_ID}',
- 'Contacts',
- NULL,
- 'Contacts',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_contacts_blob',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_contacts_quick',
- 'Contact' );
-
-DROP TABLE SOGo_${USER_TABLE}_privcal_quick;
-DROP TABLE SOGo_${USER_TABLE}_privcal_blob;
-
-CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- uid VARCHAR(256) NOT NULL,
- startdate INT NOT NULL,
- enddate INT NOT NULL,
- cycleenddate INT NULL, /* enddate for cyclic events */
- title VARCHAR(1000) NOT NULL,
- cycleinfo VARCHAR(1000) NULL, /* property list with cycle infos */
- participants VARCHAR(100000) NOT NULL, /* the CNs of the participants */
- isallday INT NULL,
- iscycle INT NULL, /* client needs to fetch to resolve */
- ispublic INT NOT NULL,
- status INT NOT NULL,
- isopaque INT NULL,
- priority INT NOT NULL, -- for marking high prio apts
- location VARCHAR(256) NULL,
- orgmail VARCHAR(256) NULL,
- partmails VARCHAR(100000) NOT NULL, /* the emails of the participants */
- partstates VARCHAR(256) NOT NULL, /* the status of each participant */
- sequence INT NULL /* the iCal sequence */
-);
-
-CREATE TABLE SOGo_${USER_TABLE}_privcal_blob (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- c_content VARCHAR(100000) NOT NULL, /* the BLOB */
- c_creationdate INT NOT NULL, /* creation date */
- c_lastmodified INT NOT NULL, /* last modification (UPDATE) */
- c_version INT NOT NULL /* version counter */
-);
-
-DROP TABLE SOGo_${USER_TABLE}_contacts_quick;
-DROP TABLE SOGo_${USER_TABLE}_contacts_blob;
-
-CREATE TABLE SOGo_${USER_TABLE}_contacts_quick (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- givenname VARCHAR(256),
- cn VARCHAR(256),
- sn VARCHAR(256),
- l VARCHAR(256),
- mail VARCHAR(256),
- o VARCHAR(256),
- ou VARCHAR(256),
- telephonenumber VARCHAR(256)
-);
-
-CREATE TABLE SOGo_${USER_TABLE}_contacts_blob (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- c_content VARCHAR(100000) NOT NULL, /* the BLOB */
- c_creationdate INT NOT NULL, /* creation date */
- c_lastmodified INT NOT NULL, /* last modification (UPDATE) */
- c_version INT NOT NULL /* version counter */
-);
-
-EOF
-shift
-done
+++ /dev/null
-#!/bin/bash
-#
-# Usage: generate-folderinfo-sql-for-users user1 [user2] [user3] [...]
-#
-
-DB="/tmp/sogo-registry.sqlite"
-
-while [ "$1" != "" ]; do
-USER_ID=$1
-USER_TABLE=`echo $USER_ID | tr -s [:punct:] _`
-
-cat << EOF
-DELETE FROM SOGo_folder_info WHERE c_path2 = '${USER_ID}';
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}',
- 'Users',
- '${USER_ID}',
- NULL,
- NULL,
- '${USER_ID}',
- 'sqlite://localhost${DB}/SOGo_user_folder_blob',
- 'sqlite://localhost${DB}/SOGo_user_folder_quick',
- 'Container' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}/Calendar',
- 'Users',
- '${USER_ID}',
- 'Calendar',
- NULL,
- 'Calendar',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_privcal',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_privcal',
- 'Appointment' );
-
-INSERT INTO SOGo_folder_info
- ( c_path, c_path1, c_path2, c_path3, c_path4, c_foldername,
- c_location, c_quick_location, c_folder_type )
-VALUES
- ( '/Users/${USER_ID}/Contacts',
- 'Users',
- '${USER_ID}',
- 'Contacts',
- NULL,
- 'Contacts',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_contacts',
- 'sqlite://localhost${DB}/SOGo_${USER_TABLE}_contacts',
- 'Contact' );
-
-
-DROP TABLE SOGo_${USER_TABLE}_privcal;
-CREATE TABLE SOGo_${USER_TABLE}_privcal (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- c_content VARCHAR(100000) NOT NULL, /* the BLOB */
- c_creationdate INT NOT NULL, /* creation date */
- c_lastmodified INT NOT NULL, /* last modification (UPDATE) */
- c_version INT NOT NULL, /* version counter */
-
- /* quick fields */
- uid VARCHAR(256) NOT NULL,
- startdate INT NOT NULL,
- enddate INT NOT NULL,
- cycleenddate INT NULL, /* enddate for cyclic events */
- title VARCHAR(1000) NOT NULL,
- cycleinfo VARCHAR(1000) NULL, /* property list with cycle infos */
- participants VARCHAR(100000) NOT NULL, /* the CNs of the participants */
- isallday INT NULL,
- iscycle INT NULL, /* client needs to fetch to resolve */
- ispublic INT NOT NULL,
- status INT NOT NULL,
- priority INT NOT NULL, -- for marking high prio apts
- isopaque INT NULL,
- location VARCHAR(256) NULL,
- orgmail VARCHAR(256) NULL,
- partmails VARCHAR(100000) NOT NULL, /* the emails of the participants */
- partstates VARCHAR(256) NOT NULL, /* the status of each participant */
- sequence INT NULL /* the iCal sequence */
-);
-
-
-DROP TABLE SOGo_${USER_TABLE}_contacts;
-CREATE TABLE SOGo_${USER_TABLE}_contacts (
- c_name VARCHAR(256) NOT NULL PRIMARY KEY, /* the filename */
- c_content VARCHAR(100000) NOT NULL, /* the BLOB */
- c_creationdate INT NOT NULL, /* creation date */
- c_lastmodified INT NOT NULL, /* last modification (UPDATE) */
- c_version INT NOT NULL, /* version counter */
-
- /* quick fields */
- givenname VARCHAR(256),
- cn VARCHAR(256),
- sn VARCHAR(256),
- l VARCHAR(256),
- mail VARCHAR(256),
- o VARCHAR(256),
- ou VARCHAR(256),
- telephonenumber VARCHAR(256)
-);
-
-EOF
-shift
-done
if (!parser)
{
+#if 1
+ parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
+ createXMLReaderWithName: @"VSCardSaxDriver"];
+ [parser retain];
+#else
parser =
[[[SaxXMLReaderFactory standardXMLReaderFactory]
- createXMLReaderForMimeType:@"text/x-vcard"]
- retain];
+ createXMLReaderForMimeType:@"text/x-vcard"] retain];
+#endif
if (parser)
{
[parser setContentHandler:sax];
+2007-02-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * CardGroup.m ([CardGroup +cardParser]): find the correct parser
+ by requesting a parser by name instead of by mime-type. This way,
+ any parser which would declare the same types would not
+ enter in conflict.
+
2007-02-08 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* CardElement.m ([CardElement -namedValue:aValueName]): use
BUNDLE_EXTENSION = .sax
BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/SaxDrivers-$(MAJOR_VERSION).$(MINOR_VERSION)/
-versitCardsSaxDriver_PRINCIPAL_CLASS = VSSaxDriver
+versitCardsSaxDriver_PRINCIPAL_CLASS = VSCardSaxDriver
versitCardsSaxDriver_PCH_FILE = common.h
#import <SaxObjC/SaxObjC.h>
#import <NGCards/NGCards.h>
#import <NGObjWeb/SoObject+SoDAV.h>
+#import <NGObjWeb/WOContext.h>
+#import <NGObjWeb/WOMessage.h>
#import <NGExtensions/NGCalendarDateRange.h>
-#import <NGObjWeb/SoClassSecurityInfo.h>
+// #import <NGObjWeb/SoClassSecurityInfo.h>
#import <SOGo/SOGoCustomGroupFolder.h>
#import <SOGo/AgenorUserManager.h>
#import <SOGo/SOGoPermissions.h>
{
NGLoggerManager *lm;
static BOOL didInit = NO;
- SoClassSecurityInfo *securityInfo;
+// SoClassSecurityInfo *securityInfo;
if (didInit) return;
didInit = YES;
/* folder type */
+- (NSString *) folderType
+{
+ return @"Appointment";
+}
+
- (NSString *) outlookFolderClass
{
return @"IPF.Appointment";
@class NSMutableDictionary;
@class NSString;
+@class WOResponse;
@interface SOGoContactFolders : SOGoObject
{
- (NSArray *) contactFolders;
+- (WOResponse *) newFolderWithName: (NSString *) name;
+
@end
#endif /* SOGOCONTACTFOLDERS_H */
#import <NGObjWeb/WOContext+SoObjects.h>
#import <NGObjWeb/SoUser.h>
+#import <GDLContentStore/GCSFolderManager.h>
+#import <GDLContentStore/GCSChannelManager.h>
+#import <GDLAccess/EOAdaptorChannel.h>
+#import <GDLContentStore/NSURL+GCS.h>
+
#import <SoObjects/SOGo/SOGoPermissions.h>
#import "common.h"
- (void) appendPersonalSourcesInContext: (WOContext *) context;
{
SOGoContactGCSFolder *ab;
+ GCSChannelManager *cm;
+ EOAdaptorChannel *fc;
+ NSURL *folderLocation;
+ NSString *sql;
+ NSArray *attrs;
+ NSDictionary *row;
+
+ cm = [GCSChannelManager defaultChannelManager];
+ folderLocation
+ = [[GCSFolderManager defaultFolderManager] folderInfoLocation];
+ fc = [cm acquireOpenChannelForURL: folderLocation];
+ if (fc)
+ {
+ sql
+ = [NSString stringWithFormat: @"SELECT c_path4, c_foldername FROM %@"
+ @" WHERE c_path2 = '%@' AND c_folder_type = 'Contact'",
+ [folderLocation gcsTableName],
+ [self ownerInContext: nil]];
+ [fc evaluateExpressionX: sql];
+ attrs = [fc describeResults: NO];
+ row = [fc fetchAttributes: attrs withZone: NULL];
+ while (row)
+ {
+ ab = [SOGoContactGCSFolder contactFolderWithName: [row objectForKey: @"c_path4"]
+ andDisplayName: [row objectForKey: @"c_foldername"]
+ inContainer: self];
+ [ab setOCSPath: [NSString stringWithFormat: @"%@/%@",
+ OCSPath, [row objectForKey: @"c_path4"]]];
+ [contactFolders setObject: ab forKey: [row objectForKey: @"c_path4"]];
+ row = [fc fetchAttributes: attrs withZone: NULL];
+ }
+
+ [cm releaseChannel: fc];
+// sql = [sql stringByAppendingFormat:@" WHERE %@ = '%@'",
+// uidColumnName, [self uid]];
+ }
+}
+
+- (WOResponse *) newFolderWithName: (NSString *) name
+{
+ SOGoContactGCSFolder *newFolder;
+ WOResponse *response;
+
+ newFolder = [SOGoContactGCSFolder contactFolderWithName: name
+ andDisplayName: name
+ inContainer: [self clientObject]];
+ if ([newFolder isKindOfClass: [NSException class]])
+ response = (WOResponse *) newFolder;
+ else
+ {
+ [newFolder setOCSPath: [NSString stringWithFormat: @"%@/%@",
+ OCSPath, name]];
+ if ([newFolder create])
+ {
+ response = [WOResponse new];
+ [response setStatus: 201];
+ [response autorelease];
+ }
+ else
+ response = [NSException exceptionWithHTTPStatus: 400
+ reason: @"The new folder could not be created"];
+ }
- ab = [SOGoContactGCSFolder contactFolderWithName: @"personal"
- andDisplayName: @"Personal Addressbook"
- inContainer: self];
- [ab setOCSPath: [NSString stringWithFormat: @"%@/%@",
- OCSPath, @"personal"]];
- [contactFolders setObject: ab forKey: @"personal"];
+ return response;
}
- (void) appendSystemSourcesInContext: (WOContext *) context;
/* folder type */
+- (NSString *) folderType
+{
+ return @"Contact";
+}
+
- (NSString *)outlookFolderClass {
return @"IPF.Contact";
}
if ((self = [self initWithName: aName
inContainer: aContainer]))
[self setDisplayName: aDisplayName];
-
+
return self;
}
*/
return [self lookupImap4Message:_key inContext:_ctx];
}
+
+ obj = [self lookupImap4Folder:_key inContext:_ctx];
+ if (obj != nil)
+ return obj;
/* check attributes directly bound to the app */
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
return obj;
- obj = [self lookupImap4Folder:_key inContext:_ctx];
- if (obj != nil)
- return obj;
-
/* return 404 to stop acquisition */
return _acquire
? [NSException exceptionWithHTTPStatus:404 /* Not Found */]
ADDITIONAL_TOOL_LIBS += -Lobj -lSOGo$(LIBRARY_NAME_SUFFIX)
-include GNUmakefile.preamble
+include ../common.make
include $(GNUSTEP_MAKEFILES)/library.make
include $(GNUSTEP_MAKEFILES)/tool.make
-include GNUmakefile.postamble
libSOGo_INCLUDE_DIRS += -I.. -I../../..
-ifneq ($(GNUSTEP_BUILD_DIR),)
- RELBUILD_DIR_libOGoContentStore = \
- $(GNUSTEP_BUILD_DIR)/../../OGoContentStore/$(GNUSTEP_OBJ_DIR_NAME)
-else
- RELBUILD_DIR_libOGoContentStore = \
- ../../OGoContentStore/$(GNUSTEP_OBJ_DIR)
-endif
-
-SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib
-
-libSOGo_LIB_DIRS += \
- -L$(RELBUILD_DIR_libOGoContentStore) -L$(RELBUILD_DIR_libOGoContentStore)/../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)
+SYSTEM_LIB_DIR += -L/usr/local/lib
libSOGo_LIBRARIES_DEPEND_UPON += \
-lOGoContentStore \
ADDITIONAL_TOOL_LIBS += \
-L$(GNUSTEP_OBJ_DIR)/ \
- $(libSOGO_LIB_DIRS) \
+ -lSOGo \
-lGDLContentStore -lGDLAccess \
+ -lNGCards \
-lNGLdap \
-lNGExtensions -lEOControl \
-lDOM -lSaxObjC
-
- (NSString *)outlookFolderClass;
+- (BOOL) create;
+
@end
@interface SOGoFolder (GroupDAVExtensions)
*/
#import <NGObjWeb/SoObject.h>
+#import <GDLContentStore/GCSFolderManager.h>
+#import <GDLContentStore/GCSFolder.h>
+#import <GDLContentStore/GCSFolderType.h>
-#include "SOGoFolder.h"
-#include "common.h"
-#include <GDLContentStore/GCSFolderManager.h>
-#include <GDLContentStore/GCSFolder.h>
-#include <unistd.h>
-#include <stdlib.h>
+#import "SOGoFolder.h"
+#import "common.h"
+#import <unistd.h>
+#import <stdlib.h>
#import "SOGoAclsFolder.h"
ASSIGNCOPY(self->ocsPath, _path);
}
+
- (NSString *)ocsPath {
return self->ocsPath;
}
return folder;
}
+- (NSString *) folderType
+{
+ return @"";
+}
+
+- (BOOL) create
+{
+ NSException *result;
+
+ [GCSFolderType setFolderNamePrefix: @"SOGo_"];
+
+ result = [[self folderManager] createFolderOfType: [self folderType]
+ atPath: ocsPath];
+
+ return (result == nil);
+}
+
- (NSArray *)fetchContentObjectNames {
NSArray *fields, *records;
ADDITIONAL_INCLUDE_DIRS += \
-I.. \
- -I../..
+ -I../.. \
+ -I../../SOPE
ADDITIONAL_LIB_DIRS += \
-L../SOGo/$(GNUSTEP_OBJ_DIR)/ \
"Add Assistant" = "Add Assistant";
"Add Delegate" = "Add Delegate";
-"Add an Addressbook..." = "Add an Addressbook...";
+"New Addressbook..." = "New Addressbook...";
+"Subscribe to an Addressbook..." = "Subscribe to an Addressbook...";
"Remove the selected Addressbook" = "Remove the selected Addressbook";
+
+"Name of the Address Book" = "Name of the Address Book";
"Add Assistant" = "Ajouter comme assistant";
"Add Delegate" = "Ajouter comme délégué";
-"Add an Addressbook..." = "Ajouter un carnet d'adresses...";
+"New Addressbook..." = "Nouveau carnet d'adresses...";
+"Subscribe to an Addressbook..." = "S'inscrire à un carnet d'adresses...";
"Remove the selected Addressbook" = "Enlever le carnet d'adresses sélectionné";
+
+"Name of the Address Book" = "Nom du carnet d'adresses";
#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoObject.h>
#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/WOContext.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/NSString+Utilities.h>
return [self _selectActionForApplication: @"new"];
}
+- (id <WOActionResults>) newAbAction
+{
+ id <WOActionResults> response;
+ NSString *name;
+
+ name = [self queryParameterForKey: @"name"];
+ if ([name length] > 0)
+ response = [[self clientObject] newFolderWithName: name];
+ else
+ response = [NSException exceptionWithHTTPStatus: 400
+ reason: @"The name is missing"];
+
+ return response;
+}
+
- (id) selectForSchedulerAction
{
return [self _selectActionForApplication: @"scheduler-contacts"];
pageName = "UIxContactFoldersView";
actionName = "new";
};
+ newAb = {
+ protectedBy = "View";
+ pageName = "UIxContactFoldersView";
+ actionName = "newAb";
+ };
scheduler-contacts = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
- (NSString *) userFolderPath
{
WOContext *ctx;
- NSString *url, *path;
NSEnumerator *objects;
SOGoObject *currentObject;
BOOL found;
else
currentObject = [objects nextObject];
- url = [currentObject baseURLInContext:ctx];
- path = [[NSURL URLWithString:url] path];
-
- return path;
+ return [[currentObject baseURLInContext:ctx] hostlessURL];
}
- (NSString *) applicationPath
{
SOGoObject *currentClient, *parent;
- NSString *url;
BOOL found;
Class objectClass, groupFolderClass, userFolderClass;
WOContext *ctx;
}
ctx = [self context];
- url = [currentClient baseURLInContext: ctx];
- return [[NSURL URLWithString: url] path];
+ return [[currentClient baseURLInContext:ctx] hostlessURL];
}
- (NSString *) resourcesPath
"Week" = "Semaine";
"this week" = "cette semaine";
-"Week %d" = "Semaine nú %d";
+"Week %d" = "Semaine nº %d";
/* Month */
NSEnumerator *aptsEnumerator;
NSDictionary *currentDayAppointment;
NSCalendarDate *start, *end;
+ int endHour;
if (!allAppointments)
{
[filteredAppointments autorelease];
start = [currentTableDay hour: [self dayStartHour] minute: 0];
- end = [currentTableDay hour: [self dayEndHour] minute: 0];
+ endHour = [self dayEndHour];
+ if (endHour < 24)
+ end = [currentTableDay hour: [self dayEndHour] minute: 0];
+ else
+ end = [[currentTableDay tomorrow] hour: 0 minute: 0];
aptsEnumerator = [allAppointments objectEnumerator];
currentDayAppointment = [aptsEnumerator nextObject];
- (unsigned) dayEndHour
{
- return 24;
+ return 23;
}
- (BOOL) shouldDisplayWeekend
<form name="searchform" var:href="view" var:_sort="sortKey"
onsubmit="return onSearchFormSubmit();" method="GET">
-<!-- var:if condition="isPopup" const:negate="YES"> -->
- <var:if condition="hideFolderTree" const:negate="YES">
+<!-- var:if condition="isPopup" const:negate="YES" -->
+<!-- <var:if condition="hideFolderTree" const:negate="YES" -->
<div class="contactFoldersList" id="contactFoldersList">
<div class="titlediv"
><var:string label:value="Address Books"
/></div>
- <var:if var:condition="isPopup" const:negate="YES"
- ><div class="toolbar">
- <a href="#" class="toolbarButton" onclick="return onAddressBookAdd(this);"
+ <!-- var:if var:condition="isPopup" const:negate="YES" -->
+ <div class="toolbar" id="abToolbar">
+ <a href="#" class="toolbarButton"
><span class="toolbarButton"
- ><img rsrc:src="add-addressbook.png" label:title="Add an Addressbook..."
+ ><img rsrc:src="add-addressbook.png" label:title="New Addressbook..."
/></span></a
- ><a href="#" class="toolbarButton" onclick="return onAddressBookRemove(this);"
+ ><a href="#" class="toolbarButton"
+ ><span class="toolbarButton"
+ ><img rsrc:src="add-user-addressbook.png" label:title="Subscribe to an Addressbook..."
+ /></span></a
+ ><a href="#" class="toolbarButton"
><span class="toolbarButton"
><img rsrc:src="remove-addressbook.png" label:title="Remove the selected Addressbook"
/></span></a
- ></div></var:if>
+ ></div><!-- var:if -->
<ul id="contactFolders"
var:additional-addressbooks="additionalAddressBooks">
</div>
<div class="dragHandle" id="dragHandle"><!-- space --></div>
- </var:if>
+ <!-- var:if -->
<div id="rightPanel">
<var:component className="UIxContactsFilterPanel" qualifier="qualifier" />
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:label="OGo:label"
>
<div class="menu" id="searchMenu">
<ul id="searchOptions">
<div id="mailboxContent"><!-- space --></div>
<div class="dragHandle" id="rightDragHandle"><!-- space --></div>
<div id="messageContent"><!-- space --></div>
- <script type="text/javascript">
- initMailboxSelection('<var:string value="mailFolderName" />');
- </script>
- </div>
- </form>
+ <script type="text/javascript">
+ initMailboxSelection('<var:string value="mailFolderName" />');
+ </script>
+ </div>
<var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
</var:component>
</td>
<!-- <td align="left" bgcolor="#FFFFF0">
<span class="aptview_text">
- <!-- use '1' instead of 'YES', otherwise breaks on OSX -->
+ ! use '1' instead of 'YES', otherwise breaks on OSX -->
<!-- <var:component className="AnaisAttendeeSelector"
const:selectorID="participant"
const:division="CC"
<var:component className="UIxContactSelector"
const:selectorId="participants" />
</td>
-<!-- <td align="left" bgcolor="#FFFFF0">
+<!-- <td align="left" bgcolor="#FFFFF0"
<span class="aptview_text">
- <!-- use '1' instead of 'YES', otherwise breaks on OSX -->
+ use '1' instead of 'YES', otherwise breaks on OSX -->
<!-- <var:component className="AnaisAttendeeSelector"
const:selectorID="participant"
const:division="CC"
function openContactsFolder(contactsFolder, params, external)
{
if (contactsFolder != currentContactFolder || params) {
- if (contactsFolder == currentContactFolder)
- selection = $("contactsList").getSelectedRowsId();
- else
+ if (contactsFolder == currentContactFolder) {
+ var contactsList = $("contactsList");
+ if (contactsList)
+ selection = contactsList.getSelectedRowsId();
+ else
+ window.alert("no contactsList");
+ }
+ else
selection = null;
currentContactFolder = contactsFolder;
configureSortableTableHeaders();
}
else
- log ("ajax fuckage");
+ log ("ajax fuckage 1");
}
function onContactFoldersContextMenu(event)
div.innerHTML = content;
}
else
- log ("ajax fuckage");
+ log ("ajax fuckage 2");
}
var rowSelectionCount = 0;
document.addressBooksAjaxRequest = null;
}
else
- log ("ajax fuckage");
+ log ("ajax fuckage 3");
}
function onContactMailTo(node) {
return false;
}
-function onAddressBookAdd(node) {
+function onAddressBookNew(event) {
+ var name = window.prompt(labels["Name of the Address Book"].decodeEntities());
+ if (name) {
+ if (document.newAbAjaxRequest) {
+ document.newAbAjaxRequest.aborted = true;
+ document.newAbAjaxRequest.abort();
+ }
+ var url = ApplicationBaseURL + "/newAb?name=" + name;
+ document.newAbAjaxRequest
+ = triggerAjaxRequest(url, newAbCallback, name);
+ }
+ event.preventDefault();
+}
+
+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);
+ }
+ else
+ log ("ajax fuckage 4:" + http.status);
+}
+
+function onAddressBookAdd(event) {
var selector = $("contactFolders");
var selectorURL = '?popup=YES&selectorId=contactFolders';
var w = window.open(urlstr, "Addressbook",
"width=640,height=400,resizable=1,scrollbars=0");
w.selector = selector;
- w.opener = this;
+ w.opener = window;
w.focus();
- return false;
+ event.preventDefault();
}
-function onAddressBookRemove(node) {
+function onAddressBookRemove(event) {
var selector = $("contactFolders");
var nodes = selector.getSelectedNodes();
if (nodes.length > 0) {
}
}
- return false;
+ event.preventDefault();
}
function configureDragHandles() {
return rights;
}
+function configureAbToolbar() {
+ var toolbar = $("abToolbar");
+ var links = toolbar.childNodesWithTag("a");
+ links[0].addEventListener("click", onAddressBookNew, false);
+ links[1].addEventListener("click", onAddressBookAdd, false);
+ links[2].addEventListener("click", onAddressBookRemove, false);
+}
+
function configureContactFolders() {
var contactFolders = $("contactFolders");
if (contactFolders) {
var initContacts = {
handleEvent: function (event) {
+ configureAbToolbar();
configureContactFolders();
// initDnd();
}
DIV#editorTabs
{
+ position: absolute;
+ top: 4.5em;
left: 0px;
right: 0px;
- height: 38em;
+ bottom: 0px;
}
DIV#editorTabs > DIV.tab
top: 0px;
left: 8em;
vertical-align: bottom;
- height: 10em;
+ bottom: 1em;
right: 1em;
padding-bottom: 1em; }
{ width: 40%; }
#otherInfos TEXTAREA
-{ width: 70%;
- height: 10em; }
+{ width: 70%; }