2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
2011-12-02 08:22:47 +01:00
|
|
|
Copyright (C) 2008-2011 Inverse inc.
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
This file is part of SOGo.
|
2008-09-28 16:02:40 +02:00
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
SOGo is free software; you can redistribute it and/or modify it under
|
2006-06-15 21:34:10 +02:00
|
|
|
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.
|
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
SOGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
2006-06-15 21:34:10 +02:00
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2010-04-08 17:27:46 +02:00
|
|
|
#import <Foundation/NSCharacterSet.h>
|
2007-05-09 21:13:42 +02:00
|
|
|
#import <Foundation/NSFileManager.h>
|
|
|
|
#import <Foundation/NSKeyValueCoding.h>
|
|
|
|
#import <Foundation/NSString.h>
|
2010-08-27 21:04:01 +02:00
|
|
|
#import <Foundation/NSValue.h>
|
2007-05-09 21:13:42 +02:00
|
|
|
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <NGHttp/NGHttpRequest.h>
|
2007-05-09 21:13:42 +02:00
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
2007-08-17 04:42:17 +02:00
|
|
|
#import <NGObjWeb/SoSubContext.h>
|
2010-01-22 17:33:35 +01:00
|
|
|
#define COMPILING_NGOBJWEB 1 /* we want httpRequest for parsing multi-part
|
|
|
|
form data */
|
2007-08-17 04:42:17 +02:00
|
|
|
#import <NGObjWeb/WORequest.h>
|
2010-01-22 17:33:35 +01:00
|
|
|
#undef COMPILING_NGOBJWEB
|
2010-06-30 20:37:12 +02:00
|
|
|
#import <NGObjWeb/WOApplication.h>
|
2007-08-17 04:42:17 +02:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
2007-05-09 21:13:42 +02:00
|
|
|
#import <NGExtensions/NSNull+misc.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
#import <NGExtensions/NSString+misc.h>
|
|
|
|
#import <NGExtensions/NSException+misc.h>
|
2007-07-27 22:03:05 +02:00
|
|
|
#import <NGMail/NGMimeMessage.h>
|
|
|
|
#import <NGMail/NGMimeMessageGenerator.h>
|
|
|
|
#import <NGMime/NGMimeBodyPart.h>
|
|
|
|
#import <NGMime/NGMimeHeaderFields.h>
|
|
|
|
#import <NGMime/NGMimeMultipartBody.h>
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <NGMime/NGMimeType.h>
|
2007-05-09 21:13:42 +02:00
|
|
|
|
2010-06-30 20:37:12 +02:00
|
|
|
#import <SOGo/SOGoUserDefaults.h>
|
2011-02-03 17:12:22 +01:00
|
|
|
#import <SOGo/SOGoUser.h>
|
2011-12-02 08:22:47 +01:00
|
|
|
#import <SOGo/SOGoUserFolder.h>
|
2011-02-03 17:12:22 +01:00
|
|
|
#import <SOGo/NSArray+Utilities.h>
|
|
|
|
#import <SOGo/NSDictionary+Utilities.h>
|
|
|
|
#import <SOGo/WOResourceManager+SOGo.h>
|
2006-10-12 18:42:59 +02:00
|
|
|
#import <SOGoUI/UIxComponent.h>
|
2011-12-02 08:22:47 +01:00
|
|
|
#import <Mailer/SOGoDraftObject.h>
|
|
|
|
#import <Mailer/SOGoMailFolder.h>
|
|
|
|
#import <Mailer/SOGoMailAccount.h>
|
|
|
|
#import <Mailer/SOGoMailAccounts.h>
|
|
|
|
#import <Contacts/SOGoContactFolders.h>
|
|
|
|
#import <Contacts/SOGoContactFolder.h>
|
|
|
|
#import <Contacts/SOGoContactSourceFolder.h>
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
UIxMailEditor
|
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
A mail editor component which works on SOGoDraftObject's.
|
2006-06-15 21:34:10 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
@interface UIxMailEditor : UIxComponent
|
|
|
|
{
|
|
|
|
NSArray *to;
|
|
|
|
NSArray *cc;
|
|
|
|
NSArray *bcc;
|
|
|
|
NSString *subject;
|
2010-06-25 21:58:30 +02:00
|
|
|
NSString *sourceUID;
|
|
|
|
NSString *sourceFolder;
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *text;
|
2010-04-08 17:27:46 +02:00
|
|
|
NSMutableArray *fromEMails;
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *from;
|
|
|
|
SOGoMailFolder *sentFolder;
|
2010-11-23 14:53:54 +01:00
|
|
|
BOOL isHTML;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2008-09-28 16:02:40 +02:00
|
|
|
NSString *priority;
|
2010-08-31 15:49:31 +02:00
|
|
|
NSString *receipt;
|
2008-09-28 16:02:40 +02:00
|
|
|
id item;
|
2011-12-02 08:22:47 +01:00
|
|
|
id currentFolder;
|
2008-09-28 16:02:40 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* these are for the inline attachment list */
|
|
|
|
NSString *attachmentName;
|
|
|
|
NSArray *attachmentNames;
|
2007-12-06 17:27:28 +01:00
|
|
|
NSMutableArray *attachedFiles;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation UIxMailEditor
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
static NSArray *infoKeys = nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
if (!infoKeys)
|
|
|
|
infoKeys = [[NSArray alloc] initWithObjects:
|
|
|
|
@"subject", @"to", @"cc", @"bcc",
|
2010-08-31 15:49:31 +02:00
|
|
|
@"from", @"inReplyTo",
|
|
|
|
@"priority", @"receipt", nil];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2008-09-28 16:02:40 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
2008-10-23 17:55:56 +02:00
|
|
|
priority = @"NORMAL";
|
2010-08-31 15:49:31 +02:00
|
|
|
receipt = nil;
|
2011-12-02 08:22:47 +01:00
|
|
|
currentFolder = nil;
|
2008-09-28 16:02:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
2008-09-28 16:02:40 +02:00
|
|
|
[item release];
|
|
|
|
[priority release];
|
2010-08-31 15:49:31 +02:00
|
|
|
[receipt release];
|
2007-05-09 21:13:42 +02:00
|
|
|
[sentFolder release];
|
|
|
|
[fromEMails release];
|
2007-08-17 04:42:17 +02:00
|
|
|
[from release];
|
|
|
|
[text release];
|
2007-05-09 21:13:42 +02:00
|
|
|
[subject release];
|
2007-08-17 04:42:17 +02:00
|
|
|
[to release];
|
|
|
|
[cc release];
|
|
|
|
[bcc release];
|
2010-06-25 21:58:30 +02:00
|
|
|
[sourceUID release];
|
|
|
|
[sourceFolder release];
|
2007-08-17 04:42:17 +02:00
|
|
|
[attachmentName release];
|
2007-05-09 21:13:42 +02:00
|
|
|
[attachmentNames release];
|
2007-12-06 17:27:28 +01:00
|
|
|
[attachedFiles release];
|
2011-12-02 08:22:47 +01:00
|
|
|
[currentFolder release];
|
2006-06-15 21:34:10 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* accessors */
|
2008-09-28 16:02:40 +02:00
|
|
|
- (void) setItem: (id) _item
|
|
|
|
{
|
|
|
|
ASSIGN (item, _item);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) item
|
|
|
|
{
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) priorityClasses
|
|
|
|
{
|
|
|
|
static NSArray *priorities = nil;
|
|
|
|
|
|
|
|
if (!priorities)
|
|
|
|
{
|
|
|
|
priorities = [NSArray arrayWithObjects: @"HIGHEST", @"HIGH",
|
|
|
|
@"NORMAL", @"LOW", @"LOWEST", nil];
|
|
|
|
[priorities retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return priorities;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setPriority: (NSString *) _priority
|
|
|
|
{
|
2010-08-31 15:49:31 +02:00
|
|
|
ASSIGN (priority, _priority);
|
2008-09-28 16:02:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) priority
|
|
|
|
{
|
|
|
|
return priority;
|
|
|
|
}
|
|
|
|
|
2010-08-31 15:49:31 +02:00
|
|
|
- (void) setReceipt: (NSString *) newReceipt
|
|
|
|
{
|
|
|
|
ASSIGN (receipt, newReceipt);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) receipt
|
|
|
|
{
|
|
|
|
return receipt;
|
|
|
|
}
|
|
|
|
|
2010-11-23 14:53:54 +01:00
|
|
|
- (void) setIsHTML: (BOOL) aBool
|
|
|
|
{
|
|
|
|
isHTML = aBool;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isHTML
|
|
|
|
{
|
|
|
|
SOGoUserDefaults *ud;
|
|
|
|
|
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
|
|
|
|
return [[ud mailComposeMessageType] isEqualToString: @"html"];
|
|
|
|
}
|
|
|
|
|
2008-09-28 16:02:40 +02:00
|
|
|
- (NSString *) itemPriorityText
|
|
|
|
{
|
|
|
|
return [self labelForKey: [NSString stringWithFormat: @"%@", [item lowercaseString]]];
|
|
|
|
}
|
|
|
|
|
2008-04-15 17:01:16 +02:00
|
|
|
- (NSString *) isMailReply
|
|
|
|
{
|
|
|
|
return ([to count] > 0 ? @"true" : @"false");
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2010-06-30 20:37:12 +02:00
|
|
|
- (NSString *) localeCode
|
|
|
|
{
|
|
|
|
SOGoUserDefaults *ud;
|
|
|
|
NSDictionary *locale;
|
|
|
|
|
|
|
|
ud = [[context activeUser] userDefaults];
|
2011-02-03 17:12:22 +01:00
|
|
|
locale = [[self resourceManager]
|
|
|
|
localeForLanguageNamed: [ud language]];
|
2010-06-30 20:37:12 +02:00
|
|
|
|
|
|
|
// WARNING : NSLocaleCode is not defined in <Foundation/NSUserDefaults.h>
|
|
|
|
return [locale objectForKey: @"NSLocaleCode"];
|
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setFrom: (NSString *) newFrom
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
ASSIGN (from, newFrom);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
2010-04-08 17:27:46 +02:00
|
|
|
- (NSString *) _emailFromIdentity: (NSDictionary *) identity
|
|
|
|
{
|
|
|
|
NSString *fullName, *format;
|
|
|
|
|
|
|
|
fullName = [identity objectForKey: @"fullName"];
|
|
|
|
if ([fullName length])
|
2010-08-26 17:29:05 +02:00
|
|
|
format = @"%{fullName} <%{email}>";
|
2010-04-08 17:27:46 +02:00
|
|
|
else
|
|
|
|
format = @"%{email}";
|
|
|
|
|
|
|
|
return [identity keysWithFormat: format];
|
|
|
|
}
|
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
- (NSString *) from
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
NSDictionary *identity;
|
|
|
|
|
|
|
|
if (!from)
|
|
|
|
{
|
|
|
|
identity = [[context activeUser] primaryIdentity];
|
2010-04-08 17:27:46 +02:00
|
|
|
from = [self _emailFromIdentity: identity];
|
2008-09-02 04:57:12 +02:00
|
|
|
[from retain];
|
2007-08-17 04:42:17 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
2007-05-09 21:13:42 +02:00
|
|
|
return from;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setSubject: (NSString *) newSubject
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
ASSIGN (subject, newSubject);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSString *) subject
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return subject;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setText: (NSString *) newText
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
ASSIGN (text, newText);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSString *) text
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return text;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
- (void) setSourceUID: (int) newSourceUID
|
|
|
|
{
|
|
|
|
NSString *s;
|
|
|
|
|
|
|
|
s = [NSString stringWithFormat: @"%i", newSourceUID];
|
|
|
|
ASSIGN (sourceUID, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) sourceUID
|
|
|
|
{
|
|
|
|
return sourceUID;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setSourceFolder: (NSString *) newSourceFolder
|
|
|
|
{
|
|
|
|
ASSIGN (sourceFolder, newSourceFolder);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) sourceFolder
|
|
|
|
{
|
|
|
|
return sourceFolder;
|
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setTo: (NSArray *) newTo
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
if ([newTo isKindOfClass: [NSNull class]])
|
|
|
|
newTo = nil;
|
|
|
|
|
|
|
|
ASSIGN (to, newTo);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSArray *) to
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return to;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setCc: (NSArray *) newCc
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
if ([newCc isKindOfClass: [NSNull class]])
|
|
|
|
newCc = nil;
|
|
|
|
|
|
|
|
ASSIGN (cc, newCc);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSArray *) cc
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return cc;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setBcc: (NSArray *) newBcc
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
if ([newBcc isKindOfClass: [NSNull class]])
|
|
|
|
newBcc = nil;
|
|
|
|
|
|
|
|
ASSIGN (bcc, newBcc);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSArray *) bcc
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return bcc;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
- (BOOL) hasOneOrMoreRecipients
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
return (([to count] + [cc count] + [bcc count]) > 0);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) setAttachmentName: (NSString *) newAttachmentName
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
ASSIGN (attachmentName, newAttachmentName);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
- (NSString *) attachmentName
|
|
|
|
{
|
2007-05-09 21:13:42 +02:00
|
|
|
return attachmentName;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* from addresses */
|
|
|
|
|
2007-05-09 21:13:42 +02:00
|
|
|
- (NSArray *) fromEMails
|
|
|
|
{
|
2010-08-06 16:27:06 +02:00
|
|
|
NSArray *identities;
|
2010-04-08 17:27:46 +02:00
|
|
|
int count, max;
|
|
|
|
NSString *email;
|
2010-08-06 16:27:06 +02:00
|
|
|
SOGoMailAccount *account;
|
2007-08-17 04:42:17 +02:00
|
|
|
|
2007-05-09 21:13:42 +02:00
|
|
|
if (!fromEMails)
|
|
|
|
{
|
2010-08-06 16:27:06 +02:00
|
|
|
account = [[self clientObject] mailAccountFolder];
|
|
|
|
identities = [account identities];
|
|
|
|
max = [identities count];
|
|
|
|
fromEMails = [[NSMutableArray alloc] initWithCapacity: max];
|
2010-04-08 17:27:46 +02:00
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
email
|
2010-08-06 16:27:06 +02:00
|
|
|
= [self _emailFromIdentity: [identities objectAtIndex: count]];
|
2010-04-08 17:27:46 +02:00
|
|
|
[fromEMails addObjectUniquely: email];
|
|
|
|
}
|
2007-05-09 21:13:42 +02:00
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-05-09 21:13:42 +02:00
|
|
|
return fromEMails;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* info loading */
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (void) loadInfo: (NSDictionary *) _info
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
if (![_info isNotNull]) return;
|
|
|
|
[self debugWithFormat:@"loading info ..."];
|
|
|
|
[self takeValuesFromDictionary:_info];
|
|
|
|
}
|
2007-08-17 04:42:17 +02:00
|
|
|
|
|
|
|
- (NSDictionary *) storeInfo
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
[self debugWithFormat:@"storing info ..."];
|
|
|
|
return [self valuesForKeys:infoKeys];
|
|
|
|
}
|
|
|
|
|
2011-12-02 08:22:47 +01:00
|
|
|
/* contacts search */
|
|
|
|
- (NSArray *) contactFolders
|
|
|
|
{
|
|
|
|
SOGoContactFolders *folderContainer;
|
|
|
|
|
|
|
|
folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts"
|
|
|
|
inContext: nil];
|
|
|
|
|
|
|
|
return [folderContainer subFolders];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) personalContactInfos
|
|
|
|
{
|
|
|
|
SOGoContactFolders *folderContainer;
|
|
|
|
id <SOGoContactFolder> folder;
|
|
|
|
NSArray *contactInfos;
|
|
|
|
|
|
|
|
folderContainer = (SOGoContactFolders *) [[[self clientObject] lookupUserFolder] privateContacts: @"Contacts"
|
|
|
|
inContext: nil];
|
|
|
|
folder = [folderContainer lookupPersonalFolder: @"personal" ignoringRights: YES];
|
|
|
|
|
|
|
|
contactInfos = [folder lookupContactsWithFilter: nil
|
|
|
|
onCriteria: nil
|
|
|
|
sortBy: @"c_cn"
|
|
|
|
ordering: NSOrderedAscending];
|
|
|
|
|
|
|
|
return contactInfos;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCurrentFolder: (id) _currentFolder
|
|
|
|
{
|
|
|
|
ASSIGN (currentFolder, _currentFolder);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) currentContactFolderId
|
|
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"/%@", [currentFolder nameInContainer]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) currentContactFolderName
|
|
|
|
{
|
|
|
|
return [currentFolder displayName];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) currentContactFolderOwner
|
|
|
|
{
|
|
|
|
return [currentFolder ownerInContext: context];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) currentContactFolderClass
|
|
|
|
{
|
|
|
|
return ([currentFolder isKindOfClass: [SOGoContactSourceFolder class]]
|
|
|
|
? @"remote" : @"local");
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* requests */
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
|
|
|
inContext: (WOContext*) localContext
|
2007-07-30 20:39:55 +02:00
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* actions */
|
2007-12-06 17:27:28 +01:00
|
|
|
- (NSString *) _fixedFilename: (NSString *) filename
|
|
|
|
{
|
|
|
|
NSString *newFilename, *baseFilename, *extension;
|
|
|
|
unsigned int variation;
|
|
|
|
|
|
|
|
if (!attachedFiles)
|
|
|
|
attachedFiles = [NSMutableArray new];
|
|
|
|
|
|
|
|
newFilename = filename;
|
|
|
|
|
|
|
|
baseFilename = [filename stringByDeletingPathExtension];
|
|
|
|
extension = [filename pathExtension];
|
|
|
|
variation = 0;
|
|
|
|
while ([attachedFiles containsObject: newFilename])
|
|
|
|
{
|
|
|
|
variation++;
|
|
|
|
newFilename = [NSString stringWithFormat: @"%@-%d.%@", baseFilename,
|
|
|
|
variation, extension];
|
|
|
|
}
|
|
|
|
[attachedFiles addObject: newFilename];
|
|
|
|
|
|
|
|
return newFilename;
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
- (NSDictionary *) _scanAttachmentFilenamesInRequest: (id) httpBody
|
|
|
|
{
|
|
|
|
NSMutableDictionary *filenames;
|
|
|
|
NSDictionary *attachment;
|
|
|
|
NSArray *parts;
|
|
|
|
unsigned int count, max;
|
|
|
|
NGMimeBodyPart *part;
|
|
|
|
NGMimeContentDispositionHeaderField *header;
|
2007-12-06 17:27:28 +01:00
|
|
|
NSString *mimeType, *filename;
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
parts = [httpBody parts];
|
|
|
|
max = [parts count];
|
|
|
|
filenames = [NSMutableDictionary dictionaryWithCapacity: max];
|
|
|
|
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
part = [parts objectAtIndex: count];
|
2007-10-25 17:28:14 +02:00
|
|
|
header = (NGMimeContentDispositionHeaderField *)
|
|
|
|
[part headerForKey: @"content-disposition"];
|
|
|
|
mimeType = [(NGMimeType *)
|
|
|
|
[part headerForKey: @"content-type"] stringValue];
|
2007-12-06 17:27:28 +01:00
|
|
|
filename = [self _fixedFilename: [header filename]];
|
2007-07-27 22:03:05 +02:00
|
|
|
attachment = [NSDictionary dictionaryWithObjectsAndKeys:
|
2007-12-06 17:27:28 +01:00
|
|
|
filename, @"filename",
|
2007-10-25 17:28:14 +02:00
|
|
|
mimeType, @"mimetype", nil];
|
|
|
|
[filenames setObject: attachment forKey: [header name]];
|
2007-07-27 22:03:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return filenames;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) _saveAttachments
|
|
|
|
{
|
|
|
|
WORequest *request;
|
|
|
|
NSEnumerator *allKeys;
|
|
|
|
NSString *key;
|
|
|
|
BOOL success;
|
|
|
|
NSDictionary *filenames;
|
|
|
|
id httpBody;
|
|
|
|
SOGoDraftObject *co;
|
|
|
|
|
|
|
|
success = YES;
|
|
|
|
request = [context request];
|
|
|
|
|
|
|
|
httpBody = [[request httpRequest] body];
|
|
|
|
filenames = [self _scanAttachmentFilenamesInRequest: httpBody];
|
|
|
|
|
|
|
|
co = [self clientObject];
|
|
|
|
allKeys = [[request formValueKeys] objectEnumerator];
|
2008-03-28 19:16:55 +01:00
|
|
|
while ((key = [allKeys nextObject]) && success)
|
|
|
|
if ([key hasPrefix: @"attachment"])
|
|
|
|
success
|
|
|
|
= (![co saveAttachment: (NSData *) [request formValueForKey: key]
|
|
|
|
withMetadata: [filenames objectForKey: key]]);
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) _saveFormInfo
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSDictionary *info;
|
2007-07-27 22:03:05 +02:00
|
|
|
NSException *error;
|
|
|
|
BOOL success;
|
2007-08-17 04:42:17 +02:00
|
|
|
SOGoDraftObject *co;
|
|
|
|
|
|
|
|
co = [self clientObject];
|
|
|
|
[co fetchInfo];
|
2007-07-27 22:03:05 +02:00
|
|
|
|
|
|
|
success = YES;
|
|
|
|
|
|
|
|
if ([self _saveAttachments])
|
|
|
|
{
|
|
|
|
info = [self storeInfo];
|
2007-08-17 04:42:17 +02:00
|
|
|
[co setHeaders: info];
|
|
|
|
[co setText: text];
|
2010-11-23 14:53:54 +01:00
|
|
|
[co setIsHTML: isHTML];
|
2007-08-17 04:42:17 +02:00
|
|
|
error = [co storeInfo];
|
|
|
|
if (error)
|
2007-07-27 22:03:05 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
[self errorWithFormat: @"failed to store draft: %@", error];
|
|
|
|
// TODO: improve error handling
|
|
|
|
success = NO;
|
2007-07-27 22:03:05 +02:00
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
else
|
|
|
|
success = NO;
|
2007-08-17 04:42:17 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: wrap content
|
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
return success;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-27 22:03:05 +02:00
|
|
|
|
2007-07-30 20:39:55 +02:00
|
|
|
- (id) failedToSaveFormResponse
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: improve error handling
|
|
|
|
return [NSException exceptionWithHTTPStatus:500 /* server error */
|
|
|
|
reason:@"failed to store draft object on server!"];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attachment helper */
|
|
|
|
|
2007-07-30 20:39:55 +02:00
|
|
|
- (NSArray *) attachmentNames
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *a;
|
2007-08-17 04:42:17 +02:00
|
|
|
|
2007-12-17 21:45:48 +01:00
|
|
|
if (!attachmentNames)
|
2007-12-06 17:27:28 +01:00
|
|
|
{
|
|
|
|
a = [[self clientObject] fetchAttachmentNames];
|
2007-12-17 21:45:48 +01:00
|
|
|
ASSIGN (attachmentNames,
|
|
|
|
[a sortedArrayUsingSelector: @selector (compare:)]);
|
2007-12-06 17:27:28 +01:00
|
|
|
}
|
2007-08-17 04:42:17 +02:00
|
|
|
|
2007-05-09 21:13:42 +02:00
|
|
|
return attachmentNames;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2007-07-30 20:39:55 +02:00
|
|
|
|
|
|
|
- (BOOL) hasAttachments
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self attachmentNames] count] > 0 ? YES : NO;
|
|
|
|
}
|
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
- (NSString *) uid
|
|
|
|
{
|
|
|
|
return [[self clientObject] nameInContainer];
|
|
|
|
}
|
|
|
|
|
2007-07-27 22:03:05 +02:00
|
|
|
- (id) defaultAction
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
SOGoDraftObject *co;
|
|
|
|
|
|
|
|
co = [self clientObject];
|
|
|
|
[co fetchInfo];
|
|
|
|
[self loadInfo: [co headers]];
|
|
|
|
[self setText: [co text]];
|
2010-06-25 21:58:30 +02:00
|
|
|
[self setSourceUID: [co IMAP4ID]];
|
|
|
|
[self setSourceFolder: [co sourceFolder]];
|
2007-08-17 04:42:17 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
- (id <WOActionResults>) saveAction
|
2007-07-30 20:39:55 +02:00
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
id result;
|
|
|
|
|
|
|
|
if ([self _saveFormInfo])
|
|
|
|
{
|
|
|
|
result = [[self clientObject] save];
|
|
|
|
if (!result)
|
2007-09-11 21:42:41 +02:00
|
|
|
result = [self responseWith204];
|
2007-08-17 04:42:17 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
result = [self failedToSaveFormResponse];
|
|
|
|
|
|
|
|
return result;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-07-30 20:39:55 +02:00
|
|
|
- (NSException *) validateForSend
|
|
|
|
{
|
2007-08-17 04:42:17 +02:00
|
|
|
NSException *error;
|
|
|
|
|
|
|
|
if (![self hasOneOrMoreRecipients])
|
|
|
|
error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
|
|
|
reason: @"Please select a recipient!"];
|
|
|
|
else if ([[self subject] length] == 0)
|
|
|
|
error = [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
|
|
|
reason: @"Please set a subject!"];
|
|
|
|
else
|
|
|
|
error = nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-08-17 04:42:17 +02:00
|
|
|
return error;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2010-08-23 22:58:41 +02:00
|
|
|
- (WOResponse *) sendAction
|
2006-10-12 18:42:59 +02:00
|
|
|
{
|
2010-06-25 21:58:30 +02:00
|
|
|
SOGoDraftObject *co;
|
2010-08-23 22:58:41 +02:00
|
|
|
NSDictionary *jsonResponse;
|
|
|
|
NSException *error;
|
2010-11-10 21:12:18 +01:00
|
|
|
NSMutableArray *errorMsg;
|
2010-08-23 22:58:41 +02:00
|
|
|
|
|
|
|
co = [self clientObject];
|
2006-10-12 18:42:59 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* first, save form data */
|
2010-08-23 22:58:41 +02:00
|
|
|
error = [self validateForSend];
|
|
|
|
if (!error)
|
2007-08-17 04:42:17 +02:00
|
|
|
{
|
|
|
|
if ([self _saveFormInfo])
|
2010-08-23 22:58:41 +02:00
|
|
|
error = [co sendMail];
|
2007-08-17 04:42:17 +02:00
|
|
|
else
|
2010-08-23 22:58:41 +02:00
|
|
|
error = [self failedToSaveFormResponse];
|
2007-08-17 04:42:17 +02:00
|
|
|
}
|
2006-10-12 18:42:59 +02:00
|
|
|
|
2010-08-23 22:58:41 +02:00
|
|
|
if (error)
|
2010-11-10 21:12:18 +01:00
|
|
|
{
|
|
|
|
// Only the first line is translated
|
|
|
|
errorMsg = [NSMutableArray arrayWithArray: [[error reason] componentsSeparatedByString: @"\n"]];
|
|
|
|
[errorMsg replaceObjectAtIndex: 0
|
|
|
|
withObject: [self labelForKey: [errorMsg objectAtIndex: 0]]];
|
|
|
|
jsonResponse = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
@"failure", @"status",
|
|
|
|
[errorMsg componentsJoinedByString: @"\n"],
|
|
|
|
@"message",
|
|
|
|
nil];
|
|
|
|
}
|
2010-08-23 22:58:41 +02:00
|
|
|
else
|
|
|
|
jsonResponse = [NSDictionary dictionaryWithObjectsAndKeys:
|
|
|
|
@"success", @"status",
|
|
|
|
[co sourceFolder], @"sourceFolder",
|
2010-08-27 02:51:46 +02:00
|
|
|
[NSNumber numberWithInt: [co IMAP4ID]], @"messageID",
|
2010-08-23 22:58:41 +02:00
|
|
|
nil];
|
|
|
|
|
|
|
|
return [self responseWithStatus: 200
|
|
|
|
andString: [jsonResponse jsonRepresentation]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@end /* UIxMailEditor */
|