+ (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)))))))
+
+(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))))