/* Copyright (C) 2004 SKYRIX Software AG This file is part of OpenGroupware.org. OGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. OGo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with OGo; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // $Id$ #include /* AnaisAttendeeSelector Select a set of attendees using Anais. Bindings: attendees - array of iCalPerson objects selectorID - string to be used as the identifier for form/JS elements withCN - show CN of person (eg disabled for resources) withAddressBook - allow selection from private address book (default:NO) division - Anais division emailForUser - default EMail cnForUser - default CN role - role for submitted attendees Sample: */ @class iCalPerson; @interface AnaisAttendeeSelector : UIxComponent { NSString *selectorID; NSString *division; NSArray *attendees; iCalPerson *attendee; NSString *emailForUser; NSString *cnForUser; NSString *role; struct { int withCN:1; int withAddressBook:1; int reserved:30; } flags; } @end #include #include #include #include #include #include "common.h" @implementation AnaisAttendeeSelector static BOOL debugOn = NO; + (void)initialize { NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; debugOn = [ud boolForKey:@"AnaisDebugEnabled"]; } - (void)dealloc { [self->role release]; [self->emailForUser release]; [self->cnForUser release]; [self->division release]; [self->selectorID release]; [self->attendee release]; [self->attendees release]; [super dealloc]; } /* notifications */ - (void)sleep { [self->attendee release]; self->attendee = nil; [super sleep]; } /* accessors */ - (void)setAttendees:(NSArray *)_attendees { ASSIGN(self->attendees, _attendees); } - (NSArray *)attendees { return self->attendees; } - (BOOL)hasAttendees { return [[self attendees] count] > 0 ? YES : NO; } - (BOOL)hasNoAttendees { return [[self attendees] count] == 0 ? YES : NO; } - (void)setWithCN:(BOOL)_flag { self->flags.withCN = _flag ? 1 : 0; } - (BOOL)withCN { return self->flags.withCN ? YES : NO; } - (void)setWithAddressBook:(BOOL)_flag { self->flags.withAddressBook = _flag ? 1 : 0; } - (BOOL)withAddressBook { return self->flags.withAddressBook ? YES : NO; } - (void)setAttendee:(iCalPerson *)_attendee { ASSIGN(self->attendee, _attendee); } - (iCalPerson *)attendee { return self->attendee; } - (void)setDivision:(NSString *)_value { ASSIGNCOPY(self->division, _value); } - (NSString *)division { return self->division; } - (void)setRole:(NSString *)_value { ASSIGNCOPY(self->role, _value); } - (NSString *)role { return self->role; } - (void)setEmailForUser:(NSString *)_value { ASSIGNCOPY(self->emailForUser, _value); } - (NSString *)emailForUser { return self->emailForUser; } - (void)setCnForUser:(NSString *)_value { ASSIGNCOPY(self->cnForUser, _value); } - (NSString *)cnForUser { return self->cnForUser; } - (BOOL)showDefaultAttendees { return [self hasNoAttendees] && [[self emailForUser] length] > 0 ? YES : NO; } /* email, stat, cn */ - (NSString *)combinedInfoForUser { NSString *e, *c; e = [self emailForUser]; c = [self cnForUser]; return [[e stringByAppendingString:@";0;"] stringByAppendingString:c]; } - (NSString *)combinedInfo { iCalPerson *p; NSString *e, *stat, *c; p = [self attendee]; e = [p rfc822Email]; c = [p cnForDisplay]; stat = [NSString stringWithFormat:@";%d;", [p participationStatus]]; return [[e stringByAppendingString:stat] stringByAppendingString:c]; } /* id accessors */ - (void)setSelectorID:(NSString *)_value { ASSIGNCOPY(self->selectorID, _value); } - (NSString *)selectorID { return self->selectorID; } - (NSString *)capitalizedSelectorID { return [[self selectorID] capitalizedString]; } - (NSString *)windowId { /* eg: 'Resources' */ return [[self capitalizedSelectorID] stringByAppendingString:@"s"]; } - (NSString *)callbackName { /* eg: 'addResource' */ return [@"add" stringByAppendingString:[self capitalizedSelectorID]]; } - (NSString *)tableId { /* eg: 'resources' */ return [[self selectorID] stringByAppendingString:@"s"]; } - (NSString *)checkboxId { /* eg: 'resources' */ return [self tableId]; /* TODO: znek, is this ok? */ } /* handling requests */ - (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values { unsigned i, count; NSMutableArray *result; count = [_values count]; result = [NSMutableArray arrayWithCapacity:count]; for (i = 0; i < count; i++) { NSString *pString, *email, *cn; NSRange r; iCalPerson *p; pString = [_values objectAtIndex:i]; if ([pString length] == 0) continue; p = [[iCalPerson alloc] init]; /* sample: 'test.et.di.cete-lyon@equipement.gouv.fr;1;test' */ /* delimiter between email and partStat */ r = [pString rangeOfString:@";"]; if (r.length > 0) { email = [pString substringToIndex:r.location]; pString = [pString substringFromIndex:NSMaxRange(r)]; /* delimiter between partStat and CN */ r = [pString rangeOfString:@";"]; if (r.length > 0) { NSString *stat; stat = [pString substringToIndex:r.location]; [p setParticipationStatus:[stat intValue]]; cn = [pString substringFromIndex:NSMaxRange(r)]; if ([cn length] == 0) cn = nil; } } else { email = pString; cn = nil; } if (cn == nil) { /* fallback */ AgenorUserManager *um = [AgenorUserManager sharedUserManager]; cn = [um getCNForUID:[um getUIDForEmail:email]]; } [p setEmail:[@"mailto:" stringByAppendingString:email]]; if ([cn isNotNull]) [p setCn:cn]; /* see RFC2445, sect. 4.2.16 for details */ [p setRole:[self role]]; [result addObject:p]; [p release]; } return result; } - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { /* OK, we have a special form value processor */ NSArray *tmp; [self debugWithFormat:@"Note: will take values ..."]; tmp = [self getICalPersonsFromFormValues: [_rq formValuesForKey:[self checkboxId]]]; [self debugWithFormat:@" got %i attendees: %@", [tmp count], tmp]; [self setAttendees:tmp]; } /* response generation */ - (NSString *)jsCode { NSMutableString *ms; WOContext *ctx; NSString *s; ms = [NSMutableString stringWithCapacity:128]; ctx = [self context]; if (![[ctx valueForKey:@"HasAddTableAnaisAttendeeSelector"] boolValue]) { static NSString *script = \ @"function unescapeCallbackParameter(s) {\n" @" s = s.replace(/'/g, \"'\");\n" @" s = s.replace(/"/g, '\"');\n" @" return s;\n" @"}\n" @"\n" @"function addToTable(tableId, type, cn, dn, email, uid, sn) {\n" @" var test = document.getElementById(email);\n" @" if(test)\n" @" return;\n" @"\n" @" var table = document.getElementById(tableId);\n" @" var tr = document.createElement('tr');\n" @" var td, checkbox, text;\n" @"\n" @" cn = this.unescapeCallbackParameter(cn);\n" @" td = document.createElement('td');\n" @" checkbox = document.createElement('input');\n" @" checkbox.setAttribute('type', 'checkbox');\n" @" checkbox.setAttribute('checked', 'checked');\n" @" checkbox.setAttribute('value', email + ';0;' + cn);\n" @" checkbox.setAttribute('id', email);\n" @" checkbox.setAttribute('name', tableId);\n" @" td.appendChild(checkbox);\n" @" tr.appendChild(td);\n" @" td = document.createElement('td');\n" @" text = document.createTextNode(cn);\n" @" td.appendChild(text);\n" @" tr.appendChild(td);\n" @" table.appendChild(tr);\n" @"}\n"; [ms appendString:script]; [ctx takeValue:[NSNumber numberWithBool:YES] forKey:@"HasAddTableAnaisAttendeeSelector"]; } s = // @"function %@(type, cn, dn, email, uid, sn) {\n" // @" addToTable('%@', type, cn, dn, email, uid, sn);\n" // @"}\n"; @"function %@() {\n" @" var type=arguments[0];\n" @" var email=arguments[1];\n" @" var uid=arguments[2];\n" @" var sn=arguments[3];\n" @" var cn=arguments[4];\n" @" var dn=arguments[5];\n" @" addToTable('%@', type, cn, dn, email, uid, sn);\n" @"}\n"; [ms appendFormat:s, [self callbackName], [self tableId]]; return ms; } /* debugging */ - (BOOL)isDebuggingEnabled { return debugOn; } @end /* AnaisAttendeeSelector */