]> err.no Git - sope/blob - skyrix-sope/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / skyrix-sope / NGObjDOM / Dynamic.subproj / ODR_bind_tabview.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
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 <NGObjDOM/ODR_bind_tabview.h>
24 #ifdef __APPLE__
25 #include <NGObjWeb/WEClientCapabilities.h>
26 #else
27 #include <WEExtensions/WEClientCapabilities.h>
28 #endif
29
30 /*
31    <var:tabview selection="selection"
32                 bgcolor="bgcolor"
33                 inactivecolor="inactivecolor"
34                 activecolor="activecolor"
35                 bgiconleft="inactivebgiconleft"
36                 bgicon="inactivebgicon"
37                 activebgicon="activebgicon">
38
39      <tab const:title="tab 1" const:key="tab1">
40        content of tab 1
41      </tab>
42
43      <tab const:title="tab 2" const:key="tab2">
44        content of tab 2
45      </tab>
46    
47    </var:tabview>
48
49    tabview attributes:
50      selection
51      bgcolor
52      inactivecolor
53      activecolor
54      bgiconleft
55      bgicon
56      activebgicon
57      
58    tab attributes:
59      disabled - bool
60      title    - String
61      key      - String
62      fontcolor
63      fontface
64      fontsize
65 */
66
67 /* context keys */
68
69 #include "common.h"
70
71 @implementation ODR_bind_tabview
72
73 #if !LIB_FOUNDATION_BOEHM_GC
74 - (void)dealloc {
75   RELEASE(self->activeKey);
76   [super dealloc];
77 }
78 #endif
79
80 - (void)_setActiveKey:(NSString *)_activeKey {
81   ASSIGN(self->activeKey, _activeKey);
82 }
83
84 - (void)setActiveKey:(id)_node inContext:(WOContext *)_ctx {
85   NSArray        *tabNodes;
86   NSMutableArray *keys;
87   int            i, cnt;
88
89   [self _setActiveKey:[self stringFor:@"selection" node:_node ctx:_ctx]];
90   keys      = [[NSMutableArray allocWithZone:[self zone]] initWithCapacity:8];
91   tabNodes  = ODRLookupQueryPath(_node, @"-tab");
92   cnt       = [tabNodes count];
93
94   for (i=0; i < cnt; i++) {
95     NSString *key = nil;
96     id       tab;
97
98     tab = [tabNodes objectAtIndex:i];
99     key = [self stringFor:@"key" node:tab ctx:_ctx];
100     if (key == nil) {
101       key = [NSString stringWithFormat:@"%d", i];
102       [self forceSetString:key for:@"key" node:tab ctx:_ctx];
103     }
104     [keys addObject:key];
105   }
106   /* selection is not available in keys */
107   if (![keys containsObject:self->activeKey])
108     [self _setActiveKey:nil];
109   
110   /* no or invalid selection, use first key */
111   if ((self->activeKey == nil) && ([keys count] > 0))
112     [self _setActiveKey:[[keys objectAtIndex:0] stringValue]];
113
114   [self forceSetString:self->activeKey for:@"selection" node:_node ctx:_ctx];
115
116   RELEASE(keys);  
117 }
118
119 /* responder */
120
121 - (void)takeValuesForNode:(id)_node
122   fromRequest:(WORequest *)_request
123   inContext:(WOContext *)_ctx
124 {
125   NSArray  *tabs;
126   unsigned i, cnt;
127   
128   /* set ODR_bind_tabview_ACTIVEKEY */
129   [self setActiveKey:_node inContext:_ctx];
130
131   tabs = ODRLookupQueryPath(_node, @"-tab");
132   cnt  = [tabs count];
133     
134   [_ctx appendElementIDComponent:@"b"];
135   [_ctx appendElementIDComponent:self->activeKey];
136   
137   for (i = 0; i < cnt; i++) {
138     NSString *key;
139     id       tab;
140
141     tab = [tabs objectAtIndex:i];
142     key = [self stringFor:@"key" node:tab ctx:_ctx];
143
144     if ([key isEqualToString:self->activeKey]) {
145       [super takeValuesForNode:tab fromRequest:_request inContext:_ctx];
146       break;
147     }
148   }
149   [_ctx deleteLastElementIDComponent]; // activeKey 
150   [_ctx deleteLastElementIDComponent]; /* 'b' */
151 }
152
153 - (id)invokeActionForNode:(id)_node
154   fromRequest:(WORequest *)_request
155   inContext:(WOContext *)_ctx
156 {
157   NSString *section;
158   id       result = nil;
159   
160   if ((section = [_ctx currentElementID])) {
161     /* header action */    
162     if ([section isEqualToString:@"h"]) {
163       
164       [_ctx consumeElementID];
165       
166       [self forceSetString:[_ctx currentElementID]
167             for:@"selection"
168             node:_node
169             ctx:_ctx];
170       
171     }
172     /* body action */
173     else if ([section isEqualToString:@"b"]) {
174       NSString *selection;
175       NSArray  *tabs;
176       int      i, cnt;
177       
178       selection = [self stringFor:@"selection" node:_node ctx:_ctx];
179       tabs      = ODRLookupQueryPath(_node, @"-tab");
180       cnt       = [tabs count];
181       
182       [_ctx consumeElementID];
183       [_ctx appendElementIDComponent:section];
184
185       for (i = 0; i < cnt; i++) {
186         NSString *key;
187         id       tab;
188
189         tab = [tabs objectAtIndex:i];
190         key = [self stringFor:@"key" node:tab ctx:_ctx];
191
192         if ([key isEqualToString:selection]) {
193           [_ctx appendElementIDComponent:key];
194           [_ctx consumeElementID];
195           result = [super invokeActionForNode:tab
196                           fromRequest:_request
197                           inContext:_ctx];
198           [_ctx deleteLastElementIDComponent];
199           break;
200         }
201       }
202       [_ctx deleteLastElementIDComponent];
203     }
204   }
205   return result;
206 }
207
208 - (void)appendTab:(id)_tab
209   node:(id)_node
210   response:(WOResponse *)_response
211   ctx:(WOContext *)_ctx
212   left:(BOOL)_isLeft
213 {
214   NSString *key       = nil;
215   NSString *title     = nil;
216   NSString *bgcolor   = nil;
217   NSString *width     = nil;
218   NSString *height    = nil;
219   NSString *bgIcon    = nil;
220   BOOL     isActive;
221   NSString *tC, *tF, *tS; // text font attrtibutes
222   BOOL     hasFont;
223
224
225   key       = [self stringFor:@"key"   node:_tab ctx:_ctx];
226   title     = [self stringFor:@"title" node:_tab ctx:_ctx];
227   isActive  = [key isEqualToString:self->activeKey];
228   
229   width     = [self stringFor:@"width"  node:_node ctx:_ctx];
230   height    = [self stringFor:@"height" node:_node ctx:_ctx];
231   bgIcon    = (isActive)
232     ? [self stringFor:@"activebgicon" node:_node ctx:_ctx]
233     : ((_isLeft) ? [self stringFor:@"bgiconleft" node:_node ctx:_ctx]
234                  : [self stringFor:@"bgicon"     node:_node ctx:_ctx]);
235   bgIcon    = ODRUriOfResource(bgIcon, _ctx);
236        
237   bgcolor   = (isActive)
238     ? [self stringFor:@"activecolor"   node:_node ctx:_ctx]
239     : [self stringFor:@"inactivecolor" node:_node ctx:_ctx];
240   
241   title = (title) ? title : key;
242   
243   [_ctx appendElementIDComponent:key]; // append tab-key
244   
245   // append <td ...>
246   [_response appendContentString:@"<td align=\"center\" valign=\"bottom\""];
247   if (bgcolor) {
248     [_response appendContentString:@" bgcolor=\""];
249     [_response appendContentString:bgcolor];
250     [_response appendContentCharacter:'"'];
251   }
252   if (width) {
253     [_response appendContentString:@" width=\""];
254     [_response appendContentString:width];
255     [_response appendContentCharacter:'"'];
256   }
257   if (height) {
258     [_response appendContentString:@" height=\""];
259     [_response appendContentString:height];
260     [_response appendContentCharacter:'"'];
261   }
262   if (bgIcon) {
263     [_response appendContentString:@" background=\""];
264     [_response appendContentString:bgIcon];
265     [_response appendContentCharacter:'"'];
266   }
267   [_response appendContentCharacter:'>'];
268   
269   [_response appendContentString:@"<a href='"];
270   [_response appendContentHTMLAttributeValue:[_ctx componentActionURL]];
271   [_response appendContentString:@"' style=\"text-decoration: none;\">"];
272   
273   tC  = [self stringFor:@"fontcolor" node:_node ctx:_ctx];
274   tF  = [self stringFor:@"fontface"  node:_node ctx:_ctx];
275   tS  = [self stringFor:@"fontsize"  node:_node ctx:_ctx];
276   
277   hasFont = (tC || tF || tS) ? YES : NO;
278   
279   if (hasFont)
280     ODRAppendFont(_response, tC, tF, tS);                      //   <font...>
281   
282   if (isActive)
283     [_response appendContentString:@"<b>"];
284
285   if (!(bgIcon || bgcolor))
286     [_response appendContentString:@"["];
287   
288   [_response appendContentString:title];
289   
290   if (!(bgIcon || bgcolor))
291     [_response appendContentString:@"]"];
292
293   if (isActive)
294     [_response appendContentString:@"</b>"];
295
296   if (hasFont)
297     [_response appendContentString:@"</font"];
298   
299   [_response appendContentString:@"</a>"];
300
301   [_response appendContentString:@"</td>"];
302   
303   [_ctx deleteLastElementIDComponent]; // delete tab-key
304 }
305
306 - (void)appendHeaderFootRow:(id)_node
307   toResponse:(WOResponse *)_response
308   inContext:(WOContext *)_ctx
309   isLeftActive:(BOOL)_isLeftActive
310 {
311   NSString *bgcolor = nil;
312   
313   /* header foot row */
314   bgcolor = [self stringFor:@"bgcolor" node:_node ctx:_ctx];
315
316   [_response appendContentString:@"<tr"];
317   if (bgcolor) {
318     [_response appendContentString:@" bgcolor=\""];
319     [_response appendContentHTMLAttributeValue:bgcolor];
320     [_response appendContentString:@"\""];
321   }
322   [_response appendContentString:@">"];
323     
324     /* left corner */
325   [_response appendContentString:@"<td align=\"left\" width=\"10\">"];
326   
327   if (_isLeftActive)
328     [_response appendContentString:@"&nbsp;"];
329     
330   if (!_isLeftActive) {
331     NSString *uri;
332
333     uri = [self stringFor:@"leftcornericon" node:_node ctx:_ctx];
334     if ((uri = ODRUriOfResource(uri, _ctx))) {
335       [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
336       [_response appendContentString:uri];
337       [_response appendContentString:@"\" />"];
338     }
339     else
340       [_response appendContentString:@"&nbsp;"];
341   }
342   [_response appendContentString:@"</td>"];
343
344   /* right corner */
345   [_response appendContentString:@"<td align=\"right\">"];
346   {
347     NSString *uri;
348     
349     uri = [self stringFor:@"rightcornericon" node:_node ctx:_ctx];
350     if ((uri = ODRUriOfResource(uri, _ctx))) {
351       [_response appendContentString:@"<img border=\"0\" alt=\"\" src=\""];
352       [_response appendContentString:uri];
353       [_response appendContentString:@"\" />"];
354     }
355     else
356       [_response appendContentString:@"&nbsp;"];
357   }
358   [_response appendContentString:@"</td>"];
359     
360   [_response appendContentString:@"</tr>"];
361 }
362
363 - (void)appendTabs:(id)_node
364   toResponse:(WOResponse *)_response
365   inContext:(WOContext *)_ctx
366 {
367   NSArray  *tabNodes;
368   NSString *selection;
369   BOOL     isLeftActive = NO, isFirst;
370   unsigned i, count;
371   
372   [_ctx appendElementIDComponent:@"h"];
373
374   tabNodes  = ODRLookupQueryPath(_node, @"-tab");
375   selection = self->activeKey;
376   
377   /* generate header row */
378   
379   [_response appendContentString:@"<tr>"];
380   [_response appendContentString:
381                @"<td colspan='2'>"
382                @"<table border='0' cellpadding='0' "
383                @"cellspacing='0'><tr>"];
384   
385   for (i = 0, isFirst = YES, count = [tabNodes count]; i < count; i++) {
386     NSString *key;
387     id       tab;
388     
389     tab = [tabNodes objectAtIndex:i];
390     
391     if ([self boolFor:@"disabled" node:tab ctx:_ctx])
392       continue;
393     
394     key = [self stringFor:@"key" node:tab ctx:_ctx];
395     if (isFirst && [key isEqualToString:selection])
396       isLeftActive = YES;
397     
398     [self appendTab:tab node:_node response:_response ctx:_ctx left:isFirst];
399     isFirst = NO;
400   }
401   [_response appendContentString:@"</tr></table></td></tr>"];
402   
403   [_ctx deleteLastElementIDComponent];
404   
405   [self appendHeaderFootRow:_node
406         toResponse:_response
407         inContext:_ctx
408         isLeftActive:isLeftActive];
409 }
410
411 - (void)appendNode:(id)_node
412   toResponse:(WOResponse *)_response
413   inContext:(WOContext *)_ctx
414 {
415   NSString     *bgcolor;
416
417   [self setActiveKey:_node inContext:_ctx];
418
419   /* start appending */
420   [_response appendContentString:
421                @"<table border='0' width='100%'"
422                @" cellpadding='0' cellspacing='0'>"];
423   
424   /* appending tabs */
425
426   [self appendTabs:_node toResponse:_response inContext:_ctx];
427
428   bgcolor   = [self stringFor:@"bgcolor" node:_node ctx:_ctx];
429
430   /* append body row */
431   {
432     [_response appendContentString:@"<tr><td colspan='2'"];
433     if (bgcolor) {
434       [_response appendContentString:@" bgcolor=\""];
435       [_response appendContentHTMLAttributeValue:bgcolor];
436       [_response appendContentString:@"\""];
437     }
438     [_response appendContentString:@">"];
439     
440     if (/*indentContent*/ YES) {
441       /* start padding table */
442       [_response appendContentString:
443                    @"<table border='0' width='100%'"
444                    @" cellpadding='10' cellspacing='0'>"];
445       [_response appendContentString:@"<tr><td>"];
446     }
447     
448     [_ctx appendElementIDComponent:@"b"];
449     
450     /* generate currently active body */
451     {
452       NSArray *tabs;
453       int     i, cnt;
454       
455       tabs = ODRLookupQueryPath(_node, @"-tab");
456       cnt  = [tabs count];
457       
458       [_ctx appendElementIDComponent:self->activeKey];
459       for (i=0; i<cnt; i++) {
460         NSString *key;
461         id       tab;
462
463         tab = [tabs objectAtIndex:i];
464         key = [self stringFor:@"key" node:tab ctx:_ctx]; 
465         if ([key isEqualToString:self->activeKey]) {
466           [super appendNode:tab toResponse:_response inContext:_ctx];
467           break;
468         }
469       }
470       [_ctx deleteLastElementIDComponent];
471     }
472     
473     [_ctx deleteLastElementIDComponent];
474     
475     if (/*indentContent*/ YES)
476       /* close padding table */
477       [_response appendContentString:@"</td></tr></table>"];
478     
479     [_response appendContentString:@"</td></tr>"];
480   }
481   
482   [_response appendContentString:@"</table>"];
483 }
484
485 @end /* ODR_bind_tabview */