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