Merge from trunk:
[elisp/wanderlust.git] / wl / wl-draft.el
index 2e4dbf9..bcb09bd 100644 (file)
 (defvar wl-draft-reedit nil)
 (defvar wl-draft-reply-buffer nil)
 (defvar wl-draft-forward nil)
-(defvar wl-draft-parent-folder nil)
 (defvar wl-draft-doing-mime-bcc nil)
 
+(defvar wl-draft-parent-folder nil
+  "Folder name of the summary in which current draft is invoked.
+This variable is local in each draft buffer.
+You can refer its value in `wl-draft-config-alist'.
+
+e.g.
+\(setq wl-draft-config-alist
+      '(((string-match \".*@domain1$\" wl-draft-parent-folder)
+         (\"From\" . \"user@domain1\"))
+        ((string-match \".*@domain2$\" wl-draft-parent-folder)
+         (\"From\" . \"user@domain2\"))))")
+
 (defvar wl-draft-config-sub-func-alist
   '((body              . wl-draft-config-sub-body)
     (top               . wl-draft-config-sub-top)
   (interactive)
   (if (not (file-exists-p wl-x-face-file))
       (error "File %s does not exist" wl-x-face-file)
-    (beginning-of-buffer)
+    (goto-char (point-min))
     (search-forward mail-header-separator nil t)
     (beginning-of-line)
     (wl-draft-insert-x-face-field-here)
       (let ((rlist (elmo-list-delete
                    (or wl-user-mail-address-list
                        (list (wl-address-header-extract-address wl-from)))
-                   (copy-sequence recipients))))
+                   recipients
+                   (lambda (elem list)
+                     (elmo-delete-if
+                      (lambda (item) (string= (downcase elem)
+                                              (downcase item)))
+                      list)))))
        (if (elmo-list-member rlist (mapcar 'downcase
                                            wl-subscribed-mailing-list))
            rlist
   (let ((myself (or wl-user-mail-address-list
                    (list (wl-address-header-extract-address wl-from)))))
     (cond (wl-draft-always-delete-myself ; always-delete option
-          (elmo-list-delete myself cc))
+          (elmo-list-delete myself cc
+                            (lambda (elem list)
+                              (elmo-delete-if
+                               (lambda (item) (string= (downcase elem)
+                                                       (downcase item)))
+                               list))))
          ((elmo-list-member (append to cc) ; subscribed mailing-list
                             (mapcar 'downcase wl-subscribed-mailing-list))
-          (elmo-list-delete myself cc))
+          (elmo-list-delete myself cc
+                            (lambda (elem list)
+                              (elmo-delete-if
+                               (lambda (item) (string= (downcase elem)
+                                                       (downcase item)))
+                               list))))
          (t cc))))
 
 (defun wl-draft-forward (original-subject summary-buf)
            references (wl-delete-duplicates references)
            references (when references
                         (mapconcat 'identity references "\n\t"))))
+    (and wl-draft-use-frame
+        (get-buffer-window summary-buf)
+        (select-window (get-buffer-window summary-buf)))
     (wl-draft (list (cons 'To "")
                    (cons 'Subject
                          (concat wl-forward-subject-prefix original-subject))
       (substring subject (match-end 0))
     subject))
 
+(defun wl-draft-self-reply-p ()
+  "Return t when From address in the current message is user's self one or not."
+  (wl-address-user-mail-address-p (or (elmo-field-body "From") "")))
+
 (defun wl-draft-reply-list-symbol (with-arg)
   "Return symbol `wl-draft-reply-*-argument-list' match condition.
 Check WITH-ARG and From: field."
-  (if (wl-address-user-mail-address-p (or (elmo-field-body "From") ""))
+  (if (wl-draft-self-reply-p)
       (if with-arg
          'wl-draft-reply-myself-with-argument-list
        'wl-draft-reply-myself-without-argument-list)
@@ -302,9 +335,10 @@ Reply to author if WITH-ARG is non-nil."
   (let (r-list
        to mail-followup-to cc subject in-reply-to references newsgroups
        to-alist cc-alist decoder parent-folder)
-    (set-buffer summary-buf)
-    (setq parent-folder (wl-summary-buffer-folder-name))
-    (set-buffer buf)
+    (when (buffer-live-p summary-buf)
+      (with-current-buffer summary-buf
+       (setq parent-folder (wl-summary-buffer-folder-name))))
+    (set-buffer (or buf mime-mother-buffer))
     (setq r-list (symbol-value (wl-draft-reply-list-symbol with-arg)))
     (catch 'done
       (while r-list
@@ -434,6 +468,9 @@ Reply to author if WITH-ARG is non-nil."
          references (wl-delete-duplicates references)
          references (if references
                         (mapconcat 'identity references "\n\t")))
+    (and wl-draft-use-frame
+        (get-buffer-window summary-buf)
+        (select-window (get-buffer-window summary-buf)))
     (wl-draft (list (cons 'To to)
                    (cons 'Cc cc)
                    (cons 'Newsgroups newsgroups)
@@ -700,23 +737,23 @@ Reply to author if WITH-ARG is non-nil."
          (delete-frame)
        ;; hide draft window
        (or (one-window-p)
-           (delete-window)))
-      ;; stay folder window if required
-      (when wl-stay-folder-window
-       (if (setq fld-buf (get-buffer wl-folder-buffer-name))
-           (if (setq fld-win (get-buffer-window fld-buf))
-               (select-window fld-win)
-             (if wl-draft-resume-folder-window ;; resume folder window
-                 (switch-to-buffer fld-buf)))))
-      (if (buffer-live-p sum-buf)
-         (if (setq sum-win (get-buffer-window sum-buf t))
-             ;; if Summary is on the frame, select it.
-             (select-window sum-win)
-           ;; if summary is not on the frame, switch to it.
-           (if (and wl-stay-folder-window
-                    (or wl-draft-resume-folder-window fld-win))
-               (wl-folder-select-buffer sum-buf)
-             (switch-to-buffer sum-buf)))))))
+           (delete-window))
+       ;; stay folder window if required
+       (when wl-stay-folder-window
+         (if (setq fld-buf (get-buffer wl-folder-buffer-name))
+             (if (setq fld-win (get-buffer-window fld-buf))
+                 (select-window fld-win)
+               (if wl-draft-resume-folder-window ;; resume folder window
+                   (switch-to-buffer fld-buf)))))
+       (if (buffer-live-p sum-buf)
+           (if (setq sum-win (get-buffer-window sum-buf t))
+               ;; if Summary is on the frame, select it.
+               (select-window sum-win)
+             ;; if summary is not on the frame, switch to it.
+             (if (and wl-stay-folder-window
+                      (or wl-draft-resume-folder-window fld-win))
+                 (wl-folder-select-buffer sum-buf)
+               (switch-to-buffer sum-buf))))))))
 
 (defun wl-draft-delete (editing-buffer)
   "kill the editing draft buffer and delete the file corresponds to it."
@@ -1051,7 +1088,7 @@ non-nil."
                     (wl-draft-write-sendlog 'failed 'smtp smtp-server
                                             recipients id)
                     (if (and (eq (car err) 'smtp-response-error)
-                             (/= (nth 1 err) 334))
+                             (= (nth 1 err) 535))
                         (elmo-remove-passwd
                          (wl-smtp-password-key
                           smtp-sasl-user-name
@@ -1426,17 +1463,20 @@ If KILL-WHEN-DONE is non-nil, current draft buffer is killed"
       (save-excursion
        (goto-char (point-min))
        (while (re-search-forward "^Fcc:[ \t]*" header-end t)
-         (setq fcc-list
-               (cons (buffer-substring-no-properties
-                      (point)
-                      (progn
-                        (end-of-line)
-                        (skip-chars-backward " \t")
-                        (point)))
-                     fcc-list))
          (save-match-data
-           (wl-folder-confirm-existence
-            (wl-folder-get-elmo-folder (eword-decode-string (car fcc-list)))))
+           (setq fcc-list
+                 (append fcc-list
+                         (split-string
+                          (buffer-substring-no-properties
+                           (point)
+                           (progn
+                             (end-of-line)
+                             (skip-chars-backward " \t")
+                             (point)))
+                          ",[ \t]*")))
+           (dolist (folder fcc-list)
+             (wl-folder-confirm-existence
+              (wl-folder-get-elmo-folder (eword-decode-string folder)))))
          (delete-region (match-beginning 0)
                         (progn (forward-line 1) (point)))))
       fcc-list)))
@@ -1602,7 +1642,7 @@ If KILL-WHEN-DONE is non-nil, current draft buffer is killed"
     (setq wl-sent-message-queued nil)
     (setq wl-draft-buffer-file-name file-name)
     (setq wl-draft-config-exec-flag t)
-    (setq wl-draft-parent-folder parent-folder)
+    (setq wl-draft-parent-folder (or parent-folder ""))
     (or (eq this-command 'wl-folder-write-current-folder)
        (setq wl-draft-buffer-cur-summary-buffer summary-buf))
     buf-name))
@@ -1834,9 +1874,23 @@ If KILL-WHEN-DONE is non-nil, current draft buffer is killed"
        (switch-to-buffer buffer))
       (set-buffer buffer)
       (insert-file-contents-as-binary file-name)
+      (elmo-delete-cr-buffer)
       (let((mime-edit-again-ignored-field-regexp
            "^\\(Content-.*\\|Mime-Version\\):"))
-       (wl-draft-decode-message-in-buffer))
+;      (wl-draft-decode-message-in-buffer))
+       ;;;; From gnus-article-mime-edit-article-setup in T-gnus
+       ;;;; XXX: it is semi issue, perhaps [wl:10790]
+       (let ((ofn (symbol-function 'mime-edit-decode-single-part-in-buffer)))
+         (fset 'mime-edit-decode-single-part-in-buffer
+               (lambda (&rest args)
+                 (unless (let ((content-type (car args)))
+                           (eq 'text (mime-content-type-primary-type
+                                      content-type)))
+                   (setcar (cdr args) 'not-decode-text))
+                 (apply ofn args)))
+         (unwind-protect
+             (wl-draft-decode-message-in-buffer)
+           (fset 'mime-edit-decode-single-part-in-buffer ofn))))
       (wl-draft-insert-mail-header-separator)
       (if (not (string-match (regexp-quote wl-draft-folder)
                             (buffer-name)))
@@ -1877,34 +1931,41 @@ If KILL-WHEN-DONE is non-nil, current draft buffer is killed"
           (beginning-of-line)
         (goto-char (point-max))))))
 
+(defsubst wl-draft-config-sub-eval-insert (content &optional newline)
+  (let (content-value)
+    (when (and content
+              (stringp (setq content-value (eval content))))
+      (insert content-value)
+      (if newline (insert "\n")))))
+
 (defun wl-draft-config-sub-body (content)
   (wl-draft-body-goto-top)
   (delete-region (point) (point-max))
-  (if content (insert (eval content))))
+  (wl-draft-config-sub-eval-insert content))
 
 (defun wl-draft-config-sub-top (content)
   (wl-draft-body-goto-top)
-  (if content (insert (eval content))))
+  (wl-draft-config-sub-eval-insert content))
 
 (defun wl-draft-config-sub-bottom (content)
   (wl-draft-body-goto-bottom)
-  (if content (insert (eval content))))
+  (wl-draft-config-sub-eval-insert content))
 
 (defun wl-draft-config-sub-header (content)
   (wl-draft-config-body-goto-header)
-  (if content (insert (concat (eval content) "\n"))))
+  (wl-draft-config-sub-eval-insert content 'newline))
 
 (defun wl-draft-config-sub-header-top (content)
   (goto-char (point-min))
-  (if content (insert (concat (eval content) "\n"))))
+  (wl-draft-config-sub-eval-insert content 'newline))
 
 (defun wl-draft-config-sub-part-top (content)
   (goto-char (mime-edit-content-beginning))
-  (if content (insert (concat (eval content) "\n"))))
+  (wl-draft-config-sub-eval-insert content 'newline))
 
 (defun wl-draft-config-sub-part-bottom (content)
   (goto-char (mime-edit-content-end))
-  (if content (insert (concat (eval content) "\n"))))
+  (wl-draft-config-sub-eval-insert content 'newline))
 
 (defsubst wl-draft-config-sub-file (content)
   (let ((coding-system-for-read wl-cs-autoconv)
@@ -2262,11 +2323,13 @@ Automatically applied in draft sending time."
 
 (defun wl-draft-highlight-and-recenter (&optional n)
   (interactive "P")
-  (if wl-highlight-body-too
-      (let ((beg (point-min))
-           (end (point-max)))
-       (put-text-property beg end 'face nil)
-       (wl-highlight-message beg end t)))
+  (when wl-highlight-body-too
+    (let ((modified (buffer-modified-p)))
+      (unwind-protect
+         (progn
+           (put-text-property (point-min) (point-max) 'face nil)
+           (wl-highlight-message (point-min) (point-max) t))
+       (set-buffer-modified-p modified))))
   (recenter n))
 
 ;;;; user-agent support by Sen Nagata