* elmo.el (elmo-message-flags): Use `elmo-msgdb-flags' instead of
[elisp/wanderlust.git] / elmo / elmo.el
index e263146..1b75434 100644 (file)
@@ -156,6 +156,7 @@ If optional argument NON-PERSISTENT is non-nil, the folder msgdb is not saved."
   (or (elmo-folder-msgdb-internal folder)
       (elmo-folder-set-msgdb-internal folder
                                      (elmo-msgdb-load folder))))
+
 (luna-define-generic elmo-folder-open (folder &optional load-msgdb)
   "Open and setup (load saved status) FOLDER.
 If optional LOAD-MSGDB is non-nil, msgdb is loaded.
@@ -204,24 +205,31 @@ Return value is cons cell or list:
 (luna-define-generic elmo-folder-reserve-status-p (folder)
   "If non-nil, the folder should not close folder after `elmo-folder-status'.")
 
+(luna-define-generic elmo-folder-set-message-modified (folder modified)
+  "Set FOLDER as modified.")
+(luna-define-method elmo-folder-set-message-modified ((folder elmo-folder)
+                                                     modified)
+  (elmo-folder-set-message-modified-internal folder modified))
+
 (luna-define-generic elmo-folder-list-messages (folder &optional visible-only
                                                       in-msgdb)
   "Return a list of message numbers contained in FOLDER.
 If optional VISIBLE-ONLY is non-nil, killed messages are not listed.
 If second optional IN-MSGDB is non-nil, only messages in the msgdb are listed.")
+
 (luna-define-method elmo-folder-list-messages ((folder elmo-folder)
                                               &optional visible-only in-msgdb)
   (let ((list (if in-msgdb
                  t
-               (elmo-folder-list-messages-internal folder visible-only))))
-    (setq list
-         (if (listp list)
-             list
-           ;; Use current list.
-           (elmo-msgdb-list-messages (elmo-folder-msgdb folder))))
+               (elmo-folder-list-messages-internal folder visible-only)))
+       (killed-list (elmo-folder-killed-list-internal folder)))
+    (unless (listp list)
+      ;; Use current list.
+      (setq list (elmo-msgdb-list-messages (elmo-folder-msgdb folder))))
     (if visible-only
-       (elmo-living-messages list (elmo-folder-killed-list-internal folder))
-      list)))
+       (elmo-living-messages list killed-list)
+      (elmo-uniq-list
+       (nconc (elmo-number-set-to-number-list killed-list) list)))))
 
 (luna-define-generic elmo-folder-list-unreads (folder)
   "Return a list of unread message numbers contained in FOLDER.")
@@ -401,7 +409,7 @@ Caller should make sure FOLDER is `writable'.
 SRC-FOLDER is the source ELMO folder structure.
 NUMBERS is the message numbers to be appended in the SRC-FOLDER.
 If second optional argument SAME-NUMBER is specified,
-message number is preserved (if possible).")
+message number is preserved \(if possible\).")
 
 (luna-define-generic elmo-folder-pack-numbers (folder)
   "Pack message numbers of FOLDER.")
@@ -620,12 +628,8 @@ FIELD is a symbol of the field name.")
 
 (luna-define-generic elmo-folder-process-crosspost (folder)
   "Process crosspost for FOLDER.
-If NUMBER-ALIST is set, it is used as number-alist.
 Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
 
-(luna-define-generic elmo-folder-append-msgdb (folder append-msgdb)
-  "Append  APPEND-MSGDB to the current msgdb of the folder.")
-
 (luna-define-generic elmo-folder-newsgroups (folder)
   "Return list of newsgroup name of FOLDER.")
 
@@ -682,7 +686,7 @@ Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).")
       (elmo-folder-set-info-max-by-numdb
        folder
        (elmo-folder-list-messages folder nil 'in-msgdb))
-      (elmo-folder-set-message-modified-internal folder nil)
+      (elmo-folder-set-message-modified folder nil)
       (elmo-msgdb-killed-list-save
        (elmo-folder-msgdb-path folder)
        (elmo-folder-killed-list-internal folder)))
@@ -887,12 +891,11 @@ NUMBERS is a list of message numbers, messages are searched from the list."
 
 (defun elmo-folder-set-info-max-by-numdb (folder numbers)
   "Set FOLDER info by MSGDB-NUMBER in msgdb."
-  (let ((numbers (sort numbers '<)))
-    (elmo-folder-set-info-hashtb
-     folder
-     (or (nth (max 0 (1- (length numbers))) numbers) 0)
-     nil ;;(length num-db)
-     )))
+  (elmo-folder-set-info-hashtb
+   folder
+   (or (car (sort numbers '>)) 0)
+   nil ;;(length num-db)
+   ))
 
 (defun elmo-folder-get-info-max (folder)
   "Return max number of FODLER from folder info."
@@ -937,11 +940,10 @@ NUMBERS is a list of message numbers, messages are searched from the list."
 
 (defsubst elmo-strict-folder-diff (folder)
   "Return folder diff information strictly from FOLDER."
-  (let* ((dir (elmo-folder-msgdb-path folder))
-        (nalist (elmo-msgdb-get-number-alist (elmo-folder-msgdb folder)))
-        (in-db (sort (mapcar 'car nalist) '<))
-        (in-folder  (elmo-folder-list-messages folder))
-        append-list delete-list diff)
+  (let ((in-db (sort (elmo-msgdb-list-messages (elmo-folder-msgdb folder))
+                    '<))
+       (in-folder  (elmo-folder-list-messages folder))
+       append-list delete-list diff)
     (cons (if (equal in-folder in-db)
              0
            (setq diff (elmo-list-diff in-folder in-db nil))
@@ -1070,11 +1072,9 @@ NUMBERS is a list of message numbers, messages are searched from the list."
 
 ;; Arguments should be reduced.
 (defun elmo-folder-move-messages (src-folder msgs dst-folder
-                                            &optional msgdb
-                                            no-delete-info
+                                            &optional
                                             no-delete
-                                            same-number
-                                            save-unread)
+                                            same-number)
   (save-excursion
     (let* ((messages msgs)
           (elmo-inhibit-display-retrieval-progress t)
@@ -1121,12 +1121,18 @@ NUMBERS is a list of message numbers, messages are searched from the list."
        folder
        (elmo-folder-expand-msgdb-path folder))))
 
+(luna-define-generic elmo-message-cached-p (folder number)
+  "Return non-nil if the message is cached.")
+
+(luna-define-method elmo-message-cached-p ((folder elmo-folder) number)
+  (elmo-msgdb-get-cached (elmo-folder-msgdb folder) number))
+
 (defun elmo-message-accessible-p (folder number)
   "Get accessibility of the message.
 Return non-nil when message is accessible."
   (or (elmo-folder-plugged-p folder)
       (elmo-folder-local-p folder)
-      (elmo-msgdb-get-cached (elmo-folder-msgdb folder) number)))
+      (elmo-message-cached-p folder number)))
 
 (luna-define-generic elmo-message-set-cached (folder number cached)
   "Set cache status of the message in the msgdb.
@@ -1173,7 +1179,7 @@ ENTITY is the message-entity to get the parent.")
   ;; List all message entities in the FOLDER.
   (mapcar
    (lambda (number) (elmo-message-entity folder number))
-   (elmo-folder-list-messages folder t t)))
+   (elmo-folder-list-messages folder nil t))) ; XXX killed-list is not used.
 
 (defmacro elmo-folder-do-each-message-entity (spec &rest form)
   "Iterator for message entity in the folder.
@@ -1207,17 +1213,38 @@ Return a list of numbers (`new' `unread' `answered')")
 (luna-define-method elmo-folder-count-flags ((folder elmo-folder))
   (let ((new 0)
        (unreads 0)
-       (answered 0))
-    (dolist (elem (elmo-msgdb-get-mark-alist (elmo-folder-msgdb folder)))
+       (answered 0)
+       flags)
+    (dolist (number (elmo-folder-list-messages folder 'visible 'in-msgdb))
+      (setq flags (elmo-message-flags folder number))
       (cond
-       ((string= (cadr elem) elmo-msgdb-new-mark)
+       ((memq 'new flags)
        (incf new))
-       ((member (cadr elem) (elmo-msgdb-unread-marks))
+       ((memq 'unread flags)
        (incf unreads))
-       ((member (cadr elem) (elmo-msgdb-answered-marks))
+       ((memq 'answered flags)
        (incf answered))))
     (list new unreads answered)))
 
+(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.")
+
+(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.
+FOLDER is a ELMO folder structure.
+NUMBER is a message number to test."
+  (let ((cur-flags (elmo-message-flags folder number)))
+    (case flag
+      (read
+       (not (memq 'unread cur-flags)))
+      (t
+       (memq flag cur-flags)))))
+
 (defun elmo-message-set-flag (folder number flag)
   "Set message flag.
 FOLDER is a ELMO folder structure.
@@ -1334,53 +1361,25 @@ FIELD is a symbol of the field.")
 ;;                                                            flag-table)
 ;;  "Append ENTITY to the folder.")
 
-(defun elmo-generic-folder-append-msgdb (folder append-msgdb)
+(defsubst elmo-folder-append-msgdb (folder append-msgdb)
   (if append-msgdb
-      (let* ((number-alist (elmo-msgdb-get-number-alist append-msgdb))
-            (all-alist (copy-sequence (append
-                                       (elmo-msgdb-get-number-alist
-                                        (elmo-folder-msgdb folder))
-                                       number-alist)))
-            (cur number-alist)
-            pair overview
-            to-be-deleted
-            mark-alist)
-       (elmo-folder-set-msgdb-internal folder
-                                       (elmo-msgdb-append
-                                        (elmo-folder-msgdb folder)
-                                        append-msgdb))
-       (while cur
-         (setq all-alist (delq (car cur) all-alist))
-         ;; same message id exists.
-         (if (setq pair (rassoc (cdr (car cur)) all-alist))
-             (setq to-be-deleted (nconc to-be-deleted (list (car pair)))))
-         (setq cur (cdr cur)))
+      (let ((duplicates (elmo-msgdb-merge folder append-msgdb)))
        (cond ((eq (elmo-folder-process-duplicates-internal folder)
                   'hide)
-              ;; Hide duplicates.
-              (setq overview (elmo-delete-if
-                              (lambda (x)
-                                (memq (elmo-msgdb-overview-entity-get-number
-                                       x)
-                                      to-be-deleted))
-                              (elmo-msgdb-get-overview append-msgdb)))
+              ;; Let duplicates be a temporary killed message.
+              (elmo-folder-kill-messages folder duplicates)
               ;; Should be mark as read.
-              (elmo-folder-mark-as-read folder to-be-deleted)
-              (elmo-msgdb-set-overview append-msgdb overview))
+              (elmo-folder-mark-as-read folder duplicates))
              ((eq (elmo-folder-process-duplicates-internal folder)
                   'read)
               ;; Mark as read duplicates.
-              (elmo-folder-mark-as-read folder to-be-deleted))
+              (elmo-folder-mark-as-read folder duplicates))
              (t
               ;; Do nothing.
-              (setq to-be-deleted nil)))
-       (length to-be-deleted))
+              (setq duplicates nil)))
+       (length duplicates))
     0))
 
-(luna-define-method elmo-folder-append-msgdb ((folder elmo-folder)
-                                             append-msgdb)
-  (elmo-generic-folder-append-msgdb folder append-msgdb))
-
 (defun elmo-folder-confirm-appends (appends)
   (let ((len (length appends))
        in)
@@ -1501,7 +1500,6 @@ If update process is interrupted, return nil.")
                                             no-check)
   (let ((killed-list (elmo-folder-killed-list-internal folder))
        (before-append t)
-       number-alist
        old-msgdb diff diff-2 delete-list new-list new-msgdb mark
        flag-table crossed after-append)
     (setq old-msgdb (elmo-folder-msgdb folder))
@@ -1556,7 +1554,7 @@ If update process is interrupted, return nil.")
              ;; process crosspost.
              ;; Return a cons cell of (NUMBER-CROSSPOSTS . NEW-MARK-ALIST).
              (elmo-folder-process-crosspost folder)
-             (elmo-folder-set-message-modified-internal folder t)
+             (elmo-folder-set-message-modified folder t)
              (elmo-folder-set-mark-modified-internal folder t))
            ;; return value.
            (or crossed 0)))
@@ -1571,7 +1569,7 @@ If update process is interrupted, return nil.")
 
 (luna-define-method elmo-folder-detach-messages ((folder elmo-folder)
                                                 numbers)
-  (elmo-msgdb-delete-msgs (elmo-folder-msgdb folder) numbers))
+  (elmo-msgdb-delete-messages (elmo-folder-msgdb folder) numbers))
 
 (luna-define-generic elmo-folder-length (folder)
   "Return number of messages in the FOLDER.")
@@ -1587,8 +1585,7 @@ If update process is interrupted, return nil.")
   (let ((msgdb (elmo-load-msgdb (elmo-folder-msgdb-path folder))))
     (elmo-folder-set-info-max-by-numdb
      folder
-     (mapcar 'elmo-msgdb-overview-entity-get-number
-            (elmo-msgdb-get-overview msgdb)))
+     (elmo-msgdb-list-messages msgdb))
     (unless silent
       (message "Loading msgdb for %s...done"
               (elmo-folder-name-internal folder)))
@@ -1685,7 +1682,6 @@ Return a hashtable for newsgroups."
   (error "Cannot rename %s folder"
         (symbol-name (elmo-folder-type-internal folder))))
 
-
 ;;; Define folders.
 (elmo-define-folder ?% 'imap4)
 (elmo-define-folder ?-  'nntp)