mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-30 09:19:28 +00:00
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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user