]> code.delx.au - gnu-emacs/blobdiff - lisp/mail/rmailmm.el
Fix various uses of display-buffer and pop-to-buffer
[gnu-emacs] / lisp / mail / rmailmm.el
index 96132739b201696758e86d3d61cfb6a456da36d2..d3351255583d8efb4ef552d709beb3aac36e4f9c 100644 (file)
@@ -153,20 +153,21 @@ MIME entities.")
 ;;; MIME-entity object
 
 (defun rmail-mime-entity (type disposition transfer-encoding
-                              display header tagline body children handler)
+                              display header tagline body children handler
+                              &optional truncated)
   "Retrun a newly created MIME-entity object from arguments.
 
-A MIME-entity is a vector of 9 elements:
+A MIME-entity is a vector of 10 elements:
 
   [TYPE DISPOSITION TRANSFER-ENCODING DISPLAY HEADER TAGLINE BODY
-   CHILDREN HANDLER]
+   CHILDREN HANDLER TRUNCATED]
 
 TYPE and DISPOSITION correspond to MIME headers Content-Type and
-Cotent-Disposition respectively, and has this format:
+Content-Disposition respectively, and have this format:
 
   \(VALUE (ATTRIBUTE . VALUE) (ATTRIBUTE . VALUE) ...)
 
-VALUE is a string and ATTRIBUTE is a symbol.
+Each VALUE is a string and each ATTRIBUTE is a string.
 
 Consider the following header, for example:
 
@@ -192,8 +193,8 @@ has these values:
   raw: displayed by the raw MIME data (for the header and body only)
 
 HEADER and BODY are vectors [BEG END DISPLAY-FLAG], where BEG and
-END specify the region of the header or body lines in RMAIL's
-data (mbox) buffer, and DISPLAY-FLAG non-nil means that the
+END are markers that specify the region of the header or body lines
+in RMAIL's data (mbox) buffer, and DISPLAY-FLAG non-nil means that the
 header or body is, by default, displayed by the decoded
 presentation form.
 
@@ -208,9 +209,12 @@ entity have one or more children.  A \"message/rfc822\" entity
 has just one child.  Any other entity has no child.
 
 HANDLER is a function to insert the entity according to DISPLAY.
-It is called with one argument ENTITY."
+It is called with one argument ENTITY.
+
+TRUNCATED is non-nil if the text of this entity was truncated."
+
   (vector type disposition transfer-encoding
-         display header tagline body children handler))
+         display header tagline body children handler truncated))
 
 ;; Accessors for a MIME-entity object.
 (defsubst rmail-mime-entity-type (entity) (aref entity 0))
@@ -222,6 +226,9 @@ It is called with one argument ENTITY."
 (defsubst rmail-mime-entity-body (entity) (aref entity 6))
 (defsubst rmail-mime-entity-children (entity) (aref entity 7))
 (defsubst rmail-mime-entity-handler (entity) (aref entity 8))
+(defsubst rmail-mime-entity-truncated (entity) (aref entity 9))
+(defsubst rmail-mime-entity-set-truncated (entity truncated)
+  (aset entity 9 truncated))
 
 (defsubst rmail-mime-message-p ()
   "Non-nil if and only if the current message is a MIME."
@@ -237,6 +244,10 @@ It is called with one argument ENTITY."
         (directory (button-get button 'directory))
         (data (button-get button 'data))
         (ofilename filename))
+    (if (and (not (stringp data))
+            (rmail-mime-entity-truncated data))
+       (unless (y-or-n-p "This entity is truncated; save anyway? ")
+         (error "Aborted")))
     (setq filename (expand-file-name
                    (read-file-name (format "Save as (default: %s): " filename)
                                    directory
@@ -387,6 +398,11 @@ The value is a vector [ INDEX HEADER TAGLINE BODY END], where
            (if (and rmail-mime-mbox-buffer (= (aref segment 1) (point-min)))
                (let ((new (aref (rmail-mime-entity-display entity) 1)))
                  (aset new 0 t))))
+       ;; Query as a warning before showing if truncated.
+       (if (and (not (stringp entity))
+                (rmail-mime-entity-truncated entity))
+           (unless (y-or-n-p "This entity is truncated; show anyway? ")
+             (error "Aborted")))
        ;; Enter the shown mode.
        (rmail-mime-shown-mode entity)
        ;; Force this body shown.
@@ -410,7 +426,7 @@ The value is a vector [ INDEX HEADER TAGLINE BODY END], where
   "Insert a tag line for MIME-entity ENTITY.
 ITEM-LIST is a list of strings or button-elements (list) to be added
 to the tag line."
-  (insert "[")
+  (insert "\n[")
   (let ((tag (aref (rmail-mime-entity-tagline entity) 0)))
     (if (> (length tag) 0) (insert (substring tag 1) ":")))
   (insert (car (rmail-mime-entity-type entity)) " ")
@@ -423,7 +439,7 @@ to the tag line."
       (if (stringp item)
          (insert item)
        (apply 'insert-button item))))
-  (insert "]\n"))
+  (insert "]\n\n"))
 
 (defun rmail-mime-update-tagline (entity)
   "Update the current tag line for MIME-entity ENTITY."
@@ -531,7 +547,7 @@ HEADER is a header component of a MIME-entity object (see
        (beg (point))
        (segment (rmail-mime-entity-segment (point) entity)))
 
-    (or (integerp (aref body 0))
+    (or (integerp (aref body 0)) (markerp (aref body 0))
        (let ((data (buffer-string)))
          (aset body 0 data)
          (delete-region (point-min) (point-max))))
@@ -688,7 +704,7 @@ directly."
         (segment (rmail-mime-entity-segment (point) entity))
         beg data size)
 
-    (if (integerp (aref body 0))
+    (if (or (integerp (aref body 0)) (markerp (aref body 0)))
        (setq data entity
              size (car bulk-data))
       (if (stringp (aref body 0))
@@ -816,7 +832,7 @@ The other arguments are the same as `rmail-mime-multipart-handler'."
   (let ((boundary (cdr (assq 'boundary content-type)))
        (subtype (cadr (split-string (car content-type) "/")))
        (index 0)
-       beg end next entities)
+       beg end next entities truncated)
     (unless boundary
       (rmail-mm-get-boundary-error-message
        "No boundary defined" content-type content-disposition
@@ -843,8 +859,18 @@ The other arguments are the same as `rmail-mime-multipart-handler'."
     ;; the beginning of the next part.  The current point is just
     ;; after the boundary tag.
     (setq beg (point-min))
-    (while (search-forward boundary nil t)
-      (setq end (match-beginning 0))
+
+    (while (or (and (search-forward boundary nil t)
+                   (setq truncated nil end (match-beginning 0)))
+              ;; If the boundary does not appear at all,
+              ;; the message was truncated.
+              ;; Handle the rest of the truncated message
+              ;; (if it isn't empty) by pretending that the boundary
+              ;; appears at the end of the message.
+              (and (save-excursion
+                     (skip-chars-forward "\n")
+                     (> (point-max) (point)))
+                   (setq truncated t end (point-max))))
       ;; If this is the last boundary according to RFC 2046, hide the
       ;; epilogue, else hide the boundary only.  Use a marker for
       ;; `next' because `rmail-mime-show' may change the buffer.
@@ -852,6 +878,9 @@ The other arguments are the same as `rmail-mime-multipart-handler'."
             (setq next (point-max-marker)))
            ((looking-at "[ \t]*\n")
             (setq next (copy-marker (match-end 0) t)))
+           (truncated
+            ;; We're handling what's left of a truncated message.
+            (setq next (point-max-marker)))
            (t
             ;; The original code signalled an error as below, but
             ;; this line may be a boundary of nested multipart.  So,
@@ -873,6 +902,7 @@ The other arguments are the same as `rmail-mime-multipart-handler'."
                ;; Display a tagline.
                (aset (aref (rmail-mime-entity-display child) 1) 1
                      (aset (rmail-mime-entity-tagline child) 2 t))
+               (rmail-mime-entity-set-truncated child truncated)
                (push child entities)))
 
          (delete-region end next)
@@ -1099,9 +1129,10 @@ modified."
 
     (if parse-tag
        (let* ((is-inline (string= (car content-disposition) "inline"))
-              (header (vector (point-min) end nil))
+              (hdr-end (copy-marker end))
+              (header (vector (point-min-marker) hdr-end nil))
               (tagline (vector parse-tag (cons nil nil) t))
-              (body (vector end (point-max) is-inline))
+              (body (vector hdr-end (point-max-marker) is-inline))
               (new (vector (aref header 2) (aref tagline 2) (aref body 2)))
               children handler entity)
          (cond ((string-match "multipart/.*" (car content-type))
@@ -1150,11 +1181,11 @@ modified."
       ;; Hide headers and handle the part.
       (put-text-property (point-min) (point-max) 'rmail-mime-entity
                         (rmail-mime-entity
-                        content-type content-disposition
-                        content-transfer-encoding
-                        (vector (vector 'raw nil 'raw) (vector 'raw nil 'raw))
-                        (vector nil nil 'raw) (vector "" (cons nil nil) nil)
-                        (vector nil nil 'raw) nil nil))
+                         content-type content-disposition
+                         content-transfer-encoding
+                         (vector (vector 'raw nil 'raw) (vector 'raw nil 'raw))
+                         (vector nil nil 'raw) (vector "" (cons nil nil) nil)
+                         (vector nil nil 'raw) nil nil))
       (save-restriction
        (cond ((string= (car content-type) "message/rfc822")
               (narrow-to-region end (point-max)))
@@ -1333,12 +1364,16 @@ attachments as specfied by `rmail-mime-attachment-dirs-alist'."
 (setq rmail-show-mime-function 'rmail-show-mime)
 
 (defun rmail-insert-mime-forwarded-message (forward-buffer)
-  "Function to set in `rmail-insert-mime-forwarded-message-function' (which see)."
-  (let ((rmail-mime-mbox-buffer
-        (with-current-buffer forward-buffer rmail-view-buffer)))
+  "Insert the message in FORWARD-BUFFER as a forwarded message.
+This is the usual value of `rmail-insert-mime-forwarded-message-function'."
+  (let ((message-buffer
+        (with-current-buffer forward-buffer
+          (if rmail-buffer-swapped
+              forward-buffer
+            rmail-view-buffer))))
     (save-restriction
       (narrow-to-region (point) (point))
-      (message-forward-make-body-mime rmail-mime-mbox-buffer))))
+      (message-forward-make-body-mime message-buffer))))
 
 (setq rmail-insert-mime-forwarded-message-function
       'rmail-insert-mime-forwarded-message)
@@ -1374,6 +1409,8 @@ attachments as specfied by `rmail-mime-attachment-dirs-alist'."
         (re-search-forward regexp nil t))
        ;; Next, search the body.
        (if (and entity
+               ;; RMS: I am not sure why, but sometimes this is a string.
+               (not (stringp entity))
                (let* ((content-type (rmail-mime-entity-type entity))
                       (charset (cdr (assq 'charset (cdr content-type)))))
                  (or (not (string-match "text/.*" (car content-type)))