From 88334e22476f9f7c813163224289108392fc823e Mon Sep 17 00:00:00 2001 From: "jefft%netscape.com" Date: Wed, 5 Jul 2000 23:19:24 +0000 Subject: [PATCH] fixed bug 33986 -- IMAP: Quit with unsaved draft, save to draft crashes & bug 44203 -- Closing last mail compose crashes the app; r=alecf git-svn-id: svn://10.0.0.236/trunk@73706 18797224-902f-48f8-a5cc-f745e15eee43 --- .../base/public/nsIMsgAccountManager.idl | 4 ++ .../base/resources/content/widgetglue.js | 35 +++++++++++++ .../mailnews/base/src/nsMsgAccountManager.cpp | 20 ++++++- .../mailnews/base/src/nsMsgAccountManager.h | 1 + .../resources/content/MsgComposeCommands.js | 2 + mozilla/mailnews/compose/src/nsMsgCompose.cpp | 7 +-- mozilla/mailnews/compose/src/nsMsgCompose.h | 4 +- mozilla/mailnews/compose/src/nsMsgCopy.cpp | 52 +++++++++++++++++++ mozilla/mailnews/compose/src/nsMsgCopy.h | 3 ++ .../global/resources/content/globalOverlay.js | 16 +++++- 10 files changed, 134 insertions(+), 10 deletions(-) diff --git a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl index 6fa63434b58..9d86167f84f 100644 --- a/mozilla/mailnews/base/public/nsIMsgAccountManager.idl +++ b/mozilla/mailnews/base/public/nsIMsgAccountManager.idl @@ -92,6 +92,10 @@ interface nsIMsgAccountManager : nsISupports { /* summary of summary files folder cache */ readonly attribute nsIMsgFolderCache folderCache; + + /* are we shutting down */ + readonly attribute boolean shutdownInProgress; + /* * search for the server with the given username, hostname, and type * the type is the same as is specified in the preferences, diff --git a/mozilla/mailnews/base/resources/content/widgetglue.js b/mozilla/mailnews/base/resources/content/widgetglue.js index 340de33cf65..59603afd337 100644 --- a/mozilla/mailnews/base/resources/content/widgetglue.js +++ b/mozilla/mailnews/base/resources/content/widgetglue.js @@ -230,5 +230,40 @@ function MsgToggleSplitter(id) } +function NotifyQuitApplication() +{ + var ObserverService = Components.classes["component://netscape/observer-service"].getService(); + ObserverService = ObserverService.QueryInterface(Components.interfaces.nsIObserverService); + if (ObserverService) + { + try + { + ObserverService.Notify(null, "quit-application", null); + } + catch (ex) + { + // dump("no observer found \n"); + } + } +} + +function LastToClose() +{ + var windowManager = Components.classes['component://netscape/rdf/datasource?name=window-mediator'].getService(); + var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator); + var enumerator = windowManagerInterface.getEnumerator( null ); + var count = 0; + + while ( enumerator.hasMoreElements() && count < 2 ) + { + var windowToClose = enumerator.getNext(); + count++; + } + if (count == 1) + return true; + else + return false; +} + diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp index 27a8b3c0b88..835aa5539d1 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.cpp +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.cpp @@ -128,6 +128,7 @@ nsMsgAccountManager::nsMsgAccountManager() : m_accountsLoaded(PR_FALSE), m_defaultAccount(null_nsCOMPtr()), m_haveShutdown(PR_FALSE), + m_shutdownInProgress(PR_FALSE), m_emptyTrashInProgress(PR_FALSE), m_prefs(0) { @@ -170,6 +171,8 @@ nsresult nsMsgAccountManager::Init() { nsAutoString topic; topic.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID); observerService->AddObserver(this, topic.GetUnicode()); + topic.AssignWithConversion("quit-application"); + observerService->AddObserver(this, topic.GetUnicode()); } return NS_OK; @@ -191,15 +194,30 @@ nsresult nsMsgAccountManager::Shutdown() return NS_OK; } +NS_IMETHODIMP +nsMsgAccountManager::GetShutdownInProgress(PRBool *_retval) +{ + NS_ENSURE_ARG_POINTER(_retval); + *_retval = m_shutdownInProgress; + return NS_OK; +} + NS_IMETHODIMP nsMsgAccountManager::Observe(nsISupports *aSubject, const PRUnichar *aTopic, const PRUnichar *someData) { nsAutoString topicString(aTopic); - nsAutoString shutdownString; shutdownString.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID); + nsAutoString shutdownString; + shutdownString.AssignWithConversion(NS_XPCOM_SHUTDOWN_OBSERVER_ID); + nsAutoString quitApplicationString; + quitApplicationString.AssignWithConversion("quit-application"); if(topicString == shutdownString) { Shutdown(); } + else if (topicString == quitApplicationString) + { + m_shutdownInProgress = PR_TRUE; + } return NS_OK; } diff --git a/mozilla/mailnews/base/src/nsMsgAccountManager.h b/mozilla/mailnews/base/src/nsMsgAccountManager.h index 097bb14ca76..c19053b0f53 100644 --- a/mozilla/mailnews/base/src/nsMsgAccountManager.h +++ b/mozilla/mailnews/base/src/nsMsgAccountManager.h @@ -77,6 +77,7 @@ private: nsCAutoString mAccountKeyList; PRBool m_haveShutdown; + PRBool m_shutdownInProgress; /* internal creation routines - updates m_identities and m_incomingServers */ diff --git a/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js b/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js index 1b7d0dfee06..fa551424321 100644 --- a/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js +++ b/mozilla/mailnews/compose/resources/content/MsgComposeCommands.js @@ -962,6 +962,8 @@ function ComposeCanClose() switch (result.value) { case 0: //Save + if (LastToClose()) + NotifyQuitApplication(); SaveAsDraft(); break; case 1: //Cancel diff --git a/mozilla/mailnews/compose/src/nsMsgCompose.cpp b/mozilla/mailnews/compose/src/nsMsgCompose.cpp index 690d30135bc..eb8f8094ecb 100644 --- a/mozilla/mailnews/compose/src/nsMsgCompose.cpp +++ b/mozilla/mailnews/compose/src/nsMsgCompose.cpp @@ -1138,15 +1138,12 @@ m_compFields->SetCc(recipStrCStr); //////////////////////////////////////////////////////////////////////////////////// QuotingOutputStreamListener::~QuotingOutputStreamListener() { - if (mComposeObj) - NS_RELEASE(mComposeObj); } QuotingOutputStreamListener::QuotingOutputStreamListener(const PRUnichar * originalMsgURI, PRBool quoteHeaders, nsIMsgIdentity *identity) { - mComposeObj = nsnull; mQuoteHeaders = quoteHeaders; mIdentity = identity; @@ -1450,7 +1447,7 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIChannel *aChannel, n } } - NS_IF_RELEASE(mComposeObj); //We are done with it, therefore release it. + mComposeObj = null_nsCOMPtr(); //We are done with it, therefore release it. return rv; } @@ -1624,7 +1621,6 @@ NS_IMPL_QUERY_INTERFACE2(nsMsgComposeSendListener, nsMsgComposeSendListener::nsMsgComposeSendListener(void) { - mComposeObj = nsnull; mDeliverMode = 0; NS_INIT_REFCNT(); @@ -1801,7 +1797,6 @@ NS_IMPL_ISUPPORTS(nsMsgDocumentStateListener, NS_GET_IID(nsIDocumentStateListene nsMsgDocumentStateListener::nsMsgDocumentStateListener(void) { NS_INIT_REFCNT(); - mComposeObj = nsnull; } nsMsgDocumentStateListener::~nsMsgDocumentStateListener(void) diff --git a/mozilla/mailnews/compose/src/nsMsgCompose.h b/mozilla/mailnews/compose/src/nsMsgCompose.h index e0f1432e871..bbe42d45e99 100644 --- a/mozilla/mailnews/compose/src/nsMsgCompose.h +++ b/mozilla/mailnews/compose/src/nsMsgCompose.h @@ -151,7 +151,7 @@ public: NS_IMETHOD SetMimeHeaders(nsIMimeHeaders * headers); private: - nsMsgCompose *mComposeObj; + nsCOMPtr mComposeObj; nsString mMsgBody; nsString mCitePrefix; nsString mSignature; @@ -202,7 +202,7 @@ public: private: - nsMsgCompose *mComposeObj; + nsCOMPtr mComposeObj; MSG_DeliverMode mDeliverMode; }; diff --git a/mozilla/mailnews/compose/src/nsMsgCopy.cpp b/mozilla/mailnews/compose/src/nsMsgCopy.cpp index 6d14517b3d1..be307f06adc 100644 --- a/mozilla/mailnews/compose/src/nsMsgCopy.cpp +++ b/mozilla/mailnews/compose/src/nsMsgCopy.cpp @@ -39,10 +39,14 @@ #include "nsIURL.h" #include "nsMsgComposeStringBundle.h" #include "nsMsgCompUtils.h" +#include "prcmon.h" +#include "nsIMsgImapMailFolder.h" +#include "nsIEventQueueService.h" static NS_DEFINE_CID(kStandardUrlCID, NS_STANDARDURL_CID); static NS_DEFINE_CID(kMsgCopyServiceCID,NS_MSGCOPYSERVICE_CID); static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); //////////////////////////////////////////////////////////////////////////////////// // This is the listener class for the copy operation. We have to create this class @@ -59,6 +63,8 @@ NS_INTERFACE_MAP_END_THREADSAFE CopyListener::CopyListener(void) { mComposeAndSend = nsnull; + mCopyObject = nsnull; + mCopyInProgress = PR_FALSE; NS_INIT_REFCNT(); } @@ -123,6 +129,13 @@ CopyListener::OnStopCopy(nsresult aStatus) #endif } + if (mCopyObject) + { + PR_CEnterMonitor(mCopyObject); + PR_CNotifyAll(mCopyObject); + mCopyInProgress = PR_FALSE; + PR_CExitMonitor(mCopyObject); + } if (mComposeAndSend) mComposeAndSend->NotifyListenersOnStopCopy(aStatus); @@ -246,8 +259,47 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder, return NS_ERROR_OUT_OF_MEMORY; mCopyListener->SetMsgComposeAndSendObject(aMsgSendObj); + nsCOMPtr eventQueue; + + if (aIsDraft) + { + nsCOMPtr imapFolder = + do_QueryInterface(dstFolder); + NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, + NS_MSGACCOUNTMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) return rv; + PRBool shutdownInProgress = PR_FALSE; + rv = accountManager->GetShutdownInProgress(&shutdownInProgress); + + if (NS_SUCCEEDED(rv) && shutdownInProgress && imapFolder) + { + // set the following only when we were in the middle of shutdown + // process + mCopyListener->mCopyObject = do_QueryInterface(tPtr); + mCopyListener->mCopyInProgress = PR_TRUE; + NS_WITH_SERVICE(nsIEventQueueService, pEventQService, + kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, + getter_AddRefs(eventQueue)); + } + } + // ** make sure we have a valid copy listener while waiting for copy + // server to finish + nsCOMPtr aCopyListener = do_QueryInterface(tPtr); + rv = copyService->CopyFileMessage(aDiskFile, dstFolder, aMsgToReplace, aIsDraft, mCopyListener, msgWindow); + // aCopyListener->mCopyInProgress can only be set when we are in the + // middle of the shutdown process + while (aCopyListener->mCopyInProgress) + { + PR_CEnterMonitor(aCopyListener); + PR_CWait(aCopyListener, 1000UL); + PR_CExitMonitor(aCopyListener); + if (eventQueue) + eventQueue->ProcessPendingEvents(); + } } return rv; diff --git a/mozilla/mailnews/compose/src/nsMsgCopy.h b/mozilla/mailnews/compose/src/nsMsgCopy.h index 95eded6538f..3d8f0b7a504 100644 --- a/mozilla/mailnews/compose/src/nsMsgCopy.h +++ b/mozilla/mailnews/compose/src/nsMsgCopy.h @@ -63,6 +63,9 @@ public: NS_IMETHOD OnStopCopy(nsresult aStatus); NS_IMETHOD SetMsgComposeAndSendObject(nsMsgComposeAndSend *obj); + + nsCOMPtr mCopyObject; + PRBool mCopyInProgress; private: nsCOMPtr mComposeAndSend; diff --git a/mozilla/xpfe/global/resources/content/globalOverlay.js b/mozilla/xpfe/global/resources/content/globalOverlay.js index 5a1f1dc49f7..dcd8a817958 100644 --- a/mozilla/xpfe/global/resources/content/globalOverlay.js +++ b/mozilla/xpfe/global/resources/content/globalOverlay.js @@ -1,9 +1,23 @@ function goQuitApplication() { + var ObserverService = Components.classes["component://netscape/observer-service"].getService(); + ObserverService = ObserverService.QueryInterface(Components.interfaces.nsIObserverService); + if (ObserverService) + { + try + { + ObserverService.Notify(null, "quit-application", null); + } + catch (ex) + { + // dump("no observer found \n"); + } + } + var windowManager = Components.classes['component://netscape/rdf/datasource?name=window-mediator'].getService(); var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator); var enumerator = windowManagerInterface.getEnumerator( null ); - + while ( enumerator.hasMoreElements() ) { var windowToClose = enumerator.getNext();