]> err.no Git - scalable-opengroupware.org/blobdiff - UI/MailerUI/UIxMailListView.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1087 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / MailerUI / UIxMailListView.m
index b1008343ae9ce6e3801e5ceeb70c9ac356612619..f0a2ff930345594c7fc47dbd1751d16886a8cbd2 100644 (file)
@@ -19,8 +19,6 @@
   02111-1307, USA.
 */
 
-#include <SOGoUI/UIxComponent.h>
-
 /*
   UIxMailListView
   
   object.
 */
 
-@class EOQualifier;
-
-@interface UIxMailListView : UIxComponent
-{
-  NSArray     *sortedUIDs; /* we always need to retrieve all anyway! */
-  NSArray     *messages;
-  unsigned    firstMessageNumber;
-  id          message;
-  EOQualifier *qualifier;
-}
-
-- (NSString *)defaultSortKey;
-- (NSString *)imap4SortKey;
-- (NSString *)imap4SortOrdering;
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSValue.h>
+#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>
 
-- (BOOL)isSortedDescending;
+#import <SoObjects/Mailer/SOGoMailFolder.h>
+#import <SoObjects/Mailer/SOGoMailObject.h>
+#import <SoObjects/SOGo/SOGoDateFormatter.h>
+#import <SoObjects/SOGo/SOGoUser.h>
 
-@end
+#import "UIxMailListView.h"
 
-#include "common.h"
-#include <SoObjects/Mailer/SOGoMailFolder.h>
-#include <SoObjects/Mailer/SOGoMailObject.h>
-#include <NGObjWeb/SoObject+SoDAV.h>
+#define messagesPerPage 50
+static int attachmentFlagSize = 8096;
 
 @implementation UIxMailListView
 
-static int attachmentFlagSize = 8096;
-
-- (void)dealloc {
+- (void) dealloc 
+{
   [self->qualifier  release];
   [self->sortedUIDs release];
   [self->messages   release];
   [self->message    release];
+  [dateFormatter release];
+  [userTimeZone release];
   [super dealloc];
 }
 
-/* frame */
-
-- (BOOL)hideFrame {
-  return [[[[self context] request] formValueForKey:@"noframe"] boolValue];
-}
-
 /* notifications */
 
-- (void)sleep {
+- (void) sleep 
+{
   [self->qualifier  release]; self->qualifier  = nil;
   [self->sortedUIDs release]; self->sortedUIDs = nil;
   [self->messages   release]; self->messages   = nil;
@@ -82,21 +72,38 @@ static int attachmentFlagSize = 8096;
 
 /* accessors */
 
-- (void)setMessage:(id)_msg {
+- (void)setMessage:(id)_msg
+{
   ASSIGN(self->message, _msg);
 }
-- (id)message {
+
+- (id) message 
+{
   return self->message;
 }
 
-- (void)setQualifier:(EOQualifier *)_msg {
+- (NSString *) messageDate
+{
+  NSCalendarDate *messageDate;
+
+  messageDate = [[message objectForKey: @"envelope"] date];
+  [messageDate setTimeZone: userTimeZone];
+
+  return [dateFormatter formattedDateAndTime: messageDate];
+}
+
+- (void) setQualifier: (EOQualifier *) _msg 
+{
   ASSIGN(self->qualifier, _msg);
 }
-- (EOQualifier *)qualifier {
+
+- (EOQualifier *) qualifier 
+{
   return self->qualifier;
 }
 
-- (BOOL)showToAddress {
+- (BOOL) showToAddress 
+{
   NSString *ftype;
   
   ftype = [[self clientObject] valueForKey:@"outlookFolderClass"];
@@ -105,10 +112,13 @@ static int attachmentFlagSize = 8096;
 
 /* title */
 
-- (NSString *)objectTitle {
+- (NSString *) objectTitle 
+{
   return [[self clientObject] nameInContainer];
 }
-- (NSString *)panelTitle {
+
+- (NSString *) panelTitle 
+{
   NSString *s;
   
   s = [self labelForKey:@"View Mail Folder"];
@@ -119,35 +129,42 @@ static int attachmentFlagSize = 8096;
 
 /* derived accessors */
 
-- (BOOL)isMessageDeleted {
+- (BOOL) isMessageDeleted 
+{
   NSArray *flags;
   
   flags = [[self message] valueForKey:@"flags"];
   return [flags containsObject:@"deleted"];
 }
 
-- (BOOL)isMessageRead {
+- (BOOL) isMessageRead 
+{
   NSArray *flags;
   
   flags = [[self message] valueForKey:@"flags"];
   return [flags containsObject:@"seen"];
 }
-- (NSString *)messageUidString {
+- (NSString *) messageUidString 
+{
   return [[[self message] valueForKey:@"uid"] stringValue];
 }
 
-- (NSString *)messageSubjectStyleClass {
-  return [self isMessageRead]
-    ? @"mailer_readmailsubject"
-    : @"mailer_unreadmailsubject";
-}
-- (NSString *)messageCellStyleClass {
+- (NSString *) messageRowStyleClass 
+{
   return [self isMessageDeleted]
     ? @"mailer_listcell_deleted"
     : @"mailer_listcell_regular";
 }
 
-- (BOOL)hasMessageAttachment {
+- (NSString *) messageSubjectCellStyleClass 
+{
+  return ([self isMessageRead]
+         ? @"mailer_readmailsubject"
+         : @"mailer_unreadmailsubject");
+}
+
+- (BOOL) hasMessageAttachment 
+{
   /* we detect attachments by size ... */
   unsigned size;
   
@@ -157,7 +174,8 @@ static int attachmentFlagSize = 8096;
 
 /* fetching messages */
 
-- (NSArray *)fetchKeys {
+- (NSArray *) fetchKeys 
+{
   /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
   static NSArray *keys = nil;
   if (keys == nil) {
@@ -167,60 +185,78 @@ static int attachmentFlagSize = 8096;
   return keys;
 }
 
-- (NSString *)defaultSortKey {
+- (NSString *) defaultSortKey 
+{
   return @"DATE";
 }
-- (NSString *)imap4SortKey {
+
+- (NSString *) imap4SortKey 
+{
   NSString *sort;
   
   sort = [[[self context] request] formValueForKey:@"sort"];
-  
+
   if ([sort length] == 0)
     sort = [self defaultSortKey];
+
   return [sort uppercaseString];
 }
 
-- (BOOL)isSortedDescending {
+- (BOOL) isSortedDescending
+{
   NSString *desc;
-  
+
   desc = [[[self context] request] formValueForKey:@"desc"];
-  if(!desc)
-    return NO;
-  return [desc boolValue] ? YES : NO;
+
+  return ((desc)
+          ? [desc boolValue]
+          : YES);
 }
 
-- (NSString *)imap4SortOrdering {
+- (NSString *) imap4SortOrdering 
+{
   NSString *sort;
-  
+
   sort = [self imap4SortKey];
-  if(![self isSortedDescending])
-    return sort;
-  return [@"REVERSE " stringByAppendingString:sort];
+
+  if ([self isSortedDescending])
+    sort = [@"REVERSE " stringByAppendingString: sort];
+
+  return sort;
 }
 
-- (NSRange)fetchRange {
+- (NSRange) fetchRange 
+{
   if (self->firstMessageNumber == 0)
-    return NSMakeRange(0, 50);
-  return NSMakeRange(self->firstMessageNumber - 1, 50);
+    return NSMakeRange(0, messagesPerPage);
+  return NSMakeRange(self->firstMessageNumber - 1, messagesPerPage);
 }
 
-- (NSArray *)sortedUIDs {
-  if (self->sortedUIDs != nil)
-    return self->sortedUIDs;
-  
-  self->sortedUIDs 
-    = [[[self clientObject] fetchUIDsMatchingQualifier:[self qualifier]
-                           sortOrdering:[self imap4SortOrdering]] retain];
+- (NSArray *) sortedUIDs 
+{
+  if (!sortedUIDs)
+    {
+      sortedUIDs 
+        = [[self clientObject] fetchUIDsMatchingQualifier: [self qualifier]
+                               sortOrdering: [self imap4SortOrdering]];
+      [sortedUIDs retain];
+    }
+
   return self->sortedUIDs;
 }
-- (unsigned int)totalMessageCount {
+
+- (unsigned int) totalMessageCount 
+{
   return [self->sortedUIDs count];
 }
-- (BOOL)showsAllMessages {
+
+- (BOOL) showsAllMessages 
+{
   return ([[self sortedUIDs] count] <= [self fetchRange].length) ? YES : NO;
 }
 
-- (NSRange)fetchBlock {
+- (NSRange) fetchBlock 
+{
   NSRange  r;
   unsigned len;
   NSArray  *uids;
@@ -246,27 +282,38 @@ static int attachmentFlagSize = 8096;
     r.length = len - r.location;
   return r;
 }
-- (unsigned int)firstMessageNumber {
+
+- (unsigned int) firstMessageNumber 
+{
   return [self fetchBlock].location + 1;
 }
-- (unsigned int)lastMessageNumber {
+
+- (unsigned int) lastMessageNumber 
+{
   NSRange r;
   
   r = [self fetchBlock];
   return r.location + r.length;
 }
-- (BOOL)hasPrevious {
+
+- (BOOL) hasPrevious 
+{
   return [self fetchBlock].location == 0 ? NO : YES;
 }
-- (BOOL)hasNext {
+
+- (BOOL) hasNext 
+{
   NSRange r = [self fetchBlock];
   return r.location + r.length >= [[self sortedUIDs] count] ? NO : YES;
 }
 
-- (unsigned int)nextFirstMessageNumber {
+- (unsigned int) nextFirstMessageNumber 
+{
   return [self firstMessageNumber] + [self fetchRange].length;
 }
-- (unsigned int)prevFirstMessageNumber {
+
+- (unsigned int) prevFirstMessageNumber 
+{
   NSRange  r;
   unsigned idx;
   
@@ -277,15 +324,23 @@ static int attachmentFlagSize = 8096;
   return 1;
 }
 
-- (NSArray *)messages {
+- (NSArray *) messages 
+{
   NSArray  *uids;
   NSArray  *msgs;
   NSRange  r;
   unsigned len;
+  SOGoUser *user;
   
   if (self->messages != nil)
     return self->messages;
-  
+
+  user = [context activeUser];
+  if (!dateFormatter)
+    dateFormatter = [user dateFormatterInContext: context];
+  if (!userTimeZone)
+    ASSIGN (userTimeZone, [user timeZone]);
+
   r    = [self fetchBlock];
   uids = [self sortedUIDs];
   if ((len = [uids count]) > r.length)
@@ -299,10 +354,14 @@ static int attachmentFlagSize = 8096;
 
 /* URL processing */
 
-- (NSString *)messageViewTarget {
-  return [@"SOGo_msg_" stringByAppendingString:[self messageUidString]];
+- (NSString *) messageViewTarget
+{
+  return [NSString stringWithFormat: @"SOGo_msg_%@",
+                   [self messageUidString]];
 }
-- (NSString *)messageViewURL {
+
+- (NSString *) messageViewURL 
+{
   // TODO: noframe only when view-target is empty
   // TODO: markread only if the message is unread
   NSString *s;
@@ -311,75 +370,43 @@ static int attachmentFlagSize = 8096;
   if (![self isMessageRead]) s = [s stringByAppendingString:@"&markread=1"];
   return s;
 }
-- (NSString *)markReadURL {
+- (NSString *) markReadURL 
+{
   return [@"markMessageRead?uid=" stringByAppendingString:
             [self messageUidString]];
 }
-- (NSString *)markUnreadURL {
+- (NSString *) markUnreadURL 
+{
   return [@"markMessageUnread?uid=" stringByAppendingString:
             [self messageUidString]];
 }
 
 /* JavaScript */
 
-- (NSString *)msgRowID {
+- (NSString *)msgRowID
+{
   return [@"row_" stringByAppendingString:[self messageUidString]];
 }
-- (NSString *)msgDivID {
+
+- (NSString *)msgDivID
+{
   return [@"div_" stringByAppendingString:[self messageUidString]];
 }
 
-- (NSString *)msgIconReadDivID {
+- (NSString *)msgIconReadImgID
+{
   return [@"readdiv_" stringByAppendingString:[self messageUidString]];
 }
-- (NSString *)msgIconUnreadDivID {
-  return [@"unreaddiv_" stringByAppendingString:[self messageUidString]];
-}
-- (NSString *)msgIconReadVisibility {
-  return [self isMessageRead] ? nil : @"display: none;";
-}
-- (NSString *)msgIconUnreadVisibility {
-  return [self isMessageRead] ? @"display: none;" : nil;
-}
 
-- (NSString *)clickedMsgJS {
-  /* return 'false' aborts processing */
-  return [NSString stringWithFormat:@"clickedUid(this, '%@'); return false", 
-                    [self messageUidString]];
-}
-
-// the following are unused?
-- (NSString *)dblClickedMsgJS {
-  return [NSString stringWithFormat:@"doubleClickedUid(this, '%@')", 
-                    [self messageUidString]];
-}
-
-// the following are unused?
-- (NSString *)highlightRowJS {
-  return [NSString stringWithFormat:@"highlightUid(this, '%@')", 
-                    [self messageUidString]];
-}
-- (NSString *)lowlightRowJS {
-  return [NSString stringWithFormat:@"lowlightUid(this, '%@')", 
-                    [self messageUidString]];
-}
-
-- (NSString *)markUnreadJS {
-  return [NSString stringWithFormat:
-                    @"mailListMarkMessage(this, 'markMessageUnread', "
-                    @"'%@', false)", 
-                    [self messageUidString]];
-}
-- (NSString *)markReadJS {
-  return [NSString stringWithFormat:
-                    @"mailListMarkMessage(this, 'markMessageRead', "
-                    @"'%@', true)", 
-                    [self messageUidString]];
+- (NSString *)msgIconUnreadImgID
+{
+  return [@"unreaddiv_" stringByAppendingString:[self messageUidString]];
 }
 
 /* error redirects */
 
-- (id)redirectToViewWithError:(id)_error {
+- (id) redirectToViewWithError: (id) _error 
+{
   // TODO: DUP in UIxMailAccountView
   // TODO: improve, localize
   // TODO: there is a bug in the treeview which preserves the current URL for
@@ -401,7 +428,8 @@ static int attachmentFlagSize = 8096;
 
 /* active message */
 
-- (SOGoMailObject *)lookupActiveMessage {
+- (SOGoMailObject *) lookupActiveMessage 
+{
   NSString *uid;
   
   if ((uid = [[[self context] request] formValueForKey:@"uid"]) == nil)
@@ -413,16 +441,13 @@ static int attachmentFlagSize = 8096;
 
 /* actions */
 
-- (id)defaultAction {
-  self->firstMessageNumber = 
-    [[[[self context] request] formValueForKey:@"idx"] intValue];
-  return self;
-}
-
-- (BOOL)isJavaScriptRequest {
+- (BOOL) isJavaScriptRequest 
+{
   return [[[[self context] request] formValueForKey:@"jsonly"] boolValue];
 }
-- (id)javaScriptOK {
+
+- (id) javaScriptOK 
+{
   WOResponse *r;
 
   r = [[self context] response];
@@ -430,7 +455,49 @@ static int attachmentFlagSize = 8096;
   return r;
 }
 
-- (id)markMessageUnreadAction {
+- (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;
+}
+
+- (id) defaultAction 
+{
+  WORequest *request;
+  NSString *specificMessage;
+
+  request = [[self context] request];
+
+  [[self clientObject] flushMailCaches];
+
+  specificMessage = [request formValueForKey: @"pageforuid"];
+  self->firstMessageNumber
+    = ((specificMessage)
+       ? [self firstMessageOfPageFor: [specificMessage intValue]]
+       : [[request formValueForKey:@"idx"] intValue]);
+
+  return self;
+}
+
+- (id) viewAction 
+{
+  return [self defaultAction];
+}
+
+- (id) markMessageUnreadAction 
+{
   NSException *error;
   
   if ((error = [[self lookupActiveMessage] removeFlags:@"seen"]) != nil)
@@ -442,7 +509,9 @@ static int attachmentFlagSize = 8096;
   
   return [self redirectToLocation:@"view"];
 }
-- (id)markMessageReadAction {
+
+- (id) markMessageReadAction 
+{
   NSException *error;
   
   if ((error = [[self lookupActiveMessage] addFlags:@"seen"]) != nil)
@@ -455,26 +524,30 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:@"view"];
 }
 
-- (id)getMailAction {
+- (id) getMailAction 
+{
   // TODO: we might want to flush the caches?
   id client;
-  
+
   if ((client = [self clientObject]) == nil) {
     return [NSException exceptionWithHTTPStatus:404 /* Not Found */
                        reason:@"did not find mail folder"];
   }
-  
-  if (![client respondsToSelector:@selector(flushMailCaches)]) {
-    return [NSException exceptionWithHTTPStatus:500 /* Server Error */
-                       reason:
-                         @"invalid client object (does not support flush)"];
-  }
-  
+
+  if (![client respondsToSelector:@selector(flushMailCaches) ]) 
+    {
+      return [NSException exceptionWithHTTPStatus: 500 /* Server Error */
+                          reason:
+                            @"invalid client object (does not support flush)"];
+    }
+
   [client flushMailCaches];
+
   return [self redirectToLocation:@"view"];
 }
 
-- (id)expungeAction {
+- (id) expungeAction 
+{
   // TODO: we might want to flush the caches?
   NSException *error;
   id client;
@@ -492,92 +565,6 @@ static int attachmentFlagSize = 8096;
   return [self redirectToLocation:@"view"];
 }
 
-- (id)emptyTrashAction {
-  // TODO: we might want to flush the caches?
-  NSException *error;
-  id client;
-  
-  if ((client = [self clientObject]) == nil) {
-    error = [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                        reason:@"did not find mail folder"];
-    return [self redirectToViewWithError:error];
-  }
-
-  if (![client isKindOfClass:NSClassFromString(@"SOGoTrashFolder")]) {
-    /* would be better to move the method to an own class, but well .. */
-    error = [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:@"method cannot be invoked on "
-                                @"the specified object"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  /* mark all as deleted */
-
-  [self logWithFormat:@"TODO: must mark all as deleted for empty-trash"];
-  
-  error = [[self clientObject] addFlagsToAllMessages:@"deleted"];
-  if (error != nil)
-    // TODO: improve error
-    return [self redirectToViewWithError:error];
-  
-  /* expunge */
-  
-  if ((error = [[self clientObject] expunge]) != nil)
-    // TODO: improve error
-    return [self redirectToViewWithError:error];
-  
-  if ([client respondsToSelector:@selector(flushMailCaches)])
-    [client flushMailCaches];
-  return [self redirectToLocation:@"view"];
-}
-
-/* folder operations */
-
-- (id)createFolderAction {
-  NSException *error;
-  NSString    *folderName;
-  id client;
-  
-  folderName = [[[self context] request] formValueForKey:@"name"];
-  if ([folderName length] == 0) {
-    error = [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:@"missing 'name' query parameter!"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  if ((client = [self clientObject]) == nil) {
-    error = [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                        reason:@"did not find mail folder"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  if ((error = [[self clientObject] davCreateCollection:folderName
-                                   inContext:[self context]]) != nil) {
-    return [self redirectToViewWithError:error];
-  }
-  
-  return [self redirectToLocation:[folderName stringByAppendingString:@"/"]];
-}
-
-- (id)deleteFolderAction {
-  NSException *error;
-  NSString *url;
-  id client;
-  
-  if ((client = [self clientObject]) == nil) {
-    error = [NSException exceptionWithHTTPStatus:404 /* Not Found */
-                        reason:@"did not find mail folder"];
-    return [self redirectToViewWithError:error];
-  }
-  
-  /* jump to parent folder afterwards */
-  url = [[client container] baseURLInContext:[self context]];
-  if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
-  
-  if ((error = [[self clientObject] delete]) != nil)
-    return [self redirectToViewWithError:error];
-  
-  return [self redirectToLocation:url];
-}
+@end
 
-@end /* UIxMailListView */
+/* UIxMailListView */