]> err.no Git - scalable-opengroupware.org/blob - UI/MailPartViewers/UIxMailRenderingContext.m
Install libs to /usr/lib
[scalable-opengroupware.org] / UI / MailPartViewers / UIxMailRenderingContext.m
1 /*
2   Copyright (C) 2004-2005 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
22 #import <Foundation/NSString.h>
23
24 #import <NGObjWeb/WOComponent.h>
25 #import <NGExtensions/NSObject+Logs.h>
26 #import <NGExtensions/NSNull+misc.h>
27
28 #import <SoObjects/Mailer/SOGoMailObject.h>
29
30 #import "UIxMailRenderingContext.h"
31
32 @interface UIxMailRenderingContext (Private)
33
34 - (BOOL) _shouldDisplayAsAttachment: (NSDictionary *) info;
35
36 @end
37
38 @implementation UIxMailRenderingContext (Private)
39
40 - (BOOL) _shouldDisplayAsAttachment: (NSDictionary *) info
41 {
42   NSString *s;
43
44   s = [[info objectForKey:@"disposition"] objectForKey: @"type"];
45         
46   return (s && [s caseInsensitiveCompare: @"ATTACHMENT"] == NSOrderedSame);
47 }
48
49 @end
50
51 @implementation UIxMailRenderingContext
52
53 static BOOL showNamedTextAttachmentsInline = NO;
54
55 - (id) initWithViewer: (WOComponent *) _viewer
56               context: (WOContext *) _ctx
57 {
58   if ((self = [super init]))
59     {
60       viewer  = _viewer;
61       context = _ctx;
62     }
63
64   return self;
65 }
66
67 - (id) init
68 {
69   return [self initWithViewer: nil context: nil];
70 }
71
72 - (void) dealloc
73 {
74   [flatContents release];
75   [super dealloc];
76 }
77
78 - (void) reset
79 {
80   [flatContents release];
81   flatContents = nil;
82 }
83
84 /* fetching */
85
86 - (NSDictionary *) flatContents
87 {
88   if (!flatContents)
89     {
90       flatContents = [[viewer clientObject] fetchPlainTextParts];
91       [flatContents retain];
92 //       [self debugWithFormat:@"CON: %@", flatContents];
93     }
94
95   return flatContents;
96 }
97
98 - (NSData *) flatContentForPartPath: (NSArray *) _partPath
99 {
100   NSString *pid;
101   NSData *content;
102
103   pid = _partPath ? [_partPath componentsJoinedByString: @"."] : @"";
104   content = [[self flatContents] objectForKey: pid];
105   if (!content && ![pid intValue])
106     content = [flatContents objectForKey: @""];
107
108   return content;
109 }
110
111 /* viewer components */
112
113 - (WOComponent *) mixedViewer
114 {
115   /* Note: we cannot cache the multipart viewers, because it can be nested */
116   return [viewer pageWithName: @"UIxMailPartMixedViewer"];
117 }
118
119 - (WOComponent *) signedViewer
120 {
121   /* Note: we cannot cache the multipart viewers, because it can be nested */
122   // TODO: temporary workaround (treat it like a plain mixed part)
123
124   return [self mixedViewer];
125 }
126
127 - (WOComponent *) alternativeViewer
128 {
129   /* Note: we cannot cache the multipart viewers, because it can be nested */
130   return [viewer pageWithName: @"UIxMailPartAlternativeViewer"];
131 }
132
133 - (WOComponent *) textViewer
134 {
135   return [viewer pageWithName: @"UIxMailPartTextViewer"];
136 }
137
138 - (WOComponent *) imageViewer
139 {
140   return [viewer pageWithName: @"UIxMailPartImageViewer"];
141 }
142
143 - (WOComponent *) linkViewer
144 {
145   return [viewer pageWithName: @"UIxMailPartLinkViewer"];
146 }
147
148 - (WOComponent *) htmlViewer
149 {
150   return [viewer pageWithName: @"UIxMailPartHTMLViewer"];
151 }
152
153 - (WOComponent *) messageViewer
154 {
155   return [viewer pageWithName: @"UIxMailPartMessageViewer"];
156 }
157
158 - (WOComponent *) iCalViewer
159 {
160   return [viewer pageWithName: @"UIxMailPartICalViewer"];
161 }
162
163 /* Kolab viewers */
164
165 - (WOComponent *) kolabContactViewer
166 {
167   return [viewer pageWithName: @"UIxKolabPartContactViewer"];
168 }
169
170 - (WOComponent *) kolabEventViewer
171 {
172   return [viewer pageWithName: @"UIxKolabPartEventViewer"];
173 }
174
175 - (WOComponent *) kolabTodoViewer
176 {
177   return [viewer pageWithName: @"UIxKolabPartTodoViewer"];
178 }
179
180 - (WOComponent *) kolabNoteViewer
181 {
182   return [self textViewer]; // TODO
183 }
184
185 - (WOComponent *) kolabJournalViewer
186 {
187   return [self textViewer]; // TODO
188 }
189
190 - (WOComponent *) kolabDistributionListViewer
191 {
192   return [self textViewer]; // TODO
193 }
194
195 /* main viewer selection */
196
197 - (WOComponent *) viewerForBodyInfo: (id) _info
198 {
199   NSString *mt, *st;
200
201   mt = [[_info valueForKey:@"type"] lowercaseString];
202   st = [[_info valueForKey:@"subtype"] lowercaseString];
203
204   if ([mt isEqualToString:@"multipart"])
205     {
206       if ([st isEqualToString:@"mixed"] || [st isEqualToString:@"related"] || [st isEqualToString: @"appledouble"])
207         return [self mixedViewer];
208       else if ([st isEqualToString:@"signed"])
209         return [self signedViewer];
210       else if ([st isEqualToString:@"alternative"])
211         return [self alternativeViewer];
212     
213       if ([st isEqualToString:@"report"])
214         /* this is used by mail-delivery reports */
215         return [self mixedViewer];
216     }
217   else if ([mt isEqualToString:@"text"])
218     {
219       if ([st isEqualToString:@"plain"] || [st isEqualToString:@"html"]) {
220         if (!showNamedTextAttachmentsInline && [self _shouldDisplayAsAttachment: _info])
221           return [self linkViewer];
222       
223         return [st isEqualToString:@"html"] 
224           ? [self htmlViewer] : [self textViewer];
225       }
226     
227       if ([st isEqualToString:@"calendar"])
228         return [self iCalViewer];
229     }
230   
231   if ([mt isEqualToString:@"image"])
232     {
233       if ([self _shouldDisplayAsAttachment: _info])
234         return [self linkViewer];
235      
236       return [self imageViewer];
237     }
238   
239   if ([mt isEqualToString:@"message"] && [st isEqualToString:@"rfc822"])
240     return [self messageViewer];
241   
242   if ([mt isEqualToString:@"message"] && 
243       [st isEqualToString:@"delivery-status"]) {
244     /*
245       Content-Description: Delivery error report
246       Content-Type: message/delivery-status
247       
248       Reporting-MTA: dns; mail.opengroupware.org
249       Arrival-Date: Mon, 18 Jul 2005 12:08:43 +0200 (CEST)
250       
251       Final-Recipient: rfc822; ioioi@plop.com
252       Action: failed
253       Status: 5.0.0
254       Diagnostic-Code: X-Postfix; host plop.com[64.39.31.55] said: 550 5.7.1
255       <ioioi@plop.com>... Relaying denied
256     */
257     // Note: we cannot use the text viewer because the body is not pre-fetched
258     return [self linkViewer];
259   }
260
261   if ([mt isEqualToString:@"application"])
262     {
263       // octet-stream (generate download link?, autodetect type?)
264     
265       if ([st hasPrefix:@"x-vnd.kolab."])
266         {
267           if ([st isEqualToString:@"x-vnd.kolab.contact"])
268             return [self kolabContactViewer];
269           if ([st isEqualToString:@"x-vnd.kolab.event"])
270             return [self kolabEventViewer];
271           if ([st isEqualToString:@"x-vnd.kolab.task"])
272             return [self kolabTodoViewer];
273           if ([st isEqualToString:@"x-vnd.kolab.note"])
274             return [self kolabNoteViewer];
275           if ([st isEqualToString:@"x-vnd.kolab.journal"])
276             return [self kolabJournalViewer];
277           if ([st isEqualToString:@"x-vnd.kolab.contact.distlist"])
278             return [self kolabDistributionListViewer];
279       
280           [self errorWithFormat:@"found no viewer for Kolab type: %@/%@", mt, st];
281           return [self linkViewer];
282         }
283       else if ([st isEqualToString:@"ics"]) /* Cooqle K4lendahr - Google Calendar */
284         return [self iCalViewer];
285
286 #if 0 /* the link viewer looks better than plain text ;-) */
287       if ([st isEqualToString:@"pgp-signature"]) // TODO: real PGP viewer
288         return [self textViewer];
289 #endif
290     }
291
292   // TODO: always fallback to octet viewer?!
293 #if 1
294   [self errorWithFormat:@"found no viewer for MIME type: %@/%@", mt, st];
295 #endif
296
297   return [self linkViewer];
298 }
299
300 /* debugging */
301
302 - (BOOL)isDebuggingEnabled {
303   return NO;
304 }
305
306 @end /* UIxMailRenderingContext */
307
308
309 @implementation WOContext(UIxMailPart)
310
311 static NSString *MRK = @"UIxMailRenderingContext";
312
313 - (void)pushMailRenderingContext:(UIxMailRenderingContext *)_mctx {
314   [self setObject:_mctx forKey:MRK];
315 }
316 - (UIxMailRenderingContext *)popMailRenderingContext {
317   UIxMailRenderingContext *mctx;
318   
319   if ((mctx = [self objectForKey:MRK]) == nil)
320     return nil;
321   
322   mctx = [[mctx retain] autorelease];
323   [self removeObjectForKey:MRK];
324   return mctx;
325 }
326 - (UIxMailRenderingContext *)mailRenderingContext {
327   return [self objectForKey:MRK];
328 }
329
330 @end /* WOContext(UIxMailPart) */
331