]> err.no Git - scalable-opengroupware.org/blob - UI/MailPartViewers/UIxMailRenderingContext.m
do not use Anais
[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 - (WOComponent *)viewerForBodyInfo:(id)_info {
149   NSString *mt, *st;
150
151   mt = [[_info valueForKey:@"type"]    lowercaseString];
152   st = [[_info valueForKey:@"subtype"] lowercaseString];
153   
154   if ([mt isEqualToString:@"multipart"]) {
155     if ([st isEqualToString:@"mixed"])
156       return [self mixedViewer];
157     if ([st isEqualToString:@"signed"])
158       return [self signedViewer];
159     if ([st isEqualToString:@"alternative"])
160       return [self alternativeViewer];
161     
162     if ([st isEqualToString:@"report"])
163       /* this is used by mail-delivery reports */
164       return [self mixedViewer];
165   }
166   else if ([mt isEqualToString:@"text"]) {
167     /* 
168        Note: in the _info dictionary we do not get the content-disposition
169              information (inline vs attachment). Our hack is to check for the
170              'name' parameter.
171     */
172     if ([st isEqualToString:@"plain"] || [st isEqualToString:@"html"]) {
173       if (!showNamedTextAttachmentsInline) {
174         NSString *n;
175         
176         n = [[_info objectForKey:@"parameterList"] objectForKey:@"name"];
177         if ([n isNotNull] && [n length] > 0)
178           return [self linkViewer];
179       }
180       
181       return [st isEqualToString:@"html"] 
182         ? [self htmlViewer] : [self textViewer];
183     }
184     
185     if ([st isEqualToString:@"calendar"])
186       return [self iCalViewer];
187   }
188   else if ([mt isEqualToString:@"image"])
189     return [self imageViewer];
190   else if ([mt isEqualToString:@"message"] && [st isEqualToString:@"rfc822"])
191     return [self messageViewer];
192   else if ([mt isEqualToString:@"message"] && 
193            [st isEqualToString:@"delivery-status"]) {
194     /*
195       Content-Description: Delivery error report
196       Content-Type: message/delivery-status
197       
198       Reporting-MTA: dns; mail.opengroupware.org
199       Arrival-Date: Mon, 18 Jul 2005 12:08:43 +0200 (CEST)
200       
201       Final-Recipient: rfc822; ioioi@plop.com
202       Action: failed
203       Status: 5.0.0
204       Diagnostic-Code: X-Postfix; host plop.com[64.39.31.55] said: 550 5.7.1
205           <ioioi@plop.com>... Relaying denied
206     */
207     // Note: we cannot use the text viewer because the body is not pre-fetched
208     return [self linkViewer];
209   }
210   else if ([mt isEqualToString:@"application"]) {
211     // octet-stream (generate download link?, autodetect type?)
212     
213 #if 0 /* the link viewer looks better than plain text ;-) */
214     if ([st isEqualToString:@"pgp-signature"]) // TODO: real PGP viewer
215       return [self textViewer];
216 #endif
217   }
218
219   // TODO: always fallback to octet viewer?!
220 #if 1
221   [self errorWithFormat:@"found no viewer for MIME type: %@/%@", mt, st];
222 #endif
223   return [self linkViewer];
224 }
225
226 /* debugging */
227
228 - (BOOL)isDebuggingEnabled {
229   return NO;
230 }
231
232 @end /* UIxMailRenderingContext */
233
234
235 @implementation WOContext(UIxMailPart)
236
237 static NSString *MRK = @"UIxMailRenderingContext";
238
239 - (void)pushMailRenderingContext:(UIxMailRenderingContext *)_mctx {
240   [self setObject:_mctx forKey:MRK];
241 }
242 - (UIxMailRenderingContext *)popMailRenderingContext {
243   UIxMailRenderingContext *mctx;
244   
245   if ((mctx = [self objectForKey:MRK]) == nil)
246     return nil;
247   
248   mctx = [[mctx retain] autorelease];
249   [self removeObjectForKey:MRK];
250   return mctx;
251 }
252 - (UIxMailRenderingContext *)mailRenderingContext {
253   return [self objectForKey:MRK];
254 }
255
256 @end /* WOContext(UIxMailPart) */
257