/*
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 */