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
===================================================================
openSUSE Build Service is sponsored by