Bug 477680 Improve the nsIMsgSendLater interfaces and tidy a few bits of code. r=bienvenu,sr=Neil
--- a/mail/base/content/mailWindowOverlay.js
+++ b/mail/base/content/mailWindowOverlay.js
@@ -2269,17 +2269,18 @@ function SendUnsentMessages()
var allIdentities = accountManager.allIdentities;
var identitiesCount = allIdentities.Count();
for (var i = 0; i < identitiesCount; i++) {
var currentIdentity = allIdentities.QueryElementAt(i, Components.interfaces.nsIMsgIdentity);
var msgFolder = msgSendlater.getUnsentMessagesFolder(currentIdentity);
if (msgFolder) {
var numMessages = msgFolder.getTotalMessages(false /* include subfolders */);
if(numMessages > 0) {
- msgSendlater.sendUnsentMessages(currentIdentity, msgWindow);
+ msgSendlater.statusFeedback = msgWindow.statusFeedback;
+ msgSendlater.sendUnsentMessages(currentIdentity);
// Right now, all identities point to the same unsent messages
// folder, so to avoid sending multiple copies of the
// unsent messages, we only call messenger.SendUnsentMessages() once.
// See bug #89150 for details.
break;
}
}
}
--- a/mailnews/base/resources/content/mailWindowOverlay.js
+++ b/mailnews/base/resources/content/mailWindowOverlay.js
@@ -2090,17 +2090,18 @@ function SendUnsentMessages()
allIdentities = accountManager.allIdentities;
identitiesCount = allIdentities.Count();
for (var i = 0; i < identitiesCount; i++) {
currentIdentity = allIdentities.QueryElementAt(i, Components.interfaces.nsIMsgIdentity);
msgFolder = msgSendlater.getUnsentMessagesFolder(currentIdentity);
if(msgFolder) {
numMessages = msgFolder.getTotalMessages(false /* include subfolders */);
if(numMessages > 0) {
- msgSendlater.sendUnsentMessages(currentIdentity, msgWindow);
+ msgSendlater.statusFeedback = statusFeedback;
+ msgSendlater.sendUnsentMessages(currentIdentity);
// right now, all identities point to the same unsent messages
// folder, so to avoid sending multiple copies of the
// unsent messages, we only call messenger.SendUnsentMessages() once
// see bug #89150 for details
break;
}
}
}
--- a/mailnews/base/src/nsMsgOfflineManager.cpp
+++ b/mailnews/base/src/nsMsgOfflineManager.cpp
@@ -245,27 +245,30 @@ nsresult nsMsgOfflineManager::SendUnsent
if (numMessages > 0)
{
identityToUse = thisIdentity;
break;
}
}
}
}
- if (identityToUse)
- {
+ if (identityToUse)
+ {
+ if (m_statusFeedback)
+ pMsgSendLater->SetStatusFeedback(m_statusFeedback);
+
pMsgSendLater->AddListener(this);
- rv = pMsgSendLater->SendUnsentMessages(identityToUse, m_window);
+ rv = pMsgSendLater->SendUnsentMessages(identityToUse);
ShowStatus("sendingUnsent");
// if we succeeded, return - we'll run the next operation when the
// send finishes. Otherwise, advance to the next state.
if (NS_SUCCEEDED(rv))
return rv;
- }
- return AdvanceToNextState(rv);
+ }
+ return AdvanceToNextState(rv);
}
#define MESSENGER_STRING_URL "chrome://messenger/locale/messenger.properties"
nsresult nsMsgOfflineManager::ShowStatus(const char *statusMsgName)
{
nsresult res = NS_OK;
@@ -280,18 +283,18 @@ nsresult nsMsgOfflineManager::ShowStatus
res = sBundleService->CreateBundle(propertyURL, getter_AddRefs(mStringBundle));
}
}
if (mStringBundle)
{
nsString statusString;
res = mStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(statusMsgName).get(), getter_Copies(statusString));
- if ( NS_SUCCEEDED(res))
- OnStatus(statusString.get());
+ if (NS_SUCCEEDED(res) && m_statusFeedback)
+ m_statusFeedback->ShowStatusString(statusString);
}
return res;
}
nsresult nsMsgOfflineManager::DownloadOfflineNewsgroups()
{
nsresult rv;
ShowStatus("downloadingNewsgroups");
@@ -392,24 +395,16 @@ NS_IMETHODIMP nsMsgOfflineManager::OnSta
NS_IMETHODIMP nsMsgOfflineManager::OnProgress(PRUint32 aCurrentMessage, PRUint32 aTotalMessage)
{
if (m_statusFeedback && aTotalMessage)
return m_statusFeedback->ShowProgress ((100 * aCurrentMessage) / aTotalMessage);
else
return NS_OK;
}
-NS_IMETHODIMP nsMsgOfflineManager::OnStatus(const PRUnichar *aMsg)
-{
- if (m_statusFeedback && aMsg)
- return m_statusFeedback->ShowStatusString(nsDependentString(aMsg));
- else
- return NS_OK;
-}
-
NS_IMETHODIMP nsMsgOfflineManager::OnStopSending(nsresult aStatus, const PRUnichar *aMsg, PRUint32 aTotalTried,
PRUint32 aSuccessful)
{
#ifdef NS_DEBUG
if (NS_SUCCEEDED(aStatus))
printf("SendLaterListener::OnStopSending: Tried to send %d messages. %d successful.\n",
aTotalTried, aSuccessful);
#endif
--- a/mailnews/compose/public/nsIMsgSendLater.idl
+++ b/mailnews/compose/public/nsIMsgSendLater.idl
@@ -34,38 +34,38 @@
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIStreamListener.idl"
-interface nsIMsgWindow;
+interface nsIMsgStatusFeedback;
interface nsIMsgIdentity;
interface nsIMsgSendLaterListener;
interface nsIMsgFolder;
/**
* nsIMsgSendLater is a service used for sending messages in the background.
* Messages should be saved to an identity's unsent messages folder, and then
* can be sent by calling sendUnsentMessages.
*/
-[scriptable, uuid(5ad3e734-b68e-449e-ad8c-c59da94b2661)]
+[scriptable, uuid(2e2142b2-8f94-4604-8cc7-06a00d59f6b5)]
interface nsIMsgSendLater : nsIStreamListener
{
+ /// Used to obtain status feedback for when messages are sent.
+ attribute nsIMsgStatusFeedback statusFeedback;
+
/**
* Sends any unsent messages in the identity's unsent messages folder.
*
* @param aIdentity The identity to send messages for.
- * @param aWindow The window to give status feedback to whilst messages
- * are being sent.
*/
- void sendUnsentMessages(in nsIMsgIdentity aIdentity,
- [optional] in nsIMsgWindow aWindow);
+ void sendUnsentMessages(in nsIMsgIdentity aIdentity);
/**
* Adds an listener to the service to receive notifications.
*
* @param aListener The listener to add.
*/
void addListener(in nsIMsgSendLaterListener aListener);
--- a/mailnews/compose/public/nsIMsgSendLaterListener.idl
+++ b/mailnews/compose/public/nsIMsgSendLaterListener.idl
@@ -37,43 +37,40 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
/**
* Implement this interface and add to nsIMsgSendLater to receive notifications
* of send later actions.
*/
-[scriptable, uuid(d61d5224-c55a-4428-9c87-340a9bd0b053)]
+[scriptable, uuid(bb9fb203-d615-42d2-962b-447c8326bf79)]
interface nsIMsgSendLaterListener : nsISupports {
/**
- * Notify the observer that the operation of sending all unset messages has
+ * Notify the observer that the operation of sending unsent messages has
* started.
+ *
+ * @param aTotalMessageCount Number of messages to be sent.
*/
- void onStartSending(in PRUint32 aTotalMessageCount);
+ void onStartSending(in unsigned long aTotalMessageCount);
/**
* Notify the observer that progress as occurred for send operation.
+ *
+ * @param aTotalSent The number of messages currently sent.
+ * @param aTotalMessages The total number of messages to be sent.
*/
- void onProgress(in PRUint32 aCurrentMessage, in PRUint32 aTotalMessage);
+ void onProgress(in unsigned long aCurrentMessage,
+ in unsigned long aTotalMessages);
/**
- * Notify the observer with a status message for the send later operation.
- */
- void onStatus(in wstring aMsg);
-
- /**
- * Notify the observer that the message has been sent. This method is
- * called once when the networking library has finished processing the
- * message.
- *
- * This method is called regardless of whether the the operation was
- * successful.
+ * Notify the observer that the send unsent messages operation has finished.
+ * This is called regardless of the success/failure of the operation.
*
* @param aStatus Status code for the message send.
* @param aMsg A text string describing the error.
* @param aTotalTried Total number of messages that were attempted to be sent.
* @param aSuccessful How many messages were successfully sent.
*/
void onStopSending(in nsresult aStatus, in wstring aMsg,
- in PRUint32 aTotalTried, in PRUint32 aSuccessful);
+ in unsigned long aTotalTried, in unsigned long aSuccessful);
};
--- a/mailnews/compose/src/nsMsgSendLater.cpp
+++ b/mailnews/compose/src/nsMsgSendLater.cpp
@@ -99,16 +99,31 @@ nsMsgSendLater::~nsMsgSendLater()
PR_Free(m_newsgroups);
PR_Free(m_newshost);
PR_Free(m_headers);
PR_Free(mLeftoverBuffer);
PR_Free(mIdentityKey);
PR_Free(mAccountKey);
}
+NS_IMETHODIMP
+nsMsgSendLater::SetStatusFeedback(nsIMsgStatusFeedback *aFeedback)
+{
+ mFeedback = aFeedback;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgSendLater::GetStatusFeedback(nsIMsgStatusFeedback **aFeedback)
+{
+ NS_ENSURE_ARG_POINTER(aFeedback);
+ NS_IF_ADDREF(*aFeedback = mFeedback);
+ return NS_OK;
+}
+
// Stream is done...drive on!
NS_IMETHODIMP
nsMsgSendLater::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status)
{
nsresult rv;
// First, this shouldn't happen, but if
// it does, flush the buffer and move on.
@@ -286,73 +301,66 @@ nsMsgSendLater::OnStartRequest(nsIReques
////////////////////////////////////////////////////////////////////////////////////
// This is the listener class for the send operation. We have to create this class
// to listen for message send completion and eventually notify the caller
////////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS2(SendOperationListener, nsIMsgSendListener,
nsIMsgCopyServiceListener)
-SendOperationListener::SendOperationListener(void)
-{
- mSendLater = nsnull;
+SendOperationListener::SendOperationListener(nsMsgSendLater *aSendLater)
+: mSendLater(aSendLater)
+{
}
SendOperationListener::~SendOperationListener(void)
{
}
-nsresult
-SendOperationListener::SetSendLaterObject(nsMsgSendLater *obj)
-{
- mSendLater = obj;
- return NS_OK;
-}
-
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnGetDraftFolderURI(const char *aFolderURI)
{
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnStartSending(const char *aMsgID, PRUint32 aMsgSize)
{
#ifdef NS_DEBUG
printf("SendOperationListener::OnStartSending()\n");
#endif
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnProgress(const char *aMsgID, PRUint32 aProgress, PRUint32 aProgressMax)
{
#ifdef NS_DEBUG
printf("SendOperationListener::OnProgress()\n");
#endif
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnStatus(const char *aMsgID, const PRUnichar *aMsg)
{
#ifdef NS_DEBUG
printf("SendOperationListener::OnStatus()\n");
#endif
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnSendNotPerformed(const char *aMsgID, nsresult aStatus)
{
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnStopSending(const char *aMsgID, nsresult aStatus, const PRUnichar *aMsg,
nsIFile *returnFile)
{
nsresult rv = NS_OK;
if (mSendLater)
{
if (NS_SUCCEEDED(aStatus))
@@ -375,43 +383,43 @@ SendOperationListener::OnStopSending(con
}
}
return rv;
}
// nsIMsgCopyServiceListener
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnStartCopy(void)
{
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnProgress(PRUint32 aProgress, PRUint32 aProgressMax)
{
return NS_OK;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::SetMessageKey(PRUint32 aKey)
{
NS_NOTREACHED("SendOperationListener::SetMessageKey()");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
SendOperationListener::GetMessageId(nsACString& messageId)
{
NS_NOTREACHED("SendOperationListener::GetMessageId()\n");
return NS_ERROR_NOT_IMPLEMENTED;
}
-nsresult
+NS_IMETHODIMP
SendOperationListener::OnStopCopy(nsresult aStatus)
{
if (mSendLater)
{
// Regardless of the success of the copy we will still keep trying
// to send the rest...
nsresult rv;
rv = mSendLater->StartNextMailFileSend();
@@ -500,40 +508,35 @@ nsMsgSendLater::CompleteMailFileSend()
#if 0
// needs cleanup. SetNewspostUrl()?
if (m_newshost)
fields->SetNewshost(m_newshost);
#endif
// Create the listener for the send operation...
- SendOperationListener * sendListener = new SendOperationListener();
+ SendOperationListener *sendListener = new SendOperationListener(this);
if (!sendListener)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(sendListener);
- // set this object for use on completion...
- sendListener->SetSendLaterObject(this);
- nsCOMPtr <nsIMsgStatusFeedback> statusFeedback;
- if (m_window)
- m_window->GetStatusFeedback(getter_AddRefs(statusFeedback));
NS_ADDREF(this); //TODO: We should remove this!!!
rv = pMsgSend->SendMessageFile(identity,
mAccountKey,
compFields, // nsIMsgCompFields *fields,
mTempFile, // nsIFile *sendFile,
PR_TRUE, // PRBool deleteSendFileOnCompletion,
PR_FALSE, // PRBool digest_p,
nsIMsgSend::nsMsgSendUnsent, // nsMsgDeliverMode mode,
nsnull, // nsIMsgDBHdr *msgToReplace,
sendListener,
- statusFeedback,
+ mFeedback,
nsnull);
- NS_IF_RELEASE(sendListener);
+ NS_RELEASE(sendListener);
return rv;
}
nsresult
nsMsgSendLater::StartNextMailFileSend()
{
nsresult rv = NS_OK;
nsCString messageURI;
@@ -642,25 +645,22 @@ nsMsgSendLater::GetUnsentMessagesFolder(
// do send operation
//
// when send is complete
// Copy from Outbox to FCC folder
// Delete from Outbox folder
//
//
NS_IMETHODIMP
-nsMsgSendLater::SendUnsentMessages(nsIMsgIdentity *aIdentity,
- nsIMsgWindow *aWindow)
+nsMsgSendLater::SendUnsentMessages(nsIMsgIdentity *aIdentity)
{
nsresult rv = GetUnsentMessagesFolder(aIdentity,
getter_AddRefs(mMessageFolder));
NS_ENSURE_SUCCESS(rv, rv);
- m_window = aWindow;
-
// ### fix me - if we need to reparse the folder, this will be asynchronous
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = mMessageFolder->GetMessages(getter_AddRefs(enumerator));
NS_ENSURE_SUCCESS(rv, rv);
// copy all the elements in the enumerator into our isupports array....
nsCOMPtr<nsISupports> currentItem;
@@ -1142,22 +1142,16 @@ nsMsgSendLater::NotifyListenersOnStartSe
void
nsMsgSendLater::NotifyListenersOnProgress(PRUint32 aCurrentMessage,
PRUint32 aTotalMessage)
{
NOTIFY_LISTENERS(OnProgress, (aCurrentMessage, aTotalMessage));
}
void
-nsMsgSendLater::NotifyListenersOnStatus(const PRUnichar *aMsg)
-{
- NOTIFY_LISTENERS(OnStatus, (aMsg));
-}
-
-void
nsMsgSendLater::NotifyListenersOnStopSending(nsresult aStatus,
const PRUnichar *aMsg,
PRUint32 aTotalTried,
PRUint32 aSuccessful)
{
// Catch-all, we may have had an issue sending, so we may not be calling
// StartNextMailFileSend to fully finish the sending. Therefore set
// mSendingMessages to false here so that we don't think we're still trying
--- a/mailnews/compose/src/nsMsgSendLater.h
+++ b/mailnews/compose/src/nsMsgSendLater.h
@@ -40,44 +40,42 @@
#include "nsIMsgSendLater.h"
#include "nsCOMArray.h"
#include "nsIMsgFolder.h"
#include "nsIMsgSendListener.h"
#include "nsIMsgSendLaterListener.h"
#include "nsIMsgSendLater.h"
-#include "nsIMsgWindow.h"
+#include "nsIMsgStatusFeedback.h"
#include "nsTObserverArray.h"
////////////////////////////////////////////////////////////////////////////////////
// This is the listener class for the send operation. We have to create this class
// to listen for message send completion and eventually notify the caller
////////////////////////////////////////////////////////////////////////////////////
class nsMsgSendLater;
class SendOperationListener : public nsIMsgSendListener,
public nsIMsgCopyServiceListener
{
public:
- SendOperationListener(void);
- virtual ~SendOperationListener(void);
+ SendOperationListener(nsMsgSendLater *aSendLater);
+ virtual ~SendOperationListener();
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIMsgSendListener interface
NS_DECL_NSIMSGSENDLISTENER
// nsIMsgCopyServiceListener interface
NS_DECL_NSIMSGCOPYSERVICELISTENER
-
- NS_IMETHOD SetSendLaterObject(nsMsgSendLater *obj);
private:
- nsMsgSendLater *mSendLater;
+ nsMsgSendLater *mSendLater;
};
class nsMsgSendLater: public nsIMsgSendLater
{
public:
nsMsgSendLater();
virtual ~nsMsgSendLater();
@@ -101,27 +99,26 @@ public:
nsresult DeliverQueuedLine(char *line, PRInt32 length);
nsresult RebufferLeftovers(char *startBuf, PRUint32 aLen);
nsresult BuildNewBuffer(const char* aBuf, PRUint32 aCount, PRUint32 *totalBufSize);
// methods for listener array processing...
void NotifyListenersOnStartSending(PRUint32 aTotalMessageCount);
void NotifyListenersOnProgress(PRUint32 aCurrentMessage,
PRUint32 aTotalMessage);
- void NotifyListenersOnStatus(const PRUnichar *aMsg);
void NotifyListenersOnStopSending(nsresult aStatus, const PRUnichar *aMsg,
PRUint32 aTotalTried, PRUint32 aSuccessful);
// counters and things for enumeration
PRUint32 mTotalSentSuccessfully;
PRUint32 mTotalSendCount;
nsCOMArray<nsIMsgDBHdr> mMessagesToSend;
nsCOMPtr<nsISimpleEnumerator> mEnumerator;
nsCOMPtr<nsIMsgFolder> mMessageFolder;
- nsCOMPtr<nsIMsgWindow> m_window;
+ nsCOMPtr<nsIMsgStatusFeedback> mFeedback;
// Private Information
private:
nsresult GetIdentityFromKey(const char *aKey, nsIMsgIdentity **aIdentity);
nsTObserverArray<nsCOMPtr<nsIMsgSendLaterListener> > mListenerArray;
nsCOMPtr<nsIMsgDBHdr> mMessage;
--- a/mailnews/compose/test/unit/test_bug474774.js
+++ b/mailnews/compose/test/unit/test_bug474774.js
@@ -30,19 +30,16 @@ msll.prototype = {
// nsIMsgSendLaterListener
onStartSending: function (aTotal) {
this._initialTotal = 1;
do_check_eq(msgSendLater.sendingMessages, true);
},
onProgress: function (aCurrentMessage, aTotal) {
// XXX Enable this function
},
- onStatus: function (aMsg) {
- // XXX Do we really need this?
- },
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
do_test_finished();
print("msll onStopSending\n");
try {
do_check_eq(aStatus, 0);
do_check_eq(aTotal, 1);
do_check_eq(aSuccessful, 1);
do_check_eq(this._initialTotal, 1);
--- a/mailnews/compose/test/unit/test_sendMessageLater.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater.js
@@ -37,19 +37,16 @@ msll.prototype = {
// nsIMsgSendLaterListener
onStartSending: function (aTotal) {
this._initialTotal = 1;
do_check_eq(msgSendLater.sendingMessages, true);
},
onProgress: function (aCurrentMessage, aTotal) {
// XXX Enable this function
},
- onStatus: function (aMsg) {
- // XXX Do we really need this?
- },
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
do_test_finished();
print("msll onStopSending\n");
try {
do_check_eq(aStatus, 0);
do_check_eq(aTotal, 1);
do_check_eq(aSuccessful, 1);
do_check_eq(this._initialTotal, 1);
--- a/mailnews/compose/test/unit/test_sendMessageLater2.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater2.js
@@ -81,19 +81,16 @@ msll.prototype = {
thread.processNextEvent(true);
server.start(SMTP_PORT);
var thread = gThreadManager.currentThread;
while (thread.hasPendingEvents())
thread.processNextEvent(true);
}
},
- onStatus: function (aMsg) {
- // XXX Do we really need this?
- },
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
try {
do_check_eq(aStatus, 0);
do_check_eq(aTotal, aSuccessful);
do_check_eq(msgSendLater.sendingMessages, false);
// XXX This is another send multiple messages hack
if (!transaction) {
--- a/mailnews/compose/test/unit/test_sendMessageLater3.js
+++ b/mailnews/compose/test/unit/test_sendMessageLater3.js
@@ -101,18 +101,16 @@ msll.prototype = {
// nsIMsgSendLaterListener
onStartSending: function (aTotal) {
this._initialTotal = 1;
do_check_eq(msgSendLater.sendingMessages, true);
},
onProgress: function (aCurrentMessage, aTotal) {
},
- onStatus: function (aMsg) {
- },
onStopSending: function (aStatus, aMsg, aTotal, aSuccessful) {
print("msll onStopSending\n");
// NS_ERROR_SMTP_SEND_FAILED_REFUSED is 2153066798
do_check_eq(aStatus, 2153066798);
do_check_eq(aTotal, 1);
do_check_eq(aSuccessful, 0);
do_check_eq(this._initialTotal, 1);