]> err.no Git - scalable-opengroupware.org/commitdiff
work on mail viewer
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 3 Oct 2004 00:05:13 +0000 (00:05 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 3 Oct 2004 00:05:13 +0000 (00:05 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@346 d1b88da0-ebda-0310-925b-ed51d893ca5b

17 files changed:
SOGo/SoObjects/Mailer/ChangeLog
SOGo/SoObjects/Mailer/SOGoMailManager.h
SOGo/SoObjects/Mailer/SOGoMailManager.m
SOGo/SoObjects/Mailer/SOGoMailObject.h
SOGo/SoObjects/Mailer/SOGoMailObject.m
SOGo/SoObjects/Mailer/Version
SOGo/UI/Mailer/ChangeLog
SOGo/UI/Mailer/GNUmakefile
SOGo/UI/Mailer/UIxEnvelopeAddressFormatter.m [new file with mode: 0644]
SOGo/UI/Mailer/UIxMailFormatter.h
SOGo/UI/Mailer/UIxMailFormatter.m
SOGo/UI/Mailer/UIxMailView.m
SOGo/UI/Mailer/UIxMailView.wox
SOGo/UI/Mailer/Version
SOGo/UI/Mailer/WOContext+UIxMailer.h
SOGo/UI/Mailer/WOContext+UIxMailer.m
SOGo/UI/Mailer/mailer.css

index 325083a26c8cf41028064c4e41e810a432874854..922d85a951cf9d46b838818dcbbc8452299bbd23 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-03  Helge Hess  <helge.hess@opengroupware.org>
+
+       * v0.9.20
+
+       * SOGoMailObject.m: added method to fetch parts
+
+       * SOGoMailManager.m: properly select folder prior fetch, added method
+         to fetch parts of a single (message) URL
+
 2004-10-02  Helge Hess  <helge.hess@opengroupware.org>
 
        * SOGoMailFolder.[hm]: removed ability to restrict UID fetch range,
index b431d0f19416ede7e58e64c01a055b3f4307723f..d6f468fd9da9d8edc0ab8005715ae6e1dfacf759 100644 (file)
 - (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url
   parts:(NSArray *)_parts password:(NSString *)_pwd;
 
+/* individual message */
+
+- (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd;
+
 @end
 
 #endif /* __Mailer_SOGoMailManager_H__ */
index f65ae96cc406bf1ba43eb8db0bf470747cc6b3dd..8852c92e6cf91268154ca4eebbd72eb34c93e58f 100644 (file)
@@ -211,7 +211,7 @@ static NSTimeInterval PoolScanInterval = 5 * 60;
   return @".";
 }
 
-- (NSString *)imap4FolderNameForURL:(NSURL *)_url {
+- (NSString *)imap4FolderNameForURL:(NSURL *)_url removeFileName:(BOOL)_delfn {
   /* a bit hackish, but should be OK */
   NSString *folderName;
 
@@ -223,10 +223,15 @@ static NSTimeInterval PoolScanInterval = 5 * 60;
     return nil;
   if ([folderName characterAtIndex:0] == '/')
     folderName = [folderName substringFromIndex:1];
+
+  if (_delfn) folderName = [folderName stringByDeletingLastPathComponent];
   
   return [[folderName pathComponents] componentsJoinedByString:
                                        [self imap4Separator]];
 }
+- (NSString *)imap4FolderNameForURL:(NSURL *)_url {
+  return [self imap4FolderNameForURL:_url removeFileName:NO];
+}
 
 - (NSArray *)extractSubfoldersForURL:(NSURL *)_url
   fromResultSet:(NSDictionary *)_result
@@ -375,6 +380,7 @@ static NSTimeInterval PoolScanInterval = 5 * 60;
 - (NSArray *)fetchUIDs:(NSArray *)_uids inURL:(NSURL *)_url
   parts:(NSArray *)_parts password:(NSString *)_pwd
 {
+  // currently returns a dict?!
   /*
     Allowed fetch keys:
       UID
@@ -394,11 +400,21 @@ static NSTimeInterval PoolScanInterval = 5 * 60;
   if (_uids == nil)
     return nil;
   if ([_uids count] == 0)
-    return [NSArray array];
+    return nil; // TODO: might break empty folders?! return a dict!
   
   if ((client = [self imap4ClientForURL:_url password:_pwd]) == nil)
     return nil;
 
+  /* select folder */
+  
+  result = [client select:[self imap4FolderNameForURL:_url]];
+  if (![[result valueForKey:@"result"] boolValue]) {
+    [self logWithFormat:@"ERROR: could not select URL: %@: %@", _url, result];
+    return nil;
+  }
+  
+  /* fetch parts */
+  
 #warning TODO: split uids into batches, otherwise Cyrus will complain
   // not really important because we batch before (in the sort)
   // if the list is too long, we get a:
@@ -414,6 +430,40 @@ static NSTimeInterval PoolScanInterval = 5 * 60;
   return (id)result;
 }
 
+- (id)fetchURL:(NSURL *)_url parts:(NSArray *)_parts password:(NSString *)_pwd{
+  // currently returns a dict
+  NGImap4Client *client;
+  NSDictionary  *result;
+  NSString *uid;
+  
+  if (![_url isNotNull]) return nil;
+  
+  
+  if ((client = [self imap4ClientForURL:_url password:_pwd]) == nil)
+    return nil;
+  
+  /* select folder */
+  
+  result = [client select:[self imap4FolderNameForURL:_url
+                               removeFileName:YES]];
+  if (![[result valueForKey:@"result"] boolValue]) {
+    [self logWithFormat:@"ERROR: could not select URL: %@: %@", _url, result];
+    return nil;
+  }
+  
+  /* fetch parts */
+  
+  uid = [[_url path] lastPathComponent];
+  
+  result = [client fetchUids:[NSArray arrayWithObject:uid] parts:_parts];
+  if (![[result valueForKey:@"result"] boolValue]) {
+    [self logWithFormat:@"ERROR: could not fetch url: %@", _url];
+    return nil;
+  }
+  //[self logWithFormat:@"RESULT: %@", result];
+  return (id)result;
+}
+
 /* debugging */
 
 - (BOOL)isDebuggingEnabled {
index 5aca122cbe9c63121f73be402e5f8e0e5e3cc9b2..9cb4ab1a0783da098b4bdc98980c2267bac4a4dd 100644 (file)
 {
 }
 
+/* message */
+
+- (id)fetchParts:(NSArray *)_parts;
+
 @end
 
 #endif /* __Mailer_SOGoMailObject_H__ */
index 608841d5ab8bc5bef938b77cb4bedf8941e25103..603ea64ac9bccda93f5ddaf1ee5a06a30968c91e 100644 (file)
@@ -21,6 +21,7 @@
 // $Id$
 
 #include "SOGoMailObject.h"
+#include "SOGoMailManager.h"
 #include "common.h"
 
 @implementation SOGoMailObject
   return [self nameInContainer];
 }
 
+/* message */
+
+- (id)fetchParts:(NSArray *)_parts {
+  return [[self mailManager] fetchURL:[self imap4URL] parts:_parts
+                            password:[self imap4Password]];
+}
+
 @end /* SOGoMailObject */
index 93c8cd1ddfe4862984d2fe8dffb82de3a02d010b..7cb001acfe53aa2f6319d40435bdf0120783297d 100644 (file)
@@ -1,3 +1,3 @@
 # $Id$
 
-SUBMINOR_VERSION:=19
+SUBMINOR_VERSION:=20
index 9c25d33e34462596d6624d498be135b584f8d01e..8a9d37ca008720637ea40fa8a426ebd0c1434cba 100644 (file)
@@ -1,5 +1,7 @@
 2004-10-03  Helge Hess  <helge.hess@opengroupware.org>
 
+       * work on viewer (v0.9.11)
+
        * UIxMailMainFrame.wox: made toolbar floating (v0.9.10)
 
 2004-10-02  Helge Hess  <helge.hess@opengroupware.org>
index 792eb63ce98eeed07bad812326abc1928cc41986..cc5af4b009f9ea6abfa8f2d0295d61c47749288f 100644 (file)
@@ -11,9 +11,10 @@ MailerUI_LANGUAGES = English French
 MailerUI_OBJC_FILES += \
        MailerUIProduct.m       \
        \
-       UIxMailFormatter.m      \
-       UIxSubjectFormatter.m   \
-       WOContext+UIxMailer.m   \
+       UIxMailFormatter.m              \
+       UIxSubjectFormatter.m           \
+       UIxEnvelopeAddressFormatter.m   \
+       WOContext+UIxMailer.m           \
        \
        UIxMailMainFrame.m      \
        UIxMailTree.m           \
diff --git a/SOGo/UI/Mailer/UIxEnvelopeAddressFormatter.m b/SOGo/UI/Mailer/UIxEnvelopeAddressFormatter.m
new file mode 100644 (file)
index 0000000..5330e57
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2004 SKYRIX Software AG
+
+  This file is part of OpenGroupware.org.
+
+  OGo is free software; you can redistribute it and/or modify it under
+  the terms of the GNU Lesser General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  OGo is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with OGo; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#include "UIxMailFormatter.h"
+#include <NGImap4/NGImap4EnvelopeAddress.h>
+#include "common.h"
+
+@implementation UIxEnvelopeAddressFormatter
+
+static Class EnvAddrClass = Nil;
+static Class StrClass     = Nil;
+
++ (void)initialize {
+  EnvAddrClass = [NGImap4EnvelopeAddress class];
+  StrClass     = [NSString       class];
+}
+
+- (id)initWithMaxLength:(unsigned int)_max generateFullEMail:(BOOL)_genFull {
+  if ((self = [super init])) {
+    self->maxLength = _max;
+    self->separator = @", ";
+    
+    self->eafFlags.fullEMail = _genFull ? 1 : 0;
+  }
+  return self;
+}
+- (id)init {
+  return [self initWithMaxLength:128 generateFullEMail:NO];
+}
+
+/* configuration */
+
+- (unsigned)maxLength {
+  return self->maxLength;
+}
+- (NSString *)separator {
+  return self->separator;
+}
+- (BOOL)generateFullEMail {
+  return self->eafFlags.fullEMail ? YES : NO;
+}
+
+/* formatting envelope addresses */
+
+- (NSString *)stringForEnvelopeAddress:(NGImap4EnvelopeAddress *)_address {
+  NSString *s;
+
+  if ([self generateFullEMail])
+    return [_address email];
+  
+  s = [_address personalName];
+  if ([s isNotNull]) return s;
+  
+  s = [_address baseEMail];
+  if ([s isNotNull]) return s;
+  
+  [self debugWithFormat:@"WARNING: unexpected envelope address: %@", _address];
+  return [_address stringValue];
+}
+
+- (NSString *)stringForArray:(NSArray *)_addresses {
+  NSMutableString *ms;
+  unsigned i, count;
+  
+  if ((count = [_addresses count]) == 0)
+    return nil;
+  
+  if (count == 1)
+    return [self stringForObjectValue:[_addresses objectAtIndex:0]];
+  
+  ms = [NSMutableString stringWithCapacity:16 * count];
+  for (i = 0; i < count && [ms length] < [self maxLength]; i++) {
+    NSString *s;
+    
+    s = [self stringForObjectValue:[_addresses objectAtIndex:i]];
+    if (s == nil)
+      continue;
+    
+    if ([ms length] > 0) [ms appendString:[self separator]];
+    [ms appendString:s];
+  }
+  return ms;
+}
+
+/* formatter entry function */
+
+- (NSString *)stringForObjectValue:(id)_address {
+  if (![_address isNotNull])
+    return nil;
+  
+  if ([_address isKindOfClass:StrClass]) /* preformatted? */
+    return _address;
+  
+  if ([_address isKindOfClass:EnvAddrClass])
+    return [self stringForEnvelopeAddress:_address];
+  
+  if ([_address isKindOfClass:[NSArray class]])
+    return [self stringForArray:_address];
+  
+  [self debugWithFormat:
+         @"NOTE: unexpected object for envelope formatter: %@<%@>",
+         _address, NSStringFromClass([_address class])];
+  return [_address stringValue];
+}
+
+@end /* UIxEnvelopeAddressFormatter */
index 8507c21b1d4bfe034c9d675c82f30fd3b667bfd1..c197eb29e3daa864fc90f04d37fe9105970e03db 100644 (file)
 @end
 
 @interface UIxEnvelopeAddressFormatter : UIxMailFormatter
+{
+  NSString     *separator;
+  unsigned int maxLength;
+  struct {
+    int fullEMail:1;
+    int reserved:31;
+  } eafFlags;
+}
+
+- (id)initWithMaxLength:(unsigned int)_max generateFullEMail:(BOOL)_genFull;
+
 @end
 
 #endif /* __Mailer_UIxMailFormatter_H__ */
index c5a13819c4b66294bf6936f4c81f79f50e0c8e7b..04a987909d36a06c0710022dc106a2ff8a9e793f 100644 (file)
@@ -147,85 +147,3 @@ static BOOL debugOn = YES;
 }
 
 @end /* UIxMailDateFormatter */
-
-#include <NGImap4/NGImap4EnvelopeAddress.h>
-
-@implementation UIxEnvelopeAddressFormatter
-
-static Class EnvAddrClass = Nil;
-
-+ (void)initialize {
-  if (EnvAddrClass == Nil) EnvAddrClass = [NGImap4EnvelopeAddress class];
-}
-
-/* configuration */
-
-- (unsigned)maxLength {
-  return 128; // TODO
-}
-
-- (NSString *)separator {
-  return @", ";
-}
-
-/* formatting envelope addresses */
-
-- (NSString *)stringForEnvelopeAddress:(NGImap4EnvelopeAddress *)_address {
-  NSString *s;
-  
-  s = [_address personalName];
-  if ([s isNotNull]) return s;
-  
-  s = [_address baseEMail];
-  if ([s isNotNull]) return s;
-  
-  [self debugWithFormat:@"WARNING: unexpected envelope address: %@", _address];
-  return [_address stringValue];
-}
-
-- (NSString *)stringForArray:(NSArray *)_addresses {
-  NSMutableString *ms;
-  unsigned i, count;
-  
-  if ((count = [_addresses count]) == 0)
-    return nil;
-  
-  if (count == 1)
-    return [self stringForObjectValue:[_addresses objectAtIndex:0]];
-  
-  ms = [NSMutableString stringWithCapacity:16 * count];
-  for (i = 0; i < count && [ms length] < [self maxLength]; i++) {
-    NSString *s;
-    
-    s = [self stringForObjectValue:[_addresses objectAtIndex:i]];
-    if (s == nil)
-      continue;
-    
-    if ([ms length] > 0) [ms appendString:[self separator]];
-    [ms appendString:s];
-  }
-  return ms;
-}
-
-/* formatter entry function */
-
-- (NSString *)stringForObjectValue:(id)_address {
-  if (![_address isNotNull])
-    return nil;
-  
-  if ([_address isKindOfClass:StrClass]) /* preformatted? */
-    return _address;
-  
-  if ([_address isKindOfClass:EnvAddrClass])
-    return [self stringForEnvelopeAddress:_address];
-  
-  if ([_address isKindOfClass:[NSArray class]])
-    return [self stringForArray:_address];
-  
-  [self debugWithFormat:
-         @"NOTE: unexpected object for envelope formatter: %@<%@>",
-         _address, NSStringFromClass([_address class])];
-  return [_address stringValue];
-}
-
-@end /* UIxEnvelopeAddressFormatter */
index 0341e336698463d23c041653932332cad77515aa..490ccc33728c504e4d0c7424a1c375dc64452801 100644 (file)
@@ -24,6 +24,7 @@
 
 @interface UIxMailView : UIxComponent
 {
+  id message;
 }
 
 - (BOOL)isDeletableClientObject;
 @end
 
 #include <SoObjects/Mailer/SOGoMailObject.h>
+#include <NGImap4/NGImap4Envelope.h>
 #include "common.h"
 
 @implementation UIxMailView
 
+- (void)dealloc {
+  [self->message release];
+  [super dealloc];
+}
+
+/* notifications */
+
+- (void)sleep {
+  [self->message release]; self->message = nil;
+  [super sleep];
+}
+
+/* fetching */
+
+- (NSArray *)fetchKeys {
+  /* Note: see SOGoMailManager.m for allowed IMAP4 keys */
+  static NSArray *keys = nil;
+  if (keys == nil) 
+    keys = [[NSArray alloc] initWithObjects:@"FLAGS", @"ENVELOPE", nil];
+  return keys;
+}
+
+- (id)message {
+  id msgs;
+  
+  if (self->message != nil)
+    return [self->message isNotNull] ? self->message : nil;
+  
+  msgs = [[self clientObject] fetchParts:[self fetchKeys]]; // returns dict
+  msgs = [msgs valueForKey:@"fetch"];
+  if ([msgs count] == 0)
+    return nil;
+  return [msgs objectAtIndex:0];
+}
+
+/* derived accessors */
+
+- (BOOL)hasCC {
+  return [[self valueForKeyPath:@"message.envelope.cc"] count] > 0 ? YES : NO;
+}
+
+/* actions */
+
+- (id)defaultAction {
+  if ([self message] == nil) {
+    return [NSException exceptionWithHTTPStatus:404 /* Not Found */
+                       reason:@"did not find specified message!"];
+  }
+  return self;
+}
+
 - (BOOL)isDeletableClientObject {
   return [[self clientObject] respondsToSelector:@selector(delete)];
 }
index 95dae8aea1e6943c060c3d28171e8f5dc3efe577..203425983af25f38dfeab7b48df5bcbe161bf227 100644 (file)
   title="name"
   const:hideFolderTree="1"
 >
+  <!-- 
+    todo: we cannot make this static because the CC list has a dynamic height?
+    -->
   <table class="mailer_fieldtable">
     <tr class="mailer_fieldrow">
       <td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
-      <td class="mailer_subjectfieldvalue">Re: Statuslist</td>
+      <td class="mailer_subjectfieldvalue">
+        <var:string value="message.envelope.subject"
+                    formatter="context.mailSubjectFormatter"/>
+      </td>
     </tr>
     <tr class="mailer_fieldrow">
       <td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
       <td class="mailer_fieldvalue">
         <!-- compose link? -->
-        <a href="#">Maxime Wacker [mwacker@linagora.com]</a>
+        <a href="#">
+          <var:string value="message.envelope.from"
+               formatter="context.mailEnvelopeFullAddressFormatter" /></a>
       </td>
     </tr>
     <tr class="mailer_fieldrow">
       <td class="mailer_fieldname" ><var:string label:value="Date"/>:</td>
-      <td class="mailer_fieldvalue">08.09.2004 15:32</td>
+      <td class="mailer_fieldvalue">
+        <var:string value="message.envelope.date" 
+                    formatter="context.mailDateFormatter"/>
+      </td>
     </tr>
+
     <tr class="mailer_fieldrow">
       <td class="mailer_fieldname" ><var:string label:value="To"/>:</td>
       <td class="mailer_fieldvalue">
         <!-- compose link? -->
-        <a href="#">Helge Hess [helge.hess@skyrix.com]</a>
+        <var:foreach list="message.envelope.to" item="currentAddress">
+          <a href="#">
+            <var:string value="currentAddress"
+                 formatter="context.mailEnvelopeFullAddressFormatter" /></a>
+        </var:foreach>
       </td>
     </tr>
+    <var:if condition="hasCC">
+      <tr class="mailer_fieldrow">
+        <td class="mailer_fieldname" ><var:string label:value="CC"/>:</td>
+        <td class="mailer_fieldvalue">
+          <!-- compose link? -->
+          <var:foreach list="message.envelope.cc" item="currentAddress">
+            <a href="#">
+              <var:string value="currentAddress"
+                   formatter="context.mailEnvelopeFullAddressFormatter" /></a>
+            <br /> <!-- TODO: better to use li+CSS -->
+          </var:foreach>
+        </td>
+      </tr>
+    </var:if>
   </table>
   
   <div class="mailer_mailcontent">
-    a b c<br />
+<!--
+    <pre><var:string value="message" /></pre><br />
+-->
     <img rsrc:src="tbird_073_viewer.png" />
   </div>
 <!--
index 317960a726fc24e656b0d801367866c318018c26..c351558f441a4d159527ee99c46d76a467ff4349 100644 (file)
@@ -1,3 +1,3 @@
 # $Id$
 
-SUBMINOR_VERSION:=10
+SUBMINOR_VERSION:=11
index 7d9d603b2cdddcbbed1dd479392e752324139443..483db2a460f51719e74cccc9c41fabbe054734f6 100644 (file)
@@ -37,6 +37,7 @@
 - (NSFormatter *)mailSubjectFormatter;
 - (NSFormatter *)mailDateFormatter;
 - (NSFormatter *)mailEnvelopeAddressFormatter;
+- (NSFormatter *)mailEnvelopeFullAddressFormatter;
 
 @end
 
index 3603b756e9b6ff8a33df393c6f164f7789ee4530..83a195c81150aefa4c69c774aa3275de8a557f32 100644 (file)
@@ -39,5 +39,9 @@
 - (NSFormatter *)mailEnvelopeAddressFormatter {
   return [[[UIxEnvelopeAddressFormatter alloc] init] autorelease];
 }
+- (NSFormatter *)mailEnvelopeFullAddressFormatter {
+  return [[[UIxEnvelopeAddressFormatter alloc] 
+           initWithMaxLength:256 generateFullEMail:YES] autorelease];
+}
 
 @end /* WOContext(UIxMailer) */
index 6a0d63e091672495982a7f5b9fa96f5455909325..d1bdc899c847ccffd47f5af8cbab7e16f41955cb 100644 (file)
@@ -260,9 +260,10 @@ tr.mailer_fieldrow {
   font-family: Arial, Helvetica, Verdana, Geneva, Tahoma, sans-serif;
 }
 td.mailer_fieldname {
-  padding-left: 24px;
-  text-align:   right;
-  font-weight:  bold;
+  padding-left:   24px;
+  text-align:     right;
+  font-weight:    bold;
+  vertical-align: top;
 }
 td.mailer_fieldvalue {
   width: 95%;
@@ -272,6 +273,7 @@ td.mailer_subjectfieldvalue {
 }
 td.mailer_fieldvalue a {
   text-decoration: underline;
+  vertical-align:  top;
 }
 
 div.mailer_mailcontent { 
@@ -279,4 +281,5 @@ div.mailer_mailcontent {
   border-top-width: 1;
   border-top-style: solid;
   background-color: white;
+  padding:          8px;
 }