]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOText.m
Ported "fragmentID" stuff from JOPE to SOPE.
[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   if ([_ctx isRenderingDisabled]) return;
170
171   sComponent = [_ctx component];
172   v  = [self->value valueInComponent:sComponent];
173   r  = [self->rows  unsignedIntValueInComponent:sComponent];
174   c  = [self->cols  unsignedIntValueInComponent:sComponent];
175   
176   fmt = _getFormatter(self, _ctx);
177   if (fmt) {
178     NSString *formattedObj = nil;
179
180     formattedObj = [fmt editingStringForObjectValue:v];
181     v = formattedObj;
182   }
183   else
184     v = [v stringValue];
185   
186   WOResponse_AddCString(_response, "<textarea name=\"");
187   [_response appendContentHTMLAttributeValue:OWFormElementName(self, _ctx)];
188   WOResponse_AddChar(_response, '"');
189   if (r > 0) {
190     WOResponse_AddCString(_response, " rows=\"");
191     WOResponse_AddUInt(_response, r);
192     WOResponse_AddChar(_response, '"');
193   }
194   if (c > 0) {
195     WOResponse_AddCString(_response, " cols=\"");
196     WOResponse_AddUInt(_response, c);
197     WOResponse_AddChar(_response, '"');
198   }
199
200   if ([self->disabled boolValueInComponent:sComponent])
201     WOResponse_AddCString(_response, " disabled=\"disabled\"");
202   
203   [self appendExtraAttributesToResponse:_response inContext:_ctx];
204   if (self->otherTagString) {
205     NSString *s;
206
207     s = [self->otherTagString stringValueInComponent:[_ctx component]];
208     WOResponse_AddChar(_response, ' ');
209     WOResponse_AddString(_response, s);
210   }
211   WOResponse_AddChar(_response, '>');
212
213   if ([v length] > 0) {
214     BOOL     removeCR = NO;
215     NSString *ua;
216     
217     ua = [[_ctx request] headerForKey:@"user-agent"];
218     
219     if ([ua rangeOfString:@"Opera"].length > 0)
220       removeCR = YES;
221     
222     if (removeCR)
223       v = [v stringByReplacingString:@"\r" withString:@""];
224     
225     [_response appendContentHTMLString:v];
226   }
227   
228   WOResponse_AddCString(_response, "</textarea>");
229 }
230
231 /* description */
232
233 - (NSString *)associationDescription {
234   NSMutableString *str = nil;
235   
236   str = [NSMutableString stringWithCapacity:64];
237   [str appendString:[super associationDescription]];
238   
239   if (self->rows)       [str appendFormat:@" rows=%@", self->rows];
240   if (self->cols)       [str appendFormat:@" cols=%@", self->cols];
241   if (self->formatter)  [str appendFormat:@" formatter=%@", self->formatter];
242   if (self->dateformat) [str appendFormat:@" dateformat=%@", self->dateformat];
243   if (self->numberformat)
244     [str appendFormat:@" numberformat=%@", self->numberformat];
245   
246   return str;
247 }
248
249 @end /* WOText */