X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=elmo%2Felmo-msgdb.el;h=0a10cdf7829c577b913d0d5451a7ee5413213307;hb=54482fff6bd6498729682555a0ba3c3cd092a1b5;hp=17d46b42a817056a2083b321c86ef6d8ce87a31d;hpb=21f27bac7391dd60d5e54c2c4c5ef1e7b5557a54;p=elisp%2Fwanderlust.git diff --git a/elmo/elmo-msgdb.el b/elmo/elmo-msgdb.el index 17d46b4..0a10cdf 100644 --- a/elmo/elmo-msgdb.el +++ b/elmo/elmo-msgdb.el @@ -37,104 +37,23 @@ (require 'emu) (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) - -(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) +(require 'modb) ;;; MSGDB interface. ;; -;; MSGDB elmo-load-msgdb PATH -;; MARK elmo-msgdb-get-mark MSGDB NUMBER - -;; CACHED elmo-msgdb-get-cached MSGDB NUMBER -;; VOID elmo-msgdb-set-cached MSGDB NUMBER CACHED USE-CACHE -;; VOID elmo-msgdb-set-flag MSGDB FOLDER NUMBER FLAG -;; VOID elmo-msgdb-unset-flag MSGDB FOLDER NUMBER FLAG - -;; LIST-OF-NUMBERS elmo-msgdb-count-marks MSGDB -;; NUMBER elmo-msgdb-get-number MSGDB MESSAGE-ID -;; FIELD-VALUE elmo-msgdb-get-field MSGDB NUMBER FIELD -;; MSGDB elmo-msgdb-append MSGDB MSGDB-APPEND -;; MSGDB elmo-msgdb-clear MSGDB -;; elmo-msgdb-delete-messages MSGDB NUMBERS +;; MSGDB elmo-load-msgdb PATH MIME-CHARSET +;; MSGDB elmo-make-msgdb LOCATION TYPE ;; elmo-msgdb-sort-by-date MSGDB -;;; -;; LIST-OF-NUMBERS elmo-msgdb-list-messages MSGDB - ;; elmo-flag-table-load ;; elmo-flag-table-set ;; elmo-flag-table-get ;; elmo-flag-table-save -;; elmo-msgdb-append-entity MSGDB ENTITY MARK-OR-FLAGS - -;; ENTITY elmo-msgdb-make-entity ARGS -;; VALUE elmo-msgdb-entity-field ENTITY -;; - -;; OVERVIEW elmo-msgdb-get-overview MSGDB -;; NUMBER-ALIST elmo-msgdb-get-number-alist MSGDB -;; MARK-ALIST elmo-msgdb-get-mark-alist MSGDB -;; elmo-msgdb-change-mark MSGDB BEFORE AFTER - -;; (for internal use?) -;; LIST-OF-MARKS elmo-msgdb-unread-marks -;; LIST-OF-MARKS elmo-msgdb-answered-marks -;; LIST-OF-MARKS elmo-msgdb-uncached-marks ;; elmo-msgdb-overview-save DIR OBJ -;; elmo-msgdb-message-entity MSGDB KEY - ;;; Abolish -;; elmo-msgdb-overview-entity-get-references ENTITY -;; elmo-msgdb-overview-entity-set-references ENTITY ;; elmo-msgdb-get-parent-entity ENTITY MSGDB -;; elmo-msgdb-overview-enitty-get-number ENTITY -;; elmo-msgdb-overview-enitty-get-from-no-decode ENTITY -;; elmo-msgdb-overview-enitty-get-from ENTITY -;; elmo-msgdb-overview-enitty-get-subject-no-decode ENTITY -;; elmo-msgdb-overview-enitty-get-subject ENTITY -;; elmo-msgdb-overview-enitty-get-date ENTITY -;; elmo-msgdb-overview-enitty-get-to ENTITY -;; elmo-msgdb-overview-enitty-get-cc ENTITY -;; elmo-msgdb-overview-enitty-get-size ENTITY -;; elmo-msgdb-overview-enitty-get-id ENTITY -;; elmo-msgdb-overview-enitty-get-extra-field ENTITY -;; elmo-msgdb-overview-enitty-get-extra ENTITY -;; elmo-msgdb-overview-get-entity ID MSGDB ;; elmo-msgdb-killed-list-load DIR ;; elmo-msgdb-killed-list-save DIR @@ -143,6 +62,7 @@ ;; elmo-msgdb-max-of-killed KILLED-LIST ;; elmo-msgdb-killed-message-p KILLED-LIST MSG ;; elmo-living-messages MESSAGES KILLED-LIST + ;; elmo-msgdb-finfo-load ;; elmo-msgdb-finfo-save ;; elmo-msgdb-flist-load @@ -151,421 +71,113 @@ ;; elmo-crosspost-alist-load ;; elmo-crosspost-alist-save -;; elmo-msgdb-create-overview-from-buffer NUMBER SIZE TIME -;; elmo-msgdb-copy-overview-entity ENTITY -;; elmo-msgdb-create-overview-entity-from-file NUMBER FILE -;; elmo-msgdb-clear-index - ;; elmo-folder-get-info ;; elmo-folder-get-info-max ;; elmo-folder-get-info-length ;; elmo-folder-get-info-unread -;; elmo-msgdb-list-flagged MSGDB FLAG -;; (MACRO) elmo-msgdb-do-each-entity - -(defun elmo-load-msgdb (path) +;;; message entity wrappers +;; +(defsubst elmo-message-entity-number (entity) + (elmo-msgdb-message-entity-number (elmo-message-entity-handler entity) + entity)) + +(defsubst elmo-message-entity-set-number (entity number) + (elmo-msgdb-message-entity-set-number (elmo-message-entity-handler entity) + entity + number)) + +(defsubst elmo-message-entity-field (entity field &optional type) + "Get message entity field value. +ENTITY is the message entity structure obtained by `elmo-message-entity'. +FIELD is the symbol of the field name. +If optional argument TYPE is specified, return converted value." + (elmo-msgdb-message-entity-field (elmo-message-entity-handler entity) + entity field type)) + +(defsubst elmo-message-entity-set-field (entity field value) + "Set message entity field value. +ENTITY is the message entity structure. +FIELD is the symbol of the field name. +VALUE is the field value." + (elmo-msgdb-message-entity-set-field (elmo-message-entity-handler entity) + entity field value)) + +(defconst elmo-msgdb-load-priorities '(legacy standard) + "Priority list of modb type for load.") + +;;; Helper functions for MSGDB +;; +(defun elmo-load-msgdb (location mime-charset) "Load the MSGDB from PATH." - (let ((inhibit-quit t)) - (elmo-make-msgdb (elmo-msgdb-overview-load path) - (elmo-msgdb-number-load path) - (elmo-msgdb-mark-load path) - path))) - -(defun elmo-make-msgdb (&optional overview number-alist mark-alist path) - "Make a MSGDB." - (let ((msgdb (list overview number-alist mark-alist nil path))) - (elmo-msgdb-make-index msgdb) + (let ((msgdb (elmo-make-msgdb location elmo-msgdb-default-type mime-charset)) + priorities loaded temp-modb) + (unless (elmo-msgdb-load msgdb) + (setq priorities + (delq elmo-msgdb-default-type + (copy-sequence elmo-msgdb-load-priorities))) + (while (and priorities + (not loaded)) + (setq temp-modb (elmo-make-msgdb location + (car priorities) + mime-charset) + loaded (elmo-msgdb-load temp-modb) + priorities (cdr priorities))) + (when loaded + (if (eq elmo-msgdb-convert-type 'auto) + (elmo-msgdb-append msgdb temp-modb) + (setq msgdb temp-modb)))) msgdb)) -(defun elmo-msgdb-list-messages (msgdb) - "Return a list of message numbers in the MSGDB." - (mapcar 'elmo-msgdb-overview-entity-get-number - (elmo-msgdb-get-overview msgdb))) - -(defsubst elmo-msgdb-mark-to-flags (mark) - (append - (and (string= mark elmo-msgdb-new-mark) - '(new)) - (and (string= mark elmo-msgdb-important-mark) - '(important)) - (and (member mark (elmo-msgdb-unread-marks)) - '(unread)) - (and (member mark (elmo-msgdb-answered-marks)) - '(answered)) - (and (not (member mark (elmo-msgdb-uncached-marks))) - '(cached)))) - -(defsubst elmo-msgdb-flags-to-mark (flags cached use-cache) - (cond ((memq 'new flags) - elmo-msgdb-new-mark) - ((memq 'important flags) - elmo-msgdb-important-mark) - ((memq 'answered flags) - (if cached - elmo-msgdb-answered-cached-mark - elmo-msgdb-answered-uncached-mark)) - ((memq 'unread flags) - (if cached - elmo-msgdb-unread-cached-mark - elmo-msgdb-unread-uncached-mark)) - (t - (if (or cached (not use-cache)) - nil - elmo-msgdb-read-uncached-mark)))) - -(defsubst elmo-msgdb-get-mark (msgdb number) - "Get mark string from MSGDB which corresponds to the message with NUMBER." - (cadr (elmo-get-hash-val (format "#%d" number) - (elmo-msgdb-get-mark-hashtb msgdb)))) - -(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-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 use-cache) - "Set message cache status. -If mark is changed, return non-nil." - (let* ((cur-mark (elmo-msgdb-get-mark msgdb number)) - (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)))) - (unless (eq cached cur-cached) - (case cur-flag - (read - (elmo-msgdb-set-mark msgdb number - (if (and use-cache (not 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))))))) - -(defsubst elmo-msgdb-flags (msgdb number) - (elmo-msgdb-mark-to-flags (elmo-msgdb-get-mark msgdb number))) - -(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 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-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 - (case cur-flag - ((read important)) ; answered mark is overriden. - (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-flag 'important) - (elmo-msgdb-set-mark msgdb number elmo-msgdb-important-mark) - (setq mark-modified t))) - (answered - (unless (or (eq cur-flag 'answered) (eq cur-flag 'important)) - (elmo-msgdb-set-mark msgdb number - (if cur-cached - 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-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 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-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 - (when (or (eq cur-flag 'read) (eq cur-flag 'answered)) - (elmo-msgdb-set-mark msgdb number - (if cur-cached - elmo-msgdb-unread-cached-mark - elmo-msgdb-unread-uncached-mark)) - (setq mark-modified t))) - (important - (when (eq cur-flag 'important) - (elmo-msgdb-set-mark msgdb number nil) - (setq mark-modified t))) - (answered - (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 () - "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)))) - -(defun elmo-msgdb-append-entity (msgdb entity &optional mark) - (when entity - (let ((number (elmo-msgdb-overview-entity-get-number entity)) - (message-id (elmo-msgdb-overview-entity-get-id entity))) - (elmo-msgdb-set-overview - msgdb - (nconc (elmo-msgdb-get-overview msgdb) - (list entity))) - (elmo-msgdb-set-number-alist - msgdb - (nconc (elmo-msgdb-get-number-alist msgdb) - (list (cons number message-id)))) - (when mark - (elmo-msgdb-set-mark-alist - msgdb - (nconc (elmo-msgdb-get-mark-alist msgdb) - (list (list number mark))))) - (elmo-msgdb-make-index - msgdb - (list entity) - (list (list number mark)))))) - -(defsubst elmo-msgdb-get-number (msgdb message-id) - "Get number of the message which corrensponds to MESSAGE-ID from MSGDB." - (elmo-msgdb-overview-entity-get-number - (elmo-msgdb-overview-get-entity message-id msgdb))) - -(defsubst elmo-msgdb-get-field (msgdb number field) - "Get FIELD value of the message with NUMBER from MSGDB." - (case field - (message-id (elmo-msgdb-overview-entity-get-id - (elmo-msgdb-overview-get-entity - number msgdb))) - (subject (elmo-msgdb-overview-entity-get-subject - (elmo-msgdb-overview-get-entity - number msgdb))) - (size (elmo-msgdb-overview-entity-get-size - (elmo-msgdb-overview-get-entity - number msgdb))) - (date (elmo-msgdb-overview-entity-get-date - (elmo-msgdb-overview-get-entity - number msgdb))) - (to (elmo-msgdb-overview-entity-get-to - (elmo-msgdb-overview-get-entity - number msgdb))) - (cc (elmo-msgdb-overview-entity-get-cc - (elmo-msgdb-overview-get-entity - number msgdb))))) - -(defun elmo-msgdb-append (msgdb msgdb-append) - "Return a list of messages which have duplicated message-id." - (let (duplicates) - (elmo-msgdb-set-overview - msgdb - (nconc (elmo-msgdb-get-overview msgdb) - (elmo-msgdb-get-overview msgdb-append))) - (elmo-msgdb-set-number-alist - msgdb - (nconc (elmo-msgdb-get-number-alist msgdb) - (elmo-msgdb-get-number-alist msgdb-append))) - (elmo-msgdb-set-mark-alist - msgdb - (nconc (elmo-msgdb-get-mark-alist msgdb) - (elmo-msgdb-get-mark-alist msgdb-append))) - (setq duplicates (elmo-msgdb-make-index - msgdb - (elmo-msgdb-get-overview msgdb-append) - (elmo-msgdb-get-mark-alist msgdb-append))) - (elmo-msgdb-set-path - msgdb - (or (elmo-msgdb-get-path msgdb) - (elmo-msgdb-get-path msgdb-append))) - duplicates)) - -(defun elmo-msgdb-merge (folder msgdb-merge) - "Return a list of messages which have duplicated message-id." - (let (msgdb duplicates) - (setq msgdb (or (elmo-folder-msgdb-internal folder) - (elmo-make-msgdb nil nil nil - (elmo-folder-msgdb-path folder)))) - (setq duplicates (elmo-msgdb-append msgdb msgdb-merge)) - (elmo-folder-set-msgdb-internal folder msgdb) - duplicates)) - -(defsubst elmo-msgdb-clear (&optional msgdb) - (if msgdb - (progn - (elmo-msgdb-set-overview msgdb nil) - (elmo-msgdb-set-number-alist msgdb nil) - (elmo-msgdb-set-mark-alist msgdb nil) - (elmo-msgdb-set-index msgdb nil) - msgdb) - (elmo-make-msgdb))) - -(defun elmo-msgdb-delete-messages (msgdb msgs) - "Delete MSGS from MSGDB -content of MSGDB is changed." - (let* ((overview (car msgdb)) - (number-alist (cadr msgdb)) - (mark-alist (caddr msgdb)) - (index (elmo-msgdb-get-index msgdb)) - (newmsgdb (list overview number-alist mark-alist index - (nth 4 msgdb))) - ov-entity) - ;; remove from current database. - (while msgs - (setq overview - (delq - (setq ov-entity - (elmo-msgdb-overview-get-entity (car msgs) newmsgdb)) - overview)) - (setq number-alist (delq (assq (car msgs) number-alist) number-alist)) - (setq mark-alist (delq (assq (car msgs) mark-alist) mark-alist)) - ;; - (when index (elmo-msgdb-clear-index msgdb ov-entity)) - (setq msgs (cdr msgs))) - (elmo-msgdb-set-overview msgdb overview) - (elmo-msgdb-set-number-alist msgdb number-alist) - (elmo-msgdb-set-mark-alist msgdb mark-alist) - (elmo-msgdb-set-index msgdb index) - t)) ;return value - -(defun elmo-msgdb-sort-entities (msgdb predicate &optional app-data) - (message "Sorting...") - (let ((overview (elmo-msgdb-get-overview msgdb))) - (elmo-msgdb-set-overview - msgdb - (sort overview (lambda (a b) (funcall predicate a b app-data)))) - (message "Sorting...done") - msgdb)) +(defun elmo-make-msgdb (&optional location type mime-charset) + "Make a MSGDB." + (let* ((type (or type elmo-msgdb-default-type)) + (class (intern (format "modb-%s" type)))) + (require class) + (luna-make-entity class + :location location + :mime-charset mime-charset))) + +(defun elmo-msgdb-extra-fields (&optional non-virtual) + (if non-virtual + (apply + #'nconc + (mapcar + (lambda (extra) + (let ((spec (assq (intern extra) modb-entity-field-extractor-alist))) + (if spec + (let ((real-fields (nth 2 spec))) + (cond ((functionp real-fields) + (funcall real-fields extra)) + ((listp real-fields) + (copy-sequence real-fields)))) + (list extra)))) + elmo-msgdb-extra-fields)) + elmo-msgdb-extra-fields)) (defun elmo-msgdb-sort-by-date (msgdb) (elmo-msgdb-sort-entities msgdb (lambda (x y app-data) (condition-case nil - (string< - (timezone-make-date-sortable - (elmo-msgdb-overview-entity-get-date x)) - (timezone-make-date-sortable - (elmo-msgdb-overview-entity-get-date y))) + (elmo-time< + (elmo-message-entity-field x 'date) + (elmo-message-entity-field y 'date)) (error))))) +(defsubst elmo-msgdb-get-parent-entity (entity msgdb) + (setq entity (elmo-message-entity-field entity 'references)) + ;; entity is parent-id. + (and entity (elmo-msgdb-message-entity msgdb entity))) + ;;; (defsubst elmo-msgdb-append-element (list element) (if list -;;; (append list (list element)) +;;; (append list (list element)) (nconc list (list element)) ;; list is nil (list element))) -(defsubst elmo-msgdb-get-overview (msgdb) - (car msgdb)) -(defsubst elmo-msgdb-get-number-alist (msgdb) - (cadr msgdb)) -(defsubst elmo-msgdb-get-mark-alist (msgdb) - (caddr msgdb)) -;(defsubst elmo-msgdb-get-location (msgdb) -; (cadddr msgdb)) - -(defsubst elmo-msgdb-get-index (msgdb) - (nth 3 msgdb)) - -(defsubst elmo-msgdb-get-entity-hashtb (msgdb) - (car (nth 3 msgdb))) - -(defsubst elmo-msgdb-get-mark-hashtb (msgdb) - (cdr (nth 3 msgdb))) - -(defsubst elmo-msgdb-get-path (msgdb) - (nth 4 msgdb)) - ;; ;; number <-> Message-ID handling ;; @@ -583,22 +195,38 @@ content of MSGDB is changed." (let ((table (elmo-make-hash)) ;; For backward compatibility (seen-file (expand-file-name elmo-msgdb-seen-filename dir)) - seen-list) + value) (when (file-exists-p seen-file) - (setq seen-list (elmo-object-load seen-file)) + (dolist (msgid (elmo-object-load seen-file)) + (elmo-set-hash-val msgid '(read) table)) (delete-file seen-file)) - (dolist (msgid seen-list) - (elmo-set-hash-val msgid 'read table)) (dolist (pair (elmo-object-load (expand-file-name elmo-flag-table-filename dir))) - (elmo-set-hash-val (car pair) (cdr pair) table)) + (setq value (cdr pair)) + (elmo-set-hash-val (car pair) + (cond ((consp value) + value) + ;; Following cases for backward compatibility. + (value + (list value)) + (t + '(unread))) + table)) table)) -(defun elmo-flag-table-set (flag-table msg-id flag) - (elmo-set-hash-val msg-id flag flag-table)) +(defun elmo-flag-table-set (flag-table msg-id flags) + (elmo-set-hash-val msg-id (or flags '(read)) flag-table)) (defun elmo-flag-table-get (flag-table msg-id) - (elmo-get-hash-val msg-id flag-table)) + (let ((flags (elmo-get-hash-val msg-id flag-table))) + (append + (and (elmo-file-cache-exists-p msg-id) + '(cached)) + (if flags + (elmo-list-delete '(cached read) + (copy-sequence flags) + #'delq) + '(new unread))))) (defun elmo-flag-table-save (dir flag-table) (elmo-object-save @@ -620,75 +248,18 @@ content of MSGDB is changed." (setq alist (elmo-msgdb-append-element alist (list id mark)))) -(defsubst elmo-msgdb-length (msgdb) - (length (elmo-msgdb-get-overview msgdb))) - (defun elmo-msgdb-flag-table (msgdb &optional flag-table) ;; Make a table of msgid flag (read, answered) - (let ((flag-table (or flag-table (elmo-make-hash (elmo-msgdb-length msgdb)))) - mark) - (dolist (ov (elmo-msgdb-get-overview msgdb)) - (setq mark (elmo-msgdb-get-mark - msgdb - (elmo-msgdb-overview-entity-get-number ov))) - (cond - ((null mark) - (elmo-set-hash-val - (elmo-msgdb-overview-entity-get-id ov) - 'read - flag-table)) - ((and mark (member mark (elmo-msgdb-answered-marks))) - (elmo-set-hash-val - (elmo-msgdb-overview-entity-get-id ov) - 'answered - flag-table)) - ((and mark (not (member mark - (elmo-msgdb-unread-marks)))) - (elmo-set-hash-val - (elmo-msgdb-overview-entity-get-id ov) - 'read - flag-table)))) + (let ((flag-table (or flag-table + (elmo-make-hash (elmo-msgdb-length msgdb)))) + msg-id) + (dolist (number (elmo-msgdb-list-messages msgdb)) + (when (setq msg-id (elmo-msgdb-message-field msgdb number 'message-id)) + (elmo-flag-table-set flag-table + msg-id + (elmo-msgdb-flags msgdb number)))) flag-table)) -;; -;; mime decode cache - -(defvar elmo-msgdb-decoded-cache-hashtb nil) -(make-variable-buffer-local 'elmo-msgdb-decoded-cache-hashtb) - -(defsubst elmo-msgdb-get-decoded-cache (string) - (if elmo-use-decoded-cache - (let ((hashtb (or elmo-msgdb-decoded-cache-hashtb - (setq elmo-msgdb-decoded-cache-hashtb - (elmo-make-hash 2048)))) - decoded) - (or (elmo-get-hash-val string hashtb) - (progn - (elmo-set-hash-val - string - (setq decoded - (decode-mime-charset-string string elmo-mime-charset)) - hashtb) - decoded))) - (decode-mime-charset-string string elmo-mime-charset))) - -;; -;; overview handling -;; -(defun elmo-multiple-field-body (name &optional boundary) - (save-excursion - (save-restriction - (std11-narrow-to-header boundary) - (goto-char (point-min)) - (let ((case-fold-search t) - (field-body nil)) - (while (re-search-forward (concat "^" name ":[ \t]*") nil t) - (setq field-body - (nconc field-body - (list (buffer-substring-no-properties - (match-end 0) (std11-field-end)))))) - field-body)))) - (defun elmo-multiple-fields-body-list (field-names &optional boundary) "Return list of each field-bodies of FIELD-NAMES of the message header in current buffer. If BOUNDARY is not nil, it is used as message @@ -714,398 +285,14 @@ header separator." (substring string (match-end 0)) string)) -(defsubst elmo-msgdb-get-last-message-id (string) - (if string - (save-match-data - (let (beg) - (elmo-set-work-buf - (insert string) - (goto-char (point-max)) - (when (search-backward "<" nil t) - (setq beg (point)) - (if (search-forward ">" nil t) - (elmo-replace-in-string - (buffer-substring beg (point)) "\n[ \t]*" "")))))))) - -(defun elmo-msgdb-number-load (dir) - (elmo-object-load - (expand-file-name elmo-msgdb-number-filename dir))) - -(defun elmo-msgdb-overview-load (dir) - (elmo-object-load - (expand-file-name elmo-msgdb-overview-filename dir))) - -(defun elmo-msgdb-mark-load (dir) - (elmo-object-load - (expand-file-name elmo-msgdb-mark-filename dir))) - (defsubst elmo-msgdb-seen-load (dir) (elmo-object-load (expand-file-name elmo-msgdb-seen-filename dir))) -(defun elmo-msgdb-number-save (dir obj) - (elmo-object-save - (expand-file-name elmo-msgdb-number-filename dir) - obj)) - -(defun elmo-msgdb-mark-save (dir obj) - (elmo-object-save - (expand-file-name elmo-msgdb-mark-filename dir) - obj)) - -(defun elmo-msgdb-change-mark (msgdb before after) - "Set the BEFORE marks to AFTER." - (let ((mark-alist (elmo-msgdb-get-mark-alist msgdb)) - entity) - (while mark-alist - (setq entity (car mark-alist)) - (when (string= (cadr entity) before) - (setcar (cdr entity) after)) - (setq mark-alist (cdr mark-alist))))) - -(defsubst elmo-msgdb-mark (flag cached &optional new) - (if new - (case flag - (read - (if cached - nil - elmo-msgdb-read-uncached-mark)) - (important - elmo-msgdb-important-mark) - (answered - (if cached - elmo-msgdb-answered-cached-mark - elmo-msgdb-answered-uncached-mark)) - (t - (if cached - elmo-msgdb-unread-cached-mark - elmo-msgdb-new-mark))) - (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-overview-save (dir overview) - (elmo-object-save - (expand-file-name elmo-msgdb-overview-filename dir) - overview)) - -(defun elmo-msgdb-match-condition-primitive (condition mark entity numbers) - (catch 'unresolved - (let ((key (elmo-filter-key condition)) - (case-fold-search t) - result) - (cond - ((string= key "last") - (setq result (<= (length (memq - (elmo-msgdb-overview-entity-get-number - entity) - numbers)) - (string-to-int (elmo-filter-value condition))))) - ((string= key "first") - (setq result (< (- - (length numbers) - (length (memq - (elmo-msgdb-overview-entity-get-number - 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) - (elmo-msgdb-overview-entity-get-from entity)))) - ((string= key "subject") - (setq result (string-match - (elmo-filter-value condition) - (elmo-msgdb-overview-entity-get-subject entity)))) - ((string= key "to") - (setq result (string-match - (elmo-filter-value condition) - (elmo-msgdb-overview-entity-get-to entity)))) - ((string= key "cc") - (setq result (string-match - (elmo-filter-value condition) - (elmo-msgdb-overview-entity-get-cc entity)))) - ((or (string= key "since") - (string= key "before")) - (let ((field-date (elmo-date-make-sortable-string - (timezone-fix-time - (elmo-msgdb-overview-entity-get-date entity) - (current-time-zone) nil))) - (specified-date - (elmo-date-make-sortable-string - (elmo-date-get-datevec - (elmo-filter-value condition))))) - (setq result (if (string= key "since") - (or (string= specified-date field-date) - (string< specified-date field-date)) - (string< field-date specified-date))))) - ((member key elmo-msgdb-extra-fields) - (let ((extval (elmo-msgdb-overview-entity-get-extra-field entity key))) - (when (stringp extval) - (setq result (string-match - (elmo-filter-value condition) - extval))))) - (t - (throw 'unresolved condition))) - (if (eq (elmo-filter-type condition) 'unmatch) - (not result) - result)))) - -(defun elmo-msgdb-match-condition-internal (condition mark entity numbers) - (cond - ((vectorp condition) - (elmo-msgdb-match-condition-primitive condition mark entity numbers)) - ((eq (car condition) 'and) - (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-internal - (nth 2 condition) mark 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))))) - ((eq (car condition) 'or) - (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-internal (nth 2 condition) - mark entity numbers))) - (cond ((elmo-filter-condition-p rhs) - (list 'or lhs rhs)) - (rhs - t) - (t - lhs)))) - (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))) - -(defsubst elmo-msgdb-set-overview (msgdb overview) - (setcar msgdb overview)) - -(defsubst elmo-msgdb-set-number-alist (msgdb number-alist) - (setcar (cdr msgdb) number-alist)) - -(defsubst elmo-msgdb-set-mark-alist (msgdb mark-alist) - (setcar (cddr msgdb) mark-alist)) - -(defsubst elmo-msgdb-set-index (msgdb index) - (setcar (cdddr msgdb) index)) - -(defsubst elmo-msgdb-set-path (msgdb path) - (setcar (cddddr msgdb) path)) - -(defsubst elmo-msgdb-overview-entity-get-references (entity) - (and entity (aref (cdr entity) 1))) - -(defsubst elmo-msgdb-overview-entity-set-references (entity references) - (and entity (aset (cdr entity) 1 references)) - entity) - -;; entity -> parent-entity -(defsubst elmo-msgdb-overview-get-parent-entity (entity database) - (setq entity (elmo-msgdb-overview-entity-get-references entity)) - ;; entity is parent-id. - (and entity (assoc entity database))) - -(defsubst elmo-msgdb-get-parent-entity (entity msgdb) - (setq entity (elmo-msgdb-overview-entity-get-references entity)) - ;; entity is parent-id. - (and entity (elmo-msgdb-overview-get-entity entity msgdb))) - -(defsubst elmo-msgdb-overview-entity-get-number (entity) - (and entity (aref (cdr entity) 0))) - -(defsubst elmo-msgdb-overview-entity-get-from-no-decode (entity) - (and entity (aref (cdr entity) 2))) - -(defsubst elmo-msgdb-overview-entity-get-from (entity) - (and entity - (aref (cdr entity) 2) - (elmo-msgdb-get-decoded-cache (aref (cdr entity) 2)))) - -(defsubst elmo-msgdb-overview-entity-set-number (entity number) - (and entity (aset (cdr entity) 0 number)) - entity) -;;;(setcar (cadr entity) number) entity) - -(defsubst elmo-msgdb-overview-entity-set-from (entity from) - (and entity (aset (cdr entity) 2 from)) - entity) - -(defsubst elmo-msgdb-overview-entity-get-subject (entity) - (and entity - (aref (cdr entity) 3) - (elmo-msgdb-get-decoded-cache (aref (cdr entity) 3)))) - -(defsubst elmo-msgdb-overview-entity-get-subject-no-decode (entity) - (and entity (aref (cdr entity) 3))) - -(defsubst elmo-msgdb-overview-entity-set-subject (entity subject) - (and entity (aset (cdr entity) 3 subject)) - entity) - -(defsubst elmo-msgdb-overview-entity-get-date (entity) - (and entity (aref (cdr entity) 4))) - -(defsubst elmo-msgdb-overview-entity-set-date (entity date) - (and entity (aset (cdr entity) 4 date)) - entity) - -(defsubst elmo-msgdb-overview-entity-get-to (entity) - (and entity (aref (cdr entity) 5))) - -(defsubst elmo-msgdb-overview-entity-get-cc (entity) - (and entity (aref (cdr entity) 6))) - -(defsubst elmo-msgdb-overview-entity-get-size (entity) - (and entity (aref (cdr entity) 7))) - -(defsubst elmo-msgdb-overview-entity-set-size (entity size) - (and entity (aset (cdr entity) 7 size)) - entity) - -(defsubst elmo-msgdb-overview-entity-get-id (entity) - (and entity (car entity))) - -(defsubst elmo-msgdb-overview-entity-get-extra-field (entity field-name) - (let ((field-name (downcase field-name)) - (extra (and entity (aref (cdr entity) 8)))) - (and extra - (cdr (assoc field-name extra))))) - -(defsubst elmo-msgdb-overview-entity-set-extra-field (entity field-name value) - (let ((field-name (downcase field-name)) - (extras (and entity (aref (cdr entity) 8))) - extra) - (if (setq extra (assoc field-name extras)) - (setcdr extra value) - (elmo-msgdb-overview-entity-set-extra - entity - (cons (cons field-name value) extras))))) - -(defsubst elmo-msgdb-overview-entity-get-extra (entity) - (and entity (aref (cdr entity) 8))) - -(defsubst elmo-msgdb-overview-entity-set-extra (entity extra) - (and entity (aset (cdr entity) 8 extra)) - entity) - -;;; New APIs -(defsubst elmo-msgdb-message-entity (msgdb key) - (elmo-get-hash-val - (cond ((stringp key) key) - ((numberp key) (format "#%d" key))) - (elmo-msgdb-get-entity-hashtb msgdb))) - -(defun elmo-msgdb-make-message-entity (&rest args) - "Make an message entity." - (cons (plist-get args :message-id) - (vector (plist-get args :number) - (plist-get args :references) - (plist-get args :from) - (plist-get args :subject) - (plist-get args :date) - (plist-get args :to) - (plist-get args :cc) - (plist-get args :size) - (plist-get args :extra)))) - -(defsubst elmo-msgdb-message-entity-field (entity field &optional decode) - (and entity - (let ((field-value - (case field - (to (aref (cdr entity) 5)) - (cc (aref (cdr entity) 6)) - (date (aref (cdr entity) 4)) - (subject (aref (cdr entity) 3)) - (from (aref (cdr entity) 2)) - (message-id (car entity)) - (references (aref (cdr entity) 1)) - (size (aref (cdr entity) 7)) - (t (cdr (assoc (symbol-name field) (aref (cdr entity) 8))))))) - (if (and decode (memq field '(from subject))) - (elmo-msgdb-get-decoded-cache field-value) - field-value)))) - -(defsubst elmo-msgdb-message-entity-set-field (entity field value) - (and entity - (case field - (to (aset (cdr entity) 5 value)) - (cc (aset (cdr entity) 6 value)) - (date (aset (cdr entity) 4 value)) - (subject (aset (cdr entity) 3 value)) - (from (aset (cdr entity) 2 value)) - (message-id (setcar entity value)) - (references (aset (cdr entity) 1 value)) - (size (aset (cdr entity) 7 value)) - (t - (let ((extras (and entity (aref (cdr entity) 8))) - extra) - (if (setq extra (assoc field extras)) - (setcdr extra value) - (aset (cdr entity) 8 (cons (cons (symbol-name field) - value) extras)))))))) - -;;; -(defun elmo-msgdb-overview-get-entity (id msgdb) - (when id - (let ((ht (elmo-msgdb-get-entity-hashtb msgdb))) - (if ht - (if (stringp id) ;; ID is message-id - (elmo-get-hash-val id ht) - (elmo-get-hash-val (format "#%d" id) ht)))))) +(defsubst elmo-msgdb-out-of-date-messages (msgdb) + (dolist (number (elmo-msgdb-list-flagged msgdb 'new)) + (elmo-msgdb-unset-flag msgdb number 'new))) ;; ;; deleted message handling @@ -1199,188 +386,6 @@ Return CONDITION itself if no entity exists in msgdb." elmo-msgdb-directory) alist)) -(defun elmo-msgdb-get-message-id-from-buffer () - (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"))) ">")))) - -(defsubst elmo-msgdb-create-overview-from-buffer (number &optional size time) - "Create overview entity from current buffer. -Header region is supposed to be narrowed." - (save-excursion - (let ((extras elmo-msgdb-extra-fields) - (default-mime-charset default-mime-charset) - message-id references from subject to cc date - extra field-body charset) - (elmo-set-buffer-multibyte default-enable-multibyte-characters) - (setq message-id (elmo-msgdb-get-message-id-from-buffer)) - (and (setq charset (cdr (assoc "charset" (mime-read-Content-Type)))) - (setq charset (intern-soft charset)) - (setq default-mime-charset charset)) - (setq references - (or (elmo-msgdb-get-last-message-id - (elmo-field-body "in-reply-to")) - (elmo-msgdb-get-last-message-id - (elmo-field-body "references")))) - (setq from (elmo-replace-in-string - (elmo-mime-string (or (elmo-field-body "from") - elmo-no-from)) - "\t" " ") - subject (elmo-replace-in-string - (elmo-mime-string (or (elmo-field-body "subject") - elmo-no-subject)) - "\t" " ")) - (setq date (or (elmo-field-body "date") time)) - (setq to (mapconcat 'identity (elmo-multiple-field-body "to") ",")) - (setq cc (mapconcat 'identity (elmo-multiple-field-body "cc") ",")) - (or size - (if (setq size (elmo-field-body "content-length")) - (setq size (string-to-int size)) - (setq size 0)));; No mean... - (while extras - (if (setq field-body (elmo-field-body (car extras))) - (setq extra (cons (cons (downcase (car extras)) - field-body) extra))) - (setq extras (cdr extras))) - (cons message-id (vector number references - from subject date to cc - size extra)) - ))) - -(defun elmo-msgdb-copy-overview-entity (entity) - (cons (car entity) - (copy-sequence (cdr entity)))) - -(defsubst elmo-msgdb-insert-file-header (file) - "Insert the header of the article." - (let ((beg 0) - insert-file-contents-pre-hook ; To avoid autoconv-xmas... - insert-file-contents-post-hook - format-alist) - (when (file-exists-p file) - ;; Read until header separator is found. - (while (and (eq elmo-msgdb-file-header-chop-length - (nth 1 - (insert-file-contents-as-binary - file nil beg - (incf beg elmo-msgdb-file-header-chop-length)))) - (prog1 (not (search-forward "\n\n" nil t)) - (goto-char (point-max)))))))) - -(defsubst elmo-msgdb-create-overview-entity-from-file (number file) - (let (insert-file-contents-pre-hook ; To avoid autoconv-xmas... - insert-file-contents-post-hook header-end - (attrib (file-attributes file)) - ret-val size mtime) - (with-temp-buffer - (if (not (file-exists-p file)) - () - (setq size (nth 7 attrib)) - (setq mtime (timezone-make-date-arpa-standard - (current-time-string (nth 5 attrib)) (current-time-zone))) - ;; insert header from file. - (catch 'done - (condition-case nil - (elmo-msgdb-insert-file-header file) - (error (throw 'done nil))) - (goto-char (point-min)) - (setq header-end - (if (re-search-forward "\\(^--.*$\\)\\|\\(\n\n\\)" nil t) - (point) - (point-max))) - (narrow-to-region (point-min) header-end) - (elmo-msgdb-create-overview-from-buffer number size mtime)))))) - -(defun elmo-msgdb-clear-index (msgdb entity) - (let ((ehash (elmo-msgdb-get-entity-hashtb msgdb)) - (mhash (elmo-msgdb-get-mark-hashtb msgdb)) - number) - (when (and entity ehash) - (and (setq number (elmo-msgdb-overview-entity-get-number entity)) - (elmo-clear-hash-val (format "#%d" number) ehash)) - (and (car entity) ;; message-id - (elmo-clear-hash-val (car entity) ehash))) - (when (and entity mhash) - (and (setq number (elmo-msgdb-overview-entity-get-number entity)) - (elmo-clear-hash-val (format "#%d" number) mhash))))) - -(defun elmo-msgdb-make-index-return (msgdb &optional overview mark-alist) - "Append OVERVIEW and MARK-ALIST to the index of MSGDB. -If OVERVIEW and MARK-ALIST are nil, make index for current MSGDB. -Return the updated INDEX." - (when msgdb - (let* ((overview (or overview (elmo-msgdb-get-overview msgdb))) - (mark-alist (or mark-alist (elmo-msgdb-get-mark-alist msgdb))) - (index (elmo-msgdb-get-index msgdb)) - (ehash (or (car index) ;; append - (elmo-make-hash (length overview)))) - (mhash (or (cdr index) ;; append - (elmo-make-hash (length overview))))) - (while overview - ;; key is message-id - (if (caar overview) - (elmo-set-hash-val (caar overview) (car overview) ehash)) - ;; key is number - (elmo-set-hash-val - (format "#%d" - (elmo-msgdb-overview-entity-get-number (car overview))) - (car overview) ehash) - (setq overview (cdr overview))) - (while mark-alist - ;; key is number - (elmo-set-hash-val - (format "#%d" (car (car mark-alist))) - (car mark-alist) mhash) - (setq mark-alist (cdr mark-alist))) - (setq index (or index (cons ehash mhash))) - (elmo-msgdb-set-index msgdb index) - index))) - -(defun elmo-msgdb-make-index (msgdb &optional overview mark-alist) - "Append OVERVIEW and MARK-ALIST to the index of MSGDB. -If OVERVIEW and MARK-ALIST are nil, make index for current MSGDB. -Return a list of message numbers which have duplicated message-ids." - (when msgdb - (let* ((overview (or overview (elmo-msgdb-get-overview msgdb))) - (mark-alist (or mark-alist (elmo-msgdb-get-mark-alist msgdb))) - (index (elmo-msgdb-get-index msgdb)) - (ehash (or (car index) ;; append - (elmo-make-hash (length overview)))) - (mhash (or (cdr index) ;; append - (elmo-make-hash (length overview)))) - duplicates) - (while overview - ;; key is message-id - (if (elmo-get-hash-val (caar overview) ehash) ; duplicated. - (setq duplicates (cons - (elmo-msgdb-overview-entity-get-number - (car overview)) - duplicates))) - (if (caar overview) - (elmo-set-hash-val (caar overview) (car overview) ehash)) - ;; key is number - (elmo-set-hash-val - (format "#%d" - (elmo-msgdb-overview-entity-get-number (car overview))) - (car overview) ehash) - (setq overview (cdr overview))) - (while mark-alist - ;; key is number - (elmo-set-hash-val - (format "#%d" (car (car mark-alist))) - (car mark-alist) mhash) - (setq mark-alist (cdr mark-alist))) - (setq index (or index (cons ehash mhash))) - (elmo-msgdb-set-index msgdb index) - duplicates))) - (defsubst elmo-folder-get-info (folder &optional hashtb) (elmo-get-hash-val folder (or hashtb elmo-folder-info-hashtb))) @@ -1413,40 +418,75 @@ Return a list of message numbers which have duplicated message-ids." 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-answered-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-list-messages msgdb)) - (let ((mark (elmo-msgdb-get-mark msgdb number))) - (unless (and mark (string-match mark-regexp mark)) - (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)) +;;; For backward compatibility. +(defsubst elmo-msgdb-overview-entity-get-number (entity) + (elmo-message-entity-number entity)) + +(defsubst elmo-msgdb-overview-entity-set-number (entity number) + (elmo-message-entity-set-number entity number)) + +(defsubst elmo-msgdb-overview-entity-get-references (entity) + (elmo-message-entity-field entity 'references)) + +(defsubst elmo-msgdb-overview-entity-set-references (entity references) + (elmo-message-entity-set-field entity 'references references)) + +(defsubst elmo-msgdb-overview-entity-get-from-no-decode (entity) + (elmo-with-enable-multibyte + (encode-mime-charset-string + (elmo-message-entity-field entity 'from) elmo-mime-charset))) + +(defsubst elmo-msgdb-overview-entity-get-from (entity) + (elmo-message-entity-field entity 'from)) + +(defsubst elmo-msgdb-overview-entity-set-from (entity from) + (elmo-message-entity-set-field entity 'from from)) + +(defsubst elmo-msgdb-overview-entity-get-subject (entity) + (elmo-message-entity-field entity 'subject)) + +(defsubst elmo-msgdb-overview-entity-get-subject-no-decode (entity) + (elmo-with-enable-multibyte + (encode-mime-charset-string + (elmo-message-entity-field entity 'subject) elmo-mime-charset))) + +(defsubst elmo-msgdb-overview-entity-set-subject (entity subject) + (elmo-message-entity-set-field entity 'subject subject)) + +(defsubst elmo-msgdb-overview-entity-get-date (entity) + (elmo-message-entity-field entity 'date 'string)) + +(defsubst elmo-msgdb-overview-entity-set-date (entity date) + (elmo-message-entity-set-field entity 'date date)) + +(defsubst elmo-msgdb-overview-entity-get-to (entity) + (elmo-message-entity-field entity 'to 'string)) + +(defsubst elmo-msgdb-overview-entity-get-cc (entity) + (elmo-message-entity-field entity 'cc 'string)) + +(defsubst elmo-msgdb-overview-entity-get-size (entity) + (elmo-message-entity-field entity 'size)) + +(defsubst elmo-msgdb-overview-entity-set-size (entity size) + (elmo-message-entity-set-field entity 'size size)) + +(defsubst elmo-msgdb-overview-entity-get-extra (entity) + ;; Truely obsolete. + ) + +(defsubst elmo-msgdb-overview-entity-set-extra (entity extra) + ;; Truely obsolete. + ) + +(defsubst elmo-msgdb-overview-entity-get-extra-field (entity + field-name) + (elmo-message-entity-field entity (intern field-name))) + +(defsubst elmo-msgdb-overview-entity-set-extra-field (entity + field-name + value) + (elmo-message-entity-set-field entity (intern field-name) value)) (require 'product) (product-provide (provide 'elmo-msgdb) (require 'elmo-version))