Merge changes from emacs-23
[bpt/emacs.git] / lisp / mail / rmailmm.el
index 077a8bf..3882c9e 100644 (file)
@@ -1,11 +1,12 @@
 ;;; rmailmm.el --- MIME decoding and display stuff for RMAIL
 
-;; Copyright (C) 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
 
 ;; Author: Alexander Pohoyda
 ;;     Alex Schroeder
 ;; Maintainer: FSF
 ;; Keywords: mail
+;; Package: rmail
 
 ;; This file is part of GNU Emacs.
 
@@ -31,6 +32,7 @@
 ;; Todo:
 
 ;; Handle multipart/alternative.
+;; Offer the option to call external/internal viewers (doc-view, xpdf, etc).
 
 ;;; Code:
 
@@ -48,8 +50,6 @@
   '(("multipart/.*" rmail-mime-multipart-handler)
     ("text/.*" rmail-mime-text-handler)
     ("text/\\(x-\\)?patch" rmail-mime-bulk-handler)
-    ;; FIXME this handler not defined anywhere?
-;;;   ("application/pgp-signature" rmail-mime-application/pgp-signature-handler)
     ("\\(image\\|audio\\|video\\|application\\)/.*" rmail-mime-bulk-handler))
   "Functions to handle various content types.
 This is an alist with elements of the form (REGEXP FUNCTION ...).
@@ -78,10 +78,13 @@ The first directory that exists is used."
 (defcustom rmail-mime-show-images 'button
   "What to do with image attachments that Emacs is capable of displaying.
 If nil, do nothing special.  If `button', add an extra button
-that when pushed displays the image in the buffer.  Anything else
-means to automatically display the image in the buffer."
+that when pushed displays the image in the buffer.  If a number,
+automatically show images if they are smaller than that size (in
+bytes), otherwise add a display button.  Anything else means to
+automatically display the image in the buffer."
   :type '(choice (const :tag "Add button to view image" button)
                 (const :tag "No special treatment" nil)
+                (number :tag "Show if smaller than certain size")
                 (other :tag "Always show" show))
   :version "23.2"
   :group 'rmail-mime)
@@ -110,6 +113,10 @@ means to automatically display the image in the buffer."
                        (file-name-as-directory filename))))
     (with-temp-buffer
       (set-buffer-file-coding-system 'no-conversion)
+      ;; Needed e.g. by jka-compr, so if the attachment is a compressed
+      ;; file, the magic signature compares equal with the unibyte
+      ;; signature string recorded in jka-compr-compression-info-list.
+      (set-buffer-multibyte nil)
       (insert data)
       (write-region nil nil filename nil nil nil t))))
 
@@ -179,6 +186,7 @@ depends upon the value of `rmail-mime-show-images'."
         (data (buffer-string))
         (udata (string-as-unibyte data))
         (size (length udata))
+        (osize size)
         (units '(B kB MB GB))
         type)
     (while (and (> size 1024.0)        ; cribbed from gnus-agent-expire-done-message
@@ -201,7 +209,9 @@ depends upon the value of `rmail-mime-show-images'."
               (memq type image-types)
               (image-type-available-p type))
       (insert " ")
-      (cond ((eq rmail-mime-show-images 'button)
+      (cond ((or (eq rmail-mime-show-images 'button)
+                (and (numberp rmail-mime-show-images)
+                     (>= osize rmail-mime-show-images)))
             (insert-button "Display"
                            :type 'rmail-mime-image
                            'help-echo "mouse-2, RET: Show image"
@@ -277,13 +287,11 @@ format."
              content-transfer-encoding)))
       (delete-region end next)
       ;; Handle the part.
-      (save-match-data
-       (save-excursion
-         (save-restriction
-           (narrow-to-region beg end)
-           (rmail-mime-show))))
-      (setq beg next)
-      (goto-char beg))))
+      (save-restriction
+       (narrow-to-region beg end)
+       (rmail-mime-show))
+      (goto-char (setq beg next)))))
+
 
 (defun test-rmail-mime-multipart-handler ()
   "Test of a mail used as an example in RFC 2046."
@@ -326,8 +334,9 @@ The current buffer should be narrowed to the respective body, and
 point should be at the beginning of the body.
 
 CONTENT-TYPE, CONTENT-DISPOSITION, and CONTENT-TRANSFER-ENCODING
-are the values of the respective parsed headers.  The parsed
-headers for CONTENT-TYPE and CONTENT-DISPOSITION have the form
+are the values of the respective parsed headers.  The latter should
+be downcased.  The parsed headers for CONTENT-TYPE and CONTENT-DISPOSITION
+have the form
 
   \(VALUE . ALIST)
 
@@ -357,7 +366,10 @@ The parsed header value:
         (setq content-transfer-encoding nil))
        ((string= content-transfer-encoding "8bit")
         ;; FIXME: Is this the correct way?
-        (set-buffer-multibyte nil)))
+         ;; No, of course not, it just means there's no decoding to do.
+        ;; (set-buffer-multibyte nil)
+         (setq content-transfer-encoding nil)
+         ))
   ;; Inline stuff requires work.  Attachments are handled by the bulk
   ;; handler.
   (if (string= "inline" (car content-disposition))
@@ -405,12 +417,16 @@ modified."
                (mail-fetch-field "Content-Transfer-Encoding")
                content-disposition
                (mail-fetch-field "Content-Disposition")))))
-    (if content-type
-       (setq content-type (mail-header-parse-content-type
-                           content-type))
-      ;; FIXME: Default "message/rfc822" in a "multipart/digest"
-      ;; according to RFC 2046.
-      (setq content-type '("text/plain")))
+    ;; Per RFC 2045, C-T-E is case insensitive (bug#5070), but the others
+    ;; are not completely so.  Hopefully mail-header-parse-* DTRT.
+    (if content-transfer-encoding
+       (setq content-transfer-encoding (downcase content-transfer-encoding)))
+    (setq content-type
+         (if content-type
+             (mail-header-parse-content-type content-type)
+           ;; FIXME: Default "message/rfc822" in a "multipart/digest"
+           ;; according to RFC 2046.
+           '("text/plain")))
     (setq content-disposition
          (if content-disposition
              (mail-header-parse-content-disposition content-disposition)
@@ -448,10 +464,14 @@ attachments as specfied by `rmail-mime-attachment-dirs-alist'."
     (set-buffer buf)
     (setq buffer-undo-list t)
     (let ((inhibit-read-only t))
+      ;; Decoding the message in fundamental mode for speed, only
+      ;; switching to rmail-mime-mode at the end for display.  Eg
+      ;; quoted-printable-decode-region gets very slow otherwise (Bug#4993).
+      (fundamental-mode)
       (erase-buffer)
       (insert data)
-      (rmail-mime-mode)
       (rmail-mime-show t)
+      (rmail-mime-mode)
       (set-buffer-modified-p nil))
     (view-buffer buf)))