* elmo-pop3.el (elmo-pop3-lock): New buffer local variable.
[elisp/wanderlust.git] / elmo / elmo-pop3.el
index 7451f98..acf13cc 100644 (file)
@@ -43,6 +43,8 @@
 (defvar elmo-pop3-exists-exactly t)
 (defvar sasl-mechanism-alist)
 
+(defvar elmo-pop3-total-size nil)
+
 (luna-define-class elmo-pop3-session (elmo-network-session))
 
 ;; buffer-local
 (defvar elmo-pop3-size-hash nil) ; number -> size
 (defvar elmo-pop3-uidl-done nil)
 (defvar elmo-pop3-list-done nil)
+(defvar elmo-pop3-lock nil)
 
 (defvar elmo-pop3-local-variables '(elmo-pop3-read-point
                                    elmo-pop3-uidl-number-hash
                                    elmo-pop3-number-uidl-hash
                                    elmo-pop3-uidl-done
                                    elmo-pop3-size-hash
-                                   elmo-pop3-list-done))
+                                   elmo-pop3-list-done
+                                   elmo-pop3-lock))
 
 (luna-define-method elmo-network-close-session ((session elmo-pop3-session))
   (when (elmo-network-session-process-internal session)
@@ -91,6 +95,7 @@
       (erase-buffer))
     (goto-char (point-min))
     (setq elmo-pop3-read-point (point))
+    (elmo-pop3-lock)
     (process-send-string process command)
     (process-send-string process "\r\n")))
 
                      (concat return-value "\n" response-string)
                    response-string)))
          (setq elmo-pop3-read-point match-end)))
+      (elmo-pop3-unlock)
       return-value)))
 
 (defun elmo-pop3-process-filter (process output)
   (save-excursion
     (set-buffer (process-buffer process))
     (goto-char (point-max))
-    (insert output)))
+    (insert output)
+    (if elmo-pop3-total-size
+       (message "Retrieving...(%d/%d bytes)." 
+                (buffer-size) elmo-pop3-total-size))))
 
 (defun elmo-pop3-auth-user (session)
   (let ((process (elmo-network-session-process-internal session)))
        (elmo-pop3-parse-uidl-response response)))))
 
 (defun elmo-pop3-read-contents (buffer process)
-  (save-excursion
-    (set-buffer buffer)
+  (with-current-buffer buffer
     (let ((case-fold-search nil)
          match-end)
       (goto-char elmo-pop3-read-point)
        (accept-process-output process)
        (goto-char elmo-pop3-read-point))
       (setq match-end (point))
+      (elmo-pop3-unlock)
       (elmo-delete-cr
        (buffer-substring elmo-pop3-read-point
                         (- match-end 3))))))
       nil))
    (t
     nil)))
+
+(defun elmo-pop3-lock ()
+  "Lock pop3 process."
+  (setq elmo-pop3-lock t))
+
+(defun elmo-pop3-unlock ()
+  "Unlock pop3 process."
+  (setq elmo-pop3-lock nil))
+
+(defun elmo-pop3-locked-p (process)
+  "Return t if pop3 PROCESS is locked."
+  (with-current-buffer (process-buffer process)
+    elmo-pop3-lock))
      
 (defun elmo-pop3-retrieve-headers (buffer tobuffer process articles)
   (save-excursion
                           (elmo-msgdb-expand-path spec)))))
         (process (elmo-network-session-process-internal
                   (elmo-pop3-get-session spec)))
-        response errmsg msg)
+        size response errmsg msg)
     (with-current-buffer (process-buffer process)
       (if loc-alist
          (setq number (elmo-pop3-uidl-to-number
                        (cdr (assq number loc-alist)))))
+      (setq size (string-to-number
+                 (elmo-pop3-number-to-size number)))
       (when number
        (elmo-pop3-send-command process
                                (format "retr %s" number))
-       (when (null (setq response (elmo-pop3-read-response
-                                   process t)))
-         (error "Fetching message failed"))
-       (setq response (elmo-pop3-read-body process outbuf))
+       (setq elmo-pop3-total-size size)
+       (unless elmo-inhibit-display-retrieval-progress
+         (setq elmo-pop3-total-size size)
+         (elmo-display-progress
+          'elmo-pop3-display-retrieval-progress
+          (format "Retrieving (0/%d bytes)..." elmo-pop3-total-size)
+          0))
+       (unwind-protect
+           (progn
+             (when (null (setq response (elmo-pop3-read-response
+                                         process t)))
+               (error "Fetching message failed"))
+             (setq response (elmo-pop3-read-body process outbuf)))
+         (setq elmo-pop3-total-size nil))
+       (unless elmo-inhibit-display-retrieval-progress
+         (elmo-display-progress
+          'elmo-display-retrieval-progress "" 100)  ; remove progress bar.
+         (message "Retrieving...done."))
        (set-buffer outbuf)
        (goto-char (point-min))
        (while (re-search-forward "^\\." nil t)
 (defun elmo-pop3-commit (spec)
   (if (elmo-pop3-plugged-p spec)
       (let ((session (elmo-pop3-get-session spec 'if-exists)))
-       (and session
-            (elmo-network-close-session session)))))
+       (when (and session
+                  (not (elmo-pop3-locked-p
+                        (elmo-network-session-process-internal session))))
+         (elmo-network-close-session session)))))
        
 
 (require 'product)