-(defun elmo-filter-msgdb-create (spec numlist new-mark already-mark
- seen-mark important-mark seen-list)
- (if (eq (nth 2 spec) 'partial)
- (elmo-msgdb-create (nth 2 spec)
- numlist
- new-mark
- already-mark
- seen-mark important-mark seen-list)
- (elmo-msgdb-create-as-numlist (nth 2 spec)
- numlist
- new-mark
- already-mark
- seen-mark important-mark seen-list)))
-
-(defun elmo-filter-msgdb-create-as-numlist (spec numlist new-mark already-mark
- seen-mark important-mark
- seen-list)
- (elmo-msgdb-create-as-numlist (nth 2 spec)
- numlist
- new-mark
- already-mark
- seen-mark important-mark seen-list))
-
-(defun elmo-filter-list-folders (spec &optional hierarchy)
- nil)
-
-(defun elmo-filter-append-msg (spec string &optional msg no-see)
- (elmo-call-func (nth 2 spec) "append" string))
-
-(defun elmo-filter-read-msg (spec number outbuf &optional msgdb unread)
- (elmo-call-func (nth 2 spec) "read-msg" number outbuf msgdb unread))
-
-(defun elmo-filter-delete-msgs (spec msgs)
- (elmo-call-func (nth 2 spec) "delete-msgs" msgs))
-
-(defun elmo-filter-list-folder (spec &optional nohide)
- (elmo-search (nth 2 spec) (nth 1 spec)))
-
-(defun elmo-filter-list-folder-unread (spec number-alist mark-alist
- unread-marks)
- (elmo-list-filter
- (mapcar 'car number-alist)
- (elmo-list-folder-unread
- (nth 2 spec) number-alist mark-alist unread-marks)))
+(defvar elmo-filter-number-filename "number-list"
+ "File name for message number database.")
+
+;;; ELMO filter folder
+(eval-and-compile
+ (luna-define-class elmo-filter-folder (elmo-folder)
+ (condition target require-msgdb number-list flag-count))
+ (luna-define-internal-accessors 'elmo-filter-folder))
+
+(luna-define-method elmo-folder-initialize ((folder elmo-filter-folder)
+ name)
+ (let (pair)
+ (setq pair (elmo-parse-search-condition name))
+ (elmo-filter-folder-set-condition-internal folder (car pair))
+ (if (string-match "^ */\\(.*\\)$" (cdr pair))
+ (elmo-filter-folder-set-target-internal
+ folder
+ (elmo-make-folder (elmo-match-string 1 (cdr pair))))
+ (error "Folder syntax error `%s'" (elmo-folder-name-internal folder)))
+ (elmo-filter-folder-set-require-msgdb-internal
+ folder
+ (elmo-folder-search-requires-msgdb-p
+ (elmo-filter-folder-target-internal folder)
+ (elmo-filter-folder-condition-internal folder)))
+ (elmo-filter-connect-signals
+ folder
+ (elmo-filter-folder-target-internal folder))
+ folder))
+
+(defun elmo-filter-connect-signals (folder target)
+ (elmo-connect-signal
+ target 'flag-changing folder
+ (elmo-define-signal-handler (folder target number old-flags new-flags)
+ (elmo-filter-add-flag-count folder number old-flags -1)
+ (elmo-filter-add-flag-count folder number new-flags)
+ (elmo-emit-signal 'flag-changing folder number old-flags new-flags))
+ (elmo-define-signal-filter (folder target number)
+ (memq number (elmo-folder-list-messages folder nil t))))
+ (elmo-connect-signal
+ target 'flag-changed folder
+ (elmo-define-signal-handler (folder target numbers)
+ (let ((filterd (elmo-list-filter
+ (elmo-folder-list-messages folder nil t)
+ numbers)))
+ (when filterd
+ (elmo-emit-signal 'flag-changed folder filterd)))))
+ (elmo-connect-signal
+ target 'cache-changed folder
+ (elmo-define-signal-handler (folder target number)
+ (elmo-emit-signal 'cache-changed folder number))
+ (elmo-define-signal-filter (folder target number)
+ (memq number (elmo-folder-list-messages folder nil t)))))
+
+(defun elmo-filter-number-list-load (dir)
+ (elmo-object-load
+ (expand-file-name elmo-filter-number-filename dir)))
+
+(defun elmo-filter-number-list-save (dir number-list)
+ (elmo-object-save
+ (expand-file-name elmo-filter-number-filename dir)
+ number-list))
+
+(defun elmo-filter-folder-number-list (folder)
+ (or (elmo-filter-folder-number-list-internal folder)
+ (elmo-filter-folder-set-number-list-internal
+ folder
+ (elmo-filter-number-list-load (elmo-folder-msgdb-path folder)))))
+
+(defsubst elmo-filter-folder-countup-message-flags (folder numbers
+ &optional delta)
+ (let ((flag-count (elmo-filter-folder-flag-count-internal folder))
+ (delta (or delta 1))
+ elem)
+ (dolist (number numbers)
+ (dolist (flag (elmo-message-flags folder number))
+ (if (setq elem (assq flag flag-count))
+ (setcdr elem (+ (cdr elem) delta))
+ (setq flag-count (cons (cons flag delta) flag-count)))))
+ (elmo-filter-folder-set-flag-count-internal folder flag-count)))
+
+(defun elmo-filter-add-flag-count (folder number flags &optional delta)
+ (let ((flag-count (elmo-filter-folder-flag-count-internal folder))
+ (delta (or delta 1))
+ elem)
+ (dolist (flag flags)
+ (if (setq elem (assq flag flag-count))
+ (setcdr elem (+ (cdr elem) delta))
+ (setq flag-count (cons (cons flag delta) flag-count))))
+ (elmo-filter-folder-set-flag-count-internal folder flag-count)))
+
+(defun elmo-filter-folder-flag-count (folder)
+ (or (elmo-filter-folder-flag-count-internal folder)
+ (elmo-filter-folder-countup-message-flags
+ folder
+ (elmo-folder-list-messages folder t t))))
+
+(defun elmo-filter-folder-copy-flag-count (flag-counts)
+ (mapcar (lambda (pair) (cons (car pair) (cdr pair))) flag-counts))
+
+(luna-define-method elmo-folder-open :after ((folder elmo-filter-folder)
+ &optional load-msgdb)
+ (when load-msgdb
+ (elmo-filter-folder-number-list folder)
+ (elmo-filter-folder-flag-count folder)
+ (elmo-folder-msgdb (elmo-filter-folder-target-internal folder))))
+
+(luna-define-method elmo-folder-open-internal ((folder elmo-filter-folder))
+ (elmo-folder-open-internal (elmo-filter-folder-target-internal folder)))
+
+(luna-define-method elmo-folder-check ((folder elmo-filter-folder))
+ (when (elmo-filter-folder-require-msgdb-internal folder)
+ (elmo-folder-synchronize (elmo-filter-folder-target-internal folder))))
+
+(luna-define-method elmo-folder-close-internal ((folder elmo-filter-folder))
+ (elmo-folder-close-internal (elmo-filter-folder-target-internal folder)))
+
+(luna-define-method elmo-folder-close :after ((folder elmo-filter-folder))
+ (elmo-filter-folder-set-number-list-internal folder nil)
+ (elmo-filter-folder-set-flag-count-internal folder nil)
+ (elmo-folder-set-msgdb-internal
+ (elmo-filter-folder-target-internal folder) nil))
+
+(luna-define-method elmo-folder-commit ((folder elmo-filter-folder))
+ (elmo-folder-commit (elmo-filter-folder-target-internal folder))
+ (when (elmo-folder-persistent-p folder)
+ (elmo-folder-set-info-max-by-numdb
+ folder
+ (elmo-folder-list-messages folder nil 'in-msgdb))
+ (elmo-msgdb-killed-list-save
+ (elmo-folder-msgdb-path folder)
+ (elmo-folder-killed-list-internal folder))
+ (elmo-filter-number-list-save
+ (elmo-folder-msgdb-path folder)
+ (elmo-filter-folder-number-list-internal folder))))
+
+(luna-define-method elmo-folder-expand-msgdb-path ((folder
+ elmo-filter-folder))
+ (expand-file-name
+ (elmo-replace-string-as-filename (elmo-folder-name-internal folder))
+ (expand-file-name "filter" elmo-msgdb-directory)))
+
+(luna-define-method elmo-folder-search-requires-msgdb-p ((folder
+ elmo-filter-folder)
+ condition)
+ (elmo-folder-search-requires-msgdb-p
+ (elmo-filter-folder-target-internal folder) condition))
+
+(luna-define-method elmo-folder-newsgroups ((folder elmo-filter-folder))
+ (elmo-folder-newsgroups (elmo-filter-folder-target-internal folder)))
+
+(luna-define-method elmo-find-fetch-strategy ((folder elmo-filter-folder)
+ number
+ &optional
+ ignore-cache
+ require-entireness)
+ (elmo-find-fetch-strategy
+ (elmo-filter-folder-target-internal folder)
+ number ignore-cache require-entireness))
+
+(luna-define-method elmo-folder-get-primitive-list ((folder
+ elmo-filter-folder))
+ (elmo-folder-get-primitive-list (elmo-filter-folder-target-internal folder)))
+
+(luna-define-method elmo-folder-contains-type ((folder elmo-filter-folder)
+ type)
+ (elmo-folder-contains-type
+ (elmo-filter-folder-target-internal folder)
+ type))