]> err.no Git - scalable-opengroupware.org/blob - SOGo/UI/Mailer/UIxMailEditor.m
fixed SOGo bug #1054, deactivated some unused toolbar buttons
[scalable-opengroupware.org] / SOGo / UI / Mailer / UIxMailEditor.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 <SOGoUI/UIxComponent.h>
23
24 /*
25   UIxMailEditor
26   
27   An mail editor component which works on SOGoDraftObject's.
28 */
29
30 @class NSArray, NSString;
31 @class SOGoMailFolder;
32
33 @interface UIxMailEditor : UIxComponent
34 {
35   NSArray  *to;
36   NSArray  *cc;
37   NSArray  *bcc;
38   NSString *subject;
39   NSString *text;
40   SOGoMailFolder *sentFolder;
41 }
42
43 @end
44
45 #include <SOGo/SoObjects/Mailer/SOGoDraftObject.h>
46 #include <SOGo/SoObjects/Mailer/SOGoMailFolder.h>
47 #include <SOGo/SoObjects/Mailer/SOGoMailAccount.h>
48 #include <NGMail/NGMimeMessage.h>
49 #include <NGMail/NGMimeMessageGenerator.h>
50 #include "common.h"
51
52 @interface UIxComponent (Scheduler_Privates)
53 - (NSString *)emailForUser;
54 @end
55
56 @implementation UIxMailEditor
57
58 static BOOL keepMailTmpFile    = NO;
59 static NSArray *infoKeys = nil;
60
61 + (void)initialize {
62   infoKeys = [[NSArray alloc] initWithObjects:
63                                 @"subject", @"text", @"to", @"cc", @"bcc", 
64                                 @"from", @"replyTo",
65                               nil];
66   
67   if (keepMailTmpFile)
68     NSLog(@"WARNING: keeping mail files.");
69 }
70
71 - (void)dealloc {
72   [self->sentFolder release];
73   [self->text    release];
74   [self->subject release];
75   [self->to      release];
76   [self->cc      release];
77   [self->bcc     release];
78   [super dealloc];
79 }
80
81 /* accessors */
82
83 - (void)setFrom:(NSString *)_ignore {
84 }
85 - (NSString *)from {
86   return [self emailForUser];
87 }
88 - (void)setReplyTo:(NSString *)_ignore {
89 }
90 - (NSString *)replyTo {
91   /* we are here for future extensibility */
92   return @"";
93 }
94
95 - (void)setSubject:(NSString *)_value {
96   ASSIGNCOPY(self->subject, _value);
97 }
98 - (NSString *)subject {
99   return self->subject ? self->subject : @"";
100 }
101
102 - (void)setText:(NSString *)_value {
103   ASSIGNCOPY(self->text, _value);
104 }
105 - (NSString *)text {
106   return [self->text isNotNull] ? self->text : @"";
107 }
108
109 - (void)setTo:(NSArray *)_value {
110   ASSIGNCOPY(self->to, _value);
111 }
112 - (NSArray *)to {
113   return [self->to isNotNull] ? self->to : [NSArray array];
114 }
115
116 - (void)setCc:(NSArray *)_value {
117   ASSIGNCOPY(self->cc, _value);
118 }
119 - (NSArray *)cc {
120   return [self->cc isNotNull] ? self->cc : [NSArray array];
121 }
122
123 - (void)setBcc:(NSArray *)_value {
124   ASSIGNCOPY(self->bcc, _value);
125 }
126 - (NSArray *)bcc {
127   return [self->bcc isNotNull] ? self->bcc : [NSArray array];
128 }
129
130 /* info loading */
131
132 - (void)loadInfo:(NSDictionary *)_info {
133   if (![_info isNotNull]) return;
134   [self debugWithFormat:@"loading info ..."];
135   [self takeValuesFromDictionary:_info];
136 }
137 - (NSDictionary *)storeInfo {
138   [self debugWithFormat:@"storing info ..."];
139   return [self valuesForKeys:infoKeys];
140 }
141
142 /* requests */
143
144 - (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
145   return YES;
146 }
147
148 /* IMAP4 store */
149
150 - (NSException *)patchFlagsInStore {
151   /*
152     Flags we should set:
153       if the draft is a reply   => [message markAnswered]
154       if the draft is a forward => [message addFlag:@"forwarded"]
155       
156     This is hard, we would need to find the original message in Cyrus.
157   */
158   return nil;
159 }
160
161 - (id)lookupSentFolder {
162   /* lookup INBOX/Sent folder */
163   SOGoMailAccount *account;
164   SOGoMailFolder  *folder;
165
166   if (self->sentFolder != nil)
167     return self;
168
169   account = [[self clientObject] mailAccountFolder];
170   if ([account isKindOfClass:[NSException class]]) return account;
171   
172   folder = [account lookupName:@"INBOX" inContext:[self context] acquire:NO];
173   if ([folder isKindOfClass:[NSException class]]) return folder;
174   
175   folder = [folder lookupName:@"Sent" inContext:[self context] acquire:NO];
176   if ([folder isKindOfClass:[NSException class]]) return folder;
177
178   if (![folder isNotNull]) {
179     return [NSException exceptionWithHTTPStatus:500 /* server error */
180                         reason:@"did not find Sent folder!"];
181   }
182   
183   self->sentFolder = [folder retain];
184   return self->sentFolder;
185 }
186
187 - (NSException *)storeMailInSentFolder:(NSString *)_path {
188   SOGoMailFolder *folder;
189   NSData *data;
190   id result;
191   
192   folder = [self lookupSentFolder];
193   if ([folder isKindOfClass:[NSException class]]) return (id)folder;
194   
195   if ((data = [[NSData alloc] initWithContentsOfMappedFile:_path]) == nil) {
196     return [NSException exceptionWithHTTPStatus:500 /* server error */
197                         reason:@"could not temporary draft file!"];
198   }
199   
200   result = [folder postData:data flags:@"seen"];
201   [data release]; data = nil;
202   return result;
203 }
204
205 /* actions */
206
207 - (BOOL)_saveFormInfo {
208   NSDictionary *info;
209   
210   if ((info = [self storeInfo]) != nil) {
211     if (![[self clientObject] storeInfo:info]) {
212       [self errorWithFormat:@"failed to store draft!"];
213       // TODO: improve error handling
214       return NO;
215     }
216   }
217   
218   // TODO: wrap content
219   
220   return YES;
221 }
222 - (id)failedToSaveFormResponse {
223   // TODO: improve error handling
224   return [NSException exceptionWithHTTPStatus:500 /* server error */
225                       reason:@"failed to store draft object on server!"];
226 }
227
228 - (id)defaultAction {
229   return [self redirectToLocation:@"edit"];
230 }
231
232 - (id)editAction {
233   [self logWithFormat:@"edit action, load content from: %@",
234           [self clientObject]];
235   
236   [self loadInfo:[[self clientObject] fetchInfo]];
237   return self;
238 }
239
240 - (id)saveAction {
241   return [self _saveFormInfo] ? self : [self failedToSaveFormResponse];
242 }
243
244 - (id)sendAction {
245   NSException *error;
246   NSString *mailPath;
247   
248   /* first, save form data */
249   
250   if (![self _saveFormInfo])
251     return [self failedToSaveFormResponse];
252   
253   /* save mail to file (so that we can upload the mail to Cyrus */
254   
255   mailPath = [[self clientObject] saveMimeMessageToTemporaryFile];
256   
257   /* then, send mail */
258   
259   if ((error = [[self clientObject] sendMimeMessageAtPath:mailPath]) != nil) {
260     // TODO: improve error handling
261     [[NSFileManager defaultManager] removeFileAtPath:mailPath handler:nil];
262     return error;
263   }
264   
265   /* patch flags in store for replies etc */
266   
267   if ((error = [self patchFlagsInStore]) != nil)
268      return error;
269   
270   /* finally store in Sent */
271
272   if ((error = [self storeMailInSentFolder:mailPath]) != nil)
273     return error;
274   
275   /* delete temporary mail file */
276   
277   if (keepMailTmpFile)
278     [self warnWithFormat:@"keeping mail file: '%@'", mailPath];
279   else
280     [[NSFileManager defaultManager] removeFileAtPath:mailPath handler:nil];
281   mailPath = nil;
282   
283   /* delete draft */
284   
285   if ((error = [[self clientObject] delete]) != nil)
286     return error;
287
288   // if everything is ok, close the window (send a JS closing the Window)
289   return [self pageWithName:@"UIxMailWindowCloser"];
290 }
291
292 - (id)deleteAction {
293   NSException *error;
294   
295   if ((error = [[self clientObject] delete]) != nil)
296     return error;
297   
298   return nil;
299 }
300
301 @end /* UIxMailEditor */