]> err.no Git - scalable-opengroupware.org/blob - SOGo/UI/SOGoUI/UIxComponent.m
work on "edit" functionality in AppointmentProposal
[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 - (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date {
180   NSMutableDictionary *qp;
181     
182   qp = [[self queryParameters] mutableCopy];
183   [self setSelectedDateQueryParameter:_date inDictionary:qp];
184   return [qp autorelease];
185 }
186
187 - (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
188         inDictionary:(NSMutableDictionary *)_qp;
189 {
190   if(_newDate != nil)
191     [_qp setObject:[self dateStringForDate:_newDate] forKey:@"day"];
192   else
193     [_qp removeObjectForKey:@"day"];
194 }
195
196 - (NSString *)completeHrefForMethod:(NSString *)_method {
197   NSDictionary *qp;
198   NSString *qs;
199     
200   qp = [self queryParameters];
201   if([qp count] == 0)
202     return _method;
203     
204   qs = [[self context] queryStringFromDictionary:qp];
205   return [_method stringByAppendingFormat:@"?%@", qs];
206 }
207
208 - (NSString *)ownMethodName {
209   NSString *uri;
210   NSRange  r;
211     
212   uri = [[[self context] request] uri];
213     
214   /* first: cut off query parameters */
215     
216   r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
217   if (r.length > 0)
218     uri = [uri substringToIndex:r.location];
219     
220   /* next: strip trailing slash */
221     
222   if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)];
223   r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
224     
225   /* then: cut of last path component */
226     
227   if (r.length == 0) // no slash? are we at root?
228     return @"/";
229     
230   return [uri substringFromIndex:(r.location + 1)];
231 }
232
233 /* date */
234
235 - (NSTimeZone *)viewTimeZone {
236   // Note: also in the folder, should be based on a cookie?
237   return MET;
238 }
239
240 - (NSTimeZone *)backendTimeZone {
241   return GMT;
242 }
243
244 - (NSCalendarDate *)selectedDate {
245   NSString       *s;
246   NSCalendarDate *cdate;
247
248   s = [self queryParameterForKey:@"day"];
249   cdate = ([s length] > 0)
250     ? [self dateForDateString:s]
251     : [NSCalendarDate date];
252   [cdate setTimeZone:[self viewTimeZone]];
253   s = [self queryParameterForKey:@"hm"];
254   if([s length] == 4) {
255       unsigned hour, minute;
256       
257       hour = [[s substringToIndex:2] unsignedIntValue];
258       minute = [[s substringFromIndex:2] unsignedIntValue];
259       cdate = [cdate hour:hour minute:minute];
260   }
261   else {
262       cdate = [cdate hour:12 minute:0];
263   }
264   return cdate;
265 }
266
267 - (NSString *)dateStringForDate:(NSCalendarDate *)_date {
268   [_date setTimeZone:[self viewTimeZone]];
269   return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
270 }
271
272 - (NSCalendarDate *)dateForDateString:(NSString *)_dateString {
273   return [NSCalendarDate dateWithString:_dateString 
274                          calendarFormat:@"%Y%m%d"];
275 }
276
277
278 /* SoUser */
279
280 - (SoUser *)user {
281     WOContext *ctx;
282     
283     ctx = [self context];
284     return [[[self clientObject] authenticatorInContext:ctx]
285                                userInContext:ctx];
286 }
287
288 - (NSString *)shortUserNameForDisplay {
289     // TODO: better use a SoUser formatter?
290     NSString *s;
291     NSRange  r;
292
293 #warning !! USE USER MANAGER INSTEAD!
294
295     s = [[self user] login];
296     if ([s length] < 10)
297         return s;
298     
299     // TODO: algorithm might be inappropriate, depends on the actual UID
300     
301     r = [s rangeOfString:@"."];
302     if (r.length == 0)
303         return s;
304     
305     return [s substringToIndex:r.location];
306 }
307
308 /* labels */
309
310 - (NSString *)labelForKey:(NSString *)_str {
311     WOResourceManager *rm;
312     NSArray           *languages;
313     WOContext         *ctx;
314     NSString          *label;
315     NSString          *lKey, *lTable, *lVal;
316     NSRange r;
317
318     if ([_str length] == 0) {
319         return nil;
320     }
321     
322     /* lookup languages */
323     
324     ctx = [self context];
325     languages = [ctx hasSession]
326         ? [[ctx session] languages]
327         : [[ctx request] browserLanguages];
328     
329     /* find resource manager */
330     
331     if ((rm = [self resourceManager]) == nil)
332         rm = [[WOApplication application] resourceManager];
333     if (rm == nil)
334         [self debugWithFormat:@"WARNING: missing resource manager!"];
335     
336     /* get parameters */
337     
338     r = [_str rangeOfString:@"/"];
339     if (r.length > 0) {
340         lTable = [_str substringToIndex:r.location];
341         lKey   = [_str substringFromIndex:(r.location + r.length)];
342     }
343     else {
344         lTable = nil;
345         lKey   = _str;
346     }
347     lVal = lKey;
348
349     if([lKey hasPrefix:@"$"]) {
350         lKey = [self valueForKeyPath:[lKey substringFromIndex:1]];
351     }
352     if([lTable hasPrefix:@"$"]) {
353         lTable = [self valueForKeyPath:[lTable substringFromIndex:1]];
354     }
355 #if 0
356     if([lVal hasPrefix:@"$"]) {
357         lVal = [self valueForKeyPath:[lVal substringFromIndex:1]];
358     }
359 #endif
360     /* lookup string */
361     
362     label = [rm stringForKey:lKey inTableNamed:lTable withDefaultValue:lVal
363                 languages:languages];
364     return label;
365 }
366
367 - (NSString *)localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
368     NSString *key =  [dayLabelKeys objectAtIndex:_dayOfWeek % 7];
369     return [self labelForKey:key];
370 }
371
372 - (NSString *)localizedAbbreviatedNameForDayOfWeek:(unsigned)_dayOfWeek {
373     NSString *key =  [abbrDayLabelKeys objectAtIndex:_dayOfWeek % 7];
374     return [self labelForKey:key];
375 }
376
377 - (NSString *)localizedNameForMonthOfYear:(unsigned)_monthOfYear {
378     NSString *key =  [monthLabelKeys objectAtIndex:(_monthOfYear - 1) % 12];
379     return [self labelForKey:key];
380 }
381
382 - (NSString *)localizedAbbreviatedNameForMonthOfYear:(unsigned)_monthOfYear {
383     NSString *key =  [abbrMonthLabelKeys objectAtIndex:(_monthOfYear - 1) % 12];
384     return [self labelForKey:key];
385 }
386
387 /* locale */
388
389 - (NSDictionary *)locale {
390     /* we need no fallback here, as locale is guaranteed to be set by sogod */
391     return [[self context] valueForKey:@"locale"];
392 }
393
394 /* Debugging */
395
396 - (BOOL)isUIxDebugEnabled {
397     return uixDebugEnabled;
398 }
399
400 @end /* UIxComponent */