]> err.no Git - scalable-opengroupware.org/blobdiff - UI/MailPartViewers/UIxMailPartViewer.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1154 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / MailPartViewers / UIxMailPartViewer.m
index bb988c4031d34a3c36df4c774e3934e7eb0a05b6..36c2a1ad783013ebde498891aa1cc25912c9d067 100644 (file)
   02111-1307, USA.
 */
 
-#include "UIxMailPartViewer.h"
-#include "UIxMailRenderingContext.h"
-#include "UIxMailSizeFormatter.h"
-#include "../MailerUI/WOContext+UIxMailer.h"
-#include <NGExtensions/NSString+Encoding.h>
-#include "common.h"
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+
+#import <NGExtensions/NGBase64Coding.h>
+#import <NGExtensions/NSNull+misc.h>
+#import <NGExtensions/NSObject+Logs.h>
+#import <NGExtensions/NGQuotedPrintableCoding.h>
+#import <NGExtensions/NSString+Encoding.h>
+#import <NGExtensions/NSString+misc.h>
+
+#import <SoObjects/SOGo/NSString+Utilities.h>
+#import <SoObjects/Mailer/SOGoMailBodyPart.h>
+
+#import "UI/MailerUI/WOContext+UIxMailer.h"
+#import "UIxMailRenderingContext.h"
+#import "UIxMailSizeFormatter.h"
+
+#import "UIxMailPartViewer.h"
 
 @implementation UIxMailPartViewer
 
-- (void)dealloc {
-  [self->flatContent release];
-  [self->bodyInfo    release];
-  [self->partPath    release];
+- (void) dealloc
+{
+  [flatContent release];
+  [bodyInfo release];
+  [partPath release];
   [super dealloc];
 }
 
 /* caches */
 
-- (void)resetPathCaches {
+- (void) resetPathCaches
+{
   /* this is called when -setPartPath: is called */
-  [self->flatContent release]; self->flatContent = nil;
+  [flatContent release]; flatContent = nil;
 }
-- (void)resetBodyInfoCaches {
+
+- (void) resetBodyInfoCaches
+{
 }
 
 /* notifications */
 
-- (void)sleep {
+- (void) sleep
+{
   [self resetPathCaches];
   [self resetBodyInfoCaches];
-  [self->partPath release]; self->partPath = nil;
-  [self->bodyInfo release]; self->bodyInfo = nil;
+  [partPath release];
+  [bodyInfo release];
+  partPath = nil;
+  bodyInfo = nil;
   [super sleep];
 }
 
 /* accessors */
 
-- (void)setPartPath:(NSArray *)_path {
-  if ([_path isEqual:self->partPath])
+- (void) setPartPath: (NSArray *) _path
+{
+  if ([_path isEqual: partPath])
     return;
-  
-  ASSIGN(self->partPath, _path);
+
+  ASSIGN(partPath, _path);
+
   [self resetPathCaches];
 }
-- (NSArray *)partPath {
-  return self->partPath;
+
+- (NSArray *) partPath
+{
+  return partPath;
 }
 
-- (void)setBodyInfo:(id)_info {
-  ASSIGN(self->bodyInfo, _info);
+- (void) setBodyInfo: (id) _info
+{
+  ASSIGN(bodyInfo, _info);
 }
-- (id)bodyInfo {
-  return self->bodyInfo;
+
+- (id) bodyInfo
+{
+  return bodyInfo;
 }
 
-- (NSData *)flatContent {
-  if (self->flatContent != nil)
-    return [self->flatContent isNotNull] ? self->flatContent : nil;
+- (NSData *) flatContent
+{
+  if (flatContent != nil)
+    return [flatContent isNotNull] ? flatContent : nil;
   
-  self->flatContent = 
-    [[[[self context] mailRenderingContext] flatContentForPartPath:
-                                             [self partPath]] retain];
-  return self->flatContent;
+  flatContent = 
+    [[[context mailRenderingContext] flatContentForPartPath:
+                                             partPath] retain];
+  return flatContent;
 }
 
-- (NSData *)decodedFlatContent {
+- (NSData *) decodedFlatContent
+{
   NSString *enc;
   
-  enc = [[(NSDictionary *)[self bodyInfo] 
-                         objectForKey:@"encoding"] lowercaseString];
-  
+  enc = [[bodyInfo objectForKey:@"encoding"] lowercaseString];
+
   if ([enc isEqualToString:@"7bit"])
     return [self flatContent];
   
     return [[self flatContent] dataByDecodingQuotedPrintable];
   
   [self errorWithFormat:@"unsupported MIME encoding: %@", enc];
+
   return [self flatContent];
 }
 
-- (NSStringEncoding)fallbackStringEncoding {
+- (NSData *) content
+{
+  NSData *content;
+  NSEnumerator *parts;
+  id currentObject;
+  NSString *currentPart;
+
+  content = nil;
+
+  currentObject = [self clientObject];
+  parts = [partPath objectEnumerator];
+  currentPart = [parts nextObject];
+  while (currentPart)
+    {
+      currentObject = [currentObject lookupName: currentPart
+                                    inContext: context
+                                    acquire: NO];
+      currentPart = [parts nextObject];
+    }
+
+  content = [currentObject fetchBLOB];
+
+  return content;
+}
+
+- (NSStringEncoding) fallbackStringEncoding
+{
   return 0;
 }
+
 - (NSString *)flatContentAsString {
   /* Note: we even have the line count in the body-info! */
   NSString *charset;
   NSString *s;
   NSData   *content;
-  
-  if ((content = [self decodedFlatContent]) == nil) {
-    [self errorWithFormat:@"got no text content: %@", 
-           [[self partPath] componentsJoinedByString:@"."]];
-    return nil;
-  }
-  
-  charset = [(NSDictionary *)
-             [(NSDictionary *)[self bodyInfo] objectForKey:@"parameterList"]
-              objectForKey:@"charset"];
-  charset = [charset lowercaseString];
 
-  // TODO: properly decode charset, might need to handle encoding?
-  
-  if ([charset length] > 0) {
-    s = [NSString stringWithData: content usingEncodingNamed: charset];
-  }
-  else {
-    s = [[NSString alloc] initWithData: content encoding: NSUTF8StringEncoding];
-    s = [s autorelease];
-  }
+  content = [self decodedFlatContent];
+  if (content)
+    {
+      charset = [[bodyInfo objectForKey:@"parameterList"]
+                 objectForKey: @"charset"];
+
+      // TODO: properly decode charset, might need to handle encoding?
   
-  if (s == nil) {
-    /* 
-       Note: this can happend with iCalendar invitations sent by Outlook 2002.
-             It will mark the content as UTF-8 but actually deliver it as
+      if ([charset length] > 0)
+       s = [NSString stringWithData: content
+                     usingEncodingNamed: [charset lowercaseString]];
+      else
+       {
+         s = [[NSString alloc] initWithData: content
+                               encoding: NSUTF8StringEncoding];
+         [s autorelease];
+       }
+
+      if (!s)
+       {
+         /* 
+            Note: this can happend with iCalendar invitations sent by Outlook 2002.
+            It will mark the content as UTF-8 but actually deliver it as
             Latin-1 (or Windows encoding?).
-    */
-    [self errorWithFormat:@"could not convert content to text, charset: '%@'",
-            charset];
-    if ([self fallbackStringEncoding] > 0) {
-      s = [[NSString alloc] initWithData:content 
-                           encoding:[self fallbackStringEncoding]];
-      s = [s autorelease];
-      
-      if (s == nil) {
-       [self errorWithFormat:
-               @"  an attempt to use fallback encoding failed to."];
-      }
+         */
+         [self errorWithFormat:@"could not convert content to text, charset: '%@'",
+               charset];
+         if ([self fallbackStringEncoding] > 0)
+           {
+             s = [[NSString alloc] initWithData:content 
+                                   encoding: [self fallbackStringEncoding]];
+             if (s)
+               [s autorelease];
+             else
+               [self errorWithFormat:
+                       @"an attempt to use fallback encoding failed to."];
+           }
+       }
     }
-  }
+  else
+    {
+      [self errorWithFormat:@"got no text content: %@", 
+           [partPath componentsJoinedByString:@"."]];
+      s = nil;
+    }
+
   return s;
 }
 
 /* path extension */
 
-- (NSString *)pathExtensionForType:(NSString *)_mt subtype:(NSString *)_st {
+- (NSString *) pathExtensionForType: (NSString *) _mt
+                           subtype: (NSString *) _st
+{
   // TODO: support /etc/mime.types
   
   if (![_mt isNotNull] || ![_st isNotNull])
   return nil;
 }
 
-- (NSString *)preferredPathExtension {
-  return [self pathExtensionForType:[[self bodyInfo] valueForKey:@"type"]
-              subtype:[[self bodyInfo] valueForKey:@"subtype"]];
+- (NSString *) preferredPathExtension
+{
+  return [self pathExtensionForType: [bodyInfo valueForKey:@"type"]
+              subtype: [bodyInfo valueForKey:@"subtype"]];
 }
 
-- (NSString *)filename {
-  id tmp;
-  
-  tmp = [[self bodyInfo] valueForKey:@"parameterList"];
-  if (![tmp isNotNull])
-    return nil;
-  
-  tmp = [tmp valueForKey:@"name"];
-  if (![tmp isNotNull])
-    return nil;
-  if ([tmp length] == 0)
-    return nil;
-  
-  return tmp;
+- (NSString *) filename
+{
+  NSDictionary *parameters;
+  NSString *filename;
+
+  filename = nil;
+  parameters = [bodyInfo valueForKey: @"parameterList"];
+  if (parameters)
+    filename = [parameters valueForKey: @"name"];
+
+  if (!filename)
+    {
+      parameters = [[bodyInfo valueForKey: @"disposition"]
+                    valueForKey: @"parameterList"];
+      filename = [parameters valueForKey: @"filename"];
+    }
+
+  return filename;
 }
 
-- (NSString *)filenameForDisplay {
+- (NSString *) filenameForDisplay
+{
   NSString *s;
   
   if ((s = [self filename]) != nil)
     return s;
   
-  s = [[self partPath] componentsJoinedByString:@"-"];
+  s = [partPath componentsJoinedByString:@"-"];
   return ([s length] > 0)
     ? [@"untitled-" stringByAppendingString:s]
     : @"untitled";
 }
 
-- (NSFormatter *)sizeFormatter {
+- (NSFormatter *) sizeFormatter
+{
   return [UIxMailSizeFormatter sharedMailSizeFormatter];
 }
 
 /* URL generation */
 
-- (NSString *)pathToAttachmentObject {
+- (NSString *) pathToAttachmentObject
+{
   /* this points to the SoObject representing the part, no modifications */
   NSString *url, *n, *pext;
 
   /* path to mail controller object */
   
-  url = [[self clientObject] baseURLInContext:[self context]];
-  if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
+  url = [[self clientObject] baseURLInContext:context];
+  if (![url hasSuffix: @"/"])
+    url = [url stringByAppendingString: @"/"];
   
   /* mail relative path to body-part */
   
-  if ([(n = [[self partPath] componentsJoinedByString:@"/"]) isNotNull]) {
-    /* eg this was nil for a draft containing an HTML message */
+  /* eg this was nil for a draft containing an HTML message */
+  if ([(n = [partPath componentsJoinedByString:@"/"]) isNotNull])
     url = [url stringByAppendingString:n];
-  }
-  
-  /* we currently NEED the extension for SoObject lookup (should be fixed) */
-  
-  pext = [self preferredPathExtension];
-  if ([pext isNotNull] && [pext length] > 0) {
-    /* attach extension */
-    if ([url hasSuffix:@"/"]) {
-      /* this happens if the part is the root-content of the mail */
-      url = [url substringToIndex:([url length] - 1)];
-    }
-    url = [url stringByAppendingString:@"."];
-    url = [url stringByAppendingString:pext];
-  }
   
   return url;
 }
 
-- (NSString *)pathToAttachment {
+- (NSString *) pathToAttachment
+{
   /* this generates a more beautiful 'download' URL for a part */
-  NSString *url, *fn;
-
-  fn   = [self filename];
-  
-  if (![fn isNotNull] || ([fn length] == 0))
-    fn = nil;
-
-  /* get basic URL */
-
-  url = [self pathToAttachmentObject];
-  
-  /* 
-     If we have an attachment name, we attach it, this is properly handled by
-     SOGoMailBodyPart.
-  */
+  NSString *fn;
+  NSMutableString *url;
+
+  fn = [self filename];
+  if ([fn length] > 0)
+    {
+      /* get basic URL */
+      url = [NSMutableString stringWithString: [self pathToAttachmentObject]];
   
-  if (fn != nil) {
-    if (![url hasSuffix:@"/"]) url = [url stringByAppendingString:@"/"];
-    if (isdigit([fn characterAtIndex:0]))
-      url = [url stringByAppendingString:@"fn-"];
-    url = [url stringByAppendingString:[fn stringByEscapingURL]];
-    
-    // TODO: should we check for a proper extension?
-  }
+      /* 
+        If we have an attachment name, we attach it, this is properly handled by
+        SOGoMailBodyPart.
+      */
   
+      if (![url hasSuffix: @"/"])
+       [url appendString: @"/"];
+      if (isdigit([url characterAtIndex: 0]))
+       [url appendString: @"fn-"];
+      [url appendString: [fn stringByEscapingURL]];
+      // TODO: should we check for a proper extension?
+    }
+  else
+    url = nil;
+
   return url;
 }