X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo-msgdb.el;h=3cdf7b2f2b904262d04f9c42d3975744b8f4e66b;hb=63ea8dd728fab75ceafe73274909e3da6e96a41a;hp=ab844ab6eac1063ea20bd100279cdf566dbcb48b;hpb=b12b74dbbc703878cd2f611c723c9a8044e6e54e;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo-msgdb.el b/elmo/elmo-msgdb.el index ab844ab..3cdf7b2 100644 --- a/elmo/elmo-msgdb.el +++ b/elmo/elmo-msgdb.el @@ -38,42 +38,6 @@ (require 'std11) (require 'mime) -(defcustom elmo-msgdb-new-mark "N" - "Mark for new message." - :type '(string :tag "Mark") - :group 'elmo) - -(defcustom elmo-msgdb-unread-uncached-mark "U" - "Mark for unread and uncached message." - :type '(string :tag "Mark") - :group 'elmo) - -(defcustom elmo-msgdb-unread-cached-mark "!" - "Mark for unread but already cached message." - :type '(string :tag "Mark") - :group 'elmo) - -(defcustom elmo-msgdb-read-uncached-mark "u" - "Mark for read but uncached message." - :type '(string :tag "Mark") - :group 'elmo) - -;; Not implemented yet. -(defcustom elmo-msgdb-answered-cached-mark "&" - "Mark for answered and cached message." - :type '(string :tag "Mark") - :group 'elmo) - -(defcustom elmo-msgdb-answered-uncached-mark "A" - "Mark for answered but cached message." - :type '(string :tag "Mark") - :group 'elmo) - -(defcustom elmo-msgdb-important-mark"$" - "Mark for important message." - :type '(string :tag "Mark") - :group 'elmo) - ;;; MSGDB interface. (defun elmo-load-msgdb (path) "Load the MSGDB from PATH." @@ -96,182 +60,25 @@ (defsubst elmo-msgdb-set-mark (msgdb number mark) "Set MARK of the message with NUMBER in the MSGDB. if MARK is nil, mark is removed." - (let ((elem (elmo-get-hash-val (format "#%d" number) - (elmo-msgdb-get-mark-hashtb msgdb)))) - (if elem - (if mark - ;; Set mark of the elem - (setcar (cdr elem) mark) - ;; Delete elem from mark-alist - (elmo-msgdb-set-mark-alist - msgdb - (delq elem (elmo-msgdb-get-mark-alist msgdb))) - (elmo-clear-hash-val (format "#%d" number) - (elmo-msgdb-get-mark-hashtb msgdb))) - (when mark - ;; Append new element. - (elmo-msgdb-set-mark-alist - msgdb - (nconc - (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)))) - ;; return value. - t)) - -(defun elmo-msgdb-set-cached (msgdb number cached) - "Set message cache status. -If mark is changed, return non-nil." - (let* ((cur-mark (elmo-msgdb-get-mark msgdb 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))))) - (unless (eq cached cur-cached) - (case cur-status - (read - (elmo-msgdb-set-mark msgdb number - (unless cached - elmo-msgdb-read-uncached-mark))) - (important nil) - (answered - (elmo-msgdb-set-mark msgdb number - (if cached - elmo-msgdb-answered-cached-mark - elmo-msgdb-answered-uncached-mark))) - (t - (elmo-msgdb-set-mark msgdb number - (if cached - elmo-msgdb-unread-cached-mark - elmo-msgdb-unread-uncached-mark))))))) - -(defun elmo-msgdb-set-status (msgdb folder number status) - "Set message status. -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: -`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)))) - mark-modified) - (case status - (read - (case cur-status - ((read important answered)) - (t (elmo-msgdb-set-mark msgdb number - (if (and use-cache (not cur-cached)) - elmo-msgdb-read-uncached-mark)) - (setq mark-modified t)))) - (important - (unless (eq cur-status '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)) - (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-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. -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: -`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)))) - mark-modified) - (case status - (read - (when (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)) - (setq mark-modified t))) - (important - (when (eq cur-status 'important) - (elmo-msgdb-set-mark msgdb number nil) - (setq mark-modified t))) - (answered - (when (eq cur-status 'answered) - (elmo-msgdb-set-mark msgdb number - (if (and cur-cached (not use-cache)) - 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 () - "Return an unread mark list" - (or elmo-msgdb-unread-marks-internal - (setq elmo-msgdb-unread-marks-internal - (list elmo-msgdb-new-mark - elmo-msgdb-unread-uncached-mark - elmo-msgdb-unread-cached-mark)))) - -(defvar elmo-msgdb-answered-marks-internal nil) -(defsubst elmo-msgdb-answered-marks () - "Return an answered mark list" - (or elmo-msgdb-answered-marks-internal - (setq elmo-msgdb-answered-marks-internal - (list elmo-msgdb-answered-cached-mark - elmo-msgdb-answered-uncached-mark)))) - -(defvar elmo-msgdb-uncached-marks-internal nil) -(defsubst elmo-msgdb-uncached-marks () - (or elmo-msgdb-uncached-marks-internal - (setq elmo-msgdb-uncached-marks-internal - (list elmo-msgdb-new-mark - elmo-msgdb-answered-uncached-mark - elmo-msgdb-unread-uncached-mark - elmo-msgdb-read-uncached-mark)))) - -(defsubst elmo-msgdb-count-marks (msgdb) + (elmo-msgdb-set-mark-alist + msgdb + (elmo-msgdb-mark-alist-set (elmo-msgdb-get-mark-alist msgdb) + number + mark msgdb)) + (unless mark + (elmo-clear-hash-val (format "#%d" number) + (elmo-msgdb-get-mark-hashtb msgdb)))) + +(defsubst elmo-msgdb-count-marks (msgdb new-mark unread-marks) (let ((new 0) - (unreads 0) - (answered 0)) + (unreads 0)) (dolist (elem (elmo-msgdb-get-mark-alist msgdb)) (cond - ((string= (cadr elem) elmo-msgdb-new-mark) + ((string= (cadr elem) new-mark) (incf new)) - ((member (cadr elem) (elmo-msgdb-unread-marks)) - (incf unreads)) - ((member (cadr elem) (elmo-msgdb-answered-marks)) - (incf answered)))) - (list new unreads answered))) + ((member (cadr elem) unread-marks) + (incf unreads)))) + (cons new unreads))) (defsubst elmo-msgdb-get-number (msgdb message-id) "Get number of the message which corrensponds to MESSAGE-ID from MSGDB." @@ -402,57 +209,32 @@ content of MSGDB is changed." ret-val)) ;;; -;; parsistent mark handling -;; (for global!) - -(defvar elmo-msgdb-global-mark-alist nil) - -(defun elmo-msgdb-global-mark-delete (msgid) - (let* ((path (expand-file-name - elmo-msgdb-global-mark-filename - elmo-msgdb-directory)) - (malist (or elmo-msgdb-global-mark-alist - (setq elmo-msgdb-global-mark-alist - (elmo-object-load path)))) - match) - (when (setq match (assoc msgid malist)) - (setq elmo-msgdb-global-mark-alist - (delete match elmo-msgdb-global-mark-alist)) - (elmo-object-save path elmo-msgdb-global-mark-alist)))) - -(defun elmo-msgdb-global-mark-set (msgid mark) - (let* ((path (expand-file-name - elmo-msgdb-global-mark-filename - elmo-msgdb-directory)) - (malist (or elmo-msgdb-global-mark-alist - (setq elmo-msgdb-global-mark-alist - (elmo-object-load path)))) - match) - (if (setq match (assoc msgid malist)) - (setcdr match mark) - (setq elmo-msgdb-global-mark-alist - (nconc elmo-msgdb-global-mark-alist - (list (cons msgid mark))))) - (elmo-object-save path elmo-msgdb-global-mark-alist))) - -(defun elmo-msgdb-global-mark-get (msgid) - (cdr (assoc msgid (or elmo-msgdb-global-mark-alist - (setq elmo-msgdb-global-mark-alist - (elmo-object-load - (expand-file-name - elmo-msgdb-global-mark-filename - elmo-msgdb-directory))))))) - -;;; ;; persistent mark handling ;; (for each folder) +(defun elmo-msgdb-mark-alist-set (alist id mark msgdb) + (let ((ret-val alist) + entity) + (setq entity (assq id alist)) + (if entity + (if (eq mark nil) + ;; delete this entity + (setq ret-val (delq entity alist)) + ;; set mark + (setcar (cdr entity) mark)) + (when mark + (setq ret-val (elmo-msgdb-append-element ret-val + (setq entity + (list id mark)))) + (elmo-set-hash-val (format "#%d" id) entity + (elmo-msgdb-get-mark-hashtb msgdb)))) + ret-val)) (defun elmo-msgdb-mark-append (alist id mark) "Append mark." (setq alist (elmo-msgdb-append-element alist (list id mark)))) -(defun elmo-msgdb-seen-list (msgdb) +(defun elmo-msgdb-seen-list (msgdb seen-marks) "Get SEEN-MSGID-LIST from MSGDB." (let ((ov (elmo-msgdb-get-overview msgdb)) mark seen-list) @@ -460,8 +242,7 @@ content of MSGDB is changed." (if (setq mark (elmo-msgdb-get-mark msgdb (elmo-msgdb-overview-entity-get-number (car ov)))) - (if (and mark (not (member mark - (elmo-msgdb-unread-marks)))) + (if (and mark (member mark seen-marks)) (setq seen-list (cons (elmo-msgdb-overview-entity-get-id (car ov)) seen-list))) @@ -593,19 +374,6 @@ header separator." (setcar (cdr entity) after)) (setq mark-alist (cdr mark-alist))))) -(defsubst elmo-msgdb-mark (status cached) - (case status - (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) @@ -616,7 +384,7 @@ header separator." (expand-file-name elmo-msgdb-overview-filename dir) overview)) -(defun elmo-msgdb-match-condition-primitive (condition mark entity numbers) +(defun elmo-msgdb-match-condition-primitive (condition entity numbers) (catch 'unresolved (let ((key (elmo-filter-key condition)) (case-fold-search t) @@ -636,21 +404,6 @@ header separator." entity) numbers))) (string-to-int (elmo-filter-value condition))))) - ((string= key "mark") - (setq result - (cond - ((string= (elmo-filter-value condition) "any") - (not (or (null mark) - (string= mark elmo-msgdb-read-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) @@ -693,31 +446,31 @@ header separator." (not result) result)))) -(defun elmo-msgdb-match-condition-internal (condition mark entity numbers) +(defun elmo-msgdb-match-condition (condition entity numbers) (cond ((vectorp condition) - (elmo-msgdb-match-condition-primitive condition mark entity numbers)) + (elmo-msgdb-match-condition-primitive condition entity numbers)) ((eq (car condition) 'and) - (let ((lhs (elmo-msgdb-match-condition-internal (nth 1 condition) - mark entity numbers))) + (let ((lhs (elmo-msgdb-match-condition (nth 1 condition) + entity numbers))) (cond ((elmo-filter-condition-p lhs) - (let ((rhs (elmo-msgdb-match-condition-internal - (nth 2 condition) mark entity numbers))) + (let ((rhs (elmo-msgdb-match-condition (nth 2 condition) + entity numbers))) (cond ((elmo-filter-condition-p rhs) (list 'and lhs rhs)) (rhs lhs)))) (lhs - (elmo-msgdb-match-condition-internal (nth 2 condition) - mark entity numbers))))) + (elmo-msgdb-match-condition (nth 2 condition) + entity numbers))))) ((eq (car condition) 'or) - (let ((lhs (elmo-msgdb-match-condition-internal (nth 1 condition) - mark entity numbers))) + (let ((lhs (elmo-msgdb-match-condition (nth 1 condition) + entity numbers))) (cond ((elmo-filter-condition-p lhs) - (let ((rhs (elmo-msgdb-match-condition-internal (nth 2 condition) - mark entity numbers))) + (let ((rhs (elmo-msgdb-match-condition (nth 2 condition) + entity numbers))) (cond ((elmo-filter-condition-p rhs) (list 'or lhs rhs)) (rhs @@ -727,22 +480,8 @@ header separator." (lhs t) (t - (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))) + (elmo-msgdb-match-condition (nth 2 condition) + entity numbers))))))) (defsubst elmo-msgdb-set-overview (msgdb overview) (setcar msgdb overview)) @@ -968,12 +707,12 @@ Return CONDITION itself if no entity exists in msgdb." elmo-msgdb-directory) alist)) -(defun elmo-msgdb-add-msgs-to-seen-list (msgs msgdb seen-list) +(defun elmo-msgdb-add-msgs-to-seen-list (msgs msgdb unread-marks seen-list) ;; Add to seen list. (let (mark) (while msgs (if (setq mark (elmo-msgdb-get-mark msgdb (car msgs))) - (unless (member mark (elmo-msgdb-unread-marks)) ;; not unread mark + (unless (member mark unread-marks) ;; not unread mark (setq seen-list (cons (elmo-msgdb-get-field msgdb (car msgs) 'message-id) @@ -987,12 +726,16 @@ Return CONDITION itself if no entity exists in msgdb." 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.