[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Re: kmail: bugreport+bugfix (nested multipart messages)
From:       Daniel F Moisset <dmoisset () grulic ! org ! ar>
Date:       2000-09-27 1:47:47
[Download RAW message or body]

On Sun, 24 Sep 2000, Michael Haeckel wrote:
> ... 
> In general we appreciate every help, but for me it is not easy to test and 
> possibly apply it, for the following reasons. You didn't send a patch but the 
> whole file. Plese use "diff -u (old-file) (new-file) > patch.diff" and send 
> us the output file, that I can see the changes and also am able to apply the 
> patch to a newer version of KMail.

Ok, after a couple of days of CVS and slow modem, it's attached.

> Another problem is the we are currently 
> working on much newer version of KMail that will come with KDE2 and your 
> changes will probably require some adaption.

I suppose so. It's a hackish patch anyway. It works for me for what I
want, but could be a lot better.

> The current development version of KMail still is not able to display the 
> test messages you sent correctely.

The result with the patch is the following:
  The first message is displayed when "Prefer HTML to text" is
enabled; both parts are displayed (text/plain and text/html). When "Prefer
HTML" is disabled, both parts are shown, but the text/html is not
rendered; the HTML source is displayed instead. (That is with View|Inline 
attachments selected).
I don't know if that's the desired behavior, but at least parts are
separated, and decoded according to Content-Transfer-Encoding.
  The second message is still rendered incorrectly; apparently mimelib
fails to recognize it as a multipart message. Perhaps the format is
incorrect (it was artificially composed), but PINE shows the parts as I
think they should be.

> If you want to have your improvements in KMail, then please send us a diff 
> against a current beta or CVS version of KMail.
I made it against a CVS version 

Anyway, it will be ugly. KMMessage::getBodyPart() makes the message look
like a list of parts, when it's actually a tree. I changed it so it now
reads all the leaf nodes (attachments) instead of only the top level, but
a clean fix should involve changing the interfaec of kmmesage (ie,
kmmessage, and all its client classes).

Without the patch, kmail takes each top-level *tree*, and it renders it
correctly when it's a common message part (text, html, images,
attached-files), but shows an undecoded list of parts when it's
not; that's quite usual with mails sent with Outlook. I think it's the
cause of several reports I've seen frequently in this list (or for
example, bugs #7077 and #6710)

Regards,

	Daniel

-- 
Syntactic sugar causes cancer of the semicolon --Alan Perlis

["patch.diff" (TEXT/PLAIN)]

--- kmmessage.cpp	Tue Sep 26 10:44:30 2000
+++ kmmessage.cpp.new	Tue Sep 26 21:50:24 2000
@@ -1557,15 +1557,65 @@
 }
 
 
+// Patched by Daniel Moisset <dmoisset@grulic.org.ar>
+// modified numbodyparts, bodypart to take nested body parts as
+// a linear sequence.
+// third revision, Sep 26 2000
+
+// this is support structure for traversing tree without recursion
+struct nestedMsgStack
+{
+   DwBodyPart *msgPart;
+   nestedMsgStack *next;
+} nestedMsgStack ;
+// for malloc 
+#include <stdlib.h>
+
 //-----------------------------------------------------------------------------
 int KMMessage::numBodyParts(void) const
 {
-  int count;
+  int count = 0;
   DwBodyPart* part = mMsg->Body().FirstBodyPart();
+  struct nestedMsgStack *currPart;
+  struct nestedMsgStack *tempPart;
+  
+  currPart = (struct nestedMsgStack *) malloc (sizeof(nestedMsgStack));
+  assert(currPart);
+  currPart->next = NULL ;
+  currPart->msgPart = part ;
+  
+  while (currPart->msgPart) 
+  {
+     //dive into multipart messages
+     while ( currPart->msgPart->Headers().HasContentType() &&
+             strcmp("multipart",currPart->msgPart->Headers().ContentType().TypeStr().c_str()) == 0 )
+     {
+        tempPart = (struct nestedMsgStack *) malloc (sizeof(nestedMsgStack));
+        assert(tempPart);
+	tempPart->next = currPart ;
+	tempPart->msgPart = currPart->msgPart->Body().FirstBodyPart() ; 
+	currPart = tempPart ;
+     }
+     // this is wher currPart->msgPart contains a leaf message part
+     count++;
+     // go up in the tree until reaching a node with next 
+     // (or the last top-level node)
+     while (!(currPart->msgPart->Next()) && currPart->next)
+     {
+        tempPart = currPart ;
+	currPart = currPart->next ;
+	free (tempPart) ;
+     } ;
+     currPart->msgPart = currPart->msgPart->Next() ;
+  } ;
 
-  for (count=0; part; count++)
-    part = part->Next();
-
+  //clean up stack
+  while (currPart)
+  {
+     tempPart = currPart->next ;
+     free(currPart) ;
+     currPart = tempPart ;
+  } ;
   return count;
 }
 
@@ -1576,11 +1626,55 @@
   DwBodyPart* part;
   DwHeaders* headers;
   int curIdx;
+  struct nestedMsgStack *currPart;
+  struct nestedMsgStack *tempPart;
 
   // Get the DwBodyPart for this index
   part = mMsg->Body().FirstBodyPart();
-  for (curIdx=0; curIdx < aIdx && part; ++curIdx)
-    part = part->Next();
+  
+  currPart = (struct nestedMsgStack *) malloc (sizeof(nestedMsgStack));
+  assert(currPart);
+  currPart->next = NULL ;
+  currPart->msgPart = part ;
+  
+  curIdx=0;
+  part = NULL ;
+  while (currPart->msgPart && !part) 
+  {
+     //dive into multipart messages
+     while ( currPart->msgPart->Headers().HasContentType() &&
+             strcmp("multipart",currPart->msgPart->Headers().ContentType().TypeStr().c_str()) == 0 )
+     {
+        tempPart = (struct nestedMsgStack *) malloc (sizeof(nestedMsgStack));
+	assert(tempPart) ;
+	tempPart->next = currPart ;
+	tempPart->msgPart = currPart->msgPart->Body().FirstBodyPart() ; 
+	currPart = tempPart ;
+     }
+     // this is where currPart->msgPart contains a leaf message part
+     if (curIdx==aIdx)
+     {
+        part = currPart->msgPart ;
+     }
+     curIdx++;
+     // go up in the tree until reaching a node with next 
+     // (or the last top-level node)
+     while (!(currPart->msgPart->Next()) && currPart->next)
+     {
+        tempPart = currPart ;
+	currPart = currPart->next ;
+	free (tempPart) ;
+     } ;
+     currPart->msgPart = currPart->msgPart->Next() ;
+  } ;
+
+  //clean up stack
+  while (currPart)
+  {
+     tempPart = currPart->next ;
+     free(currPart) ;
+     currPart = tempPart ;
+  } ;
 
   // If the DwBodyPart was found get the header fields and body
   if (part)

_______________________________________________
Kmail Developers mailing list
Kmail@master.kde.org
http://master.kde.org/mailman/listinfo/kmail


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic