+/* UI navigation */
+
+- (NSString *)treeNavigationLinkAtDepth:(int)_depth {
+ NSString *link;
+ unsigned i;
+
+ link = [[self nameInContainer] stringByAppendingString:@"/"];
+ for (i = 0; i < _depth; i++)
+ link = [@"../" stringByAppendingString:link];
+ return link;
+}
+
+- (id)treeNavigationBlockForLeafNodeAtDepth:(int)_depth {
+ NSMutableDictionary *md;
+
+ md = [NSMutableDictionary dictionaryWithCapacity:4];
+ [md setObject:[self davDisplayName] forKey:@"title"];
+ [md setObject:[self treeNavigationLinkAtDepth:_depth] forKey:@"link"];
+
+ if ([[self toManyRelationshipKeys] count] > 0)
+ /* trigger plus in treeview */
+ [md setObject:[NSArray arrayWithObject:@"FAKE"] forKey:@"children"];
+ return md;
+}
+
+- (id)treeNavigationBlockForActiveNode {
+ /* this generates the block for the clientObject */
+ NSMutableDictionary *md;
+ NSMutableArray *blocks;
+ NSArray *folders;
+ unsigned i, count;
+
+ /* process child folders */
+
+ folders = [self fetchSubfolders];
+ count = [folders count];
+ blocks = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ id block;
+
+ block = [[folders objectAtIndex:i]
+ treeNavigationBlockForLeafNodeAtDepth:0];
+ if ([block isNotNull]) [blocks addObject:block];
+ }
+
+ /* build block */
+
+ md = [NSMutableDictionary dictionaryWithCapacity:4];
+ [md setObject:[NSNumber numberWithBool:YES] forKey:@"isActiveNode"];
+ [md setObject:[NSNumber numberWithBool:YES] forKey:@"isPathNode"];
+ [md setObject:[self davDisplayName] forKey:@"title"];
+ [md setObject:[self nameInContainer] forKey:@"name"];
+ [md setObject:@"." forKey:@"link"];
+ if ([blocks count] > 0)
+ [md setObject:blocks forKey:@"children"];
+ return md;
+}
+
+- (id)treeNavigationBlockWithActiveChildBlock:(id)_activeChildBlock
+ depth:(int)_depth
+{
+ NSMutableDictionary *md;
+ NSMutableArray *blocks;
+ NSString *activeName;
+ NSArray *folders;
+ unsigned i, count;
+
+ activeName = [_activeChildBlock valueForKey:@"name"];
+
+ /* process child folders */
+
+ folders = [self fetchSubfolders];
+ count = [folders count];
+ blocks = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ id folder;
+ id block;
+
+ folder = [folders objectAtIndex:i];
+ if ([activeName isEqualToString:[folder nameInContainer]]) {
+ block = _activeChildBlock;
+ }
+ else {
+ block = [folder treeNavigationBlockForLeafNodeAtDepth:_depth];
+ }
+ if ([block isNotNull]) [blocks addObject:block];
+ }
+
+ /* build block */
+
+ md = [NSMutableDictionary dictionaryWithCapacity:4];
+ [md setObject:[self davDisplayName] forKey:@"title"];
+ [md setObject:[self nameInContainer] forKey:@"name"];
+ [md setObject:[NSNumber numberWithBool:YES] forKey:@"isPathNode"];
+ [md setObject:[self treeNavigationLinkAtDepth:(_depth + 1)] forKey:@"link"];
+ if ([blocks count] > 0)
+ [md setObject:blocks forKey:@"children"];
+
+ /* recurse up */
+
+ return [[self container] treeNavigationBlockWithActiveChildBlock:md
+ depth:(_depth + 1)];
+}
+
+- (id)treeNavigationNodes {
+ return [[self container] treeNavigationBlockWithActiveChildBlock:
+ [self treeNavigationBlockForActiveNode]
+ depth:1];
+}
+