From 3d982b21b06c48c4e48e4b78649412f914ab59d8 Mon Sep 17 00:00:00 2001 From: hmurata Date: Fri, 18 Feb 2005 16:51:11 +0000 Subject: [PATCH 1/1] * WL-ELS (ELMO-MODULES): Added elmo-signal. * 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'. --- ChangeLog | 4 ++ WL-ELS | 3 +- elmo/ChangeLog | 44 ++++++++++++ elmo/elmo-filter.el | 64 ++++++++++++------ elmo/elmo-multi.el | 58 +++++++++++++--- elmo/elmo-pipe.el | 32 ++++++--- elmo/elmo-signal.el | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++ elmo/elmo.el | 75 +++++++++------------ wl/ChangeLog | 11 +++ wl/wl-summary.el | 65 ++++++------------ wl/wl.el | 1 + 11 files changed, 412 insertions(+), 130 deletions(-) create mode 100644 elmo/elmo-signal.el diff --git a/ChangeLog b/ChangeLog index 137f353..7f313f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2005-02-18 Hiroya Murata + + * WL-ELS (ELMO-MODULES): Added elmo-signal. + 2005-01-23 Hiroya Murata * Makefile (compile-strict): New target. diff --git a/WL-ELS b/WL-ELS index b7f8269..2b15946 100644 --- a/WL-ELS +++ b/WL-ELS @@ -16,7 +16,8 @@ (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 diff --git a/elmo/ChangeLog b/elmo/ChangeLog index 4e39628..f2d13ac 100644 --- a/elmo/ChangeLog +++ b/elmo/ChangeLog @@ -1,5 +1,49 @@ 2005-02-18 Hiroya Murata + * 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 diff --git a/elmo/elmo-filter.el b/elmo/elmo-filter.el index efaa0b4..632b095 100644 --- a/elmo/elmo-filter.el +++ b/elmo/elmo-filter.el @@ -30,6 +30,7 @@ ;;; Code: ;; (require 'elmo) +(require 'elmo-signal) (require 'elmo-msgdb) (defvar elmo-filter-number-filename "number-list" @@ -45,8 +46,7 @@ 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 @@ -57,8 +57,35 @@ (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))) @@ -86,6 +113,16 @@ (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 @@ -181,14 +218,8 @@ (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) @@ -345,8 +376,7 @@ (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) @@ -380,21 +410,15 @@ 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) diff --git a/elmo/elmo-multi.el b/elmo/elmo-multi.el index 2a13b79..bfa4259 100644 --- a/elmo/elmo-multi.el +++ b/elmo/elmo-multi.el @@ -31,6 +31,7 @@ (eval-when-compile (require 'cl)) (require 'elmo) +(require 'elmo-signal) (require 'luna) (defvar elmo-multi-divide-number 100000 @@ -67,8 +68,50 @@ (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))) @@ -144,8 +187,7 @@ (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 @@ -247,11 +289,7 @@ 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) @@ -425,8 +463,7 @@ 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 @@ -434,8 +471,7 @@ &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 diff --git a/elmo/elmo-pipe.el b/elmo/elmo-pipe.el index ca07964..1a499e3 100644 --- a/elmo/elmo-pipe.el +++ b/elmo/elmo-pipe.el @@ -30,6 +30,7 @@ ;; (require 'elmo) +(require 'elmo-signal) (defvar elmo-pipe-folder-copied-filename "copied" "Copied messages number set.") @@ -52,8 +53,23 @@ (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)) @@ -79,11 +95,8 @@ (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) @@ -272,16 +285,14 @@ 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))) @@ -363,8 +374,7 @@ (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 diff --git a/elmo/elmo-signal.el b/elmo/elmo-signal.el new file mode 100644 index 0000000..afb8af4 --- /dev/null +++ b/elmo/elmo-signal.el @@ -0,0 +1,185 @@ +;;; elmo-signal.el --- "signal-slot" abstraction for routing events + +;; Copyright (C) 1998-2003 Daiki Ueno + +;; Author: Daiki Ueno +;; Hiroya Murata +;; 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 diff --git a/elmo/elmo.el b/elmo/elmo.el index 3b57f45..df61b7f 100644 --- a/elmo/elmo.el +++ b/elmo/elmo.el @@ -35,6 +35,7 @@ (require 'elmo-vars) (require 'elmo-util) (require 'elmo-msgdb) +(require 'elmo-signal) (eval-when-compile (require 'cl)) @@ -87,6 +88,16 @@ Otherwise, entire fetching of the message is aborted without confirmation." (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") @@ -131,7 +142,6 @@ If a folder name begins with PREFIX, use BACKEND." 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)) @@ -1167,7 +1177,7 @@ If CACHED is t, message is set as cached.") (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) @@ -1287,13 +1297,17 @@ VALUE is a value to set.") &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." @@ -1327,12 +1341,16 @@ If Optional LOCAL is non-nil, don't update server 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. @@ -1661,33 +1679,6 @@ Return a hashtable for newsgroups." (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." diff --git a/wl/ChangeLog b/wl/ChangeLog index b7c5b36..49810e8 100644 --- a/wl/ChangeLog +++ b/wl/ChangeLog @@ -1,5 +1,16 @@ 2005-02-18 Hiroya Murata + * 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 diff --git a/wl/wl-summary.el b/wl/wl-summary.el index 755d1e0..dc066c9 100644 --- a/wl/wl-summary.el +++ b/wl/wl-summary.el @@ -111,7 +111,6 @@ (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) @@ -187,7 +186,6 @@ (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) @@ -649,16 +647,9 @@ See also variable `wl-use-petname'." '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) @@ -686,38 +677,26 @@ See also variable `wl-use-petname'." (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) @@ -900,11 +879,7 @@ you." (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 diff --git a/wl/wl.el b/wl/wl.el index 209e08f..6098d77 100644 --- a/wl/wl.el +++ b/wl/wl.el @@ -672,6 +672,7 @@ Entering Plugged mode calls the value of `wl-plugged-mode-hook'." (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) -- 1.7.10.4