2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <NGObjWeb/WODynamicElement.h>
24 @interface WOTable : WODynamicElement
26 // WODynamicElement: extraAttributes
27 // WODynamicElement: otherTagString
29 WOAssociation *list; // array of objects to iterate through
30 WOAssociation *item; // current item in the array
31 WOAssociation *maxColumns; // number of columns
32 WOAssociation *index; // current index
33 WOAssociation *col; // current column (is updated with each iteration)
34 WOAssociation *row; // current row (is updated with each iteration)
36 WOAssociation *cellAlign; // current cell align
37 WOAssociation *cellVAlign; // current cell valign
38 WOAssociation *rowBackgroundColor; // current row background color;
39 WOAssociation *cellBackgroundColor; // current cell background color;
42 table attributes are implemented as extraAttributes:
44 tableBackgroundColor, --> bgColor
46 cellpadding, --> cellpadding
47 cellspacing, --> cellspacing
50 /* non WO attribute */
51 WOAssociation *horizontal; // order items horizontal (default = NO)
52 WOAssociation *hasOwnTDs; // don't draw TDs
60 static NSString *_WOTableHeaderString_ = @"_WOTableHeaderString_";
61 static NSString *_WOTableContentString_ = @"_WOTableContentString_";
62 static NSString *_WOTableContextMode_ = @"_WOTableContextMode_";
64 @implementation WOTable
66 - (id)initWithName:(NSString *)_name
67 associations:(NSDictionary *)_config
68 template:(WOElement *)_c
70 if ((self = [super initWithName:_name associations:_config template:_c])) {
71 self->list = WOExtGetProperty(_config, @"list");
72 self->item = WOExtGetProperty(_config, @"item");
73 self->maxColumns = WOExtGetProperty(_config, @"maxColumns");
74 self->index = WOExtGetProperty(_config, @"index");
75 self->col = WOExtGetProperty(_config, @"col");
76 self->row = WOExtGetProperty(_config, @"row");
77 self->horizontal = WOExtGetProperty(_config, @"horizontal");
78 self->hasOwnTDs = WOExtGetProperty(_config, @"hasOwnTDs");
80 self->cellAlign = WOExtGetProperty(_config, @"cellAlign");
81 self->cellVAlign = WOExtGetProperty(_config, @"cellVAlign");
83 self->rowBackgroundColor =
84 WOExtGetProperty(_config, @"rowBackgroundColor");
85 self->cellBackgroundColor =
86 WOExtGetProperty(_config, @"cellBackgroundColor");
88 self->template = RETAIN(_c);
94 [self->template release];
98 [self->maxColumns release];
99 [self->index release];
102 [self->horizontal release];
103 [self->hasOwnTDs release];
105 [self->cellAlign release];
106 [self->cellVAlign release];
107 [self->rowBackgroundColor release];
108 [self->cellBackgroundColor release];
112 static inline void _applyIndex(WOTable *self, WOComponent *cmp, unsigned _idx)
116 unsigned r, c, cnt, cols;
118 isHor = [self->horizontal boolValueInComponent:cmp];
119 cols = [self->maxColumns unsignedIntValueInComponent:cmp];
120 array = [self->list valueInComponent:cmp];
122 cols = (cols) ? cols : 1;
123 r = (isHor) ? (_idx / cols) + 1 : _idx % ((cnt / cols)+1) + 1;
124 c = (isHor) ? (_idx % cols) + 1 : _idx / ((cnt / cols)+1) + 1;
126 if ([self->index isValueSettable])
127 [self->index setUnsignedIntValue:_idx inComponent:cmp];
129 if ([self->row isValueSettable])
130 [self->row setUnsignedIntValue:r inComponent:cmp];
132 if ([self->col isValueSettable])
133 [self->col setUnsignedIntValue:c inComponent:cmp];
135 if ([self->item isValueSettable]) {
137 [self->item setValue:[array objectAtIndex:_idx] inComponent:cmp];
139 [cmp logWithFormat:@"WOTable: array did change, index is invalid."];
140 [self->item setValue:nil inComponent:cmp];
146 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
151 cmp = [_ctx component];
152 array = [self->list valueInComponent:cmp];
155 [_ctx appendZeroElementIDComponent];
157 [_ctx setObject:_WOTableContentString_ forKey:_WOTableContextMode_];
159 for (i=0; i<cnt; i++) {
160 _applyIndex(self, cmp, i);
161 [self->template takeValuesFromRequest:_req inContext:_ctx];
162 [_ctx incrementLastElementIDComponent];
165 [_ctx removeObjectForKey:_WOTableContextMode_];
166 [_ctx deleteLastElementIDComponent];
169 - (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
173 cmp = [_ctx component];
175 if ([self->list valueInComponent:cmp] != nil) {
176 unsigned idx = [[_ctx currentElementID] intValue];
179 [_ctx consumeElementID]; // consume index
180 s = [[NSString alloc] initWithFormat:@"%i", idx];
181 [_ctx appendElementIDComponent:s];
183 _applyIndex(self, cmp, idx);
184 result = [self->template invokeActionForRequest:_req inContext:_ctx];
185 [_ctx deleteLastElementIDComponent];
190 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
191 WOComponent *cmp = nil;
192 NSArray *array = nil;
193 BOOL isHor = NO; // is horizontal
195 unsigned c, colCount; // column index
196 unsigned r, rowCount; // row index
198 unsigned ownTDCount = 0;
200 cmp = [_ctx component];
201 colCount = [self->maxColumns unsignedIntValueInComponent:cmp];
202 array = [self->list valueInComponent:cmp];
204 isHor = [self->horizontal boolValueInComponent:cmp];
205 drawTD = ![self->hasOwnTDs boolValueInComponent:cmp];
207 ownTDCount = [self->hasOwnTDs intValueInComponent:cmp];
209 colCount = (colCount < cnt) ? colCount : cnt;
210 colCount = (colCount) ? colCount : 1;
211 rowCount = ((cnt % colCount) > 0) ? (cnt / colCount) + 1 : (cnt / colCount);
213 [_response appendContentString:@"<table "];
214 [self appendExtraAttributesToResponse:_response inContext:_ctx];
215 [_response appendContentCharacter:'>'];
218 NSString *rowColor = [self->rowBackgroundColor stringValueInComponent:cmp];
221 [_ctx setObject:_WOTableHeaderString_ forKey:_WOTableContextMode_];
222 [_response appendContentString:@"<tr"];
224 [_response appendContentString:@" bgcolor=\""];
225 [_response appendContentString:rowColor];
226 [_response appendContentCharacter:'"'];
228 [_response appendContentCharacter:'>'];
229 for (i = 0; i < colCount; i++) {
230 [self->template appendToResponse:_response inContext:_ctx];
232 [_response appendContentString:@"</tr>"];
233 [_ctx removeObjectForKey:_WOTableContextMode_];
237 [_ctx setObject:_WOTableContentString_ forKey:_WOTableContextMode_];
239 for (r=0; r<rowCount; r++) {
240 NSString *rowColor = [self->rowBackgroundColor stringValueInComponent:cmp];
241 [_response appendContentString:@"<tr"];
243 [_response appendContentString:@" bgcolor=\""];
244 [_response appendContentString:rowColor];
245 [_response appendContentCharacter:'"'];
247 [_response appendContentCharacter:'>'];
249 for (c=0; c<colCount; c++) {
250 NSString *cColor = [self->cellBackgroundColor stringValueInComponent:cmp];
251 NSString *align = [self->cellAlign stringValueInComponent:cmp];
252 NSString *valign = [self->cellVAlign stringValueInComponent:cmp];
253 NSString *width = nil;
254 unsigned i = (isHor) ? r*colCount+c : c*rowCount+r;
257 [_response appendContentString:@"<td"];
258 width = [[NSString alloc] initWithFormat:@"%d%%", (int)(100 / colCount)];
260 [_response appendContentString:@" width=\""];
261 [_response appendContentString:width];
262 [_response appendContentCharacter:'"'];
266 [_response appendContentString:@" bgcolor=\""];
267 [_response appendContentString:cColor];
268 [_response appendContentCharacter:'"'];
271 [_response appendContentString:@" align=\""];
272 [_response appendContentString:align];
273 [_response appendContentCharacter:'"'];
276 [_response appendContentString:@" valign=\""];
277 [_response appendContentString:valign];
278 [_response appendContentCharacter:'"'];
280 [_response appendContentCharacter:'>'];
285 s = [[NSString alloc] initWithFormat:@"%i", i];
286 [_ctx appendElementIDComponent:s];
288 _applyIndex(self, cmp, i);
289 [self->template appendToResponse:_response inContext:_ctx];
290 [_ctx deleteLastElementIDComponent];
292 else if (ownTDCount > 0) {
295 for (j = 0; j < ownTDCount; j++)
296 [_response appendContentString:@"<td> </td>"];
299 [_response appendContentString:@" "];
302 [_response appendContentString:@"</td>"];
304 [_response appendContentString:@"</tr>"];
307 [_ctx removeObjectForKey:_WOTableContextMode_];
309 [_response appendContentString:@"</table>"];
314 - (NSString *)associationDescription {
315 NSMutableString *str;
317 str = [NSMutableString stringWithCapacity:128];
318 if (self->list) [str appendFormat:@" list=%@", self->list];
319 if (self->item) [str appendFormat:@" item=%@", self->item];
320 if (self->maxColumns) [str appendFormat:@" maxColumns=%@", self->maxColumns];
321 if (self->index) [str appendFormat:@" index=%@", self->index];
322 if (self->col) [str appendFormat:@" col=%@", self->col];
323 if (self->row) [str appendFormat:@" row=%@", self->row];
324 if (self->horizontal) [str appendFormat:@" horizontal=%@", self->horizontal];
325 if (self->hasOwnTDs) [str appendFormat:@" hasOwnTDs=%@", self->hasOwnTDs];
326 if (self->template) [str appendFormat:@" template=%@", self->template];
332 @interface WOTableContextKey : WODynamicElement
338 @implementation WOTableContextKey
340 - (NSString *)_contextValue {
344 - (id)initWithName:(NSString *)_name
345 associations:(NSDictionary *)_config
346 template:(WOElement *)_c
348 if ((self = [super initWithName:_name associations:_config template:_c])) {
349 self->template = [_c retain];
355 [self->template release];
359 - (BOOL)doShow:(WOContext *)_ctx {
360 NSString *key = [_ctx objectForKey:_WOTableContextMode_];
365 return [key isEqualToString:[self _contextValue]];
368 // ******************** responder ********************
370 - (void)takeValuesFromRequest:(WORequest *)_request
371 inContext:(WOContext *)_ctx
373 if (![self doShow:_ctx])
376 [_ctx appendElementIDComponent:@"1"];
377 [self->template takeValuesFromRequest:_request inContext:_ctx];
378 [_ctx deleteLastElementIDComponent];
381 - (id)invokeActionForRequest:(WORequest *)_request inContext:(WOContext *)_ctx {
385 if ((state = [[_ctx currentElementID] stringValue]) == nil)
388 [_ctx consumeElementID]; // consume state-id (on or off)
390 if (![state isEqualToString:@"1"])
393 [_ctx appendElementIDComponent:state];
394 result = [self->template invokeActionForRequest:_request inContext:_ctx];
395 [_ctx deleteLastElementIDComponent];
399 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
400 if (![self doShow:_ctx])
403 [_ctx appendElementIDComponent:@"1"];
404 [self->template appendToResponse:_response inContext:_ctx];
405 [_ctx deleteLastElementIDComponent];
408 @end /* WOTableContextKey */
410 @interface WOTableHeader : WOTableContextKey
411 @end /* WOTableHeader */
413 @implementation WOTableHeader
415 - (NSString *)_contextValue {
416 return _WOTableHeaderString_;
419 @end /* WOTableHeader */
422 @interface WOTableContent : WOTableContextKey
423 @end /* WOTableContent */
425 @implementation WOTableContent
427 - (NSString *)_contextValue {
428 return _WOTableContentString_;
431 @end /* WOTableContent */