X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fmm-decode.el;h=ec60b54155d630bc5bcd3c00b204ca37d3e795c4;hb=23544667b54a01c4dbe52137060eb3817394c6f6;hp=65b9545174243f21d77bc9f43c503a458ade676f;hpb=96d4a7cc3dda58f46de9f03c18f91f8a59e4a8e5;p=gnus diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index 65b954517..ec60b5415 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -1,6 +1,7 @@ ;;; mm-decode.el --- Functions for decoding MIME things -;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 -;; Free Software Foundation, Inc. + +;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, +;; 2005 Free Software Foundation, Inc. ;; Author: Lars Magne Ingebrigtsen ;; MORIOKA Tomohiko @@ -18,8 +19,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. ;;; Commentary: @@ -36,6 +37,8 @@ (autoload 'mm-inline-external-body "mm-extern") (autoload 'mm-insert-inline "mm-view")) +(defvar gnus-current-window-configuration) + (add-hook 'gnus-exit-gnus-hook 'mm-destroy-postponed-undisplay-list) (defgroup mime-display () @@ -114,7 +117,7 @@ The defined renderer types are: `lynx' : use lynx; `html2text' : use html2text; nil : use external viewer." - :version "21.4" + :version "22.1" :type '(choice (const w3) (const w3m) (const w3m-standalone) @@ -133,7 +136,7 @@ It is suggested to customize `mm-text-html-renderer' instead.") "If non-nil, Gnus will allow retrieving images in HTML contents with the tags. It has no effect on Emacs/w3. See also the documentation for the `mm-w3m-safe-url-regexp' variable." - :version "21.4" + :version "22.1" :type 'boolean :group 'mime-display) @@ -149,14 +152,14 @@ when displaying the image. The default value is \"\\\\`cid:\" which only matches parts embedded to the Multipart/Related type MIME contents and Gnus will never connect to the spammer's site arbitrarily. You may set this variable to nil if you consider all urls to be safe." - :version "21.4" + :version "22.1" :type '(choice (regexp :tag "Regexp") (const :tag "All URLs are safe" nil)) :group 'mime-display) (defcustom mm-inline-text-html-with-w3m-keymap t "If non-nil, use emacs-w3m command keys in the article buffer." - :version "21.4" + :version "22.1" :type 'boolean :group 'mime-display) @@ -166,7 +169,7 @@ set this variable to nil if you consider all urls to be safe." If t, all defined external MIME handlers are used. If nil, files are saved by `mailcap-save-binary-file'. If it is the symbol `ask', you are prompted before the external MIME handler is invoked." - :version "21.4" + :version "22.1" :type '(choice (const :tag "Always" t) (const :tag "Never" nil) (const :tag "Ask" ask)) @@ -218,7 +221,12 @@ before the external MIME handler is invoked." ("text/richtext" mm-inline-text identity) ("text/x-patch" mm-display-patch-inline (lambda (handle) - (locate-library "diff-mode"))) + ;; If the diff-mode.el package is installed, the function is + ;; autoloaded. Checking (locate-library "diff-mode") would be trying + ;; to cater to broken installations. OTOH checking the function + ;; makes it possible to install another package which provides an + ;; alternative implementation of diff-mode. --Stef + (fboundp 'diff-mode))) ("application/emacs-lisp" mm-display-elisp-inline identity) ("application/x-emacs-lisp" mm-display-elisp-inline identity) ("text/dns" mm-display-dns-inline identity) @@ -283,12 +291,12 @@ type inline." "application/pdf" "application/x-dvi") "List of media types for which the external viewer will not be killed when selecting a different article." - :version "21.4" + :version "22.1" :type '(repeat string) :group 'mime-display) (defcustom mm-automatic-display - '("text/plain" "text/enriched" "text/richtext" "text/html" + '("text/plain" "text/enriched" "text/richtext" "text/html" "text/x-verbatim" "text/x-vcard" "image/.*" "message/delivery-status" "multipart/.*" "message/rfc822" "text/x-patch" "text/dns" "application/pgp-signature" "application/emacs-lisp" "application/x-emacs-lisp" @@ -380,13 +388,13 @@ If not set, `default-directory' will be used." (defcustom mm-attachment-file-modes 384 "Set the mode bits of saved attachments to this integer." - :version "21.4" + :version "22.1" :type 'integer :group 'mime-display) (defcustom mm-external-terminal-program "xterm" "The program to start an external terminal." - :version "21.4" + :version "22.1" :type 'string :group 'mime-display) @@ -419,7 +427,7 @@ If not set, `default-directory' will be used." "Option of verifying signed parts. `never', not verify; `always', always verify; `known', only verify known protocols. Otherwise, ask user." - :version "21.4" + :version "22.1" :type '(choice (item always) (item never) (item :tag "only known protocols" known) @@ -438,7 +446,7 @@ If not set, `default-directory' will be used." "Option of decrypting encrypted parts. `never', not decrypt; `always', always decrypt; `known', only decrypt known protocols. Otherwise, ask user." - :version "21.4" + :version "22.1" :type '(choice (item always) (item never) (item :tag "only known protocols" known) @@ -448,21 +456,19 @@ If not set, `default-directory' will be used." (defvar mm-viewer-completion-map (let ((map (make-sparse-keymap 'mm-viewer-completion-map))) (set-keymap-parent map minibuffer-local-completion-map) + ;; Should we bind other key to minibuffer-complete-word? + (define-key map " " 'self-insert-command) map) "Keymap for input viewer with completion.") -;; Should we bind other key to minibuffer-complete-word? -(define-key mm-viewer-completion-map " " 'self-insert-command) - (defvar mm-viewer-completion-map (let ((map (make-sparse-keymap 'mm-viewer-completion-map))) (set-keymap-parent map minibuffer-local-completion-map) + ;; Should we bind other key to minibuffer-complete-word? + (define-key map " " 'self-insert-command) map) "Keymap for input viewer with completion.") -;; Should we bind other key to minibuffer-complete-word? -(define-key mm-viewer-completion-map " " 'self-insert-command) - ;;; The functions. (defun mm-alist-to-plist (alist) @@ -509,10 +515,10 @@ Postpone undisplaying of viewers for types in (message "Destroying external MIME viewers") (mm-destroy-parts mm-postponed-undisplay-list))) -(defun mm-dissect-buffer (&optional no-strict-mime loose-mime) +(defun mm-dissect-buffer (&optional no-strict-mime loose-mime from) "Dissect the current buffer and return a list of MIME handles." (save-excursion - (let (ct ctl type subtype cte cd description id result from) + (let (ct ctl type subtype cte cd description id result) (save-restriction (mail-narrow-to-head) (when (or no-strict-mime @@ -523,8 +529,9 @@ Postpone undisplaying of viewers for types in cte (mail-fetch-field "content-transfer-encoding") cd (mail-fetch-field "content-disposition") description (mail-fetch-field "content-description") - from (mail-fetch-field "from") id (mail-fetch-field "content-id")) + (unless from + (setq from (mail-fetch-field "from"))) ;; FIXME: In some circumstances, this code is running within ;; an unibyte macro. mail-extract-address-components ;; creates unibyte buffers. This `if', though not a perfect @@ -556,14 +563,14 @@ Postpone undisplaying of viewers for types in ;; what really needs to be done here is a way to link a ;; MIME handle back to it's parent MIME handle (in a multilevel ;; MIME article). That would probably require changing - ;; the mm-handle API so we simply store the multipart buffert + ;; the mm-handle API so we simply store the multipart buffer ;; name as a text property of the "multipart/whatever" string. (add-text-properties 0 (length (car ctl)) (list 'buffer (mm-copy-to-buffer) 'from from 'start start) (car ctl)) - (cons (car ctl) (mm-dissect-multipart ctl)))) + (cons (car ctl) (mm-dissect-multipart ctl from)))) (t (mm-possibly-verify-or-decrypt (mm-dissect-singlepart @@ -588,7 +595,7 @@ Postpone undisplaying of viewers for types in (mm-make-handle (mm-copy-to-buffer) ctl cte nil cdl description nil id))) -(defun mm-dissect-multipart (ctl) +(defun mm-dissect-multipart (ctl from) (goto-char (point-min)) (let* ((boundary (concat "\n--" (mail-content-type-get ctl 'boundary))) (close-delimiter (concat (regexp-quote boundary) "--[ \t]*$")) @@ -605,7 +612,7 @@ Postpone undisplaying of viewers for types in (save-excursion (save-restriction (narrow-to-region start (point)) - (setq parts (nconc (list (mm-dissect-buffer t)) parts))))) + (setq parts (nconc (list (mm-dissect-buffer t nil from)) parts))))) (end-of-line 2) (or (looking-at boundary) (forward-line 1)) @@ -614,7 +621,7 @@ Postpone undisplaying of viewers for types in (save-excursion (save-restriction (narrow-to-region start end) - (setq parts (nconc (list (mm-dissect-buffer t)) parts))))) + (setq parts (nconc (list (mm-dissect-buffer t nil from)) parts))))) (mm-possibly-verify-or-decrypt (nreverse parts) ctl))) (defun mm-copy-to-buffer () @@ -797,8 +804,7 @@ external if displayed external." (mm-mailcap-command method file (mm-handle-type handle))) (if (buffer-live-p buffer) - (save-excursion - (set-buffer buffer) + (with-current-buffer buffer (buffer-string)))) (progn (ignore-errors (delete-file file)) @@ -810,11 +816,32 @@ external if displayed external." (let ((command (mm-mailcap-command method file (mm-handle-type handle)))) (unwind-protect - (start-process "*display*" - (setq buffer - (generate-new-buffer " *mm*")) - shell-file-name - shell-command-switch command) + (progn + (start-process "*display*" + (setq buffer + (generate-new-buffer " *mm*")) + shell-file-name + shell-command-switch command) + (set-process-sentinel + (get-buffer-process buffer) + `(lambda (process state) + (when (eq 'exit (process-status process)) + ;; Don't use `ignore-errors'. + (condition-case nil + (delete-file ,file) + (error)) + (condition-case nil + (delete-directory ,(file-name-directory file)) + (error)) + (condition-case nil + (kill-buffer ,buffer) + (error)) + (condition-case nil + ,(macroexpand (list 'mm-handle-set-undisplayer + (list 'quote handle) + nil)) + (error)) + (message "Displaying %s...done" ,command))))) (mm-handle-set-external-undisplayer handle (cons file buffer))) (message "Displaying %s..." command)) @@ -1026,27 +1053,16 @@ external if displayed external." (defun mm-insert-part (handle) "Insert the contents of HANDLE in the current buffer." - (let ((cur (current-buffer))) - (save-excursion - (if (member (mm-handle-media-supertype handle) '("text" "message")) - (with-temp-buffer - (insert-buffer-substring (mm-handle-buffer handle)) - (prog1 - (mm-decode-content-transfer-encoding - (mm-handle-encoding handle) - (mm-handle-media-type handle)) - (let ((temp (current-buffer))) - (set-buffer cur) - (insert-buffer-substring temp)))) - (mm-with-unibyte-buffer - (insert-buffer-substring (mm-handle-buffer handle)) - (prog1 - (mm-decode-content-transfer-encoding - (mm-handle-encoding handle) - (mm-handle-media-type handle)) - (let ((temp (current-buffer))) - (set-buffer cur) - (insert-buffer-substring temp)))))))) + (save-excursion + (insert + (cond ((eq (mail-content-type-get (mm-handle-type handle) 'charset) + 'gnus-decoded) + (with-current-buffer (mm-handle-buffer handle) + (buffer-string))) + ((mm-multibyte-p) + (mm-string-as-multibyte (mm-get-part handle))) + (t + (mm-get-part handle)))))) (defun mm-file-name-delete-whitespace (file-name) "Remove all whitespace characters from FILE-NAME." @@ -1086,8 +1102,9 @@ string if you do not like underscores." (setq filename (gnus-replace-in-string filename "[<>|]" "")) (gnus-replace-in-string filename "^[.-]+" "")) -(defun mm-save-part (handle) - "Write HANDLE to a file." +(defun mm-save-part (handle &optional prompt) + "Write HANDLE to a file. +PROMPT overrides the default one used to ask user for a file name." (let* ((name (mail-content-type-get (mm-handle-type handle) 'name)) (filename (mail-content-type-get (mm-handle-disposition handle) 'filename)) @@ -1097,7 +1114,7 @@ string if you do not like underscores." (file-name-nondirectory filename)))) (setq file (mm-with-multibyte - (read-file-name "Save MIME part to: " + (read-file-name (or prompt "Save MIME part to: ") (or mm-default-directory default-directory) nil nil (or filename name "")))) (setq mm-default-directory (file-name-directory file))