1 ;;; wl-action.el --- Mark and actions in the Summary mode for Wanderlust.
3 ;; Copyright (C) 2003 Yuuichi Teranishi <teranisi@gohome.org>
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
8 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
34 (defsubst wl-summary-action-mark (action)
36 (defsubst wl-summary-action-symbol (action)
38 (defsubst wl-summary-action-argument-function (action)
40 (defsubst wl-summary-action-set-function (action)
42 (defsubst wl-summary-action-exec-function (action)
44 (defsubst wl-summary-action-face (action)
46 (defsubst wl-summary-action-docstring (action)
50 (defun wl-summary-set-mark (&optional set-mark number interactive data)
52 "Set temporary mark SET-MARK on the message with NUMBER.
53 NUMBER is the message number to set the mark on.
54 INTERACTIVE is set as t if it have to run interactively.
55 DATA is passed to the set-action function of the action as an argument.
56 Return number if put mark succeed"
57 (let* ((set-mark (or set-mark
58 (completing-read "Mark: " wl-summary-mark-action-list)))
59 (current (wl-summary-message-number))
60 (action (assoc set-mark wl-summary-mark-action-list))
61 visible mark cur-mark)
65 ;; not-interactive and visible
66 (and number (wl-summary-jump-to-msg number))
68 (and (null number) current))
69 number (or number current))
70 (when (and interactive
72 (wl-summary-action-argument-function action))
73 (setq data (funcall (wl-summary-action-argument-function action)
74 (wl-summary-action-symbol action)
76 (when (setq cur-mark (nth 1 (wl-summary-registered-temp-mark number)))
77 (when (and (wl-summary-reserve-temp-mark-p cur-mark)
79 (error "Already marked as `%s'" cur-mark)))
80 (wl-summary-unset-mark number)
82 (wl-summary-mark-line set-mark)
83 (when wl-summary-highlight
84 (wl-highlight-summary-current-line))
86 (wl-summary-print-destination number data)))
88 (funcall (wl-summary-action-set-function action)
90 (wl-summary-action-mark action)
92 (set-buffer-modified-p nil))
94 (if (or interactive (interactive-p))
95 (if (eq wl-summary-move-direction-downward nil)
101 (defun wl-summary-register-target-mark (number mark data)
102 (or (memq number wl-summary-buffer-target-mark-list)
103 (setq wl-summary-buffer-target-mark-list
104 (cons number wl-summary-buffer-target-mark-list))))
106 (defun wl-summary-unregister-target-mark (number)
107 (delq number wl-summary-buffer-target-mark-list))
109 (defun wl-summary-have-target-mark-p (number)
110 (memq number wl-summary-buffer-target-mark-list))
112 (defun wl-summary-target-mark-set-action (action)
113 (unless (eq (wl-summary-action-symbol action) 'target-mark)
115 (goto-char (point-min))
116 (let ((numlist wl-summary-buffer-number-list)
118 ;; use firstly marked message.
119 (when (wl-summary-action-argument-function action)
121 (if (memq (car numlist) wl-summary-buffer-target-mark-list)
122 (setq number (car numlist)
124 (setq numlist (cdr numlist)))
125 (wl-summary-jump-to-msg number)
126 (setq data (funcall (wl-summary-action-argument-function action)
127 (wl-summary-action-symbol action) number)))
129 (when (string= (wl-summary-temp-mark) "*")
130 (let (wl-summary-buffer-disp-msg)
131 (when (setq number (wl-summary-message-number))
132 (wl-summary-set-mark (wl-summary-action-mark action)
134 (setq wl-summary-buffer-target-mark-list
135 (delq number wl-summary-buffer-target-mark-list)))))
137 (setq mlist wl-summary-buffer-target-mark-list)
139 (wl-summary-register-temp-mark (car mlist)
140 (wl-summary-action-mark action) data)
141 (setq wl-summary-buffer-target-mark-list
142 (delq (car mlist) wl-summary-buffer-target-mark-list))
143 (setq mlist (cdr mlist)))))))
145 ;; wl-summary-buffer-temp-mark-list specification
146 ;; ((1 "D" nil)(2 "o" "+fuga")(3 "O" "+hoge"))
147 (defun wl-summary-register-temp-mark (number mark mark-info)
148 (let ((elem (assq number wl-summary-buffer-temp-mark-list)))
149 (setq wl-summary-buffer-temp-mark-list
150 (delq elem wl-summary-buffer-temp-mark-list)))
151 (setq wl-summary-buffer-temp-mark-list
152 (cons (list number mark mark-info) wl-summary-buffer-temp-mark-list)))
154 (defun wl-summary-unregister-temp-mark (number)
155 (let ((elem (assq number wl-summary-buffer-temp-mark-list)))
156 (setq wl-summary-buffer-temp-mark-list
157 (delq elem wl-summary-buffer-temp-mark-list))))
159 (defun wl-summary-registered-temp-mark (number)
160 (assq number wl-summary-buffer-temp-mark-list))
162 (defun wl-summary-collect-temp-mark (mark &optional begin end)
167 (narrow-to-region (or begin (point-min))(or end (point-max)))
168 (goto-char (point-min))
170 (if (eq wl-summary-buffer-view 'thread)
171 (let (number entity mark-info)
173 (setq number (wl-summary-message-number)
174 entity (wl-thread-get-entity number)
175 mark-info (wl-summary-registered-temp-mark number))
176 ;; toplevel message mark.
177 (when (string= (nth 1 mark-info) mark)
178 (setq mark-list (cons mark-info mark-list)))
179 ;; When thread is closed...children should also be checked.
180 (unless (wl-thread-entity-get-opened entity)
181 (dolist (msg (wl-thread-get-children-msgs number))
182 (setq mark-info (wl-summary-registered-temp-mark
184 (when (string= (nth 1 mark-info) mark)
185 (setq mark-list (cons mark-info mark-list)))))
187 (let (number mark-info)
189 (setq number (wl-summary-message-number)
190 mark-info (wl-summary-registered-temp-mark number))
191 (when (string= (nth 1 mark-info) mark)
192 (setq mark-list (cons mark-info mark-list)))
196 (dolist (mark-info wl-summary-buffer-temp-mark-list)
197 (when (string= (nth 1 mark-info) mark)
198 (setq mark-list (cons mark-info mark-list))))
202 (defun wl-summary-unset-mark (&optional number interactive)
203 "Unset temporary mark of the message with NUMBER.
204 NUMBER is the message number to unset the mark.
205 If not specified, the message on the cursor position is treated.
206 Optional INTERACTIVE is non-nil when it should be called interactively.
207 Return number if put mark succeed"
211 (let ((buffer-read-only nil)
214 (setq visible (wl-summary-jump-to-msg number))
216 (setq number (or number (wl-summary-message-number)))
217 ;; Delete mark on buffer.
219 (setq mark (wl-summary-temp-mark))
220 (unless (string= mark " ")
221 (delete-backward-char 1)
222 (insert (or (wl-summary-get-score-mark number)
224 (setq action (assoc mark wl-summary-mark-action-list))
225 (when wl-summary-highlight
226 (wl-highlight-summary-current-line))
227 (when (wl-summary-action-argument-function action)
228 (wl-summary-remove-destination)))
229 (set-buffer-modified-p nil))
230 ;; Remove from temporal mark structure.
231 (wl-summary-unregister-target-mark number)
232 (wl-summary-unregister-temp-mark number)))
234 ;; (if (or interactive (interactive-p))
235 ;; (if (eq wl-summary-move-direction-downward nil)
237 ;; (wl-summary-next))))
240 (defun wl-summary-make-destination-numbers-list (mark-list)
241 (let (dest-numbers dest-number)
242 (dolist (elem mark-list)
243 (setq dest-number (assoc (nth 2 elem) dest-numbers))
245 (unless (memq (car elem) (cdr dest-number))
246 (nconc dest-number (list (car elem))))
247 (setq dest-numbers (nconc dest-numbers
253 (defun wl-summary-move-mark-list-messages (mark-list folder-name message)
257 (let ((start (point))
258 (refiles (mapcar 'car mark-list))
261 dst-msgs ; loop counter
264 (setq refile-len (length refiles))
265 (goto-char start) ; avoid moving cursor to
268 (when (> refile-len elmo-display-progress-threshold)
269 (elmo-progress-set 'elmo-folder-move-messages
273 (setq result (elmo-folder-move-messages
274 wl-summary-buffer-elmo-folder
276 (if (eq folder-name 'null)
278 (wl-folder-get-elmo-folder folder-name))
279 (wl-summary-buffer-msgdb)
280 (not (null (cdr dst-msgs)))
285 (when result ; succeeded.
287 (wl-summary-delete-messages-on-buffer refiles)
288 ;; update wl-summary-buffer-temp-mark-list.
289 (dolist (mark-info mark-list)
290 (setq wl-summary-buffer-temp-mark-list
291 (delq mark-info wl-summary-buffer-temp-mark-list))))
292 (elmo-progress-clear 'elmo-folder-move-messages)
293 (message (concat message "done"))
294 (wl-summary-set-message-modified)
295 ;; Return the operation failed message numbers.
298 (length refiles))))))
300 (defun wl-summary-get-refile-destination-subr (action number learn)
301 (let* ((number (or number (wl-summary-message-number)))
303 (elmo-message-field wl-summary-buffer-elmo-folder
304 number 'message-id)))
306 (elmo-message-entity wl-summary-buffer-elmo-folder
308 folder cur-mark tmp-folder)
311 (message "Cannot decide destination.")
314 (message "No message.")
316 (setq folder (wl-summary-read-folder
317 (or (wl-refile-guess entity) wl-trash-folder)
318 (format "for %s " action)))
319 ;; Cache folder hack by okada@opaopa.org
320 (when (and (eq (elmo-folder-type-internal
321 (wl-folder-get-elmo-folder
322 (wl-folder-get-realname folder))) 'cache)
326 (elmo-cache-get-path-subr
327 (elmo-msgid-to-cache msgid)))))))
328 (setq folder tmp-folder)
329 (message "Force refile to %s." folder))
330 (if (string= folder (wl-summary-buffer-folder-name))
331 (error "Same folder"))
332 (if (or (not (elmo-folder-writable-p (wl-folder-get-elmo-folder folder)))
333 (string= folder wl-queue-folder)
334 (string= folder wl-draft-folder))
335 (error "Don't set as target: %s" folder))
338 (wl-refile-learn entity folder))
342 (defun wl-summary-define-mark-action ()
344 (dolist (action wl-summary-mark-action-list)
345 (fset (intern (format "wl-summary-%s" (wl-summary-action-symbol action)))
346 `(lambda (&optional number data)
347 ,(wl-summary-action-docstring action)
349 (wl-summary-set-mark ,(wl-summary-action-mark action)
350 number (interactive-p))))
351 (fset (intern (format "wl-summary-%s-region"
352 (wl-summary-action-symbol action)))
354 ,(wl-summary-action-docstring action)
357 (wl-summary-mark-region-subr
358 (quote ,(intern (format "wl-summary-%s"
359 (wl-summary-action-symbol action))))
361 (if ,(wl-summary-action-argument-function action)
362 (funcall ,(wl-summary-action-argument-function action)
363 ,(wl-summary-action-symbol action)
364 (wl-summary-message-number))))))
365 (fset (intern (format "wl-summary-target-mark-%s"
366 (wl-summary-action-symbol action)))
368 ,(wl-summary-action-docstring action)
370 (wl-summary-target-mark-set-action (quote ,action))))
371 (fset (intern (format "wl-thread-%s"
372 (wl-summary-action-symbol action)))
374 ,(wl-summary-action-docstring action)
376 (wl-thread-call-region-func
377 (quote ,(intern (format "wl-summary-%s-region"
378 (wl-summary-action-symbol action))))
381 (wl-summary-goto-top-of-current-thread))
382 (if (not wl-summary-move-direction-downward)
384 (wl-thread-goto-bottom-of-sub-thread)
385 (if wl-summary-buffer-disp-msg
386 (wl-summary-redisplay)))))))
388 (defun wl-summary-get-dispose-folder (folder)
389 (if (string= folder wl-trash-folder)
391 (let* ((type (or (wl-get-assoc-list-value wl-dispose-folder-alist folder)
393 (cond ((stringp type)
395 ((or (equal type 'remove) (equal type 'null))
397 (t;; (equal type 'trash)
398 (let ((trash-folder (wl-folder-get-elmo-folder wl-trash-folder)))
399 (unless (elmo-folder-exists-p trash-folder)
401 (format "Trash Folder %s does not exist, create it? "
403 (elmo-folder-create trash-folder)
404 (error "Trash Folder is not created"))))
408 (defun wl-summary-exec-action-dispose (mark-list)
409 (wl-summary-move-mark-list-messages mark-list
410 (wl-summary-get-dispose-folder
411 (wl-summary-buffer-folder-name))
412 "Disposing messages..."))
415 (defun wl-summary-exec-action-delete (mark-list)
416 (wl-summary-move-mark-list-messages mark-list
418 "Deleting messages..."))
421 (defun wl-summary-set-action-refile (number mark data)
422 (let ((policy (wl-get-assoc-list-value wl-refile-policy-alist
423 (wl-summary-buffer-folder-name)))
424 (elem wl-summary-mark-action-list))
425 (if (eq policy 'copy)
427 (when (eq (wl-summary-action-symbol (car elem)) 'copy)
428 (wl-summary-register-temp-mark number
429 (wl-summary-action-mark (car elem))
432 (setq elem (cdr elem)))
433 (wl-summary-register-temp-mark number mark data)
434 (setq wl-summary-buffer-prev-refile-destination data))))
436 (defun wl-summary-get-refile-destination (action number)
437 "Decide refile destination."
438 (wl-summary-get-refile-destination-subr action number t))
440 (defun wl-summary-exec-action-refile (mark-list)
442 (let ((start (point))
444 (refile-len (length mark-list))
445 dst-msgs ; loop counter
449 (wl-summary-make-destination-numbers-list mark-list))
450 (goto-char start) ; avoid moving cursor to the bottom line.
451 (when (> refile-len elmo-display-progress-threshold)
452 (elmo-progress-set 'elmo-folder-move-messages
453 refile-len "Refiling messages..."))
457 (setq result (elmo-folder-move-messages
458 wl-summary-buffer-elmo-folder
460 (wl-folder-get-elmo-folder
461 (car (car dst-msgs)))
462 (wl-summary-buffer-msgdb)
463 (not (null (cdr dst-msgs)))
468 (if result ; succeeded.
471 (wl-summary-delete-messages-on-buffer (cdr (car dst-msgs)))
472 (setq wl-summary-buffer-temp-mark-list
473 (wl-delete-associations
475 wl-summary-buffer-temp-mark-list)))
477 (+ failures (length (cdr (car dst-msgs))))))
478 (setq dst-msgs (cdr dst-msgs)))
479 (elmo-progress-clear 'elmo-folder-move-messages)
483 (defun wl-summary-get-copy-destination (action number)
484 (wl-summary-get-refile-destination-subr action number nil))
486 (defun wl-summary-exec-action-copy (mark-list)
488 (let ((start (point))
490 (refile-len (length mark-list))
491 dst-msgs ; loop counter
495 (wl-summary-make-destination-numbers-list mark-list))
496 (goto-char start) ; avoid moving cursor to the bottom line.
497 (when (> refile-len elmo-display-progress-threshold)
498 (elmo-progress-set 'elmo-folder-move-messages
499 refile-len "Copying messages..."))
503 (setq result (elmo-folder-move-messages
504 wl-summary-buffer-elmo-folder
506 (wl-folder-get-elmo-folder
507 (car (car dst-msgs)))
508 (wl-summary-buffer-msgdb)
509 (not (null (cdr dst-msgs)))
510 t ; t is no-delete (copy)
514 (if result ; succeeded.
517 (wl-summary-delete-copy-marks-on-buffer (cdr (car dst-msgs)))
518 (setq wl-summary-buffer-temp-mark-list
519 (wl-delete-associations
521 wl-summary-buffer-temp-mark-list)))
523 (+ failures (length (cdr (car dst-msgs))))))
524 (setq dst-msgs (cdr dst-msgs)))
525 (elmo-progress-clear 'elmo-folder-move-messages)
529 (defun wl-summary-exec-action-prefetch (mark-list)
531 (let* ((buffer-read-only nil)
533 (length (length mark-list))
534 (mark-list-copy (copy-sequence mark-list))
538 (dolist (mark-info mark-list-copy)
539 (message "Prefetching...(%d/%d)"
540 (setq count (+ 1 count)) length)
541 (setq new-mark (wl-summary-prefetch-msg (car mark-info)))
544 (wl-summary-unset-mark (car mark-info))
545 (when (wl-summary-jump-to-msg (car mark-info))
546 (wl-summary-persistent-mark) ; move
547 (delete-backward-char 1)
549 (when wl-summary-highlight
550 (wl-highlight-summary-current-line))
555 (message "Prefetching...done")
559 (defun wl-summary-get-resend-address (action number)
560 "Decide resend address."
561 (wl-complete-field-to "Resend message to: "))
563 (defun wl-summary-exec-action-resend (mark-list)
565 (dolist (mark-info mark-list)
566 (if (condition-case nil
568 (wl-summary-exec-action-resend-subr (car mark-info)
572 (wl-summary-unmark (car mark-info))
576 (defun wl-summary-exec-action-resend-subr (number address)
577 "Resend the message with NUMBER to ADDRESS."
578 (message "Resending message to %s..." address)
579 (let ((folder wl-summary-buffer-elmo-folder))
581 ;; We first set up a normal mail buffer.
582 (set-buffer (get-buffer-create " *wl-draft-resend*"))
583 (buffer-disable-undo (current-buffer))
585 (setq wl-sent-message-via nil)
586 ;; Insert our usual headers.
587 (wl-draft-insert-from-field)
588 (wl-draft-insert-date-field)
589 (insert "To: " address "\n")
590 (goto-char (point-min))
591 ;; Rename them all to "Resent-*".
592 (while (re-search-forward "^[A-Za-z]" nil t)
597 (delete-region (point) (point-max))
599 ;; Insert the message to be resent.
602 (elmo-message-fetch folder number
603 (elmo-make-fetch-strategy 'entire)
604 nil (current-buffer) 'unread)
606 (goto-char (point-min))
607 (search-forward "\n\n")
610 (narrow-to-region beg (point))
611 (wl-draft-delete-fields wl-ignored-resent-headers)
612 (goto-char (point-max)))
613 (insert mail-header-separator)
614 ;; Rename all old ("Previous-")Resent headers.
615 (while (re-search-backward "^\\(Previous-\\)*Resent-" beg t)
617 (insert "Previous-"))
618 ;; Quote any "From " lines at the beginning.
620 (when (looking-at "From ")
621 (replace-match "X-From-Line: ")))
623 (wl-draft-dispatch-message)
624 (kill-buffer (current-buffer)))
625 (message "Resending message to %s...done" address)))
628 (defun wl-summary-remove-destination ()
630 (let ((inhibit-read-only t)
631 (buffer-read-only nil)
632 (buf (current-buffer))
636 (search-forward "\r")
639 (setq rs (next-single-property-change sol 'wl-summary-destination
641 (setq re (next-single-property-change rs 'wl-summary-destination
643 (put-text-property rs re 'wl-summary-destination nil)
644 (put-text-property rs re 'invisible nil)
646 (delete-char (- eol re)))))
648 (defun wl-summary-collect-numbers-region (begin end)
649 "Return a list of message number in the region specified by BEGIN and END."
653 (narrow-to-region (or begin (point-min))(or end (point-max)))
654 (goto-char (point-min))
656 (if (eq wl-summary-buffer-view 'thread)
657 (let (number entity mark-info)
659 (setq numbers (cons (wl-summary-message-number) numbers)
660 entity (wl-thread-get-entity number))
661 ;; When thread is closed...children should also be checked.
662 (unless (wl-thread-entity-get-opened entity)
663 (dolist (msg (wl-thread-get-children-msgs number))
664 (setq numbers (cons msg numbers))))
666 (let (number mark-info)
668 (setq numbers (cons (wl-summary-message-number) numbers))
672 (defun wl-summary-exec (&optional numbers)
675 collected pair action modified)
676 (dolist (action wl-summary-mark-action-list)
677 (setq collected (cons (cons
678 (wl-summary-action-mark action)
680 (dolist (mark-info wl-summary-buffer-temp-mark-list)
682 (when (memq (nth 0 mark-info) numbers)
683 (setq pair (assoc (nth 1 mark-info) collected)))
684 (setq pair (assoc (nth 1 mark-info) collected)))
685 (setq pair (assoc (nth 1 mark-info) collected))
686 (setcdr pair (cons mark-info (cdr pair))))
687 ;; collected is a pair of
688 ;; mark-string and a list of mark-info
689 (dolist (pair collected)
690 (setq action (assoc (car pair) wl-summary-mark-action-list))
691 (when (and (cdr pair) (wl-summary-action-exec-function action))
693 (setq failures (+ failures (funcall
694 (wl-summary-action-exec-function action)
697 (wl-summary-set-message-modified))
698 (run-hooks 'wl-summary-exec-hook)
699 ;; message buffer is not up-to-date
700 (unless (and wl-message-buffer
701 (eq (wl-summary-message-number)
702 (with-current-buffer wl-message-buffer
703 wl-message-buffer-cur-number)))
704 (wl-summary-toggle-disp-msg 'off)
705 (setq wl-message-buffer nil))
706 (set-buffer-modified-p nil)
708 (format "%d execution(s) were failed" failures))))
710 (defun wl-summary-exec-region (beg end)
713 (wl-summary-collect-numbers-region beg end)))
715 (defun wl-summary-read-folder (default &optional purpose ignore-error
717 (let ((fld (completing-read
718 (format "Folder name %s(%s): " (or purpose "")
720 'wl-folder-complete-folder
721 nil nil (or init wl-default-spec)
722 'wl-read-folder-hist)))
723 (if (or (string= fld wl-default-spec)
726 (setq fld (elmo-string (wl-folder-get-realname fld)))
727 (if (string-match "\n" fld)
728 (error "Not supported folder name: %s" fld))
732 (wl-folder-confirm-existence
733 (wl-folder-get-elmo-folder
736 (wl-folder-confirm-existence (wl-folder-get-elmo-folder
740 (defun wl-summary-print-destination (msg-num folder)
741 "Print refile destination on line."
742 (wl-summary-remove-destination)
744 (let ((inhibit-read-only t)
745 (folder (copy-sequence folder))
746 (buffer-read-only nil)
748 (setq len (string-width folder))
752 (search-forward "\r")
758 (setq c (+ c (char-width (following-char)))))
759 (and (> c len) (setq folder (concat " " folder)))
761 (when wl-summary-width
762 (put-text-property rs re 'invisible t))
763 (put-text-property rs re 'wl-summary-destination t)
765 (wl-highlight-refile-destination-string folder)
767 (set-buffer-modified-p nil)))))
769 (defsubst wl-summary-reserve-temp-mark-p (mark)
770 "Return t if temporal MARK should be reserved."
771 (member mark wl-summary-reserve-mark-list))
773 (defun wl-summary-refile-prev-destination ()
774 "Refile message to previously refiled destination."
776 (funcall (symbol-function 'wl-summary-refile)
777 wl-summary-buffer-prev-refile-destination
778 (wl-summary-message-number))
779 (if (eq wl-summary-move-direction-downward nil)
783 (defsubst wl-summary-no-auto-refile-message-p (msg)
784 (member (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) msg)
785 wl-summary-auto-refile-skip-marks))
787 (defun wl-summary-auto-refile (&optional open-all)
788 "Set refile mark automatically according to 'wl-refile-guess-by-rule'."
790 (message "Marking...")
792 (if (and (eq wl-summary-buffer-view 'thread)
794 (wl-thread-open-all))
795 (let* ((spec (wl-summary-buffer-folder-name))
798 number dst thr-entity)
801 (setq number (wl-summary-message-number))
802 (dolist (number (cons number
803 (and (eq wl-summary-buffer-view 'thread)
804 ;; process invisible children.
805 (not (wl-thread-entity-get-opened
807 (wl-thread-get-entity number))))
808 (wl-thread-entity-get-descendant
810 (when (and (not (wl-summary-no-auto-refile-message-p
813 (wl-folder-get-realname
814 (wl-refile-guess-by-rule
815 (elmo-msgdb-overview-get-entity
816 number (wl-summary-buffer-msgdb)))))
817 (not (equal dst spec))
818 (let ((pair (assoc dst checked-dsts))
825 (wl-folder-confirm-existence
826 (wl-folder-get-elmo-folder dst))
829 (setq checked-dsts (cons (cons dst ret) checked-dsts))
831 (if (funcall (symbol-function 'wl-summary-refile) dst number)
833 (message "Marking...%d message(s)." count)))
836 (message "No message was marked.")
837 (message "Marked %d message(s)." count)))))
839 (defun wl-summary-unmark (&optional number)
840 "Unmark marks (temporary, refile, copy, delete)of current line.
841 If optional argument NUMBER is specified, unmark message specified by NUMBER."
843 (wl-summary-unset-mark number (interactive-p)))
845 (defun wl-summary-target-mark (&optional number)
846 "Put target mark '*' on current message.
847 If optional argument NUMBER is specified, mark message specified by NUMBER."
849 (wl-summary-set-mark "*" number (interactive-p)))
851 (defun wl-summary-unmark-region (beg end)
855 (narrow-to-region beg end)
856 (goto-char (point-min))
857 (if (eq wl-summary-buffer-view 'thread)
860 (let* ((number (wl-summary-message-number))
861 (entity (wl-thread-get-entity number)))
862 (if (wl-thread-entity-get-opened entity)
863 ;; opened...unmark line.
866 (wl-summary-delete-marks-on-buffer
867 (wl-thread-get-children-msgs number))))
871 (forward-line 1))))))
873 (defun wl-summary-mark-region-subr (function beg end data)
876 (narrow-to-region beg end)
877 (goto-char (point-min))
878 (if (eq wl-summary-buffer-view 'thread)
881 (let* ((number (wl-summary-message-number))
882 (entity (wl-thread-get-entity number))
883 (wl-summary-move-direction-downward t)
885 (if (wl-thread-entity-get-opened entity)
886 ;; opened...delete line.
887 (funcall function number data)
889 (setq children (wl-thread-get-children-msgs number))
891 (funcall function (pop children) data)))
894 (funcall function (wl-summary-message-number) data)
895 (forward-line 1))))))
897 (defun wl-summary-target-mark-region (beg end)
899 (wl-summary-mark-region-subr 'wl-summary-target-mark beg end nil))
901 (defun wl-summary-target-mark-all ()
903 (wl-summary-target-mark-region (point-min) (point-max))
904 (setq wl-summary-buffer-target-mark-list
906 (elmo-msgdb-get-number-alist (wl-summary-buffer-msgdb)))))
908 (defun wl-summary-delete-all-mark (mark)
909 (goto-char (point-min))
911 (when (string= (wl-summary-temp-mark) mark)
915 (dolist (mark-info wl-summary-buffer-temp-mark-list)
916 (when (string= (nth 1 mark-info) mark)
917 (setq deleted (cons mark-info deleted))))
918 (dolist (delete deleted)
919 (setq wl-summary-buffer-temp-mark-list
920 (delq delete wl-summary-buffer-temp-mark-list)))))
922 (defun wl-summary-unmark-all ()
923 "Unmark all according to what you input."
925 (let ((unmarks (string-to-char-list (read-from-minibuffer "Unmark: ")))
929 (setq cur-mark (char-to-string (car unmarks)))
930 (wl-summary-delete-all-mark cur-mark)
931 (setq unmarks (cdr unmarks))))))
933 (defun wl-summary-target-mark-thread ()
935 (wl-thread-call-region-func 'wl-summary-target-mark-region t))
938 (product-provide (provide 'wl-action) (require 'wl-version))
940 ;;; wl-action.el ends here