From e245c83e46c400a8ea1f9c8beab12bdbe29c787b Mon Sep 17 00:00:00 2001 From: "alecf%netscape.com" Date: Tue, 28 Mar 2000 07:16:04 +0000 Subject: [PATCH] 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 --- .../base/public/nsIMsgAccountManager.idl | 7 + .../mailnews/base/src/nsMsgAccountManager.cpp | 155 +++++++++++++++++- .../mailnews/base/src/nsMsgAccountManager.h | 26 +++ 3 files changed, 182 insertions(+), 6 deletions(-) diff --git a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl index 458e24e782b..973928ee68f 100644 --- a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl +++ b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl @@ -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); }; diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp index 6814168a642..9e8851a76ad 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp @@ -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 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 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 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 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 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 server; + nsCOMPtr 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 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 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; +} + diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.h b/mozilla/mailnews/base/src/nsMsgAccountManager.h index b67e39747e0..9c0ed15d07c 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.h +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.h @@ -55,6 +55,7 @@ private: PRBool m_accountsLoaded; nsCOMPtr m_msgFolderCache; + nsCOMPtr 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 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); };