]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOText.m
minor improvement to WOHttpAdaptor, bumped framework revisions
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOText.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 "WOInput.h"
23 #include "decommon.h"
24 #import <Foundation/NSNumberFormatter.h>
25 #import <Foundation/NSDateFormatter.h>
26
27 @interface WOText : WOInput
28 {
29   // inherited: name
30   // inherited: value
31   // inherited: disabled
32 @protected
33   // non WO:
34   WOAssociation *rows;
35   WOAssociation *cols;
36   WOAssociation *numberformat; // string
37   WOAssociation *dateformat;   // string
38   WOAssociation *formatter;
39 }
40
41 @end /* WOText */
42
43 @interface NSObject(UsedKeyPath)
44 - (NSString *)keyPath;
45 @end
46
47 @implementation WOText
48
49 - (id)initWithName:(NSString *)_name
50   associations:(NSDictionary *)_config
51   template:(WOElement *)_t
52 {
53
54   if ((self = [super initWithName:_name associations:_config template:_t])) {
55     self->rows         = OWGetProperty(_config, @"rows");
56     self->cols         = OWGetProperty(_config, @"cols");
57     self->formatter    = OWGetProperty(_config, @"formatter");
58     self->numberformat = OWGetProperty(_config, @"numberformat");
59     self->dateformat   = OWGetProperty(_config, @"dateformat");
60     
61     if (self->formatter == nil) {
62       if ([_config objectForKey:@"formatterClass"] != nil) {
63         id className;
64
65         className = OWGetProperty(_config, @"formatterClass");
66         className = [className autorelease];
67         
68         className = [className valueInComponent:nil];
69         className = NSClassFromString(className);
70         className = [[className alloc] init];
71
72         self->formatter = [WOAssociation associationWithValue:className];
73         self->formatter = [self->formatter retain];
74         [className release];
75       }
76     }
77
78     // check formats
79     {
80       int num = 0;
81       if (self->formatter)    num++;
82       if (self->numberformat) num++;
83       if (self->dateformat)   num++;
84       if (num > 1)
85         NSLog(@"WARNING: more than one formats specified in element %@", self);
86     }
87   }
88   return self;
89 }
90
91 - (void)dealloc {
92   [self->numberformat release];
93   [self->dateformat   release];
94   [self->formatter    release];
95   [self->rows         release];
96   [self->cols         release];
97   [super dealloc];
98 }
99
100 /* formatter */
101
102 static inline NSFormatter *_getFormatter(WOText *self, WOContext *_ctx) {
103   NSFormatter *fmt = nil;
104   
105   if (self->numberformat != nil) {
106     fmt = [[[NSNumberFormatter alloc] init] autorelease];
107     [(NSNumberFormatter *)fmt setFormat:
108         [self->numberformat valueInComponent:[_ctx component]]];
109   }
110   else if (self->dateformat != nil) {
111     fmt = [[NSDateFormatter alloc]
112                             initWithDateFormat:
113                               [self->dateformat valueInComponent:
114                                                   [_ctx component]]
115                             allowNaturalLanguage:NO];
116     fmt = [fmt autorelease];
117   }
118   else if (self->formatter) {
119     fmt = [self->formatter valueInComponent:[_ctx component]];
120   }
121
122   return fmt;
123 }
124
125 /* handle requests */
126
127 - (id)parseFormValue:(id)_value inContext:(WOContext *)_ctx {
128   NSFormatter *fmt;
129   NSException *formatException = nil;
130   NSString    *keyPath         = nil;
131   NSString *errorText = nil;
132   id       object     = nil;
133
134   fmt = _getFormatter(self, _ctx);
135   if (fmt == nil)
136     return [super parseFormValue:_value inContext:_ctx];
137
138   //fmt = [self->formatter valueInComponent:[_ctx component]];
139
140   if ([fmt getObjectValue:&object forString:[_value stringValue]
141              errorDescription:&errorText]) {
142
143       return object;
144   }
145
146       
147   if ([self->value respondsToSelector:@selector(keyPath)])
148     keyPath = [(id)self->value keyPath];
149
150   formatException = [NSException exceptionWithName:@"WOValidationException"
151                                      reason:errorText
152                                      userInfo:nil];
153   
154   [[_ctx component] validationFailedWithException:formatException
155                     value:_value
156                     keyPath:keyPath];
157   return nil;
158 }
159
160 /* generate response */
161
162 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
163   WOComponent *sComponent;
164   NSFormatter *fmt;
165   id          v;
166   unsigned    r;
167   unsigned    c;
168   
169   sComponent = [_ctx component];
170   v  = [self->value valueInComponent:sComponent];
171   r  = [self->rows  unsignedIntValueInComponent:sComponent];
172   c  = [self->cols  unsignedIntValueInComponent:sComponent];
173   
174   fmt = _getFormatter(self, _ctx);
175   if (fmt) {
176     NSString *formattedObj = nil;
177
178     formattedObj = [fmt editingStringForObjectValue:v];
179     v = formattedObj;
180   }
181   else
182     v = [v stringValue];
183   
184   WOResponse_AddCString(_response, "<textarea name=\"");
185   [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
186   WOResponse_AddChar(_response, '"');
187   if (r > 0) {
188     WOResponse_AddCString(_response, " rows=\"");
189     WOResponse_AddUInt(_response, r);
190     WOResponse_AddChar(_response, '"');
191   }
192   if (c > 0) {
193     WOResponse_AddCString(_response, " cols=\"");
194     WOResponse_AddUInt(_response, c);
195     WOResponse_AddChar(_response, '"');
196   }
197
198   if ([self->disabled boolValueInComponent:sComponent])
199     WOResponse_AddCString(_response, " disabled=\"disabled\"");
200   
201   [self appendExtraAttributesToResponse:_response inContext:_ctx];
202   if (self->otherTagString) {
203     NSString *s;
204
205     s = [self->otherTagString stringValueInComponent:[_ctx component]];
206     WOResponse_AddChar(_response, ' ');
207     WOResponse_AddString(_response, s);
208   }
209   WOResponse_AddChar(_response, '>');
210
211   if ([v length] > 0) {
212     BOOL     removeCR = NO;
213     NSString *ua;
214     
215     ua = [[_ctx request] headerForKey:@"user-agent"];
216     
217     if ([ua rangeOfString:@"Opera"].length > 0)
218       removeCR = YES;
219     
220     if (removeCR)
221       v = [v stringByReplacingString:@"\r" withString:@""];
222     
223     [_response appendContentHTMLString:v];
224   }
225   
226   WOResponse_AddCString(_response, "</textarea>");
227 }
228
229 /* description */
230
231 - (NSString *)associationDescription {
232   NSMutableString *str = nil;
233   
234   str = [NSMutableString stringWithCapacity:64];
235   [str appendString:[super associationDescription]];
236   
237   if (self->rows)       [str appendFormat:@" rows=%@", self->rows];
238   if (self->cols)       [str appendFormat:@" cols=%@", self->cols];
239   if (self->formatter)  [str appendFormat:@" formatter=%@", self->formatter];
240   if (self->dateformat) [str appendFormat:@" dateformat=%@", self->dateformat];
241   if (self->numberformat)
242     [str appendFormat:@" numberformat=%@", self->numberformat];
243   
244   return str;
245 }
246
247 @end /* WOText */