/* Copyright (C) 2000-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 "WOInput.h" #include "common.h" @interface WOBrowser : WOInput { // WODynamicElement: extraAttributes // WODynamicElement: otherTagString // inherited: name // inherited: value // inherited: disabled @protected WOAssociation *list; WOAssociation *item; WOAssociation *selection; WOAssociation *string; // WO4 WOAssociation *noSelectionString; // WO4 // non-WO: WOAssociation *singleSelection; // selection contains an item, not an array WOAssociation *multiple; // multiple selections allowed WOAssociation *size; } @end /* WOBrowser */ @implementation WOBrowser + (int)version { return [super version] + 0 /* v2 */; } + (void)initialize { NSAssert2([super version] == 2, @"invalid superclass (%@) version %i !", NSStringFromClass([self superclass]), [super version]); } - (id)initWithName:(NSString *)_name associations:(NSDictionary *)_config template:(WOElement *)_c { if ((self = [super initWithName:_name associations:_config template:_c])) { self->list = OWGetProperty(_config, @"list"); self->item = OWGetProperty(_config, @"item"); self->selection = OWGetProperty(_config, @"selection"); self->string = OWGetProperty(_config, @"string"); self->singleSelection = OWGetProperty(_config, @"singleSelection"); self->multiple = OWGetProperty(_config, @"multiple"); self->size = OWGetProperty(_config, @"size"); self->noSelectionString = OWGetProperty(_config, @"noSelectionString"); // compatiblity if (self->noSelectionString == nil) self->noSelectionString = OWGetProperty(_config, @"nilString"); if (self->multiple == nil) { self->multiple = [WOAssociation associationWithValue:[NSNumber numberWithBool:YES]]; self->multiple = [self->multiple retain]; } } return self; } - (void)dealloc { RELEASE(self->noSelectionString); RELEASE(self->singleSelection); RELEASE(self->list); RELEASE(self->item); RELEASE(self->selection); RELEASE(self->string); RELEASE(self->size); RELEASE(self->multiple); [super dealloc]; } /* handling request */ - (void)_takeSingleFormValue:(id)formValue fromRequest:(WORequest *)_request inContext:(WOContext *)_ctx { WOComponent *sComponent; NSArray *objects; id object; sComponent = [_ctx component]; objects = [self->list valueInComponent:sComponent]; if ([[formValue stringValue] isEqualToString:@"$"]) object = nil; // nil item selected else { int idx; object = nil; if ((idx = [formValue intValue]) >= 0) { if (idx < (int)[objects count]) object = [objects objectAtIndex:idx]; else { [sComponent logWithFormat: @"WOBrowser got invalid index '%i' (formvalue='%@') " @"for list with count %i !", idx, formValue, [objects count]]; } } else [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !", idx]; } if ([self->selection isValueSettable]) { NSArray *sel; if ([self->item isValueSettable]) [self->item setValue:object inComponent:sComponent]; if (object) { sel = [self->singleSelection boolValueInComponent:sComponent] ? [object retain] : [[NSArray alloc] initWithObjects:object,nil]; } else // nil item selected sel = nil; [self->selection setValue:sel inComponent:sComponent]; [sel release]; sel = nil; } } - (void)_takeMultiFormValue:(NSArray *)formValue fromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { WOComponent *sComponent; NSEnumerator *values; NSString *v; NSArray *objects; id object; values = [formValue objectEnumerator]; sComponent = [_ctx component]; objects = [self->list valueInComponent:sComponent]; if ([self->selection isValueSettable]) { NSMutableArray *sel; unsigned objCount; sel = [[NSMutableArray alloc] initWithCapacity:[formValue count]]; objCount = [objects count]; while ((v = [values nextObject])) { int idx; object = nil; if ((idx = [v intValue]) >= 0) { if (idx < (int)objCount) object = [objects objectAtIndex:idx]; else { [sComponent logWithFormat: @"WOBrowser got invalid index '%i'(formValue='%@' " @"for list with count %i !", idx, objCount, v]; } if ([self->item isValueSettable]) [self->item setValue:object inComponent:sComponent]; } else { [sComponent logWithFormat:@"WOBrowser got invalid index '%i' !", idx]; } if (object) [sel addObject:object]; } if ([self->singleSelection boolValueInComponent:sComponent]) { if ([sel count] > 1) { NSLog(@"WARNING(%@): " @"using singleSelection with multiple selected values", self); } [self->selection setValue:[sel lastObject] inComponent:sComponent]; } else [self->selection setValue:sel inComponent:sComponent]; [sel release]; sel = nil; } } - (void)takeValuesFromRequest:(WORequest *)_request inContext:(WOContext *)_ctx { WOComponent *sComponent; id formValue = nil; sComponent = [_ctx component]; if ([self->disabled boolValueInComponent:sComponent]) return; formValue = [_request formValuesForKey:OWFormElementName(self, _ctx)]; #if 0 [self logWithFormat:@"value=%@ ..", formValue]; #endif if ([self->value isValueSettable]) // TODO: is this correct? [self->value setValue:formValue inComponent:sComponent]; if ([formValue count] == 1) { [self _takeSingleFormValue:[formValue lastObject] fromRequest:_request inContext:_ctx]; } else if (formValue != nil) { [self _takeMultiFormValue:formValue fromRequest:_request inContext:_ctx]; } else { // nothing selected if ([self->item isValueSettable]) [self->item setValue:nil inComponent:sComponent]; if ([self->selection isValueSettable]) [self->selection setValue:nil inComponent:sComponent]; } } - (void)appendOptionsToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { WOComponent *sComponent = [_ctx component]; BOOL isSingle = NO; NSString *nilStr = nil; NSArray *array = nil; id selArray = nil; int i, toGo; nilStr = [self->noSelectionString stringValueInComponent:sComponent]; isSingle = [self->singleSelection boolValueInComponent:sComponent]; array = [self->list valueInComponent:sComponent]; selArray = [self->selection valueInComponent:sComponent]; toGo = [array count]; if (nilStr) { WOResponse_AddCString(_response, ""); } for (i = 0; i < toGo; i++) { NSString *v = nil; NSString *displayV = nil; id object = [array objectAtIndex:i]; BOOL isSelected; if ([self->item isValueSettable]) [self->item setValue:object inComponent:sComponent]; isSelected = NO; if (selArray) { isSelected = isSingle ? [selArray isEqual:object] : [selArray containsObject:object]; } v = self->value ? [self->value stringValueInComponent:sComponent] : [NSString stringWithFormat:@"%i", i]; displayV = self->string ? [self->string stringValueInComponent:sComponent] : [object stringValue]; if (displayV == nil) displayV = @""; WOResponse_AddCString(_response, ""); } } - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { BOOL isMultiple; unsigned s; if ([[_ctx request] isFromClientComponent]) return; isMultiple = [self->multiple boolValueInComponent:[_ctx component]]; s = [self->size unsignedIntValueInComponent:[_ctx component]]; WOResponse_AddCString(_response, ""); } /* description */ - (NSString *)associationDescription { NSMutableString *str; str = [NSMutableString stringWithCapacity:256]; [str appendString:[super associationDescription]]; if (self->list) [str appendFormat:@" list=%@", self->list]; if (self->item) [str appendFormat:@" item=%@", self->item]; if (self->selection) [str appendFormat:@" selection=%@", self->selection]; if (self->string) [str appendFormat:@" string=%@", self->string]; if (self->noSelectionString) [str appendFormat:@" noselection=%@", self->noSelectionString]; if (self->singleSelection) [str appendFormat:@" singleSelection=%@", self->singleSelection]; if (self->size) [str appendFormat:@" size=%@", self->size]; if (self->multiple) [str appendFormat:@" multiple=%@", self->multiple]; return str; } @end /* WOBrowser */