]> err.no Git - scalable-opengroupware.org/blob - SOGo/UI/SOGoUI/UIxComponent.m
general enhancements
[scalable-opengroupware.org] / SOGo / UI / SOGoUI / UIxComponent.m
1 /*
2   Copyright (C) 2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23
24 #include "UIxComponent.h"
25 #include <Foundation/Foundation.h>
26 #include <NGObjWeb/NGObjWeb.h>
27 #include <NGExtensions/NGExtensions.h>
28
29
30 @interface UIxComponent (PrivateAPI)
31 - (void)_parseQueryString:(NSString *)_s;
32 @end
33
34
35 @implementation UIxComponent
36
37 static NSTimeZone *MET = nil;
38 static NSTimeZone *GMT = nil;
39
40 static NSMutableArray *dayLabelKeys = nil;
41 static NSMutableArray *abbrDayLabelKeys = nil;
42 static NSMutableArray *monthLabelKeys = nil;
43 static NSMutableArray *abbrMonthLabelKeys = nil;
44
45 static BOOL uixDebugEnabled = NO;
46
47 + (void)initialize {
48     NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
49     
50     uixDebugEnabled = [ud boolForKey:@"SOGoUIxDebugEnabled"];
51
52     if (MET == nil) {
53         MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
54         GMT = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
55     }
56     if (dayLabelKeys == nil) {
57         dayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
58         [dayLabelKeys addObject:@"Sunday"];
59         [dayLabelKeys addObject:@"Monday"];
60         [dayLabelKeys addObject:@"Tuesday"];
61         [dayLabelKeys addObject:@"Wednesday"];
62         [dayLabelKeys addObject:@"Thursday"];
63         [dayLabelKeys addObject:@"Friday"];
64         [dayLabelKeys addObject:@"Saturday"];
65
66         abbrDayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
67         [abbrDayLabelKeys addObject:@"a2_Sunday"];
68         [abbrDayLabelKeys addObject:@"a2_Monday"];
69         [abbrDayLabelKeys addObject:@"a2_Tuesday"];
70         [abbrDayLabelKeys addObject:@"a2_Wednesday"];
71         [abbrDayLabelKeys addObject:@"a2_Thursday"];
72         [abbrDayLabelKeys addObject:@"a2_Friday"];
73         [abbrDayLabelKeys addObject:@"a2_Saturday"];
74
75         monthLabelKeys = [[NSMutableArray alloc] initWithCapacity:12];
76         [monthLabelKeys addObject:@"January"];
77         [monthLabelKeys addObject:@"February"];
78         [monthLabelKeys addObject:@"March"];
79         [monthLabelKeys addObject:@"April"];
80         [monthLabelKeys addObject:@"May"];
81         [monthLabelKeys addObject:@"June"];
82         [monthLabelKeys addObject:@"July"];
83         [monthLabelKeys addObject:@"August"];
84         [monthLabelKeys addObject:@"September"];
85         [monthLabelKeys addObject:@"October"];
86         [monthLabelKeys addObject:@"November"];
87         [monthLabelKeys addObject:@"December"];
88
89         abbrMonthLabelKeys = [[NSMutableArray alloc] initWithCapacity:12];
90         [abbrMonthLabelKeys addObject:@"a3_January"];
91         [abbrMonthLabelKeys addObject:@"a3_February"];
92         [abbrMonthLabelKeys addObject:@"a3_March"];
93         [abbrMonthLabelKeys addObject:@"a3_April"];
94         [abbrMonthLabelKeys addObject:@"a3_May"];
95         [abbrMonthLabelKeys addObject:@"a3_June"];
96         [abbrMonthLabelKeys addObject:@"a3_July"];
97         [abbrMonthLabelKeys addObject:@"a3_August"];
98         [abbrMonthLabelKeys addObject:@"a3_September"];
99         [abbrMonthLabelKeys addObject:@"a3_October"];
100         [abbrMonthLabelKeys addObject:@"a3_November"];
101         [abbrMonthLabelKeys addObject:@"a3_December"];
102     }
103 }
104
105 - (id)init {
106   if ((self = [super init])) {
107     self->queryParameters = [[NSMutableDictionary alloc] init];
108   }
109   return self;
110 }
111
112 - (void)dealloc {
113   [self->queryParameters release];
114   [super dealloc];
115 }
116
117
118 - (void)awake {
119   WORequest *req;
120   NSString  *uri;
121   NSRange   r;
122
123   [super awake];
124
125   req = [[self context] request];
126   uri = [req uri];
127   r   = [uri rangeOfString:@"?"];
128   if (r.length > 0) {
129     NSString *qs;
130     
131     qs = [uri substringFromIndex:(r.location + r.length)];
132     [self->queryParameters removeAllObjects];
133     [self _parseQueryString:qs];
134   }    
135 }
136
137 - (void)_parseQueryString:(NSString *)_s {
138   NSEnumerator *e;
139   NSString *part;
140     
141   e = [[_s componentsSeparatedByString:@"&"] objectEnumerator];
142   while ((part = [e nextObject])) {
143     NSRange  r;
144     NSString *key, *value;
145         
146     r = [part rangeOfString:@"="];
147     if (r.length == 0) {
148       /* missing value of query parameter */
149       key   = [part stringByUnescapingURL];
150       value = @"1";
151     }
152     else {
153       key   = [[part substringToIndex:r.location] stringByUnescapingURL];
154       value = [[part substringFromIndex:(r.location + r.length)] 
155                 stringByUnescapingURL];
156     }
157     [self->queryParameters setObject:value forKey:key];
158   }
159 }
160
161 - (NSString *)queryParameterForKey:(NSString *)_key {
162   return [self->queryParameters objectForKey:_key];
163 }
164
165 - (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key {
166   if(_key == nil)
167     return;
168
169   if(_param != nil)
170     [self->queryParameters setObject:_param forKey:_key];
171   else
172     [self->queryParameters removeObjectForKey:_key];
173 }
174
175 - (NSDictionary *)queryParameters {
176   return self->queryParameters;
177 }
178
179 - (NSString *)completeHrefForMethod:(NSString *)_method {
180   NSDictionary *qp;
181   NSString *qs;
182     
183   qp = [self queryParameters];
184   if([qp count] == 0)
185     return _method;
186     
187   qs = [[self context] queryStringFromDictionary:qp];
188   return [_method stringByAppendingFormat:@"?%@", qs];
189 }
190
191 - (NSString *)ownMethodName {
192   NSString *uri;
193   NSRange  r;
194     
195   uri = [[[self context] request] uri];
196     
197   /* first: cut off query parameters */
198     
199   r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
200   if (r.length > 0)
201     uri = [uri substringToIndex:r.location];
202     
203   /* next: strip trailing slash */
204     
205   if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)];
206   r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
207     
208   /* then: cut of last path component */
209     
210   if (r.length == 0) // no slash? are we at root?
211     return @"/";
212     
213   return [uri substringFromIndex:(r.location + 1)];
214 }
215
216 /* date */
217
218 - (NSTimeZone *)viewTimeZone {
219   // Note: also in the folder, should be based on a cookie?
220   return MET;
221 }
222
223 - (NSTimeZone *)backendTimeZone {
224   return GMT;
225 }
226
227 - (NSCalendarDate *)selectedDate {
228   NSString       *s;
229   NSCalendarDate *cdate;
230
231   s = [self queryParameterForKey:@"day"];
232   cdate = ([s length] > 0)
233     ? [self dateForDateString:s]
234     : [NSCalendarDate date];
235   [cdate setTimeZone:[self viewTimeZone]];
236   s = [self queryParameterForKey:@"hm"];
237   if([s length] == 4) {
238       unsigned hour, minute;
239       
240       hour = [[s substringToIndex:2] unsignedIntValue];
241       minute = [[s substringFromIndex:2] unsignedIntValue];
242       cdate = [cdate hour:hour minute:minute];
243   }
244   else {
245       cdate = [cdate hour:12 minute:0];
246   }
247   return cdate;
248 }
249
250 - (NSString *)dateStringForDate:(NSCalendarDate *)_date {
251   [_date setTimeZone:[self viewTimeZone]];
252   return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
253 }
254
255 - (NSCalendarDate *)dateForDateString:(NSString *)_dateString {
256   return [NSCalendarDate dateWithString:_dateString 
257                          calendarFormat:@"%Y%m%d"];
258 }
259
260
261 /* SoUser */
262
263 - (SoUser *)user {
264     WOContext *ctx;
265     
266     ctx = [self context];
267     return [[[self clientObject] authenticatorInContext:ctx]
268                                userInContext:ctx];
269 }
270
271 - (NSString *)shortUserNameForDisplay {
272     // TODO: better use a SoUser formatter?
273     NSString *s;
274     NSRange  r;
275
276 #warning !! USE USER MANAGER INSTEAD!
277
278     s = [[self user] login];
279     if ([s length] < 10)
280         return s;
281     
282     // TODO: algorithm might be inappropriate, depends on the actual UID
283     
284     r = [s rangeOfString:@"."];
285     if (r.length == 0)
286         return s;
287     
288     return [s substringToIndex:r.location];
289 }
290
291 /* labels */
292
293 - (NSString *)labelForKey:(NSString *)_str {
294     WOResourceManager *rm;
295     NSArray           *languages;
296     WOContext         *ctx;
297     NSString          *label;
298     NSString          *lKey, *lTable, *lVal;
299     NSRange r;
300
301     if ([_str length] == 0) {
302         return nil;
303     }
304     
305     /* lookup languages */
306     
307     ctx = [self context];
308     languages = [ctx hasSession]
309         ? [[ctx session] languages]
310         : [[ctx request] browserLanguages];
311     
312     /* find resource manager */
313     
314     if ((rm = [self resourceManager]) == nil)
315         rm = [[WOApplication application] resourceManager];
316     if (rm == nil)
317         [self debugWithFormat:@"WARNING: missing resource manager!"];
318     
319     /* get parameters */
320     
321     r = [_str rangeOfString:@"/"];
322     if (r.length > 0) {
323         lTable = [_str substringToIndex:r.location];
324         lKey   = [_str substringFromIndex:(r.location + r.length)];
325     }
326     else {
327         lTable = nil;
328         lKey   = _str;
329     }
330     lVal = lKey;
331
332     if([lKey hasPrefix:@"$"]) {
333         lKey = [self valueForKeyPath:[lKey substringFromIndex:1]];
334     }
335     if([lTable hasPrefix:@"$"]) {
336         lTable = [self valueForKeyPath:[lTable substringFromIndex:1]];
337     }
338 #if 0
339     if([lVal hasPrefix:@"$"]) {
340         lVal = [self valueForKeyPath:[lVal substringFromIndex:1]];
341     }
342 #endif
343     /* lookup string */
344     
345     label = [rm stringForKey:lKey inTableNamed:lTable withDefaultValue:lVal
346                 languages:languages];
347     return label;
348 }
349
350 - (NSString *)localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
351     NSString *key =  [dayLabelKeys objectAtIndex:_dayOfWeek % 7];
352     return [self labelForKey:key];
353 }
354
355 - (NSString *)localizedAbbreviatedNameForDayOfWeek:(unsigned)_dayOfWeek {
356     NSString *key =  [abbrDayLabelKeys objectAtIndex:_dayOfWeek % 7];
357     return [self labelForKey:key];
358 }
359
360 - (NSString *)localizedNameForMonthOfYear:(unsigned)_monthOfYear {
361     NSString *key =  [monthLabelKeys objectAtIndex:(_monthOfYear - 1) % 12];
362     return [self labelForKey:key];
363 }
364
365 - (NSString *)localizedAbbreviatedNameForMonthOfYear:(unsigned)_monthOfYear {
366     NSString *key =  [abbrMonthLabelKeys objectAtIndex:(_monthOfYear - 1) % 12];
367     return [self labelForKey:key];
368 }
369
370 /* locale */
371
372 - (NSDictionary *)locale {
373     /* we need no fallback here, as locale is guaranteed to be set by sogod */
374     return [[self context] valueForKey:@"locale"];
375 }
376
377 /* Debugging */
378
379 - (BOOL)isUIxDebugEnabled {
380     return uixDebugEnabled;
381 }
382
383 @end /* UIxComponent */