Mail event system
Warning: The content of this article may be out of date. It was imported from mozilla.org and last updated in 2002.
Mozilla mail requires an event system to notify different subsystems that data has changed. This document describes the system that events are passed amongst the mail objects.
For example, when a folder gets a new message, its total message count increases. The folder pane needs to know that this changed so that it can update the message count so the user can see it.
The key interfaces here are:
- nsIFolder.idl is an interface for storing a hierarchy of objects with properties. This interface is not (should not be) mail-related. nsIFolders each store individual lists of folder listeners which are maintained with addListener() and removeListener(). When a notification is fired on a folder, all of the folder's folder listeners and the mail session itself is notified.
- nsIFolderListener.idl is an interface that an object can implement if it is interested in listening to changes on single folder or on all folders. If the object just needs to be notified about one folder, it should call that folder's addListener method. If the object wants to know about all notifications on all folders, then it should register with the mail session.
- nsIMsgMailSession.idl is a service that acts as a broadcaster for folder notifications. The mail session receives all notifications from all folders, and then forwards it on to any nsIFolderListeners that have registered themselves. The nsIMsgMailSession interface actually only allows adding and removal of listeners - the notifications happen through the nsIFolderListener interface as well.
Each event type has a two methods associated with it:
- Notify*<event> - in the nsIFolder interface, and nsIMsgMailSession interface.
- OnItem*<event> - in the nsIFolderListener interface. The mail session implements this interface.
is the type of event, such as
or the generic
Here is an example of a possible flow of control when a new message is added to a folder. In this example, there is a dialog open that shows properties for this folder including the message count. This dialog is a listener on this particular folder.
- A message is added to an nsImapMailFolder containing 4 messages.
- Because the number of messages in the folder have increased, this change in total message count needs to be broadcast to the world. The folder calls NotifyIntPropertyChanged on itself with the atom that represents "TotalMessages":
this->NotifyIntPropertychanged(kTotalMessagesAtom, 4, 5);.
- NotifyPropertyChanged broadcasts this event to each its nsIFolderListeners by calling OnItemIntPropertyChanged on each listener:
listener->OnIntPropertyChanged(this, kTotalMessagesAtom, 4, 5);
- The dialog is one of these folder-specific listeners. In its implementation of OnIntPropertyChanged, it uses this information to update the message count in the dialog.
- NotifyPropertyChanged then broadcasts this event to the mail session:
mailSession->OnIntPropertyChanged(this, kTotalMessagesAtom, 4, 5);
- The mail session rebroadcasts this information to each of the global listeners that has been registered with it. For each global listener, it calls OnIntPropertyChanged:
listener->OnIntPropertyChanged(folder, kTotalMessagesAtom, 4, 5);
- The folder datasource is a listener on all folders and receives this notification. In its implementation of OnIntPropertyChanged, it notifies RDF (via the nsIRDFObserver system) that the message count has changed. RDF handles the notification by updating the message counts in the folder pane.
At the time this document is being written, these are the current events:
In this example, a listener will be set up to be notified when the message count changes in a folder:
The notification system has two duplicate methods which could be implemented with OnItemEvent/NotifyItemEvent:
. Both of these could be done by making atoms for each of these events and just firing it with NotifyItemEvent.
There are some of redundant methods between the nsIMsgMailSession and the nsIFolderListener interfaces. nsIMsgMailSession also contains a number of other methods that are completely unrealted to folder notification. It would make sense to collapse the nsIMsgMailSession simply into an object that implements the the nsIFolderListener interface to receive notifications from the folders. The notification functions should probably go to an nsIFolderBroadcaster interface or something, since they need to know what folder is being modified.
Last modified: Fri Mar 31 12:22:03 PST 2000