]> err.no Git - scalable-opengroupware.org/blob - SOGo/SoObjects/Mailer/SOGoMailBaseObject.m
implement folder tree navigation
[scalable-opengroupware.org] / SOGo / SoObjects / Mailer / SOGoMailBaseObject.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$
22
23 #include "SOGoMailBaseObject.h"
24 #include "SOGoMailManager.h"
25 #include "common.h"
26 #include <WebDAV/SoObject+SoDAV.h>
27 #include <NGExtensions/NSURL+misc.h>
28
29 @implementation SOGoMailBaseObject
30
31 - (id)initWithImap4URL:(NSURL *)_url inContainer:(id)_container {
32   NSString *n;
33   
34   n = [[_url path] lastPathComponent];
35   if ((self = [self initWithName:n inContainer:_container])) {
36     self->imap4URL = [_url retain];
37   }
38   return self;
39 }
40
41 - (void)dealloc {
42   [self->imap4URL release];
43   [super dealloc];
44 }
45
46 /* hierarchy */
47
48 - (SOGoMailAccount *)mailAccountFolder {
49   if (![[self container] respondsToSelector:_cmd]) {
50     [self logWithFormat:@"WARNING: weird container of mailfolder: %@",
51             [self container]];
52     return nil;
53   }
54   
55   return [[self container] mailAccountFolder];
56 }
57
58 - (NSArray *)fetchSubfolders {
59   NSMutableArray *ma;
60   NSArray  *names;
61   unsigned i, count;
62   
63   if ((names = [self toManyRelationshipKeys]) == nil)
64     return nil;
65   
66   count = [names count];
67   ma    = [NSMutableArray arrayWithCapacity:count + 1];
68   for (i = 0; i < count; i++) {
69     id folder;
70     
71     folder = [self lookupName:[names objectAtIndex:i] inContext:nil 
72                    acquire:NO];
73     if (folder == nil)
74       continue;
75     if ([folder isKindOfClass:[NSException class]])
76       continue;
77     
78     [ma addObject:folder];
79   }
80   return ma;
81 }
82
83 /* IMAP4 */
84
85 - (SOGoMailManager *)mailManager {
86   return [SOGoMailManager defaultMailManager];
87 }
88
89 - (NSString *)relativeImap4Name {
90   [self logWithFormat:@"WARNING: subclass should override %@", 
91           NSStringFromSelector(_cmd)];
92   return nil;
93 }
94 - (NSURL *)baseImap4URL {
95   if (![[self container] respondsToSelector:@selector(imap4URL)]) {
96     [self logWithFormat:@"WARNING: container does not implement -imap4URL!"];
97     return nil;
98   }
99   
100   return [[self container] imap4URL];
101 }
102 - (NSURL *)imap4URL {
103   NSString *sn;
104   NSURL    *base;
105   
106   if (self->imap4URL != nil) 
107     return self->imap4URL;
108   
109   if ((sn = [self relativeImap4Name]) == nil)
110     return nil;
111   
112   if (![[self container] respondsToSelector:_cmd]) {
113     [self logWithFormat:@"WARNING: container does not implement -imap4URL!"];
114     return nil;
115   }
116   
117   if ((base = [self baseImap4URL]) == nil)
118     return nil;
119   
120   sn = [[base path] stringByAppendingPathComponent:sn];
121   self->imap4URL = [[NSURL alloc] initWithString:sn relativeToURL:base];
122   return self->imap4URL;
123 }
124
125 - (NSString *)imap4FolderName {
126   return [[self mailManager] imap4FolderNameForURL:[self imap4URL]];
127 }
128
129 - (NSString *)imap4Password {
130   return [[NSUserDefaults standardUserDefaults] stringForKey:@"hackpwd"];
131 }
132
133 - (NGImap4Client *)imap4ClientForURL:(NSURL *)_url password:(NSString *)_pwd {
134   return [[self mailManager] imap4ClientForURL:_url password:_pwd];
135 }
136
137 - (NGImap4Client *)imap4Client {
138   return [self imap4ClientForURL:[self imap4URL]
139                password:[self imap4Password]];
140 }
141
142 /* UI navigation */
143
144 - (NSString *)treeNavigationLinkAtDepth:(int)_depth {
145   NSString *link;
146   unsigned i;
147   
148   link = [[self nameInContainer] stringByAppendingString:@"/"];
149   for (i = 0; i < _depth; i++)
150     link = [@"../" stringByAppendingString:link];
151   return link;
152 }
153
154 - (id)treeNavigationBlockForLeafNodeAtDepth:(int)_depth {
155   NSMutableDictionary *md;
156   
157   md = [NSMutableDictionary dictionaryWithCapacity:4];
158   [md setObject:[self davDisplayName]                   forKey:@"title"];
159   [md setObject:[self treeNavigationLinkAtDepth:_depth] forKey:@"link"];
160   
161   if ([[self toManyRelationshipKeys] count] > 0)
162     /* trigger plus in treeview */
163     [md setObject:[NSArray arrayWithObject:@"FAKE"] forKey:@"children"];
164   return md;
165 }
166
167 - (id)treeNavigationBlockForActiveNode {
168   /* this generates the block for the clientObject */
169   NSMutableDictionary *md;
170   NSMutableArray *blocks;
171   NSArray  *folders;
172   unsigned i, count;
173   
174   /* process child folders */
175   
176   folders = [self fetchSubfolders];
177   count   = [folders count];
178   blocks  = [NSMutableArray arrayWithCapacity:count];
179   for (i = 0; i < count; i++) {
180     id block;
181     
182     block = [[folders objectAtIndex:i] 
183                       treeNavigationBlockForLeafNodeAtDepth:0];
184     if ([block isNotNull]) [blocks addObject:block];
185   }
186   
187   /* build block */
188   
189   md = [NSMutableDictionary dictionaryWithCapacity:4];
190   [md setObject:[NSNumber numberWithBool:YES] forKey:@"isActiveNode"];
191   [md setObject:[NSNumber numberWithBool:YES] forKey:@"isPathNode"];
192   [md setObject:[self davDisplayName]         forKey:@"title"];
193   [md setObject:[self nameInContainer]        forKey:@"name"];
194   [md setObject:@"."                          forKey:@"link"];
195   if ([blocks count] > 0)
196     [md setObject:blocks forKey:@"children"];
197   return md;
198 }
199
200 - (id)treeNavigationBlockWithActiveChildBlock:(id)_activeChildBlock 
201   depth:(int)_depth
202 {
203   NSMutableDictionary *md;
204   NSMutableArray *blocks;
205   NSString *activeName;
206   NSArray  *folders;
207   unsigned i, count;
208   
209   activeName = [_activeChildBlock valueForKey:@"name"];
210   
211   /* process child folders */
212   
213   folders = [self fetchSubfolders];
214   count   = [folders count];
215   blocks  = [NSMutableArray arrayWithCapacity:count];
216   for (i = 0; i < count; i++) {
217     id folder;
218     id block;
219     
220     folder = [folders objectAtIndex:i];
221     if ([activeName isEqualToString:[folder nameInContainer]]) {
222       block = _activeChildBlock;
223     }
224     else {
225       block = [folder treeNavigationBlockForLeafNodeAtDepth:_depth];
226     }
227     if ([block isNotNull]) [blocks addObject:block];
228   }
229
230   /* build block */
231   
232   md = [NSMutableDictionary dictionaryWithCapacity:4];
233   [md setObject:[self davDisplayName]         forKey:@"title"];
234   [md setObject:[self nameInContainer]        forKey:@"name"];
235   [md setObject:[NSNumber numberWithBool:YES] forKey:@"isPathNode"];
236   [md setObject:[self treeNavigationLinkAtDepth:(_depth + 1)] forKey:@"link"];
237   if ([blocks count] > 0)
238     [md setObject:blocks forKey:@"children"];
239   
240   /* recurse up */
241   
242   return [[self container] treeNavigationBlockWithActiveChildBlock:md
243                            depth:(_depth + 1)];
244 }
245
246 - (id)treeNavigationNodes {
247   return [[self container] treeNavigationBlockWithActiveChildBlock:
248                              [self treeNavigationBlockForActiveNode]
249                            depth:1];
250 }
251
252 @end /* SOGoMailBaseObject */