]> err.no Git - scalable-opengroupware.org/blob - UI/MailPartViewers/UIxMailRenderingContext.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1036 d1b88da0-ebda-0310...
[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     else if ([st isEqualToString:@"signed"])
182       return [self signedViewer];
183     else if ([st isEqualToString:@"alternative"]
184              || [st isEqualToString:@"related"])
185       return [self alternativeViewer];
186     
187     if ([st isEqualToString:@"report"])
188       /* this is used by mail-delivery reports */
189       return [self mixedViewer];
190   }
191   else if ([mt isEqualToString:@"text"]) {
192     /* 
193        Note: in the _info dictionary we do not get the content-disposition
194              information (inline vs attachment). Our hack is to check for the
195              'name' parameter.
196     */
197     if ([st isEqualToString:@"plain"] || [st isEqualToString:@"html"]) {
198       if (!showNamedTextAttachmentsInline) {
199         NSString *n;
200         
201         n = [[_info objectForKey:@"parameterList"] objectForKey:@"name"];
202         if ([n isNotNull] && [n length] > 0)
203           return [self linkViewer];
204       }
205       
206       return [st isEqualToString:@"html"] 
207         ? [self htmlViewer] : [self textViewer];
208     }
209     
210     if ([st isEqualToString:@"calendar"])
211       return [self iCalViewer];
212   }
213   
214   if ([mt isEqualToString:@"image"])
215     return [self imageViewer];
216   
217   if ([mt isEqualToString:@"message"] && [st isEqualToString:@"rfc822"])
218     return [self messageViewer];
219   
220   if ([mt isEqualToString:@"message"] && 
221       [st isEqualToString:@"delivery-status"]) {
222     /*
223       Content-Description: Delivery error report
224       Content-Type: message/delivery-status
225       
226       Reporting-MTA: dns; mail.opengroupware.org
227       Arrival-Date: Mon, 18 Jul 2005 12:08:43 +0200 (CEST)
228       
229       Final-Recipient: rfc822; ioioi@plop.com
230       Action: failed
231       Status: 5.0.0
232       Diagnostic-Code: X-Postfix; host plop.com[64.39.31.55] said: 550 5.7.1
233           <ioioi@plop.com>... Relaying denied
234     */
235     // Note: we cannot use the text viewer because the body is not pre-fetched
236     return [self linkViewer];
237   }
238
239   if ([mt isEqualToString:@"application"]) {
240     // octet-stream (generate download link?, autodetect type?)
241     
242     if ([st hasPrefix:@"x-vnd.kolab."]) {
243       if ([st isEqualToString:@"x-vnd.kolab.contact"])
244         return [self kolabContactViewer];
245       if ([st isEqualToString:@"x-vnd.kolab.event"])
246         return [self kolabEventViewer];
247       if ([st isEqualToString:@"x-vnd.kolab.task"])
248         return [self kolabTodoViewer];
249       if ([st isEqualToString:@"x-vnd.kolab.note"])
250         return [self kolabNoteViewer];
251       if ([st isEqualToString:@"x-vnd.kolab.journal"])
252         return [self kolabJournalViewer];
253       if ([st isEqualToString:@"x-vnd.kolab.contact.distlist"])
254         return [self kolabDistributionListViewer];
255       
256       [self errorWithFormat:@"found no viewer for Kolab type: %@/%@", mt, st];
257       return [self linkViewer];
258     }
259     
260 #if 0 /* the link viewer looks better than plain text ;-) */
261     if ([st isEqualToString:@"pgp-signature"]) // TODO: real PGP viewer
262       return [self textViewer];
263 #endif
264   }
265
266   // TODO: always fallback to octet viewer?!
267 #if 1
268   [self errorWithFormat:@"found no viewer for MIME type: %@/%@", mt, st];
269 #endif
270   return [self linkViewer];
271 }
272
273 /* debugging */
274
275 - (BOOL)isDebuggingEnabled {
276   return NO;
277 }
278
279 @end /* UIxMailRenderingContext */
280
281
282 @implementation WOContext(UIxMailPart)
283
284 static NSString *MRK = @"UIxMailRenderingContext";
285
286 - (void)pushMailRenderingContext:(UIxMailRenderingContext *)_mctx {
287   [self setObject:_mctx forKey:MRK];
288 }
289 - (UIxMailRenderingContext *)popMailRenderingContext {
290   UIxMailRenderingContext *mctx;
291   
292   if ((mctx = [self objectForKey:MRK]) == nil)
293     return nil;
294   
295   mctx = [[mctx retain] autorelease];
296   [self removeObjectForKey:MRK];
297   return mctx;
298 }
299 - (UIxMailRenderingContext *)mailRenderingContext {
300   return [self objectForKey:MRK];
301 }
302
303 @end /* WOContext(UIxMailPart) */
304