From edb7107c91a3777d0eacc6c7a0f19789bdeb8065 Mon Sep 17 00:00:00 2001 From: helge Date: Tue, 8 Feb 2005 22:10:26 +0000 Subject: [PATCH] some reorgs in mailer action git-svn-id: http://svn.opengroupware.org/SOGo/trunk@536 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/UI/Mailer/ChangeLog | 7 + SOGo/UI/Mailer/GNUmakefile | 2 + SOGo/UI/Mailer/UIxMailEditorAction.h | 61 ++++++ SOGo/UI/Mailer/UIxMailEditorAction.m | 229 +------------------- SOGo/UI/Mailer/UIxMailForwardAction.m | 106 +++++++++ SOGo/UI/Mailer/UIxMailPartMessageViewer.m | 3 - SOGo/UI/Mailer/UIxMailPartMessageViewer.wox | 8 +- SOGo/UI/Mailer/UIxMailReplyAction.m | 175 +++++++++++++++ SOGo/UI/Mailer/Version | 2 +- SOGo/UI/Mailer/mailer.js | 18 ++ SOGo/UI/Mailer/product.plist | 6 +- 11 files changed, 379 insertions(+), 238 deletions(-) create mode 100644 SOGo/UI/Mailer/UIxMailEditorAction.h create mode 100644 SOGo/UI/Mailer/UIxMailForwardAction.m create mode 100644 SOGo/UI/Mailer/UIxMailReplyAction.m diff --git a/SOGo/UI/Mailer/ChangeLog b/SOGo/UI/Mailer/ChangeLog index b5a89229..5d757542 100644 --- a/SOGo/UI/Mailer/ChangeLog +++ b/SOGo/UI/Mailer/ChangeLog @@ -1,5 +1,12 @@ 2005-02-08 Helge Hess + * v0.9.96 + + * UIxMailPartMessageViewer.m: fixed for multivalue from fields + + * UIxMailEditorAction.m, product.plist: split editor action in multiple + classes + * v0.9.95 * product.plist: do not use clickedEditorDelete() JS function for diff --git a/SOGo/UI/Mailer/GNUmakefile b/SOGo/UI/Mailer/GNUmakefile index cf6481f1..243cdd1d 100644 --- a/SOGo/UI/Mailer/GNUmakefile +++ b/SOGo/UI/Mailer/GNUmakefile @@ -32,6 +32,8 @@ MailerUI_OBJC_FILES += \ UIxMailEditor.m \ UIxMailEditorAttach.m \ UIxMailEditorAction.m \ + UIxMailReplyAction.m \ + UIxMailForwardAction.m \ UIxMailToSelection.m \ UIxMailAddressbook.m \ UIxMailWindowCloser.m \ diff --git a/SOGo/UI/Mailer/UIxMailEditorAction.h b/SOGo/UI/Mailer/UIxMailEditorAction.h new file mode 100644 index 00000000..9a9fa4f8 --- /dev/null +++ b/SOGo/UI/Mailer/UIxMailEditorAction.h @@ -0,0 +1,61 @@ +/* + 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/SOGo/UI/Mailer/UIxMailEditorAction.m b/SOGo/UI/Mailer/UIxMailEditorAction.m index 99ce1312..7bb19508 100644 --- a/SOGo/UI/Mailer/UIxMailEditorAction.m +++ b/SOGo/UI/Mailer/UIxMailEditorAction.m @@ -19,31 +19,12 @@ 02111-1307, USA. */ -#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 SOGoDraftObject; - -@interface UIxMailEditorAction : WODirectAction -{ - SOGoDraftObject *newDraft; -} - -@end +#include "UIxMailEditorAction.h" #include #include #include #include -#include -#include #include "common.h" @implementation UIxMailEditorAction @@ -177,212 +158,4 @@ return r; } -/* reply */ - -- (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"]; - } -} - -- (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 content */ - - // TODO: add quoted content - - /* 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]; -} - -/* forwarding */ - -- (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; - 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 = [self->newDraft storeInfo:info]) != nil) - return error; - - /* attach message */ - - // TODO: use subject for filename? - error = [self->newDraft saveAttachment:content withName:@"forward.mail"]; - 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 /* UIxMailEditorAction */ diff --git a/SOGo/UI/Mailer/UIxMailForwardAction.m b/SOGo/UI/Mailer/UIxMailForwardAction.m new file mode 100644 index 00000000..647f6194 --- /dev/null +++ b/SOGo/UI/Mailer/UIxMailForwardAction.m @@ -0,0 +1,106 @@ +/* + 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. +*/ + +#include "UIxMailEditorAction.h" + +@interface UIxMailForwardAction : UIxMailEditorAction +@end + +#include +#include +#include "common.h" + +@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; + 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 = [self->newDraft storeInfo:info]) != nil) + return error; + + /* attach message */ + + // TODO: use subject for filename? + error = [self->newDraft saveAttachment:content withName:@"forward.mail"]; + 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/SOGo/UI/Mailer/UIxMailPartMessageViewer.m b/SOGo/UI/Mailer/UIxMailPartMessageViewer.m index 9ea0aca0..7ac488e8 100644 --- a/SOGo/UI/Mailer/UIxMailPartMessageViewer.m +++ b/SOGo/UI/Mailer/UIxMailPartMessageViewer.m @@ -146,9 +146,6 @@ return [@"mailto:" stringByAppendingString:[_address baseEMail]]; } -- (NSString *)fromLink { - return [self linkToEnvelopeAddress:[[self envelope] from]]; -} - (NSString *)currentAddressLink { return [self linkToEnvelopeAddress:[self currentAddress]]; } diff --git a/SOGo/UI/Mailer/UIxMailPartMessageViewer.wox b/SOGo/UI/Mailer/UIxMailPartMessageViewer.wox index 6388d709..73c7d0ad 100644 --- a/SOGo/UI/Mailer/UIxMailPartMessageViewer.wox +++ b/SOGo/UI/Mailer/UIxMailPartMessageViewer.wox @@ -23,9 +23,11 @@ : - - + + + + diff --git a/SOGo/UI/Mailer/UIxMailReplyAction.m b/SOGo/UI/Mailer/UIxMailReplyAction.m new file mode 100644 index 00000000..fae09af2 --- /dev/null +++ b/SOGo/UI/Mailer/UIxMailReplyAction.m @@ -0,0 +1,175 @@ +/* + 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. +*/ + +#include "UIxMailEditorAction.h" + +@interface UIxMailReplyAction : UIxMailEditorAction +@end + +#include +#include +#include +#include +#include "common.h" + +@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 *)contentForReply { + // TODO: add quoted content + [self logWithFormat:@"keys: %@", + [[self clientObject] plainTextContentFetchKeys]]; + [self logWithFormat:@"texts: %@", [[self clientObject] fetchPlainTextParts]]; + return nil; +} + +- (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 */ diff --git a/SOGo/UI/Mailer/Version b/SOGo/UI/Mailer/Version index f77e7465..be40fed5 100644 --- a/SOGo/UI/Mailer/Version +++ b/SOGo/UI/Mailer/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=95 +SUBMINOR_VERSION:=96 # v0.9.94 requires SoObjects/Mailer v0.9.69 # v0.9.94 requires libNGMime v4.5.210 diff --git a/SOGo/UI/Mailer/mailer.js b/SOGo/UI/Mailer/mailer.js index 046f2f22..a6e154bf 100644 --- a/SOGo/UI/Mailer/mailer.js +++ b/SOGo/UI/Mailer/mailer.js @@ -213,3 +213,21 @@ function markMailReadInWindow(win, msguid) { else return false; } + +/* main window */ + +function reopenToRemoveLocationBar() { + if (window.locationbar && window.locationbar.visible) { + newwin = window.open(window.location.href, "SOGo", + "width=800,height=600,resizable=1,scrollbars=1," + + "toolbar=0,location=0,directories=0,status=0," + + "menubar=0,copyhistory=0"); + if (newwin) { + window.close(); // this does only work for windows opened by scripts! + newwin.focus(); + return true; + } + return false; + } + return true; +} diff --git a/SOGo/UI/Mailer/product.plist b/SOGo/UI/Mailer/product.plist index bbc90876..277a0607 100644 --- a/SOGo/UI/Mailer/product.plist +++ b/SOGo/UI/Mailer/product.plist @@ -232,17 +232,17 @@ }; reply = { protectedBy = "View"; - actionClass = "UIxMailEditorAction"; + actionClass = "UIxMailReplyAction"; actionName = "reply"; }; replyall = { protectedBy = "View"; - actionClass = "UIxMailEditorAction"; + actionClass = "UIxMailReplyAction"; actionName = "replyall"; }; forward = { protectedBy = "View"; - actionClass = "UIxMailEditorAction"; + actionClass = "UIxMailForwardAction"; actionName = "forward"; }; }; -- 2.39.5