2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
2009-03-24 16:55:55 +01:00
|
|
|
Copyright (C) 2006-2009 Inverse inc.
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2009-03-24 16:55:55 +01:00
|
|
|
This file is part of SOGo
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2009-03-24 16:55:55 +01: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-03-24 16:55:55 +01: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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
UIxMailListView
|
|
|
|
|
|
|
|
This component represent a list of mails and is attached to an SOGoMailFolder
|
|
|
|
object.
|
|
|
|
*/
|
|
|
|
|
2007-06-19 20:07:21 +02:00
|
|
|
#import <Foundation/NSCalendarDate.h>
|
2008-09-28 16:02:40 +02:00
|
|
|
#import <Foundation/NSCharacterSet.h>
|
2007-06-19 20:07:21 +02:00
|
|
|
#import <Foundation/NSDictionary.h>
|
2008-07-04 18:06:09 +02:00
|
|
|
#import <Foundation/NSEnumerator.h>
|
2007-11-09 00:18:52 +01:00
|
|
|
#import <Foundation/NSTimeZone.h>
|
2007-06-19 20:07:21 +02:00
|
|
|
#import <Foundation/NSValue.h>
|
2007-11-09 00:18:52 +01:00
|
|
|
|
2007-06-19 20:07:21 +02:00
|
|
|
#import <NGObjWeb/WOResponse.h>
|
|
|
|
#import <NGObjWeb/WORequest.h>
|
|
|
|
#import <NGObjWeb/SoObject+SoDAV.h>
|
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
|
|
|
#import <NGExtensions/NSNull+misc.h>
|
|
|
|
#import <NGExtensions/NSString+misc.h>
|
2009-09-22 17:58:43 +02:00
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
2007-06-19 20:07:21 +02:00
|
|
|
|
2007-06-27 23:26:44 +02:00
|
|
|
#import <EOControl/EOQualifier.h>
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
#import <Mailer/NSString+Mail.h>
|
|
|
|
#import <Mailer/SOGoDraftsFolder.h>
|
|
|
|
#import <Mailer/SOGoMailFolder.h>
|
|
|
|
#import <Mailer/SOGoMailObject.h>
|
|
|
|
#import <Mailer/SOGoSentFolder.h>
|
|
|
|
#import <SOGo/NSArray+Utilities.h>
|
|
|
|
#import <SOGo/SOGoDateFormatter.h>
|
|
|
|
#import <SOGo/SOGoUser.h>
|
|
|
|
#import <SOGo/SOGoUserDefaults.h>
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
#import "UIxMailListView.h"
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-06-19 20:07:21 +02:00
|
|
|
#define messagesPerPage 50
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
@implementation UIxMailListView
|
|
|
|
|
2007-06-27 23:26:44 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
SOGoUser *user;
|
|
|
|
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
|
|
|
qualifier = nil;
|
|
|
|
user = [context activeUser];
|
|
|
|
ASSIGN (dateFormatter, [user dateFormatterInContext: context]);
|
2009-11-29 05:19:32 +01:00
|
|
|
ASSIGN (userTimeZone, [[user userDefaults] timeZone]);
|
|
|
|
columnsOrder = nil;
|
2007-11-05 23:39:10 +01:00
|
|
|
folderType = 0;
|
2008-10-08 20:38:03 +02:00
|
|
|
currentColumn = nil;
|
2007-06-27 23:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
2007-06-27 23:26:44 +02:00
|
|
|
[qualifier release];
|
|
|
|
[sortedUIDs release];
|
|
|
|
[messages release];
|
|
|
|
[message release];
|
2007-06-19 20:07:21 +02:00
|
|
|
[dateFormatter release];
|
|
|
|
[userTimeZone release];
|
2008-10-08 20:38:03 +02:00
|
|
|
[currentColumn release];
|
2009-11-29 05:19:32 +01:00
|
|
|
[columnsOrder release];
|
2006-06-15 21:34:10 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* accessors */
|
|
|
|
|
2007-06-27 23:26:44 +02:00
|
|
|
- (void) setMessage: (id) _msg
|
2006-07-29 00:59:11 +02:00
|
|
|
{
|
2007-10-29 21:46:59 +01:00
|
|
|
ASSIGN (message, _msg);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
- (id) message
|
|
|
|
{
|
2007-06-27 23:26:44 +02:00
|
|
|
return message;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-06-19 20:07:21 +02:00
|
|
|
- (NSString *) messageDate
|
|
|
|
{
|
|
|
|
NSCalendarDate *messageDate;
|
|
|
|
|
2007-07-13 15:45:37 +02:00
|
|
|
messageDate = [[message valueForKey: @"envelope"] date];
|
2007-06-19 20:07:21 +02:00
|
|
|
[messageDate setTimeZone: userTimeZone];
|
|
|
|
|
|
|
|
return [dateFormatter formattedDateAndTime: messageDate];
|
|
|
|
}
|
|
|
|
|
2009-06-30 22:10:09 +02:00
|
|
|
- (NSString *) messageSize
|
|
|
|
{
|
|
|
|
NSString *rc;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
size = [[message valueForKey: @"size"] intValue];
|
2010-02-08 17:11:37 +01:00
|
|
|
if (size > 1024*1024)
|
|
|
|
rc = [NSString stringWithFormat: @"%.1f MB", (float) size/1024/1024];
|
|
|
|
else if (size > 1024*100)
|
|
|
|
rc = [NSString stringWithFormat: @"%d KB", size/1024];
|
|
|
|
else
|
|
|
|
rc = [NSString stringWithFormat: @"%.1f KB", (float) size/1024];
|
|
|
|
|
2009-06-30 22:10:09 +02:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2008-09-28 16:02:40 +02:00
|
|
|
//
|
|
|
|
// Priorities are defined like this:
|
|
|
|
//
|
|
|
|
// X-Priority: 1 (Highest)
|
|
|
|
// X-Priority: 2 (High)
|
|
|
|
// X-Priority: 3 (Normal)
|
|
|
|
// X-Priority: 4 (Low)
|
|
|
|
// X-Priority: 5 (Lowest)
|
|
|
|
//
|
|
|
|
// Sometimes, the MUAs don't send over the string in () so we ignore it.
|
|
|
|
//
|
|
|
|
- (NSString *) messagePriority
|
|
|
|
{
|
|
|
|
NSString *result;
|
|
|
|
NSData *data;
|
|
|
|
|
|
|
|
data = [message objectForKey: @"header"];
|
|
|
|
result = @"";
|
|
|
|
|
|
|
|
if (data)
|
|
|
|
{
|
|
|
|
NSString *s;
|
|
|
|
|
|
|
|
s = [[NSString alloc] initWithData: data
|
|
|
|
encoding: NSASCIIStringEncoding];
|
|
|
|
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
[s autorelease];
|
|
|
|
r = [s rangeOfString: @":"];
|
|
|
|
|
|
|
|
if (r.length)
|
|
|
|
{
|
|
|
|
s = [[s substringFromIndex: r.location+1]
|
|
|
|
stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
|
|
|
|
|
|
if ([s hasPrefix: @"1"]) result = [self labelForKey: @"highest"];
|
|
|
|
else if ([s hasPrefix: @"2"]) result = [self labelForKey: @"high"];
|
|
|
|
else if ([s hasPrefix: @"4"]) result = [self labelForKey: @"low"];
|
|
|
|
else if ([s hasPrefix: @"5"]) result = [self labelForKey: @"lowest"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2007-09-17 19:24:22 +02:00
|
|
|
- (NSString *) messageSubject
|
|
|
|
{
|
2007-11-05 17:37:17 +01:00
|
|
|
id baseSubject;
|
2007-09-17 19:24:22 +02:00
|
|
|
NSString *subject;
|
|
|
|
|
2007-11-05 17:37:17 +01:00
|
|
|
baseSubject = [[message valueForKey: @"envelope"] subject];
|
2009-11-25 03:34:24 +01:00
|
|
|
subject = [baseSubject decodedHeader];
|
2007-11-05 17:37:17 +01:00
|
|
|
if (![subject length])
|
|
|
|
subject = [self labelForKey: @"Untitled"];
|
2007-09-17 19:24:22 +02:00
|
|
|
|
|
|
|
return subject;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) showToAddress
|
|
|
|
{
|
2007-11-05 23:39:10 +01:00
|
|
|
SOGoMailFolder *co;
|
|
|
|
|
|
|
|
if (!folderType)
|
|
|
|
{
|
|
|
|
co = [self clientObject];
|
|
|
|
if ([co isKindOfClass: [SOGoSentFolder class]]
|
|
|
|
|| [co isKindOfClass: [SOGoDraftsFolder class]])
|
|
|
|
folderType = 1;
|
|
|
|
else
|
|
|
|
folderType = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (folderType == 1);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* title */
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) objectTitle
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self clientObject] nameInContainer];
|
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
- (NSString *) panelTitle
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *s;
|
|
|
|
|
|
|
|
s = [self labelForKey:@"View Mail Folder"];
|
|
|
|
s = [s stringByAppendingString:@": "];
|
|
|
|
s = [s stringByAppendingString:[self objectTitle]];
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* derived accessors */
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) isMessageDeleted
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *flags;
|
|
|
|
|
|
|
|
flags = [[self message] valueForKey:@"flags"];
|
|
|
|
return [flags containsObject:@"deleted"];
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) isMessageRead
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *flags;
|
|
|
|
|
|
|
|
flags = [[self message] valueForKey:@"flags"];
|
|
|
|
return [flags containsObject:@"seen"];
|
|
|
|
}
|
2007-09-10 22:58:57 +02:00
|
|
|
|
2009-08-19 20:22:25 +02:00
|
|
|
- (BOOL) isMessageFlagged
|
|
|
|
{
|
|
|
|
NSArray *flags;
|
|
|
|
|
|
|
|
flags = [[self message] valueForKey:@"flags"];
|
|
|
|
return [flags containsObject:@"flagged"];
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) messageUidString
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[[self message] valueForKey:@"uid"] stringValue];
|
|
|
|
}
|
|
|
|
|
2007-06-14 00:06:01 +02:00
|
|
|
- (NSString *) messageRowStyleClass
|
2006-07-29 00:59:11 +02:00
|
|
|
{
|
2007-11-05 22:19:09 +01:00
|
|
|
NSString *rowClass;
|
|
|
|
|
|
|
|
rowClass = [self isMessageDeleted]? @"mailer_listcell_deleted" : @"mailer_listcell_regular";
|
|
|
|
|
|
|
|
if (![self isMessageRead])
|
|
|
|
rowClass = [rowClass stringByAppendingString: @" mailer_unreadmail"];
|
|
|
|
|
|
|
|
return rowClass;
|
2006-07-29 00:59:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) messageSubjectCellStyleClass
|
|
|
|
{
|
2007-10-25 22:07:56 +02:00
|
|
|
NSArray *flags;
|
2007-11-05 22:19:09 +01:00
|
|
|
NSString *cellClass = @"messageSubjectColumn ";
|
2007-10-25 22:07:56 +02:00
|
|
|
|
|
|
|
flags = [[self message] valueForKey:@"flags"];
|
|
|
|
|
2007-11-05 22:19:09 +01:00
|
|
|
if ([flags containsObject: @"answered"])
|
2007-10-25 22:07:56 +02:00
|
|
|
{
|
2007-11-05 22:19:09 +01:00
|
|
|
if ([flags containsObject: @"$forwarded"])
|
|
|
|
cellClass = [cellClass stringByAppendingString: @"mailer_forwardedrepliedmailsubject"];
|
2007-10-25 22:07:56 +02:00
|
|
|
else
|
2007-11-05 22:19:09 +01:00
|
|
|
cellClass = [cellClass stringByAppendingString: @"mailer_repliedmailsubject"];
|
2007-10-25 22:07:56 +02:00
|
|
|
}
|
2007-11-05 22:19:09 +01:00
|
|
|
else if ([flags containsObject: @"$forwarded"])
|
|
|
|
cellClass = [cellClass stringByAppendingString: @"mailer_forwardedmailsubject"];
|
2007-10-25 22:07:56 +02:00
|
|
|
else
|
2007-11-05 22:19:09 +01:00
|
|
|
cellClass = [cellClass stringByAppendingString: @"mailer_readmailsubject"];
|
2007-10-25 22:07:56 +02:00
|
|
|
|
|
|
|
return cellClass;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-12 00:29:19 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) hasMessageAttachment
|
|
|
|
{
|
2007-10-29 21:46:59 +01:00
|
|
|
NSArray *parts;
|
|
|
|
NSEnumerator *dispositions;
|
|
|
|
NSDictionary *currentDisp;
|
|
|
|
BOOL hasAttachment;
|
|
|
|
|
2007-11-01 18:09:58 +01:00
|
|
|
hasAttachment = NO;
|
|
|
|
|
2007-10-29 21:46:59 +01:00
|
|
|
parts = [[message objectForKey: @"body"] objectForKey: @"parts"];
|
|
|
|
if ([parts count] > 1)
|
|
|
|
{
|
2008-10-23 17:35:20 +02:00
|
|
|
dispositions = [[parts objectsForKey: @"disposition"
|
|
|
|
notFoundMarker: nil] objectEnumerator];
|
2007-10-29 21:46:59 +01:00
|
|
|
while (!hasAttachment
|
|
|
|
&& (currentDisp = [dispositions nextObject]))
|
2008-10-23 17:35:20 +02:00
|
|
|
hasAttachment = ([[currentDisp objectForKey: @"type"] length]);
|
2007-10-29 21:46:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return hasAttachment;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* fetching messages */
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSArray *) fetchKeys
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* Note: see SOGoMailManager.m for allowed IMAP4 keys */
|
|
|
|
static NSArray *keys = nil;
|
2007-10-29 21:46:59 +01:00
|
|
|
|
|
|
|
if (!keys)
|
2007-06-28 20:28:33 +02:00
|
|
|
keys = [[NSArray alloc] initWithObjects: @"UID",
|
2008-09-28 16:02:40 +02:00
|
|
|
@"FLAGS", @"ENVELOPE", @"RFC822.SIZE",
|
2008-10-02 14:38:14 +02:00
|
|
|
@"BODYSTRUCTURE", @"BODY.PEEK[HEADER.FIELDS (X-PRIORITY)]", nil];
|
2006-06-15 21:34:10 +02:00
|
|
|
return keys;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) defaultSortKey
|
|
|
|
{
|
2007-06-28 20:28:33 +02:00
|
|
|
return @"ARRIVAL";
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) imap4SortKey
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSString *sort;
|
|
|
|
|
2007-06-28 20:28:33 +02:00
|
|
|
sort = [[context request] formValueForKey: @"sort"];
|
2006-08-01 19:56:51 +02:00
|
|
|
|
2007-06-28 20:28:33 +02:00
|
|
|
if (![sort length])
|
2006-06-15 21:34:10 +02:00
|
|
|
sort = [self defaultSortKey];
|
2006-08-01 19:56:51 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return [sort uppercaseString];
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) imap4SortOrdering
|
|
|
|
{
|
2007-06-28 20:28:33 +02:00
|
|
|
NSString *sort, *ascending;
|
2006-08-01 19:56:51 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
sort = [self imap4SortKey];
|
2006-08-01 19:56:51 +02:00
|
|
|
|
2007-06-28 20:28:33 +02:00
|
|
|
ascending = [[context request] formValueForKey: @"asc"];
|
|
|
|
if (![ascending boolValue])
|
2006-08-01 19:56:51 +02:00
|
|
|
sort = [@"REVERSE " stringByAppendingString: sort];
|
|
|
|
|
|
|
|
return sort;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSRange) fetchRange
|
|
|
|
{
|
2007-06-27 23:26:44 +02:00
|
|
|
if (firstMessageNumber == 0)
|
2006-07-31 22:16:45 +02:00
|
|
|
return NSMakeRange(0, messagesPerPage);
|
2007-06-27 23:26:44 +02:00
|
|
|
return NSMakeRange(firstMessageNumber - 1, messagesPerPage);
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSArray *) sortedUIDs
|
|
|
|
{
|
2007-09-11 17:07:30 +02:00
|
|
|
EOQualifier *fetchQualifier, *notDeleted;
|
2007-10-29 19:58:14 +01:00
|
|
|
|
2006-08-01 19:56:51 +02:00
|
|
|
if (!sortedUIDs)
|
|
|
|
{
|
2007-09-11 17:07:30 +02:00
|
|
|
notDeleted = [EOQualifier qualifierWithQualifierFormat:
|
|
|
|
@"(not (flags = %@))",
|
|
|
|
@"deleted"];
|
|
|
|
if (qualifier)
|
|
|
|
{
|
|
|
|
fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers:
|
|
|
|
notDeleted, qualifier,
|
|
|
|
nil];
|
|
|
|
[fetchQualifier autorelease];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fetchQualifier = notDeleted;
|
|
|
|
|
2007-06-28 20:28:33 +02:00
|
|
|
sortedUIDs
|
2007-09-11 17:07:30 +02:00
|
|
|
= [[self clientObject] fetchUIDsMatchingQualifier: fetchQualifier
|
2007-06-28 20:28:33 +02:00
|
|
|
sortOrdering: [self imap4SortOrdering]];
|
2006-08-01 19:56:51 +02:00
|
|
|
[sortedUIDs retain];
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2007-06-27 23:26:44 +02:00
|
|
|
return sortedUIDs;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
- (unsigned int) totalMessageCount
|
|
|
|
{
|
2007-06-27 23:26:44 +02:00
|
|
|
return [sortedUIDs count];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
- (BOOL) showsAllMessages
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return ([[self sortedUIDs] count] <= [self fetchRange].length) ? YES : NO;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSRange) fetchBlock
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSRange r;
|
|
|
|
unsigned len;
|
|
|
|
NSArray *uids;
|
|
|
|
|
|
|
|
r = [self fetchRange];
|
|
|
|
uids = [self sortedUIDs];
|
|
|
|
|
|
|
|
/* only need to restrict if we have a lot */
|
|
|
|
if ((len = [uids count]) <= r.length) {
|
|
|
|
r.location = 0;
|
|
|
|
r.length = len;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len < r.location) {
|
|
|
|
// TODO: CHECK CONDITION (< vs <=)
|
|
|
|
/* out of range, recover at first block */
|
|
|
|
r.location = 0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r.location + r.length > len)
|
|
|
|
r.length = len - r.location;
|
|
|
|
return r;
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (unsigned int) firstMessageNumber
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self fetchBlock].location + 1;
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (unsigned int) lastMessageNumber
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
r = [self fetchBlock];
|
|
|
|
return r.location + r.length;
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) hasPrevious
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self fetchBlock].location == 0 ? NO : YES;
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (BOOL) hasNext
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSRange r = [self fetchBlock];
|
|
|
|
return r.location + r.length >= [[self sortedUIDs] count] ? NO : YES;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (unsigned int) nextFirstMessageNumber
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self firstMessageNumber] + [self fetchRange].length;
|
|
|
|
}
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2007-10-29 19:58:14 +01:00
|
|
|
- (unsigned int) lastFirstMessageNumber
|
|
|
|
{
|
|
|
|
unsigned int max, modulo;
|
|
|
|
|
|
|
|
if (!sortedUIDs)
|
|
|
|
[self sortedUIDs];
|
|
|
|
|
|
|
|
max = [sortedUIDs count];
|
|
|
|
modulo = (max % messagesPerPage);
|
|
|
|
if (modulo == 0)
|
|
|
|
modulo = messagesPerPage;
|
|
|
|
|
|
|
|
return (max + 1 - modulo);
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (unsigned int) prevFirstMessageNumber
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSRange r;
|
|
|
|
unsigned idx;
|
|
|
|
|
|
|
|
idx = [self firstMessageNumber];
|
|
|
|
r = [self fetchRange];
|
|
|
|
if (idx > r.length)
|
|
|
|
return (idx - r.length);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSArray *) messages
|
|
|
|
{
|
2009-03-24 16:55:55 +01:00
|
|
|
NSMutableArray *unsortedMsgs;
|
|
|
|
NSMutableDictionary *map;
|
|
|
|
NSDictionary *msgs;
|
2007-10-29 21:46:59 +01:00
|
|
|
NSArray *uids;
|
2009-03-24 16:55:55 +01:00
|
|
|
|
|
|
|
unsigned len, i, count;
|
2007-10-29 21:46:59 +01:00
|
|
|
NSRange r;
|
2009-08-19 19:19:32 +02:00
|
|
|
|
2007-10-29 21:46:59 +01:00
|
|
|
if (!messages)
|
|
|
|
{
|
2009-03-24 16:55:55 +01:00
|
|
|
r = [self fetchBlock];
|
2007-10-29 21:46:59 +01:00
|
|
|
uids = [self sortedUIDs];
|
|
|
|
len = [uids count];
|
2009-03-24 16:55:55 +01:00
|
|
|
|
|
|
|
// only need to restrict if we have a lot
|
2007-10-29 21:46:59 +01:00
|
|
|
if (len > r.length)
|
2009-03-24 16:55:55 +01:00
|
|
|
{
|
2009-02-18 00:45:58 +01:00
|
|
|
uids = [uids subarrayWithRange: r];
|
2009-03-24 16:55:55 +01:00
|
|
|
len = [uids count];
|
|
|
|
}
|
2009-02-18 00:45:58 +01:00
|
|
|
|
|
|
|
// Don't assume the IMAP server return the messages in the
|
|
|
|
// same order as the specified list of UIDs (specially true for
|
|
|
|
// dovecot).
|
2007-11-09 00:05:00 +01:00
|
|
|
msgs = (NSDictionary *) [[self clientObject] fetchUIDs: uids
|
|
|
|
parts: [self fetchKeys]];
|
2009-02-18 00:45:58 +01:00
|
|
|
unsortedMsgs = [msgs objectForKey: @"fetch"];
|
2009-03-24 16:55:55 +01:00
|
|
|
count = [unsortedMsgs count];
|
|
|
|
|
|
|
|
messages = [NSMutableArray arrayWithCapacity: count];
|
|
|
|
|
|
|
|
// We build our uid->message map from our FETCH response
|
|
|
|
map = [[NSMutableDictionary alloc] initWithCapacity: count];
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
[map setObject: [unsortedMsgs objectAtIndex: i]
|
|
|
|
forKey: [[unsortedMsgs objectAtIndex: i] objectForKey: @"uid"]];
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
2009-02-18 00:45:58 +01:00
|
|
|
{
|
2009-03-24 16:55:55 +01:00
|
|
|
[(NSMutableArray *)messages addObject: [map objectForKey: [uids objectAtIndex: i]]];
|
2009-02-18 00:45:58 +01:00
|
|
|
}
|
2009-03-24 16:55:55 +01:00
|
|
|
|
|
|
|
RELEASE(map);
|
|
|
|
RETAIN(messages);
|
2007-10-29 21:46:59 +01:00
|
|
|
}
|
2007-06-27 23:26:44 +02:00
|
|
|
|
|
|
|
return messages;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* URL processing */
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) messageViewTarget
|
|
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"SOGo_msg_%@",
|
|
|
|
[self messageUidString]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
- (NSString *) messageViewURL
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: noframe only when view-target is empty
|
|
|
|
// TODO: markread only if the message is unread
|
|
|
|
NSString *s;
|
|
|
|
|
|
|
|
s = [[self messageUidString] stringByAppendingString:@"/view?noframe=1"];
|
|
|
|
if (![self isMessageRead]) s = [s stringByAppendingString:@"&markread=1"];
|
|
|
|
return s;
|
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) markReadURL
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"markMessageRead?uid=" stringByAppendingString:
|
|
|
|
[self messageUidString]];
|
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
- (NSString *) markUnreadURL
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"markMessageUnread?uid=" stringByAppendingString:
|
|
|
|
[self messageUidString]];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* JavaScript */
|
|
|
|
|
2006-07-12 00:29:19 +02:00
|
|
|
- (NSString *)msgRowID
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"row_" stringByAppendingString:[self messageUidString]];
|
|
|
|
}
|
2006-07-12 00:29:19 +02:00
|
|
|
|
|
|
|
- (NSString *)msgDivID
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"div_" stringByAppendingString:[self messageUidString]];
|
|
|
|
}
|
|
|
|
|
2006-07-12 00:29:19 +02:00
|
|
|
- (NSString *)msgIconReadImgID
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"readdiv_" stringByAppendingString:[self messageUidString]];
|
|
|
|
}
|
2006-07-12 00:29:19 +02:00
|
|
|
|
|
|
|
- (NSString *)msgIconUnreadImgID
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [@"unreaddiv_" stringByAppendingString:[self messageUidString]];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* error redirects */
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (id) redirectToViewWithError: (id) _error
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: DUP in UIxMailAccountView
|
|
|
|
// TODO: improve, localize
|
|
|
|
// TODO: there is a bug in the treeview which preserves the current URL for
|
|
|
|
// the active object (displaying the error again)
|
|
|
|
id url;
|
|
|
|
|
|
|
|
if (![_error isNotNull])
|
|
|
|
return [self redirectToLocation:@"view"];
|
|
|
|
|
|
|
|
if ([_error isKindOfClass:[NSException class]])
|
|
|
|
_error = [_error reason];
|
|
|
|
else if ([_error isKindOfClass:[NSString class]])
|
|
|
|
_error = [_error stringValue];
|
|
|
|
|
|
|
|
url = [_error stringByEscapingURL];
|
|
|
|
url = [@"view?error=" stringByAppendingString:url];
|
|
|
|
return [self redirectToLocation:url];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* actions */
|
|
|
|
|
2006-07-31 22:16:45 +02:00
|
|
|
- (int) firstMessageOfPageFor: (int) messageNbr
|
|
|
|
{
|
|
|
|
NSArray *messageNbrs;
|
|
|
|
int nbrInArray;
|
|
|
|
int firstMessage;
|
|
|
|
|
|
|
|
messageNbrs = [self sortedUIDs];
|
|
|
|
nbrInArray
|
|
|
|
= [messageNbrs indexOfObject: [NSNumber numberWithInt: messageNbr]];
|
|
|
|
if (nbrInArray > -1)
|
|
|
|
firstMessage = ((int) (nbrInArray / messagesPerPage)
|
|
|
|
* messagesPerPage) + 1;
|
|
|
|
else
|
|
|
|
firstMessage = 1;
|
|
|
|
|
|
|
|
return firstMessage;
|
|
|
|
}
|
|
|
|
|
2007-06-27 23:26:44 +02:00
|
|
|
- (void) _setQualifierForCriteria: (NSString *) criteria
|
|
|
|
andValue: (NSString *) value
|
|
|
|
{
|
|
|
|
[qualifier release];
|
|
|
|
|
|
|
|
if ([criteria isEqualToString: @"subject"])
|
|
|
|
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
2007-09-11 17:07:30 +02:00
|
|
|
@"(subject doesContain: %@)", value];
|
2007-06-27 23:26:44 +02:00
|
|
|
else if ([criteria isEqualToString: @"sender"])
|
|
|
|
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
2007-09-13 20:22:23 +02:00
|
|
|
@"(from doesContain: %@)", value];
|
2007-06-27 23:26:44 +02:00
|
|
|
else if ([criteria isEqualToString: @"subject_or_sender"])
|
|
|
|
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
2007-09-13 20:22:23 +02:00
|
|
|
@"((subject doesContain: %@)"
|
2007-09-10 22:58:57 +02:00
|
|
|
@" OR (from doesContain: %@))",
|
2007-06-27 23:26:44 +02:00
|
|
|
value, value];
|
|
|
|
else if ([criteria isEqualToString: @"to_or_cc"])
|
|
|
|
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
2007-09-10 22:58:57 +02:00
|
|
|
@"((to doesContain: %@)"
|
|
|
|
@" OR (cc doesContain: %@))",
|
2007-06-27 23:26:44 +02:00
|
|
|
value, value];
|
|
|
|
else if ([criteria isEqualToString: @"entire_message"])
|
|
|
|
qualifier = [EOQualifier qualifierWithQualifierFormat:
|
2007-09-10 22:58:57 +02:00
|
|
|
@"(body doesContain: %@)", value];
|
2007-06-27 23:26:44 +02:00
|
|
|
else
|
|
|
|
qualifier = nil;
|
|
|
|
|
|
|
|
[qualifier retain];
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
- (id) defaultAction
|
|
|
|
{
|
2006-07-31 22:16:45 +02:00
|
|
|
WORequest *request;
|
2007-06-27 23:26:44 +02:00
|
|
|
NSString *specificMessage, *searchCriteria, *searchValue;
|
2007-11-09 00:05:00 +01:00
|
|
|
SOGoMailFolder *co;
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2007-06-28 20:28:33 +02:00
|
|
|
request = [context request];
|
2007-01-30 19:18:16 +01:00
|
|
|
|
2007-10-26 16:26:01 +02:00
|
|
|
co = [self clientObject];
|
|
|
|
[co flushMailCaches];
|
|
|
|
[co expungeLastMarkedFolder];
|
2007-01-30 19:18:16 +01:00
|
|
|
|
2006-07-31 22:16:45 +02:00
|
|
|
specificMessage = [request formValueForKey: @"pageforuid"];
|
2007-06-27 23:26:44 +02:00
|
|
|
searchCriteria = [request formValueForKey: @"search"];
|
|
|
|
searchValue = [request formValueForKey: @"value"];
|
2007-09-10 22:58:57 +02:00
|
|
|
if ([searchValue length])
|
2007-06-27 23:26:44 +02:00
|
|
|
[self _setQualifierForCriteria: searchCriteria
|
2009-06-30 22:10:09 +02:00
|
|
|
andValue: searchValue];
|
2007-06-27 23:26:44 +02:00
|
|
|
|
|
|
|
firstMessageNumber
|
2006-07-31 22:16:45 +02:00
|
|
|
= ((specificMessage)
|
|
|
|
? [self firstMessageOfPageFor: [specificMessage intValue]]
|
|
|
|
: [[request formValueForKey:@"idx"] intValue]);
|
2007-10-26 16:26:01 +02:00
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) getMailAction
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: we might want to flush the caches?
|
|
|
|
id client;
|
2006-07-31 22:16:45 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
if ((client = [self clientObject]) == nil) {
|
|
|
|
return [NSException exceptionWithHTTPStatus:404 /* Not Found */
|
|
|
|
reason:@"did not find mail folder"];
|
|
|
|
}
|
2006-07-29 00:59:11 +02:00
|
|
|
|
|
|
|
if (![client respondsToSelector:@selector(flushMailCaches) ])
|
|
|
|
{
|
2006-07-31 22:16:45 +02:00
|
|
|
return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
|
2006-07-29 00:59:11 +02:00
|
|
|
reason:
|
|
|
|
@"invalid client object (does not support flush)"];
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
[client flushMailCaches];
|
2006-07-29 00:59:11 +02:00
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self redirectToLocation:@"view"];
|
|
|
|
}
|
|
|
|
|
2007-10-22 23:59:20 +02:00
|
|
|
- (NSString *) msgLabels
|
|
|
|
{
|
|
|
|
NSMutableArray *labels;
|
|
|
|
NSEnumerator *flags;
|
|
|
|
NSString *currentFlag;
|
|
|
|
|
2009-10-13 16:10:17 +02:00
|
|
|
labels = [NSMutableArray array];
|
2007-10-22 23:59:20 +02:00
|
|
|
|
|
|
|
flags = [[message objectForKey: @"flags"] objectEnumerator];
|
|
|
|
while ((currentFlag = [flags nextObject]))
|
|
|
|
if ([currentFlag hasPrefix: @"$label"])
|
|
|
|
[labels addObject: [currentFlag substringFromIndex: 1]];
|
|
|
|
|
|
|
|
return [labels componentsJoinedByString: @" "];
|
|
|
|
}
|
|
|
|
|
2008-10-02 17:00:13 +02:00
|
|
|
- (NSDictionary *) columnsMetaData
|
|
|
|
{
|
|
|
|
NSMutableDictionary *columnsMetaData;
|
|
|
|
NSArray *tmpColumns, *tmpKeys;
|
2008-10-15 16:53:54 +02:00
|
|
|
|
2008-10-02 17:00:13 +02:00
|
|
|
columnsMetaData = [NSMutableDictionary dictionaryWithCapacity:8];
|
|
|
|
|
2008-10-15 16:53:54 +02:00
|
|
|
tmpKeys = [NSArray arrayWithObjects: @"headerClass", @"headerId", @"value",
|
2009-07-07 20:28:50 +02:00
|
|
|
nil];
|
2008-10-15 16:53:54 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell sortableTableHeader",
|
2009-07-07 20:28:50 +02:00
|
|
|
@"subjectHeader", @"Subject", nil];
|
2008-10-15 16:53:54 +02:00
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
2009-07-07 20:28:50 +02:00
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Subject"];
|
2008-10-15 16:53:54 +02:00
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell messageFlagColumn",
|
2009-08-19 21:47:31 +02:00
|
|
|
@"invisibleHeader", @"Flagged", nil];
|
2008-10-15 16:53:54 +02:00
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
2009-08-19 21:47:31 +02:00
|
|
|
forKey: @"Flagged"];
|
2008-10-15 16:53:54 +02:00
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell messageFlagColumn",
|
|
|
|
@"attachmentHeader", @"Attachment", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects:
|
|
|
|
tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Attachment"];
|
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell", @"messageFlagHeader",
|
|
|
|
@"Unread", nil];
|
2008-10-02 17:00:13 +02:00
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns forKeys: tmpKeys] forKey: @"Unread"];
|
2008-10-15 16:53:54 +02:00
|
|
|
|
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell sortableTableHeader",
|
|
|
|
@"toHeader", @"To", nil];
|
2008-10-02 17:00:13 +02:00
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns forKeys: tmpKeys] forKey: @"To"];
|
|
|
|
|
2008-10-15 16:53:54 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell sortableTableHeader",
|
|
|
|
@"fromHeader", @"From", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"From"];
|
2008-10-02 17:00:13 +02:00
|
|
|
|
2008-10-15 16:53:54 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell sortableTableHeader",
|
|
|
|
@"dateHeader", @"Date", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Date"];
|
2008-10-02 17:00:13 +02:00
|
|
|
|
2008-10-15 16:53:54 +02:00
|
|
|
tmpColumns
|
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell", @"priorityHeader",
|
|
|
|
@"Priority", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Priority"];
|
2009-06-30 22:10:09 +02:00
|
|
|
|
|
|
|
tmpColumns
|
2009-07-07 20:28:50 +02:00
|
|
|
= [NSArray arrayWithObjects: @"tbtv_headercell sortableTableHeader", @"sizeHeader",
|
2009-06-30 22:10:09 +02:00
|
|
|
@"Size", nil];
|
|
|
|
[columnsMetaData setObject: [NSDictionary dictionaryWithObjects: tmpColumns
|
|
|
|
forKeys: tmpKeys]
|
|
|
|
forKey: @"Size"];
|
2008-10-02 17:00:13 +02:00
|
|
|
|
|
|
|
return columnsMetaData;
|
|
|
|
}
|
|
|
|
|
2008-10-15 16:53:54 +02:00
|
|
|
- (NSArray *) columnsDisplayOrder
|
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
NSMutableArray *finalOrder, *invalid;
|
|
|
|
NSArray *available;
|
|
|
|
NSDictionary *metaData;
|
|
|
|
SOGoUserDefaults *ud;
|
2008-10-15 16:53:54 +02:00
|
|
|
unsigned int i;
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
if (!columnsOrder)
|
2008-10-15 16:53:54 +02:00
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
ud = [[context activeUser] userDefaults];
|
|
|
|
columnsOrder = [ud mailListViewColumnsOrder];
|
2009-09-22 17:58:43 +02:00
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
metaData = [self columnsMetaData];
|
|
|
|
|
|
|
|
invalid = [columnsOrder mutableCopy];
|
|
|
|
[invalid autorelease];
|
|
|
|
available = [metaData allKeys];
|
|
|
|
[invalid removeObjectsInArray: available];
|
|
|
|
if ([invalid count] > 0)
|
2009-09-22 17:58:43 +02:00
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
[self errorWithFormat: @"those column names specified in"
|
2009-09-22 17:58:43 +02:00
|
|
|
@" SOGoMailListViewColumnsOrder are invalid: '%@'",
|
2009-11-29 05:19:32 +01:00
|
|
|
[invalid componentsJoinedByString: @"', '"]];
|
2009-09-22 17:58:43 +02:00
|
|
|
[self errorWithFormat: @" falling back on hardcoded column order"];
|
2009-11-29 05:19:32 +01:00
|
|
|
columnsOrder = available;
|
2009-09-22 17:58:43 +02:00
|
|
|
}
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
finalOrder = [columnsOrder mutableCopy];
|
|
|
|
[finalOrder autorelease];
|
2009-09-22 17:58:43 +02:00
|
|
|
if ([self showToAddress])
|
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
i = [finalOrder indexOfObject: @"From"];
|
2009-09-22 17:58:43 +02:00
|
|
|
if (i != NSNotFound)
|
2009-11-29 05:19:32 +01:00
|
|
|
[finalOrder replaceObjectAtIndex: i withObject: @"To"];
|
2009-09-22 17:58:43 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-29 05:19:32 +01:00
|
|
|
i = [finalOrder indexOfObject: @"To"];
|
2009-09-22 17:58:43 +02:00
|
|
|
if (i != NSNotFound)
|
2009-11-29 05:19:32 +01:00
|
|
|
[finalOrder replaceObjectAtIndex: i withObject: @"From"];
|
2009-09-22 17:58:43 +02:00
|
|
|
}
|
2009-11-29 05:19:32 +01:00
|
|
|
|
|
|
|
columnsOrder = [[self columnsMetaData] objectsForKeys: finalOrder
|
|
|
|
notFoundMarker: @""];
|
|
|
|
[columnsOrder retain];
|
2008-10-15 16:53:54 +02:00
|
|
|
}
|
|
|
|
|
2009-11-29 05:19:32 +01:00
|
|
|
return columnsOrder;
|
2008-10-15 16:53:54 +02:00
|
|
|
}
|
|
|
|
|
2009-06-30 22:10:09 +02:00
|
|
|
- (NSString *) columnsDisplayCount
|
|
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"%d", [[self columnsDisplayOrder] count]];
|
|
|
|
}
|
|
|
|
|
2009-09-22 17:58:43 +02:00
|
|
|
- (void) setCurrentColumn: (NSDictionary *) newCurrentColumn
|
|
|
|
{
|
|
|
|
ASSIGN (currentColumn, newCurrentColumn);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *) currentColumn
|
|
|
|
{
|
|
|
|
return currentColumn;
|
|
|
|
}
|
|
|
|
|
2008-10-08 20:38:03 +02:00
|
|
|
- (NSString *) columnTitle
|
|
|
|
{
|
|
|
|
return [self labelForKey: [currentColumn objectForKey: @"value"]];
|
|
|
|
}
|
|
|
|
|
2006-07-29 00:59:11 +02:00
|
|
|
@end
|
|
|
|
|
|
|
|
/* UIxMailListView */
|