* now fix NB#78955:
authorDirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>
Sun, 6 Jan 2008 10:49:25 +0000 (10:49 +0000)
committerDirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>
Sun, 6 Jan 2008 10:49:25 +0000 (10:49 +0000)
- choose the right MIME-part for the body, with breaking
          messages which worked before
- display 'inline' mime parts as attachments, if we don't
  display them otherwise
- create modest-tny-mime-part.[ch] as our TnyMimePart decorator

- do we need to use the new
modest_tny_mime_part_is_attachment_for_modest
  in other places too?

pmo-trunk-r3984

src/Makefile.am
src/modest-tny-mime-part.c [new file with mode: 0644]
src/modest-tny-mime-part.h [new file with mode: 0644]
src/modest-tny-msg.c
src/modest-tny-msg.h
src/widgets/modest-attachments-view.c

index 6bccb63..2872a4e 100644 (file)
@@ -1,6 +1,6 @@
 #
 # Makefile.am
-# Time-stamp: <2007-11-14 22:42:34 (djcb)>
+# Time-stamp: <2008-01-06 10:18:49 (djcb)>
 
 SUBDIRS=$(MODEST_PLATFORM) widgets $(dbus_api)
 
@@ -104,6 +104,8 @@ modest_SOURCES=\
        modest-tny-folder.h \
        modest-tny-local-folders-account.c \
        modest-tny-local-folders-account.h \
+       modest-tny-mime-part.c \
+       modest-tny-mime-part.h \
        modest-tny-msg.c \
        modest-tny-msg.h \
        modest-tny-outbox-account.c \
diff --git a/src/modest-tny-mime-part.c b/src/modest-tny-mime-part.c
new file mode 100644 (file)
index 0000000..bfd0d62
--- /dev/null
@@ -0,0 +1,128 @@
+/* Copyright (c) 2006, 2007, 2008 Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /*HAVE_CONFIG_H */
+
+#include "modest-tny-mime-part.h"
+#include <tny-simple-list.h>
+#include <tny-msg.h>
+#include <string.h> /* for strlen */
+#include <modest-tny-msg.h>
+#include "modest-text-utils.h"
+
+
+gchar*
+modest_tny_mime_part_get_header_value (TnyMimePart *part, const gchar *header)
+{
+       TnyList *pairs;
+       TnyIterator *iter;
+       gchar *val;
+       
+       g_return_val_if_fail (part && TNY_IS_MIME_PART(part), NULL);
+       g_return_val_if_fail (header, NULL);
+
+       pairs = tny_simple_list_new ();
+       
+       tny_mime_part_get_header_pairs (part, pairs);
+       iter = tny_list_create_iterator (pairs);
+
+       val = NULL;
+       while (!tny_iterator_is_done(iter) && !val) {
+
+               TnyPair *pair = (TnyPair*)tny_iterator_get_current(iter);
+               if (strcasecmp (header, tny_pair_get_name(pair)) == 0)
+                       val = g_strdup (tny_pair_get_value(pair));
+               g_object_unref (pair);          
+
+               tny_iterator_next (iter);
+       }
+
+       g_object_unref (pairs);
+       g_object_unref (iter);
+
+       return val;
+}
+
+
+
+
+/* we consider more things attachments than tinymail does...
+ */
+gboolean
+modest_tny_mime_part_is_attachment_for_modest (TnyMimePart *part)
+{
+       gchar *tmp, *content_type;
+       gboolean has_content_disp_name = FALSE;
+
+       g_return_val_if_fail (part && TNY_IS_MIME_PART(part), FALSE);
+       
+       /* if tinymail thinks it's an attachment, it definitely is */
+       if (tny_mime_part_is_attachment (part))
+               return TRUE; 
+
+       /* if the mime part is a message itself (ie. embedded), it's an attachment */
+       if (TNY_IS_MSG (part))
+               return TRUE;
+       
+       tmp = modest_tny_mime_part_get_header_value (part, "Content-Disposition");
+       if (tmp) {
+               gchar *content_disp = g_ascii_strdown(tmp, -1);
+               g_free (tmp);
+               has_content_disp_name = g_strstr_len (content_disp, strlen(content_disp), "name=") != NULL;
+               g_free (content_disp);
+       }
+               
+       /* if it doesn't have a content deposition with a name= attribute, it's not an attachment */
+       if (!has_content_disp_name)
+               return FALSE;
+       
+       /* ok, it must be content-disposition "inline" then, because "attachment"
+        * is already handle above "...is_attachment". modest consider these "inline" things
+         * attachments as well, unless they are embedded images for html mail 
+        */
+       content_type = g_ascii_strdown (tny_mime_part_get_content_type (part), -1);
+       if (!g_str_has_prefix (content_type, "image/")) {
+               g_free (content_type);
+               return TRUE; /* it's not an image, so it must be an attachment */
+       }
+       g_free (content_type);
+
+
+       /* now, if it's an inline-image, and it has a content-id or location, we
+        * we guess it's an inline image, and not an attachment */
+       if (tny_mime_part_get_content_id (part) || tny_mime_part_get_content_location(part))
+               return FALSE;
+               
+       /* in other cases... */
+       return TRUE;
+}
+
+
diff --git a/src/modest-tny-mime-part.h b/src/modest-tny-mime-part.h
new file mode 100644 (file)
index 0000000..b1c577c
--- /dev/null
@@ -0,0 +1,59 @@
+/* Copyright (c) 2006, 2007, 2008 Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MODEST_TNY_MIME_PART_H__
+#define __MODEST_TNY_MIME_PART_H__
+
+#include <tny-mime-part.h>
+
+/**
+ * modest_tny_mime_part_get_header_value:
+ * @self: some #TnyMimePart 
+ * @header: the header to get
+ * 
+ * gets the mail header for a #TnyMimePart as a newly allocated string,
+ * or NULL if it cannot be found
+ * 
+ * Returns: the header
+ **/
+gchar* modest_tny_mime_part_get_header_value (TnyMimePart *part, const gchar *header);
+
+
+/**
+ * modest_tny_mime_part_is_attachment_for_modest
+ * @self: some #TnyMimePart 
+ * 
+ * determines whether some MIME part is an attachment, from Modest's PoV.
+ *
+ * Returns: TRUE if it's an attachment, FALSE otherwise.
+ **/
+
+gboolean modest_tny_mime_part_is_attachment_for_modest (TnyMimePart *part);
+
+#endif /*__MODEST_TNY_MIME_PART_H__*/
index 943f4bc..437d79e 100644 (file)
@@ -40,6 +40,8 @@
 #include <camel/camel-stream-mem.h>
 #include <glib/gprintf.h>
 #include <modest-tny-folder.h>
+#include "modest-tny-mime-part.h"
+
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -408,8 +410,9 @@ modest_tny_msg_find_body_part_from_mime_part (TnyMimePart *msg, gboolean want_ht
                return TNY_MIME_PART (g_object_ref(G_OBJECT(msg)));
        } else {
                do {
-                       gchar *content_type = NULL;
-                       
+                       gchar *tmp, *content_type = NULL;
+                       gboolean has_content_disp_name = FALSE;
+
                        part = TNY_MIME_PART(tny_iterator_get_current (iter));
 
                        if (!part) {
@@ -422,15 +425,26 @@ modest_tny_msg_find_body_part_from_mime_part (TnyMimePart *msg, gboolean want_ht
                                g_object_unref (part);
                                tny_iterator_next (iter);
                                continue;
-                       }
-                       
+                       }                       
 
                        /* we need to strdown the content type, because
                         * tny_mime_part_has_content_type does not do it...
                         */
                        content_type = g_ascii_strdown (tny_mime_part_get_content_type (part), -1);
-
-                       if (g_str_has_prefix (content_type, desired_mime_type) && !tny_mime_part_is_attachment (part)) {
+                       
+                       /* mime-parts with a content-disposition header (either 'inline' or 'attachment')
+                        * and a 'name=' thingy cannot be body parts
+                         */
+                               
+                       tmp = modest_tny_mime_part_get_header_value (part, "Content-Disposition");
+                       if (tmp) {
+                               gchar *content_disp = g_ascii_strdown(tmp, -1);
+                               g_free (tmp);
+                               has_content_disp_name = g_strstr_len (content_disp, strlen(content_disp), "name=") != NULL;
+                               g_free (content_disp);
+                       }
+                       
+                       if (g_str_has_prefix (content_type, desired_mime_type) && !has_content_disp_name) {
                                /* we found the desired mime-type! */
                                g_free (content_type);
                                break;
@@ -627,38 +641,6 @@ modest_tny_msg_create_forward_msg (TnyMsg *msg,
 }
 
 
-gchar*
-modest_tny_msg_get_header (TnyMsg *msg, const gchar *header)
-{
-       TnyList *pairs;
-       TnyIterator *iter;
-       gchar *val;
-       
-       g_return_val_if_fail (msg && TNY_IS_MSG(msg), NULL);
-       g_return_val_if_fail (header, NULL);
-
-       pairs = tny_simple_list_new ();
-
-       tny_mime_part_get_header_pairs (TNY_MIME_PART(msg), pairs);
-       iter = tny_list_create_iterator (pairs);
-
-       val = NULL;
-       while (!tny_iterator_is_done(iter) && !val) {
-
-               TnyPair *pair = (TnyPair*)tny_iterator_get_current(iter);
-               if (strcasecmp (header, tny_pair_get_name(pair)) == 0)
-                       val = g_strdup (tny_pair_get_value(pair));
-               g_object_unref (pair);          
-
-               tny_iterator_next (iter);
-       }
-
-       g_object_unref (pairs);
-       g_object_unref (iter);
-
-       return val;
-}
-
 
 static gint
 count_addresses (const gchar* addresses)
@@ -694,14 +676,16 @@ get_new_to (TnyMsg *msg, TnyHeader *header, const gchar* from,
         * for mailing lists, both the Reply-To: and From: should be included
         * in the new To:; for now, we're ignoring List-Post
         */
-       gchar* list_help = modest_tny_msg_get_header (msg, "List-Help");
+       gchar* list_help = modest_tny_mime_part_get_header_value (TNY_MIME_PART(msg), 
+                                                                 "List-Help");
        gboolean is_mailing_list = (list_help != NULL);
        g_free (list_help);
 
 
        /* reply to sender, use ReplyTo or From */
        //old_reply_to = tny_header_get_replyto (header);
-       old_reply_to = modest_tny_msg_get_header (msg, "Reply-To"); 
+       old_reply_to = modest_tny_mime_part_get_header_value (TNY_MIME_PART(msg), 
+                                                             "Reply-To"); 
        old_from     = tny_header_get_from (header);
        
        if (!old_from &&  !old_reply_to) {
index f83eb2f..acef7e4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, Nokia Corporation
+/* Copyright (c) 2006, 2007, 2008 Nokia Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -129,18 +129,6 @@ gchar*        modest_tny_msg_get_body        (TnyMsg *self, gboolean want_html,
 
 
 
-/**
- * modest_tny_msg_get_header:
- * @self: some #TnyMsg 
- * @header: the header to get
- * 
- * gets the mail header for a #TnyMsg as a newly allocated string,
- * or NULL if it cannot be found
- * 
- * Returns: the header
- **/
-gchar*       modest_tny_msg_get_header (TnyMsg *msg, const gchar *header);
-
 
 /**
  * modest_tny_msg_create_forward_msg:
index 22d3b05..1fcf4c3 100644 (file)
@@ -29,8 +29,6 @@
 
 #include <config.h>
 
-//#include <glib/gi18n-lib.h>
-
 #include <string.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -41,6 +39,7 @@
 #include <modest-runtime.h>
 #include <modest-attachment-view.h>
 #include <modest-attachments-view.h>
+#include <modest-tny-mime-part.h>
 
 static GObjectClass *parent_class = NULL;
 
@@ -135,7 +134,6 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn
                return;
        }
 
-       
        parts = TNY_LIST (tny_simple_list_new ());
        tny_mime_part_get_parts (TNY_MIME_PART (priv->msg), parts);
        iter = tny_list_create_iterator (parts);
@@ -144,9 +142,9 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn
                TnyMimePart *part;
 
                part = TNY_MIME_PART (tny_iterator_get_current (iter));
-               if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
+
+               if (part && (modest_tny_mime_part_is_attachment_for_modest (part))) 
                        modest_attachments_view_add_attachment (attachments_view, part);
-               }
 
                if (part)
                        g_object_unref (part);