SoObjects/Appointments/GNUmakefile

Monotone-Parent: 18c8420c0a0c752ea4dd761f934a473b321568f8
Monotone-Revision: b2699a981cd5458fbd1da1a9a72992020a29a4fc

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2006-12-14T21:20:13
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Wolfgang Sourdeau 2006-12-14 21:20:13 +00:00
parent 87dd80e801
commit dc40718409
51 changed files with 1420 additions and 969 deletions

View File

@ -26,15 +26,16 @@
NSMutableDictionary *localeLUT; NSMutableDictionary *localeLUT;
} }
- (NSDictionary *)currentLocaleConsideringLanguages:(NSArray *)_langs; - (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs;
- (NSDictionary *)localeForLanguageNamed:(NSString *)_name; - (NSDictionary *) localeForLanguageNamed:(NSString *)_name;
@end @end
#include "SOGoProductLoader.h" #include "SOGoProductLoader.h"
#include <SOGo/SOGoAuthenticator.h>
#include <WEExtensions/WEResourceManager.h> #include <WEExtensions/WEResourceManager.h>
#include <SOGo/SOGoAuthenticator.h>
#include <SOGo/SOGoUserFolder.h> #include <SOGo/SOGoUserFolder.h>
#include <SOGo/SOGoPermissions.h>
#include "common.h" #include "common.h"
@implementation SOGo @implementation SOGo
@ -44,6 +45,8 @@ static BOOL doCrashOnSessionCreate = NO;
+ (void)initialize { + (void)initialize {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
SoClassSecurityInfo *sInfo;
NSArray *basicRoles;
id tmp; id tmp;
doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"]; doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
@ -64,18 +67,19 @@ static BOOL doCrashOnSessionCreate = NO;
#endif #endif
/* SoClass security declarations */ /* SoClass security declarations */
sInfo = [self soClassSecurityInfo];
/* require View permission to access the root (bound to authenticated ...) */ /* require View permission to access the root (bound to authenticated ...) */
[[self soClassSecurityInfo] declareObjectProtected:SoPerm_View]; [sInfo declareObjectProtected: SoPerm_View];
/* to allow public access to all contained objects (subkeys) */ /* to allow public access to all contained objects (subkeys) */
[[self soClassSecurityInfo] setDefaultAccess:@"allow"]; [sInfo setDefaultAccess: @"allow"];
basicRoles = [NSArray arrayWithObjects: SoRole_Authenticated,
SOGoRole_FreeBusy, nil];
/* require Authenticated role for View and WebDAV */ /* require Authenticated role for View and WebDAV */
[[self soClassSecurityInfo] declareRole: SoRole_Authenticated [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_View];
asDefaultForPermission: SoPerm_View]; [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
[[self soClassSecurityInfo] declareRole: SoRole_Authenticated
asDefaultForPermission: SoPerm_WebDAVAccess];
} }
- (id)init { - (id)init {
@ -108,7 +112,7 @@ static BOOL doCrashOnSessionCreate = NO;
/* authenticator */ /* authenticator */
- (id)authenticatorInContext:(id)_ctx { - (id)authenticatorInContext:(id)_ctx {
return [SOGoAuthenticator sharedSOGoAuthenticator]; return [$(@"SOGoAuthenticator") sharedSOGoAuthenticator];
} }
/* name lookup */ /* name lookup */

View File

@ -13,6 +13,7 @@ Appointments_OBJC_FILES = \
NSArray+Appointments.m \ NSArray+Appointments.m \
iCalEntityObject+Agenor.m \ iCalEntityObject+Agenor.m \
\ \
SOGoCalendarComponent.m \
SOGoAppointmentObject.m \ SOGoAppointmentObject.m \
SOGoTaskObject.m \ SOGoTaskObject.m \
SOGoAppointmentFolder.m \ SOGoAppointmentFolder.m \

View File

@ -72,7 +72,7 @@
to: (NSCalendarDate *) _endDate to: (NSCalendarDate *) _endDate
component: (id) _component; component: (id) _component;
- (NSArray *) fetchFreebusyInfosFrom: (NSCalendarDate *) _startDate - (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
to: (NSCalendarDate *) _endDate; to: (NSCalendarDate *) _endDate;
- (void) deleteEntriesWithIds: (NSArray *) ids; - (void) deleteEntriesWithIds: (NSArray *) ids;

View File

@ -25,11 +25,13 @@
#import <NGObjWeb/SoObject+SoDAV.h> #import <NGObjWeb/SoObject+SoDAV.h>
#import <NGExtensions/NGCalendarDateRange.h> #import <NGExtensions/NGCalendarDateRange.h>
#import <NGObjWeb/SoClassSecurityInfo.h>
#import <SOGo/SOGoCustomGroupFolder.h> #import <SOGo/SOGoCustomGroupFolder.h>
#import <SOGo/AgenorUserManager.h> #import <SOGo/AgenorUserManager.h>
#import <SOGo/SOGoPermissions.h>
#import <SOGo/NSString+Utilities.h>
#import "common.h" #import "common.h"
#import <SOGo/NSString+URL.h>
#import "SOGoAppointmentObject.h" #import "SOGoAppointmentObject.h"
#import "SOGoTaskObject.h" #import "SOGoTaskObject.h"
@ -42,35 +44,6 @@
@end @end
#endif #endif
@interface NSString (SOGoExtensions)
- calDavMethodToObjC;
@end
@implementation NSString (SOGoExtensions)
- calDavMethodToObjC
{
NSMutableString *newName;
NSEnumerator *components;
NSString *component;
newName = [NSMutableString new];
[newName autorelease];
components = [[self componentsSeparatedByString: @"-"] objectEnumerator];
component = [components nextObject];
while (component)
{
[newName appendString: [component capitalizedString]];
component = [components nextObject];
}
return newName;
}
@end
@implementation SOGoAppointmentFolder @implementation SOGoAppointmentFolder
static NGLogger *logger = nil; static NGLogger *logger = nil;
@ -85,6 +58,7 @@ static NSNumber *sharedYes = nil;
{ {
NGLoggerManager *lm; NGLoggerManager *lm;
static BOOL didInit = NO; static BOOL didInit = NO;
SoClassSecurityInfo *securityInfo;
if (didInit) return; if (didInit) return;
didInit = YES; didInit = YES;
@ -96,6 +70,16 @@ static NSNumber *sharedYes = nil;
lm = [NGLoggerManager defaultLoggerManager]; lm = [NGLoggerManager defaultLoggerManager];
logger = [lm loggerForDefaultKey:@"SOGoAppointmentFolderDebugEnabled"]; logger = [lm loggerForDefaultKey:@"SOGoAppointmentFolderDebugEnabled"];
securityInfo = [self soClassSecurityInfo];
[securityInfo declareRole: SOGoRole_Delegate
asDefaultForPermission: SoPerm_AddDocumentsImagesAndFiles];
[securityInfo declareRole: SOGoRole_Delegate
asDefaultForPermission: SoPerm_ChangeImagesAndFiles];
[securityInfo declareRoles: [NSArray arrayWithObjects:
SOGoRole_Delegate,
SOGoRole_Assistant, nil]
asDefaultForPermission: SoPerm_View];
sharedYes = [[NSNumber numberWithBool:YES] retain]; sharedYes = [[NSNumber numberWithBool:YES] retain];
} }
@ -135,8 +119,7 @@ static NSNumber *sharedYes = nil;
SoSelectorInvocation *invocation; SoSelectorInvocation *invocation;
NSString *name; NSString *name;
name = [NSString stringWithFormat: @"do%@:", name = [NSString stringWithFormat: @"%@:", [_key davMethodToObjC]];
[_key calDavMethodToObjC]];
invocation = [[SoSelectorInvocation alloc] invocation = [[SoSelectorInvocation alloc]
initWithSelectorNamed: name initWithSelectorNamed: name
@ -198,7 +181,7 @@ static NSNumber *sharedYes = nil;
- (NSDictionary *) _parseCalendarFilter: (id <DOMElement>) filterElement - (NSDictionary *) _parseCalendarFilter: (id <DOMElement>) filterElement
{ {
NSMutableDictionary *filterData; NSMutableDictionary *filterData;
id <DOMElement> parentNode; id <DOMNode> parentNode;
id <DOMNodeList> ranges; id <DOMNodeList> ranges;
NSString *componentName; NSString *componentName;
@ -274,7 +257,7 @@ static NSNumber *sharedYes = nil;
} }
} }
- (id) doCalendarQuery: (id) context - (id) davCalendarQuery: (id) context
{ {
WOResponse *r; WOResponse *r;
NSArray *filters; NSArray *filters;
@ -415,6 +398,11 @@ static NSNumber *sharedYes = nil;
return classes; return classes;
} }
- (NSString *) groupDavResourceType
{
return @"vevent-collection";
}
/* vevent UID handling */ /* vevent UID handling */
- (NSString *) resourceNameForEventUID: (NSString *)_u - (NSString *) resourceNameForEventUID: (NSString *)_u
@ -799,7 +787,7 @@ static NSNumber *sharedYes = nil;
} }
- (NSArray *) fetchFreebusyInfosFrom: (NSCalendarDate *) _startDate - (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
to: (NSCalendarDate *) _endDate to: (NSCalendarDate *) _endDate
{ {
static NSArray *infos = nil; // TODO: move to a plist file static NSArray *infos = nil; // TODO: move to a plist file

View File

@ -42,12 +42,14 @@
@class iCalEvent; @class iCalEvent;
@class iCalCalendar; @class iCalCalendar;
@interface SOGoAppointmentObject : SOGoContentObject #import "SOGoCalendarComponent.h"
@interface SOGoAppointmentObject : SOGoCalendarComponent
/* accessors */ /* accessors */
- (NSString *)iCalString; - (iCalEvent *) event;
- (iCalEvent *)event; - (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) calendar;
/* folder management */ /* folder management */
@ -70,7 +72,6 @@
- (NSException *)changeParticipationStatus:(NSString *)_status - (NSException *)changeParticipationStatus:(NSString *)_status
inContext:(id)_ctx; inContext:(id)_ctx;
- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) calendar;
@end @end

View File

@ -21,16 +21,17 @@
#import "SOGoAppointmentObject.h" #import "SOGoAppointmentObject.h"
#import <SOGo/AgenorUserManager.h>
#import <SOGo/SOGoObject.h>
#import <SaxObjC/SaxObjC.h>
#import <NGCards/NGCards.h>
#import <NGCards/iCalCalendar.h> #import <NGCards/iCalCalendar.h>
#import <NGCards/iCalEvent.h> #import <NGCards/iCalEvent.h>
#import <NGCards/iCalEventChanges.h>
#import <NGCards/iCalPerson.h>
#import <NGMime/NGMime.h> #import <NGMime/NGMime.h>
#import <NGMail/NGMail.h> #import <NGMail/NGMail.h>
#import <NGMail/NGSendMail.h> #import <NGMail/NGSendMail.h>
#import <SOGo/AgenorUserManager.h>
#import <SOGo/SOGoObject.h>
#import "SOGoAptMailNotification.h" #import "SOGoAptMailNotification.h"
#import "iCalEntityObject+Agenor.h" #import "iCalEntityObject+Agenor.h"
@ -59,35 +60,15 @@
@implementation SOGoAppointmentObject @implementation SOGoAppointmentObject
static id<NSObject,SaxXMLReader> parser = nil;
static SaxObjectDecoder *sax = nil;
static NGLogger *logger = nil;
static NSString *mailTemplateDefaultLanguage = nil; static NSString *mailTemplateDefaultLanguage = nil;
+ (void)initialize { + (void)initialize {
NSUserDefaults *ud; NSUserDefaults *ud;
NGLoggerManager *lm;
SaxXMLReaderFactory *factory;
static BOOL didInit = NO; static BOOL didInit = NO;
if (didInit) return; if (didInit) return;
didInit = YES; didInit = YES;
lm = [NGLoggerManager defaultLoggerManager];
logger = [lm loggerForClass:self];
factory = [SaxXMLReaderFactory standardXMLReaderFactory];
parser = [[factory createXMLReaderForMimeType:@"text/calendar"]
retain];
if (parser == nil)
[logger fatalWithFormat:@"did not find a parser for text/calendar!"];
sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGCards"];
if (sax == nil)
[logger fatalWithFormat:@"could not create the iCal SAX handler!"];
[parser setContentHandler:sax];
[parser setErrorHandler:sax];
ud = [NSUserDefaults standardUserDefaults]; ud = [NSUserDefaults standardUserDefaults];
mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"] mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
retain]; retain];
@ -97,31 +78,9 @@ static NSString *mailTemplateDefaultLanguage = nil;
/* accessors */ /* accessors */
- (NSString *) iCalString
{
// for UI-X appointment viewer
return [self contentAsString];
}
- (iCalEvent *) event - (iCalEvent *) event
{ {
iCalEvent *event; return [self firstEventFromCalendar: [self calendar]];
iCalCalendar *calendar;
NSString *iCalString;
iCalString = [self iCalString];
if (iCalString)
{
calendar = [iCalCalendar parseSingleFromSource: iCalString];
if (calendar)
event = [self firstEventFromCalendar: calendar];
else
event = nil;
}
else
event = nil;
return event;
} }
/* iCal handling */ /* iCal handling */
@ -273,12 +232,12 @@ static NSString *mailTemplateDefaultLanguage = nil;
return allErrors; return allErrors;
} }
- (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) calendar - (iCalEvent *) firstEventFromCalendar: (iCalCalendar *) aCalendar
{ {
iCalEvent *event; iCalEvent *event;
NSArray *events; NSArray *events;
events = [calendar childrenWithTag: @"vevent"]; events = [aCalendar childrenWithTag: @"vevent"];
if ([events count]) if ([events count])
event = (iCalEvent *) [[events objectAtIndex: 0] event = (iCalEvent *) [[events objectAtIndex: 0]
groupWithClass: [iCalEvent class]]; groupWithClass: [iCalEvent class]];
@ -310,7 +269,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
- send iMIP mail for all folders not found - send iMIP mail for all folders not found
*/ */
AgenorUserManager *um; AgenorUserManager *um;
iCalCalendar *calendar; iCalCalendar *newCalendar;
iCalEvent *oldApt, *newApt; iCalEvent *oldApt, *newApt;
iCalEventChanges *changes; iCalEventChanges *changes;
iCalPerson *organizer; iCalPerson *organizer;
@ -339,10 +298,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
oldApt = nil; oldApt = nil;
} }
else else
{ oldApt = [self firstEventFromCalendar: [self calendar]];
calendar = [iCalCalendar parseSingleFromSource: oldContent];
oldApt = [self firstEventFromCalendar: calendar];
}
/* compare sequence if requested */ /* compare sequence if requested */
@ -353,8 +309,8 @@ static NSString *mailTemplateDefaultLanguage = nil;
/* handle new content */ /* handle new content */
calendar = [iCalCalendar parseSingleFromSource: _iCal]; newCalendar = [iCalCalendar parseSingleFromSource: _iCal];
newApt = [self firstEventFromCalendar: calendar]; newApt = [self firstEventFromCalendar: newCalendar];
if (newApt == nil) { if (newApt == nil) {
return [NSException exceptionWithHTTPStatus:400 /* Bad Request */ return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
reason:@"could not parse iCalendar content!"]; reason:@"could not parse iCalendar content!"];
@ -462,7 +418,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
canceledApt = [newApt copy]; canceledApt = [newApt copy];
[(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"]; [(iCalCalendar *) [canceledApt parent] setMethod: @"cancel"];
[self sendAttendeeRemovalEMailForAppointment:canceledApt [self sendAttendeeRemovalEMailForAppointment:canceledApt
toAttendees:attendees]; toAttendees: attendees];
[canceledApt release]; [canceledApt release];
} }
return nil; return nil;
@ -483,18 +439,13 @@ static NSString *mailTemplateDefaultLanguage = nil;
- delete in removed folders - delete in removed folders
- send iMIP mail for all folders not found - send iMIP mail for all folders not found
*/ */
iCalCalendar *calendar;
iCalEvent *apt; iCalEvent *apt;
NSArray *removedUIDs; NSArray *removedUIDs;
NSMutableArray *attendees; NSMutableArray *attendees;
/* load existing content */ /* load existing content */
calendar = [iCalCalendar parseSingleFromSource: [self iCalString]]; apt = [self event];
if (calendar)
apt = [self firstEventFromCalendar: calendar];
else
NSLog (@"this is not good at all, totally fucked we are going tyo crash...");
/* compare sequence if requested */ /* compare sequence if requested */
@ -528,15 +479,9 @@ static NSString *mailTemplateDefaultLanguage = nil;
return [self saveContentString:_iCalString baseSequence:0]; return [self saveContentString:_iCalString baseSequence:0];
} }
- (NSException *)delete {
return [self deleteWithBaseSequence:0];
}
- (NSException *)changeParticipationStatus:(NSString *)_status - (NSException *)changeParticipationStatus:(NSString *)_status
inContext:(id)_ctx inContext:(id)_ctx
{ {
iCalCalendar *calendar;
iCalEvent *apt; iCalEvent *apt;
iCalPerson *p; iCalPerson *p;
NSString *newContent; NSString *newContent;
@ -544,14 +489,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
NSString *myEMail; NSString *myEMail;
// TODO: do we need to use SOGoAppointment? (prefer iCalEvent?) // TODO: do we need to use SOGoAppointment? (prefer iCalEvent?)
calendar = [iCalCalendar parseSingleFromSource: [self iCalString]]; apt = [self event];
if (calendar)
apt = [self firstEventFromCalendar: calendar];
else
{
apt = nil;
NSLog (@"this is not good at all, totally fucked we are going tyo crash...");
}
if (apt == nil) { if (apt == nil) {
return [NSException exceptionWithHTTPStatus:500 /* Server Error */ return [NSException exceptionWithHTTPStatus:500 /* Server Error */
@ -643,7 +581,7 @@ static NSString *mailTemplateDefaultLanguage = nil;
newContentString = contentString; newContentString = contentString;
else else
{ {
[event setOrganizerWithUid: [self ownerInContext: nil]]; [event setOrganizerWithUid: [[self container] ownerInContext: nil]];
newContentString = [eventCalendar versitString]; newContentString = [eventCalendar versitString];
} }
} }
@ -652,10 +590,10 @@ static NSString *mailTemplateDefaultLanguage = nil;
baseVersion: baseVersion]; baseVersion: baseVersion];
} }
- (void)sendEMailUsingTemplateNamed:(NSString *)_pageName - (void)sendEMailUsingTemplateNamed: (NSString *)_pageName
forOldAppointment:(iCalEvent *)_oldApt forOldAppointment: (iCalEvent *)_oldApt
andNewAppointment:(iCalEvent *)_newApt andNewAppointment: (iCalEvent *)_newApt
toAttendees:(NSArray *)_attendees toAttendees: (NSArray *)_attendees
{ {
NSString *pageName; NSString *pageName;
iCalPerson *organizer; iCalPerson *organizer;
@ -828,4 +766,28 @@ static NSString *mailTemplateDefaultLanguage = nil;
return @"text/calendar"; return @"text/calendar";
} }
- (NSString *) roleOfUser: (NSString *) login
inContext: (WOContext *) context
{
AgenorUserManager *um;
iCalEvent *event;
NSString *role, *email;
um = [AgenorUserManager sharedUserManager];
email = [um getEmailForUID: login];
event = [self event];
if ([event isOrganizer: email])
role = @"Organizer";
else if ([event isParticipant: email])
role = @"Participant";
else
role = nil;
return role;
}
@end /* SOGoAppointmentObject */ @end /* SOGoAppointmentObject */

View File

@ -45,7 +45,7 @@
- (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate - (NSString *)contentAsStringFrom:(NSCalendarDate *)_startDate
to:(NSCalendarDate *)_endDate; to:(NSCalendarDate *)_endDate;
- (NSArray *)fetchFreebusyInfosFrom:(NSCalendarDate *)_startDate - (NSArray *)fetchFreeBusyInfosFrom:(NSCalendarDate *)_startDate
to:(NSCalendarDate *)_endDate; to:(NSCalendarDate *)_endDate;
@end @end

View File

@ -20,14 +20,15 @@
*/ */
// $Id: SOGoFreeBusyObject.m 675 2005-07-06 20:56:09Z znek $ // $Id: SOGoFreeBusyObject.m 675 2005-07-06 20:56:09Z znek $
#include "SOGoFreeBusyObject.h" #import <NGCards/iCalCalendar.h>
#include "common.h" #import <NGCards/iCalFreeBusy.h>
#include <SOGo/AgenorUserManager.h>
#include <NGCards/NGCards.h>
@interface NSDate (UsedPrivates) #import "common.h"
- (NSString *) icalString; // declared in NGCards
@end #import <SOGo/AgenorUserManager.h>
#import <SOGo/SOGoPermissions.h>
#import "SOGoFreeBusyObject.h"
@interface SOGoFreeBusyObject (PrivateAPI) @interface SOGoFreeBusyObject (PrivateAPI)
- (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos - (NSString *) iCalStringForFreeBusyInfos: (NSArray *) _infos
@ -58,19 +59,34 @@
{ {
NSArray *infos; NSArray *infos;
infos = [self fetchFreebusyInfosFrom:_startDate to:_endDate]; infos = [self fetchFreeBusyInfosFrom:_startDate to:_endDate];
return [self iCalStringForFreeBusyInfos:infos from:_startDate to:_endDate]; return [self iCalStringForFreeBusyInfos:infos from:_startDate to:_endDate];
} }
- (NSArray *) fetchFreebusyInfosFrom: (NSCalendarDate *) _startDate - (NSArray *) fetchFreeBusyInfosFrom: (NSCalendarDate *) _startDate
to: (NSCalendarDate *) _endDate to: (NSCalendarDate *) _endDate
{ {
id calFolder; id calFolder;
SoSecurityManager *sm;
WOApplication *woApp;
NSArray *infos;
woApp = [WOApplication application];
calFolder = [container lookupName: @"Calendar" inContext: nil acquire: NO]; calFolder = [container lookupName: @"Calendar" inContext: nil acquire: NO];
sm = [SoSecurityManager sharedSecurityManager];
if (![sm validatePermission: SOGoPerm_FreeBusyLookup
onObject: calFolder
inContext: [woApp context]])
infos = [calFolder fetchFreeBusyInfosFrom: _startDate
to: _endDate];
else
{
infos = [NSArray new];
[infos autorelease];
}
return [calFolder fetchFreebusyInfosFrom: _startDate return infos;
to: _endDate];
} }
/* Private API */ /* Private API */

View File

@ -128,6 +128,11 @@
NSMutableArray *result; NSMutableArray *result;
NSMutableDictionary *uidToRecord; NSMutableDictionary *uidToRecord;
unsigned i, count; unsigned i, count;
WOContext *context;
SoSecurityManager *securityManager;
context = [[WOApplication application] context];
securityManager = [SoSecurityManager sharedSecurityManager];
if ((folders = [[self container] valueForKey:@"memberFolders"]) == nil) { if ((folders = [[self container] valueForKey:@"memberFolders"]) == nil) {
[self errorWithFormat:@"calendar container has no 'memberFolders'?!"]; [self errorWithFormat:@"calendar container has no 'memberFolders'?!"];
@ -158,7 +163,15 @@
[folders objectAtIndex:i]]; [folders objectAtIndex:i]];
continue; continue;
} }
if ([securityManager validatePermission: SoPerm_AccessContentsInformation
onObject: aptFolder
inContext: context]) {
[self debugWithFormat:@"no permission to read the content of calendar: %@",
[folders objectAtIndex:i]];
continue;
}
results = [aptFolder fetchFields: _fields results = [aptFolder fetchFields: _fields
from: _startDate from: _startDate
to: _endDate to: _endDate

View File

@ -22,7 +22,7 @@
#ifndef __Appointments_SOGoTaskObject_H__ #ifndef __Appointments_SOGoTaskObject_H__
#define __Appointments_SOGoTaskObject_H__ #define __Appointments_SOGoTaskObject_H__
#import <SOGo/SOGoContentObject.h> #import "SOGoCalendarComponent.h"
/* /*
SOGoTaskObject SOGoTaskObject
@ -42,12 +42,12 @@
@class iCalToDo; @class iCalToDo;
@class iCalCalendar; @class iCalCalendar;
@interface SOGoTaskObject : SOGoContentObject @interface SOGoTaskObject : SOGoCalendarComponent
/* accessors */ /* accessors */
- (NSString *) iCalString;
- (iCalToDo *) task; - (iCalToDo *) task;
- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) calendar;
/* folder management */ /* folder management */
@ -70,7 +70,6 @@
- (NSException *)changeParticipationStatus:(NSString *)_status - (NSException *)changeParticipationStatus:(NSString *)_status
inContext:(id)_ctx; inContext:(id)_ctx;
- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) calendar;
@end @end

View File

@ -19,18 +19,18 @@
02111-1307, USA. 02111-1307, USA.
*/ */
#include "SOGoTaskObject.h" #import "SOGoTaskObject.h"
#include <SOGo/AgenorUserManager.h> #import <NGCards/iCalCalendar.h>
#include <SaxObjC/SaxObjC.h> #import <NGCards/iCalToDo.h>
#include <NGCards/NGCards.h> #import <NGCards/iCalEventChanges.h>
#include <NGCards/iCalCalendar.h> #import <NGCards/iCalPerson.h>
#include <NGCards/iCalToDo.h> #import <SOGo/AgenorUserManager.h>
#include <NGMime/NGMime.h> #import <NGMime/NGMime.h>
#include <NGMail/NGMail.h> #import <NGMail/NGMail.h>
#include <NGMail/NGSendMail.h> #import <NGMail/NGSendMail.h>
#include "SOGoAptMailNotification.h" #import "SOGoAptMailNotification.h"
#include "common.h" #import "common.h"
#import "NSArray+Appointments.h" #import "NSArray+Appointments.h"
@ -55,35 +55,15 @@
@implementation SOGoTaskObject @implementation SOGoTaskObject
static id<NSObject,SaxXMLReader> parser = nil;
static SaxObjectDecoder *sax = nil;
static NGLogger *logger = nil;
static NSString *mailTemplateDefaultLanguage = nil; static NSString *mailTemplateDefaultLanguage = nil;
+ (void)initialize { + (void)initialize {
NSUserDefaults *ud; NSUserDefaults *ud;
NGLoggerManager *lm;
SaxXMLReaderFactory *factory;
static BOOL didInit = NO; static BOOL didInit = NO;
if (didInit) return; if (didInit) return;
didInit = YES; didInit = YES;
lm = [NGLoggerManager defaultLoggerManager];
logger = [lm loggerForClass:self];
factory = [SaxXMLReaderFactory standardXMLReaderFactory];
parser = [[factory createXMLReaderForMimeType:@"text/calendar"]
retain];
if (parser == nil)
[logger fatalWithFormat:@"did not find a parser for text/calendar!"];
sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGCards"];
if (sax == nil)
[logger fatalWithFormat:@"could not create the iCal SAX handler!"];
[parser setContentHandler:sax];
[parser setErrorHandler:sax];
ud = [NSUserDefaults standardUserDefaults]; ud = [NSUserDefaults standardUserDefaults];
mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"] mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
retain]; retain];
@ -93,32 +73,9 @@ static NSString *mailTemplateDefaultLanguage = nil;
/* accessors */ /* accessors */
- (NSString *) iCalString
{
// for UI-X task viewer
return [self contentAsString];
}
- (iCalToDo *) task - (iCalToDo *) task
{ {
iCalToDo *task; return [self firstTaskFromCalendar: [self calendar]];
iCalCalendar *calendar;
NSString *iCalString;
iCalString = [self iCalString];
if (iCalString)
{
calendar = [iCalCalendar parseSingleFromSource: iCalString];
if (calendar)
task = [self firstTaskFromCalendar: calendar];
else
task = nil;
}
else
task = nil;
return task;
} }
/* iCal handling */ /* iCal handling */
@ -271,19 +228,19 @@ static NSString *mailTemplateDefaultLanguage = nil;
return allErrors; return allErrors;
} }
- (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) calendar - (iCalToDo *) firstTaskFromCalendar: (iCalCalendar *) aCalendar
{ {
iCalToDo *event; iCalToDo *task;
NSArray *events; NSArray *tasks;
events = [calendar childrenWithTag: @"vtodo"]; tasks = [aCalendar childrenWithTag: @"vtodo"];
if ([events count]) if ([tasks count])
event = (iCalToDo *) [[events objectAtIndex: 0] task = (iCalToDo *) [[tasks objectAtIndex: 0]
groupWithClass: [iCalToDo class]]; groupWithClass: [iCalToDo class]];
else else
event = nil; task = nil;
return event; return task;
} }
/* "iCal multifolder saves" */ /* "iCal multifolder saves" */
@ -483,18 +440,13 @@ static NSString *mailTemplateDefaultLanguage = nil;
- delete in removed folders - delete in removed folders
- send iMIP mail for all folders not found - send iMIP mail for all folders not found
*/ */
iCalCalendar *calendar; iCalToDo *task;
iCalToDo *apt;
NSArray *removedUIDs; NSArray *removedUIDs;
NSMutableArray *attendees; NSMutableArray *attendees;
/* load existing content */ /* load existing content */
calendar = [iCalCalendar parseSingleFromSource: [self iCalString]]; task = [self task];
if (calendar)
apt = [self firstTaskFromCalendar: calendar];
else
NSLog (@"this is not good at all, totally fucked we are going tyo crash...");
/* compare sequence if requested */ /* compare sequence if requested */
@ -502,21 +454,21 @@ static NSString *mailTemplateDefaultLanguage = nil;
// TODO // TODO
} }
removedUIDs = [self attendeeUIDsFromTask:apt]; removedUIDs = [self attendeeUIDsFromTask:task];
/* send notification email to attendees excluding organizer */ /* send notification email to attendees excluding organizer */
attendees = [NSMutableArray arrayWithArray:[apt attendees]]; attendees = [NSMutableArray arrayWithArray:[task attendees]];
[attendees removePerson:[apt organizer]]; [attendees removePerson:[task organizer]];
/* flag task as being canceled */ /* flag task as being canceled */
[(iCalCalendar *) [apt parent] setMethod: @"cancel"]; [(iCalCalendar *) [task parent] setMethod: @"cancel"];
[apt increaseSequence]; [task increaseSequence];
/* remove all attendees to signal complete removal */ /* remove all attendees to signal complete removal */
[apt removeAllAttendees]; [task removeAllAttendees];
/* send notification email */ /* send notification email */
[self sendTaskDeletionEMailForTask:apt [self sendTaskDeletionEMailForTask:task
toAttendees:attendees]; toAttendees:attendees];
/* perform */ /* perform */
@ -527,49 +479,37 @@ static NSString *mailTemplateDefaultLanguage = nil;
- (NSException *)saveContentString:(NSString *)_iCalString { - (NSException *)saveContentString:(NSString *)_iCalString {
return [self saveContentString:_iCalString baseSequence:0]; return [self saveContentString:_iCalString baseSequence:0];
} }
- (NSException *)delete {
return [self deleteWithBaseSequence:0];
}
- (NSException *)changeParticipationStatus:(NSString *)_status - (NSException *)changeParticipationStatus:(NSString *)_status
inContext:(id)_ctx inContext:(id)_ctx
{ {
iCalCalendar *calendar; iCalToDo *task;
iCalToDo *apt;
iCalPerson *p; iCalPerson *p;
NSString *newContent; NSString *newContent;
NSException *ex; NSException *ex;
NSString *myEMail; NSString *myEMail;
// TODO: do we need to use SOGoTask? (prefer iCalToDo?) // TODO: do we need to use SOGoTask? (prefer iCalToDo?)
calendar = [iCalCalendar parseSingleFromSource: [self iCalString]]; task = [self task];
if (calendar)
apt = [self firstTaskFromCalendar: calendar];
else
{
apt = nil;
NSLog (@"this is not good at all, totally fucked we are going tyo crash...");
}
if (apt == nil) { if (task == nil) {
return [NSException exceptionWithHTTPStatus:500 /* Server Error */ return [NSException exceptionWithHTTPStatus:500 /* Server Error */
reason:@"unable to parse task record"]; reason:@"unable to parse task record"];
} }
myEMail = [[_ctx activeUser] email]; myEMail = [[_ctx activeUser] email];
if ((p = [apt findParticipantWithEmail:myEMail]) == nil) { if ((p = [task findParticipantWithEmail:myEMail]) == nil) {
return [NSException exceptionWithHTTPStatus:404 /* Not Found */ return [NSException exceptionWithHTTPStatus:404 /* Not Found */
reason:@"user does not participate in this " reason:@"user does not participate in this "
@"task"]; @"task"];
} }
[p setPartStat:_status]; [p setPartStat:_status];
newContent = [[apt parent] versitString]; newContent = [[task parent] versitString];
// TODO: send iMIP reply mails? // TODO: send iMIP reply mails?
// [apt release]; apt = nil; // [task release]; task = nil;
if (newContent == nil) { if (newContent == nil) {
return [NSException exceptionWithHTTPStatus:500 /* Server Error */ return [NSException exceptionWithHTTPStatus:500 /* Server Error */

View File

@ -10,6 +10,13 @@
classes = { classes = {
SOGoAppointmentFolder = { SOGoAppointmentFolder = {
superclass = "SOGoFolder"; superclass = "SOGoFolder";
defaultRoles = {
"Add Documents, Images, and Files" = ( "Owner", "Delegate" );
"View" = ( "Owner", "Delegate", "Assistant" );
"WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
"FreeBusyLookup" = ( "Owner", "Delegate", "Assistant", "FreeBusyLookup" );
"Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
};
}; };
SOGoGroupAppointmentFolder = { SOGoGroupAppointmentFolder = {
@ -18,14 +25,24 @@
SOGoAppointmentObject = { SOGoAppointmentObject = {
superclass = "SOGoContentObject"; superclass = "SOGoContentObject";
defaultRoles = {
"View" = ( "Owner", "Delegate", "Organizer" );
};
}; };
SOGoTaskObject = { SOGoTaskObject = {
superclass = "SOGoContentObject"; superclass = "SOGoContentObject";
defaultRoles = {
"View" = ( "Owner", "Delegate", "Organizer" );
};
}; };
SOGoFreeBusyObject = { SOGoFreeBusyObject = {
superclass = "SOGoContentObject"; superclass = "SOGoContentObject";
protectedBy = "View";
defaultRoles = {
"View" = ( "Authenticated", "FreeBusy" );
"WebDAV Access" = ( "Authenticated", "FreeBusy" );
};
}; };
}; };
} }

View File

@ -174,6 +174,11 @@
return records; return records;
} }
- (NSString *) groupDavResourceType
{
return @"vcard-collection";
}
// /* GET */ // /* GET */
// - (id) GETAction: (id)_ctx // - (id) GETAction: (id)_ctx

View File

@ -393,4 +393,9 @@
return result; return result;
} }
- (NSString *) groupDavResourceType
{
return @"vcard-collection";
}
@end @end

View File

@ -255,11 +255,11 @@ static BOOL useAltNamespace = NO;
// TODO: those should be product.plist bindings? (can't be class bindings // TODO: those should be product.plist bindings? (can't be class bindings
// though because they are 'per-account') // though because they are 'per-account')
if ([_key isEqualToString:draftsFolderName]) { if ([_key isEqualToString: draftsFolderName]) {
if ((obj = [self lookupDraftsFolder:_key inContext:_ctx]) != nil) if ((obj = [self lookupDraftsFolder:_key inContext:_ctx]) != nil)
return obj; return obj;
} }
if ([_key isEqualToString:sieveFolderName]) { if ([_key isEqualToString: sieveFolderName]) {
if ((obj = [self lookupFiltersFolder:_key inContext:_ctx]) != nil) if ((obj = [self lookupFiltersFolder:_key inContext:_ctx]) != nil)
return obj; return obj;
} }

View File

@ -20,6 +20,7 @@
*/ */
#import <NGLdap/NGLdapConnection.h> #import <NGLdap/NGLdapConnection.h>
#import "SOGoPermissions.h"
#include "SOGoAuthenticator.h" #include "SOGoAuthenticator.h"
#include "SOGoUser.h" #include "SOGoUser.h"
@ -73,6 +74,7 @@ static SOGoAuthenticator *auth = nil;
{ {
BOOL result; BOOL result;
// return YES;
if ([authMethod isEqualToString: @"LDAP"]) if ([authMethod isEqualToString: @"LDAP"])
result = [self LDAPCheckLogin: _login password: _pwd]; result = [self LDAPCheckLogin: _login password: _pwd];
else else
@ -98,29 +100,64 @@ static SOGoAuthenticator *auth = nil;
/* create SOGoUser */ /* create SOGoUser */
- (SoUser *)userInContext:(WOContext *)_ctx - (SoUser *) userInContext:(WOContext *)_ctx
{ {
static SoUser *anonymous = nil; static SoUser *anonymous = nil, *freebusy;
NSString *login; NSString *login;
NSArray *uroles;
if (!anonymous) if (!anonymous)
anonymous anonymous
= [[SOGoUser alloc] initWithLogin:@"anonymous" = [[SOGoUser alloc] initWithLogin:@"anonymous"
roles: [NSArray arrayWithObject: SoRole_Anonymous]]; roles: [NSArray arrayWithObject: SoRole_Anonymous]];
if (!freebusy)
freebusy
= [[SOGoUser alloc] initWithLogin: @"freebusy"
roles: [NSArray arrayWithObject: SOGoRole_FreeBusy]];
if ((login = [self checkCredentialsInContext:_ctx]) == nil) if ((login = [self checkCredentialsInContext:_ctx]) == nil)
/* some error (otherwise result would have been anonymous */ /* some error (otherwise result would have been anonymous */
return nil; return nil;
if ([login isEqualToString:@"anonymous"]) if ([login isEqualToString: @"anonymous"])
return anonymous; return anonymous;
else if ([login isEqualToString: @"freebusy"])
return freebusy;
uroles = [self rolesForLogin:login]; // uroles = [NSMutableArray arrayWithArray: ];
return [[[SOGoUser alloc] initWithLogin:login return [[[SOGoUser alloc] initWithLogin: login
roles:uroles] roles: [self rolesForLogin: login]]
autorelease]; autorelease];
} }
// - (BOOL) renderException: (NSException *) exception
// inContext: (WOContext *) context
// {
// id renderedException;
// WOComponent *tmpComponent;
// WOResponse *response;
// BOOL rc;
// rc = [super renderException: exception inContext: context];
// if (!rc)
// {
// tmpComponent = [WOComponent new];
// renderedException = [tmpComponent pageWithName: @"UIxException"];
// if (renderedException)
// {
// rc = YES;
// response = [context response];
// [response setHeader: @"text/html" forKey: @"content-type"];
// [renderedException setClientObject: exception];
// [context setPage: renderedException];
// [renderedException appendToResponse: response
// inContext: context];
// }
// [tmpComponent release];
// }
// return rc;
// }
@end /* SOGoAuthenticator */ @end /* SOGoAuthenticator */

View File

@ -22,10 +22,11 @@
#ifndef __SOGo_SOGoFolder_H__ #ifndef __SOGo_SOGoFolder_H__
#define __SOGo_SOGoFolder_H__ #define __SOGo_SOGoFolder_H__
#include <SOGo/SOGoObject.h> #import "SOGoObject.h"
@class NSString, NSArray, NSDictionary; @class NSString, NSArray, NSDictionary;
@class GCSFolder; @class GCSFolder;
@class SOGoAclsFolder;
/* /*
SOGoFolder SOGoFolder
@ -54,7 +55,6 @@
- (GCSFolder *)ocsFolder; - (GCSFolder *)ocsFolder;
/* lower level fetches */ /* lower level fetches */
- (NSArray *)fetchContentObjectNames; - (NSArray *)fetchContentObjectNames;
- (NSDictionary *)fetchContentStringsAndNamesOfAllObjects; - (NSDictionary *)fetchContentStringsAndNamesOfAllObjects;
@ -64,4 +64,10 @@
@end @end
@interface SOGoFolder (GroupDAVExtensions)
- (NSString *) groupDavResourceType;
@end
#endif /* __SOGo_SOGoFolder_H__ */ #endif /* __SOGo_SOGoFolder_H__ */

View File

@ -19,6 +19,8 @@
02111-1307, USA. 02111-1307, USA.
*/ */
#import <NGObjWeb/SoObject.h>
#include "SOGoFolder.h" #include "SOGoFolder.h"
#include "common.h" #include "common.h"
#include <GDLContentStore/GCSFolderManager.h> #include <GDLContentStore/GCSFolderManager.h>
@ -26,6 +28,8 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#import "SOGoAclsFolder.h"
@implementation SOGoFolder @implementation SOGoFolder
+ (int)version { + (int)version {
@ -143,35 +147,49 @@
return nil; return nil;
} }
- (NSArray *)toOneRelationshipKeys { - (NSArray *) davResourceType
{
NSArray *rType, *groupDavCollection;
if ([self respondsToSelector: @selector (groupDavResourceType)])
{
groupDavCollection = [NSArray arrayWithObjects: [self groupDavResourceType],
@"http://groupdav.org/", @"G", nil];
rType = [NSArray arrayWithObjects: @"collection", groupDavCollection, nil];
}
else
rType = [NSArray arrayWithObject: @"collection"];
return rType;
}
- (NSArray *) toOneRelationshipKeys {
/* toOneRelationshipKeys are the 'files' contained in a folder */ /* toOneRelationshipKeys are the 'files' contained in a folder */
NSMutableArray *ma; NSMutableArray *ma;
NSArray *names; NSArray *names;
NSString *ext; NSString *name, *ext;
unsigned i, count; unsigned i, count;
NSRange r;
if ((names = [self fetchContentObjectNames]) == nil) names = [self fetchContentObjectNames];
return names; count = [names count];
ext = [self defaultFilenameExtension];
if ((count = [names count]) == 0) if (count && [ext length] > 0)
return names; {
ma = [NSMutableArray arrayWithCapacity: count];
if ((ext = [self defaultFilenameExtension]) == nil) for (i = 0; i < count; i++)
return names; {
name = [names objectAtIndex: i];
ma = [NSMutableArray arrayWithCapacity:count]; r = [name rangeOfString: @"."];
for (i = 0; i < count; i++) { if (r.length == 0)
NSRange r; name = [[name stringByAppendingString:@"."] stringByAppendingString: ext];
NSString *name; [ma addObject:name];
}
name = [names objectAtIndex:i];
r = [name rangeOfString:@"."]; names = ma;
if (r.length == 0) }
name = [[name stringByAppendingString:@"."] stringByAppendingString:ext];
return names;
[ma addObject:name];
}
return ma;
} }
/* WebDAV */ /* WebDAV */

View File

@ -37,6 +37,10 @@
@class NSString, NSArray, NSMutableString, NSException, NSTimeZone; @class NSString, NSArray, NSMutableString, NSException, NSTimeZone;
@class GCSFolderManager, GCSFolder; @class GCSFolderManager, GCSFolder;
@class SOGoUserFolder, SOGoGroupsFolder; @class SOGoUserFolder, SOGoGroupsFolder;
@class WOContext;
@class SOGoDAVSet;
#define $(class) NSClassFromString(class)
@interface SOGoObject : NSObject @interface SOGoObject : NSObject
{ {
@ -78,6 +82,8 @@
- (NSException *)delete; - (NSException *)delete;
- (id)GETAction:(id)_ctx; - (id)GETAction:(id)_ctx;
- (SOGoDAVSet *) davCurrentUserPrivilegeSet;
/* etag support */ /* etag support */
- (NSException *)matchesRequestConditionInContext:(id)_ctx; - (NSException *)matchesRequestConditionInContext:(id)_ctx;

View File

@ -19,20 +19,120 @@
02111-1307, USA. 02111-1307, USA.
*/ */
#import "SOGoUser.h"
#import "SOGoObject.h"
#import "SOGoUserFolder.h"
#import "AgenorUserManager.h"
#import <NGObjWeb/WEClientCapabilities.h> #import <NGObjWeb/WEClientCapabilities.h>
#import <NGObjWeb/SoObject+SoDAV.h> #import <NGObjWeb/SoObject+SoDAV.h>
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/WOApplication.h>
#import <NGCards/NSDictionary+NGCards.h>
#import "common.h" #import "common.h"
#import "NSString+URL.h" #import "NSArray+Utilities.h"
#import "NSString+Utilities.h"
#import "SOGoPermissions.h"
#import "SOGoUser.h"
#import "SOGoAclsFolder.h"
#import "SOGoAuthenticator.h"
#import "SOGoUserFolder.h"
#import "SOGoDAVRendererTypes.h"
#import "AgenorUserManager.h"
#import "SOGoObject.h"
@interface SOGoObject(Content) @interface SOGoObject(Content)
- (NSString *)contentAsString; - (NSString *)contentAsString;
@end @end
@interface SoClassSecurityInfo (SOGoAcls)
+ (id) defaultWebDAVPermissionsMap;
- (NSArray *) allPermissions;
- (NSArray *) allDAVPermissions;
- (NSArray *) DAVPermissionsForRole: (NSString *) role;
- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles;
@end
@implementation SoClassSecurityInfo (SOGoAcls)
+ (id) defaultWebDAVPermissionsMap
{
return [NSDictionary dictionaryWithObjectsAndKeys:
@"read", SoPerm_AccessContentsInformation,
@"read", SoPerm_View,
@"bind", SoPerm_AddDocumentsImagesAndFiles,
@"unbind", SoPerm_DeleteObjects,
@"write-acl", SoPerm_ChangePermissions,
@"write-content", SoPerm_ChangeImagesAndFiles,
@"read-free-busy", SOGoPerm_FreeBusyLookup,
NULL];
}
- (NSArray *) allPermissions
{
return [defRoles allKeys];
}
- (NSArray *) allDAVPermissions
{
NSEnumerator *allPermissions;
NSMutableArray *davPermissions;
NSDictionary *davPermissionsMap;
NSString *sopePermission, *davPermission;
davPermissions = [NSMutableArray array];
davPermissionsMap = [[self class] defaultWebDAVPermissionsMap];
allPermissions = [[self allPermissions] objectEnumerator];
sopePermission = [allPermissions nextObject];
while (sopePermission)
{
davPermission = [davPermissionsMap objectForCaseInsensitiveKey: sopePermission];
if (davPermission && ![davPermissions containsObject: davPermission])
[davPermissions addObject: davPermission];
sopePermission = [allPermissions nextObject];
}
return davPermissions;
}
- (NSArray *) DAVPermissionsForRole: (NSString *) role
{
return [self DAVPermissionsForRoles: [NSArray arrayWithObject: role]];
}
- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles
{
NSEnumerator *allPermissions;
NSMutableArray *davPermissions;
NSDictionary *davPermissionsMap;
NSString *sopePermission, *davPermission;
davPermissions = [NSMutableArray array];
davPermissionsMap = [[self class] defaultWebDAVPermissionsMap];
allPermissions = [[self allPermissions] objectEnumerator];
sopePermission = [allPermissions nextObject];
while (sopePermission)
{
if ([[defRoles objectForCaseInsensitiveKey: sopePermission]
firstObjectCommonWithArray: roles])
{
davPermission
= [davPermissionsMap objectForCaseInsensitiveKey: sopePermission];
if (davPermission
&& ![davPermissions containsObject: davPermission])
[davPermissions addObject: davPermission];
}
sopePermission = [allPermissions nextObject];
}
return davPermissions;
}
@end
@implementation SOGoObject @implementation SOGoObject
static BOOL kontactGroupDAV = YES; static BOOL kontactGroupDAV = YES;
@ -47,23 +147,23 @@ static NSTimeZone *serverTimeZone = nil;
NSString *tzName; NSString *tzName;
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
kontactGroupDAV = kontactGroupDAV =
[ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES; [ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES;
/* SoClass security declarations */ /* SoClass security declarations */
/* require View permission to access the root (bound to authenticated ...) */ /* require View permission to access the root (bound to authenticated ...) */
[[self soClassSecurityInfo] declareObjectProtected:SoPerm_View]; [[self soClassSecurityInfo] declareObjectProtected: SoPerm_View];
/* to allow public access to all contained objects (subkeys) */ /* to allow public access to all contained objects (subkeys) */
[[self soClassSecurityInfo] setDefaultAccess:@"allow"]; [[self soClassSecurityInfo] setDefaultAccess: @"allow"];
/* require Authenticated role for View and WebDAV */ /* require Authenticated role for View and WebDAV */
[[self soClassSecurityInfo] declareRole:SoRole_Authenticated [[self soClassSecurityInfo] declareRole: SoRole_Owner
asDefaultForPermission:SoPerm_View]; asDefaultForPermission: SoPerm_View];
[[self soClassSecurityInfo] declareRole:SoRole_Authenticated [[self soClassSecurityInfo] declareRole: SoRole_Owner
asDefaultForPermission:SoPerm_WebDAVAccess]; asDefaultForPermission: SoPerm_WebDAVAccess];
if (!serverTimeZone) if (!serverTimeZone)
{ {
@ -75,6 +175,51 @@ static NSTimeZone *serverTimeZone = nil;
} }
} }
+ (void) _fillDictionary: (NSMutableDictionary *) dictionary
withDAVMethods: (NSString *) firstMethod, ...
{
va_list ap;
NSString *aclMethodName;
NSString *methodName;
SEL methodSel;
va_start (ap, firstMethod);
aclMethodName = firstMethod;
while (aclMethodName)
{
methodName = [aclMethodName davMethodToObjC];
methodSel = NSSelectorFromString (methodName);
if (methodSel && [self instancesRespondToSelector: methodSel])
[dictionary setObject: methodName
forKey: [NSString stringWithFormat: @"{DAV:}%@",
aclMethodName]];
else
NSLog(@"************ method '%@' is still unimplemented!",
methodName);
aclMethodName = va_arg (ap, NSString *);
}
va_end (ap);
}
+ (NSDictionary *) defaultWebDAVAttributeMap
{
static NSMutableDictionary *map = nil;
if (!map)
{
map = [NSMutableDictionary
dictionaryWithDictionary: [super defaultWebDAVAttributeMap]];
[map retain];
[self _fillDictionary: map
withDAVMethods: @"owner", @"group", @"supported-privilege-set",
@"current-user-privilege-set", @"acl", @"acl-restrictions",
@"inherited-acl-set", @"principal-collection-set", nil];
}
return map;
}
/* containment */ /* containment */
+ (id) objectWithName: (NSString *)_name inContainer:(id)_container + (id) objectWithName: (NSString *)_name inContainer:(id)_container
@ -87,6 +232,165 @@ static NSTimeZone *serverTimeZone = nil;
return object; return object;
} }
/* DAV ACL properties */
- (NSString *) _principalForUser: (NSString *) user
{
WOContext *context;
context = [[WOApplication application] context];
return [NSString stringWithFormat: @"%@users/%@",
[self rootURLInContext: context],
user];
}
- (NSString *) davOwner
{
return [self _principalForUser: [self ownerInContext: nil]];
}
- (NSString *) davAclRestrictions
{
NSMutableString *restrictions;
restrictions = [NSMutableString string];
[restrictions appendString: @"<D:grant-only/>"];
[restrictions appendString: @"<D:no-invert/>"];
return restrictions;
}
- (SOGoDAVSet *) davPrincipalCollectionSet
{
NSString *usersUrl;
WOContext *context;
context = [[WOApplication application] context];
usersUrl = [NSString stringWithFormat: @"%@users",
[self rootURLInContext: context]];
return [SOGoDAVSet davSetWithArray: [NSArray arrayWithObject: usersUrl]
ofValuesTaggedAs: @"D:href"];
}
- (SOGoDAVSet *) davCurrentUserPrivilegeSet
{
SOGoAuthenticator *sAuth;
SoUser *user;
NSArray *roles;
WOContext *context;
SoClassSecurityInfo *sInfo;
NSArray *davPermissions;
sAuth = [SOGoAuthenticator sharedSOGoAuthenticator];
context = [[WOApplication application] context];
user = [sAuth userInContext: context];
roles = [user rolesForObject: self inContext: context];
sInfo = [[self class] soClassSecurityInfo];
davPermissions
= [[sInfo DAVPermissionsForRoles: roles] stringsWithFormat: @"<D:%@/>"];
return [SOGoDAVSet davSetWithArray: davPermissions
ofValuesTaggedAs: @"D:privilege"];
}
- (SOGoDAVSet *) davSupportedPrivilegeSet
{
SoClassSecurityInfo *sInfo;
NSArray *allPermissions;
sInfo = [[self class] soClassSecurityInfo];
allPermissions = [[sInfo allDAVPermissions] stringsWithFormat: @"<D:%@/>"];
return [SOGoDAVSet davSetWithArray: allPermissions
ofValuesTaggedAs: @"D:privilege"];
}
- (NSArray *) _davAcesFromAclsDictionary: (NSDictionary *) aclsDictionary
{
NSEnumerator *keys;
NSArray *privileges;
NSMutableString *currentAce;
NSMutableArray *davAces;
NSString *currentKey;
SOGoDAVSet *privilegesDS;
davAces = [NSMutableArray array];
keys = [[aclsDictionary allKeys] objectEnumerator];
currentKey = [keys nextObject];
while (currentKey)
{
currentAce = [NSMutableString string];
if ([currentKey hasPrefix: @":"])
[currentAce
appendFormat: @"<D:principal><D:property><D:%@/></D:property></D:principal>",
[currentKey substringFromIndex: 1]];
else
[currentAce
appendFormat: @"<D:principal><D:href>%@</D:href></D:principal>",
[self _principalForUser: currentKey]];
privileges = [[aclsDictionary objectForKey: currentKey]
stringsWithFormat: @"<D:%@/>"];
privilegesDS = [SOGoDAVSet davSetWithArray: privileges
ofValuesTaggedAs: @"privilege"];
[currentAce appendString: [privilegesDS stringForTag: @"{DAV:}grant"
rawName: @"grant"
inContext: nil prefixes: nil]];
[davAces addObject: currentAce];
currentKey = [keys nextObject];
}
return davAces;
}
- (void) _appendRolesForPseudoPrincipals: (NSMutableDictionary *) aclsDictionary
withClassSecurityInfo: (SoClassSecurityInfo *) sInfo
{
NSArray *perms;
perms = [sInfo DAVPermissionsForRole: SoRole_Owner];
if ([perms count])
[aclsDictionary setObject: perms forKey: @":owner"];
perms = [sInfo DAVPermissionsForRole: SoRole_Authenticated];
if ([perms count])
[aclsDictionary setObject: perms forKey: @":authenticated"];
perms = [sInfo DAVPermissionsForRole: SoRole_Anonymous];
if ([perms count])
[aclsDictionary setObject: perms forKey: @":unauthenticated"];
}
- (SOGoDAVSet *) davAcl
{
NSArray *role;
NSEnumerator *acls;
NSMutableDictionary *aclsDictionary;
NSDictionary *currentAcl;
SoClassSecurityInfo *sInfo;
acls = [[[SOGoAclsFolder aclsFolder] aclsForObject: self] objectEnumerator];
aclsDictionary = [NSMutableDictionary dictionary];
sInfo = [[self class] soClassSecurityInfo];
currentAcl = [acls nextObject];
while (currentAcl)
{
role = [NSArray arrayWithObject: [currentAcl objectForKey: @"role"]];
[aclsDictionary setObject: [sInfo DAVPermissionsForRoles: role]
forKey: [currentAcl objectForKey: @"uid"]];
currentAcl = [acls nextObject];
}
[self _appendRolesForPseudoPrincipals: aclsDictionary
withClassSecurityInfo: sInfo];
return [SOGoDAVSet davSetWithArray:
[self _davAcesFromAclsDictionary: aclsDictionary]
ofValuesTaggedAs: @"D:ace"];
}
/* end of properties */
- (BOOL)doesRetainContainer { - (BOOL)doesRetainContainer {
return YES; return YES;
} }
@ -143,9 +447,10 @@ static NSTimeZone *serverTimeZone = nil;
ma = [NSMutableArray arrayWithCapacity:count + 1]; ma = [NSMutableArray arrayWithCapacity:count + 1];
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
id folder; id folder;
folder = [self lookupName:[names objectAtIndex:i] inContext:nil folder = [self lookupName: [names objectAtIndex:i]
acquire:NO]; inContext: nil
acquire: NO];
if (folder == nil) if (folder == nil)
continue; continue;
if ([folder isKindOfClass:[NSException class]]) if ([folder isKindOfClass:[NSException class]])

View File

@ -34,9 +34,8 @@
context.activeUser context.activeUser
*/ */
@class NSString, NSArray, NSDictionary, NSUserDefaults; @class NSString, NSArray, NSDictionary, NSURL, NSUserDefaults;
@class WOContext;
@class NSString, NSArray, NSURL, NSUserDefaults;
@interface SOGoUser : SoUser @interface SOGoUser : SoUser
{ {
@ -68,6 +67,9 @@
- (id)homeFolderInContext:(id)_ctx; - (id)homeFolderInContext:(id)_ctx;
- (id)schedulingCalendarInContext:(id)_ctx; - (id)schedulingCalendarInContext:(id)_ctx;
- (NSArray *) rolesForObject: (NSObject *) object
inContext: (WOContext *) context;
@end @end
#endif /* __SOGoUser_H__ */ #endif /* __SOGoUser_H__ */

View File

@ -19,9 +19,19 @@
02111-1307, USA. 02111-1307, USA.
*/ */
#include "SOGoUser.h" #import <NGObjWeb/SoObject.h>
#include <SOGo/AgenorUserManager.h> #import "AgenorUserManager.h"
#include "common.h" #import "SOGoAclsFolder.h"
#import "common.h"
#import "SOGoUser.h"
@interface NSObject (SOGoRoles)
- (NSString *) roleOfUser: (NSString *) uid
inContext: (WOContext *) context;
@end
@implementation SOGoUser @implementation SOGoUser
@ -131,4 +141,35 @@
return folder; return folder;
} }
- (NSArray *) rolesForObject: (NSObject *) object
inContext: (WOContext *) context
{
NSMutableArray *rolesForObject;
SOGoAclsFolder *aclsFolder;
NSArray *sogoRoles;
NSString *role;
rolesForObject
= [NSMutableArray arrayWithArray: [super rolesForObject: object
inContext: context]];
if ([[object ownerInContext: context] isEqualToString: [self login]])
[rolesForObject addObject: SoRole_Owner];
if ([object isKindOfClass: [SOGoObject class]])
{
aclsFolder = [SOGoAclsFolder new];
sogoRoles = [aclsFolder aclsForObject: (SOGoObject *) object
forUser: login];
[rolesForObject addObjectsFromArray: sogoRoles];
[aclsFolder release];
}
if ([object respondsToSelector: @selector (roleOfUser:inContext:)])
{
role = [object roleOfUser: login inContext: context];
if (role)
[rolesForObject addObject: role];
}
return rolesForObject;
}
@end /* SOGoUser */ @end /* SOGoUser */

View File

@ -22,7 +22,7 @@
#ifndef __SOGo_SOGoUserFolder_H__ #ifndef __SOGo_SOGoUserFolder_H__
#define __SOGo_SOGoUserFolder_H__ #define __SOGo_SOGoUserFolder_H__
#include <SOGo/SOGoFolder.h> #import "SOGoFolder.h"
/* /*
SOGoUserFolder SOGoUserFolder
@ -37,10 +37,9 @@
*/ */
@class NSString; @class NSString;
@class WOContext;
@interface SOGoUserFolder : SOGoFolder @interface SOGoUserFolder : SOGoFolder
{
}
/* accessors */ /* accessors */
@ -48,7 +47,7 @@
/* ownership */ /* ownership */
- (NSString *) ownerInContext: (id) _ctx; - (NSString *) ownerInContext: (WOContext *) _ctx;
/* pathes */ /* pathes */

View File

@ -19,207 +19,181 @@
02111-1307, USA. 02111-1307, USA.
*/ */
#import "SOGoUserFolder.h"
#import "WOContext+Agenor.h" #import "WOContext+Agenor.h"
#import "common.h" #import "common.h"
#import "SOGoUser.h" #import "SOGoUser.h"
#import "Appointments/SOGoAppointmentFolder.h" #import "Appointments/SOGoAppointmentFolder.h"
#import "Appointments/SOGoFreeBusyObject.h"
#import "Contacts/SOGoContactFolders.h" #import "Contacts/SOGoContactFolders.h"
#import "Mailer/SOGoMailAccounts.h"
#import "SOGoUserFolder.h"
@implementation SOGoUserFolder @implementation SOGoUserFolder
/* accessors */ /* accessors */
- (NSString *)login { - (NSString *) login
return [self nameInContainer]; {
return nameInContainer;
} }
/* hierarchy */ /* hierarchy */
- (NSArray *)toManyRelationshipKeys { - (NSArray *) toManyRelationshipKeys
{
static NSArray *children = nil; static NSArray *children = nil;
if (children == nil) { if (!children)
children = [[NSArray alloc] initWithObjects: children = [[NSArray alloc] initWithObjects:
@"Calendar", @"Contacts", @"Mail", nil]; @"Calendar", @"Contacts", @"Mail", nil];
}
return children; return children;
} }
/* ownership */ /* ownership */
- (NSString *)ownerInContext:(id)_ctx { - (NSString *) ownerInContext: (WOContext *) _ctx
return [self login]; {
return nameInContainer;
} }
/* looking up shared objects */ /* looking up shared objects */
- (SOGoUserFolder *)lookupUserFolder { - (SOGoUserFolder *) lookupUserFolder
{
return self; return self;
} }
- (SOGoGroupsFolder *)lookupGroupsFolder { - (SOGoGroupsFolder *) lookupGroupsFolder
return [self lookupName:@"Groups" inContext:nil acquire:NO]; {
return [self lookupName: @"Groups" inContext: nil acquire: NO];
} }
/* pathes */ /* pathes */
- (void)setOCSPath:(NSString *)_path { - (void) setOCSPath: (NSString *) _path
{
[self warnWithFormat: [self warnWithFormat:
@"rejected attempt to reset user-folder path: '%@'", _path]; @"rejected attempt to reset user-folder path: '%@'", _path];
} }
- (NSString *)ocsPath {
return [@"/Users/" stringByAppendingString:[self login]]; - (NSString *) ocsPath
{
return [@"/Users/" stringByAppendingString: [self login]];
} }
- (NSString *)ocsUserPath { - (NSString *) ocsUserPath
{
return [self ocsPath]; return [self ocsPath];
} }
- (NSString *)ocsPrivateCalendarPath {
- (NSString *) ocsPrivateCalendarPath
{
return [[self ocsUserPath] stringByAppendingString:@"/Calendar"]; return [[self ocsUserPath] stringByAppendingString:@"/Calendar"];
} }
- (NSString *)ocsPrivateContactsPath {
- (NSString *) ocsPrivateContactsPath
{
return [[self ocsUserPath] stringByAppendingString:@"/Contacts"]; return [[self ocsUserPath] stringByAppendingString:@"/Contacts"];
} }
/* name lookup */ /* name lookup */
- (id)privateCalendar:(NSString *)_key inContext:(id)_ctx { // - (NSString *) permissionForKey: (NSString *) key
static Class calClass = Nil; // {
id calendar; // return ([key isEqualToString: @"freebusy.ifb"]
// ? SoPerm_WebDAVAccess
// : [super permissionForKey: key]);
// }
- (SOGoAppointmentFolder *) privateCalendar: (NSString *) _key
inContext: (WOContext *) _ctx
{
SOGoAppointmentFolder *calendar;
if (calClass == Nil) calendar = [$(@"SOGoAppointmentFolder") objectWithName: _key inContainer: self];
calClass = NSClassFromString(@"SOGoAppointmentFolder"); [calendar setOCSPath: [self ocsPrivateCalendarPath]];
if (calClass == Nil) {
[self errorWithFormat:@"missing SOGoAppointmentFolder class!"];
return nil;
}
calendar = [[calClass alloc] initWithName:_key inContainer:self]; return calendar;
[calendar setOCSPath:[self ocsPrivateCalendarPath]];
return [calendar autorelease];
} }
- (SOGoContactFolders *) privateContacts: (NSString *)_key inContext:(id)_ctx - (SOGoContactFolders *) privateContacts: (NSString *) _key
inContext: (WOContext *) _ctx
{ {
static Class contactsClass = Nil;
SOGoContactFolders *contacts; SOGoContactFolders *contacts;
if (!contactsClass) contacts = [$(@"SOGoContactFolders") objectWithName:_key inContainer: self];
contactsClass = NSClassFromString (@"SOGoContactFolders"); [contacts setBaseOCSPath: [self ocsPrivateContactsPath]];
if (!contactsClass)
{
[self errorWithFormat:@"missing SOGoContactFolders class!"];
contacts = nil;
}
else
{
contacts = [[contactsClass alloc] initWithName:_key inContainer: self];
[contacts autorelease];
[contacts setBaseOCSPath: [self ocsPrivateContactsPath]];
}
return contacts; return contacts;
} }
- (id)groupsFolder:(NSString *)_key inContext:(id)_ctx { - (id) groupsFolder: (NSString *) _key
static Class fldClass = Nil; inContext: (WOContext *) _ctx
id folder; {
return [$(@"SOGoGroupsFolder") objectWithName: _key inContainer: self];
if (fldClass == Nil)
fldClass = NSClassFromString(@"SOGoGroupsFolder");
if (fldClass == Nil) {
[self errorWithFormat:@"missing SOGoGroupsFolder class!"];
return nil;
}
folder = [[fldClass alloc] initWithName:_key inContainer:self];
return [folder autorelease];
} }
- (id)mailAccountsFolder:(NSString *)_key inContext:(id)_ctx { - (id) mailAccountsFolder: (NSString *) _key
static Class fldClass = Nil; inContext: (WOContext *) _ctx
id folder; {
return [$(@"SOGoMailAccounts") objectWithName: _key inContainer: self];
if (fldClass == Nil)
fldClass = NSClassFromString(@"SOGoMailAccounts");
if (fldClass == Nil) {
[self errorWithFormat:@"missing SOGoMailAccounts class!"];
return nil;
}
folder = [[fldClass alloc] initWithName:_key inContainer:self];
return [folder autorelease];
} }
- (id)freeBusyObject:(NSString *)_key inContext:(id)_ctx { - (id) freeBusyObject: (NSString *) _key
static Class fbClass = Nil; inContext: (WOContext *) _ctx
id fb; {
return [$(@"SOGoFreeBusyObject") objectWithName: _key inContainer: self];
if (fbClass == Nil)
fbClass = NSClassFromString(@"SOGoFreeBusyObject");
if (fbClass == Nil) {
[self errorWithFormat:@"missing SOGoFreeBusyObject class!"];
return nil;
}
fb = [[fbClass alloc] initWithName:_key inContainer:self];
return [fb autorelease];
} }
- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag { - (id) lookupName: (NSString *) _key
inContext: (WOContext *) _ctx
acquire: (BOOL) _flag
{
id obj; id obj;
/* first check attributes directly bound to the application */ /* first check attributes directly bound to the application */
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO])) obj = [super lookupName: _key inContext: _ctx acquire: NO];
return obj; if (!obj)
{
if ([_key hasPrefix:@"Calendar"]) { if ([_key hasPrefix: @"Calendar"])
id calendar; {
obj = [self privateCalendar: @"Calendar" inContext: _ctx];
calendar = [self privateCalendar:@"Calendar" inContext:_ctx]; if (![_key isEqualToString: @"Calendar"])
if ([_key isEqualToString:@"Calendar"]) obj = [obj lookupName: [_key pathExtension]
return calendar; inContext: _ctx acquire: NO];
}
return [calendar lookupName:[_key pathExtension] else if ([_key isEqualToString: @"Contacts"])
inContext:_ctx acquire:NO]; obj = [self privateContacts: _key inContext: _ctx];
} else if ([_key isEqualToString: @"Groups"])
obj = [self groupsFolder: _key inContext: _ctx];
if ([_key isEqualToString:@"Contacts"]) else if ([_key isEqualToString: @"Mail"])
return [self privateContacts:_key inContext:_ctx]; obj = [self mailAccountsFolder: _key inContext: _ctx];
else if ([_key isEqualToString: @"freebusy.ifb"])
if ([_key isEqualToString:@"Groups"]) { obj = [self freeBusyObject:_key inContext:_ctx];
/* Agenor requirement, return 403 to stop acquisition */ else
if (![_ctx isAccessFromIntranet]) { obj = [NSException exceptionWithHTTPStatus: 404 /* Not Found */];
return [NSException exceptionWithHTTPStatus:403 /* Forbidden */];
} }
return [self groupsFolder:_key inContext:_ctx];
}
if ([_key isEqualToString:@"Mail"]) return obj;
return [self mailAccountsFolder:_key inContext:_ctx];
if ([_key isEqualToString:@"freebusy.ifb"])
return [self freeBusyObject:_key inContext:_ctx];
/* return 404 to stop acquisition */
return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
} }
/* WebDAV */ /* WebDAV */
- (NSArray *)fetchContentObjectNames { - (NSArray *) fetchContentObjectNames
{
static NSArray *cos = nil; static NSArray *cos = nil;
if (!cos) { if (!cos)
cos = [[NSArray alloc] initWithObjects:@"freebusy.ifb", nil]; cos = [[NSArray alloc] initWithObjects: @"freebusy.ifb", nil];
}
return cos; return cos;
} }
- (BOOL) davIsCollection { - (BOOL) davIsCollection
{
return YES; return YES;
} }

View File

@ -16,6 +16,7 @@ CommonUI_OBJC_FILES += \
UIxAppNavView.m \ UIxAppNavView.m \
UIxJSClose.m \ UIxJSClose.m \
\ \
UIxAclEditor.m \
UIxElemBuilder.m \ UIxElemBuilder.m \
UIxTabView.m \ UIxTabView.m \
UIxTabItem.m \ UIxTabItem.m \
@ -27,6 +28,9 @@ CommonUI_OBJC_FILES += \
CommonUI_RESOURCE_FILES += \ CommonUI_RESOURCE_FILES += \
Version \ Version \
product.plist \ product.plist \
Toolbars/SOGoAclOwner.toolbar \
Toolbars/SOGoAclAssistant.toolbar \
CommonUI_LOCALIZED_RESOURCE_FILES += \ CommonUI_LOCALIZED_RESOURCE_FILES += \
Localizable.strings \ Localizable.strings \

View File

@ -138,9 +138,9 @@
return isPopup; return isPopup;
} }
- (NSString *) pageContentClasses - (NSString *) bodyClasses
{ {
return (isPopup ? @"pageContent popup" : @"pageContent"); return (isPopup ? @"popup" : @"main");
} }
/* page based JavaScript */ /* page based JavaScript */

View File

@ -1,38 +1,47 @@
{ { /* -*-javascript-*- */
requires = ( MAIN, Mailer ); requires = ( MAIN, Mailer );
publicResources = ( publicResources = (
calendar.css, calendar.css,
uix.css, uix.css,
menu_logo_top.gif, menu_logo_top.gif,
line_left.gif, line_left.gif,
line_stretch.gif, line_stretch.gif,
line_right.gif, line_right.gif,
box_topleft.gif, box_topleft.gif,
box_top.gif, box_top.gif,
box_topright.gif, box_topright.gif,
box_left.gif, box_left.gif,
box_right.gif, box_right.gif,
box_botleft.gif, box_botleft.gif,
box_bottom.gi88f, box_bottom.gif,
box_botright.gif, box_botright.gif,
tab_selected.gif, tab_selected.gif,
tab_.gif, tab_.gif,
corner_right.gif, corner_right.gif,
closewindow.gif, closewindow.gif,
OGoLogo.gif, OGoLogo.gif,
upward_sorted.gif, upward_sorted.gif,
downward_sorted.gif, downward_sorted.gif,
non_sorted.gif non_sorted.gif
); );
factories = { factories = {
}; };
categories = { categories = {
SOGoObject = { SOGoFolder = {
methods = { methods = {
}; acls = {
}; protectedBy = "ReadAcls";
pageName = "UIxAclEditor";
};
saveAcls = {
protectedBy = "SaveAcls";
pageName = "UIxAclEditor";
actionName = "saveAcls";
};
};
};
}; };
} }

View File

@ -9,9 +9,10 @@ ContactsUI_PRINCIPAL_CLASS = ContactsUIProduct
ContactsUI_LANGUAGES = English French ContactsUI_LANGUAGES = English French
ContactsUI_OBJC_FILES = \ ContactsUI_OBJC_FILES = \
UIxContactsMailerSelection.m \ UIxContactsAclsSelection.m \
UIxContactsCalendarsSelection.m \
UIxContactsAddressBooksSelection.m \ UIxContactsAddressBooksSelection.m \
UIxContactsCalendarsSelection.m \
UIxContactsMailerSelection.m \
\ \
ContactsUIProduct.m \ ContactsUIProduct.m \
UIxContactsFilterPanel.m \ UIxContactsFilterPanel.m \

View File

@ -27,7 +27,7 @@
#import <NGObjWeb/WOResponse.h> #import <NGObjWeb/WOResponse.h>
#import <SoObjects/SOGo/SOGoUser.h> #import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/NSString+URL.h> #import <SoObjects/SOGo/NSString+Utilities.h>
#import <SoObjects/Contacts/SOGoContactFolders.h> #import <SoObjects/Contacts/SOGoContactFolders.h>
#import <SoObjects/Contacts/SOGoContactFolder.h> #import <SoObjects/Contacts/SOGoContactFolder.h>
@ -87,6 +87,11 @@
return [self _selectActionForApplication: @"addressbooks-contacts"]; return [self _selectActionForApplication: @"addressbooks-contacts"];
} }
- (id) selectForAclsAction
{
return [self _selectActionForApplication: @"acls-contacts"];
}
- (NSArray *) _searchResults: (NSString *) contact - (NSArray *) _searchResults: (NSString *) contact
{ {
NSMutableArray *results; NSMutableArray *results;

View File

@ -97,6 +97,13 @@
return self; return self;
} }
- (id) aclsContactsAction
{
selectorComponentClass = @"UIxContactsAclsSelection";
return self;
}
- (NSString *) defaultSortKey - (NSString *) defaultSortKey
{ {
return @"fn"; return @"fn";

View File

@ -1,196 +1,219 @@
{ { /* -*-javascript-*- */
requires = ( MAIN, CommonUI, Contacts ); requires = ( MAIN, CommonUI, Contacts );
publicResources = ( publicResources = ();
);
factories = { factories = {};
};
categories = { categories = {
SOGoContactFolders = { SOGoContactFolders = {
methods = { methods = {
view = { view = {
protectedBy = "View"; protectedBy = "View";
pageName = "UIxContactFoldersView"; pageName = "UIxContactFoldersView";
};
new = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "new";
};
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 = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "selectForAcls";
};
contactSearch = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "contactSearch";
};
updateAdditionalAddressBooks = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "updateAdditionalAddressBooks";
};
acls = {
protectedBy = "ReadAcls";
pageName = "UIxAclEditor";
};
saveAcls = {
protectedBy = "SaveAcls";
pageName = "UIxAclEditor";
actionName = "saveAcls";
};
}; };
new = { };
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "new";
};
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";
};
contactSearch = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "contactSearch";
};
updateAdditionalAddressBooks = {
protectedBy = "View";
pageName = "UIxContactFoldersView";
actionName = "updateAdditionalAddressBooks";
};
};
};
SOGoContactGCSFolder = { SOGoContactGCSFolder = {
slots = { slots = {
toolbar = { toolbar = {
protectedBy = "View"; protectedBy = "View";
value = "SOGoContactFolder.toolbar"; value = "SOGoContactFolder.toolbar";
};
}; };
}; methods = {
methods = { view = {
view = { protectedBy = "View";
protectedBy = "View"; pageName = "UIxContactsListView";
pageName = "UIxContactsListView"; };
new = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "new";
};
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";
};
}; };
new = { };
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "new";
};
mailer-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "mailerContacts";
};
calendars-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "calendarsContacts";
};
addressbooks-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "addressBooksContacts";
};
};
};
SOGoContactLDAPFolder = { SOGoContactLDAPFolder = {
slots = { slots = {
toolbar = { toolbar = {
protectedBy = "View"; protectedBy = "View";
value = "SOGoContactFolder.toolbar"; value = "SOGoContactFolder.toolbar";
};
}; };
}; methods = {
methods = { view = {
view = { protectedBy = "View";
protectedBy = "View"; pageName = "UIxContactsListView";
pageName = "UIxContactsListView"; };
new = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "new";
};
scheduler-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "schedulerContacts";
};
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";
};
}; };
new = { };
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "new";
};
scheduler-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "schedulerContacts";
};
mailer-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "mailerContacts";
};
calendars-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "calendarsContacts";
};
addressbooks-contacts = {
protectedBy = "View";
pageName = "UIxContactsListView";
actionName = "addressBooksContacts";
};
};
};
SOGoContactGCSEntry = { SOGoContactGCSEntry = {
methods = { methods = {
view = { view = {
protectedBy = "View"; protectedBy = "View";
pageName = "UIxContactView"; pageName = "UIxContactView";
};
delete = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "delete";
};
edit = {
protectedBy = "View";
pageName = "UIxContactEditor";
};
save = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "save";
};
write = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "write";
};
vcard = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "vcard";
};
}; };
delete = { };
protectedBy = "View";
pageName = "UIxContactView";
actionName = "delete";
};
edit = {
protectedBy = "View";
pageName = "UIxContactEditor";
};
save = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "save";
};
write = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "write";
};
vcard = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "vcard";
};
};
};
SOGoContactLDAPEntry = { SOGoContactLDAPEntry = {
methods = { methods = {
view = { view = {
protectedBy = "View"; protectedBy = "View";
pageName = "UIxContactView"; pageName = "UIxContactView";
};
delete = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "delete";
};
edit = {
protectedBy = "View";
pageName = "UIxContactEditor";
};
save = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "save";
};
write = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "write";
};
vcard = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "vcard";
};
}; };
delete = { };
protectedBy = "View";
pageName = "UIxContactView";
actionName = "delete";
};
edit = {
protectedBy = "View";
pageName = "UIxContactEditor";
};
save = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "save";
};
write = {
protectedBy = "View";
pageName = "UIxContactEditor";
actionName = "write";
};
vcard = {
protectedBy = "View";
pageName = "UIxContactView";
actionName = "vcard";
};
};
};
}; };
} }

View File

@ -50,13 +50,14 @@
Note: we cannot use acquisition to find the nearest drafts folder, because Note: we cannot use acquisition to find the nearest drafts folder, because
the IMAP4 server might contains an own Drafts folder. the IMAP4 server might contains an own Drafts folder.
*/ */
SOGoDraftsFolder *drafts; // SOGoDraftsFolder *drafts;
id client; SOGoMailAccount *accountFolder;
client = [self clientObject]; accountFolder = [[self clientObject] mailAccountFolder];
drafts = [[client mailAccountFolder]
lookupName:@"Drafts" inContext:[self context] acquire:NO]; return [accountFolder
return drafts; lookupName: [accountFolder draftsFolderNameInContext: context]
inContext: context acquire: NO];
} }
/* errors */ /* errors */
@ -93,7 +94,7 @@
returnValue = drafts; returnValue = drafts;
else else
{ {
urlBase = [drafts newObjectBaseURLInContext: [self context]]; urlBase = [drafts newObjectBaseURLInContext: context];
if ([urlBase isNotNull]) if ([urlBase isNotNull])
{ {
urlParams = [NSMutableDictionary new]; urlParams = [NSMutableDictionary new];
@ -119,7 +120,7 @@
[self debugWithFormat:@"compose on %@: %@", drafts, url]; [self debugWithFormat:@"compose on %@: %@", drafts, url];
r = [[self context] response]; r = [context response];
[r setStatus: 302 /* move d */]; [r setStatus: 302 /* move d */];
[r setHeader: url forKey: @"location"]; [r setHeader: url forKey: @"location"];
[self reset]; [self reset];
@ -147,7 +148,7 @@
if ([drafts isKindOfClass:[NSException class]]) if ([drafts isKindOfClass:[NSException class]])
return drafts; return drafts;
return [drafts newObjectInContext:[self context]]; return [drafts newObjectInContext:context];
} }
- (NSException *)_setupNewDraft { - (NSException *)_setupNewDraft {
@ -178,14 +179,14 @@
return nil; return nil;
} }
url = [self->newDraft baseURLInContext:[self context]]; url = [self->newDraft baseURLInContext:context];
if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"]; if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
url = [url stringByAppendingString:@"edit"]; url = [url stringByAppendingString:@"edit"];
// TODO: debug log // TODO: debug log
[self logWithFormat:@"compose on %@", url]; [self logWithFormat:@"compose on %@", url];
r = [[self context] response]; r = [context response];
[r setStatus:302 /* moved */]; [r setStatus:302 /* moved */];
[r setHeader:url forKey:@"location"]; [r setHeader:url forKey:@"location"];
[self reset]; [self reset];

View File

@ -17,7 +17,7 @@ MainUI_OBJC_FILES += \
MainUI_RESOURCE_FILES += \ MainUI_RESOURCE_FILES += \
Version \ Version \
product.plist product.plist
MainUI_LOCALIZED_RESOURCE_FILES += \ MainUI_LOCALIZED_RESOURCE_FILES += \
Locale Localizable.strings Locale Localizable.strings

View File

@ -290,7 +290,7 @@ static NSArray *internetAccessStates = nil;
for (count = 1; count < intervals; count++) for (count = 1; count < intervals; count++)
[freeBusyItems addObject: @"0"]; [freeBusyItems addObject: @"0"];
records = [[fb fetchFreebusyInfosFrom: startDate to: endDate] objectEnumerator]; records = [[fb fetchFreeBusyInfosFrom: startDate to: endDate] objectEnumerator];
[self _fillFreeBusyItems: freeBusyItems withRecords: records [self _fillFreeBusyItems: freeBusyItems withRecords: records
fromStartDate: startDate toEndDate: endDate]; fromStartDate: startDate toEndDate: endDate];

View File

@ -4,6 +4,53 @@
publicResources = ( publicResources = (
); );
factories = {
};
classes = {
SOGoRootPage = {
superclass = "SoComponent";
protectedBy = "View";
defaultRoles = {
"View" = ( "Authenticated", "FreeBusy" );
};
};
SOGoUserFolder = {
superclass = "SOGoFolder";
protectedBy = "HomePage Access";
defaultRoles = {
"Homepage Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
"WebDAV Access" = ( "Owner", "Assistant", "Delegate", "FreeBusy" );
"Access Contents Information" = ( "Owner", "Assistant", "Delegate",
"FreeBusy" );
};
};
SOGoFolder = {
superclass = "SOGoObject";
protectedBy = "Access Contents Information";
defaultRoles = {
"Add Documents, Images, and Files" = ( "Owner", "Delegate" );
"View" = ( "Owner", "Delegate", "Assistant" );
"WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
"Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
"ReadAcls" = ( "Owner", "Delegate", "Assistant" );
"SaveAcls" = ( "Owner" );
};
};
SOGoGroupsFolder = {
superclass = "SOGoObject";
protectedBy = "View";
};
SOGoGroupFolder = {
superclass = "SOGoObject";
protectedBy = "View";
};
SOGoCustomGroupFolder = {
superclass = "SOGoGroupFolder";
protectedBy = "View";
};
};
categories = { categories = {
SOGo = { // TODO: move decls to class SOGo = { // TODO: move decls to class
methods = { methods = {
@ -15,31 +62,11 @@
protectedBy = "View"; protectedBy = "View";
pageName = "SOGoRootPage"; pageName = "SOGoRootPage";
}; };
connect = {
protectedBy = "View";
pageName = "SOGoRootPage";
actionName = "connect";
};
}; };
}; };
};
classes = {
SOGoRootPage = { SOGoRootPage = {
superclass = "SoComponent";
protectedBy = "View";
defaultRoles = {
"View" = "Authenticated";
};
}; };
SOGoUserFolder = { SOGoUserFolder = {
superclass = "SOGoFolder";
defaultRoles = {
"HomePage Access" = "Owner";
};
methods = { methods = {
view = { view = {
protectedBy = "HomePage Access"; protectedBy = "HomePage Access";
@ -58,9 +85,7 @@
*/ */
}; };
}; };
SOGoGroupsFolder = { SOGoGroupsFolder = {
superclass = "SOGoObject";
methods = { methods = {
index = { index = {
protectedBy = "View"; protectedBy = "View";
@ -69,7 +94,6 @@
}; };
}; };
SOGoGroupFolder = { SOGoGroupFolder = {
superclass = "SOGoObject";
methods = { methods = {
index = { index = {
protectedBy = "View"; protectedBy = "View";
@ -78,17 +102,15 @@
}; };
}; };
SOGoFreeBusyObject = { SOGoFreeBusyObject = {
superclass = "SOGoObject";
methods = { methods = {
ajaxRead = { ajaxRead = {
protectedBy = "View"; protectedBy = "View";
pageName = "SOGoUserHomePage"; pageName = "SOGoUserHomePage";
actionName = "readFreeBusy"; actionName = "readFreeBusy";
}; };
}; };
}; };
SOGoCustomGroupFolder = { SOGoCustomGroupFolder = {
superclass = "SOGoGroupFolder";
methods = { methods = {
}; };
}; };

View File

@ -298,12 +298,12 @@
inContext:[self context]]; inContext:[self context]];
[self debugWithFormat:@"group calendar: %@", groupCalendar]; [self debugWithFormat:@"group calendar: %@", groupCalendar];
if (![groupCalendar respondsToSelector:@selector(fetchFreebusyInfosFrom:to:)]) { if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
[self errorWithFormat:@"invalid folder to run freebusy query on!"]; [self errorWithFormat:@"invalid folder to run freebusy query on!"];
return NO; return NO;
} }
infos = [groupCalendar fetchFreebusyInfosFrom:[_apt startDate] infos = [groupCalendar fetchFreeBusyInfosFrom:[_apt startDate]
to:[_apt endDate]]; to:[_apt endDate]];
[self debugWithFormat:@" process: %d events", [infos count]]; [self debugWithFormat:@" process: %d events", [infos count]];

View File

@ -416,7 +416,7 @@
fb = [fbos objectAtIndex:i]; fb = [fbos objectAtIndex:i];
if (fb != (SOGoFreeBusyObject *)[NSNull null]) { if (fb != (SOGoFreeBusyObject *)[NSNull null]) {
infos = [fb fetchFreebusyInfosFrom:[self startDate] to:[self endDate]]; infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]];
[allInfos addObjectsFromArray:infos]; [allInfos addObjectsFromArray:infos];
} }
} }

View File

@ -284,12 +284,12 @@
inContext:[self context]]; inContext:[self context]];
[self debugWithFormat:@"group calendar: %@", groupCalendar]; [self debugWithFormat:@"group calendar: %@", groupCalendar];
if (![groupCalendar respondsToSelector:@selector(fetchFreebusyInfosFrom:to:)]) { if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
[self errorWithFormat:@"invalid folder to run freebusy query on!"]; [self errorWithFormat:@"invalid folder to run freebusy query on!"];
return NO; return NO;
} }
infos = [groupCalendar fetchFreebusyInfosFrom:[_task startDate] infos = [groupCalendar fetchFreeBusyInfosFrom:[_task startDate]
to:[_task due]]; to:[_task due]];
[self debugWithFormat:@" process: %d tasks", [infos count]]; [self debugWithFormat:@" process: %d tasks", [infos count]];

View File

@ -416,7 +416,7 @@
fb = [fbos objectAtIndex:i]; fb = [fbos objectAtIndex:i];
if (fb != (SOGoFreeBusyObject *)[NSNull null]) { if (fb != (SOGoFreeBusyObject *)[NSNull null]) {
infos = [fb fetchFreebusyInfosFrom:[self startDate] to:[self endDate]]; infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]];
[allInfos addObjectsFromArray:infos]; [allInfos addObjectsFromArray:infos];
} }
} }

View File

@ -64,13 +64,13 @@
protectedBy = "View"; protectedBy = "View";
pageName = "UIxCalMonthView"; pageName = "UIxCalMonthView";
}; };
newevent = { newevent = {
protectedBy = "View"; protectedBy = "Add Documents, Images, and Files";
pageName = "UIxAppointmentEditor"; pageName = "UIxAppointmentEditor";
actionName = "new"; actionName = "new";
}; };
newtask = { newtask = {
protectedBy = "View"; protectedBy = "Add Documents, Images, and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "new"; actionName = "new";
}; };
@ -89,7 +89,7 @@
actionName = "proposalSearch"; actionName = "proposalSearch";
}; };
batchDelete = { batchDelete = {
protectedBy = "View"; protectedBy = "Delete Objects";
pageName = "UIxCalMainView"; pageName = "UIxCalMainView";
actionName = "batchDelete"; actionName = "batchDelete";
}; };
@ -160,7 +160,7 @@
pageName = "UIxAppointmentView"; pageName = "UIxAppointmentView";
actionName = "delete"; actionName = "delete";
}; };
edit = { edit = {
protectedBy = "View"; protectedBy = "View";
pageName = "UIxAppointmentEditor"; pageName = "UIxAppointmentEditor";
}; };
@ -219,35 +219,35 @@
actionName = "delete"; actionName = "delete";
}; };
edit = { edit = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
}; };
editAsTask = { editAsTask = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
}; };
save = { save = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "save"; actionName = "save";
}; };
saveAsTask = { saveAsTask = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "save"; actionName = "save";
}; };
changeStatus = { changeStatus = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "changeStatus"; actionName = "changeStatus";
}; };
accept = { accept = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "accept"; actionName = "accept";
}; };
decline = { decline = {
protectedBy = "View"; protectedBy = "Change Images and Files";
pageName = "UIxTaskEditor"; pageName = "UIxTaskEditor";
actionName = "decline"; actionName = "decline";
}; };

View File

@ -46,19 +46,5 @@
<var:string value="currentContactName" /></li> <var:string value="currentContactName" /></li>
</var:foreach> </var:foreach>
</ul><br /> </ul><br />
<!-- <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"
class="button_submit_env"
>
<script language="JavaScript">
<var:string value="jsCode" const:escapeHTML="NO" />
</script>
<a var:href="jsFunctionHref"
class="button_submit"
><var:string value="title" /></a>
</span>
<br /> -->
</div> </div>
</container> </container>

View File

@ -12,39 +12,24 @@
<var:if condition="hideFrame" const:negate="YES"> <var:if condition="hideFrame" const:negate="YES">
<div class="menu" id="contactFoldersMenu"> <div class="menu" id="contactFoldersMenu">
<ul> <ul>
<li <li><var:string label:value="Modify" /></li>
onmousedown="return false;" <li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
onmouseup="return false;"><var:string label:value="Modify" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li><var:string label:value="New Card" /></li>
onmousedown="return false;" <li><var:string label:value="New List" /></li>
onmouseup="return false;"><var:string label:value="New Card" /></li>
<li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="New List" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li><var:string label:value="Delete" /></li>
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Delete" /></li>
</ul> </ul>
</div> </div>
<div class="menu" id="contactMenu"> <div class="menu" id="contactMenu">
<ul> <ul>
<li <li id="modifyContactMenuEntry" onmouseup="return onMenuEditContact(event, this);"><var:string label:value="Modify" /></li>
onmousedown="return false;"
onmouseup="return onMenuEditContact(event, this);"><var:string label:value="Modify" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li id="writeToContactMenuEntry" onmouseup="return onMenuWriteToContact(event, this);"><var:string label:value="Write" /></li>
onmousedown="return false;" <li id="imContactMenuEntry"><var:string label:value="Instant Message" /></li>
onmouseup="return onMenuWriteToContact(event, this);"><var:string label:value="Write" /></li>
<li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Instant Message" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li id="deleteContactMenuEntry" onmouseup="return onMenuDeleteContact(event, this);"><var:string label:value="Delete" /></li>
onmousedown="return false;"
onmouseup="return onMenuDeleteContact(event, this);"><var:string label:value="Delete" /></li>
</ul> </ul>
</div> </div>

View File

@ -12,20 +12,15 @@
<div class="menu" id="accountIconMenu"> <div class="menu" id="accountIconMenu">
<ul id="sourceList"> <ul id="sourceList">
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Subscribe..." /></li> onmouseup="return false;"><var:string label:value="Subscribe..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Get Messages for Account" /></li> onmouseup="return false;"><var:string label:value="Get Messages for Account" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="New Folder..." /></li> onmouseup="return false;"><var:string label:value="New Folder..." /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Search Messages..." /></li> onmouseup="return false;"><var:string label:value="Search Messages..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Properties..." /></li> onmouseup="return false;"><var:string label:value="Properties..." /></li>
</ul> </ul>
</div> </div>
@ -33,30 +28,22 @@
<div class="menu" id="inboxIconMenu"> <div class="menu" id="inboxIconMenu">
<ul id="sourceList"> <ul id="sourceList">
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li> onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li> onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Subscribe..." /></li> onmouseup="return false;"><var:string label:value="Subscribe..." /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li> onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="New Folder..." /></li> onmouseup="return false;"><var:string label:value="New Folder..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Compact This Folder" /></li> onmouseup="return false;"><var:string label:value="Compact This Folder" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Search Messages..." /></li> onmouseup="return false;"><var:string label:value="Search Messages..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Properties..." /></li> onmouseup="return false;"><var:string label:value="Properties..." /></li>
</ul> </ul>
</div> </div>
@ -64,33 +51,24 @@
<div class="menu" id="trashIconMenu"> <div class="menu" id="trashIconMenu">
<ul id="sourceList"> <ul id="sourceList">
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li> onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li> onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Subscribe..." /></li> onmouseup="return false;"><var:string label:value="Subscribe..." /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li> onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="New Subfolder..." /></li> onmouseup="return false;"><var:string label:value="New Subfolder..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Compact This Folder" /></li> onmouseup="return false;"><var:string label:value="Compact This Folder" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Empty Trash" /></li> onmouseup="return false;"><var:string label:value="Empty Trash" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Search Messages..." /></li> onmouseup="return false;"><var:string label:value="Search Messages..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Properties..." /></li> onmouseup="return false;"><var:string label:value="Properties..." /></li>
</ul> </ul>
</div> </div>
@ -98,36 +76,26 @@
<div class="menu" id="mailboxIconMenu"> <div class="menu" id="mailboxIconMenu">
<ul id="sourceList"> <ul id="sourceList">
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li> onmouseup="return false;"><var:string label:value="Open in New Mail Window" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li> onmouseup="return false;"><var:string label:value="Copy Folder Location" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Subscribe..." /></li> onmouseup="return false;"><var:string label:value="Subscribe..." /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li> onmouseup="return false;"><var:string label:value="Mark Folder Read..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="New Subfolder..." /></li> onmouseup="return false;"><var:string label:value="New Subfolder..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Rename Folder..." /></li> onmouseup="return false;"><var:string label:value="Rename Folder..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Compact This Folder" /></li> onmouseup="return false;"><var:string label:value="Compact This Folder" /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Delete Folder" /></li> onmouseup="return false;"><var:string label:value="Delete Folder" /></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Search Messages..." /></li> onmouseup="return false;"><var:string label:value="Search Messages..." /></li>
<li <li
onmousedown="return false;"
onmouseup="return false;"><var:string label:value="Properties..." /></li> onmouseup="return false;"><var:string label:value="Properties..." /></li>
</ul> </ul>
</div> </div>
@ -135,13 +103,10 @@
<div class="menu" id="addressMenu"> <div class="menu" id="addressMenu">
<ul id="sourceList"> <ul id="sourceList">
<li id="add_to_addressbook" <li id="add_to_addressbook"
onmousedown="return false;"
onmouseup="newContactFromEmail(this);"><var:string label:value="Add to Address Book..."/></li> onmouseup="newContactFromEmail(this);"><var:string label:value="Add to Address Book..."/></li>
<li id="compose_mailto" <li id="compose_mailto"
onmousedown="return false;"
onmouseup="newEmailTo(this);"><var:string label:value="Compose Mail To"/></li> onmouseup="newEmailTo(this);"><var:string label:value="Compose Mail To"/></li>
<li id="create_filter" <li id="create_filter"
onmousedown="return false;"
onmouseup="onMenuEntryClick(this, event);"><var:string label:value="Create Filter From Message..."/></li> onmouseup="onMenuEntryClick(this, event);"><var:string label:value="Create Filter From Message..."/></li>
</ul> </ul>
</div> </div>
@ -149,20 +114,15 @@
<div class="menu" id="messageListMenu"> <div class="menu" id="messageListMenu">
<ul id="sourceList"> <ul id="sourceList">
<li <li
onmousedown="return false;"
onmouseup="onMenuOpenMessage(event);"><var:string label:value="Open Message In New Window"/></li> onmouseup="onMenuOpenMessage(event);"><var:string label:value="Open Message In New Window"/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li> onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li> onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li> onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li> onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
@ -189,124 +149,98 @@
onmousedown="return false;"><var:string label:value="Mark"/></li> onmousedown="return false;"><var:string label:value="Mark"/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li> onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li> onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li> onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
<li <li
onmousedown="return false;"
onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li> onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
</ul> </ul>
<div class="menu" id="messageContentMenu">
<ul>
<li
onmousedown="return false;"
onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
<li
onmousedown="return false;"
onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
<li
onmousedown="return false;"
onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
<li
onmousedown="return false;"
onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
<li
class="submenu"
mailboxaction="move"
submenu="mailboxes-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Move To"/></li>
<li
class="submenu"
mailboxaction="copy"
submenu="mailboxes-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Copy To"/></li>
<li class="separator"></li>
<li
class="submenu"
submenu="label-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Label"/></li>
<li
class="submenu"
submenu="mark-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Mark"/></li>
<li class="separator"></li>
<li
onmousedown="return false;"
onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
<li
onmousedown="return false;"
onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
<li
onmousedown="return false;"
onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
<li
onmousedown="return false;"
onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
</ul>
</div>
<div class="menu" id="label-menu">
<ul id="">
<li onmousedown="return false;"
onmouseup="onMenuLabelMessage(event, 'none');"><var:string label:value="None" /></li>
<li class="separator"></li>
<li onmousedown="return false;"
onmouseup="onMenuLabelMessage(event, 'important);"><var:string label:value="Important" /></li>
<li onmousedown="return false;"
onmouseup="onMenuLabelMessage(event, 'work');"><var:string label:value="Work" /></li>
<li onmousedown="return false;"
onmouseup="onMenuLabelMessage(event, 'personal');"><var:string label:value="Personal" /></li>
<li onmousedown="return false;"
onmouseup="onMenuLabelMessage(event, 'todo');"><var:string label:value="To Do" /></li>
<li onmousedown="return false;"
onmouseup="onMenuLab-elMessage(event, 'later');"><var:string label:value="Later" /></li>
</ul>
</div>
<var:component
className="UIxMailFolderMenu"
const:menuId="mailboxes-menu"
const:parentMenu="0"
rootClassName="treeRootClassName"
const:treeFolderAction="view"
/>
<div class="menu" id="mark-menu">
<ul id="">
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'read');"><var:string label:value="As Read" /></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'threadread');"><var:string label:value="Thread As Read" /></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'readbydate);"><var:string label:value="As Read By Date..." /></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'allread);"><var:string label:value="All Read" /></li>
<li class="separator"></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'flag);"><var:string label:value="Flag" /></li>
<li class="separator"></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'junk);"><var:string label:value="As Junk" /></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'notjunk);"><var:string label:value="As Not Junk" /></li>
<li onmousedown="return false;"
onmouseup="onMenuMarkMessage(event, 'runjunkmailcontrols);"><var:string label:value="Run Junk Mail Controls" /></li>
</ul>
</div>
</div> </div>
<div class="menu" id="messageContentMenu">
<ul>
<li
onmouseup="onMenuReplyToSender(event);"><var:string label:value="Reply to Sender Only"/></li>
<li
onmouseup="onMenuReplyToAll(event);"><var:string label:value="Reply to All"/></li>
<li
onmouseup="onMenuForwardMessage(event);"><var:string label:value="Forward"/></li>
<li
onmouseup="onMenuEditMessageAsNew(event);"><var:string label:value="Edit As New..."/></li>
<li
class="submenu"
mailboxaction="move"
submenu="mailboxes-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Move To"/></li>
<li
class="submenu"
mailboxaction="copy"
submenu="mailboxes-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Copy To"/></li>
<li class="separator"></li>
<li
class="submenu"
submenu="label-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Label"/></li>
<li
class="submenu"
submenu="mark-menu"
onmouseover="dropDownSubmenu(event);"
onmousedown="return false;"><var:string label:value="Mark"/></li>
<li class="separator"></li>
<li
onmouseup="onMenuSaveMessageAs(event);"><var:string label:value="Save As..."/></li>
<li
onmouseup="onMenuPreviewPrintMessage(event);"><var:string label:value="Print Preview"/></li>
<li
onmouseup="onMenuPrintMessage(event);"><var:string label:value="Print..."/></li>
<li
onmouseup="onMenuDeleteMessage(event);"><var:string label:value="Delete Message"/></li>
</ul>
</div>
<div class="menu" id="label-menu">
<ul id="">
<li onmouseup="onMenuLabelMessage(event, 'none');"><var:string label:value="None" /></li>
<li class="separator"></li>
<li onmouseup="onMenuLabelMessage(event, 'important);"><var:string label:value="Important" /></li>
<li onmouseup="onMenuLabelMessage(event, 'work');"><var:string label:value="Work" /></li>
<li onmouseup="onMenuLabelMessage(event, 'personal');"><var:string label:value="Personal" /></li>
<li onmouseup="onMenuLabelMessage(event, 'todo');"><var:string label:value="To Do" /></li>
<li onmouseup="onMenuLab-elMessage(event, 'later');"><var:string label:value="Later" /></li>
</ul>
</div>
<var:component
className="UIxMailFolderMenu"
const:menuId="mailboxes-menu"
const:parentMenu="0"
rootClassName="treeRootClassName"
const:treeFolderAction="view"
/>
<div class="menu" id="mark-menu">
<ul id="">
<li onmouseup="onMenuMarkMessage(event, 'read');"><var:string label:value="As Read" /></li>
<li onmouseup="onMenuMarkMessage(event, 'threadread');"><var:string label:value="Thread As Read" /></li>
<li onmouseup="onMenuMarkMessage(event, 'readbydate);"><var:string label:value="As Read By Date..." /></li>
<li onmouseup="onMenuMarkMessage(event, 'allread);"><var:string label:value="All Read" /></li>
<li class="separator"></li>
<li onmouseup="onMenuMarkMessage(event, 'flag);"><var:string label:value="Flag" /></li>
<li class="separator"></li>
<li onmouseup="onMenuMarkMessage(event, 'junk);"><var:string label:value="As Junk" /></li>
<li onmouseup="onMenuMarkMessage(event, 'notjunk);"><var:string label:value="As Not Junk" /></li>
<li onmouseup="onMenuMarkMessage(event, 'runjunkmailcontrols);"><var:string label:value="Run Junk Mail Controls" /></li>
</ul>
</div>
<form name="pageform" var:href="pageFormURL" _wosid="0" onsubmit="checkSearchValue(event);"> <form name="pageform" var:href="pageFormURL" _wosid="0" onsubmit="checkSearchValue(event);">
<var:if condition="isPopup" const:negate="YES"> <var:if condition="isPopup" const:negate="YES">
<var:if condition="hideFolderTree" const:negate="YES"> <var:if condition="hideFolderTree" const:negate="YES">
<div class="folderTree" id="mailerFolderTree"> <div class="folderTree" id="mailerFolderTree">
<div class="titlediv"><var:string label:value="Folders" /></div> <div class="titlediv"><var:string label:value="Folders" /></div>
@ -318,20 +252,20 @@
<div class="dragHandle" id="dragHandle"><!-- space --></div> <div class="dragHandle" id="dragHandle"><!-- space --></div>
</var:if> </var:if>
<div id="mailerPageContent"> <div id="mailerPageContent">
<var:component-content/> <var:component-content/>
</div> </div>
</var:if> </var:if>
<var:if condition="isPopup"> <var:if condition="isPopup">
<var:component-content/> <var:component-content/>
</var:if> </var:if>
</form> </form>
<var:string value="errorAlertJavaScript" const:escapeHTML="NO" /> <var:string value="errorAlertJavaScript" const:escapeHTML="NO" />
</var:if> </var:if>
<var:if condition="hideFrame"> <var:if condition="hideFrame">
<var:component-content/> <var:component-content/>
</var:if> </var:if>

View File

@ -33,35 +33,31 @@
<div class="menu" id="appointmentsListMenu"> <div class="menu" id="appointmentsListMenu">
<ul> <ul>
<li <li onmouseup="newEvent(this, 'event');"><var:string label:value="New Event..."/></li>
onmousedown="return false;"
onmouseup="newEvent(this, 'event');"><var:string label:value="New Event..."/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li onmouseup="newEvent(this, 'task');"><var:string label:value="New Task..."/></li>
onmousedown="return false;" <li onmouseup="editEvent();"><var:string label:value="Edit Selected Event..."/></li>
onmouseup="newEvent(this, 'task');"><var:string label:value="New Task..."/></li> <li onmouseup="deleteEvent();"><var:string label:value="Delete Selected Event"/></li>
<li
onmousedown="return false;"
onmouseup="editEvent();"
><var:string label:value="Edit Selected Event..."/></li>
<li
onmousedown="return false;"
onmouseup="deleteEvent();"
><var:string label:value="Delete Selected Event"/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li onmouseup="onSelectAll();"><var:string label:value="Select All"/></li>
onmousedown="return false;"
onmouseup="onSelectAll();"
><var:string label:value="Select All"/></li>
<li class="separator"></li> <li class="separator"></li>
<li <li onmouseup="onToggleWorkweekDaysOnly();"><var:string label:value="Workweek days only" /></li>
onmousedown="return false;" <li onmouseup="onToggleTasksInView();"><var:string label:value="Tasks in View"/></li>
onmouseup="onToggleWorkweekDaysOnly();" </ul>
><var:string label:value="Workweek days only" /></li> </div>
<li
onmousedown="return false;" <div class="menu" id="calendarsMenu">
onmouseup="onToggleTasksInView();" <ul>
><var:string label:value="Tasks in View"/></li> <li id="newCalendarMenuEntry"><var:string label:value="New Calendar..."/></li>
<li id="deleteCalendarMenuEntry"><var:string label:value="Delete Calendar"/></li>
<li id="accessRightsMenuEntry"><var:string label:value="Access Rights..." /></li>
<li class="separator"></li>
<li id="exportCalendarMenuEntry"><var:string label:value="Export Calendar..."/></li>
<li id="publishCalendarMenuEntry"><var:string label:value="Publish Calendar..."/></li>
<li class="separator"></li>
<li id="publishCalendarMenuEntry"><var:string label:value="Reload Remote Calendars"/></li>
<li class="separator"></li>
<li id="calendarPropertiesMenuEntry"><var:string label:value="Properties"/></li>
</ul> </ul>
</div> </div>
@ -105,8 +101,4 @@
selectedDate="selectedDate" selectedDate="selectedDate"
--></div> --></div>
</div> </div>
<script type="text/javascript">
initCalendarContactsSelector('calendarsList');
</script>
</var:component> </var:component>

View File

@ -28,7 +28,7 @@
/></var:if> /></var:if>
</head> </head>
<body oncontextmenu="return false;"> <body oncontextmenu="return false;" var:class="bodyClasses">
<script type="text/javascript"> <script type="text/javascript">
var UserFolderURL = '<var:string value="userFolderPath" />'; var UserFolderURL = '<var:string value="userFolderPath" />';
var ApplicationBaseURL = '<var:string value="applicationPath" />'; var ApplicationBaseURL = '<var:string value="applicationPath" />';
@ -68,7 +68,7 @@
><var:string label:value="Address Book" /></a> | ><var:string label:value="Address Book" /></a> |
<a var:href="relativeMailPath" <a var:href="relativeMailPath"
><var:string label:value="Mail" /></a> | ><var:string label:value="Mail" /></a> |
<a href="http://to.be.done/" <a href="#" id="rightAdministrationLink"
><var:string label:value="Right Administration" /></a> | ><var:string label:value="Right Administration" /></a> |
<a var:href="logoffPath" <a var:href="logoffPath"
><var:string label:value="Logoff" /></a> ><var:string label:value="Logoff" /></a>
@ -82,7 +82,7 @@
><var:component className="UIxToolbar" var:toolbar="toolbar" ><var:component className="UIxToolbar" var:toolbar="toolbar"
/> />
<div var:class="pageContentClasses" <div class="pageContent"
><var:component-content ><var:component-content
/></div> /></div>
<noscript> <noscript>

View File

@ -498,14 +498,13 @@ function onConfirmContactSelection(tag)
var contactsList = $("contactsList"); var contactsList = $("contactsList");
var rows = contactsList.getSelectedRows(); var rows = contactsList.getSelectedRows();
for (i = 0; i < rows.length; i++) for (i = 0; i < rows.length; i++) {
{ var cid = rows[i].getAttribute("contactid");
var cid = rows[i].getAttribute("contactid"); var cname = '' + rows[i].getAttribute("contactname");
var cname = '' + rows[i].getAttribute("contactname"); var email = '' + rows[i].cells[1].innerHTML;
var email = '' + rows[i].cells[1].innerHTML; opener.window.addContact(tag, currentContactFolderName + '/' + cname,
opener.window.addContact(tag, currentContactFolderName + '/' + cname, cid, cname, email);
cid, cname, email); }
}
if (selector && selector.changeNotification if (selector && selector.changeNotification
&& selectorList.value != initialValues) && selectorList.value != initialValues)
@ -604,13 +603,13 @@ function refreshContacts(contactId) {
function onAddressBookAdd(node) { function onAddressBookAdd(node) {
var selector = $("contactFolders"); var selector = $("contactFolders");
var selectorUrl = '?popup=YES&selectorId=contactFolders'; var selectorURL = '?popup=YES&selectorId=contactFolders';
urlstr = ApplicationBaseURL; urlstr = ApplicationBaseURL;
if (urlstr[urlstr.length-1] != '/') if (urlstr[urlstr.length-1] != '/')
urlstr += '/'; urlstr += '/';
urlstr += ("../../" + UserLogin + "/Contacts/" urlstr += ("../../" + UserLogin + "/Contacts/"
+ contactSelectorAction + selectorUrl); + contactSelectorAction + selectorURL);
// log (urlstr); // log (urlstr);
var w = window.open(urlstr, "Addressbook", var w = window.open(urlstr, "Addressbook",
"width=640,height=400,resizable=1,scrollbars=0"); "width=640,height=400,resizable=1,scrollbars=0");
@ -660,9 +659,29 @@ function configureDragHandles() {
function configureContactFolders() { function configureContactFolders() {
var contactFolders = $("contactFolders"); var contactFolders = $("contactFolders");
if (contactFolders) { if (contactFolders)
contactFolders.addEventListener("selectionchange", onFolderSelectionChange, false); contactFolders.addEventListener("selectionchange", onFolderSelectionChange, false);
} }
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/acl";
else
url = ApplicationBaseURL + selected.getAttribute("id") + "/acl";
openAclWindow(url, title);
}
function initializeMenus() {
var menus = new Array("contactFoldersMenu", "contactMenu", "searchMenu");
initMenusNamed(menus);
var menuEntry = $("accessRightsMenuEntry");
menuEntry.addEventListener("mouseup", onAccessRightsMenuEntryMouseUp, false);
} }
var initContacts = { var initContacts = {

View File

@ -141,3 +141,39 @@ HTMLElement.prototype.getSelectedNodesId = function() {
return selArray; return selArray;
} }
HTMLElement.prototype.onContextMenu = function(event) {
var popup = this.sogoContextMenu;
if (document.currentPopupMenu)
hideMenu(event, document.currentPopupMenu);
var menuTop = event.pageY;
var menuLeft = event.pageX;
var heightDiff = (window.innerHeight
- (menuTop + popup.offsetHeight));
if (heightDiff < 0)
menuTop += heightDiff;
var leftDiff = (window.innerWidth
- (menuLeft + popup.offsetWidth));
if (leftDiff < 0)
menuLeft -= popup.offsetWidth;
popup.style.top = menuTop + "px;";
popup.style.left = menuLeft + "px;";
popup.style.visibility = "visible;";
// setupMenuTarget(popup, event.target);
bodyOnClick = "" + document.body.getAttribute("onclick");
document.body.setAttribute("onclick", "onBodyClick(event);");
document.currentPopupMenu = popup;
// event.cancelBubble = true;
// event.returnValue = false;
}
HTMLElement.prototype.attachMenu = function(menuName) {
this.sogoContextMenu = $(menuName);
this.addEventListener("contextmenu", this.onContextMenu, true);
}

View File

@ -487,7 +487,7 @@ function messageListCallback(http)
log ("ajax fuckage"); log ("ajax fuckage");
} }
function onMessageContextMenu(event, element) function onMessageContextMenu(event)
{ {
var menu = $('messageListMenu'); var menu = $('messageListMenu');
menu.addEventListener("hideMenu", onMessageContextMenuHide, false); menu.addEventListener("hideMenu", onMessageContextMenuHide, false);
@ -498,8 +498,8 @@ function onMessageContextMenu(event, element)
for (var i = 0; i < selectedNodes.length; i++) for (var i = 0; i < selectedNodes.length; i++)
deselectNode (selectedNodes[i]); deselectNode (selectedNodes[i]);
topNode.menuSelectedRows = selectedNodes; topNode.menuSelectedRows = selectedNodes;
topNode.menuSelectedEntry = element; topNode.menuSelectedEntry = this;
selectNode(element); selectNode(this);
} }
function onMessageContextMenuHide(event) function onMessageContextMenuHide(event)
@ -1003,4 +1003,12 @@ var initMailer = {
} }
} }
function initializeMenus() {
var menus = new Array("accountIconMenu", "inboxIconMenu", "trashIconMenu",
"mailboxIconMenu", "addressMenu", "messageListMenu",
"messageContentMenu", "label-menu", "mailboxes-menu",
"mark-menu", "searchMenu");
initMenusNamed(menus);
}
window.addEventListener("load", initMailer, false); window.addEventListener("load", initMailer, false);

View File

@ -12,11 +12,15 @@ var SOGODragAndDropSourceInterface = {
this.addEventListener("mousedown", this.dragGestureMouseDownHandler, false); this.addEventListener("mousedown", this.dragGestureMouseDownHandler, false);
}, },
dragGestureMouseDownHandler: function (event) { dragGestureMouseDownHandler: function (event) {
// log("mousedown"); if (event.button == 0) {
document._dragGestureStartPoint = new Array(event.clientX, event.clientY); document._dragGestureStartPoint = new Array(event.clientX,
document._currentMouseGestureObject = this; event.clientY);
window.addEventListener("mousemove", this.dragGestureMouseMoveHandler, false); document._currentMouseGestureObject = this;
window.addEventListener("mouseup", this.dragGestureMouseUpHandler, false); window.addEventListener("mousemove", this.dragGestureMouseMoveHandler,
false);
window.addEventListener("mouseup", this.dragGestureMouseUpHandler,
false);
}
}, },
dragGestureMouseUpHandler: function (event) { dragGestureMouseUpHandler: function (event) {
log("mouseup"); log("mouseup");

View File

@ -3,7 +3,6 @@ var sortKey = '';
var listFilter = 'view_today'; var listFilter = 'view_today';
var CalendarBaseURL = ApplicationBaseURL; var CalendarBaseURL = ApplicationBaseURL;
var listOfSelection = null; var listOfSelection = null;
var hideCompletedTasks = 0; var hideCompletedTasks = 0;
@ -478,12 +477,11 @@ function calendarDisplayCallback(http)
if (http.callbackData["hour"]) if (http.callbackData["hour"])
hour = http.callbackData["hour"]; hour = http.callbackData["hour"];
var contentView; var contentView;
log ("currentView: " + currentView);
if (currentView == "monthview") if (currentView == "monthview")
contentView = $("calendarContent"); contentView = $("calendarContent");
else { else {
scrollDayView(hour); scrollDayView(hour);
log("cbtest1"); // log("cbtest1");
contentView = $("daysView"); contentView = $("daysView");
} }
var appointments = document.getElementsByClassName("appointment", contentView); var appointments = document.getElementsByClassName("appointment", contentView);
@ -507,7 +505,7 @@ function calendarDisplayCallback(http)
clickableCells[j].addEventListener("dblclick", clickableCells[j].addEventListener("dblclick",
onClickableCellsDblClick, false); onClickableCellsDblClick, false);
} }
log("cbtest1"); // log("cbtest1");
} }
else else
log ("ajax fuckage"); log ("ajax fuckage");
@ -610,7 +608,7 @@ function _loadTasksHref(href) {
} }
function onHeaderClick(event) { function onHeaderClick(event) {
log("onHeaderClick: " + this.link); // log("onHeaderClick: " + this.link);
_loadAppointmentHref(this.link); _loadAppointmentHref(this.link);
event.preventDefault(); event.preventDefault();
@ -947,14 +945,6 @@ function updateCalendarsList(method)
updateCalendarStatus(); updateCalendarStatus();
} }
function initCalendarContactsSelector(selId)
{
var selector = $(selId);
inhibitMyCalendarEntry();
updateCalendarStatus();
selector.changeNotification = updateCalendarsList;
}
function addContact(tag, fullContactName, contactId, contactName, contactEmail) function addContact(tag, fullContactName, contactId, contactName, contactEmail)
{ {
var uids = $('uixselector-calendarsList-uidList'); var uids = $('uixselector-calendarsList-uidList');
@ -1002,7 +992,7 @@ function onChangeCalendar(list) {
} }
function validateBrowseURL(input) { function validateBrowseURL(input) {
var button = $("browseUrlBtn"); var button = $("browseURLBtn");
if (input.value.length) { if (input.value.length) {
if (!button.enabled) if (!button.enabled)
@ -1011,7 +1001,7 @@ function validateBrowseURL(input) {
disableAnchor(button); disableAnchor(button);
} }
function browseUrl(anchor, event) { function browseURL(anchor, event) {
if (event.button == 0) { if (event.button == 0) {
var input = $("url"); var input = $("url");
var url = input.value; var url = input.value;
@ -1022,6 +1012,32 @@ function browseUrl(anchor, event) {
return false; return false;
} }
function initializeMenus() {
var menus = new Array("monthListMenu", "yearListMenu",
"appointmentsListMenu", "calendarsMenu", "searchMenu");
initMenusNamed(menus);
var calendarsList = $("calendarsList");
calendarsList.attachMenu("calendarsMenu");
var accessRightsMenuEntry = $("accessRightsMenuEntry");
accessRightsMenuEntry.addEventListener("mouseup",
onAccessRightsMenuEntryMouseUp,
false);
}
function onAccessRightsMenuEntryMouseUp(event) {
var folders = $("uixselector-calendarsList-display");
var selected = folders.getSelectedNodes()[0];
var uid = selected.getAttribute("uid");
if (uid == UserLogin)
url = ApplicationBaseURL + "acl";
else
url = UserFolderURL + "../" + uid + "/Calendar/acl";
openAclWindow(url, uid);
}
function configureDragHandles() { function configureDragHandles() {
var handle = $("verticalDragHandle"); var handle = $("verticalDragHandle");
if (handle) { if (handle) {
@ -1037,3 +1053,17 @@ function configureDragHandles() {
handle.lowerBlock=$("calendarView"); handle.lowerBlock=$("calendarView");
} }
} }
function initCalendarContactsSelector() {
var selector = $("calendarsList");
inhibitMyCalendarEntry();
updateCalendarStatus();
selector.changeNotification = updateCalendarsList;
}
function initCalendars() {
if (!document.body.hasClassName("popup"))
initCalendarContactsSelector();
}
window.addEventListener("load", initCalendars, false);

View File

@ -149,10 +149,10 @@ function sanitizeMailTo(dirtyMailTo) {
} }
function openMailComposeWindow(url) { function openMailComposeWindow(url) {
w = window.open(url, null, var w = window.open(url, null,
"width=680,height=520,resizable=1,scrollbars=1,toolbar=0," "width=680,height=520,resizable=1,scrollbars=1,toolbar=0,"
+ "location=0,directories=0,status=0,menubar=0" + "location=0,directories=0,status=0,menubar=0"
+ ",copyhistory=0"); + ",copyhistory=0");
w.focus(); w.focus();
return w; return w;
@ -367,6 +367,7 @@ function acceptMultiSelect(node) {
function onRowClick(event) { function onRowClick(event) {
var node = event.target; var node = event.target;
if (node.tagName == 'TD') if (node.tagName == 'TD')
node = node.parentNode; node = node.parentNode;
@ -754,17 +755,17 @@ function initCriteria()
function onContactAdd(node) function onContactAdd(node)
{ {
var selector = null; var selector = null;
var selectorUrl = '?popup=YES'; var selectorURL = '?popup=YES';
if (node) { if (node) {
selector = node.parentNode.parentNode; selector = node.parentNode.parentNode;
selectorUrl += ("&selectorId=" + selector.getAttribute("id")); selectorURL += ("&selectorId=" + selector.getAttribute("id"));
} }
urlstr = ApplicationBaseURL; urlstr = ApplicationBaseURL;
if (urlstr[urlstr.length-1] != '/') if (urlstr[urlstr.length-1] != '/')
urlstr += '/'; urlstr += '/';
urlstr += ("../../" + UserLogin + "/Contacts/" urlstr += ("../../" + UserLogin + "/Contacts/"
+ contactSelectorAction + selectorUrl); + contactSelectorAction + selectorURL);
// log (urlstr); // log (urlstr);
var w = window.open(urlstr, "Addressbook", var w = window.open(urlstr, "Addressbook",
"width=640,height=400,resizable=1,scrollbars=0"); "width=640,height=400,resizable=1,scrollbars=0");
@ -834,15 +835,45 @@ function initTabs()
} }
} }
function initMenusNamed(menuDivNames) {
for (var i = 0; i < menuDivNames.length; i++) {
var menuDIV = $(menuDivNames[i]);
if (menuDIV)
initMenu(menuDIV);
else
log("menu named '" + menuDivNames[i] + "' not found");
}
}
function initMenu(menuDIV) {
var lis = menuDIV.childNodesWithTag("ul")[0].childNodesWithTag("li");
for (var j = 0; j < lis.length; j++)
lis[j].addEventListener("mousedown", listRowMouseDownHandler, false);
var subMenus = menuDIV.childNodesWithTag("div");
for (var i = 0; i < subMenus.length; i++)
initMenu(subMenus[i]);
}
function onTabMouseDown(event) { function onTabMouseDown(event) {
event.cancelBubble = true; event.cancelBubble = true;
return false; event.preventDefault();
} }
function openExternalLink(anchor) { function openExternalLink(anchor) {
return false; return false;
} }
function openAclWindow(url, objectTitle) {
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.focus();
w.title = "Poil: " + objectTitle;
return w;
}
function onTabClick(event) { function onTabClick(event) {
var node = event.target; var node = event.target;
@ -932,7 +963,10 @@ function indexColor(number) {
var onLoadHandler = { var onLoadHandler = {
handleEvent: function (event) { handleEvent: function (event) {
queryParameters = parseQueryParameters('' + window.location); queryParameters = parseQueryParameters('' + window.location);
initLogConsole(); if (!document.body.hasClassName("popup")) {
initLogConsole();
initializeMenus();
}
initTabs(); initTabs();
configureDragHandles(); configureDragHandles();
configureSortableTableHeaders(); configureSortableTableHeaders();
@ -960,6 +994,14 @@ function onLinkBannerClick() {
checkAjaxRequestsState(); checkAjaxRequestsState();
} }
function onRightsAdministrationClick(event) {
var url = ApplicationBaseURL;
if (!url)
url = UserFolderURL;
openAclWindow(url+ "/acls");
event.preventDefault();
}
function configureLinkBanner() { function configureLinkBanner() {
var linkBanner = $("linkBanner"); var linkBanner = $("linkBanner");
if (linkBanner) { if (linkBanner) {
@ -969,6 +1011,7 @@ function configureLinkBanner() {
false); false);
anchors[i].addEventListener("click", onLinkBannerClick, false); anchors[i].addEventListener("click", onLinkBannerClick, false);
} }
anchors[4].addEventListener("click", onRightsAdministrationClick, false);
if (anchors.length > 6) if (anchors.length > 6)
anchors[6].addEventListener("click", toggleLogConsole, true); anchors[6].addEventListener("click", toggleLogConsole, true);
} }
@ -980,6 +1023,9 @@ window.addEventListener("load", onLoadHandler, false);
function configureDragHandles() { function configureDragHandles() {
} }
function initializeMenus() {
}
function onHeaderClick(event) { function onHeaderClick(event) {
window.alert("generic headerClick"); window.alert("generic headerClick");
} }