]> err.no Git - sope/blob - sope-appserver/WEExtensions/WETreeData.m
added strict OSX bundle dependencies
[sope] / sope-appserver / WEExtensions / WETreeData.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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 /*
23   WETreeDate
24
25   Take a look at WETreeView for more information.
26
27   WETreeData associations:
28     isTreeElement
29     icon
30     cornerIcon
31     title
32     string
33     treeLink (do not generate a -componentActionURL but use the specified link)
34
35   Example:
36       TreeDataCell: WETreeData {
37         isTreeElement = YES; // this is a tree cell (that means, it has plus
38                              // and minus icons and all that stuff)
39       }
40       DataCell: WETreeData {
41         isTreeElement = NO;  // this is NOT a  tree cell, i.e. it does NOT
42                              // have any plus or minus icons. (This is just a
43                              // ordinary <td></td>!!!)
44       }
45 */
46
47 #include <NGObjWeb/WODynamicElement.h>
48
49 @interface WETreeData : WODynamicElement
50 {
51   // WODynamicElement: extraAttributes
52   // WODynamicElement: otherTagString
53 @protected
54   WOAssociation *isTreeElement;
55   WOAssociation *title;
56   WOAssociation *string;
57   WOAssociation *icon;
58   WOAssociation *cornerIcon;
59   WOAssociation *treeLink;
60   
61   BOOL          doTable;
62   WOElement     *template;
63 }
64
65 @end
66
67 #include "WETreeContextKeys.h"
68 #include "WETreeMatrixElement.h"
69 #include "common.h"
70
71 @implementation WETreeData
72
73 static Class StrClass = Nil;
74
75 + (void)initialize {
76   StrClass = [NSString class];
77 }
78
79 - (id)initWithName:(NSString *)_name
80   associations:(NSDictionary *)_config
81   template:(WOElement *)_root
82 {
83   if ((self = [super initWithName:_name associations:_config template:_root])){
84     self->isTreeElement = WOExtGetProperty(_config, @"isTreeElement");
85     self->icon          = WOExtGetProperty(_config, @"icon");
86     self->cornerIcon    = WOExtGetProperty(_config, @"cornerIcon");
87     self->title         = WOExtGetProperty(_config, @"title");
88     self->string        = WOExtGetProperty(_config, @"string");
89     self->treeLink      = WOExtGetProperty(_config, @"treeLink");
90
91     self->template = [_root retain];
92   }
93   return self;
94 }
95
96 - (void)dealloc {
97   [self->isTreeElement release];
98   [self->treeLink      release];
99   [self->icon          release];
100   [self->cornerIcon    release];
101   [self->title         release];
102   [self->string        release];
103   [self->template      release];
104   [super dealloc];
105 }
106
107 /* HTML generation */
108
109 - (void)_appendIcon:(NSString *)_icon alt:(NSString *)_alt
110   toResponse:(WOResponse *)_response inContext:(WOContext *)_ctx
111 {
112   NSString *iconWidth;
113   
114   iconWidth = [_ctx objectForKey:WETreeView_IconWidth];
115   
116   [_response appendContentString:@"<img border=\"0\" src=\""];
117   [_response appendContentHTMLAttributeValue:_icon];
118   [_response appendContentString:@"\""];
119   
120   if ([iconWidth length] > 0) {
121     [_response appendContentString:@" width=\""];
122     [_response appendContentString:iconWidth];
123     [_response appendContentString:@"\""];
124   }
125   if ([_alt length] > 0) {
126     [_response appendContentString:@" alt=\""];
127     [_response appendContentHTMLAttributeValue:_alt];
128     [_response appendContentString:@"\""];
129   }
130   
131   if (_ctx->wcFlags.xmlStyleEmptyElements)
132     [_response appendContentString:@" />"];
133   else
134     [_response appendContentString:@">"];
135 }
136
137 - (void)_appendLink:(NSString *)_icon resp:(WOResponse *)_response
138   ctx:(WOContext *)_ctx
139 {
140   BOOL doForm;
141   
142   // doForm = [_ctx isInForm];
143   doForm = NO;
144   
145   if (doForm) {
146     // TODO: we might want to support an assoc to provide the name
147     [_response appendContentString:@"<input type=\"image\" border=\"0\""];
148     [_response appendContentString:@" align=\"top\" name=\""];
149     [_response appendContentString:[_ctx elementID]];
150     [_response appendContentString:@"\" src=\""];
151     [_response appendContentString:_icon];
152     if (_ctx->wcFlags.xmlStyleEmptyElements)
153       [_response appendContentString:@"\" />"];
154     else
155       [_response appendContentString:@"\">"];
156   }
157   else {
158     NSString *link;
159     
160     [_ctx appendElementIDComponent:WETreeView_ZOOM_ACTION_ID];
161
162     link = (self->treeLink != nil)
163       ? [self->treeLink stringValueInComponent:[_ctx component]]
164       : [_ctx componentActionURL];
165     
166     if ([link length] > 0) {
167       [_response appendContentString:@"<a href=\""];
168       [_response appendContentString:link];
169       [_response appendContentString:@"\">"];
170     }
171     [self _appendIcon:_icon alt:@"z" toResponse:_response inContext:_ctx];
172     if ([link length] > 0)
173       [_response appendContentString:@"</a>"];
174     
175     [_ctx deleteLastElementIDComponent];
176   }
177 }
178
179 - (void)_appendTreeElement:(NSString *)_key
180   toResponse:(WOResponse *)_response
181   inContext:(WOContext *)_ctx
182 {
183   BOOL     doLink;
184   NSString *img;
185   NSString *link;
186   
187   // TODO: we need to patch this for stateless operation
188   
189   link   = nil;
190   doLink = (_key == WETreeView_Plus   || _key == WETreeView_CornerPlus ||
191             _key == WETreeView_Minus  || _key == WETreeView_CornerMinus);
192   if (doLink) {
193     if (self->treeLink) {
194       link = [self->treeLink stringValueInComponent:[_ctx component]];
195       if ([link length] == 0)
196         doLink = NO;
197     }
198   }
199   
200   img = [_ctx objectForKey:_key];
201   img = WEUriOfResource(img, _ctx);
202   
203   if (_key == WETreeView_Leaf) {
204     NSString *tmp = [self->icon stringValueInComponent:[_ctx component]];
205     
206     tmp = WEUriOfResource(tmp, _ctx);
207     img = (tmp) ? tmp : img;    
208   }
209   else if (_key == WETreeView_CornerLeaf) {
210     NSString *tmp = [self->cornerIcon stringValueInComponent:[_ctx component]];
211     tmp = WEUriOfResource(tmp, _ctx);
212     img = (tmp) ? tmp : img;
213   }
214   
215   if (img == nil) {
216     if (doLink) {
217       [_ctx appendElementIDComponent:WETreeView_ZOOM_ACTION_ID];
218       [_response appendContentString:@"<a href=\""];
219       [_response appendContentString:(link ? link :[_ctx componentActionURL])];
220       [_response appendContentString:@"\">"];
221
222       if (_key == WETreeView_Plus || _key == WETreeView_CornerPlus)
223         [_response appendContentString:@"<tt>[+]</tt>"];
224       else if (_key == WETreeView_Minus || _key == WETreeView_CornerMinus)
225         [_response appendContentString:@"<tt>[-]</tt>"];
226       
227       [_response appendContentString:@"</a>"];
228       [_ctx deleteLastElementIDComponent]; /* WETreeView_ZOOM_ACTION_ID */
229     }
230     else if (_key == WETreeView_Leaf)
231       [_response appendContentString:@"<tt>--&nbsp;</tt>"];
232     else if (_key == WETreeView_CornerLeaf)
233       [_response appendContentString:@"<tt>-|&nbsp;</tt>"];
234     else if (_key == WETreeView_Line)
235       [_response appendContentString:@"<tt>&nbsp;|&nbsp;</tt>"];
236     else if (_key == WETreeView_CornerLeaf)
237       [_response appendContentString:@"<tt>&nbsp;--</tt>"];
238     else if (_key == WETreeView_Junction || _key == WETreeView_Corner)
239       [_response appendContentString:@"<tt>&nbsp;|-</tt>"];
240     else if (_key == WETreeView_Space)
241       [_response appendContentString:@"<tt>&nbsp;&nbsp;&nbsp;</tt>"];
242   }
243   else {
244     if (doLink)
245       [self _appendLink:img resp:_response ctx:_ctx];
246     else
247       [self _appendIcon:img alt:@"z" toResponse:_response inContext:_ctx];
248   }
249 }
250
251 - (void)appendHeader:(WOResponse *)_response inContext:(WOContext *)_ctx {
252   WOComponent *cmp;
253   NSString    *tmp;
254   BOOL        isTree;
255   
256   cmp    = [_ctx component];
257   tmp    = [self->title stringValueInComponent:cmp];
258   isTree = [self->isTreeElement boolValueInComponent:cmp];;
259   
260   if (tmp == nil)
261     return;
262   
263   if (self->doTable) {
264     [_response appendContentString:@"<td"];
265     [self appendExtraAttributesToResponse:_response inContext:_ctx];
266     if (self->otherTagString) {
267       [_response appendContentCharacter:' '];
268       [_response appendContentString:
269                    [self->otherTagString stringValueInComponent:
270                         [_ctx component]]];
271     }
272     if (isTree) {
273       [_response appendContentString:@" colspan=\""];
274       [_response appendContentString:
275                    [[_ctx objectForKey:WETreeView_HEADER_MODE] stringValue]];
276       [_response appendContentString:@"\"><nobr>"];
277     }
278     else
279       [_response appendContentString:@"><nobr>"];
280   }
281   
282   [_response appendContentString:@"<b>"];
283   [_response appendContentHTMLString:tmp];
284   [_response appendContentString:@"</b>"];
285   
286   if (doTable)
287     [_response appendContentString:@"</nobr></td>"];
288 }
289
290 - (void)appendData:(WOResponse *)_response inContext:(WOContext *)_ctx {
291   /* TODO: split up this method */
292   _WETreeMatrixElement *treeElement;
293   WOComponent *cmp       = nil;
294   BOOL        isTree     = NO;
295   NSString    *content   = nil;
296   int         i;
297
298   cmp         = [_ctx component];
299   isTree      = [self->isTreeElement boolValueInComponent:cmp];
300   content     = [self->string stringValueInComponent:cmp];
301   treeElement = [_ctx objectForKey:WETreeView_TreeElement];
302
303   if (isTree) {
304     for (i = 0; i < [treeElement depth]+1; i++) {
305       NSString *iconWidth;
306       NSString *treeElm;
307
308       iconWidth = [_ctx objectForKey:WETreeView_IconWidth];
309       
310       treeElm = (i < [treeElement depth])
311         ? [treeElement elementAtIndex:i]
312         : [treeElement leaf];
313
314       if (self->doTable) {
315         [_response appendContentString:@"<td"];
316         [self appendExtraAttributesToResponse:_response inContext:_ctx];
317         [_response appendContentString:@" valign=\"middle\" align=\"center\""];
318         
319         if (iconWidth) {
320           NSString *s;
321           s = [[StrClass alloc] initWithFormat:@" width=\"%@\"", iconWidth];
322           [_response appendContentString:s];
323           [s release];
324         }
325         
326         if (treeElm == WETreeView_Plus     || treeElm == WETreeView_Minus ||
327             treeElm == WETreeView_Junction || treeElm == WETreeView_Line) {
328           NSString *img;
329           
330           img = [_ctx objectForKey:WETreeView_Line];
331           img = WEUriOfResource(img, _ctx);
332           if (img) {
333             [_response appendContentString:@" background=\""];
334             [_response appendContentString:img];
335             [_response appendContentCharacter:'"'];
336           }
337         }
338         [_response appendContentString:@"><nobr>"];
339       }
340         
341       [self _appendTreeElement:treeElm toResponse:_response inContext:_ctx];
342       if (self->doTable)
343         [_response appendContentString:@"</nobr></td>"];
344     }
345
346     if (self->doTable) {
347       [_response appendContentString:@"<td"];
348       [self appendExtraAttributesToResponse:_response inContext:_ctx];
349       [_response appendContentString:@" width='97%'"];
350       [_response appendContentString:@" valign='middle' align='left'"];
351       [_response appendContentString:@" colspan=\""];
352       [_response appendContentString:[treeElement colspanAsString]];
353       [_response appendContentString:@"\">"];
354     }
355     
356     /* add cell content */
357     [self->template appendToResponse:_response inContext:_ctx];
358     if (content)
359       [_response appendContentHTMLString:content];
360     
361     if (self->doTable)
362       [_response appendContentString:@"</td>"];
363   }
364   else { // ! isTree
365     if (self->doTable) {
366       [_response appendContentString:@"<td"];
367       [self appendExtraAttributesToResponse:_response inContext:_ctx];
368       if (self->otherTagString) {
369         [_response appendContentCharacter:' '];
370         [_response appendContentString:
371                    [self->otherTagString stringValueInComponent:
372                         [_ctx component]]];
373       }
374       [_response appendContentCharacter:'>'];
375     }
376     
377     /* add cell content */
378     [self->template appendToResponse:_response inContext:_ctx];
379     if (content) [_response appendContentHTMLString:content];
380
381     if (self->doTable)
382       [_response appendContentString:@"</td>"];
383   }
384 }
385
386 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
387   [self->template takeValuesFromRequest:_rq inContext:_ctx];
388 }
389
390 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
391   return [self->template invokeActionForRequest:_rq inContext:_ctx];
392 }
393
394 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
395   self->doTable = ([_ctx objectForKey:WETreeView_RenderNoTable] == nil);
396   
397   if ([_ctx objectForKey:WETreeView_HEADER_MODE])
398     [self appendHeader:_response inContext:_ctx];
399   else
400     [self appendData:_response inContext:_ctx];
401 }
402
403 @end /* WETreeData */