* wl-summary.el (wl-summary-set-flags): Allow flag operation even
[elisp/wanderlust.git] / wl / wl-summary.el
index 248b8e0..a2e1069 100644 (file)
@@ -60,7 +60,7 @@
 (defvar dragdrop-drop-functions)
 (defvar scrollbar-height)
 (defvar mail-reply-buffer)
-(defvar elmo-global-flag-list)
+(defvar elmo-global-flags)
 
 (defvar wl-summary-buffer-name "Summary")
 (defvar wl-summary-mode-map nil)
 (defvar wl-summary-buffer-line-format nil)
 (defvar wl-summary-buffer-mode-line-formatter nil)
 (defvar wl-summary-buffer-mode-line nil)
-(defvar wl-summary-buffer-display-as-is nil)
+(defvar wl-summary-buffer-display-mime-mode 'mime)
+(defvar wl-summary-buffer-display-all-header nil)
 
 (defvar wl-thread-indent-level-internal nil)
 (defvar wl-thread-have-younger-brother-str-internal nil)
 (make-variable-buffer-local 'wl-summary-buffer-line-format)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line-formatter)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line)
-(make-variable-buffer-local 'wl-summary-buffer-display-as-is)
+(make-variable-buffer-local 'wl-summary-buffer-display-mime-mode)
+(make-variable-buffer-local 'wl-summary-buffer-display-all-header)
 
 (defvar wl-datevec)
 (defvar wl-thr-indent-string)
@@ -435,7 +437,7 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr)
   (define-key wl-summary-mode-map "\C-c\C-p" 'wl-summary-previous-buffer)
   (define-key wl-summary-mode-map "\C-c\C-n" 'wl-summary-next-buffer)
-  (define-key wl-summary-mode-map "H"    'wl-summary-redisplay-all-header)
+  (define-key wl-summary-mode-map "H"    'wl-summary-toggle-all-header)
   (define-key wl-summary-mode-map "M"    'wl-summary-toggle-mime)
   (define-key wl-summary-mode-map "B"    'wl-summary-burst)
   (define-key wl-summary-mode-map "Z"    'wl-status-update)
@@ -885,12 +887,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 (defun wl-summary-overview-entity-compare-by-from (x y)
   "Compare entity X and Y by from."
   (string<
-   (wl-address-header-extract-address
-    (or (elmo-message-entity-field x 'from t)
-       wl-summary-no-from-message))
-   (wl-address-header-extract-address
-    (or (elmo-message-entity-field y 'from t)
-       wl-summary-no-from-message))))
+   (or (elmo-message-entity-field x 'from t)
+       wl-summary-no-from-message)
+   (or (elmo-message-entity-field y 'from t)
+       wl-summary-no-from-message)))
 
 (defun wl-summary-overview-entity-compare-by-subject (x y)
   "Compare entity X and Y by subject."
@@ -1658,10 +1658,10 @@ If ARG is non-nil, checking is omitted."
       (let ((folder wl-summary-buffer-elmo-folder)
            (cur-buf (current-buffer)))
        (message "Setting all msgs as read...")
-       (elmo-folder-set-flag
+       (elmo-folder-unset-flag
         folder
         (elmo-folder-list-flagged folder 'unread 'in-msgdb)
-        'read)
+        'unread)
        (save-excursion
          (goto-char (point-min))
          (while (not (eobp))
@@ -1796,7 +1796,7 @@ This function is defined for `window-scroll-functions'"
 
 (defun wl-summary-get-available-flags (&optional include-specials)
   (let ((flags (elmo-uniq-list
-               (append elmo-global-flag-list
+               (append elmo-global-flags
                        (copy-sequence elmo-preserved-flags))
                #'delq)))
     (if include-specials
@@ -2301,8 +2301,10 @@ If ARG, without confirm."
          (unless (eq major-mode 'wl-summary-mode)
            (wl-summary-mode))
          (wl-summary-buffer-set-folder folder)
-         (setq wl-summary-buffer-display-as-is
-               (wl-summary-no-mime-p wl-summary-buffer-elmo-folder))
+         (setq wl-summary-buffer-display-mime-mode
+               (if (wl-summary-no-mime-p wl-summary-buffer-elmo-folder)
+                   'as-is
+                 'mime))
          (setq wl-summary-buffer-disp-msg nil)
          (setq wl-summary-buffer-last-displayed-msg nil)
          (setq wl-summary-buffer-current-msg nil)
@@ -2729,14 +2731,20 @@ If ARG, without confirm."
     i))
 
 (defun wl-summary-pick (&optional from-list delete-marks)
-  (interactive)
+  (interactive "i\nP")
   (save-excursion
-    (let* ((condition (car (elmo-parse-search-condition
+    (let* ((messages (or from-list
+                        (elmo-folder-list-messages
+                         wl-summary-buffer-elmo-folder
+                         'visible
+                         'in-msgdb)
+                        (error "No messages")))
+          (condition (car (elmo-parse-search-condition
                            (elmo-read-search-condition
                             wl-summary-pick-field-default))))
           (result (elmo-folder-search wl-summary-buffer-elmo-folder
                                       condition
-                                      from-list))
+                                      messages))
           num)
       (if delete-marks
          (let ((mlist wl-summary-buffer-target-mark-list))
@@ -2898,8 +2906,13 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
      (or (cadr (memq (current-buffer) buffers))
         (car buffers)))))
 
+(defun wl-summary-check-target-mark ()
+  (when (null wl-summary-buffer-target-mark-list)
+    (error "No marked message")))
+
 (defun wl-summary-target-mark-mark-as-read ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2911,6 +2924,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-mark-as-unread ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2921,6 +2935,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
        (wl-summary-unset-mark number)))))
 
 (defun wl-summary-target-mark-operation (flag &optional inverse)
+  (wl-summary-check-target-mark)
   (save-excursion
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
@@ -2941,6 +2956,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-set-flags (&optional remove)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (save-excursion
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
@@ -2953,6 +2969,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-save ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((wl-save-dir
         (wl-read-directory-name "Save to directory: "
                                 wl-temporary-file-directory))
@@ -2966,6 +2983,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-pick ()
   (interactive)
+  (wl-summary-check-target-mark)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
 (defun wl-summary-update-persistent-mark (&optional number flags)
@@ -3105,7 +3123,7 @@ Return non-nil if the mark is updated"
     (let ((completion-ignore-case t))
       (setq flag (intern (downcase
                          (completing-read
-                          "Flag: "
+                          "Mark name: "
                           (mapcar (lambda (flag)
                                     (list (capitalize (symbol-name flag))))
                                   (wl-summary-get-available-flags))
@@ -3128,7 +3146,7 @@ Return non-nil if the mark is updated"
     (let ((completion-ignore-case t))
       (setq flag (intern (downcase
                          (completing-read
-                          "Flag: "
+                          "Mark name: "
                           (mapcar (lambda (flag)
                                     (list (capitalize (symbol-name flag))))
                                   (wl-summary-get-available-flags))
@@ -3148,7 +3166,7 @@ Return non-nil if the mark is updated"
        flag)
     (setq flag (intern (downcase
                        (completing-read
-                        "Flag: "
+                        "Mark name: "
                         (mapcar (lambda (flag)
                                   (list (capitalize (symbol-name flag))))
                                 (wl-summary-get-available-flags))
@@ -3198,18 +3216,20 @@ Return non-nil if the mark is updated"
                  "Flags: "
                  (mapcar (lambda (flag)
                            (list (capitalize (symbol-name flag))))
-                         elmo-global-flag-list)
+                         elmo-global-flags)
                  nil nil (mapconcat (lambda (flag)
                                       (capitalize (symbol-name flag)))
                                     flags
                                     ",")))))
     (dolist (flag new-flags)
-      (unless (memq flag elmo-global-flag-list)
-       (if (y-or-n-p (format "Flag `%s' does not exist yet. Create?"
+      (unless (memq flag elmo-global-flags)
+       (when (elmo-local-flag-p flag)
+         (error "Cannot treat `%s'." flag))
+       (if (y-or-n-p (format "Flag `%s' is not registered yet. Register?"
                              (capitalize (symbol-name flag))))
-           (setq elmo-global-flag-list (append
-                                        elmo-global-flag-list
-                                        (list flag)))
+           (setq elmo-global-flags (append
+                                    elmo-global-flags
+                                    (list flag)))
          (error "Stopped"))))
     new-flags))
 
@@ -3245,14 +3265,10 @@ Return non-nil if the mark is updated"
 
 (defun wl-summary-set-flags (&optional remove)
   (interactive "P")
-  (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder))
-      (error "Cannot process flags in this folder"))
   (wl-summary-set-flags-internal nil nil nil remove))
 
 (defun wl-summary-mark-as-important (&optional prompt)
   (interactive "P")
-  (if (eq 'flag (elmo-folder-type-internal wl-summary-buffer-elmo-folder))
-      (error "Cannot process flags in this folder"))
   (if prompt
       (wl-summary-set-flags-internal)
     (wl-summary-set-persistent-mark-internal
@@ -3807,14 +3823,14 @@ Return t if message exists."
        (progn
          (set-buffer wl-message-buffer)
          t)
-      (wl-summary-redisplay-internal folder number nil
-                                    wl-summary-buffer-display-as-is)
+      (wl-summary-redisplay-internal folder number)
       (when (buffer-live-p wl-message-buffer)
        (set-buffer wl-message-buffer))
       nil)))
 
 (defun wl-summary-target-mark-forward (&optional arg)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        (wl-draft-forward t)
@@ -3845,6 +3861,7 @@ Return t if message exists."
 
 (defun wl-summary-target-mark-reply-with-citation (&optional arg)
   (interactive "P")
+  (wl-summary-check-target-mark)
   (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        change-major-mode-hook
@@ -4339,42 +4356,69 @@ Use function list is `wl-summary-write-current-folder-functions'."
            (wl-summary-redisplay)))
     (message "No last message.")))
 
-(defun wl-summary-toggle-mime ()
-  "Toggle MIME decoding."
-  (interactive)
-  (setq wl-summary-buffer-display-as-is
-       (not wl-summary-buffer-display-as-is))
-  (wl-summary-redisplay)
-  (wl-summary-update-modeline)
-  (message "MIME decoding: %s"
-          (if wl-summary-buffer-display-as-is "OFF" "ON")))
+(defun wl-summary-toggle-mime (&optional arg)
+  "Toggle MIME decoding.
+If ARG is non-nil, ask coding-system to display the message in the current
+MIME analysis mode.
 
-(defun wl-summary-redisplay (&optional arg)
-  "Redisplay message."
+If ARG is numeric number, decode message as following:
+1: Enable MIME analysis.
+2: Enable MIME analysis only for headers.
+3: Disable MIME analysis."
   (interactive "P")
-  (wl-summary-redisplay-internal nil nil arg
-                                wl-summary-buffer-display-as-is))
+  (let ((rest (memq wl-summary-buffer-display-mime-mode
+                   wl-summary-display-mime-mode-list))
+       (elmo-mime-display-as-is-coding-system
+        elmo-mime-display-as-is-coding-system))
+    (if (numberp arg)
+       (setq wl-summary-buffer-display-mime-mode
+             (case arg
+               (1 'mime)
+               (2 'header-only)
+               (3 'as-is)))
+      (if arg
+         ;; Specify coding-system (doesn't change the MIME mode).
+         (setq elmo-mime-display-as-is-coding-system
+               (if (and arg (not (eq wl-summary-buffer-display-mime-mode
+                                     'mime)))
+                   (or (read-coding-system "Coding system: ")
+                       elmo-mime-display-as-is-coding-system)
+                 elmo-mime-display-as-is-coding-system))
+       ;; Change the MIME mode.
+       (if (cadr rest)
+           (setq wl-summary-buffer-display-mime-mode (cadr rest))
+         (setq wl-summary-buffer-display-mime-mode
+               (car wl-summary-display-mime-mode-list)))))
+    (wl-summary-redisplay arg)
+    (wl-summary-update-modeline)
+    (message "MIME decoding: %s%s"
+            (upcase (symbol-name wl-summary-buffer-display-mime-mode))
+            (if (and arg
+                     (not (numberp arg))
+                     (not (eq wl-summary-buffer-display-mime-mode
+                              'mime)))
+                (concat " ("
+                        (symbol-name elmo-mime-display-as-is-coding-system)
+                        ")")
+              ""))))
 
-(defun wl-summary-redisplay-all-header (&optional arg)
-  "Redisplay message with all header."
+(defun wl-summary-redisplay (&optional arg)
+  "Redisplay message."
   (interactive "P")
-  (wl-summary-redisplay-internal nil nil arg
-                                wl-summary-buffer-display-as-is 'all-header))
+  (wl-summary-redisplay-internal nil nil arg))
 
-(defun wl-summary-redisplay-no-mime (&optional ask-coding)
-  "Display message without MIME decoding.
-If ASK-CODING is non-nil, coding-system for the message is asked."
+(defun wl-summary-toggle-all-header (&optional arg)
+  "Toggle displaying message with all header."
   (interactive "P")
-  (let ((elmo-mime-display-as-is-coding-system
-        (if ask-coding
-            (or (read-coding-system "Coding system: ")
-                elmo-mime-display-as-is-coding-system)
-          elmo-mime-display-as-is-coding-system)))
-    (wl-summary-redisplay-internal nil nil nil t 'all-header)))
+  (setq wl-summary-buffer-display-all-header
+       (not wl-summary-buffer-display-all-header))
+  (wl-summary-redisplay-internal nil nil arg))
 
 (defun wl-summary-redisplay-internal (&optional folder number force-reload
-                                               as-is all-header)
+                                               mode all-header)
   (let* ((folder (or folder wl-summary-buffer-elmo-folder))
+        (mode (or mode wl-summary-buffer-display-mime-mode))
+        (all-header (or all-header wl-summary-buffer-display-all-header))
         (num (or number (wl-summary-message-number)))
         (wl-mime-charset      wl-summary-buffer-mime-charset)
         (default-mime-charset wl-summary-buffer-mime-charset)
@@ -4403,7 +4447,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
          (setq no-folder-mark
                ;; If cache is used, change folder-mark.
                (if (wl-message-redisplay folder num
-                                         as-is all-header
+                                         mode all-header
                                          (or
                                           force-reload
                                           (string= (elmo-folder-name-internal
@@ -4650,7 +4694,6 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
              wl-break-pages)
          (save-excursion
            (wl-summary-set-message-buffer-or-redisplay)
-           ;; (wl-summary-redisplay-internal)
            (let* ((buffer (generate-new-buffer " *print*"))
                   (entity (progn
                             (set-buffer summary-buffer)
@@ -4688,14 +4731,13 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
 
 (defun wl-summary-target-mark-print ()
   (interactive)
-  (if (null wl-summary-buffer-target-mark-list)
-      (message "No marked message.")
-    (when (y-or-n-p "Print all marked messages. OK? ")
-      (while (car wl-summary-buffer-target-mark-list)
-       (let ((num (car wl-summary-buffer-target-mark-list)))
-         (wl-thread-jump-to-msg num)
-         (wl-summary-print-message)
-         (wl-summary-unmark))))))
+  (wl-summary-check-target-mark)
+  (when (y-or-n-p "Print all marked messages. OK? ")
+    (while (car wl-summary-buffer-target-mark-list)
+      (let ((num (car wl-summary-buffer-target-mark-list)))
+       (wl-thread-jump-to-msg num)
+       (wl-summary-print-message)
+       (wl-summary-unmark)))))
 
 (defun wl-summary-folder-info-update ()
   (wl-folder-set-folder-updated
@@ -4719,6 +4761,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
 
 (defun wl-summary-target-mark-uudecode ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((mlist (reverse wl-summary-buffer-target-mark-list))
        (summary-buf (current-buffer))
        (tmp-buf (get-buffer-create "*WL UUENCODE*"))