2 Copyright (C) 2004 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
23 #include <SOGoUI/UIxComponent.h>
25 @interface UIxMailView : UIxComponent
30 - (BOOL)isDeletableClientObject;
34 #include "UIxMailRenderingContext.h"
35 #include "WOContext+UIxMailer.h"
36 #include <SoObjects/Mailer/SOGoMailObject.h>
37 #include <NGImap4/NGImap4Envelope.h>
40 @implementation UIxMailView
43 [self->currentAddress release];
50 [self->currentAddress release]; self->currentAddress = nil;
56 - (void)setCurrentAddress:(id)_addr {
57 ASSIGN(self->currentAddress, _addr);
59 - (id)currentAddress {
60 return self->currentAddress;
66 return [[self clientObject] fetchCoreInfos];
70 return [[[self clientObject] ccEnvelopeAddresses] count] > 0 ? YES : NO;
73 /* process body structure */
75 - (BOOL)shouldFetchPartOfType:(NSString *)_type subtype:(NSString *)_subtype {
76 _type = [_type lowercaseString];
77 _subtype = [_subtype lowercaseString];
79 if ([_type isEqualToString:@"text"])
80 return [_subtype isEqualToString:@"plain"];
84 - (void)addRequiredKeysOfStructure:(id)_info path:(NSString *)_p
85 toArray:(NSMutableArray *)_keys
91 fetchPart = [self shouldFetchPartOfType:[_info valueForKey:@"type"]
92 subtype:[_info valueForKey:@"subtype"]];
96 if ([_p length] > 0) {
97 k = [[@"body[" stringByAppendingString:_p] stringByAppendingString:@"]"];
101 for some reason we need to add ".TEXT" for plain text stuff on root
103 TODO: check with HTML
112 parts = [_info objectForKey:@"parts"];
113 for (i = 0, count = [parts count]; i < count; i++) {
118 ? [_p stringByAppendingFormat:@".%d", i + 1]
119 : [NSString stringWithFormat:@"%d", i + 1];
121 childInfo = [parts objectAtIndex:i];
123 [self addRequiredKeysOfStructure:childInfo path:sp toArray:_keys];
127 - (NSArray *)contentFetchKeys {
130 ma = [NSMutableArray arrayWithCapacity:4];
131 [self addRequiredKeysOfStructure:[[self clientObject] bodyStructure]
132 path:@"" toArray:ma];
136 - (NSDictionary *)fetchFlatContents {
137 NSMutableDictionary *flatContents;
142 keys = [self contentFetchKeys];
143 [self debugWithFormat:@"fetch keys: %@", keys];
145 result = [[self clientObject] fetchParts:keys];
146 result = [result valueForKey:@"RawResponse"]; // hackish
147 result = [result objectForKey:@"fetch"]; // Note: -valueForKey: doesn't work!
149 count = [keys count];
150 flatContents = [NSMutableDictionary dictionaryWithCapacity:count];
151 for (i = 0; i < count; i++) {
155 key = [keys objectAtIndex:i];
156 data = [[result objectForKey:key] objectForKey:@"data"];
158 if (![data isNotNull]) {
159 [self debugWithFormat:@"got no data fork key: %@", key];
163 if ([key isEqualToString:@"body[text]"])
164 key = @""; // see key collector
165 else if ([key hasPrefix:@"body["]) {
168 key = [key substringFromIndex:5];
169 r = [key rangeOfString:@"]"];
171 key = [key substringToIndex:r.location];
173 [flatContents setObject:data forKey:key];
180 - (id)contentViewerComponent {
183 info = [[self clientObject] bodyStructure];
184 return [[[self context] mailRenderingContext] viewerForBodyInfo:info];
189 - (id)defaultAction {
190 if ([self message] == nil) {
191 return [NSException exceptionWithHTTPStatus:404 /* Not Found */
192 reason:@"did not find specified message!"];
195 [self logWithFormat:@"FETCH BODY PARTS: %@", [self contentFetchKeys]];
196 [self logWithFormat:@"CORE: %@", [self fetchFlatContents]];
201 - (BOOL)isDeletableClientObject {
202 return [[self clientObject] respondsToSelector:@selector(delete)];
204 - (BOOL)isInlineViewer {
211 if (![self isDeletableClientObject]) {
212 return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
213 reason:@"method cannot be invoked on "
214 @"the specified object"];
217 if ((ex = [[self clientObject] delete]) != nil) {
218 // TODO: improve error handling
219 [self debugWithFormat:@"failed to delete: %@", ex];
223 if (![self isInlineViewer]) {
224 // if everything is ok, close the window (send a JS closing the Window)
225 return [self pageWithName:@"UIxMailWindowCloser"];
230 url = [[[self clientObject] container] baseURLInContext:[self context]];
231 return [self redirectToLocation:url];
235 - (id)getMailAction {
236 // TODO: we might want to flush the caches?
237 return [self redirectToLocation:@"view"];
240 /* generating response */
242 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
243 UIxMailRenderingContext *mctx;
245 mctx = [[UIxMailRenderingContext alloc] initWithViewer:self context:_ctx];
246 [_ctx pushMailRenderingContext:mctx];
249 [super appendToResponse:_response inContext:_ctx];
251 [[_ctx popMailRenderingContext] reset];
254 @end /* UIxMailView */