]> err.no Git - scalable-opengroupware.org/blob - SOGo/UI/Mailer/UIxMailTree.m
changes to use NGLogging in all places
[scalable-opengroupware.org] / SOGo / UI / Mailer / UIxMailTree.m
1 /*
2   Copyright (C) 2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id: UIxMailTree.m 278 2004-08-26 23:29:09Z helge $
22
23 #include <SOGoUI/UIxComponent.h>
24
25 @interface UIxMailTree : UIxComponent
26 {
27   id rootNodes;
28   id item;
29 }
30 @end
31
32 #include "UIxMailTreeBlock.h"
33 #include <SOGo/SoObjects/Mailer/SOGoMailBaseObject.h>
34 #include "common.h"
35 #include <NGObjWeb/SoComponent.h>
36 #include <NGObjWeb/SoObject+SoDAV.h>
37
38
39 @implementation UIxMailTree
40
41 - (void)dealloc {
42   [self->rootNodes release];
43   [self->item      release];
44   [super dealloc];
45 }
46
47 /* accessors */
48
49 - (void)setItem:(id)_item {
50   ASSIGN(self->item, _item);
51 }
52 - (id)item {
53   return self->item;
54 }
55
56 /* navigation nodes */
57
58 - (BOOL)isRootObject:(id)_object {
59   if (![_object isNotNull]) {
60     [self warnWithFormat:@"(%s): got to root by nil lookup ...",
61             __PRETTY_FUNCTION__];
62     return YES;
63   }
64   
65   return [_object isKindOfClass:NSClassFromString(@"SOGoMailAccounts")];
66 }
67
68 - (NSString *)treeNavigationLinkForObject:(id)_object atDepth:(int)_depth {
69   NSString *link;
70   unsigned i;
71   
72   link = [[_object nameInContainer] stringByAppendingString:@"/"];
73   for (i = 0; i < _depth; i++)
74     link = [@"../" stringByAppendingString:link];
75   return link;
76 }
77
78 - (UIxMailTreeBlock *)treeNavigationBlockForLeafNode:(id)_o atDepth:(int)_d {
79   UIxMailTreeBlock *md;
80   id blocks;
81   
82   /* 
83      Trigger plus in treeview if it has subfolders. It is an optimization that
84      we do not generate blocks for folders which are not displayed anyway.
85   */
86   blocks = [[_o toManyRelationshipKeys] count] > 0
87     ? [[NSArray alloc] initWithObjects:@"FAKE", nil]
88     : nil;
89   
90   md = [UIxMailTreeBlock blockWithName:nil
91                          title:[_o davDisplayName]
92                          link:[self treeNavigationLinkForObject:_o atDepth:_d]
93                          isPathNode:NO isActiveNode:NO
94                          childBlocks:blocks];
95   return md;
96 }
97
98 - (UIxMailTreeBlock *)treeNavigationBlockForRootNode:(id)_object {
99   /* this generates the block for the clientObject */
100   UIxMailTreeBlock *md;
101   NSMutableArray      *blocks;
102   NSArray             *folders;
103   unsigned            i, count;
104   
105   /* process child folders */
106   
107   folders = [_object fetchSubfolders];
108   count   = [folders count];
109   blocks  = [NSMutableArray arrayWithCapacity:count];
110   for (i = 0; i < count; i++) {
111     id block;
112     
113     block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
114                   atDepth:0];
115     if ([block isNotNull]) [blocks addObject:block];
116   }
117   if ([blocks count] == 0)
118     blocks = nil;
119   
120   /* build block */
121   
122   md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
123                          title:[_object davDisplayName]
124                          link:[@"../" stringByAppendingString:
125                                   [_object nameInContainer]]
126                          isPathNode:YES isActiveNode:YES
127                          childBlocks:blocks];
128   return md;
129 }
130
131 - (UIxMailTreeBlock *)treeNavigationBlockForActiveNode:(id)_object {
132   /* 
133      this generates the block for the clientObject (the object which has the 
134      focus)
135   */
136   UIxMailTreeBlock *md;
137   NSMutableArray   *blocks;
138   NSArray  *folders;
139   unsigned i, count;
140   
141   // TODO: maybe we can join the two implementations, this might not be
142   //       necessary
143   if ([self isRootObject:_object]) /* we are at the top */
144     return [self treeNavigationBlockForRootNode:_object];
145   
146   /* process child folders */
147   
148   folders = [_object fetchSubfolders];
149   count   = [folders count];
150   blocks  = [NSMutableArray arrayWithCapacity:count];
151   for (i = 0; i < count; i++) {
152     UIxMailTreeBlock *block;
153     
154     block = [self treeNavigationBlockForLeafNode:[folders objectAtIndex:i]
155                   atDepth:0];
156     if ([block isNotNull]) [blocks addObject:block];
157   }
158   if ([blocks count] == 0) blocks = nil;
159   
160   /* build block */
161   
162   md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
163                          title:[_object davDisplayName]
164                          link:@"."
165                          isPathNode:YES isActiveNode:YES
166                          childBlocks:blocks];
167   return md;
168 }
169
170 - (UIxMailTreeBlock *)treeNavigationBlockForObject:(id)_object
171   withActiveChildBlock:(UIxMailTreeBlock *)_activeChildBlock 
172   depth:(int)_depth
173 {
174   UIxMailTreeBlock *md;
175   NSMutableArray   *blocks;
176   NSString         *activeName;
177   NSArray          *folders;
178   unsigned         i, count;
179   
180   if ([self isRootObject:_object]) /* we are at the top */
181     return _activeChildBlock;
182   
183   /* the following is not run on the OGoMailAccounts (root) object */
184   
185   activeName = [_activeChildBlock valueForKey:@"name"];
186   
187   /* process child folders */
188   
189   folders = [_object fetchSubfolders];
190   count   = [folders count];
191   blocks  = [NSMutableArray arrayWithCapacity:count];
192   for (i = 0; i < count; i++) {
193     UIxMailTreeBlock *block;
194     id folder;
195     
196     folder = [folders objectAtIndex:i];
197     block = [activeName isEqualToString:[folder nameInContainer]]
198       ? _activeChildBlock
199       : [self treeNavigationBlockForLeafNode:folder atDepth:_depth];
200     
201     if ([block isNotNull]) [blocks addObject:block];
202   }
203   if ([blocks count] == 0) blocks = nil;
204   
205   /* build block */
206   
207   md = [UIxMailTreeBlock blockWithName:[_object nameInContainer]
208                          title:[_object davDisplayName]
209                          link:[self treeNavigationLinkForObject:_object 
210                                     atDepth:(_depth + 1)] 
211                          isPathNode:YES isActiveNode:NO
212                          childBlocks:blocks];
213   
214   /* recurse up */
215   
216   return [self treeNavigationBlockForObject:[_object container] 
217                withActiveChildBlock:md
218                depth:(_depth + 1)];
219 }
220
221 - (id)buildNavigationNodesForObject:(id)_object {
222   id block;
223   
224   block = [self treeNavigationBlockForActiveNode:_object];
225   
226   if ([self isRootObject:_object])
227     return block;
228   
229   /* the following returns the root block! */
230   block = [self treeNavigationBlockForObject:[_object container] 
231                 withActiveChildBlock:block
232                 depth:1];
233   return block;
234 }
235
236 /* tree */
237
238 - (NSArray *)rootNodes {
239   id navNode;
240   
241   if (self->rootNodes != nil)
242     return self->rootNodes;
243   
244   navNode = [self buildNavigationNodesForObject:[self clientObject]];
245   self->rootNodes = [[NSArray alloc] initWithObjects:&navNode count:1];
246   return self->rootNodes;
247 }
248
249 /* notifications */
250
251 - (void)sleep {
252   [self->item      release]; self->item      = nil;
253   [self->rootNodes release]; self->rootNodes = nil;
254   [super sleep];
255 }
256
257 @end /* UIxMailTree */