start firing notifications when the default server changes

r=scottip


git-svn-id: svn://10.0.0.236/trunk@64337 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
alecf%netscape.com
2000-03-28 07:16:04 +00:00
parent 241ac44a44
commit e245c83e46
3 changed files with 182 additions and 6 deletions

View File

@@ -28,6 +28,7 @@
#include "nsIIncomingServerListener.idl"
interface nsIMsgFolderCache;
interface nsIFolderListener;
[scriptable, uuid(6ed2cc00-e623-11d2-b7fc-00805f05ffa5)]
interface nsIMsgAccountManager : nsISupports {
@@ -131,8 +132,14 @@ interface nsIMsgAccountManager : nsISupports {
void CloseCachedConnections();
void addRootFolderListener(in nsIFolderListener listener);
void removeRootFolderListener(in nsIFolderListener listener);
// these are going away in favor of add/removeRootFolderListener
void AddIncomingServerListener(in nsIIncomingServerListener serverListener);
void RemoveIncomingServerListener(in nsIIncomingServerListener serverListener);
// these are going away in favor of nsIFolder::NotifyEvent(in nsIAtom event);
void NotifyServerLoaded(in nsIMsgIncomingServer server);
void NotifyServerUnloaded(in nsIMsgIncomingServer server);
};

View File

@@ -54,6 +54,7 @@
#include "nsString.h"
#include "nsIMsgBiffManager.h"
#include "nsIObserverService.h"
#include "nsIMsgMailSession.h"
#if defined(DEBUG_alecf) || defined(DEBUG_sspitzer_) || defined(DEBUG_seth_)
#define DEBUG_ACCOUNTMANAGER 1
@@ -77,6 +78,7 @@ static NS_DEFINE_CID(kSmtpServiceCID, NS_SMTPSERVICE_CID);
static NS_DEFINE_CID(kFileLocatorCID, NS_FILELOCATOR_CID);
static NS_DEFINE_IID(kIFileLocatorIID, NS_IFILELOCATOR_IID);
static NS_DEFINE_CID(kMsgFolderCacheCID, NS_MSGFOLDERCACHE_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
// use this to search for all servers with the given hostname/iid and
// put them in "servers"
@@ -154,6 +156,8 @@ nsresult nsMsgAccountManager::Init()
rv = NS_NewISupportsArray(getter_AddRefs(m_incomingServerListeners));
if(NS_FAILED(rv)) return rv;
rv = NS_NewISupportsArray(getter_AddRefs(mFolderListeners));
NS_WITH_SERVICE (nsIObserverService, observerService, NS_OBSERVERSERVICE_PROGID, &rv);
if (NS_SUCCEEDED(rv))
{
@@ -313,7 +317,7 @@ nsMsgAccountManager::createKeyedIdentity(const char* key,
nsStringKey hashKey(key);
// addref for the hash table
// addref for the hash table`
nsISupports* idsupports = identity;
NS_ADDREF(idsupports);
m_identities.Put(&hashKey, (void *)idsupports);
@@ -435,12 +439,42 @@ nsMsgAccountManager::createKeyedServer(const char* key,
NS_ADDREF(serversupports);
m_incomingServers.Put(&hashKey, serversupports);
// now add all listeners that are supposed to be
// waiting on root folders
nsCOMPtr<nsIFolder> rootFolder;
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
mFolderListeners->EnumerateForwards(addListenerToFolder, (void *)rootFolder);
*aServer = server;
NS_ADDREF(*aServer);
return NS_OK;
}
PRBool
nsMsgAccountManager::addListenerToFolder(nsISupports *element, void *data)
{
nsresult rv;
nsIFolder *rootFolder = (nsIFolder *)data;
nsCOMPtr<nsIFolderListener> listener = do_QueryInterface(element, &rv);
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rootFolder->AddFolderListener(listener);
return PR_TRUE;
}
PRBool
nsMsgAccountManager::removeListenerFromFolder(nsISupports *element, void *data)
{
nsresult rv;
nsIFolder *rootFolder = (nsIFolder *)data;
nsCOMPtr<nsIFolderListener> listener = do_QueryInterface(element, &rv);
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rootFolder->RemoveFolderListener(listener);
return PR_TRUE;
}
NS_IMETHODIMP
nsMsgAccountManager::DuplicateAccount(nsIMsgAccount *aAccount)
{
@@ -498,8 +532,14 @@ nsMsgAccountManager::RemoveAccount(nsIMsgAccount *aAccount)
// remove reference from hashtable
NS_IF_RELEASE(removedServer);
nsCOMPtr<nsIFolder> rootFolder;
server->GetRootFolder(getter_AddRefs(rootFolder));
mFolderListeners->EnumerateForwards(removeListenerFromFolder,
(void*)rootFolder);
NotifyServerUnloaded(server);
rv = server->RemoveFiles();
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to remove the files associated with server");
@@ -622,18 +662,53 @@ nsMsgAccountManager::GetDefaultAccount(nsIMsgAccount * *aDefaultAccount)
NS_IMETHODIMP
nsMsgAccountManager::SetDefaultAccount(nsIMsgAccount * aDefaultAccount)
{
// TODO make sure it's in the account list
if (aDefaultAccount)
m_defaultAccount = dont_QueryInterface(aDefaultAccount);
else
m_defaultAccount = nsnull;
nsCOMPtr<nsIMsgAccount> oldAccount = m_defaultAccount;
m_defaultAccount = aDefaultAccount;
// it's ok if this fails
setDefaultAccountPref(aDefaultAccount);
// ok if notifications fail
notifyDefaultServerChange(oldAccount, aDefaultAccount);
return NS_OK;
}
// fire notifications
nsresult
nsMsgAccountManager::notifyDefaultServerChange(nsIMsgAccount *aOldAccount,
nsIMsgAccount *aNewAccount)
{
nsresult rv;
nsCOMPtr<nsIMsgIncomingServer> server;
nsCOMPtr<nsIFolder> rootFolder;
// first tell old server it's no longer the default
if (aOldAccount) {
rv = aOldAccount->GetIncomingServer(getter_AddRefs(server));
if (NS_SUCCEEDED(rv) && server) {
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
rootFolder->NotifyBoolPropertyChanged(kDefaultServerAtom,
PR_TRUE, PR_FALSE);
}
}
// now tell new server it is.
if (aNewAccount) {
rv = aNewAccount->GetIncomingServer(getter_AddRefs(server));
if (NS_SUCCEEDED(rv) && server) {
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
rootFolder->NotifyBoolPropertyChanged(kDefaultServerAtom,
PR_FALSE, PR_TRUE);
}
}
return NS_OK;
}
nsresult
nsMsgAccountManager::setDefaultAccountPref(nsIMsgAccount* aDefaultAccount)
{
@@ -908,6 +983,8 @@ nsMsgAccountManager::LoadAccounts()
// for now safeguard multiple calls to this function
if (m_accountsLoaded)
return NS_OK;
kDefaultServerAtom = NS_NewAtom("DefaultServer");
//Ensure biff service has started
NS_WITH_SERVICE(nsIMsgBiffManager, biffService, kMsgBiffManagerCID, &rv);
@@ -991,6 +1068,7 @@ nsresult
nsMsgAccountManager::UnloadAccounts()
{
// release the default account
kDefaultServerAtom = nsnull;
m_defaultAccount=nsnull;
m_incomingServers.Enumerate(hashUnloadServer, this);
@@ -1478,3 +1556,68 @@ nsMsgAccountManager::findServersForIdentity(nsISupports *element, void *aData)
return PR_TRUE;
}
nsresult
nsMsgAccountManager::AddRootFolderListener(nsIFolderListener *aListener)
{
nsresult rv;
// first add listener to the list
rv = mFolderListeners->AppendElement(aListener);
// now add the listener to all loaded accounts
m_incomingServers.Enumerate(addListener, (void *)aListener);
return NS_OK;
}
nsresult
nsMsgAccountManager::RemoveRootFolderListener(nsIFolderListener *aListener)
{
nsresult rv;
// remove the listener from the notification list
rv = mFolderListeners->RemoveElement(aListener);
// remove the listener from the individual folders
m_incomingServers.Enumerate(removeListener, (void *)aListener);
return NS_OK;
}
// enumeration functions
PRBool
nsMsgAccountManager::addListener(nsHashKey *aKey, void *element, void *aData)
{
nsIMsgIncomingServer *server = (nsIMsgIncomingServer *)element;
nsIFolderListener* listener = (nsIFolderListener *)aData;
nsresult rv;
nsCOMPtr<nsIFolder> rootFolder;
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rv = rootFolder->AddFolderListener(listener);
NS_ENSURE_SUCCESS(rv, PR_TRUE);
return PR_TRUE;
}
PRBool
nsMsgAccountManager::removeListener(nsHashKey *aKey, void *element, void *aData)
{
nsIMsgIncomingServer *server = (nsIMsgIncomingServer *)element;
nsIFolderListener* listener = (nsIFolderListener *)aData;
nsresult rv;
nsCOMPtr<nsIFolder> rootFolder;
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
NS_ENSURE_SUCCESS(rv, PR_TRUE);
rv = rootFolder->RemoveFolderListener(listener);
NS_ENSURE_SUCCESS(rv, PR_TRUE);
return PR_TRUE;
}

View File

@@ -55,6 +55,7 @@ private:
PRBool m_accountsLoaded;
nsCOMPtr <nsIMsgFolderCache> m_msgFolderCache;
nsCOMPtr<nsIAtom> kDefaultServerAtom;
nsISupportsArray *m_accounts;
nsHashtable m_identities;
nsHashtable m_incomingServers;
@@ -84,6 +85,10 @@ private:
// sets the pref for the defualt server
nsresult setDefaultAccountPref(nsIMsgAccount *aDefaultAccount);
// fires notifications to the appropriate root folders
nsresult notifyDefaultServerChange(nsIMsgAccount *aOldAccount,
nsIMsgAccount *aNewAccount);
// hash table enumerators
@@ -144,9 +149,30 @@ private:
static char *getUniqueAccountKey(const char* prefix,
nsISupportsArray *accounts);
nsresult SetSendLaterUriPref(nsIMsgIncomingServer *server);
nsresult getPrefService();
nsIPref *m_prefs;
//
// root folder listener stuff
//
// this array is for folder listeners that are supposed to be listening
// on the root folders.
// When a new server is created, all of the the folder listeners
// should be added to the new server
// When a new listener is added, it should be added to all root folders.
// similar for when servers are deleted or listeners removed
nsCOMPtr<nsISupportsArray> mFolderListeners;
// add and remove listeners from the given server
static PRBool addListener(nsHashKey *aKey, void *element, void *aData);
static PRBool removeListener(nsHashKey *aKey, void *element, void *aData);
// folder listener enumerators
static PRBool addListenerToFolder(nsISupports *element, void *data);
static PRBool removeListenerFromFolder(nsISupports *element, void *data);
};