+2005-01-31 Helge Hess <helge.hess@opengroupware.org>
+
+ * v0.9.84
+
+ * UIxMailView.m: properly recurse into message/rfc822 bodies for flat
+ content fetches
+
+ * UIxMailView.m, UIxMailPartMessageViewer.m: added links for email
+ addresses (currently mailto://)
+
2005-01-30 Helge Hess <helge.hess@opengroupware.org>
+
+ * v0.9.83
+
+ * UIxMailRenderingContext.m: activate UIxMailPartMessageViewer for
+ message/rfc822 contents
+
+ * added a UIxMailPartMessageViewer for displaying embedded (eg
+ forwarded) MIME messages
* v0.9.82
UIxMailPartLinkViewer.m \
UIxMailPartMixedViewer.m \
UIxMailPartAlternativeViewer.m \
+ UIxMailPartMessageViewer.m \
\
UIxFilterList.m \
UIxSieveEditor.m \
UIxMailPartImageViewer.wox \
UIxMailPartLinkViewer.wox \
UIxMailPartAlternativeViewer.wox\
+ UIxMailPartMessageViewer.wox \
\
UIxFilterList.wox \
UIxSieveEditor.wox \
Multiparts: multipart/MIXED, multipart/SIGNED
+Feature: we fetch all plain/text bodies in a single run by traversing the
+ body structure.
+
Sample Bodystructure (GPG):
---snip---
{
/*
- Copyright (C) 2004 SKYRIX Software AG
+ Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of OpenGroupware.org.
if ([_address isKindOfClass:[NSArray class]])
return [self stringForArray:_address];
-
+
[self debugWithFormat:
@"NOTE: unexpected object for envelope formatter: %@<%@>",
_address, NSStringFromClass([_address class])];
@implementation UIxMailPartLinkViewer
-- (void)dealloc {
- [super dealloc];
-}
-
/* URLs */
- (NSString *)pathToAttachment {
<var:string label:value="Size" />:
<var:string value="bodyInfo.size" formatter="sizeFormatter" />
</div>
-
+
<!-- debug
+ <pre><var:string value="bodyInfo"/></pre>
+
<a var:href="pathToAttachment"
var:title="bodyInfo"
class="mailer_imagecontent"
--- /dev/null
+/*
+ Copyright (C) 2004-2005 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 "UIxMailPartViewer.h"
+
+/*
+ UIxMailPartMessageViewer
+
+ Show message/rfc822 mail parts. Note that the IMAP4 server already returns a
+ proper body structure of the message.
+
+ Relevant body-info keys:
+ to/sender/from/cc/bcc/in-reply-to/reply-to - array of addr-dicts
+ type/subtype - message/RFC822
+ size
+ subject
+ parameterList - dict (eg 'name')
+ messageId
+ date
+ encoding - 7BIT
+ bodyLines - 83
+ bodyId - (empty string?)
+ description - (empty string?, content-description?)
+
+ body - a body structure?
+
+ Addr-Dict:
+ hostName / mailboxName / personalName / sourceRoute
+*/
+
+@class NGImap4Envelope;
+
+@interface UIxMailPartMessageViewer : UIxMailPartViewer
+{
+ NGImap4Envelope *envelope;
+ id currentAddress;
+}
+
+@end
+
+#include "WOContext+UIxMailer.h"
+#include "UIxMailRenderingContext.h"
+#include <NGImap4/NGImap4Envelope.h>
+#include <NGImap4/NGImap4EnvelopeAddress.h>
+#include "common.h"
+
+@implementation UIxMailPartMessageViewer
+
+- (void)dealloc {
+ [self->currentAddress release];
+ [self->envelope release];
+ [super dealloc];
+}
+
+/* cache maintenance */
+
+- (void)resetBodyInfoCaches {
+ [super resetBodyInfoCaches];
+ [self->envelope release]; self->envelope = nil;
+ [self->currentAddress release]; self->currentAddress = nil;
+}
+
+/* notifications */
+
+- (void)sleep {
+ [self->currentAddress release]; self->currentAddress = nil;
+ [super sleep];
+}
+
+/* accessors */
+
+- (void)setCurrentAddress:(id)_addr {
+ ASSIGN(self->currentAddress, _addr);
+}
+- (id)currentAddress {
+ return self->currentAddress;
+}
+
+/* nested body structure */
+
+- (id)contentInfo {
+ return [[self bodyInfo] valueForKey:@"body"];
+}
+
+- (id)contentPartPath {
+ /*
+ Path processing is a bit weird in the context of message/rfc822. If we have
+ a multipart, the multipart itself has no own identifier! Instead the
+ children of the multipart are directly mapped into the message namespace.
+
+ If the message has just a plain content, ids seems to be as expected (that
+ is, its just a "1").
+ */
+ NSArray *pp;
+ NSString *mt;
+
+ mt = [[[self contentInfo] valueForKey:@"type"] lowercaseString];
+ if ([mt isEqualToString:@"multipart"])
+ return [self partPath];
+
+ pp = [self partPath];
+ return [pp count] > 0
+ ? [pp arrayByAddingObject:@"1"]
+ : [NSArray arrayWithObject:@"1"];
+}
+
+- (id)contentViewerComponent {
+ id info;
+
+ info = [self contentInfo];
+ return [[[self context] mailRenderingContext] viewerForBodyInfo:info];
+}
+
+/* generating envelope */
+
+- (NGImap4Envelope *)envelope {
+ if (self->envelope == nil) {
+ self->envelope = [[NGImap4Envelope alloc] initWithBodyStructureInfo:
+ [self bodyInfo]];
+ }
+ return self->envelope;
+}
+
+/* links to recipients */
+
+- (NSString *)linkToEnvelopeAddress:(NGImap4EnvelopeAddress *)_address {
+ // TODO: make some web-link, eg open a new compose panel?
+ return [@"mailto:" stringByAppendingString:[_address baseEMail]];
+}
+
+- (NSString *)fromLink {
+ return [self linkToEnvelopeAddress:[[self envelope] from]];
+}
+- (NSString *)currentAddressLink {
+ return [self linkToEnvelopeAddress:[self currentAddress]];
+}
+
+@end /* UIxMailPartMessageViewer */
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<div xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ class="linked_attachment_frame"
+>
+ <div class="linked_attachment_body">
+
+ <!-- TODO: the table is a DUP to UIxMailView, own component? -->
+ <table class="mailer_fieldtable">
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
+ <td class="mailer_subjectfieldvalue">
+ <var:string value="envelope.subject"
+ formatter="context.mailSubjectFormatter"/>
+<!--
+ <a var:href="pathToAttachment"
+ var:title="filenameForDisplay"
+ >(<var:string label:value="download" />)</a>
+-->
+ </td>
+ </tr>
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
+ <td class="mailer_fieldvalue">
+ <!-- compose link? -->
+ <a var:href="fromLink">
+ <var:string value="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">
+ <var:string value="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? -->
+ <var:foreach list="envelope.to" item="currentAddress">
+ <a var:href="currentAddressLink">
+ <var:string value="currentAddress"
+ formatter="context.mailEnvelopeFullAddressFormatter" /></a>
+ </var:foreach>
+ </td>
+ </tr>
+ <var:if condition="envelope.hasCC">
+ <tr class="mailer_fieldrow">
+ <td class="mailer_fieldname" ><var:string label:value="CC"/>:</td>
+ <td class="mailer_fieldvalue">
+ <!-- compose link? -->
+ <var:foreach list="envelope.cc" item="currentAddress">
+ <a var:href="currentAddressLink">
+ <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">
+ <var:component value="contentViewerComponent"
+ bodyInfo="contentInfo"
+ partPath="contentPartPath" />
+ </div>
+
+<!-- debug
+ <pre><var:string value="envelope"/></pre>
+ <pre><var:string value="bodyInfo.body"/></pre>
+-->
+ </div>
+</div>
NSData *content;
if ((content = [self decodedFlatContent]) == nil) {
- [self errorWithFormat:@"got no text content: %@", [self partPath]];
+ [self errorWithFormat:@"got no text content: %@",
+ [[self partPath] componentsJoinedByString:@"."]];
return nil;
}
WOComponent *textViewer;
WOComponent *imageViewer;
WOComponent *linkViewer;
+ WOComponent *messageViewer;
}
- (id)initWithViewer:(WOComponent *)_viewer context:(WOContext *)_ctx;
- (void)dealloc {
[self->alternativeViewer release];
- [self->mixedViewer release];
- [self->textViewer release];
- [self->imageViewer release];
- [self->linkViewer release];
+ [self->mixedViewer release];
+ [self->textViewer release];
+ [self->imageViewer release];
+ [self->linkViewer release];
+ [self->messageViewer release];
[super dealloc];
}
[self->textViewer release]; self->textViewer = nil;
[self->imageViewer release]; self->imageViewer = nil;
[self->linkViewer release]; self->linkViewer = nil;
+ [self->messageViewer release]; self->messageViewer = nil;
}
/* fetching */
return self->linkViewer;
}
+- (WOComponent *)messageViewer {
+ if (self->messageViewer == nil) {
+ self->messageViewer =
+ [[self->viewer pageWithName:@"UIxMailPartMessageViewer"] retain];
+ }
+ return self->messageViewer;
+}
+
- (WOComponent *)viewerForBodyInfo:(id)_info {
NSString *mt, *st;
}
else if ([mt isEqualToString:@"image"])
return [self imageViewer];
+ else if ([mt isEqualToString:@"message"] && [st isEqualToString:@"rfc822"])
+ return [self messageViewer];
else if ([mt isEqualToString:@"application"]) {
/*
- octed-stream (generate download link?)
+ octet-stream (generate download link?, autodetect type?)
pgp-viewer
*/
}
#include "WOContext+UIxMailer.h"
#include <SoObjects/Mailer/SOGoMailObject.h>
#include <NGImap4/NGImap4Envelope.h>
+#include <NGImap4/NGImap4EnvelopeAddress.h>
#include "common.h"
@implementation UIxMailView
return s;
}
+/* links (DUP to UIxMailPartViewer!) */
+
+- (NSString *)linkToEnvelopeAddress:(NGImap4EnvelopeAddress *)_address {
+ // TODO: make some web-link, eg open a new compose panel?
+ return [@"mailto:" stringByAppendingString:[_address baseEMail]];
+}
+
+- (NSString *)fromLink {
+ return [self linkToEnvelopeAddress:
+ [[self clientObject] fromEnvelopeAddress]];
+}
+- (NSString *)currentAddressLink {
+ return [self linkToEnvelopeAddress:[self currentAddress]];
+}
+
/* fetching */
- (id)message {
NSArray *parts;
unsigned i, count;
BOOL fetchPart;
+ id body;
fetchPart = [self shouldFetchPartOfType:[_info valueForKey:@"type"]
subtype:[_info valueForKey:@"subtype"]];
[self addRequiredKeysOfStructure:childInfo path:sp toArray:_keys];
}
+
+ /* check body */
+
+ if ((body = [_info objectForKey:@"body"]) != nil) {
+ NSString *sp;
+
+ sp = [[body valueForKey:@"type"] lowercaseString];
+ if ([sp isEqualToString:@"multipart"])
+ sp = _p;
+ else
+ sp = [_p length] > 0 ? [_p stringByAppendingString:@".1"] : @"1";
+ [self addRequiredKeysOfStructure:body path:sp toArray:_keys];
+ }
}
- (NSArray *)contentFetchKeys {
<tr class="mailer_fieldrow">
<td class="mailer_fieldname" ><var:string label:value="From"/>:</td>
<td class="mailer_fieldvalue">
- <!-- compose link? -->
- <a href="#">
+ <a var:href="fromLink">
<var:string value="clientObject.fromEnvelopeAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
</td>
<tr class="mailer_fieldrow">
<td class="mailer_fieldname" ><var:string label:value="To"/>:</td>
<td class="mailer_fieldvalue">
- <!-- compose link? -->
<var:foreach list="clientObject.toEnvelopeAddresses"
item="currentAddress">
- <a href="#">
+ <a var:href="currentAddressLink">
<var:string value="currentAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
</var:foreach>
<tr class="mailer_fieldrow">
<td class="mailer_fieldname" ><var:string label:value="CC"/>:</td>
<td class="mailer_fieldvalue">
- <!-- compose link? -->
<var:foreach list="clientObject.ccEnvelopeAddresses"
item="currentAddress">
- <a href="#">
+ <a var:href="currentAddressLink">
<var:string value="currentAddress"
formatter="context.mailEnvelopeFullAddressFormatter" /></a>
<br /> <!-- TODO: better to use li+CSS -->
# version file
-SUBMINOR_VERSION:=82
+SUBMINOR_VERSION:=84
+# v0.9.84 requires libNGMime v4.5.209
# v0.9.81 requires SoObjects/Sieve v0.9.5
# v0.9.80 requires SoObjects/Mailer v0.9.59
# v0.9.78 requires SoObjects/Mailer v0.9.58