From 91c8da4b819855576e12acdced6ae32a84204cda Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Fri, 17 Aug 2007 02:14:02 +0000 Subject: [PATCH] Monotone-Parent: ed5df203630a48a2ac353943b36f22b0ba1acd7c Monotone-Revision: 7d2b60688cdc88f9cad91827644a95830fad8d3f Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-08-17T02:14:02 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 9 ++ UI/MailerUI/UIxMailEditorAction.h | 61 ------- UI/MailerUI/UIxMailEditorAction.m | 203 ----------------------- UI/MailerUI/UIxMailForwardAction.m | 117 -------------- UI/MailerUI/UIxMailReplyAction.m | 252 ----------------------------- 5 files changed, 9 insertions(+), 633 deletions(-) delete mode 100644 UI/MailerUI/UIxMailEditorAction.h delete mode 100644 UI/MailerUI/UIxMailEditorAction.m delete mode 100644 UI/MailerUI/UIxMailForwardAction.m delete mode 100644 UI/MailerUI/UIxMailReplyAction.m diff --git a/ChangeLog b/ChangeLog index 6264e27f1..6dd4b7881 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2007-08-16 Wolfgang Sourdeau + * UI/MailerUI/UIxMailReplyAction.m: removed obsolete class + module. + + * UI/MailerUI/UIxMailForwardAction.m: removed obsolete class + module. + + * UI/MailerUI/UIxMailEditorAction.[hm]: removed obsolete class + module. + * SoObjects/Mailer/SOGoDraftObject.m ([SOGoDraftObject -init]): new method, initializing the new ivars: IMAP4ID, headers, text, sourceURL and sourceFlag. diff --git a/UI/MailerUI/UIxMailEditorAction.h b/UI/MailerUI/UIxMailEditorAction.h deleted file mode 100644 index 9a9fa4f8e..000000000 --- a/UI/MailerUI/UIxMailEditorAction.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#ifndef __UIxMailEditorAction_H__ -#define __UIxMailEditorAction_H__ - -#include - -/* - UIxMailEditorAction - - This action implements the backend for the various buttons which invoke the - mail editor. The mail editor itself only works on a SOGoDraftObject which - needs to be created in advance. -*/ - -@class NSException; -@class WOResponse; -@class SOGoDraftObject, SOGoDraftsFolder; - -@interface UIxMailEditorAction : WODirectAction -{ - SOGoDraftObject *newDraft; -} - -/* errors */ - -- (id)didNotFindDraftsError; -- (id)couldNotCreateDraftError:(SOGoDraftsFolder *)_draftsFolder; -- (id)didNotFindMailError; - -/* creating new draft object */ - -- (NSException *)_setupNewDraft; -- (WOResponse *)redirectToEditNewDraft; - -/* state */ - -- (void)reset; - -@end - -#endif /* __UIxMailEditorAction_H__ */ diff --git a/UI/MailerUI/UIxMailEditorAction.m b/UI/MailerUI/UIxMailEditorAction.m deleted file mode 100644 index 8fd8ed27c..000000000 --- a/UI/MailerUI/UIxMailEditorAction.m +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#import - -#import -#import -#import -#import -#import -#import - -#import -#import -#import -#import -#import - -#import "UIxMailEditorAction.h" - -@implementation UIxMailEditorAction - -- (void)dealloc -{ - [self->newDraft release]; - [super dealloc]; -} - -/* caches */ - -- (void)reset { - [self->newDraft release]; self->newDraft = nil; -} - -/* lookups */ - -- (SOGoDraftsFolder *)draftsFolder { - /* - Note: we cannot use acquisition to find the nearest drafts folder, because - the IMAP4 server might contains an own Drafts folder. - */ -// SOGoDraftsFolder *drafts; - SOGoMailAccount *accountFolder; - - accountFolder = [[self clientObject] mailAccountFolder]; - - return [accountFolder - lookupName: [accountFolder draftsFolderNameInContext: context] - inContext: context acquire: NO]; -} - -/* errors */ - -- (id)didNotFindDraftsError { - // TODO: make a nice error page - return [@"did not find drafts folder in object: " - stringByAppendingString:[[self clientObject] description]]; -} -- (id)couldNotCreateDraftError:(SOGoDraftsFolder *)_draftsFolder { - return [@"could not create a new draft in folder: " - stringByAppendingString:[_draftsFolder description]]; -} -- (id)didNotFindMailError { - return [NSException exceptionWithHTTPStatus:404 /* Not Found */ - reason:@"Did not find mail for operation!"]; -} - -/* compose */ - -- (id) composeAction -{ - SOGoDraftsFolder *drafts; - WOResponse *r; - NSString *urlBase, *url; - NSMutableDictionary *urlParams; - id parameter; - id returnValue; - - drafts = [self draftsFolder]; - if ([drafts isNotNull]) - { - if ([drafts isKindOfClass: [NSException class]]) - returnValue = drafts; - else - { - urlBase = [drafts newObjectBaseURLInContext: context]; - if ([urlBase isNotNull]) - { - urlParams = [NSMutableDictionary new]; - [urlParams autorelease]; - - /* attach mail-account info */ - parameter - = [[self clientObject] valueForKey: @"mailAccountFolder"]; - if (parameter && ![parameter isExceptionOrNull]) - [urlParams setObject: [parameter nameInContainer] - forKey: @"account"]; - - parameter = [[self request] formValueForKey: @"mailto"]; - if (parameter) - [urlParams setObject: parameter - forKey: @"mailto"]; - - url = [urlBase composeURLWithAction: @"edit" - parameters: urlParams - andHash: NO]; - - /* perform redirect */ - - [self debugWithFormat:@"compose on %@: %@", drafts, url]; - - r = [context response]; - [r setStatus: 302 /* move d */]; - [r setHeader: url forKey: @"location"]; - [self reset]; - - returnValue = r; - } - else - returnValue = [self couldNotCreateDraftError: drafts]; - } - } - else - returnValue = [self didNotFindDraftsError]; - - return returnValue; -} - -/* creating new draft object */ - -- (id)newDraftObject { - SOGoDraftsFolder *drafts; - - drafts = [self draftsFolder]; - if (![drafts isNotNull]) - return [self didNotFindDraftsError]; - if ([drafts isKindOfClass:[NSException class]]) - return drafts; - - return [drafts newObjectInContext:context]; -} - -- (NSException *)_setupNewDraft { - SOGoDraftObject *tmp; - - /* create draft object */ - - if ([(tmp = [self newDraftObject]) isKindOfClass:[NSException class]]) - return (NSException *)tmp; - if (![tmp isNotNull]) { /* Note: should never happen? */ - [self logWithFormat:@"WARNING: got no new draft object and no error!"]; - return [self didNotFindDraftsError]; // TODO: not exact - } - - ASSIGN(self->newDraft, tmp); - //[self debugWithFormat:@"NEW DRAFT: %@", self->newDraft]; - - return nil; -} - -- (WOResponse *)redirectToEditNewDraft { - WOResponse *r; - NSString *url; - - if (![self->newDraft isNotNull]) { - [self logWithFormat:@"ERROR(%s): missing new draft (already -reset?)", - __PRETTY_FUNCTION__]; - return nil; - } - - url = [self->newDraft baseURLInContext:context]; - if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"]; - url = [url stringByAppendingString:@"edit"]; - - // TODO: debug log - [self logWithFormat:@"compose on %@", url]; - - r = [context response]; - [r setStatus:302 /* moved */]; - [r setHeader:url forKey:@"location"]; - [self reset]; - return r; -} - -@end /* UIxMailEditorAction */ diff --git a/UI/MailerUI/UIxMailForwardAction.m b/UI/MailerUI/UIxMailForwardAction.m deleted file mode 100644 index ba59391e4..000000000 --- a/UI/MailerUI/UIxMailForwardAction.m +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#import -#import - -#import - -#import -#import - -#import "UIxMailEditorAction.h" - -@interface UIxMailForwardAction : UIxMailEditorAction -@end - - -@implementation UIxMailForwardAction - -- (NSString *)getAttachmentNameForSubject:(NSString *)_subject { - /* SOGoDraftObject disallows some strings - anything else required? */ - static NSString *sescape[] = { - @"/", @"..", @"~", @"\"", @"'", @" ", @".", nil - }; - static int maxFilenameLength = 64; - NSString *s; - unsigned i; - - if (![_subject isNotNull] || [_subject length] == 0) - return _subject; - s = _subject; - - if ([s length] > maxFilenameLength) - s = [s substringToIndex:maxFilenameLength]; - - for (i = 0; sescape[i] != nil; i++) - s = [s stringByReplacingString:sescape[i] withString:@"_"]; - - return [s stringByAppendingString:@".mail"]; -} - -- (NSString *)forwardSubject:(NSString *)_subject { - if (![_subject isNotNull] || [_subject length] == 0) - return _subject; - - /* Note: this is how Thunderbird 1.0 creates the subject */ - _subject = [@"[Fwd: " stringByAppendingString:_subject]; - _subject = [_subject stringByAppendingString:@"]"]; - return _subject; -} - -- (id)forwardAction { - NSException *error; - NSData *content; - NSDictionary *info, *attachment; - id result; - - /* fetch message */ - - if ((content = [[self clientObject] content]) == nil) - return [self didNotFindMailError]; - if ([content isKindOfClass:[NSException class]]) - return content; - - /* setup draft */ - - if ((error = [self _setupNewDraft]) != nil) - return error; - - /* set subject (do we need to set anything else?) */ - - info = [NSDictionary dictionaryWithObjectsAndKeys: - [self forwardSubject:[[self clientObject] subject]], - @"subject", - nil]; - if ((error = [newDraft storeInfo:info]) != nil) - return error; - - /* attach message */ - - // TODO: use subject for filename? -// error = [newDraft saveAttachment:content withName:@"forward.mail"]; - attachment = [NSDictionary dictionaryWithObjectsAndKeys: - @"forward.mail", @"filename", - @"message/rfc822", @"mime-type", - nil]; - error = [newDraft saveAttachment: content - withMetadata: attachment]; - if (error != nil) - return error; - - // TODO: we might want to pass the original URL to the editor for a final - // redirect back to the message? - result = [self redirectToEditNewDraft]; - [self reset]; - return result; -} - -@end /* UIxMailForwardAction */ diff --git a/UI/MailerUI/UIxMailReplyAction.m b/UI/MailerUI/UIxMailReplyAction.m deleted file mode 100644 index ac3e13b8e..000000000 --- a/UI/MailerUI/UIxMailReplyAction.m +++ /dev/null @@ -1,252 +0,0 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#import -#import -#import -#import -#import -#import -#import -#import - -#import "UIxMailEditorAction.h" - -@interface UIxMailReplyAction : UIxMailEditorAction -@end - -@implementation UIxMailReplyAction - -- (BOOL)hasReplyPrefix:(NSString *)_subject { - static NSString *replyPrefixes[] = { - @"Re:", // regular - @"RE:", // Outlook v11 (English?) - @"AW:", // German Outlook v11 - @"Re[", // numbered Re, eg "Re[2]:" - nil - }; - unsigned i; - for (i = 0; replyPrefixes[i] != nil; i++) { - if ([_subject hasPrefix:replyPrefixes[i]]) - return YES; - } - return NO; -} - -- (NSString *)replySubject:(NSString *)_subject { - if (![_subject isNotNull] || [_subject length] == 0) - return _subject; - - if ([self hasReplyPrefix:_subject]) { - /* do not do: "Re: Re: Re: My Mail" - a single Re is sufficient ;-) */ - return _subject; - } - - return [@"Re: " stringByAppendingString:_subject]; -} - -- (void)addEMailsOfAddresses:(NSArray *)_addrs toArray:(NSMutableArray *)_ma { - unsigned i, count; - - for (i = 0, count = [_addrs count]; i < count; i++) - [_ma addObject:[(NGImap4EnvelopeAddress *)[_addrs objectAtIndex:i] email]]; -} - -- (void)fillInReplyAddresses:(NSMutableDictionary *)_info - replyToAll:(BOOL)_replyToAll - envelope:(NGImap4Envelope *)_envelope -{ - /* - The rules as implemented by Thunderbird: - - if there is a 'reply-to' header, only include that (as TO) - - if we reply to all, all non-from addresses are added as CC - - the from is always the lone TO (except for reply-to) - - Note: we cannot check reply-to, because Cyrus even sets a reply-to in the - envelope if none is contained in the message itself! (bug or - feature?) - - TODO: what about sender (RFC 822 3.6.2) - */ - NSMutableArray *to; - NSArray *addrs; - - to = [NSMutableArray arrayWithCapacity:2]; - - /* first check for "reply-to" */ - - addrs = [_envelope replyTo]; - if ([addrs count] == 0) { - /* no "reply-to", try "from" */ - addrs = [_envelope from]; - } - [self addEMailsOfAddresses:addrs toArray:to]; - [_info setObject:to forKey:@"to"]; - - /* CC processing if we reply-to-all: add all 'to' and 'cc' */ - - if (_replyToAll) { - to = [NSMutableArray arrayWithCapacity:8]; - - [self addEMailsOfAddresses:[_envelope to] toArray:to]; - [self addEMailsOfAddresses:[_envelope cc] toArray:to]; - - [_info setObject:to forKey:@"cc"]; - } -} - -- (NSString *) contentForReplyOnParts: (NSDictionary *) _prts - keys: (NSArray *) _k -{ - static NSString *textPartSeparator = @"\n---\n"; - NSMutableString *ms; - unsigned i, count; - - ms = [NSMutableString stringWithCapacity:16000]; - for (i = 0, count = [_k count]; i < count; i++) { - NSString *k, *v; - - k = [_k objectAtIndex:i]; - - // TODO: this is DUP code to SOGoMailObject - if ([k isEqualToString:@"body[text]"]) - k = @""; - else if ([k hasPrefix:@"body["]) { - k = [k substringFromIndex:5]; - if ([k length] > 0) k = [k substringToIndex:([k length] - 1)]; - } - - v = [_prts objectForKey:k]; - if (![v isKindOfClass:[NSString class]]) { - [self logWithFormat:@"Note: cannot show part %@", k]; - continue; - } - if ([v length] == 0) - continue; - - if (i != 0) [ms appendString:textPartSeparator]; - [ms appendString:[v stringByApplyingMailQuoting]]; - } - return ms; -} - -- (NSString *)contentForReply { - NSArray *keys, *partInfos; - NSDictionary *parts, *infos; - - keys = [[self clientObject] plainTextContentFetchKeys]; -// SOGoMailObject *co; - -// co = [self clientObject]; -// keys = [co plainTextContentFetchKeys]; -// infos = [co fetchCoreInfos]; -// partInfos = [infos objectForKey: keys]; -// NSLog (@"infos: '%@'", infos); - - if ([keys count] == 0) - return nil; - - if ([keys count] > 1) { - /* filter keys, only include top-level, or if none, the first */ - NSMutableArray *topLevelKeys = nil; - unsigned i; - - for (i = 0; i < [keys count]; i++) { - NSRange r; - - r = [[keys objectAtIndex:i] rangeOfString:@"."]; - if (r.length > 0) - continue; - - if (topLevelKeys == nil) - topLevelKeys = [NSMutableArray arrayWithCapacity:4]; - [topLevelKeys addObject:[keys objectAtIndex:i]]; - } - - if ([topLevelKeys count] > 0) { - /* use top-level keys if we have some */ - keys = topLevelKeys; - } - else { - /* just take the first part */ - keys = [NSArray arrayWithObject:[keys objectAtIndex:0]]; - } - } - - parts = [[self clientObject] fetchPlainTextStrings:keys]; - return [self contentForReplyOnParts:parts keys:keys]; -} - -- (id)replyToAll:(BOOL)_replyToAll { - NSMutableDictionary *info; - NSException *error; - id result; - id tmp; - - /* ensure mail exists and is filled */ - - // TODO: we could transport the body structure in a hidden field of the mail - // viewer to avoid refetching the core-info? - tmp = [[self clientObject] fetchCoreInfos]; - if ([tmp isKindOfClass:[NSException class]]) - return tmp; - if (![tmp isNotNull]) - return [self didNotFindMailError]; - - /* setup draft */ - - if ((error = [self _setupNewDraft]) != nil) - return error; - - /* fill draft info */ - - info = [NSMutableDictionary dictionaryWithCapacity:16]; - - [info setObject:[self replySubject:[[self clientObject] subject]] - forKey:@"subject"]; - [self fillInReplyAddresses:info replyToAll:_replyToAll - envelope:[[self clientObject] envelope]]; - - /* fill in text content */ - - if ((tmp = [self contentForReply]) != nil) - [info setObject:tmp forKey:@"text"]; - - /* save draft info */ - - if ((error = [self->newDraft storeInfo:info]) != nil) - return error; - - // TODO: we might want to pass the original URL to the editor for a final - // redirect back to the message? - result = [self redirectToEditNewDraft]; - [self reset]; - return result; -} - -- (id)replyAction { - return [self replyToAll:NO]; -} -- (id)replyallAction { - return [self replyToAll:YES]; -} - -@end /* UIxMailReplyAction */