2004-11-09 Helge Hess <helge.hess@skyrix.com>
+ * moved all tree navigation code to UIxMailTree (v0.9.51)
+
* SOGoMailBaseObject.m, SOGoMailAccounts.m: moved tree code to separate
file (v0.9.50)
\
SOGoDraftsFolder.m \
SOGoDraftObject.m \
- \
- SOGoMailTree.m \
Mailer_RESOURCE_FILES += \
Version \
@end
-@interface SOGoMailBaseObject(Tree)
-
-/* UI navigation */
-
-- (NSArray *)treeNavigationNodes;
-
-@end
-
#endif /* __Mailer_SOGoMailBaseObject_H__ */
+++ /dev/null
-/*
- Copyright (C) 2004 SKYRIX Software AG
-
- This file is part of OpenGroupware.org.
-
- OGo is free software; you can redistribute it and/or modify it under
- the terms of the GNU Lesser General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- OGo is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with OGo; see the file COPYING. If not, write to the
- Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
-*/
-// $Id: SOGoMailAccounts.m 274 2004-08-26 13:10:49Z znek $
-
-#include "SOGoMailBaseObject.h"
-#include "SOGoMailAccounts.h"
-#include <NGObjWeb/SoObject+SoDAV.h>
-#include "common.h"
-
-static BOOL debugTree = NO;
-
-@implementation SOGoMailBaseObject(Tree)
-
-- (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 {
- id block;
-
- block = [self treeNavigationBlockForActiveNode];
- if (debugTree) [self logWithFormat:@"own block: %@", block];
- block = [[self container] treeNavigationBlockWithActiveChildBlock:block
- depth:1];
- if (debugTree) [self logWithFormat:@" root block: %@", block];
- return block;
-}
-
-@end /* SOGoMailBaseObject(Tree) */
-
-@implementation SOGoMailAccounts(Tree)
-
-- (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:[@"../" stringByAppendingString:[self nameInContainer]]
- forKey:@"link"];
- if ([blocks count] > 0)
- [md setObject:blocks forKey:@"children"];
- return md;
-}
-
-- (id)treeNavigationBlockWithActiveChildBlock:(id)_activeChildBlock
- depth:(int)_depth
-{
- return _activeChildBlock;
-}
-
-- (id)treeNavigationNodes {
- return [self treeNavigationBlockForActiveNode];
-}
-
-@end /* SOGoMailAccounts(Tree) */
# Version file
-SUBMINOR_VERSION:=50
+SUBMINOR_VERSION:=51
# v0.9.44 requires NGMime v4.3.194
# v0.9.41 requires NGMime v4.3.190
2004-11-09 Helge Hess <helge.hess@skyrix.com>
+ * UIxMailTree.m: added tree navigation code from SoObjects (v0.9.60)
+
* UIxMailTree.m: removed unused code (v0.9.59)
* UIxMailListView.m: flush mail caches in the getMail action (v0.9.58)
\
UIxMailMainFrame.m \
UIxMailTree.m \
+ UIxMailTreeBlock.m \
UIxMailToolbar.m \
\
UIxMailAccountsView.m \
}
@end
+#include "UIxMailTreeBlock.h"
#include <SOGo/SoObjects/Mailer/SOGoMailBaseObject.h>
#include "common.h"
#include <NGObjWeb/SoComponent.h>
+#include <NGObjWeb/SoObject+SoDAV.h>
+
@implementation UIxMailTree
/* navigation nodes */
+- (BOOL)isRootObject:(id)_object {
+ if (![_object isNotNull]) {
+ [self logWithFormat:@"WARNING(%s): got to root by nil lookup ...",
+ __PRETTY_FUNCTION__];
+ return YES;
+ }
+
+ return [_object isKindOfClass:NSClassFromString(@"SOGoMailAccounts")];
+}
+
+- (NSString *)treeNavigationLinkForObject:(id)_object atDepth:(int)_depth {
+ NSString *link;
+ unsigned i;
+
+ link = [[_object nameInContainer] stringByAppendingString:@"/"];
+ for (i = 0; i < _depth; i++)
+ link = [@"../" stringByAppendingString:link];
+ return link;
+}
+
+- (UIxMailTreeBlock *)treeNavigationBlockForLeafNode:(id)_o atDepth:(int)_d {
+ UIxMailTreeBlock *md;
+ id blocks;
+
+ /*
+ Trigger plus in treeview if it has subfolders. It is an optimization that
+ we do not generate blocks for folders which are not displayed anyway.
+ */
+ blocks = [[_o toManyRelationshipKeys] count] > 0
+ ? [[NSArray alloc] initWithObjects:@"FAKE", nil]
+ : nil;
+
+ md = [UIxMailTreeBlock blockWithName:nil
+ title:[_o davDisplayName]
+ link:[self treeNavigationLinkForObject:_o atDepth:_d]
+ isPathNode:NO isActiveNode:NO
+ childBlocks:blocks];
+ return md;
+}
+
+- (UIxMailTreeBlock *)treeNavigationBlockForRootNode:(id)_object {
+ /* this generates the block for the clientObject */
+ UIxMailTreeBlock *md;
+ NSMutableArray *blocks;
+ NSArray *folders;
+ unsigned i, count;
+
+ /* process child folders */
+
+ folders = [_object fetchSubfolders];
+ count = [folders count];
+ blocks = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ id block;
+
+ block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
+ atDepth:0];
+ if ([block isNotNull]) [blocks addObject:block];
+ }
+ if ([blocks count] == 0)
+ blocks = nil;
+
+ /* build block */
+
+ md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
+ title:[_object davDisplayName]
+ link:[@"../" stringByAppendingString:
+ [_object nameInContainer]]
+ isPathNode:YES isActiveNode:YES
+ childBlocks:blocks];
+ return md;
+}
+
+- (UIxMailTreeBlock *)treeNavigationBlockForActiveNode:(id)_object {
+ /*
+ this generates the block for the clientObject (the object which has the
+ focus)
+ */
+ UIxMailTreeBlock *md;
+ NSMutableArray *blocks;
+ NSArray *folders;
+ unsigned i, count;
+
+ // TODO: maybe we can join the two implementations, this might not be
+ // necessary
+ if ([self isRootObject:_object]) /* we are at the top */
+ return [self treeNavigationBlockForRootNode:_object];
+
+ /* process child folders */
+
+ folders = [_object fetchSubfolders];
+ count = [folders count];
+ blocks = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ UIxMailTreeBlock *block;
+
+ block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
+ atDepth:0];
+ if ([block isNotNull]) [blocks addObject:block];
+ }
+ if ([blocks count] == 0) blocks = nil;
+
+ /* build block */
+
+ md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
+ title:[_object davDisplayName]
+ link:@"."
+ isPathNode:YES isActiveNode:YES
+ childBlocks:blocks];
+ return md;
+}
+
+- (UIxMailTreeBlock *)treeNavigationBlockForObject:(id)_object
+ withActiveChildBlock:(UIxMailTreeBlock *)_activeChildBlock
+ depth:(int)_depth
+{
+ UIxMailTreeBlock *md;
+ NSMutableArray *blocks;
+ NSString *activeName;
+ NSArray *folders;
+ unsigned i, count;
+
+ if ([self isRootObject:_object]) /* we are at the top */
+ return _activeChildBlock;
+
+ /* the following is not run on the OGoMailAccounts (root) object */
+
+ activeName = [_activeChildBlock valueForKey:@"name"];
+
+ /* process child folders */
+
+ folders = [_object fetchSubfolders];
+ count = [folders count];
+ blocks = [NSMutableArray arrayWithCapacity:count];
+ for (i = 0; i < count; i++) {
+ UIxMailTreeBlock *block;
+ id folder;
+
+ folder = [folders objectAtIndex:i];
+ block = [activeName isEqualToString:[folder nameInContainer]]
+ ? _activeChildBlock
+ : [self treeNavigationBlockForLeafNode:folder atDepth:_depth];
+
+ if ([block isNotNull]) [blocks addObject:block];
+ }
+ if ([blocks count] == 0) blocks = nil;
+
+ /* build block */
+
+ md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
+ title:[_object davDisplayName]
+ link:[self treeNavigationLinkForObject:_object
+ atDepth:(_depth + 1)]
+ isPathNode:YES isActiveNode:NO
+ childBlocks:blocks];
+
+ /* recurse up */
+
+ return [self treeNavigationBlockForObject:[_object container]
+ withActiveChildBlock:md
+ depth:(_depth + 1)];
+}
+
- (id)buildNavigationNodesForObject:(id)_object {
- return [_object treeNavigationNodes];
+ id block;
+
+ block = [self treeNavigationBlockForActiveNode:_object];
+
+ if ([self isRootObject:_object])
+ return block;
+
+ /* the following returns the root block! */
+ block = [self treeNavigationBlockForObject:[_object container]
+ withActiveChildBlock:block
+ depth:1];
+ return block;
}
/* tree */
--- /dev/null
+/*
+ Copyright (C) 2004 SKYRIX Software AG
+
+ This file is part of OpenGroupware.org.
+
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+// $Id: UIxMailTree.m 278 2004-08-26 23:29:09Z helge $
+
+#import <Foundation/NSObject.h>
+
+@class NSString, NSArray;
+
+@interface UIxMailTreeBlock : NSObject
+{
+ NSString *name;
+ NSString *title;
+ NSString *link;
+ NSArray *blocks;
+ struct {
+ int isPath:1;
+ int isActive:1;
+ int reserved:30;
+ } flags;
+}
+
++ (id)blockWithName:(NSString *)_name title:(NSString *)_title
+ link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
+ childBlocks:(NSArray *)_blocks;
+
+- (id)initWithName:(NSString *)_name title:(NSString *)_title
+ link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
+ childBlocks:(NSArray *)_blocks;
+
+@end
--- /dev/null
+/*
+ Copyright (C) 2004 SKYRIX Software AG
+
+ This file is part of OpenGroupware.org.
+
+ OGo is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with OGo; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+// $Id: UIxMailTree.m 278 2004-08-26 23:29:09Z helge $
+
+#include "UIxMailTreeBlock.h"
+#include "common.h"
+
+@implementation UIxMailTreeBlock
+
++ (id)blockWithName:(NSString *)_name title:(NSString *)_title
+ link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
+ childBlocks:(NSArray *)_blocks
+{
+ UIxMailTreeBlock *block;
+
+ block = [[self alloc] initWithName:_name title:_title link:_link
+ isPathNode:_isPath isActiveNode:_isActive
+ childBlocks:_blocks];
+ return [block autorelease];
+}
+
+- (id)initWithName:(NSString *)_name title:(NSString *)_title
+ link:(NSString *)_link isPathNode:(BOOL)_isPath isActiveNode:(BOOL)_isActive
+ childBlocks:(NSArray *)_blocks
+{
+ if ((self = [self init])) {
+ self->name = [_name copy];
+ self->title = [_title copy];
+ self->link = [_link copy];
+ self->blocks = [_blocks retain];
+
+ self->flags.isPath = _isPath ? 1 : 0;
+ self->flags.isActive = _isActive ? 1 : 0;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [self->blocks release];
+ [self->name release];
+ [self->title release];
+ [self->link release];
+ [super dealloc];
+}
+
+/* accessors */
+
+- (NSString *)name {
+ return self->name;
+}
+- (NSString *)title {
+ return self->title;
+}
+- (NSString *)link {
+ return self->link;
+}
+
+- (NSArray *)children {
+ return self->blocks;
+}
+
+- (BOOL)isPathNode {
+ return self->flags.isPath ? YES : NO;
+}
+- (BOOL)isActiveNode {
+ return self->flags.isActive ? YES : NO;
+}
+
+@end /* UIxMailTreeBlock */
# $Id$
-SUBMINOR_VERSION:=59
+SUBMINOR_VERSION:=60
# v0.9.50 requires NGMime v4.3.190
# v0.9.43 requires NGObjWeb v4.3.73