comparison lisp/mh-e/mh-mime.el @ 50702:7dd3d5eae9c7

Upgraded to MH-E version 7.3. See etc/MH-E-NEWS and lisp/mh-e/ChangeLog for details.
author Bill Wohler <wohler@newt.com>
date Fri, 25 Apr 2003 05:52:00 +0000
parents b35587af8747
children 695cf19ef79e
comparison
equal deleted inserted replaced
50701:cb5f0a5d5b36 50702:7dd3d5eae9c7
1 ;;; mh-mime.el --- MH-E support for composing MIME messages 1 ;;; mh-mime.el --- MH-E support for composing MIME messages
2 2
3 ;; Copyright (C) 1993, 1995, 2001, 2002 Free Software Foundation, Inc. 3 ;; Copyright (C) 1993, 1995, 2001, 02, 2003 Free Software Foundation, Inc.
4 4
5 ;; Author: Bill Wohler <wohler@newt.com> 5 ;; Author: Bill Wohler <wohler@newt.com>
6 ;; Maintainer: Bill Wohler <wohler@newt.com> 6 ;; Maintainer: Bill Wohler <wohler@newt.com>
7 ;; Keywords: mail 7 ;; Keywords: mail
8 ;; See: mh-e.el 8 ;; See: mh-e.el
29 ;; Internal support for MH-E package. 29 ;; Internal support for MH-E package.
30 ;; Support for generating an mhn composition file. 30 ;; Support for generating an mhn composition file.
31 ;; MIME is supported only by MH 6.8 or later. 31 ;; MIME is supported only by MH 6.8 or later.
32 32
33 ;;; Change Log: 33 ;;; Change Log:
34
35 ;; $Id: mh-mime.el,v 1.100 2003/01/25 19:18:51 satyaki Exp $
36 34
37 ;;; Code: 35 ;;; Code:
38 36
39 (require 'cl) 37 (require 'cl)
40 (require 'mh-comp) 38 (require 'mh-comp)
56 (autoload 'mml-minibuffer-read-file "mml") 54 (autoload 'mml-minibuffer-read-file "mml")
57 (autoload 'mml-minibuffer-read-description "mml") 55 (autoload 'mml-minibuffer-read-description "mml")
58 (autoload 'mml-insert-empty-tag "mml") 56 (autoload 'mml-insert-empty-tag "mml")
59 (autoload 'mml-to-mime "mml") 57 (autoload 'mml-to-mime "mml")
60 (autoload 'mml-attach-file "mml") 58 (autoload 'mml-attach-file "mml")
59 (autoload 'rfc2047-decode-region "rfc2047")
61 60
62 ;;;###mh-autoload 61 ;;;###mh-autoload
63 (defun mh-compose-insertion (&optional inline) 62 (defun mh-compose-insertion (&optional inline)
64 "Add a directive to insert a MIME part from a file, using mhn or gnus. 63 "Add a directive to insert a MIME part from a file, using mhn or gnus.
65 If the variable `mh-compose-insertion' is set to 'mhn, then that will be used. 64 If the variable `mh-compose-insertion' is set to 'mhn, then that will be used.
233 "Insert a mhn directive to insert a file. 232 "Insert a mhn directive to insert a file.
234 233
235 The file specified by FILENAME is encoded as TYPE. An optional DESCRIPTION is 234 The file specified by FILENAME is encoded as TYPE. An optional DESCRIPTION is
236 used as the Content-Description field, optional set of ATTRIBUTES and an 235 used as the Content-Description field, optional set of ATTRIBUTES and an
237 optional COMMENT can also be included." 236 optional COMMENT can also be included."
238 (setq mh-mhn-compose-insert-flag t)
239 (beginning-of-line) 237 (beginning-of-line)
240 (insert "#" type) 238 (insert "#" type)
241 (and attributes 239 (and attributes
242 (insert "; " attributes)) 240 (insert "; " attributes))
243 (and comment 241 (and comment
304 file and TYPE which is the MIME Content-Type. Optional arguments include 302 file and TYPE which is the MIME Content-Type. Optional arguments include
305 DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES, 303 DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES,
306 EXTRA-PARAMS, and COMMENT. 304 EXTRA-PARAMS, and COMMENT.
307 305
308 See also \\[mh-edit-mhn]." 306 See also \\[mh-edit-mhn]."
309 (setq mh-mhn-compose-insert-flag t)
310 (beginning-of-line) 307 (beginning-of-line)
311 (insert "#@" type) 308 (insert "#@" type)
312 (and attributes 309 (and attributes
313 (insert "; " attributes)) 310 (insert "; " attributes))
314 (and comment 311 (and comment
339 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) 336 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil)
340 (read-string (format "Messages%s: " 337 (read-string (format "Messages%s: "
341 (if mh-sent-from-msg 338 (if mh-sent-from-msg
342 (format " [%d]" mh-sent-from-msg) 339 (format " [%d]" mh-sent-from-msg)
343 ""))))) 340 "")))))
344 (setq mh-mhn-compose-insert-flag t)
345 (beginning-of-line) 341 (beginning-of-line)
346 (insert "#forw [") 342 (insert "#forw [")
347 (and description 343 (and description
348 (not (string= description "")) 344 (not (string= description ""))
349 (insert description)) 345 (insert description))
366 362
367 Process the current draft with the mhn program, which, using directives 363 Process the current draft with the mhn program, which, using directives
368 already inserted in the draft, fills in all the MIME components and header 364 already inserted in the draft, fills in all the MIME components and header
369 fields. 365 fields.
370 366
371 This step should be done last just before sending the message. 367 This step is performed automatically when sending the message, but this
368 function may be called manually before sending the draft as well.
372 369
373 The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the 370 The `\\[mh-revert-mhn-edit]' command undoes this command. The arguments in the
374 list `mh-mhn-args' are passed to mhn if this function is passed an optional 371 list `mh-mhn-args' are passed to mhn if this function is passed an optional
375 prefix argument EXTRA-ARGS. 372 prefix argument EXTRA-ARGS.
376 373
377 For assistance with creating mhn directives to insert various types of 374 For assistance with creating mhn directives to insert various types of
378 components in a message, see \\[mh-mhn-compose-insertion] (generic insertion 375 components in a message, see \\[mh-mhn-compose-insertion] (generic insertion
379 from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via 376 from a file), \\[mh-mhn-compose-anon-ftp] (external reference to file via
380 anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] \ \(reference to 377 anonymous ftp), \\[mh-mhn-compose-external-compressed-tar] \ \(reference to
381 compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward 378 compressed tar file via anonymous ftp), and \\[mh-mhn-compose-forw] (forward
382 message). If these helper functions are used, `mh-edit-mhn' is run 379 message).
383 automatically when the draft is sent.
384 380
385 The value of `mh-edit-mhn-hook' is a list of functions to be called, with no 381 The value of `mh-edit-mhn-hook' is a list of functions to be called, with no
386 arguments, after performing the conversion. 382 arguments, after performing the conversion.
387 383
388 The mhn program is part of MH version 6.8 or later." 384 The mhn program is part of MH version 6.8 or later."
394 (mh-exec-cmd-error nil 390 (mh-exec-cmd-error nil
395 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name)) 391 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name))
396 (t 392 (t
397 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name) 393 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name)
398 "mhn" (if extra-args mh-mhn-args) buffer-file-name))) 394 "mhn" (if extra-args mh-mhn-args) buffer-file-name)))
399 (setq mh-mhn-compose-insert-flag nil)
400 (revert-buffer t t) 395 (revert-buffer t t)
401 (message "mhn editing...done") 396 (message "mhn editing...done")
402 (run-hooks 'mh-edit-mhn-hook)) 397 (run-hooks 'mh-edit-mhn-hook))
403 398
404 ;;;###mh-autoload 399 ;;;###mh-autoload
427 (let ((buffer-read-only nil)) 422 (let ((buffer-read-only nil))
428 (erase-buffer) 423 (erase-buffer)
429 (insert-file-contents backup-file)) 424 (insert-file-contents backup-file))
430 (after-find-file nil))) 425 (after-find-file nil)))
431 426
427 ;;;###mh-autoload
428 (defun mh-mhn-directive-present-p ()
429 "Check if the current buffer has text which might be a MHN directive."
430 (save-excursion
431 (block 'search-for-mhn-directive
432 (goto-char (point-min))
433 (while (re-search-forward "^#" nil t)
434 (let ((s (buffer-substring-no-properties (point) (line-end-position))))
435 (cond ((equal s ""))
436 ((string-match "^forw[ \t\n]+" s)
437 (return-from 'search-for-mhn-directive t))
438 (t (let ((first-token (car (split-string s "[ \t;@]"))))
439 (when (string-match mh-media-type-regexp first-token)
440 (return-from 'search-for-mhn-directive t)))))))
441 nil)))
442
432 443
433 444
434 ;;; MIME composition functions 445 ;;; MIME composition functions
435 446
436 ;;;###mh-autoload 447 ;;;###mh-autoload
437 (defun mh-mml-to-mime () 448 (defun mh-mml-to-mime ()
438 "Compose MIME message from mml directives." 449 "Compose MIME message from mml directives.
450 This step is performed automatically when sending the message, but this
451 function may be called manually before sending the draft as well."
439 (interactive) 452 (interactive)
440 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP 453 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP
441 (message-options-set-recipient)) 454 (message-options-set-recipient))
442 (mml-to-mime) 455 (mml-to-mime))
443 (setq mh-mml-compose-insert-flag nil))
444 456
445 ;;;###mh-autoload 457 ;;;###mh-autoload
446 (defun mh-mml-forward-message (description folder message) 458 (defun mh-mml-forward-message (description folder message)
447 "Forward a message as attachment. 459 "Forward a message as attachment.
448 The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE 460 The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE
458 mh-user-path (substring folder 1) msg) 470 mh-user-path (substring folder 1) msg)
459 "message/rfc822") 471 "message/rfc822")
460 (mml-attach-file (format "%s%s/%d" 472 (mml-attach-file (format "%s%s/%d"
461 mh-user-path (substring folder 1) msg) 473 mh-user-path (substring folder 1) msg)
462 "message/rfc822" 474 "message/rfc822"
463 description)) 475 description)))
464 (setq mh-mml-compose-insert-flag t))
465 (t (error "The message number, %s is not a integer!" msg))))) 476 (t (error "The message number, %s is not a integer!" msg)))))
466 477
467 ;;;###mh-autoload 478 ;;;###mh-autoload
468 (defun mh-mml-attach-file (&optional disposition) 479 (defun mh-mml-attach-file (&optional disposition)
469 "Attach a file to the outgoing MIME message. 480 "Attach a file to the outgoing MIME message.
486 (completing-read "Disposition: [attachment] " 497 (completing-read "Disposition: [attachment] "
487 '(("attachment")("inline")) 498 '(("attachment")("inline"))
488 nil t nil nil 499 nil t nil nil
489 "attachment")))) 500 "attachment"))))
490 (mml-insert-empty-tag 'part 'type type 'filename file 501 (mml-insert-empty-tag 'part 'type type 'filename file
491 'disposition dispos 'description description) 502 'disposition dispos 'description description)))
492 (setq mh-mml-compose-insert-flag t)))
493 503
494 ;;;###mh-autoload 504 ;;;###mh-autoload
495 (defun mh-mml-secure-message-sign-pgpmime () 505 (defun mh-mml-secure-message-sign-pgpmime ()
496 "Add directive to encrypt/sign the entire message." 506 "Add directive to encrypt/sign the entire message."
497 (interactive) 507 (interactive)
498 (if (not mh-gnus-pgp-support-flag) 508 (if (not mh-gnus-pgp-support-flag)
499 (error "Sorry. Your version of gnus does not support PGP/GPG") 509 (error "Sorry. Your version of gnus does not support PGP/GPG")
500 (mml-secure-message-sign-pgpmime) 510 (mml-secure-message-sign-pgpmime)))
501 (setq mh-mml-compose-insert-flag t)))
502 511
503 ;;;###mh-autoload 512 ;;;###mh-autoload
504 (defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign) 513 (defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign)
505 "Add directive to encrypt and sign the entire message. 514 "Add directive to encrypt and sign the entire message.
506 If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." 515 If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)."
507 (interactive "P") 516 (interactive "P")
508 (if (not mh-gnus-pgp-support-flag) 517 (if (not mh-gnus-pgp-support-flag)
509 (error "Sorry. Your version of gnus does not support PGP/GPG") 518 (error "Sorry. Your version of gnus does not support PGP/GPG")
510 (mml-secure-message-encrypt-pgpmime dontsign) 519 (mml-secure-message-encrypt-pgpmime dontsign)))
511 (setq mh-mml-compose-insert-flag t))) 520
521 ;;;###mh-autoload
522 (defun mh-mml-directive-present-p ()
523 "Check if the current buffer has text which may be an MML directive."
524 (save-excursion
525 (goto-char (point-min))
526 (re-search-forward
527 "\\(<#part\\(.\\|\n\\)*>[ \n\t]*<#/part>\\|^<#secure.+>$\\)"
528 nil t)))
512 529
513 530
514 531
515 ;;; MIME decoding 532 ;;; MIME decoding
516 533
544 (car handle)))) 561 (car handle))))
545 562
546 ;; Copy of original macro is in mm-decode.el 563 ;; Copy of original macro is in mm-decode.el
547 (mh-defun-compat mm-handle-multipart-ctl-parameter (handle parameter) 564 (mh-defun-compat mm-handle-multipart-ctl-parameter (handle parameter)
548 (get-text-property 0 parameter (car handle))) 565 (get-text-property 0 parameter (car handle)))
566
567 (mh-do-in-xemacs (defvar default-enable-multibyte-characters))
549 568
550 ;; Copy of original function in mm-decode.el 569 ;; Copy of original function in mm-decode.el
551 (mh-defun-compat mm-readable-p (handle) 570 (mh-defun-compat mm-readable-p (handle)
552 "Say whether the content of HANDLE is readable." 571 "Say whether the content of HANDLE is readable."
553 (and (< (with-current-buffer (mm-handle-buffer handle) 572 (and (< (with-current-buffer (mm-handle-buffer handle)
608 ;;;###mh-autoload 627 ;;;###mh-autoload
609 (defun mh-mime-cleanup () 628 (defun mh-mime-cleanup ()
610 "Free the decoded MIME parts." 629 "Free the decoded MIME parts."
611 (let ((mime-data (gethash (current-buffer) mh-globals-hash))) 630 (let ((mime-data (gethash (current-buffer) mh-globals-hash)))
612 ;; This is for Emacs, what about XEmacs? 631 ;; This is for Emacs, what about XEmacs?
613 (cond ((fboundp 'remove-images) 632 (mh-funcall-if-exists remove-images (point-min) (point-max))
614 (remove-images (point-min) (point-max))))
615 (when mime-data 633 (when mime-data
616 (mm-destroy-parts (mh-mime-handles mime-data)) 634 (mm-destroy-parts (mh-mime-handles mime-data))
617 (remhash (current-buffer) mh-globals-hash)))) 635 (remhash (current-buffer) mh-globals-hash))))
618 636
619 ;;;###mh-autoload 637 ;;;###mh-autoload
660 (defun mh-display-smileys () 678 (defun mh-display-smileys ()
661 "Function to display smileys." 679 "Function to display smileys."
662 (when (and mh-graphical-smileys-flag 680 (when (and mh-graphical-smileys-flag
663 (fboundp 'smiley-region) 681 (fboundp 'smiley-region)
664 (boundp 'font-lock-maximum-size) 682 (boundp 'font-lock-maximum-size)
683 font-lock-maximum-size
665 (>= (/ font-lock-maximum-size 8) (buffer-size))) 684 (>= (/ font-lock-maximum-size 8) (buffer-size)))
666 (smiley-region (point-min) (point-max)))) 685 (smiley-region (point-min) (point-max))))
667 686
668 ;;;###mh-autoload 687 ;;;###mh-autoload
669 (defun mh-display-emphasis () 688 (defun mh-display-emphasis ()
670 "Function to display graphical emphasis." 689 "Function to display graphical emphasis."
671 (when (and mh-graphical-emphasis-flag 690 (when (and mh-graphical-emphasis-flag
672 (boundp 'font-lock-maximum-size) 691 (if font-lock-maximum-size
673 (>= (/ font-lock-maximum-size 8) (buffer-size))) 692 (>= (/ font-lock-maximum-size 8) (buffer-size))))
674 (flet ((article-goto-body ())) ; shadow this function to do nothing 693 (flet ((article-goto-body ())) ; shadow this function to do nothing
675 (save-excursion 694 (save-excursion
676 (goto-char (point-min)) 695 (goto-char (point-min))
677 (article-emphasize))))) 696 (article-emphasize)))))
678 697
683 (defvar mh-mime-button-map 702 (defvar mh-mime-button-map
684 (let ((map (make-sparse-keymap))) 703 (let ((map (make-sparse-keymap)))
685 (unless (>= (string-to-number emacs-version) 21) 704 (unless (>= (string-to-number emacs-version) 21)
686 ;; XEmacs doesn't care. 705 ;; XEmacs doesn't care.
687 (set-keymap-parent map mh-show-mode-map)) 706 (set-keymap-parent map mh-show-mode-map))
688 (define-key map [mouse-2] 'mh-push-button) 707 (mh-do-in-gnu-emacs
708 (define-key map [mouse-2] 'mh-push-button))
709 (mh-do-in-xemacs
710 (define-key map '(button2) 'mh-push-button))
689 (dolist (c mh-mime-button-commands) 711 (dolist (c mh-mime-button-commands)
690 (define-key map (cadr c) (car c))) 712 (define-key map (cadr c) (car c)))
691 map)) 713 map))
692 (defvar mh-mime-button-line-format-alist 714 (defvar mh-mime-button-line-format-alist
693 '((?T long-type ?s) 715 '((?T long-type ?s)
706 (defvar mh-mime-security-button-map 728 (defvar mh-mime-security-button-map
707 (let ((map (make-sparse-keymap))) 729 (let ((map (make-sparse-keymap)))
708 (unless (>= (string-to-number emacs-version) 21) 730 (unless (>= (string-to-number emacs-version) 21)
709 (set-keymap-parent map mh-show-mode-map)) 731 (set-keymap-parent map mh-show-mode-map))
710 (define-key map "\r" 'mh-press-button) 732 (define-key map "\r" 'mh-press-button)
711 (define-key map [mouse-2] 'mh-push-button) 733 (mh-do-in-gnu-emacs
734 (define-key map [mouse-2] 'mh-push-button))
735 (mh-do-in-xemacs
736 (define-key map '(button2) 'mh-push-button))
712 map)) 737 map))
713 738
714 (defvar mh-mime-save-parts-directory nil 739 (defvar mh-mime-save-parts-directory nil
715 "Default to use for `mh-mime-save-parts-default-directory'. 740 "Default to use for `mh-mime-save-parts-default-directory'.
716 Set from last use.") 741 Set from last use.")
753 (if (not (file-directory-p directory)) 778 (if (not (file-directory-p directory))
754 (message "No directory specified.") 779 (message "No directory specified.")
755 (if (equal nil mh-mime-save-parts-default-directory) 780 (if (equal nil mh-mime-save-parts-default-directory)
756 (setq mh-mime-save-parts-directory directory)) 781 (setq mh-mime-save-parts-directory directory))
757 (save-excursion 782 (save-excursion
758 (set-buffer (get-buffer-create " *mh-store*")) 783 (set-buffer (get-buffer-create mh-log-buffer))
759 (cd directory) 784 (cd directory)
760 (setq mh-mime-save-parts-directory directory) 785 (setq mh-mime-save-parts-directory directory)
761 (erase-buffer) 786 (let ((initial-size (mh-truncate-log-buffer)))
762 (apply 'call-process 787 (apply 'call-process
763 (expand-file-name command mh-progs) nil t nil 788 (expand-file-name command mh-progs) nil t nil
764 (mh-list-to-string (list folder msg "-auto"))) 789 (mh-list-to-string (list folder msg "-auto")))
765 (if (> (buffer-size) 0) 790 (if (> (buffer-size) initial-size)
766 (save-window-excursion 791 (save-window-excursion
767 (switch-to-buffer-other-window " *mh-store*") 792 (switch-to-buffer-other-window mh-log-buffer)
768 (sit-for 3))))))) 793 (sit-for 3))))))))
769 794
770 ;; Avoid errors if gnus-sum isn't loaded yet... 795 ;; Avoid errors if gnus-sum isn't loaded yet...
771 (defvar gnus-newsgroup-charset nil) 796 (defvar gnus-newsgroup-charset nil)
772 (defvar gnus-newsgroup-name nil) 797 (defvar gnus-newsgroup-name nil)
798
799 (defun mh-decode-message-body ()
800 "Decode message based on charset.
801 If message has been encoded for transfer take that into account."
802 (let* ((ct (ignore-errors (mail-header-parse-content-type
803 (message-fetch-field "Content-Type" t))))
804 (charset (mail-content-type-get ct 'charset))
805 (cte (message-fetch-field "Content-Transfer-Encoding")))
806 (when (stringp cte) (setq cte (mail-header-strip cte)))
807 (when (or (not ct) (equal (car ct) "text/plain"))
808 (save-restriction
809 (narrow-to-region (min (1+ (mh-mail-header-end)) (point-max))
810 (point-max))
811 (mm-decode-body charset
812 (and cte (intern (downcase
813 (gnus-strip-whitespace cte))))
814 (car ct))))))
815
816 ;;;###mh-autoload
817 (defun mh-decode-message-header ()
818 "Decode RFC2047 encoded message header fields."
819 (when mh-decode-mime-flag
820 (let ((buffer-read-only nil))
821 (rfc2047-decode-region (point-min) (mh-mail-header-end)))))
773 822
774 ;;;###mh-autoload 823 ;;;###mh-autoload
775 (defun mh-mime-display (&optional pre-dissected-handles) 824 (defun mh-mime-display (&optional pre-dissected-handles)
776 "Display (and possibly decode) MIME handles. 825 "Display (and possibly decode) MIME handles.
777 Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If 826 Optional argument, PRE-DISSECTED-HANDLES is a list of MIME handles. If
778 present they are displayed otherwise the buffer is parsed and then 827 present they are displayed otherwise the buffer is parsed and then
779 displayed." 828 displayed."
780 (let ((handles ()) 829 (let ((handles ())
781 (folder mh-show-folder-buffer)) 830 (folder mh-show-folder-buffer)
831 (raw-message-data (buffer-string)))
782 (flet ((mm-handle-set-external-undisplayer 832 (flet ((mm-handle-set-external-undisplayer
783 (handle function) 833 (handle function)
784 (mh-handle-set-external-undisplayer folder handle function))) 834 (mh-handle-set-external-undisplayer folder handle function)))
785 ;; If needed dissect the current buffer 835 (goto-char (point-min))
786 (if pre-dissected-handles 836 (unless (search-forward "\n\n" nil t)
787 (setq handles pre-dissected-handles) 837 (goto-char (point-max))
788 (setq handles (or (mm-dissect-buffer nil) (mm-uu-dissect))) 838 (insert "\n\n"))
789 (setf (mh-mime-handles (mh-buffer-data)) 839
790 (mm-merge-handles handles (mh-mime-handles (mh-buffer-data)))) 840 (condition-case err
791 841 (progn
792 ;; Use charset to decode body... 842 ;; If needed dissect the current buffer
793 (unless handles 843 (if pre-dissected-handles
794 (let* ((ct (ignore-errors 844 (setq handles pre-dissected-handles)
795 (mail-header-parse-content-type 845 (setq handles (or (mm-dissect-buffer nil) (mm-uu-dissect)))
796 (message-fetch-field "Content-Type" t)))) 846 (setf (mh-mime-handles (mh-buffer-data))
797 (charset (mail-content-type-get ct 'charset))) 847 (mm-merge-handles handles
798 (when (stringp charset) 848 (mh-mime-handles (mh-buffer-data))))
799 (mm-decode-body charset))))) 849 (unless handles (mh-decode-message-body)))
800 850
801 (when (and handles (or (not (stringp (car handles))) (cdr handles))) 851 (when (and handles
802 ;; Goto start of message body 852 (or (not (stringp (car handles))) (cdr handles)))
803 (goto-char (point-min)) 853 ;; Goto start of message body
804 (or (search-forward "\n\n" nil t) (goto-char (point-max))) 854 (goto-char (point-min))
805 855 (or (search-forward "\n\n" nil t) (goto-char (point-max)))
806 ;; Delete the body 856
807 (delete-region (point) (point-max)) 857 ;; Delete the body
808 858 (delete-region (point) (point-max))
809 ;; Display the MIME handles 859
810 (mh-mime-display-part handles))))) 860 ;; Display the MIME handles
861 (mh-mime-display-part handles)))
862 (error
863 (message "Please report this error. The error message is:\n %s"
864 (error-message-string err))
865 (delete-region (point-min) (point-max))
866 (insert raw-message-data))))))
811 867
812 (defun mh-mime-display-part (handle) 868 (defun mh-mime-display-part (handle)
813 "Decides the viewer to call based on the type of HANDLE." 869 "Decides the viewer to call based on the type of HANDLE."
814 (cond ((null handle) nil) 870 (cond ((null handle) nil)
815 ((not (stringp (car handle))) 871 ((not (stringp (car handle)))
866 ; this only tells us if the image is 922 ; this only tells us if the image is
867 ; something that emacs can display 923 ; something that emacs can display
868 (let* ((image (mm-get-image handle))) 924 (let* ((image (mm-get-image handle)))
869 (cond ((fboundp 'glyph-width) 925 (cond ((fboundp 'glyph-width)
870 ;; XEmacs -- totally untested, copied from gnus 926 ;; XEmacs -- totally untested, copied from gnus
871 (and (< (glyph-width image) 927 (and (mh-funcall-if-exists glyphp image)
928 (< (glyph-width image)
872 (or mh-max-inline-image-width 929 (or mh-max-inline-image-width
873 (window-pixel-width))) 930 (window-pixel-width)))
874 (< (glyph-height image) 931 (< (glyph-height image)
875 (or mh-max-inline-image-height 932 (or mh-max-inline-image-height
876 (window-pixel-height))))) 933 (window-pixel-height)))))
877 ((fboundp 'image-size) 934 ((fboundp 'image-size)
878 ;; Emacs21 -- copied from gnus 935 ;; Emacs21 -- copied from gnus
879 (let ((size (image-size image))) 936 (let ((size (mh-funcall-if-exists image-size image)))
880 (and (< (cdr size) 937 (and size
938 (< (cdr size)
881 (or mh-max-inline-image-height 939 (or mh-max-inline-image-height
882 (1- (window-height)))) 940 (1- (window-height))))
883 (< (car size) 941 (< (car size)
884 (or mh-max-inline-image-width (window-width)))))) 942 (or mh-max-inline-image-width (window-width))))))
885 (t 943 (t
887 nil)))))) 945 nil))))))
888 946
889 (defun mh-inline-vcard-p (handle) 947 (defun mh-inline-vcard-p (handle)
890 "Decide if HANDLE is a vcard that must be displayed inline." 948 "Decide if HANDLE is a vcard that must be displayed inline."
891 (let ((type (mm-handle-type handle))) 949 (let ((type (mm-handle-type handle)))
892 (and (consp type) 950 (and (or (featurep 'vcard) (fboundp 'vcard-pretty-print))
951 (consp type)
893 (equal (car type) "text/x-vcard") 952 (equal (car type) "text/x-vcard")
894 (save-excursion 953 (save-excursion
895 (save-restriction 954 (save-restriction
896 (widen) 955 (widen)
897 (goto-char (point-min)) 956 (goto-char (point-min))
930 (insert "\n") 989 (insert "\n")
931 (mh-insert-mime-button handle (mh-mime-part-index handle) nil) 990 (mh-insert-mime-button handle (mh-mime-part-index handle) nil)
932 (forward-line -1) 991 (forward-line -1)
933 (mh-mm-display-part handle))) 992 (mh-mm-display-part handle)))
934 (goto-char (point-max))))) 993 (goto-char (point-max)))))
994
995 (mh-do-in-xemacs
996 (defvar dots)
997 (defvar type))
935 998
936 (defun mh-insert-mime-button (handle index displayed) 999 (defun mh-insert-mime-button (handle index displayed)
937 "Insert MIME button for HANDLE. 1000 "Insert MIME button for HANDLE.
938 INDEX is the part number that will be DISPLAYED. It is also used by commands 1001 INDEX is the part number that will be DISPLAYED. It is also used by commands
939 like \"K v\" which operate on individual MIME parts." 1002 like \"K v\" which operate on individual MIME parts."
997 (if (mm-handle-displayed-p handle) 1060 (if (mm-handle-displayed-p handle)
998 ;; This will remove the part. 1061 ;; This will remove the part.
999 (progn 1062 (progn
1000 ;; Delete the button and displayed part (if any) 1063 ;; Delete the button and displayed part (if any)
1001 (let ((region (get-text-property point 'mh-region))) 1064 (let ((region (get-text-property point 'mh-region)))
1002 (when region 1065 (when (and region (fboundp 'remove-images))
1003 (when (fboundp 'remove-images) 1066 (mh-funcall-if-exists
1004 (remove-images (car region) (cdr region)))) 1067 remove-images (car region) (cdr region)))
1005 (mm-display-part handle) 1068 (mm-display-part handle)
1006 (when region 1069 (when region
1007 (delete-region (car region) (cdr region)))) 1070 (delete-region (car region) (cdr region))))
1008 ;; Delete button (if it still remains). This happens for 1071 ;; Delete button (if it still remains). This happens for
1009 ;; externally displayed parts where the previous step does 1072 ;; externally displayed parts where the previous step does
1065 "Click MIME button for EVENT. 1128 "Click MIME button for EVENT.
1066 If the MIME part is visible then it is removed. Otherwise the part is 1129 If the MIME part is visible then it is removed. Otherwise the part is
1067 displayed. This function is called when the mouse is used to click the MIME 1130 displayed. This function is called when the mouse is used to click the MIME
1068 button." 1131 button."
1069 (interactive "e") 1132 (interactive "e")
1070 (set-buffer (window-buffer (posn-window (event-start event)))) 1133 (save-excursion
1071 (select-window (posn-window (event-start event))) 1134 (let* ((event-window
1072 (let* ((pos (posn-point (event-start event))) 1135 (or (mh-funcall-if-exists posn-window (event-start event));GNU Emacs
1073 (folder mh-show-folder-buffer) 1136 (mh-funcall-if-exists event-window event))) ;XEmacs
1074 (mm-inline-media-tests mh-mm-inline-media-tests) 1137 (event-position
1075 (data (get-text-property pos 'mh-data)) 1138 (or (mh-funcall-if-exists posn-point (event-start event)) ;GNU Emacs
1076 (function (get-text-property pos 'mh-callback)) 1139 (mh-funcall-if-exists event-closest-point event))) ;XEmacs
1077 (buffer-read-only nil)) 1140 (original-window (selected-window))
1078 (flet ((mm-handle-set-external-undisplayer 1141 (original-position (progn
1079 (handle function) 1142 (set-buffer (window-buffer event-window))
1080 (mh-handle-set-external-undisplayer folder handle function))) 1143 (set-marker (make-marker) (point))))
1081 (goto-char pos) 1144 (folder mh-show-folder-buffer)
1082 (unwind-protect (and function (funcall function data)) 1145 (mm-inline-media-tests mh-mm-inline-media-tests)
1083 (set-buffer-modified-p nil))))) 1146 (data (get-text-property event-position 'mh-data))
1147 (function (get-text-property event-position 'mh-callback))
1148 (buffer-read-only nil))
1149 (unwind-protect
1150 (progn
1151 (select-window event-window)
1152 (flet ((mm-handle-set-external-undisplayer (handle func)
1153 (mh-handle-set-external-undisplayer folder handle func)))
1154 (goto-char event-position)
1155 (and function (funcall function data))))
1156 (set-buffer-modified-p nil)
1157 (goto-char original-position)
1158 (set-marker original-position nil)
1159 (select-window original-window)))))
1084 1160
1085 ;;;###mh-autoload 1161 ;;;###mh-autoload
1086 (defun mh-mime-save-part () 1162 (defun mh-mime-save-part ()
1087 "Save MIME part at point." 1163 "Save MIME part at point."
1088 (interactive) 1164 (interactive)
1240 (mm-merge-handles 1316 (mm-merge-handles
1241 handles (mh-mime-handles (mh-buffer-data)))) 1317 handles (mh-mime-handles (mh-buffer-data))))
1242 handles)))) 1318 handles))))
1243 1319
1244 (goto-char (point-min)) 1320 (goto-char (point-min))
1321 (mh-show-xface)
1245 (cond (clean-message-header 1322 (cond (clean-message-header
1246 (mh-clean-msg-header (point-min) 1323 (mh-clean-msg-header (point-min)
1247 invisible-headers 1324 invisible-headers
1248 visible-headers) 1325 visible-headers)
1249 (goto-char (point-min))) 1326 (goto-char (point-min)))
1250 (t 1327 (t
1251 (mh-start-of-uncleaned-message))) 1328 (mh-start-of-uncleaned-message)))
1252 (mh-show-xface) 1329 (mh-decode-message-header)
1253 (mh-show-addr) 1330 (mh-show-addr)
1254 ;; The other highlighting types don't need anything special 1331 ;; The other highlighting types don't need anything special
1255 (when (eq mh-highlight-citation-p 'gnus) 1332 (when (eq mh-highlight-citation-p 'gnus)
1256 (mh-gnus-article-highlight-citation)) 1333 (mh-gnus-article-highlight-citation))
1257 (goto-char (point-min)) 1334 (goto-char (point-min))