X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo-msgdb.el;h=286741a78f03594731eb406be8e694834c58fc7c;hb=64eb91d7fe775e78e0f1e6555b595e40f391260a;hp=32203ea71ab55eb90ea78b9cae35104e84b3aa74;hpb=6a04c1030e0afd6d3705aed1d1d56bf41a01abe6;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo-msgdb.el b/elmo/elmo-msgdb.el index 32203ea..286741a 100644 --- a/elmo/elmo-msgdb.el +++ b/elmo/elmo-msgdb.el @@ -116,25 +116,34 @@ if MARK is nil, mark is removed." (elmo-msgdb-get-mark-alist msgdb) (list (setq elem (list number mark))))) (elmo-set-hash-val (format "#%d" number) elem - (elmo-msgdb-get-mark-hashtb msgdb)))))) + (elmo-msgdb-get-mark-hashtb msgdb)))) + ;; return value. + t)) + +(defun elmo-msgdb-get-cached (msgdb number) + "Return non-nil if message is cached." + (not (member (elmo-msgdb-get-mark msgdb number) + (elmo-msgdb-uncached-marks)))) -(defun elmo-msgdb-set-cached (msgdb number cached) - "Set message cache status." +(defun elmo-msgdb-set-cached (msgdb number cached use-cache) + "Set message cache status. +If mark is changed, return non-nil." (let* ((cur-mark (elmo-msgdb-get-mark msgdb number)) - (cur-status (cond + (cur-flag (cond ((string= cur-mark elmo-msgdb-important-mark) 'important) ((member cur-mark (elmo-msgdb-answered-marks)) 'answered) ((not (member cur-mark (elmo-msgdb-unread-marks))) 'read))) - (cur-cached (not (member cur-mark (elmo-msgdb-uncached-marks))))) - (unless (eq (not cached) (not cur-cached)) - (case cur-status + (cur-cached (elmo-file-cache-exists-p + (elmo-msgdb-get-field msgdb number 'message-id)))) + (unless (eq cached cur-cached) + (case cur-flag (read (elmo-msgdb-set-mark msgdb number - (unless cached - elmo-msgdb-read-uncached-mark))) + (if (and use-cache (not cached)) + elmo-msgdb-read-uncached-mark))) (important nil) (answered (elmo-msgdb-set-mark msgdb number @@ -147,85 +156,88 @@ if MARK is nil, mark is removed." elmo-msgdb-unread-cached-mark elmo-msgdb-unread-uncached-mark))))))) -(defun elmo-msgdb-set-status (msgdb folder number status) - "Set message status. +(defun elmo-msgdb-set-flag (msgdb folder number flag) + "Set message flag. MSGDB is the ELMO msgdb. FOLDER is a ELMO folder structure. -NUMBER is a message number to be set status. -STATUS is a symbol which is one of the following: +NUMBER is a message number to set flag. +FLAG is a symbol which is one of the following: `read' ... Messages which are already read. `important' ... Messages which are marked as important. `answered' ... Messages which are marked as answered." (let* ((cur-mark (elmo-msgdb-get-mark msgdb number)) (use-cache (elmo-message-use-cache-p folder number)) - (cur-status (cond - ((string= cur-mark elmo-msgdb-important-mark) - 'important) - ((member cur-mark (elmo-msgdb-answered-marks)) - 'answered) - ((not (member cur-mark (elmo-msgdb-unread-marks))) - 'read))) - (cur-cached (not (member cur-mark (elmo-msgdb-uncached-marks)))) + (cur-flag (cond + ((string= cur-mark elmo-msgdb-important-mark) + 'important) + ((member cur-mark (elmo-msgdb-answered-marks)) + 'answered) + ((not (member cur-mark (elmo-msgdb-unread-marks))) + 'read))) + (cur-cached (elmo-file-cache-exists-p + (elmo-msgdb-get-field msgdb number 'message-id))) mark-modified) - (case status + (case flag (read - (case cur-status + (case cur-flag ((read important answered)) (t (elmo-msgdb-set-mark msgdb number - (if (and use-cache cur-cached) - (elmo-msgdb-set-mark - msgdb number - elmo-msgdb-read-uncached-mark))) + (if (and use-cache (not cur-cached)) + elmo-msgdb-read-uncached-mark)) (setq mark-modified t)))) (important - (unless (eq cur-status 'important) + (unless (eq cur-flag 'important) (elmo-msgdb-set-mark msgdb number elmo-msgdb-important-mark) (setq mark-modified t))) (answered - (unless (or (eq cur-status 'answered) (eq cur-status 'important)) + (unless (or (eq cur-flag 'answered) (eq cur-flag 'important)) (elmo-msgdb-set-mark msgdb number (if cur-cached - (if use-cache - elmo-msgdb-answered-cached-mark - elmo-msgdb-answered-uncached-mark) + elmo-msgdb-answered-cached-mark elmo-msgdb-answered-uncached-mark))) (setq mark-modified t))) (if mark-modified (elmo-folder-set-mark-modified-internal folder t)))) -(defun elmo-msgdb-unset-status (msgdb folder number status) - "Unset message status. +(defun elmo-msgdb-unset-flag (msgdb folder number flag) + "Unset message flag. MSGDB is the ELMO msgdb. FOLDER is a ELMO folder structure. -NUMBER is a message number to be set status. -STATUS is a symbol which is one of the following: +NUMBER is a message number to be set flag. +FLAG is a symbol which is one of the following: `read' ... Messages which are already read. `important' ... Messages which are marked as important. `answered' ... Messages which are marked as answered." (let* ((cur-mark (elmo-msgdb-get-mark msgdb number)) (use-cache (elmo-message-use-cache-p folder number)) - (cur-status (cond - ((string= cur-mark elmo-msgdb-important-mark) - 'important) - ((member cur-mark (elmo-msgdb-answered-marks)) - 'answered) - ((not (member cur-mark (elmo-msgdb-unread-marks))) - 'read))) - (cur-cached (not (member cur-mark (elmo-msgdb-uncached-marks))))) - (case status + (cur-flag (cond + ((string= cur-mark elmo-msgdb-important-mark) + 'important) + ((member cur-mark (elmo-msgdb-answered-marks)) + 'answered) + ((not (member cur-mark (elmo-msgdb-unread-marks))) + 'read))) + (cur-cached (elmo-file-cache-exists-p + (elmo-msgdb-get-field msgdb number 'message-id))) + mark-modified) + (case flag (read - (if (eq cur-status 'read) - (elmo-msgdb-set-mark msgdb number - (if (and cur-cached use-cache) - elmo-msgdb-unread-cached-mark - elmo-msgdb-unread-uncached-mark)))) + (when (eq cur-flag 'read) + (elmo-msgdb-set-mark msgdb number + (if cur-cached + elmo-msgdb-unread-cached-mark + elmo-msgdb-unread-uncached-mark)) + (setq mark-modified t))) (important - (if (eq cur-status 'important) - (elmo-msgdb-set-mark msgdb number nil))) + (when (eq cur-flag 'important) + (elmo-msgdb-set-mark msgdb number nil) + (setq mark-modified t))) (answered - (if (eq cur-status 'answered) - (elmo-msgdb-set-mark msgdb number - (if (and cur-cached (not use-cache)) - elmo-msgdb-read-uncached-mark))))))) + (when (eq cur-flag 'answered) + (elmo-msgdb-set-mark msgdb number + (if (and use-cache (not cur-cached)) + elmo-msgdb-read-uncached-mark)) + (setq mark-modified t)))) + (if mark-modified (elmo-folder-set-mark-modified-internal folder t)))) (defvar elmo-msgdb-unread-marks-internal nil) (defsubst elmo-msgdb-unread-marks () @@ -248,7 +260,8 @@ STATUS is a symbol which is one of the following: (defsubst elmo-msgdb-uncached-marks () (or elmo-msgdb-uncached-marks-internal (setq elmo-msgdb-uncached-marks-internal - (list elmo-msgdb-answered-uncached-mark + (list elmo-msgdb-new-mark + elmo-msgdb-answered-uncached-mark elmo-msgdb-unread-uncached-mark elmo-msgdb-read-uncached-mark)))) @@ -453,8 +466,8 @@ content of MSGDB is changed." (if (setq mark (elmo-msgdb-get-mark msgdb (elmo-msgdb-overview-entity-get-number (car ov)))) - (if (and mark (member mark (list elmo-msgdb-important-mark - elmo-msgdb-read-uncached-mark))) + (if (and mark (not (member mark + (elmo-msgdb-unread-marks)))) (setq seen-list (cons (elmo-msgdb-overview-entity-get-id (car ov)) seen-list))) @@ -586,6 +599,19 @@ header separator." (setcar (cdr entity) after)) (setq mark-alist (cdr mark-alist))))) +(defsubst elmo-msgdb-mark (flag cached) + (case flag + (unread + (if cached + elmo-msgdb-unread-cached-mark + elmo-msgdb-unread-uncached-mark)) + (important + elmo-msgdb-important-mark) + (answered + (if cached + elmo-msgdb-answered-cached-mark + elmo-msgdb-answered-uncached-mark)))) + (defsubst elmo-msgdb-seen-save (dir obj) (elmo-object-save (expand-file-name elmo-msgdb-seen-filename dir) @@ -596,7 +622,7 @@ header separator." (expand-file-name elmo-msgdb-overview-filename dir) overview)) -(defun elmo-msgdb-match-condition-primitive (condition entity numbers) +(defun elmo-msgdb-match-condition-primitive (condition mark entity numbers) (catch 'unresolved (let ((key (elmo-filter-key condition)) (case-fold-search t) @@ -616,6 +642,26 @@ header separator." entity) numbers))) (string-to-int (elmo-filter-value condition))))) + ((string= key "flag") + (setq result + (cond + ((string= (elmo-filter-value condition) "any") + (not (or (null mark) + (string= mark elmo-msgdb-read-uncached-mark)))) + ((string= (elmo-filter-value condition) "digest") + (not (or (null mark) + (string= mark elmo-msgdb-read-uncached-mark) + (string= mark elmo-msgdb-answered-cached-mark) + (string= mark elmo-msgdb-answered-uncached-mark)))) +;; (member mark (append (elmo-msgdb-answered-marks) +;; (list elmo-msgdb-important-mark) +;; (elmo-msgdb-unread-marks)))) + ((string= (elmo-filter-value condition) "unread") + (member mark (elmo-msgdb-unread-marks))) + ((string= (elmo-filter-value condition) "important") + (string= mark elmo-msgdb-important-mark)) + ((string= (elmo-filter-value condition) "answered") + (member mark (elmo-msgdb-answered-marks)))))) ((string= key "from") (setq result (string-match (elmo-filter-value condition) @@ -658,31 +704,31 @@ header separator." (not result) result)))) -(defun elmo-msgdb-match-condition (condition entity numbers) +(defun elmo-msgdb-match-condition-internal (condition mark entity numbers) (cond ((vectorp condition) - (elmo-msgdb-match-condition-primitive condition entity numbers)) + (elmo-msgdb-match-condition-primitive condition mark entity numbers)) ((eq (car condition) 'and) - (let ((lhs (elmo-msgdb-match-condition (nth 1 condition) - entity numbers))) + (let ((lhs (elmo-msgdb-match-condition-internal (nth 1 condition) + mark entity numbers))) (cond ((elmo-filter-condition-p lhs) - (let ((rhs (elmo-msgdb-match-condition (nth 2 condition) - entity numbers))) + (let ((rhs (elmo-msgdb-match-condition-internal + (nth 2 condition) mark entity numbers))) (cond ((elmo-filter-condition-p rhs) (list 'and lhs rhs)) (rhs lhs)))) (lhs - (elmo-msgdb-match-condition (nth 2 condition) - entity numbers))))) + (elmo-msgdb-match-condition-internal (nth 2 condition) + mark entity numbers))))) ((eq (car condition) 'or) - (let ((lhs (elmo-msgdb-match-condition (nth 1 condition) - entity numbers))) + (let ((lhs (elmo-msgdb-match-condition-internal (nth 1 condition) + mark entity numbers))) (cond ((elmo-filter-condition-p lhs) - (let ((rhs (elmo-msgdb-match-condition (nth 2 condition) - entity numbers))) + (let ((rhs (elmo-msgdb-match-condition-internal (nth 2 condition) + mark entity numbers))) (cond ((elmo-filter-condition-p rhs) (list 'or lhs rhs)) (rhs @@ -692,8 +738,22 @@ header separator." (lhs t) (t - (elmo-msgdb-match-condition (nth 2 condition) - entity numbers))))))) + (elmo-msgdb-match-condition-internal (nth 2 condition) + mark entity numbers))))))) + +(defun elmo-msgdb-match-condition (msgdb condition number numbers) + "Check whether the condition of the message is satisfied or not. +MSGDB is the msgdb to search from. +CONDITION is the search condition. +NUMBER is the message number to check. +NUMBERS is the target message number list. +Return CONDITION itself if no entity exists in msgdb." + (let ((entity (elmo-msgdb-overview-get-entity number msgdb))) + (if entity + (elmo-msgdb-match-condition-internal condition + (elmo-msgdb-get-mark msgdb number) + entity numbers) + condition))) (defsubst elmo-msgdb-set-overview (msgdb overview) (setcar msgdb overview)) @@ -938,12 +998,16 @@ header separator." seen-list)) (defun elmo-msgdb-get-message-id-from-buffer () - (or (elmo-field-body "message-id") + (let ((msgid (elmo-field-body "message-id"))) + (if msgid + (if (string-match "<\\(.+\\)>$" msgid) + msgid + (concat "<" msgid ">")) ; Invaild message-id. ;; no message-id, so put dummy msgid. (concat "<" (timezone-make-date-sortable (elmo-field-body "date")) (nth 1 (eword-extract-address-components - (or (elmo-field-body "from") "nobody"))) ">"))) + (or (elmo-field-body "from") "nobody"))) ">")))) (defsubst elmo-msgdb-create-overview-from-buffer (number &optional size time) "Create overview entity from current buffer. @@ -1121,6 +1185,41 @@ Return the updated INDEX." elmo-msgdb-location-filename dir) alist)) +(defun elmo-msgdb-list-flagged (msgdb flag) + (let ((case-fold-search nil) + mark-regexp matched) + (case flag + (new + (setq mark-regexp (regexp-quote elmo-msgdb-new-mark))) + (unread + (setq mark-regexp (elmo-regexp-opt (elmo-msgdb-unread-marks)))) + (answered + (setq mark-regexp (elmo-regexp-opt (elmo-msgdb-unread-marks)))) + (important + (setq mark-regexp (regexp-quote elmo-msgdb-important-mark))) + (read + (setq mark-regexp (elmo-regexp-opt (elmo-msgdb-unread-marks)))) + (digest + (setq mark-regexp (elmo-regexp-opt + (append (elmo-msgdb-unread-marks) + (list elmo-msgdb-important-mark))))) + (any + (setq mark-regexp (elmo-regexp-opt + (append + (elmo-msgdb-unread-marks) + (elmo-msgdb-answered-marks) + (list elmo-msgdb-important-mark)))))) + (when mark-regexp + (if (eq flag 'read) + (dolist (number (elmo-msgdb-get-number-alist msgdb)) + (unless (string-match mark-regexp (elmo-msgdb-get-mark + msgdb number)) + (setq matched (cons number matched)))) + (dolist (elem (elmo-msgdb-get-mark-alist msgdb)) + (if (string-match mark-regexp (cadr elem)) + (setq matched (cons (car elem) matched)))))) + matched)) + (put 'elmo-msgdb-do-each-entity 'lisp-indent-function '1) (def-edebug-spec elmo-msgdb-do-each-entity ((symbolp form &rest form) &rest form))