Monotone-Parent: 8566d6fbfa896a774b9907c3125e7b3de87296cd

Monotone-Revision: 2ad8b0c019808014c990f51cc69c4457fdb537c6

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2006-07-28T22:59:11
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2006-07-28 22:59:11 +00:00
parent bef8dad238
commit 39228fb130
73 changed files with 4023 additions and 1628 deletions

View File

@@ -19,23 +19,16 @@
02111-1307, USA.
*/
#include <SOGoUI/UIxComponent.h>
#import "common.h"
@interface UIxMailTree : UIxComponent
{
NSString *rootClassName;
NSString *treeFolderAction;
id rootNodes;
id item;
}
@end
#import <SoObjects/Mailer/SOGoMailBaseObject.h>
#import <SoObjects/Mailer/SOGoMailAccount.h>
#import <SoObjects/Mailer/SOGoMailFolder.h>
#import <NGObjWeb/SoComponent.h>
#import <NGObjWeb/SoObject+SoDAV.h>
#include "UIxMailTreeBlock.h"
#include <SoObjects/Mailer/SOGoMailBaseObject.h>
#include <SoObjects/Mailer/SOGoMailAccount.h>
#include "common.h"
#include <NGObjWeb/SoComponent.h>
#include <NGObjWeb/SoObject+SoDAV.h>
#import "UIxMailTree.h"
#import "UIxMailTreeBlock.h"
/*
Support special icons:
@@ -58,21 +51,34 @@
static BOOL debugBlocks = NO;
+ (void)initialize {
+ (void)initialize
{
[UIxMailTreeBlock class]; // ensure that globals are initialized
}
- (void)dealloc {
- (id) init
{
if ((self = [super init]))
{
flattenedNodes = [NSMutableDictionary new];
}
return self;
}
- (void) dealloc
{
[self->treeFolderAction release];
[self->rootClassName release];
[self->rootNodes release];
[self->item release];
[flattenedNodes release];
[super dealloc];
}
/* icons */
- (NSString *)defaultIconName {
- (NSString *) defaultIconName
{
return @"tbtv_leaf_corner_17x17.gif";
}
@@ -133,7 +139,7 @@ static BOOL debugBlocks = NO;
[self logWithFormat:@"to-many: %@ %@", _object,
[names componentsJoinedByString:@","]];
}
count = [names count];
ma = [NSMutableArray arrayWithCapacity:(count + 1)];
for (i = 0; i < count; i++) {
@@ -180,40 +186,48 @@ static BOOL debugBlocks = NO;
return [_object isKindOfClass:NSClassFromString([self rootClassName])];
}
- (NSString *)treeNavigationLinkForObject:(id)_object atDepth:(int)_depth {
NSString *link;
unsigned i;
link = [[_object nameInContainer] stringByAppendingString:@"/"];
link = [link stringByAppendingString:[self treeFolderAction]];
switch (_depth) {
case 0: return link;
case 1: return [@"../" stringByAppendingString:link];
case 2: return [@"../../" stringByAppendingString:link];
case 3: return [@"../../../" stringByAppendingString:link];
}
- (NSString *)treeNavigationLinkForObject:(id)_object
atDepth:(int)_depth
{
NSMutableString *link;
int i;
link = [NSMutableString new];
[link autorelease];
for (i = 0; i < _depth; i++)
link = [@"../" stringByAppendingString:link];
[link appendString: @"../"];
[link appendFormat: @"%@/%@",
[_object nameInContainer],
[self treeFolderAction]];
return link;
}
- (void)getTitle:(NSString **)_t andIcon:(NSString **)_icon
forObject:(id)_object
- (void) getTitle: (NSString **)_t
folderType: (NSString **)_ft
andIcon: (NSString **)_icon
forObject: (id)_object
{
// TODO: need to refactor for reuse!
NSString *ftype;
unsigned len;
// if ([_object respondsToSelector: @selector (outlookFolderClass)])
// ftype = [_object outlookFolderClass];
// else
ftype = [_object valueForKey:@"outlookFolderClass"];
len = [ftype length];
ftype = [_object valueForKey:@"outlookFolderClass"];
len = [ftype length];
*_ft = nil;
switch (len) {
case 8:
if ([ftype isEqualToString:@"IPF.Sent"]) {
*_t = [self labelForKey:@"SentFolderName"];
*_icon = @"tbtv_sent_17x17.gif";
*_ft = @"sent";
return;
}
break;
@@ -221,11 +235,13 @@ static BOOL debugBlocks = NO;
if ([ftype isEqualToString:@"IPF.Inbox"]) {
*_t = [self labelForKey:@"InboxFolderName"];
*_icon = @"tbtv_inbox_17x17.gif";
*_ft = @"inbox";
return;
}
if ([ftype isEqualToString:@"IPF.Trash"]) {
*_t = [self labelForKey:@"TrashFolderName"];
*_icon = @"tbtv_trash_17x17.gif";
*_ft = @"trash";
return;
}
break;
@@ -233,11 +249,13 @@ static BOOL debugBlocks = NO;
if ([ftype isEqualToString:@"IPF.Drafts"]) {
*_t = [self labelForKey:@"DraftsFolderName"];
*_icon = @"tbtv_drafts_17x17.gif";
*_ft = @"drafts";
return;
}
if ([ftype isEqualToString:@"IPF.Filter"]) {
*_t = [self labelForKey:@"SieveFolderName"];
*_icon = nil;
*_ft = @"sieve";
return;
}
break;
@@ -249,32 +267,30 @@ static BOOL debugBlocks = NO;
if ([_object isKindOfClass:NSClassFromString(@"SOGoMailFolder")])
*_icon = nil;
else if ([_object isKindOfClass:NSClassFromString(@"SOGoMailAccount")]) {
*_icon = @"tbtv_inbox_17x17.gif";
*_icon = @"tbtv_account_17x17.gif";
*_ft = @"account";
/* title processing is somehow Agenor specific and should be done in UI */
*_t = [[_object nameInContainer] titleForSOGoIMAP4String];
}
else if ([_object isKindOfClass:NSClassFromString(@"SOGoMailAccounts")])
*_icon = @"tbtv_inbox_17x17.gif";
*_icon = @"tbtv_account_17x17.gif";
else if ([_object isKindOfClass:NSClassFromString(@"SOGoUserFolder")])
*_icon = @"tbtv_inbox_17x17.gif";
else {
// TODO: use drafts icon for other SOGo folders
*_icon = @"tbtv_drafts_17x17.gif";
}
NSLog (@"title: '%@', ftype: '%@', class: '%@', icon: '%@'",
*_t,
ftype, NSStringFromClass([_object class]), *_icon);
return;
}
- (UIxMailTreeBlock *)treeNavigationBlockForLeafNode:(id)_o atDepth:(int)_d {
- (UIxMailTreeBlock *) treeNavigationBlockForLeafNode: (id) _o
atDepth: (int) _d
{
UIxMailTreeBlock *md;
NSString *n, *i;
NSString *n, *i, *ft;
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.
@@ -282,14 +298,16 @@ static BOOL debugBlocks = NO;
blocks = [[_o toManyRelationshipKeys] count] > 0
? UIxMailTreeHasChildrenMarker
: nil;
[self getTitle:&n andIcon:&i forObject:_o];
md = [UIxMailTreeBlock blockWithName:nil
title:n iconName:i
link:[self treeNavigationLinkForObject:_o atDepth:_d]
isPathNode:NO isActiveNode:NO
childBlocks:blocks];
[self getTitle: &n folderType: &ft andIcon: &i forObject:_o];
md = [UIxMailTreeBlock blockWithName: nil
title: n
iconName: i
link: [self treeNavigationLinkForObject:_o atDepth:_d]
isPathNode:NO
isActiveNode:NO
childBlocks: blocks];
return md;
}
@@ -301,7 +319,7 @@ static BOOL debugBlocks = NO;
UIxMailTreeBlock *md;
NSMutableArray *blocks;
NSArray *folders;
NSString *title, *icon;
NSString *title, *icon, *ft;
unsigned i, count;
if (debugBlocks) {
@@ -317,7 +335,7 @@ static BOOL debugBlocks = NO;
for (i = 0; i < count; i++) {
id block;
block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
block = [self treeNavigationBlockForLeafNode: [folders objectAtIndex:i]
atDepth:0];
if ([block isNotNull]) [blocks addObject:block];
}
@@ -326,18 +344,63 @@ static BOOL debugBlocks = NO;
/* build block */
[self getTitle:&title andIcon:&icon forObject:_object];
[self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
title:title iconName:icon
link:[@"../" stringByAppendingString:
[_object nameInContainer]]
isPathNode:YES isActiveNode:YES
childBlocks:blocks];
md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
title: title
iconName: icon
link: [@"../" stringByAppendingString:
[_object nameInContainer]]
isPathNode: YES
isActiveNode: YES
childBlocks: blocks];
return md;
}
- (UIxMailTreeBlock *)treeNavigationBlockForActiveNode:(id)_object {
- (UIxMailTreeBlock *) fullTreeNavigationBlockForNode: (id)_object
{
UIxMailTreeBlock *md;
NSMutableArray *blocks;
NSArray *folders;
NSString *title, *icon, *ft;
unsigned i, count;
if (debugBlocks)
[self logWithFormat:@"block for root node 0x%08X<%@>",
_object, NSStringFromClass([_object class])];
folders = [self fetchSubfoldersOfObject: _object];
count = [folders count];
blocks = [NSMutableArray arrayWithCapacity: count];
for (i = 0; i < count; i++)
{
id block;
block = [self fullTreeNavigationBlockForNode: [folders objectAtIndex:i]];
if ([block isNotNull]) [blocks addObject:block];
}
if (![blocks count])
blocks = nil;
[self getTitle: &title folderType: &ft andIcon: &icon forObject: _object];
// NSLog (@"*********** title = '%@'/icon = '%@'", title, icon);
md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
title: title
iconName: icon
link: [@"../" stringByAppendingString:
[_object nameInContainer]]
isPathNode: YES
isActiveNode: YES
childBlocks: blocks];
[md setFolderType: ft];
return md;
}
- (UIxMailTreeBlock *) treeNavigationBlockForActiveNode: (id) _object
{
/*
This generates the block for the clientObject (the object which has the
focus)
@@ -345,7 +408,7 @@ static BOOL debugBlocks = NO;
UIxMailTreeBlock *md;
NSMutableArray *blocks;
NSArray *folders;
NSString *title, *icon;
NSString *title, *icon, *ft;
unsigned i, count;
// TODO: maybe we can join the two implementations, this might not be
@@ -367,26 +430,29 @@ static BOOL debugBlocks = NO;
for (i = 0; i < count; i++) {
UIxMailTreeBlock *block;
block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
atDepth:0];
block = [self treeNavigationBlockForLeafNode: [folders objectAtIndex:i]
atDepth: 0];
if ([block isNotNull]) [blocks addObject:block];
}
if ([blocks count] == 0) blocks = nil;
/* build block */
[self getTitle:&title andIcon:&icon forObject:_object];
md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
title:title iconName:icon
link:@"."
isPathNode:YES isActiveNode:YES
childBlocks:blocks];
[self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
md = [UIxMailTreeBlock blockWithName: [_object nameInContainer]
title: title
iconName: icon
link: @"."
isPathNode: YES
isActiveNode: YES
childBlocks: blocks];
return md;
}
- (UIxMailTreeBlock *)treeNavigationBlockForObject:(id)_object
withActiveChildBlock:(UIxMailTreeBlock *)_activeChildBlock
depth:(int)_depth
- (UIxMailTreeBlock *)
treeNavigationBlockForObject: (id) _object
withActiveChildBlock: (UIxMailTreeBlock *) _activeChildBlock
depth: (int) _depth
{
/*
Note: 'activeChildBlock' here doesn't mean that the block is the selected
@@ -397,7 +463,7 @@ static BOOL debugBlocks = NO;
NSMutableArray *blocks;
NSString *activeName;
NSArray *folders;
NSString *title, *icon;
NSString *title, *icon, *ft;
unsigned i, count;
activeName = [_activeChildBlock valueForKey:@"name"];
@@ -411,11 +477,11 @@ static BOOL debugBlocks = NO;
UIxMailTreeBlock *block;
id folder;
NSLog(@"activeName: %@", activeName);
folder = [folders objectAtIndex:i];
block = [activeName isEqualToString:[folder nameInContainer]]
? _activeChildBlock
: [self treeNavigationBlockForLeafNode:folder atDepth:_depth];
: [self treeNavigationBlockForLeafNode: folder
atDepth:_depth];
if ([block isNotNull]) [blocks addObject:block];
}
@@ -425,17 +491,19 @@ static BOOL debugBlocks = NO;
else
blocks = nil;
}
/* build block */
[self getTitle:&title andIcon:&icon forObject:_object];
resultBlock = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
title:title iconName:icon
link:
[self treeNavigationLinkForObject:_object
atDepth:(_depth + 1)]
isPathNode:YES isActiveNode:NO
childBlocks:blocks];
[self getTitle:&title folderType: &ft andIcon:&icon forObject:_object];
resultBlock
= [UIxMailTreeBlock blockWithName: [_object nameInContainer]
title: title
iconName: icon
link:
[self treeNavigationLinkForObject: _object
atDepth: (_depth + 1)]
isPathNode:YES isActiveNode:NO
childBlocks:blocks];
/* recurse up unless we are at the root */
@@ -478,7 +546,7 @@ static BOOL debugBlocks = NO;
if (debugBlocks) [self logWithFormat:@"ACTIVE parent block ..."];
block = [self treeNavigationBlockForObject:[_object container]
withActiveChildBlock:block
depth:1];
depth: 1];
if (debugBlocks) [self logWithFormat:@"done: %@", block];
return block;
}
@@ -501,6 +569,78 @@ static BOOL debugBlocks = NO;
return self->rootNodes;
}
- (int) addNodes: (NSArray *) nodes
atSerial: (int) startSerial
forParent: (int) parent
withRootName: (NSString *) rootName
toArray: (NSMutableArray *) array
{
unsigned int count, max, currentSerial;
UIxMailTreeBlock *curNode;
NSArray *children;
NSString *fullName;
max = [nodes count];
currentSerial = startSerial;
for (count = 0; count < max; count++)
{
curNode = [nodes objectAtIndex: count];
fullName = [rootName stringByAppendingFormat: @"/%@", [curNode name]];
[curNode setName: fullName];
[curNode setSerial: currentSerial];
[curNode setParent: parent];
[array addObject: curNode];
if ([curNode hasChildren])
currentSerial = [self addNodes: [curNode children]
atSerial: currentSerial + 1
forParent: currentSerial
withRootName: fullName
toArray: array];
else
currentSerial++;
}
return currentSerial;
}
- (NSArray *) flattenedNodes
{
NSMutableArray *flattenedBlocks = nil;
NSString *userKey;
UIxMailTreeBlock *rootNode; // , *curNode;
id mailAccounts;
// unsigned int count, max;
userKey = [[self user] login];
flattenedBlocks = [flattenedNodes objectForKey: userKey];
if (!flattenedBlocks)
{
flattenedBlocks = [NSMutableArray new];
if (![[self clientObject] isKindOfClass: NSClassFromString(@"SOGoMailAccounts")])
mailAccounts = [[self clientObject] mailAccountsFolder];
else
mailAccounts = [self clientObject];
rootNode = [self fullTreeNavigationBlockForNode: mailAccounts];
[self addNodes: [rootNode children]
atSerial: 1
forParent: 0
withRootName: @""
toArray: flattenedBlocks];
[flattenedNodes setObject: flattenedBlocks forKey: userKey];
// max = [flattenedBlocks count];
// for (count = 0; count < max; count++)
// {
// curNode = [flattenedBlocks objectAtIndex: count];
// NSLog (@"%d: %@/%@", count, [curNode title], [curNode iconName]);
// }
}
return flattenedBlocks;
}
/* notifications */
- (void)sleep {