2006-06-15 21:34:10 +02:00
|
|
|
/*
|
2011-04-21 18:02:31 +02:00
|
|
|
Copyright (C) 2007-2011 Inverse inc.
|
2006-06-15 21:34:10 +02:00
|
|
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
|
|
|
|
2011-12-29 18:50:48 +01:00
|
|
|
Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
|
|
Ludovic Marcotte <lmarcotte@inverse.ca>
|
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
This file is part of SOGo.
|
2006-06-15 21:34:10 +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.
|
|
|
|
*/
|
|
|
|
|
2008-07-04 18:06:09 +02:00
|
|
|
#import <Foundation/NSEnumerator.h>
|
2008-02-01 17:28:53 +01:00
|
|
|
#import <Foundation/NSValue.h>
|
2007-12-17 16:29:06 +01:00
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
#import <EOControl/EOQualifier.h>
|
|
|
|
|
2008-07-08 13:32:43 +02:00
|
|
|
#import <NGCards/NGVCard.h>
|
2009-08-24 23:02:47 +02:00
|
|
|
#import <NGCards/NGVCardReference.h>
|
2009-08-24 22:26:52 +02:00
|
|
|
#import <NGCards/NGVList.h>
|
2007-11-09 00:18:52 +01:00
|
|
|
#import <NGObjWeb/WOContext.h>
|
2007-07-27 19:30:37 +02:00
|
|
|
#import <NGObjWeb/WORequest.h>
|
2007-12-17 16:29:06 +01:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
2007-07-27 19:30:37 +02:00
|
|
|
#import <NGObjWeb/SoComponent.h>
|
2010-05-27 16:41:59 +02:00
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
2007-07-27 19:30:37 +02:00
|
|
|
#import <NGExtensions/NSString+misc.h>
|
|
|
|
|
2008-07-08 13:32:43 +02:00
|
|
|
#import <Contacts/SOGoContactObject.h>
|
2009-08-24 22:26:52 +02:00
|
|
|
#import <Contacts/SOGoContactGCSList.h>
|
|
|
|
#import <Contacts/SOGoContactGCSEntry.h>
|
2008-07-08 13:32:43 +02:00
|
|
|
#import <Contacts/SOGoContactFolders.h>
|
2009-10-23 22:25:36 +02:00
|
|
|
#import <Contacts/SOGoContactLDIFEntry.h>
|
2008-07-08 13:32:43 +02:00
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <Mailer/SOGoMailObject.h>
|
|
|
|
#import <Mailer/SOGoMailAccount.h>
|
|
|
|
#import <Mailer/SOGoMailAccounts.h>
|
2010-06-25 21:58:30 +02:00
|
|
|
#import <Mailer/SOGoMailFolder.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/NSDictionary+URL.h>
|
|
|
|
#import <SOGo/NSArray+Utilities.h>
|
|
|
|
#import <SOGo/NSString+Utilities.h>
|
|
|
|
#import <SOGo/NSDictionary+Utilities.h>
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <SOGo/SOGoDomainDefaults.h>
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <SOGo/SOGoUser.h>
|
|
|
|
#import <SOGo/SOGoUserDefaults.h>
|
|
|
|
#import <SOGo/SOGoUserFolder.h>
|
2010-04-21 16:35:58 +02:00
|
|
|
#import <SOGo/SOGoUserSettings.h>
|
2006-07-29 00:59:11 +02:00
|
|
|
#import <SOGoUI/UIxComponent.h>
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-07-27 19:30:37 +02:00
|
|
|
#import "UIxMailMainFrame.h"
|
2010-06-25 21:58:30 +02:00
|
|
|
#import "UIxMailListActions.h"
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
// Avoid compilation warnings
|
|
|
|
@interface SOGoUserFolder (private)
|
|
|
|
|
|
|
|
- (SOGoAppointmentFolders *) privateContacts: (NSString *) key
|
|
|
|
inContext: (WOContext *) localContext;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@implementation UIxMailMainFrame
|
|
|
|
|
2010-05-28 21:18:52 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
|
|
|
folderType = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-12-13 22:07:09 +01:00
|
|
|
- (void) _setupContext
|
|
|
|
{
|
|
|
|
SOGoUser *activeUser;
|
2010-05-28 21:18:52 +02:00
|
|
|
NSString *module;
|
2007-12-13 22:07:09 +01:00
|
|
|
SOGoMailAccounts *clientObject;
|
|
|
|
|
|
|
|
activeUser = [context activeUser];
|
|
|
|
clientObject = [self clientObject];
|
|
|
|
|
|
|
|
module = [clientObject nameInContainer];
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
us = [activeUser userSettings];
|
|
|
|
moduleSettings = [us objectForKey: module];
|
2007-12-13 22:07:09 +01:00
|
|
|
if (!moduleSettings)
|
|
|
|
{
|
2009-09-30 16:26:18 +02:00
|
|
|
moduleSettings = [NSMutableDictionary dictionary];
|
2009-11-29 05:19:32 +01:00
|
|
|
[us setObject: moduleSettings forKey: module];
|
2007-12-13 22:07:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
/* accessors */
|
2008-10-23 17:35:20 +02:00
|
|
|
|
2007-05-25 23:19:31 +02:00
|
|
|
- (NSString *) mailAccounts
|
|
|
|
{
|
2010-08-03 20:52:49 +02:00
|
|
|
NSArray *accounts, *names;
|
2009-09-29 22:13:36 +02:00
|
|
|
|
2010-08-03 20:52:49 +02:00
|
|
|
accounts = [[self clientObject] mailAccounts];
|
|
|
|
names = [accounts objectsForKey: @"name" notFoundMarker: nil];
|
2007-05-25 23:19:31 +02:00
|
|
|
|
2010-08-03 20:52:49 +02:00
|
|
|
return [names jsonRepresentation];
|
2007-05-25 23:19:31 +02:00
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-08-15 23:09:50 +02:00
|
|
|
- (NSString *) pageFormURL
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *u;
|
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
u = [[[self context] request] uri];
|
|
|
|
if ((r = [u rangeOfString:@"?"]).length > 0) {
|
|
|
|
/* has query parameters */
|
|
|
|
// TODO: this is ugly, create reusable link facility in SOPE
|
|
|
|
// TODO: remove 'search' and 'filterpopup', preserve sorting
|
|
|
|
NSMutableString *ms;
|
2012-05-29 20:56:15 +02:00
|
|
|
NSArray *qp;
|
|
|
|
NSUInteger i, count;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
qp = [[u substringFromIndex:(r.location + r.length)]
|
|
|
|
componentsSeparatedByString:@"&"];
|
|
|
|
count = [qp count];
|
|
|
|
ms = [NSMutableString stringWithCapacity:count * 12];
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
NSString *s;
|
|
|
|
|
|
|
|
s = [qp objectAtIndex:i];
|
|
|
|
|
|
|
|
/* filter out */
|
|
|
|
if ([s hasPrefix:@"search="]) continue;
|
|
|
|
if ([s hasPrefix:@"filterpopup="]) continue;
|
|
|
|
|
|
|
|
if ([ms length] > 0) [ms appendString:@"&"];
|
|
|
|
[ms appendString:s];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([ms length] == 0) {
|
|
|
|
/* no other query params */
|
|
|
|
u = [u substringToIndex:r.location];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
u = [u substringToIndex:r.location + r.length];
|
|
|
|
u = [u stringByAppendingString:ms];
|
|
|
|
}
|
|
|
|
return u;
|
|
|
|
}
|
|
|
|
return [u hasSuffix:@"/"] ? @"view" : @"#";
|
|
|
|
}
|
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
- (NSString *) inboxData
|
|
|
|
{
|
|
|
|
SOGoMailAccounts *accounts;
|
|
|
|
SOGoMailAccount *account;
|
|
|
|
SOGoMailFolder *inbox;
|
|
|
|
NSDictionary *data;
|
|
|
|
UIxMailListActions *actions;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
|
2010-08-03 20:52:49 +02:00
|
|
|
#warning this code is dirty: we should not invoke UIxMailListActions from here!
|
2010-06-25 21:58:30 +02:00
|
|
|
actions = [[[UIxMailListActions new] initWithRequest: [context request]] autorelease];
|
|
|
|
accounts = [self clientObject];
|
|
|
|
|
2010-08-03 20:52:49 +02:00
|
|
|
account = [accounts lookupName: @"0" inContext: context acquire: NO];
|
2010-06-25 21:58:30 +02:00
|
|
|
inbox = [account inboxFolderInContext: context];
|
|
|
|
|
2011-07-08 19:38:27 +02:00
|
|
|
data = [actions getUIDsInFolder: inbox withHeaders: YES];
|
2010-06-25 21:58:30 +02:00
|
|
|
|
|
|
|
return [data jsonRepresentation];
|
|
|
|
}
|
|
|
|
|
2007-08-21 16:49:48 +02:00
|
|
|
- (id <WOActionResults>) composeAction
|
|
|
|
{
|
2009-08-24 22:26:52 +02:00
|
|
|
id contact;
|
2010-08-03 20:52:49 +02:00
|
|
|
NSArray *contactsId, *cards;
|
|
|
|
NSString *newLocation, *parameters, *folderId, *uid, *formattedMail;
|
2008-07-08 13:32:43 +02:00
|
|
|
NSEnumerator *uids;
|
|
|
|
NSMutableArray *addresses;
|
|
|
|
NGVCard *card;
|
2009-08-24 22:26:52 +02:00
|
|
|
NGVList *list;
|
2007-08-21 16:49:48 +02:00
|
|
|
SOGoMailAccounts *co;
|
2008-07-08 13:32:43 +02:00
|
|
|
SOGoContactFolders *folders;
|
|
|
|
SOGoParentFolder *folder;
|
2012-05-29 20:56:15 +02:00
|
|
|
WORequest *request;
|
|
|
|
NSUInteger i, count;
|
2007-08-21 16:49:48 +02:00
|
|
|
|
2008-07-08 13:32:43 +02:00
|
|
|
parameters = nil;
|
2007-08-21 16:49:48 +02:00
|
|
|
co = [self clientObject];
|
2008-07-08 13:32:43 +02:00
|
|
|
|
|
|
|
request = [context request];
|
|
|
|
|
|
|
|
if ((folderId = [request formValueForKey: @"folder"]) &&
|
|
|
|
(contactsId = [request formValuesForKey: @"uid"]))
|
|
|
|
{
|
|
|
|
// Retrieve the email addresses from the specified address book
|
|
|
|
// and contact IDs
|
2009-04-01 15:49:24 +02:00
|
|
|
folders = (SOGoContactFolders *)[[[self clientObject] container] privateContacts: @"Contacts"
|
2009-08-24 21:40:29 +02:00
|
|
|
inContext: nil];
|
2008-07-08 13:32:43 +02:00
|
|
|
folder = [folders lookupName: folderId
|
2009-08-24 21:40:29 +02:00
|
|
|
inContext: nil
|
|
|
|
acquire: NO];
|
2008-07-08 13:32:43 +02:00
|
|
|
if (folder)
|
2009-08-24 21:40:29 +02:00
|
|
|
{
|
|
|
|
uids = [contactsId objectEnumerator];
|
|
|
|
uid = [uids nextObject];
|
|
|
|
|
2009-09-30 16:26:18 +02:00
|
|
|
addresses = [NSMutableArray array];
|
2009-08-24 21:40:29 +02:00
|
|
|
|
|
|
|
while (uid)
|
|
|
|
{
|
|
|
|
contact = [folder lookupName: uid
|
|
|
|
inContext: [self context]
|
|
|
|
acquire: NO];
|
2009-08-24 22:26:52 +02:00
|
|
|
if ([contact isKindOfClass: [SOGoContactGCSList class]])
|
|
|
|
{
|
2009-08-24 23:02:47 +02:00
|
|
|
list = [(SOGoContactGCSList *)contact vList];
|
2009-08-24 22:26:52 +02:00
|
|
|
cards = [list cardReferences];
|
|
|
|
count = [cards count];
|
|
|
|
for (i = 0; i < count; i++)
|
2009-10-23 22:11:56 +02:00
|
|
|
{
|
|
|
|
formattedMail = [self formattedMailtoString: [cards objectAtIndex: i]];
|
|
|
|
if (formattedMail)
|
|
|
|
[addresses addObject: formattedMail];
|
|
|
|
}
|
2009-08-24 22:26:52 +02:00
|
|
|
}
|
2009-10-23 22:25:36 +02:00
|
|
|
else if ([contact isKindOfClass: [SOGoContactGCSEntry class]]
|
|
|
|
|| [contact isKindOfClass: [SOGoContactLDIFEntry class]])
|
2009-08-24 21:40:29 +02:00
|
|
|
{
|
|
|
|
// We fetch the preferred email address of the contact or
|
|
|
|
// the first defined email address
|
|
|
|
card = [contact vCard];
|
2009-10-23 22:11:56 +02:00
|
|
|
formattedMail = [self formattedMailtoString: card];
|
|
|
|
if (formattedMail)
|
|
|
|
[addresses addObject: formattedMail];
|
2009-08-24 21:40:29 +02:00
|
|
|
}
|
2009-10-23 22:25:36 +02:00
|
|
|
|
2009-08-24 21:40:29 +02:00
|
|
|
uid = [uids nextObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([addresses count] > 0)
|
2010-09-02 21:00:38 +02:00
|
|
|
parameters = [NSString stringWithFormat: @"?mailto=%@",
|
2012-02-02 21:46:30 +01:00
|
|
|
[addresses jsonRepresentation]];
|
2009-08-24 21:40:29 +02:00
|
|
|
}
|
2008-07-08 13:32:43 +02:00
|
|
|
}
|
|
|
|
else if ([[request formValues] objectForKey: @"mailto"])
|
|
|
|
// We use the email addresses defined in the request
|
|
|
|
parameters = [[request formValues] asURLParameters];
|
2009-08-24 21:40:29 +02:00
|
|
|
|
2008-07-08 13:32:43 +02:00
|
|
|
if (!parameters)
|
|
|
|
// No parameter passed; simply open the compose window
|
|
|
|
parameters = @"?mailto=";
|
|
|
|
|
2010-08-03 20:52:49 +02:00
|
|
|
newLocation = [NSString stringWithFormat: @"%@/0/compose%@",
|
2009-08-24 21:40:29 +02:00
|
|
|
[co baseURLInContext: context],
|
|
|
|
parameters];
|
2007-08-21 16:49:48 +02:00
|
|
|
|
|
|
|
return [self redirectToLocation: newLocation];
|
|
|
|
}
|
|
|
|
|
2009-08-24 22:26:52 +02:00
|
|
|
- (NSString *) formattedMailtoString: (NGVCard *) card
|
|
|
|
{
|
2011-11-14 17:07:04 +01:00
|
|
|
NSString *firstName, *lastName, *email;
|
2009-08-24 22:26:52 +02:00
|
|
|
NSMutableString *fn, *rc = nil;
|
2011-11-14 17:07:04 +01:00
|
|
|
CardElement *n;
|
2009-08-24 22:26:52 +02:00
|
|
|
|
2009-08-24 23:02:47 +02:00
|
|
|
if ([card isKindOfClass: [NGVCard class]])
|
2009-08-24 22:26:52 +02:00
|
|
|
email = [card preferredEMail];
|
|
|
|
else
|
2009-08-24 23:02:47 +02:00
|
|
|
email = [(NGVCardReference *)card email];
|
2009-08-24 22:26:52 +02:00
|
|
|
|
|
|
|
if (email == nil)
|
|
|
|
email = (NSString*)[card firstChildWithTag: @"EMAIL"];
|
|
|
|
|
|
|
|
if (email)
|
|
|
|
{
|
|
|
|
email = [NSString stringWithFormat: @"<%@>", email];
|
|
|
|
|
|
|
|
// We append the contact's name
|
|
|
|
fn = [NSMutableString stringWithString: [card fn]];
|
2009-10-23 21:57:53 +02:00
|
|
|
if ([fn length] == 0
|
|
|
|
&& [card isKindOfClass: [NGVCard class]])
|
2009-08-24 22:26:52 +02:00
|
|
|
{
|
|
|
|
n = [card n];
|
2011-11-14 17:07:04 +01:00
|
|
|
lastName = [n flattenedValueAtIndex: 0 forKey: @""];
|
|
|
|
firstName = [n flattenedValueAtIndex: 1 forKey: @""];
|
|
|
|
if ([firstName length] > 0)
|
2009-08-24 22:26:52 +02:00
|
|
|
{
|
2011-11-14 17:07:04 +01:00
|
|
|
if ([lastName length] > 0)
|
|
|
|
fn = [NSMutableString stringWithFormat: @"%@ %@", firstName, lastName];
|
|
|
|
else
|
|
|
|
fn = [NSMutableString stringWithString: firstName];
|
2009-08-24 22:26:52 +02:00
|
|
|
}
|
2011-11-14 17:07:04 +01:00
|
|
|
else if ([lastName length] > 0)
|
|
|
|
fn = [NSMutableString stringWithString: lastName];
|
2009-08-24 22:26:52 +02:00
|
|
|
}
|
2009-10-23 21:57:53 +02:00
|
|
|
if ([fn length] > 0)
|
2009-08-24 22:26:52 +02:00
|
|
|
{
|
|
|
|
[fn appendFormat: @" %@", email];
|
|
|
|
rc = fn;
|
|
|
|
}
|
|
|
|
else
|
2009-08-24 23:02:47 +02:00
|
|
|
rc = [NSMutableString stringWithString: email];
|
2009-08-24 22:26:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-03-25 20:59:13 +01:00
|
|
|
- (WOResponse *) getFoldersStateAction
|
2008-02-01 19:44:58 +01:00
|
|
|
{
|
2008-03-25 20:59:13 +01:00
|
|
|
NSString *expandedFolders;
|
2008-02-01 19:44:58 +01:00
|
|
|
|
|
|
|
[self _setupContext];
|
2008-03-25 20:59:13 +01:00
|
|
|
expandedFolders = [moduleSettings objectForKey: @"ExpandedFolders"];
|
2008-02-01 19:44:58 +01:00
|
|
|
|
2008-03-25 20:59:13 +01:00
|
|
|
return [self responseWithStatus: 200 andString: expandedFolders];
|
|
|
|
}
|
2008-02-04 23:22:14 +01:00
|
|
|
|
2008-03-25 20:59:13 +01:00
|
|
|
- (NSString *) verticalDragHandleStyle
|
|
|
|
{
|
|
|
|
NSString *vertical;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
vertical = [moduleSettings objectForKey: @"DragHandleVertical"];
|
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
return ((vertical && [vertical intValue] > 0) ? (id)[vertical stringByAppendingString: @"px"] : nil);
|
2008-02-01 19:44:58 +01:00
|
|
|
}
|
|
|
|
|
2008-03-25 20:59:13 +01:00
|
|
|
- (NSString *) horizontalDragHandleStyle
|
2007-12-13 22:07:09 +01:00
|
|
|
{
|
2008-03-25 20:59:13 +01:00
|
|
|
NSString *horizontal;
|
2007-12-13 22:07:09 +01:00
|
|
|
|
2008-03-25 20:59:13 +01:00
|
|
|
[self _setupContext];
|
|
|
|
horizontal = [moduleSettings objectForKey: @"DragHandleHorizontal"];
|
2007-12-13 22:07:09 +01:00
|
|
|
|
2010-06-25 21:58:30 +02:00
|
|
|
return ((horizontal && [horizontal intValue] > 0) ? (id)[horizontal stringByAppendingString: @"px"] : nil);
|
2008-03-25 20:59:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) mailboxContentStyle
|
|
|
|
{
|
|
|
|
NSString *height;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
height = [moduleSettings objectForKey: @"DragHandleVertical"];
|
|
|
|
|
2009-04-01 15:49:24 +02:00
|
|
|
return ((height && [height intValue] > 0) ? (id)[NSString stringWithFormat: @"%ipx", ([height intValue] - 27)] : nil);
|
2007-12-13 22:07:09 +01:00
|
|
|
}
|
|
|
|
|
2008-02-04 23:22:14 +01:00
|
|
|
- (WOResponse *) saveDragHandleStateAction
|
2008-02-01 19:44:58 +01:00
|
|
|
{
|
|
|
|
WORequest *request;
|
2008-02-04 23:22:14 +01:00
|
|
|
NSString *dragHandle;
|
2008-02-01 19:44:58 +01:00
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
request = [context request];
|
|
|
|
|
2008-02-04 23:22:14 +01:00
|
|
|
if ((dragHandle = [request formValueForKey: @"vertical"]) != nil)
|
|
|
|
[moduleSettings setObject: dragHandle
|
|
|
|
forKey: @"DragHandleVertical"];
|
|
|
|
else if ((dragHandle = [request formValueForKey: @"horizontal"]) != nil)
|
|
|
|
[moduleSettings setObject: dragHandle
|
|
|
|
forKey: @"DragHandleHorizontal"];
|
|
|
|
else
|
|
|
|
return [self responseWithStatus: 400];
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
[us synchronize];
|
2008-02-04 23:22:14 +01:00
|
|
|
|
2008-02-01 19:44:58 +01:00
|
|
|
return [self responseWithStatus: 204];
|
|
|
|
}
|
|
|
|
|
2007-12-13 22:07:09 +01:00
|
|
|
- (WOResponse *) saveFoldersStateAction
|
|
|
|
{
|
|
|
|
WORequest *request;
|
|
|
|
NSString *expandedFolders;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
request = [context request];
|
|
|
|
expandedFolders = [request formValueForKey: @"expandedFolders"];
|
|
|
|
|
|
|
|
[moduleSettings setObject: expandedFolders
|
|
|
|
forKey: @"ExpandedFolders"];
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
[us synchronize];
|
2007-12-13 22:07:09 +01:00
|
|
|
|
|
|
|
return [self responseWithStatus: 204];
|
|
|
|
}
|
|
|
|
|
2010-05-28 21:18:52 +02:00
|
|
|
- (NSString *) columnsState
|
|
|
|
{
|
|
|
|
NSDictionary *columns;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
columns = [moduleSettings objectForKey: @"ColumnsState"];
|
|
|
|
|
|
|
|
return [columns jsonRepresentation];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (WOResponse *) saveColumnsStateAction
|
|
|
|
{
|
|
|
|
WORequest *request;
|
|
|
|
NSDictionary *columns;
|
|
|
|
NSArray *columnsIds, *widths;
|
|
|
|
|
|
|
|
[self _setupContext];
|
|
|
|
request = [context request];
|
|
|
|
|
|
|
|
columnsIds = [[request formValueForKey: @"columns"] componentsSeparatedByString: @","];
|
|
|
|
widths = [[request formValueForKey: @"widths"] componentsSeparatedByString: @","];
|
|
|
|
if (columnsIds != nil && widths != nil && [columnsIds count] == [widths count])
|
|
|
|
{
|
|
|
|
columns = [NSDictionary dictionaryWithObjects: widths
|
|
|
|
forKeys: columnsIds];
|
|
|
|
[moduleSettings setObject: columns
|
|
|
|
forKey: @"ColumnsState"];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return [self responseWithStatus: 400];
|
|
|
|
|
|
|
|
[us synchronize];
|
|
|
|
|
|
|
|
return [self responseWithStatus: 204];
|
|
|
|
}
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
- (id) defaultAction
|
|
|
|
{
|
|
|
|
SOGoUserDefaults *ud;
|
|
|
|
|
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
if ([ud rememberLastModule])
|
|
|
|
{
|
|
|
|
[ud setLoginModule: @"Mail"];
|
|
|
|
[ud synchronize];
|
|
|
|
}
|
|
|
|
|
|
|
|
return [super defaultAction];
|
|
|
|
}
|
|
|
|
|
2010-05-27 16:41:59 +02:00
|
|
|
- (BOOL) showToAddress
|
|
|
|
{
|
|
|
|
SOGoMailFolder *co;
|
|
|
|
|
|
|
|
if (!folderType)
|
|
|
|
{
|
|
|
|
co = [self clientObject];
|
|
|
|
if ([co isKindOfClass: [SOGoSentFolder class]]
|
|
|
|
|| [co isKindOfClass: [SOGoDraftsFolder class]])
|
|
|
|
folderType = 1;
|
|
|
|
else
|
|
|
|
folderType = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (folderType == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *) columnsMetaData
|
|
|
|
{
|
|
|
|
NSMutableDictionary *columnsMetaData;
|
|
|
|
NSArray *tmpColumns, *tmpKeys;
|
|
|
|
|
|
|
|
columnsMetaData = [NSMutableDictionary dictionaryWithCapacity: 8];
|
|
|
|
|
|
|
|
tmpKeys = [NSArray arrayWithObjects: @"headerClass", @"headerId", @"value",
|
2011-06-01 23:10:25 +02:00
|
|
|
nil];
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageThreadColumn tbtv_headercell",
|
|
|
|
@"invisibleHeader", @"Thread", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Thread"];
|
2010-05-27 16:41:59 +02:00
|
|
|
|
2011-07-07 15:58:50 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageSubjectColumn tbtv_headercell sortableTableHeader resizable",
|
|
|
|
@"subjectHeader", @"Subject", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Subject"];
|
|
|
|
|
2010-05-27 16:41:59 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageFlagColumn tbtv_headercell",
|
|
|
|
@"invisibleHeader", @"Flagged", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Flagged"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageFlagColumn tbtv_headercell",
|
|
|
|
@"attachmentHeader", @"Attachment", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Attachment"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageFlagColumn tbtv_headercell", @"messageFlagHeader",
|
|
|
|
@"Unread", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns forKeys: tmpKeys]
|
|
|
|
forKey: @"Unread"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageAddressHeader tbtv_headercell sortableTableHeader resizable",
|
|
|
|
@"toHeader", @"To", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns forKeys: tmpKeys]
|
|
|
|
forKey: @"To"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageAddressColumn tbtv_headercell sortableTableHeader resizable",
|
|
|
|
@"fromHeader", @"From", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"From"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageDateColumn tbtv_headercell sortableTableHeader resizable",
|
|
|
|
@"dateHeader", @"Date", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Date"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messagePriorityColumn tbtv_headercell resizable", @"priorityHeader",
|
|
|
|
@"Priority", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Priority"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"messageSizeColumn tbtv_headercell sortableTableHeader", @"sizeHeader",
|
|
|
|
@"Size", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Size"];
|
|
|
|
|
|
|
|
return columnsMetaData;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) columnsDisplayOrder
|
|
|
|
{
|
|
|
|
NSMutableArray *finalOrder, *invalid;
|
|
|
|
NSArray *available;
|
|
|
|
NSDictionary *metaData;
|
|
|
|
SOGoUserDefaults *ud;
|
2012-05-29 20:56:15 +02:00
|
|
|
NSUInteger i;
|
2010-05-27 16:41:59 +02:00
|
|
|
|
|
|
|
if (!columnsOrder)
|
|
|
|
{
|
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
columnsOrder = [ud mailListViewColumnsOrder];
|
|
|
|
|
|
|
|
metaData = [self columnsMetaData];
|
|
|
|
|
|
|
|
invalid = [columnsOrder mutableCopy];
|
|
|
|
[invalid autorelease];
|
|
|
|
available = [metaData allKeys];
|
|
|
|
[invalid removeObjectsInArray: available];
|
|
|
|
if ([invalid count] > 0)
|
|
|
|
{
|
|
|
|
[self errorWithFormat: @"those column names specified in"
|
|
|
|
@" SOGoMailListViewColumnsOrder are invalid: '%@'",
|
|
|
|
[invalid componentsJoinedByString: @"', '"]];
|
|
|
|
[self errorWithFormat: @" falling back on hardcoded column order"];
|
|
|
|
columnsOrder = available;
|
|
|
|
}
|
|
|
|
|
|
|
|
finalOrder = [columnsOrder mutableCopy];
|
|
|
|
[finalOrder autorelease];
|
2011-06-01 23:10:25 +02:00
|
|
|
|
|
|
|
if (![ud mailSortByThreads])
|
|
|
|
[finalOrder removeObject: @"Thread"];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i = [finalOrder indexOfObject: @"Thread"];
|
|
|
|
if (i == NSNotFound)
|
|
|
|
[finalOrder insertObject: @"Thread" atIndex: 0];
|
|
|
|
}
|
2010-05-27 16:41:59 +02:00
|
|
|
if ([self showToAddress])
|
|
|
|
{
|
|
|
|
i = [finalOrder indexOfObject: @"From"];
|
|
|
|
if (i != NSNotFound)
|
|
|
|
{
|
|
|
|
[finalOrder removeObject: @"To"];
|
|
|
|
[finalOrder replaceObjectAtIndex: i withObject: @"To"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i = [finalOrder indexOfObject: @"To"];
|
|
|
|
if (i != NSNotFound)
|
|
|
|
{
|
|
|
|
[finalOrder removeObject: @"From"];
|
|
|
|
[finalOrder replaceObjectAtIndex: i withObject: @"From"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
columnsOrder = [[self columnsMetaData] objectsForKeys: finalOrder
|
|
|
|
notFoundMarker: @""];
|
|
|
|
[columnsOrder retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return columnsOrder;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) columnsDisplayCount
|
|
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"%d", [[self columnsDisplayOrder] count]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCurrentColumn: (NSDictionary *) newCurrentColumn
|
|
|
|
{
|
|
|
|
ASSIGN (currentColumn, newCurrentColumn);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *) currentColumn
|
|
|
|
{
|
|
|
|
return currentColumn;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) columnTitle
|
|
|
|
{
|
|
|
|
return [self labelForKey: [currentColumn objectForKey: @"value"]];
|
|
|
|
}
|
|
|
|
|
2011-12-29 18:50:48 +01:00
|
|
|
- (NSString *) unseenCountFolders
|
2010-08-12 22:51:10 +02:00
|
|
|
{
|
2011-12-29 18:50:48 +01:00
|
|
|
NSArray *pathComponents, *filters, *actions;
|
|
|
|
NSDictionary *d, *action;
|
|
|
|
NSMutableArray *folders;
|
|
|
|
NSMutableString *path;
|
|
|
|
SOGoUserDefaults *ud;
|
2012-05-29 20:56:15 +02:00
|
|
|
NSString *s;
|
|
|
|
NSUInteger i, j, k;
|
2011-12-29 18:50:48 +01:00
|
|
|
|
2012-05-31 18:25:31 +02:00
|
|
|
// If Sieve scripts aren't enabled, there's no need in considering
|
|
|
|
// what's potentially in the database regarding "fileinto" scripts.
|
|
|
|
if (![[[context activeUser] domainDefaults] sieveScriptsEnabled])
|
|
|
|
return [[NSArray array] jsonRepresentation];
|
|
|
|
|
2011-12-29 18:50:48 +01:00
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
folders = [NSMutableArray array];
|
2010-08-12 22:51:10 +02:00
|
|
|
|
2011-12-29 18:50:48 +01:00
|
|
|
filters = [ud sieveFilters];
|
2010-08-12 22:51:10 +02:00
|
|
|
|
2011-12-29 18:50:48 +01:00
|
|
|
for (i = 0; i < [filters count]; i++)
|
|
|
|
{
|
|
|
|
d = [filters objectAtIndex: i];
|
|
|
|
actions = [d objectForKey: @"actions"];
|
|
|
|
|
|
|
|
for (j = 0; j < [actions count]; j++)
|
|
|
|
{
|
|
|
|
action = [actions objectAtIndex: j];
|
|
|
|
|
|
|
|
if ([[action objectForKey: @"method"] caseInsensitiveCompare: @"fileinto"] == NSOrderedSame)
|
|
|
|
{
|
|
|
|
s = [action objectForKey: @"argument"];
|
|
|
|
|
|
|
|
// We format the result string so that MailerUI.js can simply consume that information
|
|
|
|
// without doing anything special on its side
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
pathComponents = [s componentsSeparatedByString: @"/"];
|
|
|
|
path = [NSMutableString string];
|
|
|
|
|
|
|
|
for (k = 0; k < [pathComponents count]; k++)
|
|
|
|
{
|
|
|
|
[path appendFormat: @"folder%@", [[pathComponents objectAtIndex: k] asCSSIdentifier]];
|
|
|
|
if (k < [pathComponents count] - 1)
|
|
|
|
[path appendString: @"/"];
|
|
|
|
}
|
|
|
|
|
|
|
|
[folders addObject: [NSString stringWithFormat: @"/0/%@", path]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return [folders jsonRepresentation];
|
2010-08-12 22:51:10 +02:00
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@end /* UIxMailMainFrame */
|