X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo.el;h=7a8b7815648cf6cc4e0724674d4e38bcdd129f74;hb=298179ef92e7400bdab05f509725ebfb9672b038;hp=d9fe6702d2244c1f79846e347cc6f934106f1ee0;hpb=f28225e3ae99f99be034192d6607df003b905d26;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo.el b/elmo/elmo.el index d9fe670..7a8b781 100644 --- a/elmo/elmo.el +++ b/elmo/elmo.el @@ -85,6 +85,7 @@ Otherwise, entire fetching of the message is aborted without confirmation." (autoload 'elmo-dop-queue-flush "elmo-dop") (autoload 'elmo-nntp-post "elmo-nntp") (autoload 'elmo-global-flag-p "elmo-flag") + (autoload 'elmo-local-flag-p "elmo-flag") (autoload 'elmo-global-flag-detach "elmo-flag") (autoload 'elmo-global-flag-detach-messages "elmo-flag") (autoload 'elmo-global-flag-set "elmo-flag") @@ -122,6 +123,7 @@ If a folder name begins with PREFIX, use BACKEND." persistent ; non-nil if persistent. process-duplicates ; read or hide biff ; folder for biff + handlers ; list of event handler. )) (luna-define-internal-accessors 'elmo-folder)) @@ -314,12 +316,18 @@ Otherwise, all descendent folders are returned.") "Rename FOLDER to NEW-NAME (string).") (luna-define-generic elmo-folder-delete-messages (folder numbers) - "Delete messages. + "Delete messages with msgdb entity. FOLDER is the ELMO folder structure. NUMBERS is a list of message numbers to be deleted. It is not recommended to use this function other than internal use. Use `elmo-folder-move-messages' with dst-folder 'null instead.") +(luna-define-generic elmo-folder-delete-messages-internal (folder numbers) + "Delete messages, but no delete msgdb entity. +FOLDER is the ELMO folder structure. +NUMBERS is a list of message numbers to be deleted. +Override this method by each implement of `elmo-folder'.") + (luna-define-generic elmo-folder-search (folder condition &optional numbers) "Search and return list of message numbers. FOLDER is the ELMO folder structure. @@ -382,7 +390,8 @@ FOLDER is the ELMO folder structure.") "Append current buffer as a new message. FOLDER is the destination folder (ELMO folder structure). FLAGS is the flag list for the appended message (list of symbols). -If it is nil, it is not that there is no flag and what is not defined is meant. +If FLAGS contain `read', the message is appended as `not-unread'. +If it is nil, the appended message will be treated as `new'. If optional argument NUMBER is specified, the new message number is set \(if possible\). Return nil on failure.") @@ -458,25 +467,17 @@ Return newly created temporary directory name which contains temporary files.") (luna-define-generic elmo-message-file-p (folder number) "Return t if message in the FOLDER with NUMBER is a file.") -(luna-define-generic elmo-message-flags (folder number &optional msgid) +(luna-define-generic elmo-message-flags (folder number) "Return a list of flags. FOLDER is a ELMO folder structure. -NUMBER is a number of the message. -If optional argument MSGID is specified, -the message with NUMBER checks whether it has MSGID.") +NUMBER is a number of the message.") (luna-define-method elmo-message-flag-available-p ((folder elmo-folder) number flag) (elmo-msgdb-flag-available-p (elmo-folder-msgdb folder) flag)) -(luna-define-method elmo-message-flags ((folder elmo-folder) number - &optional msgid) - (if msgid - (let ((this-id (elmo-message-field folder number 'message-id))) - (and this-id - (string= this-id msgid) - (elmo-msgdb-flags (elmo-folder-msgdb folder) number))) - (elmo-msgdb-flags (elmo-folder-msgdb folder) number))) +(luna-define-method elmo-message-flags ((folder elmo-folder) number) + (elmo-msgdb-flags (elmo-folder-msgdb folder) number)) (defsubst elmo-message-flagged-p (folder number flag) "Return non-nil if the message is set FLAG. @@ -702,16 +703,17 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-FLAG-ALIST).") (elmo-generic-folder-commit folder)) (defun elmo-generic-folder-commit (folder) - (let ((msgdb (elmo-folder-msgdb-internal folder))) - (when (and msgdb (elmo-folder-persistent-p folder)) - (when (elmo-msgdb-message-modified-p msgdb) - (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-msgdb-save msgdb)))) + (when (elmo-folder-persistent-p folder) + (let ((msgdb (elmo-folder-msgdb-internal folder))) + (when msgdb + (when (elmo-msgdb-message-modified-p msgdb) + (elmo-folder-set-info-max-by-numdb + folder + (elmo-folder-list-messages folder nil 'in-msgdb))) + (elmo-msgdb-save msgdb))) + (elmo-msgdb-killed-list-save + (elmo-folder-msgdb-path folder) + (elmo-folder-killed-list-internal folder)))) (luna-define-method elmo-folder-close-internal ((folder elmo-folder)) ;; do nothing. @@ -762,6 +764,11 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-FLAG-ALIST).") (elmo-folder-send folder 'elmo-folder-rename-internal new-folder) (elmo-msgdb-rename-path folder new-folder))) +(luna-define-method elmo-folder-delete-messages ((folder elmo-folder) + numbers) + (and (elmo-folder-delete-messages-internal folder numbers) + (elmo-folder-detach-messages folder numbers))) + (luna-define-method elmo-folder-search ((folder elmo-folder) condition &optional numbers) @@ -1057,10 +1064,13 @@ If optional argument IF-EXISTS is nil, load on demand. (> (buffer-size) 0) (elmo-folder-append-buffer folder - (elmo-message-flags - src-folder - (car numbers) - (elmo-msgdb-get-message-id-from-buffer)) + (let ((this-id (elmo-message-field src-folder (car numbers) + 'message-id))) + (and this-id + (string= this-id + (elmo-msgdb-get-message-id-from-buffer)) + (or (elmo-message-flags src-folder (car numbers)) + '(read)))) (if same-number (car numbers)))))) (error (setq failure t))) ;; FETCH & APPEND finished @@ -1099,8 +1109,7 @@ If optional argument IF-EXISTS is nil, load on demand. (elmo-folder-close dst-folder))) (if (and (not no-delete) succeeds) (progn - (if (and (elmo-folder-delete-messages src-folder succeeds) - (elmo-folder-detach-messages src-folder succeeds)) + (if (elmo-folder-delete-messages src-folder succeeds) (progn (elmo-global-flag-detach-messages src-folder succeeds (eq dst-folder 'null)) @@ -1274,7 +1283,8 @@ VALUE is a value to set.") (elmo-global-flag-set flag folder number message-id))) (elmo-msgdb-set-flag (elmo-folder-msgdb folder) number - flag)))) + flag)) + (elmo-folder-notify-event folder 'flag-changed numbers))) (defun elmo-message-has-global-flag-p (folder number) "Return non-nil when the message in the FOLDER with NUMBER has global flag." @@ -1312,7 +1322,8 @@ If Optional LOCAL is non-nil, don't update server flag." (elmo-global-flag-detach flag folder number 'always)) (elmo-msgdb-unset-flag (elmo-folder-msgdb folder) number - flag)))) + flag)) + (elmo-folder-notify-event folder 'flag-changed numbers))) (luna-define-method elmo-folder-process-crosspost ((folder elmo-folder)) ;; Do nothing. @@ -1483,48 +1494,45 @@ If update process is interrupted, return nil.") ignore-msgdb no-check mask) - (let ((killed-list (elmo-folder-killed-list-internal folder)) - (before-append t) - old-msgdb diff diff-2 delete-list new-list new-msgdb flag - flag-table crossed after-append) - (setq old-msgdb (elmo-folder-msgdb folder)) - (setq flag-table (elmo-flag-table-load (elmo-folder-msgdb-path folder))) + (let ((old-msgdb (elmo-folder-msgdb folder)) + (killed-list (elmo-folder-killed-list-internal folder)) + (flag-table (elmo-flag-table-load (elmo-folder-msgdb-path folder))) + (before-append t)) (when ignore-msgdb (elmo-msgdb-flag-table (elmo-folder-msgdb folder) flag-table) (elmo-folder-clear folder (not disable-killed))) (unless no-check (elmo-folder-check folder)) (condition-case nil - (progn + (let ((killed-list (elmo-folder-killed-list-internal folder)) + diff-new diff-del + delete-list new-list new-msgdb crossed) (message "Checking folder diff...") - (setq diff (elmo-list-diff (elmo-folder-list-messages - folder - (not disable-killed)) - (elmo-folder-list-messages - folder - (not disable-killed) - 'in-msgdb))) - (when (and mask (car diff)) - (setcar diff (elmo-list-filter mask (car diff)))) + (elmo-set-list + '(diff-new diff-del) + (elmo-list-diff (elmo-folder-list-messages folder) + (elmo-folder-list-messages folder nil 'in-msgdb))) + (when diff-new + (unless disable-killed + (setq diff-new (elmo-living-messages diff-new killed-list))) + (when mask + (setq diff-new (elmo-list-filter mask diff-new)))) (message "Checking folder diff...done") - (setq new-list (elmo-folder-confirm-appends (car diff))) - ;; Set killed list as ((1 . MAX-OF-DISAPPEARED)) - (when (and (not (eq (length (car diff)) - (length new-list))) - (setq diff-2 (elmo-list-diff (car diff) new-list))) - (elmo-folder-kill-messages-range - folder - (car (car diff-2)) - (nth (- (length (car diff-2)) 1) (car diff-2)))) - (setq delete-list (cadr diff)) - (if (or (equal diff '(nil nil)) - (equal diff '(nil)) - (and (eq (length (car diff)) 0) - (eq (length (cadr diff)) 0))) + (setq new-list (elmo-folder-confirm-appends diff-new)) + ;; Append to killed list as (MIN-OF-DISAPPEARED . MAX-OF-DISAPPEARED) + (when (not (eq (length diff-new) + (length new-list))) + (let* ((diff (elmo-list-diff diff-new new-list)) + (disappeared (car diff))) + (when disappeared + (elmo-folder-kill-messages-range folder + (car disappeared) + (elmo-last disappeared))))) + (setq delete-list diff-del) + (if (and (null diff-new) (null diff-del)) (progn (elmo-folder-update-number folder) (elmo-folder-process-crosspost folder) - 0 ; no updates. - ) + 0) ; `0' means no updates. (when delete-list (elmo-folder-detach-messages folder delete-list)) (when new-list @@ -1553,7 +1561,14 @@ If update process is interrupted, return nil.") (luna-define-method elmo-folder-detach-messages ((folder elmo-folder) numbers) - (elmo-msgdb-delete-messages (elmo-folder-msgdb folder) numbers)) + (when (elmo-msgdb-delete-messages (elmo-folder-msgdb folder) numbers) + ;; Remove NUMBERS from killed message list. + (elmo-folder-set-killed-list-internal + folder + (elmo-number-set-delete-list + (elmo-folder-killed-list-internal folder) + numbers)) + t)) (luna-define-generic elmo-folder-length (folder) "Return number of messages in the FOLDER.") @@ -1638,6 +1653,31 @@ Return a hashtable for newsgroups." (elmo-make-directory temp-dir) temp-dir)) +;; Event notification/observer framework +(eval-and-compile + (luna-define-class elmo-event-handler ())) + +(luna-define-generic elmo-event-handler-flag-changed (handler numbers) + "Notify flag of the messages with NUMBERS is changed.") + +(defun elmo-folder-add-handler (folder handler) + (unless (memq handler (elmo-folder-handlers-internal folder)) + (elmo-folder-set-handlers-internal + folder + (cons handler (elmo-folder-handlers-internal folder))))) + +(defun elmo-folder-remove-handler (folder handler) + (elmo-folder-set-handlers-internal + folder + (delq handler (elmo-folder-handlers-internal folder)))) + +(defun elmo-folder-notify-event (folder event &rest args) + (when (elmo-folder-handlers-internal folder) + (let ((message (format "elmo-event-handler-%s" event))) + (dolist (handler (elmo-folder-handlers-internal folder)) + (apply #'luna-send handler message handler args))))) + +;;; (defun elmo-init () "Initialize ELMO module." (elmo-crosspost-message-alist-load) @@ -1718,6 +1758,8 @@ Return a hashtable for newsgroups." 'elmo-cache-directory) (elmo-define-obsolete-variable 'elmo-msgdb-dir 'elmo-msgdb-directory) +(elmo-define-obsolete-variable 'elmo-global-flag-list + 'elmo-global-flags) ;; Obsolete functions. ;; 2001-12-11: *-dir -> *-directory