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