* elmo-signal.el: New file.
* elmo.el (toplevel): Require elmo-signal.
(flag-changing, flag-changed, cache-changed): New signal.
(elmo-folder): Remove slog `handlers'.
(elmo-message-set-cached): Use `elmo-emit-signal' instead of
`elmo-folder-notify-event'.
(elmo-folder-set-flag): Likewise. Emit signal `flag-changing'.
(elmo-folder-unset-flag): Ditto.
(elmo-event-handler): Abolish.
(elmo-event-handler-flag-changed): Ditto.
(elmo-event-handler-cache-changed): Ditto.
(elmo-folder-add-handler): Ditto.
(elmo-folder-remove-handler): Ditto.
(elmo-folder-notify-event): Ditto.
* elmo-pipe.el (toplevel): Require elmo-signal.
(elmo-folder-initialize): Call `elmo-pipe-connect-signals'.
(elmo-pipe-connect-signals): New function.
(elmo-message-fetch): Does not call `elmo-folder-notify-event'.
(elmo-folder-set-flag): Ditto.
(elmo-folder-unset-flag): Ditto.
(elmo-message-set-cached): Ditto.
* elmo-multi.el (toplevel): Require elmo-signal.
(elmo-folder-initialize): Call `elmo-multi-connect-signals'.
(elmo-multi-connect-signals): New function.
(elmo-multi-map-numbers): Ditto.
(elmo-message-set-cached): Does not call `elmo-folder-notify-event'.
(elmo-message-fetch): Ditto.
(elmo-folder-set-flag): Ditto.
(elmo-folder-unset-flag): Ditto.
* elmo-filter.el (toplevel): Require elmo-signal.
(elmo-folder-initialize): Call `elmo-filter-connect-signals'.
(elmo-filter-connect-signals): New function.
(elmo-filter-add-flag-count): Ditto.
(elmo-message-fetch): Does not call
`elmo-filter-folder-countup-message-flags' and
`elmo-folder-notify-event'.
(elmo-message-set-cached): Ditto.
(elmo-folder-set-flag): Ditto.
(elmo-folder-unset-flag): Ditto.
* wl.el (wl-exit): Call `elmo-clear-signal-slots'.
* wl-summary.el (wl-summary-buffer-event-handler): Abolish.
(wl-summary-event-handler): Ditto.
(wl-summary-update-persistent-mark-on-event): New
function (renamed from `elmo-event-handler-flag-changed').
(wl-summary-buffer-attach): New function.
(wl-summary-buffer-detach): Rewrite by `elmo-signal'.
(wl-summary-buffer-set-folder): Use `wl-summary-buffer-attach'
instead of `elmo-folder-add-handler'.
+2005-02-18 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+
+ * WL-ELS (ELMO-MODULES): Added elmo-signal.
+
2005-01-23 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
* Makefile (compile-strict): New target.
(defconst ELMO-MODULES '(
utf7 pldap acap slp mmimap
- elmo-date elmo-util elmo-version elmo-vars elmo elmo-msgdb
+ elmo-signal elmo-date elmo-util elmo-version
+ elmo-vars elmo elmo-msgdb
elmo-net elmo-imap4 elmo-pop3 elmo-nntp
elmo-localdir elmo-localnews elmo-map elmo-maildir
elmo-multi elmo-access elmo-filter
2005-02-18 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+ * elmo-signal.el: New file.
+
+ * elmo.el (toplevel): Require elmo-signal.
+ (flag-changing, flag-changed, cache-changed): New signal.
+ (elmo-folder): Remove slog `handlers'.
+ (elmo-message-set-cached): Use `elmo-emit-signal' instead of
+ `elmo-folder-notify-event'.
+ (elmo-folder-set-flag): Likewise. Emit signal `flag-changing'.
+ (elmo-folder-unset-flag): Ditto.
+ (elmo-event-handler): Abolish.
+ (elmo-event-handler-flag-changed): Ditto.
+ (elmo-event-handler-cache-changed): Ditto.
+ (elmo-folder-add-handler): Ditto.
+ (elmo-folder-remove-handler): Ditto.
+ (elmo-folder-notify-event): Ditto.
+
+ * elmo-pipe.el (toplevel): Require elmo-signal.
+ (elmo-folder-initialize): Call `elmo-pipe-connect-signals'.
+ (elmo-pipe-connect-signals): New function.
+ (elmo-message-fetch): Does not call `elmo-folder-notify-event'.
+ (elmo-folder-set-flag): Ditto.
+ (elmo-folder-unset-flag): Ditto.
+ (elmo-message-set-cached): Ditto.
+
+ * elmo-multi.el (toplevel): Require elmo-signal.
+ (elmo-folder-initialize): Call `elmo-multi-connect-signals'.
+ (elmo-multi-connect-signals): New function.
+ (elmo-multi-map-numbers): Ditto.
+ (elmo-message-set-cached): Does not call `elmo-folder-notify-event'.
+ (elmo-message-fetch): Ditto.
+ (elmo-folder-set-flag): Ditto.
+ (elmo-folder-unset-flag): Ditto.
+
+ * elmo-filter.el (toplevel): Require elmo-signal.
+ (elmo-folder-initialize): Call `elmo-filter-connect-signals'.
+ (elmo-filter-connect-signals): New function.
+ (elmo-filter-add-flag-count): Ditto.
+ (elmo-message-fetch): Does not call
+ `elmo-filter-folder-countup-message-flags' and
+ `elmo-folder-notify-event'.
+ (elmo-message-set-cached): Ditto.
+ (elmo-folder-set-flag): Ditto.
+ (elmo-folder-unset-flag): Ditto.
+
* elmo-version.el (elmo-version): Up to 2.13.2.
2005-02-17 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
;;; Code:
;;
(require 'elmo)
+(require 'elmo-signal)
(require 'elmo-msgdb)
(defvar elmo-filter-number-filename "number-list"
name)
(let (pair)
(setq pair (elmo-parse-search-condition name))
- (elmo-filter-folder-set-condition-internal folder
- (car pair))
+ (elmo-filter-folder-set-condition-internal folder (car pair))
(if (string-match "^ */\\(.*\\)$" (cdr pair))
(elmo-filter-folder-set-target-internal
folder
(elmo-folder-search-requires-msgdb-p
(elmo-filter-folder-target-internal folder)
(elmo-filter-folder-condition-internal folder)))
+ (elmo-filter-connect-signals
+ folder
+ (elmo-filter-folder-target-internal folder))
folder))
+(defun elmo-filter-connect-signals (folder target)
+ (elmo-connect-signal
+ target 'flag-changing folder
+ (elmo-define-signal-handler (folder target number old-flags new-flags)
+ (elmo-filter-add-flag-count folder number old-flags -1)
+ (elmo-filter-add-flag-count folder number new-flags)
+ (elmo-emit-signal 'flag-changing folder number old-flags new-flags))
+ (elmo-define-signal-filter (folder target number)
+ (memq number (elmo-folder-list-messages folder nil t))))
+ (elmo-connect-signal
+ target 'flag-changed folder
+ (elmo-define-signal-handler (folder target numbers)
+ (let ((filterd (elmo-list-filter
+ (elmo-folder-list-messages folder nil t)
+ numbers)))
+ (when filterd
+ (elmo-emit-signal 'flag-changed folder filterd)))))
+ (elmo-connect-signal
+ target 'cache-changed folder
+ (elmo-define-signal-handler (folder target number)
+ (elmo-emit-signal 'cache-changed folder number))
+ (elmo-define-signal-filter (folder target number)
+ (memq number (elmo-folder-list-messages folder nil t)))))
+
(defun elmo-filter-number-list-load (dir)
(elmo-object-load
(expand-file-name elmo-filter-number-filename dir)))
(setq flag-count (cons (cons flag delta) flag-count)))))
(elmo-filter-folder-set-flag-count-internal folder flag-count)))
+(defun elmo-filter-add-flag-count (folder number flags &optional delta)
+ (let ((flag-count (elmo-filter-folder-flag-count-internal folder))
+ (delta (or delta 1))
+ elem)
+ (dolist (flag flags)
+ (if (setq elem (assq flag flag-count))
+ (setcdr elem (+ (cdr elem) delta))
+ (setq flag-count (cons (cons flag delta) flag-count))))
+ (elmo-filter-folder-set-flag-count-internal folder flag-count)))
+
(defun elmo-filter-folder-flag-count (folder)
(or (elmo-filter-folder-flag-count-internal folder)
(elmo-filter-folder-countup-message-flags
(luna-define-method elmo-message-fetch ((folder elmo-filter-folder)
number strategy
&optional unseen section)
- (unless unseen
- (elmo-filter-folder-countup-message-flags folder (list number) -1))
- (when (elmo-message-fetch (elmo-filter-folder-target-internal folder)
- number strategy unseen section)
- (unless unseen
- (elmo-filter-folder-countup-message-flags folder (list number))
- (elmo-folder-notify-event folder 'flag-changed (list number)))
- t))
+ (elmo-message-fetch (elmo-filter-folder-target-internal folder)
+ number strategy unseen section))
(luna-define-method elmo-folder-delete-messages ((folder elmo-filter-folder)
numbers)
(luna-define-method elmo-message-set-cached ((folder elmo-filter-folder)
number cached)
(elmo-message-set-cached
- (elmo-filter-folder-target-internal folder) number cached)
- (elmo-folder-notify-event folder 'cache-changed number))
+ (elmo-filter-folder-target-internal folder) number cached))
(luna-define-method elmo-message-number ((folder elmo-filter-folder)
message-id)
numbers
flag
&optional is-local)
- (elmo-filter-folder-countup-message-flags folder numbers -1)
(elmo-folder-set-flag (elmo-filter-folder-target-internal folder)
- numbers flag is-local)
- (elmo-filter-folder-countup-message-flags folder numbers)
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ numbers flag is-local))
(luna-define-method elmo-folder-unset-flag ((folder elmo-filter-folder)
numbers
flag
&optional is-local)
- (elmo-filter-folder-countup-message-flags folder numbers -1)
(elmo-folder-unset-flag (elmo-filter-folder-target-internal folder)
- numbers flag is-local)
- (elmo-filter-folder-countup-message-flags folder numbers)
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ numbers flag is-local))
(luna-define-method elmo-message-folder ((folder elmo-filter-folder)
number)
(eval-when-compile (require 'cl))
(require 'elmo)
+(require 'elmo-signal)
(require 'luna)
(defvar elmo-multi-divide-number 100000
(elmo-multi-folder-set-divide-number-internal
folder
elmo-multi-divide-number)
+ (elmo-multi-connect-signals folder)
folder)
+(defun elmo-multi-connect-signals (folder)
+ (elmo-connect-signal
+ nil 'flag-changing folder
+ (elmo-define-signal-handler (folder child number old-flags new-flags)
+ (elmo-emit-signal 'flag-changing folder
+ (car (elmo-multi-map-numbers folder child (list number)))
+ old-flags new-flags))
+ (elmo-define-signal-filter (folder sender)
+ (memq sender (elmo-multi-folder-children-internal folder))))
+ (elmo-connect-signal
+ nil 'flag-changed folder
+ (elmo-define-signal-handler (folder child numbers)
+ (elmo-emit-signal 'flag-changed folder
+ (elmo-multi-map-numbers folder child numbers)))
+ (elmo-define-signal-filter (folder sender)
+ (memq sender (elmo-multi-folder-children-internal folder))))
+ (elmo-connect-signal
+ nil 'cache-changed folder
+ (elmo-define-signal-handler (folder child number)
+ (elmo-emit-signal
+ 'flag-changed folder
+ (car (elmo-multi-map-numbers folder child (list number)))))
+ (elmo-define-signal-filter (folder sender)
+ (memq sender (elmo-multi-folder-children-internal folder)))))
+
+(defun elmo-multi-map-numbers (folder child numbers)
+ (let ((multi (catch 'found
+ (let ((children (elmo-multi-folder-children-internal folder))
+ (index 0))
+ (while children
+ (setq index (1+ index))
+ (when (eq (car children) child)
+ (throw 'found index))
+ (setq children (cdr children)))))))
+ (when multi
+ (let ((offset (* (elmo-multi-folder-divide-number-internal folder)
+ multi)))
+ (mapcar (lambda (number) (+ offset number))
+ numbers)))))
+
+
(luna-define-method elmo-folder-open-internal ((folder elmo-multi-folder))
(dolist (fld (elmo-multi-folder-children-internal folder))
(elmo-folder-open-internal fld)))
(luna-define-method elmo-message-set-cached ((folder elmo-multi-folder)
number cached)
(let ((pair (elmo-multi-real-folder-number folder number)))
- (elmo-message-set-cached (car pair) (cdr pair) cached))
- (elmo-folder-notify-event folder 'cache-changed number))
+ (elmo-message-set-cached (car pair) (cdr pair) cached)))
(luna-define-method elmo-find-fetch-strategy ((folder elmo-multi-folder)
number
number strategy
&optional unseen section)
(let ((pair (elmo-multi-real-folder-number folder number)))
- (when (elmo-message-fetch (car pair) (cdr pair)
- strategy unseen section)
- (unless unseen
- (elmo-folder-notify-event folder 'flag-changed (list number)))
- t)))
+ (elmo-message-fetch (car pair) (cdr pair) strategy unseen section)))
(luna-define-method elmo-folder-delete-messages ((folder elmo-multi-folder)
numbers)
flag
&optional is-local)
(dolist (pair (elmo-multi-make-folder-numbers-list folder numbers))
- (elmo-folder-set-flag (car pair) (cdr pair) flag is-local))
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ (elmo-folder-set-flag (car pair) (cdr pair) flag is-local)))
(luna-define-method elmo-folder-unset-flag ((folder elmo-multi-folder)
numbers
&optional is-local)
(dolist (pair (elmo-multi-make-folder-numbers-list folder numbers))
(ignore-errors
- (elmo-folder-unset-flag (car pair) (cdr pair) flag is-local)))
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ (elmo-folder-unset-flag (car pair) (cdr pair) flag is-local))))
(luna-define-method elmo-folder-list-flagged ((folder elmo-multi-folder)
flag
;;
(require 'elmo)
+(require 'elmo-signal)
(defvar elmo-pipe-folder-copied-filename "copied"
"Copied messages number set.")
(elmo-pipe-folder-set-copy-internal folder
(string= ":"
(elmo-match-string 2 name))))
+ (elmo-pipe-connect-signals folder (elmo-pipe-folder-dst-internal folder))
folder)
+(defun elmo-pipe-connect-signals (folder destination)
+ (elmo-connect-signal
+ destination 'flag-changing folder
+ (elmo-define-signal-handler (folder dst number old-flags new-flags)
+ (elmo-emit-signal 'flag-changing folder number old-flags new-flags)))
+ (elmo-connect-signal
+ destination 'flag-changed folder
+ (elmo-define-signal-handler (folder dst numbers)
+ (elmo-emit-signal 'flag-changed folder numbers)))
+ (elmo-connect-signal
+ destination 'cache-changed folder
+ (elmo-define-signal-handler (folder dst number)
+ (elmo-emit-signal 'cache-changed folder number))))
+
(luna-define-method elmo-folder-get-primitive-list ((folder elmo-pipe-folder))
(nconc
(elmo-folder-get-primitive-list (elmo-pipe-folder-src-internal folder))
(luna-define-method elmo-message-fetch ((folder elmo-pipe-folder)
number strategy
&optional unseen section)
- (when (elmo-message-fetch (elmo-pipe-folder-dst-internal folder)
- number strategy unseen section)
- (unless unseen
- (elmo-folder-notify-event folder 'flag-changed (list number)))
- t))
+ (elmo-message-fetch (elmo-pipe-folder-dst-internal folder)
+ number strategy unseen section))
(luna-define-method elmo-folder-clear :after ((folder elmo-pipe-folder)
&optional keep-killed)
flag
&optional is-local)
(elmo-folder-set-flag (elmo-pipe-folder-dst-internal folder)
- numbers flag is-local)
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ numbers flag is-local))
(luna-define-method elmo-folder-unset-flag ((folder elmo-pipe-folder)
numbers
flag
&optional is-local)
(elmo-folder-unset-flag (elmo-pipe-folder-dst-internal folder)
- numbers flag is-local)
- (elmo-folder-notify-event folder 'flag-changed numbers))
+ numbers flag is-local))
(luna-define-method elmo-folder-pack-numbers ((folder elmo-pipe-folder))
(elmo-folder-pack-numbers (elmo-pipe-folder-dst-internal folder)))
(luna-define-method elmo-message-set-cached ((folder elmo-pipe-folder)
number cached)
(elmo-message-set-cached (elmo-pipe-folder-dst-internal folder)
- number cached)
- (elmo-folder-notify-event folder 'cache-changed number))
+ number cached))
(luna-define-method elmo-find-fetch-strategy ((folder elmo-pipe-folder)
number
--- /dev/null
+;;; elmo-signal.el --- "signal-slot" abstraction for routing events
+
+;; Copyright (C) 1998-2003 Daiki Ueno <ueno@unixuser.org>
+
+;; Author: Daiki Ueno <ueno@unixuser.org>
+;; Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+;; Keywords: mail, net news
+
+;; This file is part of ELMO (Elisp Library for Message Orchestration).
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+;;
+
+;;; Commentary:
+
+;;; This module implements Qt like "signal-slot" abstraction for
+;;; routing events.
+
+;;; Based on riece-signal.el.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defvar elmo-signal-slot-obarray
+ (make-vector 31 0))
+
+(defun elmo-make-slot (source listener function &optional filter handback)
+ "Make an instance of slot object.
+Arguments are corresponding to callback function, filter function, and
+a handback object, respectively.
+This function is for internal use only."
+ (vector source listener function filter handback))
+
+(defun elmo-slot-source (slot)
+ "Return the source of SLOT.
+This function is for internal use only."
+ (aref slot 0))
+
+(defun elmo-slot-listener (slot)
+ "Return the listener of SLOT.
+This function is for internal use only."
+ (aref slot 1))
+
+(defun elmo-slot-function (slot)
+ "Return the callback function of SLOT.
+This function is for internal use only."
+ (aref slot 2))
+
+(defun elmo-slot-filter (slot)
+ "Return the filter function of SLOT.
+This function is for internal use only."
+ (aref slot 3))
+
+(defun elmo-slot-handback (slot)
+ "Return the handback object of SLOT.
+This function is for internal use only."
+ (aref slot 4))
+
+(put 'elmo-define-signal 'lisp-indent-function 'defun)
+(defmacro elmo-define-signal (name args &optional doc)
+ `(setplist ',name (list 'elmo-signal-args ',args
+ 'elmo-signal-docstring ,doc)))
+
+(defun elmo-signal-name (signal)
+ "Return the name of SIGNAL."
+ signal)
+
+(defun elmo-signal-args (signal)
+ "Return the argument list of SIGNAL."
+ (get signal 'elmo-signal-args))
+
+(defun elmo-signal-docstring (signal)
+ "Return the docment string of SIGNAL."
+ (get signal 'elmo-signal-docstring))
+
+(defun elmo-signal-bindings (source listener args handback arg-list)
+ (let ((i 0)
+ bindings)
+ (when (car arg-list)
+ (setq bindings (list (list (car arg-list) listener))))
+ (when (setq arg-list (cdr arg-list))
+ (setq bindings (nconc bindings
+ (list (list (car arg-list) source)))))
+ (while (and (setq arg-list (cdr arg-list))
+ (not (eq (car arg-list) '&optional)))
+ (setq bindings (nconc bindings
+ (list (list (car arg-list) (list 'nth i args))))
+ i (1+ i)))
+ (when (and handback
+ (setq arg-list (cdr arg-list)))
+ (setq bindings (nconc bindings
+ (list (list (car arg-list) handback)))))
+ bindings))
+
+(defmacro elmo-define-signal-handler (args &rest body)
+ (let ((source (make-symbol "--source--"))
+ (listener (make-symbol "--listener--"))
+ (argument (make-symbol "--argument--"))
+ (handback (make-symbol "--handback--")))
+ `(lambda (,listener ,source ,argument ,handback)
+ (let ,(elmo-signal-bindings source listener argument handback args)
+ ,@body))))
+
+(put 'elmo-define-signal-handler 'lisp-indent-function 'defun)
+(def-edebug-spec elmo-define-signal-handler
+ (&define (arg [&rest arg] [&optional ["&optional" arg &rest arg]])
+ def-body))
+
+(defmacro elmo-define-signal-filter (args &rest body)
+ (let ((source (make-symbol "--source--"))
+ (listener (make-symbol "--listener--"))
+ (argument (make-symbol "--argument--")))
+ `(lambda (,listener ,source ,argument)
+ (let ,(elmo-signal-bindings source listener argument nil args)
+ ,@body))))
+
+(put 'elmo-define-signal-filter 'lisp-indent-function 'defun)
+(def-edebug-spec elmo-define-signal-filter
+ (&define (arg [&rest arg])
+ def-body))
+
+(defun elmo-connect-signal (source signal-name listener function
+ &optional filter handback)
+ "Add FUNCTION as a listener of a signal identified by SIGNAL-NAME."
+ (let ((symbol (intern (symbol-name signal-name) elmo-signal-slot-obarray)))
+ (set symbol (cons (elmo-make-slot source listener function filter handback)
+ (if (boundp symbol)
+ (symbol-value symbol))))))
+
+(defun elmo-disconnect-signal (signal-name listener &optional function)
+ "Remove FUNCTION from the listener of the signal identified by SIGNAL-NAME."
+ (let* ((symbol (intern-soft (symbol-name signal-name)
+ elmo-signal-slot-obarray))
+ (slots (symbol-value symbol)))
+ (while slots
+ (when (and (eq (elmo-slot-listener (car slots)) listener)
+ (or (null function)
+ (eq (elmo-slot-function (car slots)) function)))
+ (set symbol (delq (car slots) (symbol-value symbol))))
+ (setq slots (cdr slots)))))
+
+(defun elmo-clear-signal-slots ()
+ "Remove all functions from listeners list."
+ (fillarray elmo-signal-slot-obarray 0))
+
+(defun elmo-emit-signal (signal-name source &rest args)
+ "Emit SIGNAL."
+ (let ((symbol (intern-soft (symbol-name signal-name)
+ elmo-signal-slot-obarray))
+ signal)
+ (when symbol
+ (dolist (slot (symbol-value symbol))
+ (ignore-errors
+ (when (and (or (null (elmo-slot-source slot))
+ (eq (elmo-slot-source slot) source))
+ (or (null (elmo-slot-filter slot))
+ (ignore-errors
+ (funcall (elmo-slot-filter slot)
+ (elmo-slot-listener slot)
+ (elmo-slot-source slot)
+ args))))
+ (funcall (elmo-slot-function slot)
+ (elmo-slot-listener slot)
+ (elmo-slot-source slot)
+ args
+ (elmo-slot-handback slot))))))))
+
+(require 'product)
+(product-provide (provide 'elmo-signal) (require 'elmo-version))
+
+;;; elmo-signal.el ends here
(require 'elmo-vars)
(require 'elmo-util)
(require 'elmo-msgdb)
+(require 'elmo-signal)
(eval-when-compile (require 'cl))
(elmo-define-error 'elmo-authenticate-error "Login failed" 'elmo-open-error)
(elmo-define-error 'elmo-imap4-bye-error "IMAP4 session was terminated" 'elmo-open-error)
+;; Event declarations
+(elmo-define-signal flag-changing (number old-flags new-flags)
+ "Notify the changing flag of the messages with NUMBER.")
+
+(elmo-define-signal flag-changed (numbers)
+ "Notify the change flag of the messages with NUMBERS.")
+
+(elmo-define-signal cache-changed (number)
+ "Notify the change cache status of the message with NUMBER.")
+
;; autoloads
(eval-and-compile
(autoload 'md5 "md5")
persistent ; non-nil if persistent.
process-duplicates ; read or hide
biff ; folder for biff
- handlers ; list of event handler.
))
(luna-define-internal-accessors 'elmo-folder))
(if cached
(elmo-msgdb-set-flag (elmo-folder-msgdb folder) number 'cached)
(elmo-msgdb-unset-flag (elmo-folder-msgdb folder) number 'cached))
- (elmo-folder-notify-event folder 'cache-changed number))
+ (elmo-emit-signal 'cache-changed folder number))
(defun elmo-message-copy-entity (entity)
(elmo-msgdb-copy-message-entity (elmo-message-entity-handler entity)
&optional is-local)
(when (elmo-folder-msgdb-internal folder)
(dolist (number numbers)
- (when (elmo-global-flag-p flag)
- (let ((message-id (elmo-message-field folder number 'message-id)))
- (elmo-global-flag-set flag folder number message-id)))
- (elmo-msgdb-set-flag (elmo-folder-msgdb folder)
- number
- flag))
- (elmo-folder-notify-event folder 'flag-changed numbers)))
+ (let ((old-flags (elmo-message-flags folder number)))
+ (when (elmo-global-flag-p flag)
+ (let ((message-id (elmo-message-field folder number 'message-id)))
+ (elmo-global-flag-set flag folder number message-id)))
+ (elmo-msgdb-set-flag (elmo-folder-msgdb folder) number flag)
+ (elmo-emit-signal 'flag-changing
+ folder
+ number
+ old-flags
+ (elmo-message-flags folder number))))
+ (elmo-emit-signal 'flag-changed folder numbers)))
(defun elmo-message-has-global-flag-p (folder number)
"Return non-nil when the message in the FOLDER with NUMBER has global flag."
&optional is-local)
(when (elmo-folder-msgdb-internal folder)
(dolist (number numbers)
- (when (elmo-global-flag-p flag)
- (elmo-global-flag-detach flag folder number 'always))
- (elmo-msgdb-unset-flag (elmo-folder-msgdb folder)
- number
- flag))
- (elmo-folder-notify-event folder 'flag-changed numbers)))
+ (let ((old-flags (elmo-message-flags folder number)))
+ (when (elmo-global-flag-p flag)
+ (elmo-global-flag-detach flag folder number 'always))
+ (elmo-msgdb-unset-flag (elmo-folder-msgdb folder) number flag)
+ (elmo-emit-signal 'flag-changing
+ folder
+ number
+ old-flags
+ (elmo-message-flags folder number))))
+ (elmo-emit-signal 'flag-changed folder numbers)))
(luna-define-method elmo-folder-process-crosspost ((folder elmo-folder))
;; Do nothing.
(elmo-make-directory temp-dir)
temp-dir))
-;; Event notification/observer framework
-(eval-and-compile
- (luna-define-class elmo-event-handler ()))
-
-(luna-define-generic elmo-event-handler-flag-changed (handler numbers)
- "Notify flag of the messages with NUMBERS is changed.")
-
-(luna-define-generic elmo-event-handler-cache-changed (handler number)
- "Called when cache status of the message with NUMBER is changed.")
-
-(defun elmo-folder-add-handler (folder handler)
- (unless (memq handler (elmo-folder-handlers-internal folder))
- (elmo-folder-set-handlers-internal
- folder
- (cons handler (elmo-folder-handlers-internal folder)))))
-
-(defun elmo-folder-remove-handler (folder handler)
- (elmo-folder-set-handlers-internal
- folder
- (delq handler (elmo-folder-handlers-internal folder))))
-
-(defun elmo-folder-notify-event (folder event &rest args)
- (when (elmo-folder-handlers-internal folder)
- (let ((message (format "elmo-event-handler-%s" event)))
- (dolist (handler (elmo-folder-handlers-internal folder))
- (apply #'luna-send handler message handler args)))))
-
;;;
(defun elmo-init ()
"Initialize ELMO module."
2005-02-18 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
+ * wl.el (wl-exit): Call `elmo-clear-signal-slots'.
+
+ * wl-summary.el (wl-summary-buffer-event-handler): Abolish.
+ (wl-summary-event-handler): Ditto.
+ (wl-summary-update-persistent-mark-on-event): New
+ function (renamed from `elmo-event-handler-flag-changed').
+ (wl-summary-buffer-attach): New function.
+ (wl-summary-buffer-detach): Rewrite by `elmo-signal'.
+ (wl-summary-buffer-set-folder): Use `wl-summary-buffer-attach'
+ instead of `elmo-folder-add-handler'.
+
* Version number is increased to 2.13.2.
2005-02-14 Hiroya Murata <lapis-lazuli@pop06.odn.ne.jp>
(defvar wl-summary-buffer-mode-line nil)
(defvar wl-summary-buffer-display-mime-mode 'mime)
(defvar wl-summary-buffer-display-header-mode 'partial)
-(defvar wl-summary-buffer-event-handler nil)
(defvar wl-thread-indent-level-internal nil)
(defvar wl-thread-have-younger-brother-str-internal nil)
(make-variable-buffer-local 'wl-summary-buffer-mode-line)
(make-variable-buffer-local 'wl-summary-buffer-display-mime-mode)
(make-variable-buffer-local 'wl-summary-buffer-display-header-mode)
-(make-variable-buffer-local 'wl-summary-buffer-event-handler)
(defvar wl-datevec)
(defvar wl-thr-indent-string)
'nomini frame))))
;; Handler of event from elmo-folder
-(eval-and-compile
- (luna-define-class wl-summary-event-handler (elmo-event-handler)
- (buffer))
- (luna-define-internal-accessors 'wl-summary-event-handler))
-
-(luna-define-method elmo-event-handler-flag-changed ((handler
- wl-summary-event-handler)
- numbers)
+(defun wl-summary-update-persistent-mark-on-event (buffer numbers)
(save-excursion
- (set-buffer (wl-summary-event-handler-buffer-internal handler))
+ (set-buffer buffer)
(if wl-summary-lazy-update-mark
(let ((window-list (get-buffer-window-list (current-buffer) 'nomini t))
invalidate)
(wl-summary-jump-to-msg number))
(wl-summary-update-persistent-mark number))))))
-(luna-define-method elmo-event-handler-cache-changed
- ((handler wl-summary-event-handler) number)
- (save-excursion
- (set-buffer (wl-summary-event-handler-buffer-internal handler))
- (if wl-summary-lazy-update-mark
- (let ((window-list (get-buffer-window-list (current-buffer) 'nomini t)))
- (when (wl-summary-message-visible-p number)
- (if (catch 'visible
- (let ((window-list window-list)
- win)
- (while (setq win (car window-list))
- (when (wl-summary-jump-to-msg number
- (window-start win)
- (window-end win))
- (throw 'visible t))
- (setq window-list (cdr window-list)))))
- (wl-summary-update-persistent-mark number)
- (wl-summary-invalidate-persistent-mark)
- (dolist (win window-list)
- (wl-summary-validate-persistent-mark
- (window-start win)
- (window-end win))))))
- (when (and (wl-summary-message-visible-p number)
- (wl-summary-jump-to-msg number))
- (wl-summary-update-persistent-mark number)))))
+(defun wl-summary-buffer-attach ()
+ (when wl-summary-buffer-elmo-folder
+ (elmo-connect-signal
+ wl-summary-buffer-elmo-folder
+ 'flag-changed
+ (current-buffer)
+ (elmo-define-signal-handler (buffer folder numbers)
+ (wl-summary-update-persistent-mark-on-event buffer numbers)))
+ (elmo-connect-signal
+ wl-summary-buffer-elmo-folder
+ 'cache-changed
+ (current-buffer)
+ (elmo-define-signal-handler (buffer folder number)
+ (wl-summary-update-persistent-mark-on-event buffer (list number))))))
(defun wl-summary-buffer-detach ()
(when (and (eq major-mode 'wl-summary-mode)
- wl-summary-buffer-elmo-folder
- wl-summary-buffer-event-handler)
- (elmo-folder-remove-handler wl-summary-buffer-elmo-folder
- wl-summary-buffer-event-handler)))
+ wl-summary-buffer-elmo-folder)
+ (elmo-disconnect-signal 'flag-changed (current-buffer))
+ (elmo-disconnect-signal 'cache-changed (current-buffer))))
(defun wl-status-update ()
(interactive)
(setq wl-summary-buffer-persistent
(wl-folder-persistent-p (elmo-folder-name-internal folder)))
(elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent)
- (elmo-folder-add-handler folder
- (setq wl-summary-buffer-event-handler
- (luna-make-entity
- 'wl-summary-event-handler
- :buffer (current-buffer))))
+ (wl-summary-buffer-attach)
;; process duplicates.
(elmo-folder-set-process-duplicates-internal
folder (cdr (elmo-string-matched-assoc
(elmo-quit)
(when wl-use-acap (funcall (symbol-function 'wl-acap-exit)))
(wl-biff-stop)
+ (elmo-clear-signal-slots)
(elmo-passwd-alist-clear)
(run-hooks 'wl-exit-hook)
(wl-save-status)