diff --git a/ChangeLog b/ChangeLog index 784684cfb..92aae14f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,101 @@ +2007-08-16 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailObject+Draft.m: new extension module + containing a rewrite of the mail action methods found in + UI/Mailer/, that needed to be put in the SOGoMailObject class. + ([SOGoMailObject -subjectForReply]): new method that returns a + subject suitable for replies. + ([SOGoMailObject -contentForReply]): new method that returns the + textual content of an email, quoted for replying. + ([SOGoMailObject -filenameForForward]): new method that returns + the name of the filename that should contain the forwarded + message, based on its subject. + ([SOGoMailObject -subjectForForward]): explicit. + +2007-08-15 Wolfgang Sourdeau + + * UI/MailerUI/UIxMailMainFrame.m ([UIxMailMainFrame + -mailAccounts]): rewrote method to return the name of the mail + accounts now available with the -[SOGoUser mailAccounts] method. + ([UIxMailMainFrame -showLinkBanner]): removed method. + ([UIxMailMainFrame -bannerToolbarStyle]): removed method. + ([UIxMailMainFrame -bannerConsumeStyle]): removed method. + ([UIxMailMainFrame -rootURL]): removed method. + ([UIxMailMainFrame -userRootURL]): removed method. + ([UIxMailMainFrame -calendarRootURL]): removed method. + ([UIxMailMainFrame -contactsRootURL]): removed method. + ([UIxMailMainFrame -hasErrorText]) + ([UIxMailMainFrame -errorText]) + ([UIxMailMainFrame -errorAlertJavaScript]): removed methods. + ([-composeAction]): removed method. Now provided by + UIxMailAccountActions. + ([UIxMailMainFrame -setHideFolderTree:_flag]): removed method. + ([UIxMailMainFrame -hideFolderTree]): removed method. + ([UIxMailMainFrame -treeRootClassName]): removed method. + ([UIxMailMainFrame +initialize]): removed method. + SOGoMailTreeRootClass userdefaults will no longer have any effect. + + * UI/Common/WODirectAction+SOGo.m ([WODirectAction + -redirectToLocation:newLocation]): new method that implements the + same functionality as WOComponent. + + * UI/Common/WODirectAction+SOGo.[hm]: new class extension module. + + * UI/MailerUI/UIxMailView.m ([UIxMailView -mailIsDraft]): new + method that returns whether the current mail is store in the + drafts folder hierarchy. + + * SoObjects/SOGo/SOGoUser.m ([-fullEmail]): removed method. + ([-primaryEmail]): removed method. + ([SOGoUser -primaryIMAP4AccountString]): removed method. + ([SOGoUser -mailAccounts]): new method that returns an array + containing description dictionaries for all the user mail + accounts. Each account also contain the user's identities for that + account. + ([SOGoUser -allIdentities]): new utility method that returns all + the user identities on all accounts. + ([SOGoUser -primaryIdentity]): new method return the first + identity of the first account. + + * SoObjects/Mailer/SOGoMailFolder.m ([SOGoMailFolder -httpURLForAdvisoryToUser:uid]): + + * SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount + -isInDraftsFolder]): returns NO. + ([-preferredIdentity]): removed method, replaced with -[SOGoUser + primaryIdentity]. + ([SOGoMailAccount -draftsFolderInContext:_ctx]): new method. + + * SoObjects/Mailer/SOGoMailBaseObject.m ([SOGoMailBaseObject + -isInDraftsFolder]): new method that detects if self is contained + by the drafts folder by calling itself on the container object. + + * SoObjects/Mailer/SOGoMailAccounts.m ([-fetchAllIdentities]): + removed method. + ([-fetchIdentitiesWithEmitterPermissions]): removed method. + ([SOGoMailAccounts -toManyRelationshipKeys]): rewrote method to + return the name of the mail accounts now available with the + -[SOGoUser mailAccounts] method. + + * SoObjects/Mailer/SOGoUser+Mail.[hm]: removed useless class + extension module. + + * SoObjects/Mailer/SOGoMailIdentity.[hm]: removed useless class + module. + + * SoObjects/SOGo/NSArray+Utilities.m ([NSArray + -keysWithFormat:format]): method that forward the method of the + same name to each member of the array, considering they all are + instances of NSDictionary. + ([NSArray -objectsForKey:key]): same principle as above. + ([NSArray -flattenedArray]): new method that transforms an array + of arrays into a single array containing all the elements of the + subarrays. + + * SoObjects/SOGo/NSDictionary+Utilities.m ([NSDictionary + -keysWithFormat:keyFormat]): new method inspired by the python + string formatting system and which replaces occurences of "%{key}" + by the corresponding keys. + 2007-08-13 Wolfgang Sourdeau * Main/SOGo.m ([SOGo -run]): check for channel-type specific diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 7e0c0e6dc..5e7955a7e 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -746,7 +746,8 @@ static NSNumber *sharedYes = nil; privacySqlString = @"and (c_isopaque = 1)"; else { - email = [activeUser primaryEmail]; +#warning we do not manage all the user's possible emails + email = [[activeUser primaryIdentity] objectForKey: @"email"]; privacySqlString = [NSString stringWithFormat: diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 808275d36..be754cf65 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -274,14 +274,12 @@ static BOOL sendEMailNotifications = NO; iCalPerson *person; NSString *newContent; NSException *ex; - NSString *myEMail; ex = nil; component = [self component: NO]; if (component) { - myEMail = [[context activeUser] primaryEmail]; person = [self findParticipantWithUID: owner]; if (person) { diff --git a/SoObjects/Appointments/iCalEntityObject+SOGo.m b/SoObjects/Appointments/iCalEntityObject+SOGo.m index 5b100f9a5..6b67f2da4 100644 --- a/SoObjects/Appointments/iCalEntityObject+SOGo.m +++ b/SoObjects/Appointments/iCalEntityObject+SOGo.m @@ -23,6 +23,7 @@ #import #import +#import #import #import "iCalEntityObject+SOGo.h" @@ -32,12 +33,14 @@ - (BOOL) userIsParticipant: (SOGoUser *) user { NSEnumerator *emails; + NSArray *identities; NSString *currentEmail; BOOL response; response = NO; - emails = [[user allEmails] objectEnumerator]; + identities = [user allIdentities]; + emails = [[identities objectsForKey: @"email"] objectEnumerator]; currentEmail = [emails nextObject]; while (!response && currentEmail) if ([self isParticipant: currentEmail]) @@ -51,12 +54,14 @@ - (BOOL) userIsOrganizer: (SOGoUser *) user { NSEnumerator *emails; + NSArray *identities; NSString *currentEmail; BOOL response; response = NO; - emails = [[user allEmails] objectEnumerator]; + identities = [user allIdentities]; + emails = [[identities objectsForKey: @"email"] objectEnumerator]; currentEmail = [emails nextObject]; while (!response && currentEmail) if ([self isOrganizer: currentEmail]) diff --git a/SoObjects/Mailer/SOGoMailAccount.h b/SoObjects/Mailer/SOGoMailAccount.h index d9bd07513..dff405376 100644 --- a/SoObjects/Mailer/SOGoMailAccount.h +++ b/SoObjects/Mailer/SOGoMailAccount.h @@ -22,7 +22,7 @@ #ifndef __Mailer_SOGoMailAccount_H__ #define __Mailer_SOGoMailAccount_H__ -#include +#import /* SOGoMailAccount @@ -33,41 +33,42 @@ password, etc) */ -@class NSString, NSArray; -@class SOGoMailFolder, SOGoMailIdentity; +@class NSArray; +@class NSString; +@class SOGoDraftsFolder; +@class SOGoMailFolder; @interface SOGoMailAccount : SOGoMailBaseObject { SOGoMailFolder *inboxFolder; + SOGoDraftsFolder *draftsFolder; SOGoMailFolder *sentFolder; SOGoMailFolder *trashFolder; } /* folder pathes */ -- (NSArray *)allFolderPaths; -- (NSArray *)additionalRootFolderNames; /* stuff like filters and drafts */ +- (NSArray *) allFolderPaths; +- (NSArray *) additionalRootFolderNames; /* stuff like filters and drafts */ +- (BOOL) isInDraftsFolder; /* shared accounts */ -- (BOOL)isSharedAccount; -- (NSString *)sharedAccountName; - -/* identity */ - -- (SOGoMailIdentity *)preferredIdentity; +- (BOOL) isSharedAccount; +- (NSString *) sharedAccountName; /* special folders */ -- (NSString *)inboxFolderNameInContext:(id)_ctx; -- (NSString *)draftsFolderNameInContext:(id)_ctx; -- (NSString *)sieveFolderNameInContext:(id)_ctx; -- (NSString *)sentFolderNameInContext:(id)_ctx; -- (NSString *)trashFolderNameInContext:(id)_ctx; +- (NSString *) inboxFolderNameInContext: (id)_ctx; +- (NSString *) draftsFolderNameInContext: (id)_ctx; +- (NSString *) sieveFolderNameInContext: (id)_ctx; +- (NSString *) sentFolderNameInContext: (id)_ctx; +- (NSString *) trashFolderNameInContext: (id)_ctx; -- (SOGoMailFolder *)inboxFolderInContext:(id)_ctx; -- (SOGoMailFolder *)sentFolderInContext:(id)_ctx; -- (SOGoMailFolder *)trashFolderInContext:(id)_ctx; +- (SOGoMailFolder *) inboxFolderInContext: (id)_ctx; +- (SOGoDraftsFolder *) draftsFolderInContext: (id)_ctx; +- (SOGoMailFolder *) sentFolderInContext: (id)_ctx; +- (SOGoMailFolder *) trashFolderInContext: (id)_ctx; /* user defaults */ - (NSString *) sharedFolderName; diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index 93927275b..bf2a7a587 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -35,23 +35,23 @@ #import "SOGoMailFolder.h" #import "SOGoMailManager.h" #import "SOGoDraftsFolder.h" -#import "SOGoUser+Mail.h" #import "SOGoMailAccount.h" @implementation SOGoMailAccount -static NSArray *rootFolderNames = nil; -static NSString *inboxFolderName = @"INBOX"; -static NSString *draftsFolderName = @"Drafts"; -static NSString *sieveFolderName = @"Filters"; +static NSArray *rootFolderNames = nil; +static NSString *inboxFolderName = @"INBOX"; +static NSString *draftsFolderName = @"Drafts"; +static NSString *sieveFolderName = @"Filters"; static NSString *sentFolderName = nil; static NSString *trashFolderName = nil; -static NSString *sharedFolderName = @""; // TODO: add English default +static NSString *sharedFolderName = @""; // TODO: add English default static NSString *otherUsersFolderName = @""; // TODO: add English default -static BOOL useAltNamespace = NO; +static BOOL useAltNamespace = NO; -+ (void)initialize { ++ (void) initialize +{ NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSString *cfgDraftsFolderName; @@ -82,22 +82,43 @@ static BOOL useAltNamespace = NO; NSLog(@"Note: using shared-folders name: '%@'", sharedFolderName); NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName); - if ([ud boolForKey:@"SOGoEnableSieveFolder"]) { + if ([ud boolForKey: @"SOGoEnableSieveFolder"]) rootFolderNames = [[NSArray alloc] initWithObjects: draftsFolderName, sieveFolderName, nil]; - } - else { + else rootFolderNames = [[NSArray alloc] initWithObjects: draftsFolderName, nil]; - } +} + +- (id) init +{ + if ((self = [super init])) + { + inboxFolder = nil; + draftsFolder = nil; + sentFolder = nil; + trashFolder = nil; + } + + return self; +} + +- (void) dealloc +{ + [inboxFolder release]; + [draftsFolder release]; + [sentFolder release]; + [trashFolder release]; + [super dealloc]; } /* shared accounts */ -- (BOOL)isSharedAccount { +- (BOOL) isSharedAccount +{ NSString *s; NSRange r; @@ -110,23 +131,29 @@ static BOOL useAltNamespace = NO; return [s rangeOfString:@".-."].length > 0 ? YES : NO; } -- (NSString *)sharedAccountName { +- (NSString *) sharedAccountName +{ return nil; } /* listing the available folders */ -- (NSArray *)additionalRootFolderNames { +- (NSArray *) additionalRootFolderNames +{ return rootFolderNames; } +- (BOOL) isInDraftsFolder +{ + return NO; +} + - (NSArray *) toManyRelationshipKeys { NSMutableArray *folders; NSArray *imapFolders, *additionalFolders; - folders = [NSMutableArray new]; - [folders autorelease]; + folders = [NSMutableArray array]; imapFolders = [[self imap4Connection] subfoldersForURL: [self imap4URL]]; additionalFolders = [self additionalRootFolderNames]; @@ -141,16 +168,10 @@ static BOOL useAltNamespace = NO; return folders; } -/* identity */ - -- (SOGoMailIdentity *)preferredIdentity { - return [[context activeUser] primaryMailIdentityForAccount: - [self nameInContainer]]; -} - /* hierarchy */ -- (SOGoMailAccount *)mailAccountFolder { +- (SOGoMailAccount *) mailAccountFolder +{ return self; } @@ -175,11 +196,13 @@ static BOOL useAltNamespace = NO; /* IMAP4 */ -- (BOOL)useSSL { +- (BOOL) useSSL +{ return NO; } -- (NSString *)imap4LoginFromHTTP { +- (NSString *) imap4LoginFromHTTP +{ WORequest *rq; NSString *s; NSArray *creds; @@ -231,21 +254,29 @@ static BOOL useAltNamespace = NO; /* name lookup */ -- (id)lookupFolder:(NSString *)_key ofClassNamed:(NSString *)_cn - inContext:(id)_cx +- (id) lookupFolder: (NSString *) _key + ofClassNamed: (NSString *) _cn + inContext: (id) _cx { Class clazz; + SOGoMailFolder *folder; - if ((clazz = NSClassFromString(_cn)) == Nil) { - [self logWithFormat:@"ERROR: did not find class '%@' for key: '%@'", + if ((clazz = NSClassFromString(_cn)) == Nil) + { + [self logWithFormat:@"ERROR: did not find class '%@' for key: '%@'", _cn, _key]; - return [NSException exceptionWithHTTPStatus:500 /* server error */ - reason:@"did not find mail folder class!"]; - } - return [[[clazz alloc] initWithName:_key inContainer:self] autorelease]; + return [NSException exceptionWithHTTPStatus:500 /* server error */ + reason:@"did not find mail folder class!"]; + } + + folder = [clazz objectWithName: _key inContainer: self]; + + return folder; } -- (id)lookupImap4Folder:(NSString *)_key inContext:(id)_cx { +- (id) lookupImap4Folder: (NSString *) _key + inContext: (id) _cx +{ NSString *s; s = [_key isEqualToString: [self trashFolderNameInContext:_cx]] @@ -254,11 +285,15 @@ static BOOL useAltNamespace = NO; return [self lookupFolder:_key ofClassNamed:s inContext:_cx]; } -- (id)lookupDraftsFolder:(NSString *)_key inContext:(id)_ctx { - return [self lookupFolder:_key ofClassNamed:@"SOGoDraftsFolder" - inContext:_ctx]; +- (id) lookupDraftsFolder: (NSString *) _key + inContext: (id) _ctx +{ + return [self lookupFolder: _key ofClassNamed: @"SOGoDraftsFolder" + inContext: _ctx]; } -- (id)lookupFiltersFolder:(NSString *)_key inContext:(id)_ctx { + +- (id) lookupFiltersFolder: (NSString *) _key inContext: (id) _ctx +{ return [self lookupFolder:_key ofClassNamed:@"SOGoSieveScriptsFolder" inContext:_ctx]; } @@ -332,6 +367,29 @@ static BOOL useAltNamespace = NO; return inboxFolder; } +- (SOGoDraftsFolder *) draftsFolderInContext: (id) _ctx +{ + SOGoMailFolder *lookupFolder; + // TODO: use some profile to determine real location, use a -traverse lookup + + if (!draftsFolder) + { + lookupFolder = (useAltNamespace + ? (id) self + : [self inboxFolderInContext:_ctx]); + if (![lookupFolder isKindOfClass: [NSException class]]) + draftsFolder + = [lookupFolder lookupName: [self draftsFolderNameInContext:_ctx] + inContext: _ctx acquire: NO]; + if (![draftsFolder isNotNull]) + draftsFolder = [NSException exceptionWithHTTPStatus: 404 /* not found */ + reason: @"did not find Drafts folder!"]; + [draftsFolder retain]; + } + + return draftsFolder; +} + - (SOGoMailFolder *) sentFolderInContext: (id) _ctx { SOGoMailFolder *lookupFolder; diff --git a/SoObjects/Mailer/SOGoMailAccounts.h b/SoObjects/Mailer/SOGoMailAccounts.h index 3bccf9087..96475f7ac 100644 --- a/SoObjects/Mailer/SOGoMailAccounts.h +++ b/SoObjects/Mailer/SOGoMailAccounts.h @@ -22,7 +22,7 @@ #ifndef __Mailer_SOGoMailAccounts_H__ #define __Mailer_SOGoMailAccounts_H__ -#include +#import /* SOGoMailAccounts @@ -40,11 +40,6 @@ @class NSArray; @interface SOGoMailAccounts : SOGoObject -{ -} - -- (NSArray *)fetchAllIdentities; -- (NSArray *)fetchIdentitiesWithEmitterPermissions; @end diff --git a/SoObjects/Mailer/SOGoMailAccounts.m b/SoObjects/Mailer/SOGoMailAccounts.m index 71d4f0b8c..09a8cfd64 100644 --- a/SoObjects/Mailer/SOGoMailAccounts.m +++ b/SoObjects/Mailer/SOGoMailAccounts.m @@ -26,7 +26,8 @@ #import #import -#import "SOGoUser+Mail.h" +#import "../SOGo/NSArray+Utilities.h" +#import "../SOGo/SOGoUser.h" #import "SOGoMailAccounts.h" @@ -38,72 +39,28 @@ static NSString *AgenorShareLoginMarker = @".-."; - (BOOL) isInHomeFolderBranchOfLoggedInAccount: (NSString *) userLogin { - return [[[self container] nameInContainer] isEqualToString: userLogin]; + return [[container nameInContainer] isEqualToString: userLogin]; } -- (NSArray *)toManyRelationshipKeys { - SOGoUser *user; - id account; -// NSArray *shares; - NSString *userLogin; - - /* - Note: this is not strictly correct. The accounts being retrieved should be - the accounts based on the container object of this folder. Given - sufficient rights (eg delegation rights!), this would allow you to - browse the hierarchies of other users. - - But then, the home-folder would need to know about mail - functionality which isn't perfect either. - => TODO - */ - user = [context activeUser]; - userLogin = [user login]; - - /* for now: return nothing if the home-folder does not belong to the login */ - if (![self isInHomeFolderBranchOfLoggedInAccount: userLogin]) { - [self warnWithFormat:@"User %@ tried to access mail hierarchy of %@", - [user login], [[self container] nameInContainer]]; - return nil; - } - - account = [user primaryIMAP4AccountString]; - if ([account isNotNull]) account = [NSArray arrayWithObject:account]; - - return account; -// shares = [user valueForKey:@"additionalIMAP4AccountStrings"] -// return ([shares count] == 0) -// ? account -// : [account arrayByAddingObjectsFromArray:shares]; -} - -- (NSArray *) fetchIdentitiesWithOnlyEmitterAccess: (BOOL) _flag +- (NSArray *) toManyRelationshipKeys { - NSString *accountString; + NSArray *accounts; - accountString = [[context activeUser] primaryIMAP4AccountString]; + accounts = [[context activeUser] mailAccounts]; - return [NSArray arrayWithObject: accountString]; -} - -- (NSArray *)fetchAllIdentities { - return [self fetchIdentitiesWithOnlyEmitterAccess:NO]; -} - -- (NSArray *)fetchIdentitiesWithEmitterPermissions { - return [self fetchIdentitiesWithOnlyEmitterAccess:YES]; + return [accounts objectsForKey: @"name"]; } /* name lookup */ -- (BOOL)isValidMailAccountName:(NSString *)_key { - if ([_key length] == 0) - return NO; - - return YES; +- (BOOL) isValidMailAccountName: (NSString *) _key +{ + return ([_key length] > 0); } -- (id)mailAccountWithName:(NSString *)_key inContext:(id)_ctx { +- (id) mailAccountWithName: (NSString *) _key + inContext: (id) _ctx +{ static Class ctClass = Nil; id ct; @@ -118,22 +75,22 @@ static NSString *AgenorShareLoginMarker = @".-."; return [ct autorelease]; } -- (id)sharedMailAccountWithName:(NSString *)_key inContext:(id)_ctx { +- (id) sharedMailAccountWithName: (NSString *) _key + inContext: (id) _ctx +{ static Class ctClass = Nil; - id ct; - + + if (ctClass == Nil) + ctClass = NSClassFromString (@"SOGoSharedMailAccount"); if (ctClass == Nil) - ctClass = NSClassFromString(@"SOGoSharedMailAccount"); - if (ctClass == Nil) { [self errorWithFormat:@"missing SOGoSharedMailAccount class!"]; - return nil; - } - ct = [[ctClass alloc] initWithName:_key inContainer:self]; - return [ct autorelease]; + return [ctClass objectWithName: _key inContainer: self]; } -- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag +- (id) lookupName: (NSString *) _key + inContext: (id) _ctx + acquire: (BOOL) _flag { id obj; NSString *userLogin; @@ -145,8 +102,8 @@ static NSString *AgenorShareLoginMarker = @".-."; return obj; if (![self isInHomeFolderBranchOfLoggedInAccount: userLogin]) { - [self warnWithFormat:@"User %@ tried to access mail hierarchy of %@", - userLogin, [[self container] nameInContainer]]; + [self warnWithFormat:@ "User %@ tried to access mail hierarchy of %@", + userLogin, [container nameInContainer]]; return [NSException exceptionWithHTTPStatus:403 /* Forbidden */ reason:@"Tried to access the mail of another user"]; diff --git a/SoObjects/Mailer/SOGoMailBaseObject.h b/SoObjects/Mailer/SOGoMailBaseObject.h index d22317868..ec2d8baaa 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.h +++ b/SoObjects/Mailer/SOGoMailBaseObject.h @@ -48,30 +48,32 @@ NGImap4Connection *imap4; } -- (id)initWithImap4URL:(NSURL *)_url inContainer:(id)_container; +- (id) initWithImap4URL: (NSURL *) _url + inContainer: (id) _container; /* hierarchy */ -- (SOGoMailAccount *)mailAccountFolder; -- (SOGoMailAccounts *)mailAccountsFolder; +- (SOGoMailAccount *) mailAccountFolder; +- (SOGoMailAccounts *) mailAccountsFolder; +- (BOOL) isInDraftsFolder; /* IMAP4 */ -- (NGImap4Connection *)imap4Connection; -- (NGImap4ConnectionManager *)mailManager; +- (NGImap4Connection *) imap4Connection; +- (NGImap4ConnectionManager *) mailManager; - (NSString *) relativeImap4Name; - (NSMutableString *) imap4URLString; -- (NSURL *)imap4URL; -- (NSString *)imap4Login; -- (NSString *)imap4Password; +- (NSURL *) imap4URL; +- (NSString *) imap4Login; +- (NSString *) imap4Password; -- (void)flushMailCaches; +- (void) flushMailCaches; /* IMAP4 names */ -- (BOOL)isBodyPartKey:(NSString *)_key inContext:(id)_ctx; +- (BOOL) isBodyPartKey: (NSString *) _key inContext: (id) _ctx; @end diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index 91d3c8d88..a317c44db 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -95,6 +95,11 @@ static BOOL debugOn = YES; return o; } +- (BOOL) isInDraftsFolder +{ + return [container isInDraftsFolder]; +} + /* IMAP4 */ - (NGImap4ConnectionManager *) mailManager diff --git a/SoObjects/Mailer/SOGoMailIdentity.h b/SoObjects/Mailer/SOGoMailIdentity.h deleted file mode 100644 index c340fdee2..000000000 --- a/SoObjects/Mailer/SOGoMailIdentity.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (C) 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 __Mailer_SOGoMailIdentity_H__ -#define __Mailer_SOGoMailIdentity_H__ - -#import - -/* - SOGoMailIdentity - - A user identity bound to an account. - - Note: currently this is not a SoObject. This might change later on. - - - In Thunderbird you have a set of accounts which in turn have a set of - identities. There is one default identity. - - The identities then have: - - settings - - a name - - a from-email - - a reply-to - - an organization - - a signature - - a vcard (to be attached) - - folder settings - - Sent-Folder and bcc - - Drafts + Templates - - composition - - whether to use HTML - - whether to quote the source message (reply below, above the quote or - select the quote) -*/ - -@class NSString; - -@interface SOGoMailIdentity : NSObject -{ - NSString *name; - NSString *email; - NSString *replyTo; - NSString *organization; - NSString *signature; - NSString *vCard; - NSString *sentFolderName; - NSString *sentBCC; - NSString *draftsFolderName; - NSString *templatesFolderName; - struct { - int composeHTML:1; - int reserved:31; - } idFlags; -} - -/* accessors */ - -- (void)setName:(NSString *)_value; -- (NSString *)name; - -- (void)setEmail:(NSString *)_value; -- (NSString *)email; - -- (void)setReplyTo:(NSString *)_value; -- (NSString *)replyTo; - -- (void)setOrganization:(NSString *)_value; -- (NSString *)organization; - -- (void)setSignature:(NSString *)_value; -- (NSString *)signature; -- (BOOL)hasSignature; - -- (void)setVCard:(NSString *)_value; -- (NSString *)vCard; -- (BOOL)hasVCard; - -- (void)setSentFolderName:(NSString *)_value; -- (NSString *)sentFolderName; - -- (void)setSentBCC:(NSString *)_value; -- (NSString *)sentBCC; - -- (void)setDraftsFolderName:(NSString *)_value; -- (NSString *)draftsFolderName; - -- (void)setTemplatesFolderName:(NSString *)_value; -- (NSString *)templatesFolderName; - -@end - -#endif /* __Mailer_SOGoMailIdentity_H__ */ diff --git a/SoObjects/Mailer/SOGoMailIdentity.m b/SoObjects/Mailer/SOGoMailIdentity.m deleted file mode 100644 index 424d08918..000000000 --- a/SoObjects/Mailer/SOGoMailIdentity.m +++ /dev/null @@ -1,143 +0,0 @@ -/* - Copyright (C) 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 "SOGoMailIdentity.h" - -@implementation SOGoMailIdentity - -- (void)dealloc { - [name release]; - [email release]; - [replyTo release]; - [organization release]; - [signature release]; - [vCard release]; - [sentFolderName release]; - [sentBCC release]; - [draftsFolderName release]; - [templatesFolderName release]; - [super dealloc]; -} - -/* accessors */ - -- (void)setName:(NSString *)_value { - ASSIGNCOPY(name, _value); -} -- (NSString *)name { - return name; -} - -- (void)setEmail:(NSString *)_value { - ASSIGNCOPY(email, _value); -} -- (NSString *)email { - return email; -} - -- (void)setReplyTo:(NSString *)_value { - ASSIGNCOPY(replyTo, _value); -} -- (NSString *)replyTo { - return replyTo; -} - -- (void)setOrganization:(NSString *)_value { - ASSIGNCOPY(organization, _value); -} -- (NSString *)organization { - return organization; -} - -- (void)setSignature:(NSString *)_value { - ASSIGNCOPY(signature, _value); -} -- (NSString *)signature { - return signature; -} -- (BOOL)hasSignature { - return [[self signature] isNotEmpty]; -} - -- (void)setVCard:(NSString *)_value { - ASSIGNCOPY(vCard, _value); -} -- (NSString *)vCard { - return vCard; -} -- (BOOL)hasVCard { - return [[self vCard] isNotEmpty]; -} - -- (void)setSentFolderName:(NSString *)_value { - ASSIGNCOPY(sentFolderName, _value); -} -- (NSString *)sentFolderName { - return sentFolderName; -} - -- (void)setSentBCC:(NSString *)_value { - ASSIGNCOPY(sentBCC, _value); -} -- (NSString *)sentBCC { - return sentBCC; -} - -- (void)setDraftsFolderName:(NSString *)_value { - ASSIGNCOPY(draftsFolderName, _value); -} -- (NSString *)draftsFolderName { - return draftsFolderName; -} - -- (void)setTemplatesFolderName:(NSString *)_value { - ASSIGNCOPY(templatesFolderName, _value); -} -- (NSString *)templatesFolderName { - return templatesFolderName; -} - -/* description */ - -- (NSString *)description { - NSMutableString *ms; - - ms = [NSMutableString stringWithCapacity:128]; - [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; - - if (name != nil) [ms appendFormat:@" name='%@'", name]; - if (email != nil) [ms appendFormat:@" email='%@'", email]; - - if (sentFolderName != nil) - [ms appendFormat:@" sent='%@'", sentFolderName]; - - if ([sentBCC length] > 0) [ms appendString:@" sent-bcc"]; - if ([vCard length] > 0) [ms appendString:@" vcard"]; - - [ms appendString:@">"]; - return ms; -} - -@end /* SOGoMailIdentity */ diff --git a/SoObjects/Mailer/SOGoMailObject+Draft.h b/SoObjects/Mailer/SOGoMailObject+Draft.h new file mode 100644 index 000000000..5da1cdaee --- /dev/null +++ b/SoObjects/Mailer/SOGoMailObject+Draft.h @@ -0,0 +1,38 @@ +/* SOGoMailObject+Draft.h - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOMAILOBJECT_DRAFT_H +#define SOGOMAILOBJECT_DRAFT_H + +#import "SOGoMailObject.h" + +@interface SOGoMailObject (SOGoDraftObjectExtensions) + +- (NSString *) subjectForReply; +- (NSString *) contentForReply; + +- (NSString *) subjectForForward; +- (NSString *) filenameForForward; + +@end + +#endif /* SOGOMAILOBJECT_DRAFT_H */ diff --git a/SoObjects/Mailer/SOGoMailObject+Draft.m b/SoObjects/Mailer/SOGoMailObject+Draft.m new file mode 100644 index 000000000..a5d8da062 --- /dev/null +++ b/SoObjects/Mailer/SOGoMailObject+Draft.m @@ -0,0 +1,205 @@ +/* SOGoMailObject+Draft.m - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import +#import + +#import "SOGoMailObject+Draft.h" + +#define maxFilenameLength 64 + +@implementation SOGoMailObject (SOGoDraftObjectExtensions) + +- (NSString *) subjectForReply +{ + static NSString *replyPrefixes[] = { + @"Re:", // regular + @"RE:", // Outlook v11 (English?) + @"AW:", // German Outlook v11 + @"Re[", // numbered Re, eg "Re[2]:" + nil + }; + BOOL hasPrefix; + unsigned int i; + NSString *subject, *newSubject; + + hasPrefix = NO; + + subject = [[self envelope] subject]; + i = 0; + while (!hasPrefix && replyPrefixes[i]) + if ([subject hasPrefix: replyPrefixes[i]]) + hasPrefix = YES; + else + i++; + + if (hasPrefix) + newSubject = subject; + else + newSubject = [NSString stringWithFormat: @"Re: %@", subject]; + + return newSubject; +} + +- (NSString *) contentForReplyOnParts: (NSDictionary *) _prts + keys: (NSArray *) _k +{ + static NSString *textPartSeparator = @"\n---\n"; + NSMutableString *ms; + unsigned int count, max; + NSString *k, *v; + + ms = [NSMutableString stringWithCapacity: 16000]; + + max = [_k count]; + for (count = 0; count < max; count++) + { + k = [_k objectAtIndex: count]; + + // 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]] + && [v length] > 0) + { + if (count > 0) + [ms appendString: textPartSeparator]; + [ms appendString: [v stringByApplyingMailQuoting]]; + } + else + [self logWithFormat:@"Note: cannot show part %@", k]; + } + + return ms; +} + +#warning this method should be fixed to return the first available text/plain \ + part, and otherwise the first text/html part converted to text +- (NSString *) contentForReply +{ + NSArray *keys; + NSDictionary *parts; + NSMutableArray *topLevelKeys = nil; + unsigned int count, max; + NSRange r; + NSString *contentForReply; + +// SOGoMailObject *co; + +// co = self; +// keys = [co plainTextContentFetchKeys]; +// infos = [co fetchCoreInfos]; +// partInfos = [infos objectForKey: keys]; +// NSLog (@"infos: '%@'", infos); + + keys = [self plainTextContentFetchKeys]; + max = [keys count]; + if (max > 0) + { + if (max > 1) + { + /* filter keys, only include top-level, or if none, the first */ + for (count = 0; count < max; count++) + { + r = [[keys objectAtIndex: count] rangeOfString: @"."]; + if (!r.length) + { + if (!topLevelKeys) + topLevelKeys = [NSMutableArray arrayWithCapacity: 4]; + [topLevelKeys addObject: [keys objectAtIndex: count]]; + } + } + + 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 fetchPlainTextStrings: keys]; + contentForReply = [self contentForReplyOnParts: parts + keys: keys]; + } + else + contentForReply = nil; + + return contentForReply; +} + +- (NSString *) filenameForForward +{ + NSString *subject; + NSMutableString *newSubject; + static NSString *sescape[] = { + @"/", @"..", @"~", @"\"", @"'", @" ", @".", nil + }; + unsigned int count, length; + + subject = [[self envelope] subject]; + length = [subject length]; + if (!length) + { + subject = @"forward"; + length = [subject length]; + } + + if (length > maxFilenameLength) + length = maxFilenameLength; + newSubject = [NSMutableString + stringWithString: [subject substringToIndex: length]]; + count = 0; + while (sescape[count]) + { + [newSubject replaceString: sescape[count] + withString: @"_"]; + count++; + } + [newSubject appendString: @".eml"]; + + return newSubject; +} + +- (NSString *) subjectForForward +{ + NSString *subject, *newSubject; + + subject = [[self envelope] subject]; + if ([subject length] > 0) + newSubject = [NSString stringWithFormat: @"[Fwd: %@]", subject]; + else + newSubject = subject; + + return newSubject; +} + +@end diff --git a/SoObjects/Mailer/SOGoMailObject.h b/SoObjects/Mailer/SOGoMailObject.h index 72dae3885..2dd21d42b 100644 --- a/SoObjects/Mailer/SOGoMailObject.h +++ b/SoObjects/Mailer/SOGoMailObject.h @@ -86,7 +86,7 @@ /* deletion */ - (BOOL)isDeletionAllowed; -- (NSException *)trashInContext:(id)_ctx; +- (NSException *) trashInContext:(id)_ctx; - (NSException *) moveToFolderNamed: (NSString *) folderName inContext: (id)_ctx; diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index 5eb140692..9868fc80e 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -134,7 +134,8 @@ static BOOL debugSoParts = NO; /* part hierarchy */ -- (NSString *)keyExtensionForPart:(id)_partInfo { +- (NSString *) keyExtensionForPart: (id) _partInfo +{ NSString *mt, *st; if (_partInfo == nil) @@ -200,7 +201,8 @@ static BOOL debugSoParts = NO; /* message */ -- (id)fetchParts:(NSArray *)_parts { +- (id) fetchParts: (NSArray *) _parts +{ // TODO: explain what it does /* Called by -fetchPlainTextParts: diff --git a/SoObjects/Mailer/SOGoUser+Mail.h b/SoObjects/Mailer/SOGoUser+Mail.h deleted file mode 100644 index 432de0f1d..000000000 --- a/SoObjects/Mailer/SOGoUser+Mail.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright (C) 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 __Mailer_SOGoUser_Mail_H__ -#define __Mailer_SOGoUser_Mail_H__ - -#include - -/* - SOGoUser(Mail) - - TODO: document - - This category adds mail related stuff to the SOGo user class. -*/ - -#include - -@class NSArray; -@class SOGoMailIdentity; - -@interface SOGoUser(Mail) - -- (SOGoMailIdentity *)primaryMailIdentity; -- (NSArray *)fetchAllMailIdentitiesWithOnlyEmitterAccess:(BOOL)_onlyGC; -- (SOGoMailIdentity *)primaryMailIdentityForAccount:(NSString *)_account; - -@end - -#endif /* __Mailer_SOGoUser_Mail_H__ */ diff --git a/SoObjects/Mailer/SOGoUser+Mail.m b/SoObjects/Mailer/SOGoUser+Mail.m deleted file mode 100644 index 2cde83986..000000000 --- a/SoObjects/Mailer/SOGoUser+Mail.m +++ /dev/null @@ -1,146 +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 "SOGoMailIdentity.h" - -#import "SOGoUser+Mail.h" - -@implementation SOGoUser(Mail) - -- (NSString *)agenorSentFolderName { - /* Note: specialty: the Sent folder is called the same in all accounts */ - static NSString *s = nil; - if (s == nil) { - NSUserDefaults *ud; - - ud = [NSUserDefaults standardUserDefaults]; - s = [[ud stringForKey:@"SOGoSentFolderName"] copy]; - if (![s isNotEmpty]) s = @"Sent"; - [self logWithFormat:@"Note: using SOGoSentFolderName: '%@'", s]; - } - return s; -} - -- (NSString *)agenorSentFolderForAccount:(NSString *)_account { - // TODO: support different locations for shares! - NSString *p; - - if (![_account isNotEmpty]) - return nil; - - // if ([_account rangeOfString:@".-."].length == 0) - // TODO: check whether we need special handling for shares! - p = [_account stringByAppendingString:@"/"]; - p = [p stringByAppendingString:[self agenorSentFolderName]]; - return p; -} - -- (SOGoMailIdentity *)primaryMailIdentity { - SOGoMailIdentity *identity; - NSString *account; - - account = [self valueForKey:@"primaryIMAP4AccountString"]; - - identity = [[[SOGoMailIdentity alloc] init] autorelease]; - [identity setName: [self cn]]; - [identity setEmail: [self primaryEmail]]; - [identity setSentFolderName:[self agenorSentFolderForAccount:account]]; - return identity; -} - -- (SOGoMailIdentity *)mailIdentityForAccount:(NSString *)_account - emitter:(NSString *)_em -{ - SOGoMailIdentity *identity; - - identity = [[[SOGoMailIdentity alloc] init] autorelease]; - [identity setName:[self cn]]; // TODO: should we use something else? - if ([_em isNotEmpty]) [identity setEmail:_em]; - [identity setSentFolderName:[self agenorSentFolderForAccount:_account]]; - return identity; -} - -- (NSArray *)fetchAllMailIdentitiesWithOnlyEmitterAccess:(BOOL)_onlyGC { - NSMutableArray *identities; - NSEnumerator *accounts; - NSDictionary *shares; - NSString *account; - id identity; - - identity = [self primaryMailIdentity]; - shares = [self valueForKey:@"additionalIMAP4AccountsAndEMails"]; - if ([shares count] == 0) - return [NSArray arrayWithObject: identity]; - - identities = [NSMutableArray arrayWithCapacity:[shares count] + 1]; - if (identity != nil) [identities addObject:identity]; - - accounts = [shares keyEnumerator]; - while ((account = [accounts nextObject]) != nil) { - NSString *emitter; - - emitter = [shares objectForKey:account]; - if (_onlyGC && ![emitter isNotNull]) continue; - - identity = [self mailIdentityForAccount:account emitter:emitter]; - if (identity != nil) - [identities addObject:identity]; - } - - return identities; -} - -- (SOGoMailIdentity *)primaryMailIdentityForAccount:(NSString *)_account { - NSEnumerator *accounts; - NSDictionary *shares; - NSString *account; - id identity; - - identity = [self primaryMailIdentity]; - shares = [self valueForKey:@"additionalIMAP4AccountsAndEMails"]; - if ([shares count] == 0) - return identity; - - /* scan shares for ID */ - accounts = [shares keyEnumerator]; - while ((account = [accounts nextObject]) != nil) { - NSString *emitter; - - if (![account isEqualToString:_account]) - continue; - - emitter = [shares objectForKey:account]; - identity = [self mailIdentityForAccount:_account emitter:emitter]; - if ([identity isNotNull]) - return identity; - } - - return identity; -} - -@end /* SOGoUser(Mail) */ diff --git a/SoObjects/SOGo/NSArray+Utilities.h b/SoObjects/SOGo/NSArray+Utilities.h index b330cf854..181f636cd 100644 --- a/SoObjects/SOGo/NSArray+Utilities.h +++ b/SoObjects/SOGo/NSArray+Utilities.h @@ -32,6 +32,9 @@ - (NSString *) jsonRepresentation; - (NSArray *) stringsWithFormat: (NSString *) format; +- (NSArray *) keysWithFormat: (NSString *) format; +- (NSArray *) objectsForKey: (NSString *) key; +- (NSArray *) flattenedArray; - (BOOL) containsCaseInsensitiveString: (NSString *) match; diff --git a/SoObjects/SOGo/NSArray+Utilities.m b/SoObjects/SOGo/NSArray+Utilities.m index 77dabdcbd..4845b33df 100644 --- a/SoObjects/SOGo/NSArray+Utilities.m +++ b/SoObjects/SOGo/NSArray+Utilities.m @@ -33,6 +33,7 @@ id currentObject; formattedStrings = [NSMutableArray arrayWithCapacity: [self count]]; + objects = [self objectEnumerator]; currentObject = [objects nextObject]; while (currentObject) @@ -45,6 +46,61 @@ return formattedStrings; } +- (NSArray *) keysWithFormat: (NSString *) format +{ + NSMutableArray *formattedStrings; + NSEnumerator *objects; + id currentObject; + + formattedStrings = [NSMutableArray arrayWithCapacity: [self count]]; + + objects = [self objectEnumerator]; + currentObject = [objects nextObject]; + while (currentObject) + { + [formattedStrings addObject: [currentObject keysWithFormat: format]]; + currentObject = [objects nextObject]; + } + + return formattedStrings; +} + +- (NSArray *) objectsForKey: (NSString *) key +{ + NSMutableArray *objectsForKey; + unsigned int count, max; + id value; + + max = [self count]; + objectsForKey = [NSMutableArray arrayWithCapacity: max]; + + for (count = 0; count < max; count++) + { + value = [[self objectAtIndex: count] objectForKey: key]; + [objectsForKey addObject: value]; + } + + return objectsForKey; +} + +- (NSArray *) flattenedArray +{ + NSMutableArray *flattenedArray; + NSEnumerator *objects; + id currentObject; + + flattenedArray = [NSMutableArray array]; + objects = [self objectEnumerator]; + currentObject = [objects nextObject]; + while (currentObject) + { + [flattenedArray addObjectsFromArray: currentObject]; + currentObject = [objects nextObject]; + } + + return flattenedArray; +} + - (void) makeObjectsPerform: (SEL) selector withObject: (id) object1 withObject: (id) object2 diff --git a/SoObjects/SOGo/NSDictionary+Utilities.h b/SoObjects/SOGo/NSDictionary+Utilities.h index df40a3427..bc054c813 100644 --- a/SoObjects/SOGo/NSDictionary+Utilities.h +++ b/SoObjects/SOGo/NSDictionary+Utilities.h @@ -30,6 +30,7 @@ @interface NSDictionary (SOGoDictionaryUtilities) - (NSString *) jsonRepresentation; +- (NSString *) keysWithFormat: (NSString *) keyFormat; @end diff --git a/SoObjects/SOGo/NSDictionary+Utilities.m b/SoObjects/SOGo/NSDictionary+Utilities.m index 5b21ce2c9..6caaeaa67 100644 --- a/SoObjects/SOGo/NSDictionary+Utilities.m +++ b/SoObjects/SOGo/NSDictionary+Utilities.m @@ -23,6 +23,7 @@ #import #import +#import "NSArray+Utilities.h" #import "NSObject+Utilities.h" #import "NSDictionary+Utilities.h" @@ -52,4 +53,27 @@ return representation; } +- (NSString *) keysWithFormat: (NSString *) keyFormat +{ + NSArray *keys, *allKeys; + unsigned int count, max; + NSMutableString *keysWithFormat; + id value; + + keysWithFormat = [NSMutableString stringWithString: keyFormat]; + + allKeys = [self allKeys]; + keys = [allKeys stringsWithFormat: @"%{%@}"]; + + max = [allKeys count]; + for (count = 0; count < max; count++) + { + value = [self objectForKey: [allKeys objectAtIndex: count]]; + [keysWithFormat replaceString: [keys objectAtIndex: count] + withString: [value description]]; + } + + return keysWithFormat; +} + @end diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 5b6f5d2c2..d6676c0e5 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -23,8 +23,10 @@ #import #import +#import #import #import +#import #import #import @@ -134,10 +136,7 @@ static NSString *defaultUserID = @""; static GCSFolderManager *folderManager = nil; if (!folderManager) - { - folderManager = [GCSFolderManager defaultFolderManager]; - [folderManager setFolderNamePrefix: @"SOGo"]; - } + folderManager = [GCSFolderManager defaultFolderManager]; return folderManager; } diff --git a/SoObjects/SOGo/SOGoUser.h b/SoObjects/SOGo/SOGoUser.h index 7d6816424..5d4bd9ad3 100644 --- a/SoObjects/SOGo/SOGoUser.h +++ b/SoObjects/SOGo/SOGoUser.h @@ -58,6 +58,7 @@ extern NSString *SOGoWeekStartFirstFullWeek; NSUserDefaults *userSettings; NSTimeZone *userTimeZone; SOGoDateFormatter *dateFormatter; + NSMutableArray *mailAccounts; } + (SOGoUser *) userWithLogin: (NSString *) login @@ -67,11 +68,11 @@ extern NSString *SOGoWeekStartFirstFullWeek; /* properties */ -- (NSString *) fullEmail; +// - (NSString *) fullEmail; -- (NSString *) primaryEmail; -- (NSString *) systemEmail; -- (NSArray *) allEmails; +// - (NSString *) primaryEmail; +// - (NSString *) systemEmail; +// - (NSArray *) allEmails; - (BOOL) hasEmail: (NSString *) email; @@ -82,7 +83,7 @@ extern NSString *SOGoWeekStartFirstFullWeek; /* shares and identities */ -- (NSString *) primaryIMAP4AccountString; +// - (NSString *) primaryIMAP4AccountString; // - (NSString *) primaryIMAP4AccountString; // - (NSString *) primaryMailServer; @@ -99,6 +100,10 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (NSTimeZone *) timeZone; - (NSTimeZone *) serverTimeZone; +- (NSArray *) mailAccounts; +- (NSArray *) allIdentities; +- (NSDictionary *) primaryIdentity; + /* folders */ - (id) homeFolderInContext: (id) _ctx; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index d212d2c1e..3dc5273a5 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -23,6 +23,7 @@ #import #import #import +#import #import #import #import @@ -189,17 +190,25 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; /* properties */ -- (NSString *) fullEmail -{ - return [[LDAPUserManager sharedUserManager] getFullEmailForUID: login]; -} +// - (NSString *) fullEmail +// { +// return [[LDAPUserManager sharedUserManager] getFullEmailForUID: login]; +// } -- (NSString *) primaryEmail +// - (NSString *) primaryEmail +// { +// if (!allEmails) +// [self _fetchAllEmails]; + +// return [allEmails objectAtIndex: 0]; +// } + +- (NSArray *) allEmails { if (!allEmails) [self _fetchAllEmails]; - return [allEmails objectAtIndex: 0]; + return allEmails; } - (NSString *) systemEmail @@ -210,14 +219,6 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return [allEmails lastObject]; } -- (NSArray *) allEmails -{ - if (!allEmails) - [self _fetchAllEmails]; - - return allEmails; -} - - (BOOL) hasEmail: (NSString *) email { if (!allEmails) @@ -234,11 +235,6 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return cn; } -- (NSString *) primaryIMAP4AccountString -{ - return [NSString stringWithFormat: @"%@@%@", login, fallbackIMAP4Server]; -} - // - (NSString *) primaryMailServer // { // return [[self userManager] getServerForUID: [self login]]; @@ -347,6 +343,115 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; return serverTimeZone; } +/* mail */ +- (NSArray *) mailAccounts +{ +#warning should be implemented with the user defaults interfaces + NSMutableDictionary *mailAccount, *identity; + NSMutableArray *identities; + NSString *name, *fullName; + + if (!mailAccounts) + { + mailAccount = [NSMutableDictionary dictionary]; + name = [NSString stringWithFormat: @"%@@%@", login, fallbackIMAP4Server]; + [mailAccount setObject: login forKey: @"userName"]; + [mailAccount setObject: fallbackIMAP4Server forKey: @"serverName"]; + [mailAccount setObject: name forKey: @"name"]; + + identity = [NSMutableDictionary dictionary]; + fullName = [self cn]; + if (![fullName length]) + fullName = login; + [identity setObject: fullName forKey: @"fullName"]; + [identity setObject: [self systemEmail] forKey: @"email"]; + [identity setObject: [NSNumber numberWithBool: YES] forKey: @"isDefault"]; + + identities = [NSMutableArray array]; + [identities addObject: identity]; + [mailAccount setObject: identities forKey: @"identities"]; + + mailAccounts = [NSMutableArray new]; + [mailAccounts addObject: mailAccount]; + } + + return mailAccounts; +} + +/* +@interface SOGoMailIdentity : NSObject +{ + NSString *name; + NSString *email; + NSString *replyTo; + NSString *organization; + NSString *signature; + NSString *vCard; + NSString *sentFolderName; + NSString *sentBCC; + NSString *draftsFolderName; + NSString *templatesFolderName; + struct + { + int composeHTML:1; + int reserved:31; + } idFlags; +} + +- (void) setName: (NSString *) _value; +- (NSString *) name; + +- (void) setEmail: (NSString *) _value; +- (NSString *) email; + +- (void) setReplyTo: (NSString *) _value; +- (NSString *) replyTo; + +- (void) setOrganization: (NSString *) _value; +- (NSString *) organization; + +- (void) setSignature: (NSString *) _value; +- (NSString *) signature; +- (BOOL) hasSignature; + +- (void) setVCard: (NSString *) _value; +- (NSString *) vCard; +- (BOOL) hasVCard; + +- (void) setSentFolderName: (NSString *) _value; +- (NSString *) sentFolderName; + +- (void) setSentBCC: (NSString *) _value; +- (NSString *) sentBCC; + +- (void) setDraftsFolderName: (NSString *) _value; +- (NSString *) draftsFolderName; + +- (void) setTemplatesFolderName: (NSString *) _value; +- (NSString *) templatesFolderName; + +@end */ + +- (NSArray *) allIdentities +{ + NSArray *identities; + + [self mailAccounts]; + identities = [mailAccounts objectsForKey: @"identities"]; + + return [identities flattenedArray]; +} + +- (NSDictionary *) primaryIdentity +{ + NSDictionary *defaultAccount; + + [self mailAccounts]; + defaultAccount = [mailAccounts objectAtIndex: 0]; + + return [[defaultAccount objectForKey: @"identities"] objectAtIndex: 0]; +} + /* folders */ // TODO: those methods should check whether the traversal stack in the context diff --git a/UI/Common/GNUmakefile b/UI/Common/GNUmakefile index cd4320a21..455202c20 100644 --- a/UI/Common/GNUmakefile +++ b/UI/Common/GNUmakefile @@ -22,7 +22,9 @@ CommonUI_OBJC_FILES += \ UIxTabItem.m \ UIxUserRightsEditor.m \ \ - UIxToolbar.m + UIxToolbar.m \ + \ + WODirectAction+SOGo.m \ CommonUI_RESOURCE_FILES += \ Version \ diff --git a/UI/Common/WODirectAction+SOGo.h b/UI/Common/WODirectAction+SOGo.h new file mode 100644 index 000000000..92ec03206 --- /dev/null +++ b/UI/Common/WODirectAction+SOGo.h @@ -0,0 +1,37 @@ +/* WODirectAction+SOGo.h - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef WODIRECTACTION_SOGO_H +#define WODIRECTACTION_SOGO_H + +#import + +@class NSString; +@class WOResponse; + +@interface WODirectAction (SOGoExtension) + +- (WOResponse *) redirectToLocation: (NSString *) newLocation; + +@end + +#endif /* WODIRECTACTION_SOGO_H */ diff --git a/UI/Common/WODirectAction+SOGo.m b/UI/Common/WODirectAction+SOGo.m new file mode 100644 index 000000000..ddeea2aaa --- /dev/null +++ b/UI/Common/WODirectAction+SOGo.m @@ -0,0 +1,42 @@ +/* WODirectAction+SOGo.m - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#import +#import + +#import "WODirectAction+SOGo.h" + +@implementation WODirectAction (SOGoExtension) + +- (WOResponse *) redirectToLocation: (NSString *) newLocation +{ + WOResponse *response; + + response = [context response]; + [response setStatus: 302 /* moved */]; + [response setHeader: newLocation forKey: @"location"]; + + return response; +} + +@end diff --git a/UI/MailPartViewers/UIxMailPartICalViewer.m b/UI/MailPartViewers/UIxMailPartICalViewer.m index 600a473ad..6e7a690c8 100644 --- a/UI/MailPartViewers/UIxMailPartICalViewer.m +++ b/UI/MailPartViewers/UIxMailPartICalViewer.m @@ -252,8 +252,13 @@ /* organizer tracking */ -- (NSString *)loggedInUserEMail { - return [[[self context] activeUser] primaryEmail]; +- (NSString *) loggedInUserEMail +{ + NSDictionary *identity; + + identity = [[context activeUser] primaryIdentity]; + + return [identity objectForKey: @"email"]; } - (iCalEvent *)authorativeEvent { diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index f253e9c39..01ee00022 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -69,6 +69,8 @@ "Addressbook" = "Addressbook"; "Anais" = "Anais"; +"Edit Draft..." = "Edit Draft..."; + "This mail is being sent from an unsecure network!" = "This mail is being sent from an unsecure network!"; /* Popup "show" */ diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings index 1c6046843..1a48c9016 100644 --- a/UI/MailerUI/French.lproj/Localizable.strings +++ b/UI/MailerUI/French.lproj/Localizable.strings @@ -69,6 +69,8 @@ "cc" = "Cc"; "bcc" = "Cci"; +"Edit Draft..." = "Modifier le brouillon..."; + "This mail is being sent from an unsecure network!" = "Ce mail est envoyé depuis un réseau non sécurisé !"; /* Popup "show" */ diff --git a/UI/MailerUI/Toolbars/SOGoMailObject.toolbar b/UI/MailerUI/Toolbars/SOGoMailObject.toolbar index 8df3661db..ac4ad5a82 100644 --- a/UI/MailerUI/Toolbars/SOGoMailObject.toolbar +++ b/UI/MailerUI/Toolbars/SOGoMailObject.toolbar @@ -10,8 +10,8 @@ { link = "#"; isSafe = NO; image = "tb-mail-write-flat-24x24.png"; - onclick = "return openMessageWindow(null, 'compose');"; - cssClass = "tbicon_compose"; label = "Write"; }, + onclick = "return onComposeMessage();"; + cssClass = "tbicon_compose"; label = "Write"; }, { link = "#"; target = "addressbook"; onclick = "openAddressbook(this);return false;"; image = "tb-mail-addressbook-flat-24x24.png"; diff --git a/UI/MailerUI/UIxMailMainFrame.h b/UI/MailerUI/UIxMailMainFrame.h index 2de756099..9e5ddd282 100644 --- a/UI/MailerUI/UIxMailMainFrame.h +++ b/UI/MailerUI/UIxMailMainFrame.h @@ -1,4 +1,4 @@ -/* UIxMailMainFrame.h - this file is part of $PROJECT_NAME_HERE$ +/* UIxMailMainFrame.h - this file is part of SOGo * * Copyright (C) 2006 Inverse groupe conseil * @@ -23,21 +23,9 @@ #ifndef UIXMAILMAINFRAME_H #define UIXMAILMAINFRAME_H -#import "../Common/UIxPageFrame.h" +#import "../Common/UIxComponent.h" -@interface UIxMailMainFrame : UIxPageFrame -{ - NSString *rootURL; - NSString *userRootURL; - struct { - int hideFolderTree:1; - int reserved:31; - } mmfFlags; -} - -- (NSString *)rootURL; -- (NSString *)userRootURL; -- (NSString *)calendarRootURL; +@interface UIxMailMainFrame : UIxComponent @end diff --git a/UI/MailerUI/UIxMailMainFrame.m b/UI/MailerUI/UIxMailMainFrame.m index 95c64ca83..9ad78fb1e 100644 --- a/UI/MailerUI/UIxMailMainFrame.m +++ b/UI/MailerUI/UIxMailMainFrame.m @@ -26,54 +26,27 @@ #import #import -#import -#import +#import +#import #import #import "UIxMailMainFrame.h" @implementation UIxMailMainFrame -static NSString *treeRootClassName = nil; - -+ (void)initialize { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - - treeRootClassName = [[ud stringForKey:@"SOGoMailTreeRootClass"] copy]; - if (treeRootClassName) - NSLog(@"Note: use class '%@' as root for mail tree.", treeRootClassName); - else - treeRootClassName = @"SOGoMailAccounts"; -} - -- (void)dealloc { - [self->rootURL release]; - [self->userRootURL release]; - [super dealloc]; -} - /* accessors */ - (NSString *) mailAccounts { - SOGoMailAccounts *co; + NSArray *accounts, *accountNames; - co = [self clientObject]; + accounts = [[context activeUser] mailAccounts]; + accountNames = [accounts objectsForKey: @"name"]; - return [[co fetchAllIdentities] jsonRepresentation]; + return [accountNames jsonRepresentation]; } -- (NSString *)treeRootClassName { - return treeRootClassName; -} - -- (void)setHideFolderTree:(BOOL)_flag { - self->mmfFlags.hideFolderTree = _flag ? 1 : 0; -} -- (BOOL)hideFolderTree { - return self->mmfFlags.hideFolderTree ? YES : NO; -} - -- (NSString *) pageFormURL { +- (NSString *) pageFormURL +{ NSString *u; NSRange r; @@ -117,136 +90,4 @@ static NSString *treeRootClassName = nil; return [u hasSuffix:@"/"] ? @"view" : @"#"; } -- (BOOL)showLinkBanner { - return YES; -} - -- (NSString *)bannerToolbarStyle { - return nil; -} - -- (NSString *)bannerConsumeStyle { - return nil; -} - -/* URL generation */ -// TODO: I think all this should be done by the clientObject?! -// TODO: is the stuff below necessary at all in the mailer frame? - -- (NSString *)rootURL { - WOContext *ctx; - NSArray *traversalObjects; - - if (self->rootURL != nil) - return self->rootURL; - - ctx = [self context]; - traversalObjects = [ctx objectTraversalStack]; - self->rootURL = [[[traversalObjects objectAtIndex:0] - rootURLInContext:ctx] - copy]; - return self->rootURL; -} - -- (NSString *)userRootURL { - WOContext *ctx; - NSArray *traversalObjects; - - if (self->userRootURL) - return self->userRootURL; - - ctx = [self context]; - traversalObjects = [ctx objectTraversalStack]; - self->userRootURL = [[[[traversalObjects objectAtIndex:1] - baseURLInContext:ctx] - stringByAppendingString:@"/"] - retain]; - return self->userRootURL; -} - -- (NSString *)calendarRootURL { - return [[self userRootURL] stringByAppendingString:@"Calendar/"]; -} - -- (NSString *)contactsRootURL { - return [[self userRootURL] stringByAppendingString:@"Contacts/"]; -} - -/* error handling */ - -- (BOOL)hasErrorText { - return [[[[self context] request] formValueForKey:@"error"] length] > 0 - ? YES : NO; -} -- (NSString *)errorText { - return [[[self context] request] formValueForKey:@"error"]; -} - -- (NSString *)errorAlertJavaScript { - NSString *errorText; - - if ([(errorText = [self errorText]) length] == 0) - return nil; - - // TODO: proper JavaScript escaping - errorText = [errorText stringByEscapingHTMLString]; - errorText = [errorText stringByReplacingString:@"\"" withString:@"'"]; - - return [NSString stringWithFormat: - @"", errorText]; -} - -/* FIXME: migrated methods which might not work yet... */ -// #warning check this -// - (NSString *) mailFolderName -// { -// NSMutableArray *mailboxes; -// SOGoMailObject *currentObject; - -// mailboxes = [NSMutableArray new]; -// [mailboxes autorelease]; - -// currentObject = [self clientObject]; -// while (![currentObject isKindOfClass: [SOGoMailAccounts class]]) -// { -// [mailboxes insertObject: [currentObject nameInContainer] atIndex: 0]; -// currentObject = [currentObject container]; -// } - -// return [NSString stringWithFormat: @"/%@", -// [mailboxes componentsJoinedByString: @"/"]]; -// } - -- (id) composeAction -{ - NSArray *c; - NSString *inbox, *url, *parameter; - NSMutableDictionary *urlParams; - id actionResult; - - c = [[self clientObject] toManyRelationshipKeys]; - if ([c count] > 0) - { - urlParams = [NSMutableDictionary new]; - [urlParams autorelease]; - - parameter = [self queryParameterForKey: @"mailto"]; - if (parameter) - [urlParams setObject: parameter - forKey: @"mailto"]; - inbox = [NSString stringWithFormat: @"%@/folderINBOX", - [c objectAtIndex: 0]]; - url = [inbox composeURLWithAction: @"compose" - parameters: urlParams - andHash: NO]; - actionResult = [self redirectToLocation: url]; - } - else - actionResult = self; - - return actionResult; -} - @end /* UIxMailMainFrame */ diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index a8c01a0bc..1eb40bc79 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -187,6 +187,11 @@ static NSString *mailETag = nil; return NO; } +- (BOOL) mailIsDraft +{ + return [[self clientObject] isInDraftsFolder]; +} + - (id) redirectToParentFolder { id url; diff --git a/UI/SOGoUI/SOGoACLAdvisory.m b/UI/SOGoUI/SOGoACLAdvisory.m index aefddbdd2..31b42ad6c 100644 --- a/UI/SOGoUI/SOGoACLAdvisory.m +++ b/UI/SOGoUI/SOGoACLAdvisory.m @@ -176,13 +176,21 @@ NGMimeMessage *message; NGMimeMultipartBody *body; SOGoUser *activeUser; + NSDictionary *identity; + NSString *from, *fullMail; activeUser = [context activeUser]; - recipient = [[LDAPUserManager sharedUserManager] getFullEmailForUID: recipientUID]; + identity = [activeUser primaryIdentity]; + from = [identity objectForKey: @"email"]; + fullMail = [NSString stringWithFormat: @"%@ <%@>", + [identity objectForKey: @"fullName"], from]; + + recipient = [[LDAPUserManager sharedUserManager] + getFullEmailForUID: recipientUID]; headerMap = [NGMutableHashMap hashMapWithCapacity: 5]; [headerMap setObject: @"multipart/alternative" forKey: @"content-type"]; - [headerMap setObject: [activeUser fullEmail] forKey: @"From"]; + [headerMap setObject: fullMail forKey: @"From"]; [headerMap setObject: recipient forKey: @"To"]; date = [[NSCalendarDate date] rfc822DateString]; [headerMap setObject: date forKey: @"Date"]; @@ -197,7 +205,7 @@ [[SOGoMailer sharedMailer] sendMimePart: message toRecipients: [NSArray arrayWithObject: recipient] - sender: [activeUser primaryEmail]]; + sender: from]; } @end diff --git a/UI/Scheduler/UIxCalView.m b/UI/Scheduler/UIxCalView.m index fd5b0f244..62fb66fe1 100644 --- a/UI/Scheduler/UIxCalView.m +++ b/UI/Scheduler/UIxCalView.m @@ -100,23 +100,20 @@ static BOOL shouldDisplayWeekend = NO; - (NSArray *) filterAppointments:(NSArray *) _apts { NSMutableArray *filtered; - unsigned i, count; - NSString *email; - NSDictionary *info; - NSArray *partmails; - unsigned p, pCount; + unsigned i, count, p, pCount; + NSString *email, *partmailsString, *state, *pEmail; + NSDictionary *info, *primaryIdentity; + NSArray *partmails, *partstates; BOOL shouldAdd; - NSString *partmailsString; - NSArray *partstates; - NSString *state; - NSString *pEmail; if ([self shouldDisplayRejectedAppointments]) return _apts; { count = [_apts count]; filtered = [[[NSMutableArray alloc] initWithCapacity: count] autorelease]; - email = [[context activeUser] primaryEmail]; + + primaryIdentity = [[context activeUser] primaryIdentity]; + email = [primaryIdentity objectForKey: @"email"]; for (i = 0; i < count; i++) { diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 08ef20929..cec6bbd1a 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -783,6 +783,7 @@ { NSString *organizerEmail; SOGoUser *activeUser; + NSDictionary *primaryIdentity; organizerEmail = [[component organizer] email]; if ([organizerEmail length] == 0) @@ -791,8 +792,9 @@ { ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]); activeUser = [context activeUser]; + primaryIdentity = [activeUser primaryIdentity]; [organizer setCn: [activeUser cn]]; - [organizer setEmail: [activeUser primaryEmail]]; + [organizer setEmail: [primaryIdentity objectForKey: @"email"]]; [component setOrganizer: organizer]; } } diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index 87826311b..229a502b1 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -1,58 +1,59 @@ - - + + + -
-
-
- -
    - -
-
- : -
-
- -
-
:
+ +
+
+ +
    + +
+ : +
+
+ +
+
:
+
-