diff lisp/mh-e/mh-mime.el @ 56406:d36b00b98db0

Upgraded to MH-E version 7.4.4. See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
author Bill Wohler <wohler@newt.com>
date Tue, 13 Jul 2004 03:06:25 +0000
parents 695cf19ef79e
children e9a6cbc8ca5e 97905c4f1a42
line wrap: on
line diff
--- a/lisp/mh-e/mh-mime.el	Tue Jul 13 01:32:18 2004 +0000
+++ b/lisp/mh-e/mh-mime.el	Tue Jul 13 03:06:25 2004 +0000
@@ -1,6 +1,6 @@
 ;;; mh-mime.el --- MH-E support for composing MIME messages
 
-;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1995, 2001, 02, 03, 2004 Free Software Foundation, Inc.
 
 ;; Author: Bill Wohler <wohler@newt.com>
 ;; Maintainer: Bill Wohler <wohler@newt.com>
@@ -34,14 +34,11 @@
 
 ;;; Code:
 
-(require 'cl)
+(require 'mh-utils)
+(mh-require-cl)
 (require 'mh-comp)
-(require 'mh-utils)
-(load "mm-decode" t t)                  ; Non-fatal dependency
-(load "mm-uu" t t)                      ; Non-fatal dependency
-(load "mailcap" t t)                    ; Non-fatal dependency
-(load "smiley" t t)                     ; Non-fatal dependency
 (require 'gnus-util)
+(require 'mh-gnus)
 
 (autoload 'gnus-article-goto-header "gnus-art")
 (autoload 'article-emphasize "gnus-art")
@@ -450,6 +447,7 @@
 This step is performed automatically when sending the message, but this
 function may be called manually before sending the draft as well."
   (interactive)
+  (require 'message)
   (when mh-gnus-pgp-support-flag ;; This is only needed for PGP
     (message-options-set-recipient))
   (mml-to-mime))
@@ -529,99 +527,6 @@
 
 
 
-;;; MIME decoding
-
-(defmacro mh-defun-compat (function arg-list &rest body)
-  "This is a macro to define functions which are not defined.
-It is used for Gnus utility functions which were added recently. If FUNCTION
-is not defined then it is defined to have argument list, ARG-LIST and body,
-BODY."
-  (let ((defined-p (fboundp function)))
-    (unless defined-p
-      `(defun ,function ,arg-list ,@body))))
-(put 'mh-defun-compat 'lisp-indent-function 'defun)
-
-;; Copy of original function from gnus-util.el
-(mh-defun-compat gnus-local-map-property (map)
-  "Return a list suitable for a text property list specifying keymap MAP."
-  (cond (mh-xemacs-flag (list 'keymap map))
-        ((>= emacs-major-version 21) (list 'keymap map))
-        (t (list 'local-map map))))
-
-;; Copy of original function from mm-decode.el
-(mh-defun-compat mm-merge-handles (handles1 handles2)
-  (append (if (listp (car handles1)) handles1 (list handles1))
-          (if (listp (car handles2)) handles2 (list handles2))))
-
-;; Copy of function from mm-decode.el
-(mh-defun-compat mm-set-handle-multipart-parameter (handle parameter value)
-  ;; HANDLE could be a CTL.
-  (if handle
-      (put-text-property 0 (length (car handle)) parameter value
-                         (car handle))))
-
-;; Copy of original macro is in mm-decode.el
-(mh-defun-compat mm-handle-multipart-ctl-parameter (handle parameter)
-  (get-text-property 0 parameter (car handle)))
-
-(mh-do-in-xemacs (defvar default-enable-multibyte-characters))
-
-;; Copy of original function in mm-decode.el
-(mh-defun-compat mm-readable-p (handle)
-  "Say whether the content of HANDLE is readable."
-  (and (< (with-current-buffer (mm-handle-buffer handle)
-            (buffer-size)) 10000)
-       (mm-with-unibyte-buffer
-         (mm-insert-part handle)
-         (and (eq (mm-body-7-or-8) '7bit)
-              (not (mm-long-lines-p 76))))))
-
-;; Copy of original function in mm-bodies.el
-(mh-defun-compat mm-long-lines-p (length)
-  "Say whether any of the lines in the buffer is longer than LINES."
-  (save-excursion
-    (goto-char (point-min))
-    (end-of-line)
-    (while (and (not (eobp))
-                (not (> (current-column) length)))
-      (forward-line 1)
-      (end-of-line))
-    (and (> (current-column) length)
-         (current-column))))
-
-(mh-defun-compat mm-keep-viewer-alive-p (handle)
-  ;; Released Gnus doesn't keep handles associated with externally displayed
-  ;; MIME parts. So this will always return nil.
-  nil)
-
-(mh-defun-compat mm-destroy-parts (list)
-  "Older emacs don't have this function."
-  nil)
-
-;;; This is mm-save-part from gnus 5.10 since that function in emacs21.2 is
-;;; buggy (the args to read-file-name are incorrect). When all supported
-;;; versions of Emacs come with at least Gnus 5.10, we can delete this
-;;; function and rename calls to mh-mm-save-part to mm-save-part.
-(defun mh-mm-save-part (handle)
-  "Write HANDLE to a file."
-  (let ((name (mail-content-type-get (mm-handle-type handle) 'name))
-        (filename (mail-content-type-get
-                   (mm-handle-disposition handle) 'filename))
-        file)
-    (when filename
-      (setq filename (file-name-nondirectory filename)))
-    (setq file (read-file-name "Save MIME part to: "
-                               (or mm-default-directory
-                                   default-directory)
-                               nil nil (or filename name "")))
-    (setq mm-default-directory (file-name-directory file))
-    (and (or (not (file-exists-p file))
-             (yes-or-no-p (format "File %s already exists; overwrite? "
-                                  file)))
-         (mm-save-part-to-file handle file))))
-
-
-
 ;;; MIME cleanup
 
 ;;;###mh-autoload
@@ -668,28 +573,36 @@
 I have seen this only in spam, so maybe we shouldn't fix this ;-)"
   (save-excursion
     (goto-char (point-min))
-    (when (and (message-fetch-field "content-type")
-               (not (message-fetch-field "mime-version")))
-      (when (search-forward "\n\n" nil t)
-        (forward-line -1)
+    (re-search-forward "\n\n" nil t)
+    (save-restriction
+      (narrow-to-region (point-min) (point))
+      (when (and (message-fetch-field "content-type")
+                 (not (message-fetch-field "mime-version")))
+        (goto-char (point-min))
         (insert "MIME-Version: 1.0\n")))))
 
+(defun mh-small-show-buffer-p ()
+  "Check if show buffer is small.
+This is used to decide if smileys and graphical emphasis will be displayed."
+  (let ((max nil))
+    (when (and (boundp 'font-lock-maximum-size) font-lock-maximum-size)
+      (cond ((numberp font-lock-maximum-size)
+             (setq max font-lock-maximum-size))
+            ((listp font-lock-maximum-size)
+             (setq max (cdr (or (assoc 'mh-show-mode font-lock-maximum-size)
+                                (assoc t font-lock-maximum-size)))))))
+    (or (not (numberp max)) (>= (/ max 8) (buffer-size)))))
+
 ;;;###mh-autoload
 (defun mh-display-smileys ()
   "Function to display smileys."
-  (when (and mh-graphical-smileys-flag
-             (fboundp 'smiley-region)
-             (boundp 'font-lock-maximum-size)
-             font-lock-maximum-size
-             (>= (/ font-lock-maximum-size 8) (buffer-size)))
-    (smiley-region (point-min) (point-max))))
+  (when (and mh-graphical-smileys-flag (mh-small-show-buffer-p))
+    (mh-funcall-if-exists smiley-region (point-min) (point-max))))
 
 ;;;###mh-autoload
 (defun mh-display-emphasis ()
   "Function to display graphical emphasis."
-  (when (and mh-graphical-emphasis-flag
-             (if font-lock-maximum-size
-                 (>= (/ font-lock-maximum-size 8) (buffer-size))))
+  (when (and mh-graphical-emphasis-flag (mh-small-show-buffer-p))
     (flet ((article-goto-body ()))      ; shadow this function to do nothing
       (save-excursion
         (goto-char (point-min))
@@ -799,10 +712,15 @@
 (defun mh-decode-message-body ()
   "Decode message based on charset.
 If message has been encoded for transfer take that into account."
-  (let* ((ct (ignore-errors (mail-header-parse-content-type
-                             (message-fetch-field "Content-Type" t))))
-         (charset (mail-content-type-get ct 'charset))
-         (cte (message-fetch-field "Content-Transfer-Encoding")))
+  (let (ct charset cte)
+    (goto-char (point-min))
+    (re-search-forward "\n\n" nil t)
+    (save-restriction
+      (narrow-to-region (point-min) (point))
+      (setq ct (ignore-errors (mail-header-parse-content-type
+                               (message-fetch-field "Content-Type" t)))
+            charset (mail-content-type-get ct 'charset)
+            cte (message-fetch-field "Content-Transfer-Encoding")))
     (when (stringp cte) (setq cte (mail-header-strip cte)))
     (when (or (not ct) (equal (car ct) "text/plain"))
       (save-restriction
@@ -881,16 +799,31 @@
 (defun mh-mime-display-alternative (handles)
   "Choose among the alternatives, HANDLES the part that will be displayed.
 If no part is preferred then all the parts are displayed."
-  (let ((preferred (mm-preferred-alternative handles)))
+  (let* ((preferred (mm-preferred-alternative handles))
+         (others (loop for x in handles unless (eq x preferred) collect x)))
     (cond ((and preferred (stringp (car preferred)))
-           (mh-mime-display-part preferred))
+           (mh-mime-display-part preferred)
+           (mh-mime-maybe-display-alternatives others))
           (preferred
            (save-restriction
              (narrow-to-region (point) (if (eobp) (point) (1+ (point))))
              (mh-mime-display-single preferred)
+             (mh-mime-maybe-display-alternatives others)
              (goto-char (point-max))))
           (t (mh-mime-display-mixed handles)))))
 
+(defun mh-mime-maybe-display-alternatives (alternatives)
+  "Show buttons for ALTERNATIVES.
+If `mh-mime-display-alternatives-flag' is non-nil then display buttons for
+alternative parts that are usually suppressed."
+  (when (and mh-display-buttons-for-alternatives-flag alternatives)
+    (insert "\n----------------------------------------------------\n")
+    (insert "Alternatives:\n")
+    (dolist (x alternatives)
+      (insert "\n")
+      (mh-insert-mime-button x (mh-mime-part-index x) nil))
+    (insert "\n----------------------------------------------------\n")))
+
 (defun mh-mime-display-mixed (handles)
   "Display the list of MIME parts, HANDLES recursively."
   (mapcar #'mh-mime-display-part handles))
@@ -904,12 +837,6 @@
       (setf (gethash handle (mh-mime-part-index-hash (mh-buffer-data)))
             (incf (mh-mime-parts-count (mh-buffer-data))))))
 
-;;; Avoid compiler warnings for XEmacs functions...
-(eval-when (compile)
-  (loop for function in '(glyph-width window-pixel-width
-                                      glyph-height window-pixel-height)
-        do (or (fboundp function) (defalias function 'ignore))))
-
 (defun mh-small-image-p (handle)
   "Decide whether HANDLE is a \"small\" image that can be displayed inline.
 This is only useful if a Content-Disposition header is not present."
@@ -922,27 +849,20 @@
                                         ; this only tells us if the image is
                                         ; something that emacs can display
          (let* ((image (mm-get-image handle)))
-           (cond ((fboundp 'glyph-width)
-                  ;; XEmacs -- totally untested, copied from gnus
-                  (and (mh-funcall-if-exists glyphp image)
-                       (< (glyph-width image)
-                          (or mh-max-inline-image-width
-                              (window-pixel-width)))
-                       (< (glyph-height image)
-                          (or mh-max-inline-image-height
-                              (window-pixel-height)))))
-                 ((fboundp 'image-size)
-                  ;; Emacs21 -- copied from gnus
-                  (let ((size (mh-funcall-if-exists image-size image)))
-                    (and size
-                         (< (cdr size)
-                            (or mh-max-inline-image-height
-                                (1- (window-height))))
-                         (< (car size)
-                            (or mh-max-inline-image-width (window-width))))))
-                 (t
-                  ;; Can't show image inline
-                  nil))))))
+           (or (mh-do-in-xemacs
+                 (and (mh-funcall-if-exists glyphp image)
+                      (< (glyph-width image)
+                         (or mh-max-inline-image-width (window-pixel-width)))
+                      (< (glyph-height image)
+                         (or mh-max-inline-image-height
+                             (window-pixel-height)))))
+               (mh-do-in-gnu-emacs
+                 (let ((size (mh-funcall-if-exists image-size image)))
+                   (and size
+                        (< (cdr size) (or mh-max-inline-image-height
+                                          (1- (window-height))))
+                        (< (car size) (or mh-max-inline-image-width
+                                          (window-width)))))))))))
 
 (defun mh-inline-vcard-p (handle)
   "Decide if HANDLE is a vcard that must be displayed inline."
@@ -1062,7 +982,7 @@
                 (progn
                   ;; Delete the button and displayed part (if any)
                   (let ((region (get-text-property point 'mh-region)))
-                    (when (and region (fboundp 'remove-images))
+                    (when region
                       (mh-funcall-if-exists
                        remove-images (car region) (cdr region)))
                     (mm-display-part handle)
@@ -1130,33 +1050,14 @@
 displayed. This function is called when the mouse is used to click the MIME
 button."
   (interactive "e")
-  (save-excursion
-    (let* ((event-window
-            (or (mh-funcall-if-exists posn-window (event-start event));GNU Emacs
-                (mh-funcall-if-exists event-window event)))            ;XEmacs
-           (event-position
-            (or (mh-funcall-if-exists posn-point (event-start event)) ;GNU Emacs
-                (mh-funcall-if-exists event-closest-point event)))    ;XEmacs
-           (original-window (selected-window))
-           (original-position (progn
-                                (set-buffer (window-buffer event-window))
-                                (set-marker (make-marker) (point))))
-           (folder mh-show-folder-buffer)
-           (mm-inline-media-tests mh-mm-inline-media-tests)
-           (data (get-text-property event-position 'mh-data))
-           (function (get-text-property event-position 'mh-callback))
-           (buffer-read-only nil))
-      (unwind-protect
-          (progn
-            (select-window event-window)
-            (flet ((mm-handle-set-external-undisplayer (handle func)
-                     (mh-handle-set-external-undisplayer folder handle func)))
-              (goto-char event-position)
-              (and function (funcall function data))))
-        (set-buffer-modified-p nil)
-        (goto-char original-position)
-        (set-marker original-position nil)
-        (select-window original-window)))))
+  (mh-do-at-event-location event
+    (let ((folder mh-show-folder-buffer)
+          (mm-inline-media-tests mh-mm-inline-media-tests)
+          (data (get-text-property (point) 'mh-data))
+          (function (get-text-property (point) 'mh-callback)))
+      (flet ((mm-handle-set-external-undisplayer (handle func)
+               (mh-handle-set-external-undisplayer folder handle func)))
+        (and function (funcall function data))))))
 
 ;;;###mh-autoload
 (defun mh-mime-save-part ()
@@ -1164,7 +1065,9 @@
   (interactive)
   (let ((data (get-text-property (point) 'mh-data)))
     (when data
-      (let ((mm-default-directory mh-mime-save-parts-directory))
+      (let ((mm-default-directory
+             (file-name-as-directory (or mh-mime-save-parts-directory
+                                         default-directory))))
         (mh-mm-save-part data)
         (setq mh-mime-save-parts-directory mm-default-directory)))))