File r899972.diff of Package kdepim4
Subject: kmail: fix inline-forwarding of messages with attachments.
From: wstephenson@suse.de
Bug: kde#178128,kde#146921
Patch-upstream: 899972
--- kmail/templateparser.cpp (revision 899971)
+++ kmail/templateparser.cpp (revision 899972)
@@ -28,6 +28,8 @@
#include "globalsettings_base.h"
#include "kmkernel.h"
+#include <mimelib/bodypart.h>
+
#include <kpimidentities/identity.h>
#include <kpimidentities/identitymanager.h>
@@ -845,14 +847,22 @@ void TemplateParser::processWithTemplate
}
}
- // kDebug(5006) <<"Message body:" << body;
+ // kDebug(5006) << "Message body:" << body;
if ( mAppend ) {
QByteArray msg_body = mMsg->body();
msg_body.append( body.toUtf8() );
mMsg->setBody( msg_body );
} else {
- mMsg->setBodyFromUnicode( body );
+ DwEntity *entityToChange = 0;
+ if ( mMsg->typeStr().toLower() == "multipart" ) {
+ entityToChange = mMsg->findDwBodyPart( "text", "plain" );
+ if ( !entityToChange )
+ kWarning() << "No text/plain part found in this multipart message, "
+ "template parser can not set the text!";
+ }
+
+ mMsg->setBodyFromUnicode( body, entityToChange );
}
}
--- kmail/kmmessage.h (revision 899971)
+++ kmail/kmmessage.h (revision 899972)
@@ -31,6 +31,7 @@ class KMMessagePart;
class KMMsgInfo;
class KMForwardCommand;
+class DwEntity;
class DwMessage;
class DwBodyPart;
class DwMediaType;
@@ -489,25 +490,40 @@ public:
the header via headers() function) */
void setNeedsAssembly();
- /** Get or set the 'Content-Transfer-Encoding' header field
- The member functions that involve enumerated types (ints)
- will work only for well-known encodings. */
+ /**
+ * Get or set the 'Content-Transfer-Encoding' header field
+ * The member functions that involve enumerated types (ints)
+ * will work only for well-known encodings.
+ * Some functions take a DwEntity as second parameter, which
+ * specifies the body part or message of which the CTE will be changed or
+ * returned. If this is zero, the toplevel message will be taken.
+ */
QByteArray contentTransferEncodingStr() const;
- int contentTransferEncoding() const;
- void setContentTransferEncodingStr(const QByteArray& aStr);
- void setContentTransferEncoding(int aCte);
+ int contentTransferEncoding( DwEntity *entity = 0 ) const;
+ void setContentTransferEncodingStr( const QByteArray& cteString, DwEntity *entity = 0 );
+ void setContentTransferEncoding( int cte, DwEntity *entity = 0 );
- /** Cte is short for ContentTransferEncoding.
- These functions are an alternative to the ones with longer names. */
+ /**
+ * Cte is short for ContentTransferEncoding.
+ * These functions are an alternative to the ones with longer names.
+ */
QByteArray cteStr() const { return contentTransferEncodingStr(); }
- int cte() const { return contentTransferEncoding(); }
- void setCteStr(const QByteArray& aStr) { setContentTransferEncodingStr(aStr); }
- void setCte(int aCte) { setContentTransferEncoding(aCte); }
+ int cte( DwEntity *entity = 0 ) const { return contentTransferEncoding( entity ); }
+ void setCteStr( const QByteArray& aStr, DwEntity *entity = 0 ) {
+ setContentTransferEncodingStr( aStr, entity );
+ }
+ void setCte( int aCte, DwEntity *entity = 0 ) {
+ setContentTransferEncoding( aCte, entity );
+ }
- /** Sets this body part's content to @p str. @p str is subject to
- automatic charset and CTE detection.
- **/
- void setBodyFromUnicode( const QString & str );
+ /**
+ * Sets this body's content to @p str. @p str is subject to
+ * automatic charset and CTE detection.
+ *
+ * @param entity The body of this entity will be changed. If entity is 0,
+ * the body of the whole message will be changed.
+ */
+ void setBodyFromUnicode( const QString & str, DwEntity *entity = 0 );
/** Returns the body part decoded to unicode.
**/
@@ -522,11 +538,17 @@ public:
/** Hack to enable structured body parts to be set as flat text... */
void setMultiPartBody( const QByteArray & aStr );
- /** Set the message body, encoding it according to the current content
- transfer encoding. The first method for null terminated strings,
- the second for binary data */
- void setBodyEncoded(const QByteArray& aStr);
- void setBodyEncodedBinary(const QByteArray& aStr);
+ /**
+ * Set the message body, encoding it according to the current content
+ * transfer encoding. The first method for null terminated strings,
+ * the second for binary data.
+ *
+ * @param entity Specifies the body part or message of which the body will be
+ * set. If this is 0, the body of the toplevel message will be
+ * set.
+ */
+ void setBodyEncoded( const QByteArray& aStr );
+ void setBodyEncodedBinary( const QByteArray& bodyStr, DwEntity *entity = 0 );
/** Returns a list of content-transfer-encodings that can be used with
the given result of the character frequency analysis of a message or
@@ -535,19 +557,23 @@ public:
bool allow8Bit,
bool willBeSigned );
- /** Sets body, encoded in the best fitting
- content-transfer-encoding, which is determined by character
- frequency count.
-
- @param aBuf input buffer
- @param allowedCte return: list of allowed cte's
- @param allow8Bit whether "8bit" is allowed as cte.
- @param willBeSigned whether "7bit"/"8bit" is allowed as cte according to RFC 3156
- */
- void setBodyAndGuessCte( const QByteArray& aBuf,
- QList<int>& allowedCte,
- bool allow8Bit = false,
- bool willBeSigned = false );
+ /**
+ * Sets body, encoded in the best fitting
+ * content-transfer-encoding, which is determined by character
+ * frequency count.
+ *
+ * @param aBuf input buffer
+ * @param allowedCte return: list of allowed cte's
+ * @param allow8Bit whether "8bit" is allowed as cte.
+ * @param willBeSigned whether "7bit"/"8bit" is allowed as cte according to RFC 3156
+ * @param entity The body of this message or body part will get changed.
+ * If this is 0, the body of the toplevel message will be
+ * set.
+ */
+ void setBodyAndGuessCte( const QByteArray& aBuf, QList<int>& allowedCte,
+ bool allow8Bit = false,
+ bool willBeSigned = false,
+ DwEntity *entity = 0 );
/** Returns a decoded version of the body from the current content transfer
encoding. The first method returns a null terminated string, the second
@@ -705,8 +731,15 @@ public:
/** Get the message charset.*/
QByteArray charset() const;
- /** Set the message charset. */
- void setCharset(const QByteArray& aStr);
+ /**
+ * Sets the charset of the message or a subpart of the message.
+ * Only call this when the message or the subpart has a textual mimetype.
+ *
+ * @param aStr the MIME-compliant charset name, like 'ISO-88519-15'.
+ * @param entity the body part or message of which the charset should be changed.
+ * If this is 0, the charset of the toplevel message will be changed.
+ */
+ void setCharset( const QByteArray& charset, DwEntity *entity = 0 );
/** Get a QTextCodec suitable for this message part */
const QTextCodec * codec() const;
--- kmail/kmmessage.cpp (revision 899971)
+++ kmail/kmmessage.cpp (revision 899972)
@@ -2511,28 +2511,38 @@ QByteArray KMMessage::contentTransferEnc
//-----------------------------------------------------------------------------
-int KMMessage::contentTransferEncoding() const
+int KMMessage::contentTransferEncoding( DwEntity *entity ) const
{
- DwHeaders& header = mMsg->Headers();
- if (header.HasContentTransferEncoding())
+ if ( !entity )
+ entity = mMsg;
+
+ DwHeaders& header = entity->Headers();
+ if ( header.HasContentTransferEncoding() )
return header.ContentTransferEncoding().AsEnum();
else return DwMime::kCteNull;
}
//-----------------------------------------------------------------------------
-void KMMessage::setContentTransferEncodingStr(const QByteArray& aStr)
+void KMMessage::setContentTransferEncodingStr( const QByteArray& cteString,
+ DwEntity *entity )
{
- mMsg->Headers().ContentTransferEncoding().FromString(aStr);
- mMsg->Headers().ContentTransferEncoding().Parse();
+ if ( !entity )
+ entity = mMsg;
+
+ entity->Headers().ContentTransferEncoding().FromString( cteString );
+ entity->Headers().ContentTransferEncoding().Parse();
mNeedsAssembly = true;
}
//-----------------------------------------------------------------------------
-void KMMessage::setContentTransferEncoding(int aCte)
+void KMMessage::setContentTransferEncoding( int cte, DwEntity *entity )
{
- mMsg->Headers().ContentTransferEncoding().FromEnum(aCte);
+ if ( !entity )
+ entity = mMsg;
+
+ entity->Headers().ContentTransferEncoding().FromEnum( cte );
mNeedsAssembly = true;
}
@@ -2666,22 +2676,16 @@ QList<int> KMMessage::determineAllowedCt
void KMMessage::setBodyAndGuessCte( const QByteArray& aBuf,
QList<int> & allowedCte,
bool allow8Bit,
- bool willBeSigned )
+ bool willBeSigned,
+ DwEntity *entity )
{
- CharFreq cf( aBuf ); // it's safe to pass null arrays
+ if ( !entity )
+ entity = mMsg;
+ CharFreq cf( aBuf ); // it's safe to pass null arrays
allowedCte = determineAllowedCtes( cf, allow8Bit, willBeSigned );
-
-#ifndef NDEBUG
- DwString dwCte;
- DwCteEnumToStr(allowedCte[0], dwCte);
- kDebug(5006) <<"CharFreq returned" << cf.type() <<"/"
- << cf.printableRatio() << "and I chose"
- << dwCte.c_str();
-#endif
-
- setCte( allowedCte[0] ); // choose best fitting
- setBodyEncodedBinary( aBuf );
+ setCte( allowedCte[0], entity ); // choose best fitting
+ setBodyEncodedBinary( aBuf, entity );
}
//-----------------------------------------------------------------------------
@@ -2692,25 +2696,28 @@ void KMMessage::setBodyEncoded(const QBy
}
//-----------------------------------------------------------------------------
-void KMMessage::setBodyEncodedBinary(const QByteArray& aStr)
+void KMMessage::setBodyEncodedBinary( const QByteArray& bodyStr, DwEntity *entity )
{
- DwString dwSrc = KMail::Util::dwString(aStr);
+ if ( !entity )
+ entity = mMsg;
+
+ DwString dwSrc = KMail::Util::dwString( bodyStr );
DwString dwResult;
- switch (cte())
+ switch ( cte( entity ) )
{
case DwMime::kCteBase64:
- DwEncodeBase64(dwSrc, dwResult);
+ DwEncodeBase64( dwSrc, dwResult );
break;
case DwMime::kCteQuotedPrintable:
- DwEncodeQuotedPrintable(dwSrc, dwResult);
+ DwEncodeQuotedPrintable( dwSrc, dwResult );
break;
default:
dwResult = dwSrc;
break;
}
- mMsg->Body().FromString(dwResult);
+ entity->Body().FromString( dwResult );
mNeedsAssembly = true;
}
@@ -2722,6 +2729,7 @@ void KMMessage::setBody(const QByteArray
mNeedsAssembly = true;
}
+//-----------------------------------------------------------------------------
void KMMessage::setMultiPartBody( const QByteArray & aStr ) {
setBody( aStr );
mMsg->Body().Parse();
@@ -3965,7 +3973,7 @@ QByteArray KMMessage::charset() const
}
//-----------------------------------------------------------------------------
-void KMMessage::setCharset(const QByteArray& bStr)
+void KMMessage::setCharset( const QByteArray &charset, DwEntity *entity )
{
kWarning( type() != DwMime::kTypeText )
<< "Trying to set a charset for a non-textual mimetype." << endl
@@ -3973,23 +3981,32 @@ void KMMessage::setCharset(const QByteAr
<< "====================================================================" << endl
<< kBacktrace( 5 ) << endl
<< "====================================================================";
- QByteArray aStr = bStr;
- kAsciiToLower( aStr.data() );
- DwMediaType &mType = dwContentType();
+
+ if ( !entity )
+ entity = mMsg;
+
+ DwMediaType &mType = entity->Headers().ContentType();
mType.Parse();
- DwParameter *param=mType.FirstParameter();
- while(param)
+ DwParameter *param = mType.FirstParameter();
+ while( param ) {
+
// FIXME use the mimelib functions here for comparison.
- if (!kasciistricmp(param->Attribute().c_str(), "charset")) break;
- else param=param->Next();
- if (!param){
- param=new DwParameter;
- param->SetAttribute("charset");
- mType.AddParameter(param);
+ if ( !kasciistricmp( param->Attribute().c_str(), "charset" ) )
+ break;
+
+ param = param->Next();
+ }
+ if ( !param ) {
+ param = new DwParameter;
+ param->SetAttribute( "charset" );
+ mType.AddParameter( param );
}
else
mType.SetModified();
- param->SetValue(DwString(aStr));
+
+ QByteArray lowerCharset = charset;
+ kAsciiToLower( lowerCharset.data() );
+ param->SetValue( DwString( lowerCharset ) );
mType.Assemble();
}
@@ -4249,7 +4266,7 @@ void KMMessage::updateAttachmentState( D
}
}
-void KMMessage::setBodyFromUnicode( const QString &str )
+void KMMessage::setBodyFromUnicode( const QString &str, DwEntity *entity )
{
QByteArray encoding =
KMMsgBase::autoDetectCharset( charset(),
@@ -4260,8 +4277,9 @@ void KMMessage::setBodyFromUnicode( cons
const QTextCodec * codec = KMMsgBase::codecForName( encoding );
assert( codec );
QList<int> dummy;
- setCharset( encoding );
- setBodyAndGuessCte( codec->fromUnicode( str ), dummy, false /* no 8bit */ );
+ setCharset( encoding, entity );
+ setBodyAndGuessCte( codec->fromUnicode( str ), dummy, false /* no 8bit */,
+ false, entity );
}
const QTextCodec * KMMessage::codec() const
Index: kmail/templateparser.cpp
===================================================================
Index: kmail/kmmessage.h
===================================================================
Index: kmail/kmmessage.cpp
===================================================================