]> err.no Git - scalable-opengroupware.org/blob - UI/Common/UIxTabItem.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1145 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / Common / UIxTabItem.m
1 /*
2   Copyright (C) 2000-2005 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
22 #include "UIxTabView.h"
23 #include "common.h"
24
25 #if DEBUG
26 #  define DEBUG_JS 1
27 #endif
28
29 /* context keys */
30 extern NSString *UIxTabView_HEAD;
31 extern NSString *UIxTabView_BODY;
32 extern NSString *UIxTabView_KEYS;
33 extern NSString *UIxTabView_SCRIPT;
34 extern NSString *UIxTabView_ACTIVEKEY;
35 extern NSString *UIxTabView_COLLECT;
36
37 @implementation UIxTabItem
38
39 static Class StrClass = Nil;
40
41 + (int)version {
42   return [super version] + 0;
43 }
44 + (void)initialize {
45   StrClass = [NSString class];
46 }
47
48 static NSString *retStrForInt(int i) {
49   switch(i) {
50   case 0:  return @"0";
51   case 1:  return @"1";
52   case 2:  return @"2";
53   case 3:  return @"3";
54   case 4:  return @"4";
55   case 5:  return @"5";
56   case 6:  return @"6";
57   case 7:  return @"7";
58   case 8:  return @"8";
59   case 9:  return @"9";
60   case 10: return @"10";
61     // TODO: find useful count!
62   default:
63     return [[StrClass alloc] initWithFormat:@"%i", i];
64   }
65 }
66
67 - (id)initWithName:(NSString *)_name
68   associations:(NSDictionary *)_config
69   template:(WOElement *)_subs
70 {
71   if ((self = [super initWithName:_name associations:_config template:_subs])) {
72     self->key      = WOExtGetProperty(_config, @"key");
73     self->label    = WOExtGetProperty(_config, @"label");
74
75     self->isScript = WOExtGetProperty(_config, @"isScript");
76     self->href     = WOExtGetProperty(_config, @"href");
77
78     self->icon     = WOExtGetProperty(_config, @"icon");
79     self->action   = WOExtGetProperty(_config, @"action");
80
81     self->tabStyle         = WOExtGetProperty(_config, @"tabStyle");
82     self->selectedTabStyle = WOExtGetProperty(_config, @"selectedTabStyle");
83
84     self->tabIcon         = WOExtGetProperty(_config, @"tabIcon");
85     self->leftTabIcon     = WOExtGetProperty(_config, @"leftTabIcon");
86     self->selectedTabIcon = WOExtGetProperty(_config, @"selectedTabIcon");
87     
88     self->asBackground    = WOExtGetProperty(_config, @"asBackground");
89     self->width           = WOExtGetProperty(_config, @"width");
90     self->height          = WOExtGetProperty(_config, @"height");
91     self->activeBgColor   = WOExtGetProperty(_config, @"activeBgColor");
92     self->inactiveBgColor = WOExtGetProperty(_config, @"inactiveBgColor");
93     
94     self->template = [_subs retain];
95   }
96   return self;
97 }
98
99 - (void)dealloc {
100   [self->key      release];
101   [self->label    release];
102
103   [self->href   release];
104
105   [self->action   release];
106
107   [self->isScript release];
108   [self->template release];
109
110   [self->tabStyle release];
111   [self->selectedTabStyle release];
112
113   [self->icon     release];
114   [self->leftTabIcon     release];
115   [self->selectedTabIcon release];
116   [self->tabIcon         release];
117
118   [self->asBackground release];
119   [self->width        release];
120   [self->height       release];
121
122   [self->activeBgColor   release];
123   [self->inactiveBgColor release];
124   
125   [super dealloc];
126 }
127
128 /* responder */
129
130 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
131   NSString *activeTabKey;
132   NSString *myTabKey;
133   BOOL     doCheck;
134   
135   if ([_ctx objectForKey:UIxTabView_HEAD]) {
136     /* head clicks */
137     [[_ctx component] debugWithFormat:
138                         @"UIxTabItem: head takes (no) values, eid='%@'",
139                         [_ctx elementID]];
140     return;
141   }
142
143   if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY]) == nil) {
144     [[_ctx component] debugWithFormat:@"UIxTabItem: invalid state"];
145     [self->template takeValuesFromRequest:_rq inContext:_ctx];
146     return;
147   }
148   
149   myTabKey = [self->key      stringValueInComponent:[_ctx component]];
150   doCheck  = [self->isScript boolValueInComponent:[_ctx component]];
151     
152   if ([activeTabKey isEqualToString:myTabKey] || doCheck) {
153 #if ADD_OWN_ELEMENTIDS
154     [_ctx appendElementIDComponent:activeTabKey];
155 #endif
156       
157 #if DEBUG_TAKEVALUES
158     [[_ctx component] debugWithFormat:
159                           @"UIxTabItem: body takes values, eid='%@'",
160                           [_ctx elementID]];
161 #endif
162       
163     [self->template takeValuesFromRequest:_rq inContext:_ctx];
164 #if ADD_OWN_ELEMENTIDS
165     [_ctx deleteLastElementIDComponent];
166 #endif
167   }
168 #if DEBUG_TAKEVALUES
169   else {
170       [[_ctx component] debugWithFormat:
171                           @"UIxTabItem: body takes no values, eid='%@'",
172                           [_ctx elementID]];
173   }
174 #endif
175 }
176
177 - (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
178   id            result;
179   WOAssociation *tmp;
180   NSString      *activeTabKey;
181   
182   if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) {
183     /* click on tab icon */
184     NSString      *tabkey;
185     
186     tabkey = [_ctx currentElementID];
187     [_ctx consumeElementID];
188     [_ctx appendElementIDComponent:tabkey];
189     
190     if ([tmp isValueSettable])
191       [tmp setValue:tabkey inComponent:[_ctx component]];
192     
193 #if 0
194     result = [self->action valueInComponent:[_ctx component]];
195 #endif
196
197     [_ctx deleteLastElementIDComponent];
198   }
199   else if ((activeTabKey = [_ctx objectForKey:UIxTabView_BODY])) {
200     /* clicked somewhere in the (active) body */
201     result = [self->template invokeActionForRequest:_req inContext:_ctx];
202   }
203   else {
204     [[_ctx component] logWithFormat:@"UIxTabItem: invalid invoke state"];
205     result = [self->template invokeActionForRequest:_req inContext:_ctx];
206   }
207   
208   return result;
209 }
210
211 /* info collection */
212
213 - (void)_collectInContext:(WOContext *)_ctx key:(NSString *)k {
214   BOOL  isLeft = NO;
215   NSMutableArray *keys;
216   UIxTabItemInfo  *info;
217   WOComponent    *cmp;
218       
219   cmp  = [_ctx component];
220   keys = [_ctx objectForKey:UIxTabView_KEYS];
221   if (keys == nil) {
222     keys = [[[NSMutableArray alloc] init] autorelease];
223     [_ctx setObject:keys forKey:UIxTabView_KEYS];
224     isLeft = YES;
225   }
226       
227   if (k == nil) {
228     /* auto-assign a key */
229     k = retStrForInt([keys count]);
230   }
231   else
232     k = [k retain];
233   [_ctx appendElementIDComponent:k];
234   
235   info = [[UIxTabItemInfo alloc] init];
236   info->key      = [k copy];
237   info->label    = [[self->label stringValueInComponent:cmp] copy];
238   info->icon     = [[self->icon  stringValueInComponent:cmp] copy];
239 #if 0
240   info->uri      = [[_ctx componentActionURL] copy];
241 #else
242   info->uri      = [[self->href stringValueInComponent:cmp] copy];
243 #endif
244   info->isScript = [self->isScript boolValueInComponent:cmp];
245   info->tabIcon  = [[self->tabIcon stringValueInComponent:cmp] copy];
246   info->leftIcon = [[self->leftTabIcon stringValueInComponent:cmp] copy];
247   info->selIcon  = [[self->selectedTabIcon stringValueInComponent:cmp]
248                                            copy];
249   info->tabStyle         = [[self->tabStyle stringValueInComponent:cmp] copy];
250   info->selectedTabStyle = [[self->selectedTabStyle stringValueInComponent:cmp]
251                                                     copy];
252
253   if (self->asBackground == nil)
254     info->asBackground = 0;
255   else {
256     info->asBackground
257       = ([self->asBackground boolValueInComponent:cmp]) ? 1 : -1;
258   }
259   info->width        = [[self->width  stringValueInComponent:cmp] copy];
260   info->height       = [[self->height stringValueInComponent:cmp] copy];
261   info->activeBg     = [[self->activeBgColor stringValueInComponent:cmp]
262                                              copy];
263   info->inactiveBg   = [[self->inactiveBgColor stringValueInComponent:cmp]
264                                                copy];
265       
266   if (info->leftIcon == nil) info->leftIcon = [info->tabIcon copy];
267       
268   [keys addObject:info];
269   [info release];
270   [k release];
271       
272   [_ctx deleteLastElementIDComponent];
273 }
274
275 /* header generation */
276
277 - (void)_appendHeadToResponse:(WOResponse *)_response
278   inContext:(WOContext *)_ctx
279   activeKey:(NSString *)activeKey
280   key:(NSString *)k
281 {
282   /* head is currently generated in UIxTabView */
283 #if 0
284   // note: some associations can be inherited by UIxTabView !
285   BOOL        doImages;
286   WOComponent *comp;
287   BOOL        doBgIcon;
288   NSString    *label;
289   NSString    *w, *h;
290   
291   doImages = ![[[_ctx request] clientCapabilities] isTextModeBrowser];
292   comp     = [_ctx component];
293   
294   doBgIcon = self->asBackground && doImages
295     ? [self->asBackground boolValueInComponent:comp] ? YES : NO
296     : NO;
297   
298   if ((label = [self->label stringValueInComponent:comp]) == nil)
299     label = k;
300
301   if (doImages) {
302     /* lookup image */
303     NSString *imgName = nil;
304     // ...
305     
306     imgUri = WEUriOfResource(imgName, _ctx);
307     if ([imgUri length] < 1)
308       doImages = NO;
309   }
310   
311   // .... _isActive
312 #endif
313 }
314
315 /* body generation */
316
317 - (void)_appendBodyToResponse:(WOResponse *)_response
318   inContext:(WOContext *)_ctx
319   activeKey:(NSString *)tmp
320   key:(NSString *)k
321 {
322   BOOL doScript;
323   BOOL isScript_;
324   BOOL isActive;
325
326   doScript  = [[_ctx objectForKey:UIxTabView_SCRIPT] boolValue];
327   isScript_ = [self->isScript boolValueInComponent:[_ctx component]];
328   isActive  = [tmp isEqualToString:k];
329     
330   if (doScript && (isActive || isScript_)) {
331     [_response appendContentString:@"<div id=\""];
332     [_response appendContentString:k];
333     [_response appendContentString:@"TabLayer\" style=\"display: none;\">\n"];
334   }
335   
336   if (isActive || (doScript && isScript_)) {
337     /* content is active or used as layer*/
338 #if ADD_OWN_ELEMENTIDS
339     [_ctx appendElementIDComponent:k];
340 #endif
341 #if DEBUG && 0
342     NSLog(@"TAB: %@", k);
343 #endif
344     
345     [self->template appendToResponse:_response inContext:_ctx];
346     
347 #if ADD_OWN_ELEMENTIDS
348     [_ctx deleteLastElementIDComponent];
349 #endif
350   }
351     
352   if (doScript && (isActive || isScript_)) {
353     NSString *jsout;
354     [_response appendContentString:@"</div>"];
355
356     jsout = [NSString alloc];
357     jsout = [jsout initWithFormat:
358                    @"<script language=\"JavaScript\">\n<!--\n"
359                    @"%@Tab[\"Div\"] = %@TabLayer;\n",
360                    k, k];
361     
362     [_response appendContentString:jsout];
363     [jsout release];
364     
365 #if DEBUG_JS
366     jsout = [NSString alloc];
367     jsout = [jsout initWithFormat:
368                      @"if (%@Tab[\"Div\"].style==null) {"
369                      @"alert('missing style in div for tab %@');}",
370                      k, k];
371     
372     [_response appendContentString:jsout];
373     [jsout release];
374 #endif
375     
376     if (isActive) {
377       [_response appendContentString:@"showTab("];
378       [_response appendContentString:k];
379       [_response appendContentString:@"Tab);\n"];
380     }
381     [_response appendContentString:@"//-->\n</script>"];
382   }
383 }
384
385 /* master generation method */
386
387 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
388   NSString *k;
389   BOOL     doForm;
390   id       tmp;
391   
392   doForm = [_ctx isInForm];
393   k = [self->key stringValueInComponent:[_ctx component]];
394   
395   if ((tmp = [_ctx objectForKey:UIxTabView_HEAD])) {
396     if ([tmp isEqual:UIxTabView_COLLECT]) {
397       [self _collectInContext:_ctx key:k];
398     }
399     else {
400       [self _appendHeadToResponse:_response inContext:_ctx
401             activeKey:tmp key:k];
402     }
403   }
404   else if ((tmp = [_ctx objectForKey:UIxTabView_BODY])) {
405     [self _appendBodyToResponse:_response inContext:_ctx
406           activeKey:tmp key:k];
407   }
408   else {
409     [self warnWithFormat:@"(%s): invalid UIxTabItem state !!!",
410             __PRETTY_FUNCTION__];
411     [_response appendContentString:@"[invalid state]"];
412   }
413 }
414
415 @end /* UIxTabItem */
416
417 @implementation UIxTabItemInfo
418
419 - (void)dealloc {
420   [self->uri                release];
421   [self->icon               release];
422   [self->label              release];
423   [self->key                release];
424   [self->tabStyle           release];
425   [self->selectedTabStyle   release];
426   [self->tabIcon            release];
427   [self->selIcon            release];
428   [self->leftIcon           release];
429   [self->width              release];
430   [self->height             release];
431   [self->activeBg           release];
432   [self->inactiveBg         release];
433
434   [super dealloc];
435 }
436
437 /* accessors */
438
439 - (NSString *)key {
440   return self->key;
441 }
442 - (NSString *)label {
443   return self->label;
444 }
445 - (NSString *)icon {
446   return self->icon;
447 }
448 - (NSString *)uri {
449   return self->uri;
450 }
451 - (BOOL)isScript {
452   return self->isScript;
453 }
454
455 - (int)asBackground {
456   return self->asBackground;
457 }
458
459 - (NSString *)width {
460   return self->width;
461 }
462
463 - (NSString *)height {
464   return self->height;
465 }
466
467 - (NSString *)activeBg {
468   return self->activeBg;
469 }
470
471 - (NSString *)inactiveBg {
472   return self->inactiveBg;
473 }
474
475 @end /* UIxTabItemInfo */