]> err.no Git - sope/blob - sope-appserver/WOExtensions/WORadioButtonMatrix.m
updated framework version
[sope] / sope-appserver / WOExtensions / WORadioButtonMatrix.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include <NGObjWeb/WODynamicElement.h>
23
24 @interface WORadioButtonMatrix : WODynamicElement
25 {
26   // WODynamicElement: extraAttributes (are appended at the main table)
27   // WODynamicElement: otherTagString
28 @protected
29   WOAssociation *list;       // array of objects to iterate through
30   WOAssociation *item;       // current item in the array
31   WOAssociation *selection;  // selected object
32   WOAssociation *maxColumns; // number of columns
33   
34   /* non WO attribute */
35   WOAssociation *index;      // current index
36   WOAssociation *col;        // current column (is updated with each iteration)
37   WOAssociation *row;        // current row    (is updated with each iteration)
38
39   WOAssociation *cellAlign;  // current cell align
40   WOAssociation *cellVAlign; // current cell valign
41   WOAssociation *rowBackgroundColor;  // current row background color;
42   WOAssociation *cellBackgroundColor; // current cell background color;
43   WOAssociation *horizontal;   // order items horizontal (default = NO)
44
45   WOElement     *template;
46 }
47 @end
48
49 #include "common.h"
50
51 // TODO: this shares a lot of common code with WOCheckBoxMatrix!!
52
53 @implementation WORadioButtonMatrix
54
55 static NSString *retStrForInt(int i) {
56   switch(i) {
57   case 0:  return @"0";
58   case 1:  return @"1";
59   case 2:  return @"2";
60   case 3:  return @"3";
61   case 4:  return @"4";
62   case 5:  return @"5";
63   case 6:  return @"6";
64   case 7:  return @"7";
65   case 8:  return @"8";
66   case 9:  return @"9";
67   case 10: return @"10";
68     // TODO: find useful count!
69   default:
70     return [[NSString alloc] initWithFormat:@"%i", i];
71   }
72 }
73
74 - (id)initWithName:(NSString *)_name
75   associations:(NSDictionary *)_config
76   template:(WOElement *)_c
77 {
78   if ((self = [super initWithName:_name associations:_config template:_c])) {
79     self->list       = WOExtGetProperty(_config, @"list");
80     self->item       = WOExtGetProperty(_config, @"item");
81     self->selection  = WOExtGetProperty(_config, @"selection");
82     self->maxColumns = WOExtGetProperty(_config, @"maxColumns");
83     
84     self->index      = WOExtGetProperty(_config, @"index");
85     self->col        = WOExtGetProperty(_config, @"col");
86     self->row        = WOExtGetProperty(_config, @"row");
87     self->horizontal = WOExtGetProperty(_config, @"horizontal");
88
89     self->cellAlign  = WOExtGetProperty(_config, @"cellAlign");
90     self->cellVAlign = WOExtGetProperty(_config, @"cellVAlign");
91     
92     self->rowBackgroundColor  = 
93       WOExtGetProperty(_config, @"rowBackgroundColor");
94     self->cellBackgroundColor = 
95       WOExtGetProperty(_config, @"cellBackgroundColor");
96
97     self->template = RETAIN(_c);
98   }
99   return self;
100 }
101
102 - (void)dealloc {
103   [self->template release];
104   
105   [self->list release];
106   [self->item release];
107   [self->maxColumns release];
108   [self->selection release];
109   
110   [self->index release];
111   [self->col release];
112   [self->row release];
113   [self->horizontal release];
114
115   [self->cellAlign release];
116   [self->cellVAlign release];
117   [self->rowBackgroundColor release];
118   [self->cellBackgroundColor release];
119   [super dealloc];
120 }
121
122 static inline
123 void _applyIndex(WORadioButtonMatrix *self, WOComponent *cmp, unsigned _idx)
124 {
125   NSArray  *array;
126   BOOL     isHor;
127   unsigned r, c, cnt, cols;
128
129   isHor = [self->horizontal boolValueInComponent:cmp];
130   cols  = [self->maxColumns unsignedIntValueInComponent:cmp];
131   array = [self->list valueInComponent:cmp];
132   cnt   = [array count];
133   cols  = (cols) ? cols : 1;
134   r     = (isHor) ? (_idx / cols) + 1 : _idx % ((cnt / cols)+1) + 1;
135   c     = (isHor) ? (_idx % cols) + 1 : _idx / ((cnt / cols)+1) + 1;
136     
137   if ([self->index isValueSettable])
138     [self->index setUnsignedIntValue:_idx inComponent:cmp];
139
140   if ([self->row isValueSettable])
141     [self->row setUnsignedIntValue:r inComponent:cmp];
142
143   if ([self->col isValueSettable])
144     [self->col setUnsignedIntValue:c inComponent:cmp];
145
146   if ([self->item isValueSettable]) {
147     if (_idx < cnt)
148       [self->item setValue:[array objectAtIndex:_idx] inComponent:cmp];
149     else {
150       [cmp logWithFormat:
151            @"WORadioButtonMatrix: array did change, index is invalid."];
152       [self->item setValue:nil inComponent:cmp];
153     }
154   }
155 }
156
157
158 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
159   WOComponent *cmp;
160   NSArray     *array;
161   id          formValue;
162   unsigned    cnt, i;
163
164   cmp   = [_ctx component];
165   array = [self->list valueInComponent:cmp];
166   cnt   = [array count];
167
168   [_ctx appendZeroElementIDComponent];
169   for (i=0; i<cnt; i++) {
170     _applyIndex(self, cmp, i);
171     [self->template takeValuesFromRequest:_req inContext:_ctx];
172     [_ctx incrementLastElementIDComponent];
173   }
174   [_ctx deleteLastElementIDComponent];
175
176   if ((formValue = [_req formValueForKey:[_ctx elementID]])) {
177     i = [formValue unsignedIntValue];
178     _applyIndex(self, cmp, i);
179     
180     if ([self->selection isValueSettable])
181       [self->selection setValue:[array objectAtIndex:i] inComponent:cmp];
182   }
183 }
184
185 - (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
186   WOComponent *cmp;
187   id          result = nil;
188   unsigned    idx;
189   NSString    *s;
190
191   cmp = [_ctx component];
192   if ([self->list valueInComponent:cmp] == nil)
193     return nil;
194   
195   idx = [[_ctx currentElementID] intValue];
196   [_ctx consumeElementID]; // consume index
197   s = retStrForInt(idx);
198   [_ctx appendElementIDComponent:s];
199   [s release];
200   _applyIndex(self, cmp, idx);
201   result = [self->template invokeActionForRequest:_req inContext:_ctx];
202   [_ctx deleteLastElementIDComponent];
203   return result;
204 }
205
206 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
207   WOComponent *cmp   = nil;
208   NSArray     *array = nil;
209   NSString    *n     = nil;
210   id          sel    = nil;
211   BOOL        isHor  = NO; // is horizontal
212   unsigned    c, colCount; // column index
213   unsigned    r, rowCount; // row    index
214   unsigned    cnt;
215
216   cmp      = [_ctx component];
217   colCount = [self->maxColumns unsignedIntValueInComponent:cmp];
218   array    = [self->list valueInComponent:cmp];
219   cnt      = [array count];
220   isHor    = [self->horizontal boolValueInComponent:cmp];
221   sel      = [self->selection valueInComponent:cmp];
222
223   colCount = (colCount) ? colCount : 1;
224   rowCount = ((cnt % colCount) > 0) ? (cnt / colCount) + 1 : (cnt / colCount);
225
226   n = [_ctx elementID];
227
228   [_response appendContentString:@"<table "];
229   [self appendExtraAttributesToResponse:_response inContext:_ctx];
230   [_response appendContentCharacter:'>'];
231
232   for (r = 0; r < rowCount; r++) {
233     NSString *rowColor;
234     
235     rowColor = [self->rowBackgroundColor stringValueInComponent:cmp];
236     [_response appendContentString:@"<tr"];
237     if (rowColor) {
238       [_response appendContentString:@" bgcolor=\""];
239       [_response appendContentString:rowColor];
240       [_response appendContentCharacter:'"'];
241     }
242     [_response appendContentCharacter:'>'];
243     
244     for (c = 0; c < colCount; c++) {
245       NSString *cColor = [self->cellBackgroundColor stringValueInComponent:cmp];
246       NSString *align  = [self->cellAlign  stringValueInComponent:cmp];
247       NSString *valign = [self->cellVAlign stringValueInComponent:cmp];
248       unsigned i = (isHor) ? r*colCount+c : c*rowCount+r;
249
250       [_response appendContentString:@"<td"];
251       if (cColor) {
252         [_response appendContentString:@" bgcolor=\""];
253         [_response appendContentString:cColor];
254         [_response appendContentCharacter:'"'];
255       }
256       if (align) {
257         [_response appendContentString:@" align=\""];
258         [_response appendContentString:align];
259         [_response appendContentCharacter:'"'];
260       }
261       if (valign) {
262         [_response appendContentString:@" valign=\""];
263         [_response appendContentString:valign];
264         [_response appendContentCharacter:'"'];
265       }
266       [_response appendContentCharacter:'>'];
267       
268       if (i < cnt) {
269         NSString *s;
270         id obj;
271         
272         s = retStrForInt(i);
273         [_ctx appendElementIDComponent:s];
274         [s release];
275         _applyIndex(self, cmp, i);
276         obj = [self->item valueInComponent:cmp];
277
278         /* append radio button */
279         [_response appendContentString:@"<input type=\"radio\" name=\""];
280         [_response appendContentHTMLAttributeValue:n];
281         [_response appendContentString:@"\" value=\""];
282         s = retStrForInt(i);
283         [_response appendContentString:s];
284         [s release];
285         [_response appendContentCharacter:'"'];
286   
287         if ([sel isEqual:obj])
288          [_response appendContentString:@" checked=\"checked\""];
289         
290         [_response appendContentString:
291                      (_ctx->wcFlags.xmlStyleEmptyElements ? @" />" : @">")];
292         
293         // append template
294         [self->template appendToResponse:_response inContext:_ctx];
295         [_ctx deleteLastElementIDComponent];
296       }
297       else
298         [_response appendContentString:@"&nbsp;"];
299       [_response appendContentString:@"</td>"];
300     }
301     [_response appendContentString:@"</tr>"];
302   }
303   [_response appendContentString:@"</table>"];
304 }
305
306 /* description */
307
308 - (NSString *)associationDescription {
309   NSMutableString *str;
310
311   str = [NSMutableString stringWithCapacity:128];
312   if (self->list)       [str appendFormat:@" list=%@",       self->list];
313   if (self->item)       [str appendFormat:@" item=%@",       self->item];
314   if (self->maxColumns) [str appendFormat:@" maxColumns=%@", self->maxColumns];
315   if (self->selection)  [str appendFormat:@" selection=%@",  self->selection];
316   if (self->index)      [str appendFormat:@" index=%@",      self->index];
317   if (self->col)        [str appendFormat:@" col=%@",        self->col];
318   if (self->row)        [str appendFormat:@" row=%@",        self->row];
319   if (self->horizontal) [str appendFormat:@" horizontal=%@", self->horizontal];
320   if (self->template)   [str appendFormat:@" template=%@",   self->template];
321
322   return str;
323 }
324
325 @end /* WORadioButtonMatrix */