WOAssociation *cornerIcon;
WOAssociation *treeLink;
- BOOL doTable;
+ BOOL doTable; // THREAD (used during generation)
WOElement *template;
}
toResponse:(WOResponse *)_response
inContext:(WOContext *)_ctx
{
+ /* this appends plus and minus images and links to expand/collapse */
+ // TODO: explain more
BOOL doLink;
NSString *img;
NSString *link;
[_response appendContentString:@"</nobr></td>"];
}
+- (void)appendPaddingCellsOfTreeElement:(id)treeElement
+ toResponse:(WOResponse *)_response
+ inContext:(WOContext *)_ctx
+{
+ /*
+ This renders all the tree-view related lines and plus/minus signs,
+ padding etc.
+ */
+ unsigned int i;
+
+ for (i = 0; i < [treeElement depth]+1; i++) {
+ NSString *iconWidth;
+ NSString *treeElm;
+
+ iconWidth = [_ctx objectForKey:WETreeView_IconWidth];
+
+ treeElm = (i < [treeElement depth])
+ ? [treeElement elementAtIndex:i]
+ : [treeElement leaf];
+
+ if (self->doTable) {
+ [_response appendContentString:@"<td"];
+ [self appendExtraAttributesToResponse:_response inContext:_ctx];
+ [_response appendContentString:@" valign=\"middle\" align=\"center\""];
+
+ if (iconWidth) {
+ NSString *s;
+ s = [[StrClass alloc] initWithFormat:@" width=\"%@\"", iconWidth];
+ [_response appendContentString:s];
+ [s release];
+ }
+
+ if (treeElm == WETreeView_Plus || treeElm == WETreeView_Minus ||
+ treeElm == WETreeView_Junction || treeElm == WETreeView_Line) {
+ NSString *img;
+
+ img = [_ctx objectForKey:WETreeView_Line];
+ img = WEUriOfResource(img, _ctx);
+ if (img) {
+ [_response appendContentString:@" background=\""];
+ [_response appendContentString:img];
+ [_response appendContentCharacter:'"'];
+ }
+ }
+ [_response appendContentString:@"><nobr>"];
+ }
+
+ /* this appends plus and minus images and links to expand/collapse */
+ [self _appendTreeElement:treeElm toResponse:_response inContext:_ctx];
+
+ if (self->doTable)
+ [_response appendContentString:@"</nobr></td>"];
+ }
+}
+
- (void)appendData:(WOResponse *)_response inContext:(WOContext *)_ctx {
/* TODO: split up this method */
_WETreeMatrixElement *treeElement;
WOComponent *cmp = nil;
BOOL isTree = NO;
NSString *content = nil;
- int i;
-
+
cmp = [_ctx component];
isTree = [self->isTreeElement boolValueInComponent:cmp];
content = [self->string stringValueInComponent:cmp];
treeElement = [_ctx objectForKey:WETreeView_TreeElement];
if (isTree) {
- for (i = 0; i < [treeElement depth]+1; i++) {
- NSString *iconWidth;
- NSString *treeElm;
-
- iconWidth = [_ctx objectForKey:WETreeView_IconWidth];
-
- treeElm = (i < [treeElement depth])
- ? [treeElement elementAtIndex:i]
- : [treeElement leaf];
-
- if (self->doTable) {
- [_response appendContentString:@"<td"];
- [self appendExtraAttributesToResponse:_response inContext:_ctx];
- [_response appendContentString:@" valign=\"middle\" align=\"center\""];
-
- if (iconWidth) {
- NSString *s;
- s = [[StrClass alloc] initWithFormat:@" width=\"%@\"", iconWidth];
- [_response appendContentString:s];
- [s release];
- }
-
- if (treeElm == WETreeView_Plus || treeElm == WETreeView_Minus ||
- treeElm == WETreeView_Junction || treeElm == WETreeView_Line) {
- NSString *img;
-
- img = [_ctx objectForKey:WETreeView_Line];
- img = WEUriOfResource(img, _ctx);
- if (img) {
- [_response appendContentString:@" background=\""];
- [_response appendContentString:img];
- [_response appendContentCharacter:'"'];
- }
- }
- [_response appendContentString:@"><nobr>"];
- }
-
- [self _appendTreeElement:treeElm toResponse:_response inContext:_ctx];
- if (self->doTable)
- [_response appendContentString:@"</nobr></td>"];
- }
+ /* this is a first cell in a row, it renders the tree controls */
+ [self appendPaddingCellsOfTreeElement:treeElement
+ toResponse:_response inContext:_ctx];
if (self->doTable) {
[_response appendContentString:@"<td"];
[_response appendContentString:@"</td>"];
}
else { // ! isTree
+ /* this is a follow-up cell in a row, it renders just the content */
if (self->doTable) {
[_response appendContentString:@"<td"];
[self appendExtraAttributesToResponse:_response inContext:_ctx];
/* add cell content */
[self->template appendToResponse:_response inContext:_ctx];
- if (content) [_response appendContentHTMLString:content];
+ if (content != nil) [_response appendContentHTMLString:content];
if (self->doTable)
[_response appendContentString:@"</td>"];
}
}
+/* handle requests */
+
- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
[self->template takeValuesFromRequest:_rq inContext:_ctx];
}
return [self->template invokeActionForRequest:_rq inContext:_ctx];
}
+/* generate response */
+
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
- self->doTable = ([_ctx objectForKey:WETreeView_RenderNoTable] == nil);
+ self->doTable = ([_ctx objectForKey:WETreeView_RenderNoTable] == nil)?YES:NO;
if ([_ctx objectForKey:WETreeView_HEADER_MODE])
[self appendHeader:_response inContext:_ctx];
#include <NGObjWeb/WODynamicElement.h>
-@class NSMutableArray;
-
@interface WETreeView : WODynamicElement
{
// WODynamicElement: extraAttributes
WOAssociation *lineIcon;
WOAssociation *spaceIcon;
WOAssociation *iconWidth;
-
- // private:
- NSMutableArray *matrix;
WOElement *template;
}
[self->iconWidth release];
[self->template release];
- [self->matrix release];
[super dealloc];
}
return ([a count] > 0) ? a : nil;
}
+/* handle requests */
+
- (void)_takeValuesFromRequest:(WORequest *)_req
inContext:(WOContext *)_ctx
withArray:(NSArray *)array
return result;
}
+/* collect rows */
+
- (void)appendList:(NSArray *)_list
treeElement:(_WETreeMatrixElement *)_element
+ toTableRows:(NSMutableArray *)_matrix
inContext:(WOContext *)_ctx
{
/* TODO: split up this method! */
#endif
for (i = 0; i < cnt; i++) {
- id object = [_list objectAtIndex:i];
+ id object;
+ object = [_list objectAtIndex:i];
+
[_element setIndex:i];
[_element setItem:object];
newElement = [[_WETreeMatrixElement alloc] initWithElement:_element];
- [self->matrix addObject:newElement];
+ [_matrix addObject:newElement];
[newElement release]; newElement = nil;
if (isZoom) {
newElement = [[_WETreeMatrixElement alloc] initWithElement:_element];
- [self appendList:sl treeElement:newElement inContext:_ctx];
+ [self appendList:sl treeElement:newElement
+ toTableRows:_matrix inContext:_ctx];
[newElement release]; newElement = nil;
}
}
[newElement setLeaf:WETreeView_Leaf];
- [self->matrix addObject:newElement];
+ [_matrix addObject:newElement];
[newElement release]; newElement = nil;
}
}
}
}
-- (void)_calcMatrixInContext:(WOContext *)_ctx depth:(int *)_depth {
- _WETreeMatrixElement *treeElm = nil;
- NSArray *top = nil;
+- (NSArray *)_calcMatrixInContext:(WOContext *)_ctx depth:(int *)_depth {
+ /*
+ Note: returns a retained object!
+
+ This is the main entry for the calculation of the rows and the depth
+ nesting.
+ The rows are stored in _WETreeMatrixElement objects which know about
+ their colspan, depth and columns.
+ */
+ NSMutableArray *tableRows;
+ _WETreeMatrixElement *treeElm;
+ NSArray *top;
int i, cnt, d, maxDepth = 0;
- top = [self->list valueInComponent:[_ctx component]];
+ top = [self->list valueInComponent:[_ctx component]];
+ tableRows = [[NSMutableArray alloc] initWithCapacity:64];
- [self->matrix release]; self->matrix = nil;
- self->matrix = [[NSMutableArray allocWithZone:[self zone]]
- initWithCapacity:64];
-
treeElm = [[_WETreeMatrixElement alloc] init];
+ [self appendList:top treeElement:treeElm toTableRows:tableRows
+ inContext:_ctx];
+ [treeElm release]; treeElm = nil;
- [self appendList:top treeElement:treeElm inContext:_ctx];
+ cnt = [tableRows count];
- [treeElm release]; treeElm = nil;
-
- cnt = [self->matrix count];
-
/* calc max depth */
for (i = 0; i < cnt; i++) {
- d = [[self->matrix objectAtIndex:i] depth];
+ d = [[tableRows objectAtIndex:i] depth];
maxDepth = (maxDepth < d) ? d : maxDepth;
}
- /* update depth */
+ /* update colspan (max-depth minus element-depth) */
for (i = 0; i < cnt; i++) {
_WETreeMatrixElement *element;
- element = [self->matrix objectAtIndex:i];
- [element setColspan:maxDepth-[element depth]+1];
+ element = [tableRows objectAtIndex:i];
+ [element setColspan:(maxDepth - [element depth] + 1)];
}
*_depth = maxDepth + 2;
+ return tableRows;
}
+/* generate response, main entry function */
+
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
WOComponent *comp;
+ NSArray *matrix;
BOOL doTable;
int i, cnt, depth;
@"<table border='0' cellspacing='0' cellpadding='0'"];
[self appendExtraAttributesToResponse:_response inContext:_ctx];
- if (self->otherTagString) {
+ if (self->otherTagString != nil) {
[_response appendContentCharacter:' '];
[_response appendContentString:
[self->otherTagString stringValueInComponent:
}
[_response appendContentCharacter:'>'];
}
+
+ matrix = [self _calcMatrixInContext:_ctx depth:&depth];
- [self _calcMatrixInContext:_ctx depth:&depth];
-
- /* append table title */
+ /* append table title */
if (doTable)
[_response appendContentString:@"<tr>"];
[_response appendContentString:@"<br />"];
else
[_response appendContentString:@"<br>"];
+
+ /* generate content rows */
- cnt = [self->matrix count];
-
- for (i = 0; i < cnt; i++) {
+ for (i = 0, cnt = [matrix count]; i < cnt; i++) {
_WETreeMatrixElement *element;
- element = [self->matrix objectAtIndex:i];
+ element = [matrix objectAtIndex:i];
+
+ /* push positioning info into component */
if ([self->index isValueSettable])
- [self->index setUnsignedIntValue:[element index]
- inComponent:comp];
-
+ [self->index setUnsignedIntValue:[element index] inComponent:comp];
+
if ([self->item isValueSettable])
- [self->item setValue:[element item]
- inComponent:comp];
+ [self->item setValue:[element item] inComponent:comp];
if ([self->currentPath isValueSettable])
- [self->currentPath setValue:[element currentPath]
- inComponent:comp];
+ [self->currentPath setValue:[element currentPath] inComponent:comp];
+ /* set active tree element in context (tree cannot be nested!) */
+
[_ctx setObject:element forKey:WETreeView_TreeElement];
+ /* start table row and update element-ids */
+
[_ctx appendElementIDComponent:[element elementID]];
-
[_ctx appendElementIDComponent:@"end"];
if (doTable)
[_response appendContentString:@"<tr>"];
+
+ /* generate content */
+
[self->template appendToResponse:_response inContext:_ctx];
+
+ /* close table row and update element-ids */
+
if (doTable)
[_response appendContentString:@"</tr>"];
else if (_ctx->wcFlags.xmlStyleEmptyElements)
if (doTable)
[_response appendContentString:@"</table>"];
+
+ /* cleanup rendering context */
[self removeConfigInContext:_ctx];
[_ctx removeObjectForKey:WETreeView_RenderNoTable];
- [self->matrix release]; self->matrix = nil;
+ [matrix release]; matrix = nil;
}
@end /* WETreeView */