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