2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
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.
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
22 #import <Foundation/NSString.h>
24 #import <NGObjWeb/WOComponent.h>
25 #import <NGExtensions/NSObject+Logs.h>
26 #import <NGExtensions/NSNull+misc.h>
28 #import <SoObjects/Mailer/SOGoMailObject.h>
30 #import "UIxMailRenderingContext.h"
32 @implementation UIxMailRenderingContext
34 static BOOL showNamedTextAttachmentsInline = NO;
36 - (id) initWithViewer: (WOComponent *) _viewer
37 context: (WOContext *) _ctx
39 if ((self = [super init]))
50 return [self initWithViewer: nil context: nil];
55 [flatContents release];
59 [imageViewer release];
61 [messageViewer release];
67 [flatContents release];
71 [imageViewer release];
73 [messageViewer release];
86 - (NSDictionary *) flatContents
90 flatContents = [[viewer clientObject] fetchPlainTextParts];
91 [flatContents retain];
92 // [self debugWithFormat:@"CON: %@", flatContents];
98 - (NSData *) flatContentForPartPath: (NSArray *) _partPath
102 pid = _partPath ? [_partPath componentsJoinedByString:@"."] : @"";
104 return [[self flatContents] objectForKey:pid];
107 /* viewer components */
109 - (WOComponent *) mixedViewer
111 /* Note: we cannot cache the multipart viewers, because it can be nested */
112 return [viewer pageWithName: @"UIxMailPartMixedViewer"];
115 - (WOComponent *) signedViewer
117 /* Note: we cannot cache the multipart viewers, because it can be nested */
118 // TODO: temporary workaround (treat it like a plain mixed part)
120 return [self mixedViewer];
123 - (WOComponent *) alternativeViewer
125 /* Note: we cannot cache the multipart viewers, because it can be nested */
126 return [viewer pageWithName: @"UIxMailPartAlternativeViewer"];
129 - (WOComponent *) textViewer
133 textViewer = [viewer pageWithName: @"UIxMailPartTextViewer"];
140 - (WOComponent *) imageViewer
144 imageViewer = [viewer pageWithName: @"UIxMailPartImageViewer"];
145 [imageViewer retain];
151 - (WOComponent *) linkViewer
155 linkViewer = [viewer pageWithName: @"UIxMailPartLinkViewer"];
162 - (WOComponent *) htmlViewer
166 htmlViewer = [viewer pageWithName: @"UIxMailPartHTMLViewer"];
173 - (WOComponent *) messageViewer
177 messageViewer = [viewer pageWithName: @"UIxMailPartMessageViewer"];
178 [messageViewer retain];
181 return messageViewer;
184 - (WOComponent *) iCalViewer
188 iCalViewer = [viewer pageWithName: @"UIxMailPartICalViewer"];
197 - (WOComponent *) kolabContactViewer
199 return [viewer pageWithName: @"UIxKolabPartContactViewer"];
202 - (WOComponent *) kolabEventViewer
204 return [viewer pageWithName: @"UIxKolabPartEventViewer"];
207 - (WOComponent *) kolabTodoViewer
209 return [viewer pageWithName: @"UIxKolabPartTodoViewer"];
212 - (WOComponent *) kolabNoteViewer
214 return [self textViewer]; // TODO
217 - (WOComponent *) kolabJournalViewer
219 return [self textViewer]; // TODO
222 - (WOComponent *) kolabDistributionListViewer
224 return [self textViewer]; // TODO
227 /* main viewer selection */
229 - (WOComponent *) viewerForBodyInfo: (id) _info
233 mt = [[_info valueForKey:@"type"] lowercaseString];
234 st = [[_info valueForKey:@"subtype"] lowercaseString];
236 if ([mt isEqualToString:@"multipart"])
238 if ([st isEqualToString:@"mixed"])
239 return [self mixedViewer];
240 else if ([st isEqualToString:@"signed"])
241 return [self signedViewer];
242 else if ([st isEqualToString:@"alternative"]
243 || [st isEqualToString:@"related"])
244 return [self alternativeViewer];
246 if ([st isEqualToString:@"report"])
247 /* this is used by mail-delivery reports */
248 return [self mixedViewer];
250 else if ([mt isEqualToString:@"text"])
253 Note: in the _info dictionary we do not get the content-disposition
254 information (inline vs attachment). Our hack is to check for the
257 if ([st isEqualToString:@"plain"] || [st isEqualToString:@"html"]) {
258 if (!showNamedTextAttachmentsInline) {
261 n = [[_info objectForKey:@"parameterList"] objectForKey:@"name"];
262 if ([n isNotNull] && [n length] > 0)
263 return [self linkViewer];
266 return [st isEqualToString:@"html"]
267 ? [self htmlViewer] : [self textViewer];
270 if ([st isEqualToString:@"calendar"])
271 return [self iCalViewer];
274 if ([mt isEqualToString:@"image"])
275 return [self imageViewer];
277 if ([mt isEqualToString:@"message"] && [st isEqualToString:@"rfc822"])
278 return [self messageViewer];
280 if ([mt isEqualToString:@"message"] &&
281 [st isEqualToString:@"delivery-status"]) {
283 Content-Description: Delivery error report
284 Content-Type: message/delivery-status
286 Reporting-MTA: dns; mail.opengroupware.org
287 Arrival-Date: Mon, 18 Jul 2005 12:08:43 +0200 (CEST)
289 Final-Recipient: rfc822; ioioi@plop.com
292 Diagnostic-Code: X-Postfix; host plop.com[64.39.31.55] said: 550 5.7.1
293 <ioioi@plop.com>... Relaying denied
295 // Note: we cannot use the text viewer because the body is not pre-fetched
296 return [self linkViewer];
299 if ([mt isEqualToString:@"application"])
301 // octet-stream (generate download link?, autodetect type?)
303 if ([st hasPrefix:@"x-vnd.kolab."])
305 if ([st isEqualToString:@"x-vnd.kolab.contact"])
306 return [self kolabContactViewer];
307 if ([st isEqualToString:@"x-vnd.kolab.event"])
308 return [self kolabEventViewer];
309 if ([st isEqualToString:@"x-vnd.kolab.task"])
310 return [self kolabTodoViewer];
311 if ([st isEqualToString:@"x-vnd.kolab.note"])
312 return [self kolabNoteViewer];
313 if ([st isEqualToString:@"x-vnd.kolab.journal"])
314 return [self kolabJournalViewer];
315 if ([st isEqualToString:@"x-vnd.kolab.contact.distlist"])
316 return [self kolabDistributionListViewer];
318 [self errorWithFormat:@"found no viewer for Kolab type: %@/%@", mt, st];
319 return [self linkViewer];
322 #if 0 /* the link viewer looks better than plain text ;-) */
323 if ([st isEqualToString:@"pgp-signature"]) // TODO: real PGP viewer
324 return [self textViewer];
328 // TODO: always fallback to octet viewer?!
330 [self errorWithFormat:@"found no viewer for MIME type: %@/%@", mt, st];
333 return [self linkViewer];
338 - (BOOL)isDebuggingEnabled {
342 @end /* UIxMailRenderingContext */
345 @implementation WOContext(UIxMailPart)
347 static NSString *MRK = @"UIxMailRenderingContext";
349 - (void)pushMailRenderingContext:(UIxMailRenderingContext *)_mctx {
350 [self setObject:_mctx forKey:MRK];
352 - (UIxMailRenderingContext *)popMailRenderingContext {
353 UIxMailRenderingContext *mctx;
355 if ((mctx = [self objectForKey:MRK]) == nil)
358 mctx = [[mctx retain] autorelease];
359 [self removeObjectForKey:MRK];
362 - (UIxMailRenderingContext *)mailRenderingContext {
363 return [self objectForKey:MRK];
366 @end /* WOContext(UIxMailPart) */