diff --git a/mailnews/compose/public/nsIMsgCompose.idl b/mailnews/compose/public/nsIMsgCompose.idl index fb744626092..ea59670049e 100644 --- a/mailnews/compose/public/nsIMsgCompose.idl +++ b/mailnews/compose/public/nsIMsgCompose.idl @@ -236,6 +236,7 @@ interface nsIMsgCompose : nsISupports { /* set any reply flags on the original message's folder */ [noscript] void processReplyFlags(); + [noscript] void rememberQueuedDisposition(); /* ... */ [noscript] void convertAndLoadComposeWindow(in nsStringRef aPrefix, diff --git a/mailnews/compose/src/nsMsgCompUtils.h b/mailnews/compose/src/nsMsgCompUtils.h index ae954845e0d..e1a348faff9 100644 --- a/mailnews/compose/src/nsMsgCompUtils.h +++ b/mailnews/compose/src/nsMsgCompUtils.h @@ -50,6 +50,12 @@ class nsIPrompt; #define ANY_SERVER "anyfolder://" +// these are msg hdr property names for storing the original +// msg uri's and disposition(replied/forwarded) when queuing +// messages to send later. +#define ORIG_URI_PROPERTY "origURIs" +#define QUEUED_DISPOSITION_PROPERTY "queuedDisposition" + class nsMsgCompUtils : public nsIMsgCompUtils { public: diff --git a/mailnews/compose/src/nsMsgCompose.cpp b/mailnews/compose/src/nsMsgCompose.cpp index 4e36f409caf..0a75844c713 100644 --- a/mailnews/compose/src/nsMsgCompose.cpp +++ b/mailnews/compose/src/nsMsgCompose.cpp @@ -2506,6 +2506,43 @@ void nsMsgCompose::CleanUpRecipients(nsString& recipients) recipients = newRecipient; } +NS_IMETHODIMP nsMsgCompose::RememberQueuedDisposition() +{ + // need to find the msg hdr in the saved folder and then set a property on + // the header that we then look at when we actually send the message. + if (mType == nsIMsgCompType::Reply || + mType == nsIMsgCompType::ReplyAll || + mType == nsIMsgCompType::ReplyToGroup || + mType == nsIMsgCompType::ReplyToSender || + mType == nsIMsgCompType::ReplyToSenderAndGroup || + mType == nsIMsgCompType::ForwardAsAttachment || + mType == nsIMsgCompType::ForwardInline) + { + if (!mOriginalMsgURI.IsEmpty()) + { + nsMsgKey msgKey; + if (mMsgSend) + { + mMsgSend->GetMessageKey(&msgKey); + const char *dispositionSetting = "replied"; + if (mType == nsIMsgCompType::ForwardAsAttachment || + mType == nsIMsgCompType::ForwardInline) + dispositionSetting = "forwarded"; + nsCAutoString msgUri(m_folderName); + msgUri.Insert("-message", 7); // "mailbox: -> "mailbox-message:" + msgUri.Append('#'); + msgUri.AppendInt(msgKey); + nsCOMPtr msgHdr; + nsresult rv = GetMsgDBHdrFromURI(msgUri.get(), getter_AddRefs(msgHdr)); + NS_ENSURE_SUCCESS(rv, rv); + msgHdr->SetStringProperty(ORIG_URI_PROPERTY, mOriginalMsgURI.get()); + msgHdr->SetStringProperty(QUEUED_DISPOSITION_PROPERTY, dispositionSetting); + } + } + } + return NS_OK; +} + nsresult nsMsgCompose::ProcessReplyFlags() { nsresult rv; @@ -2808,6 +2845,9 @@ nsMsgComposeSendListener::OnStopCopy(nsresult aStatus) nsCOMPtrcompose = do_QueryReferent(mWeakComposeObj); if (compose) { + if (mDeliverMode == nsIMsgSend::nsMsgQueueForLater) + compose->RememberQueuedDisposition(); + // Ok, if we are here, we are done with the send/copy operation so // we have to do something with the window....SHOW if failed, Close // if succeeded @@ -2952,15 +2992,15 @@ nsMsgComposeSendListener::RemoveCurrentDraftMessage(nsIMsgCompose *compObj, PRBo NS_ASSERTION(str, "Failed to get current draft id url"); if (str) { - nsMsgKeyArray messageID; - nsCAutoString srcStr(str+1); - PRInt32 num=0, err; - num = srcStr.ToInteger(&err); - if (num != nsMsgKey_None) - { - messageID.Add(num); - rv = imapFolder->StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE, messageID.GetArray(), messageID.GetSize()); - } + nsMsgKeyArray messageID; + nsCAutoString srcStr(str+1); + PRInt32 num=0, err; + num = srcStr.ToInteger(&err); + if (num != nsMsgKey_None) + { + messageID.Add(num); + rv = imapFolder->StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE, messageID.GetArray(), messageID.GetSize()); + } } } } @@ -3404,9 +3444,9 @@ nsMsgCompose::BuildBodyMessageAndSignature() switch (mType) { case nsIMsgCompType::New : - case nsIMsgCompType::Reply : /* should not append! but just in case */ - case nsIMsgCompType::ReplyAll : /* should not append! but just in case */ - case nsIMsgCompType::ForwardAsAttachment : /* should not append! but just in case */ + case nsIMsgCompType::Reply : /* should not happen! but just in case */ + case nsIMsgCompType::ReplyAll : /* should not happen! but just in case */ + case nsIMsgCompType::ForwardAsAttachment : /* should not happen! but just in case */ case nsIMsgCompType::ForwardInline : case nsIMsgCompType::NewsPost : case nsIMsgCompType::ReplyToGroup : diff --git a/mailnews/compose/src/nsMsgCompose.h b/mailnews/compose/src/nsMsgCompose.h index 78669ac491c..66b6d8ae7b1 100644 --- a/mailnews/compose/src/nsMsgCompose.h +++ b/mailnews/compose/src/nsMsgCompose.h @@ -115,9 +115,9 @@ private: nsCString m_folderName; private: - nsresult _SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity, PRBool entityConversionDone); - nsresult CreateMessage(const char * originalMsgURI, MSG_ComposeType type, nsIMsgCompFields* compFields); - void CleanUpRecipients(nsString& recipients); + nsresult _SendMsg(MSG_DeliverMode deliverMode, nsIMsgIdentity *identity, PRBool entityConversionDone); + nsresult CreateMessage(const char * originalMsgURI, MSG_ComposeType type, nsIMsgCompFields* compFields); + void CleanUpRecipients(nsString& recipients); nsresult GetABDirectories(const nsACString& dirUri, nsISupportsArray* directoriesArray, PRBool searchSubDirectory); nsresult BuildMailListArray(nsIAddrDatabase* database, nsIAbDirectory* parentDir, nsISupportsArray* array); nsresult GetMailListAddresses(nsString& name, nsISupportsArray* mailListArray, nsISupportsArray** addresses); @@ -125,6 +125,8 @@ private: nsresult _BodyConvertible(nsIDOMNode *node, PRInt32 *_retval); nsresult SetBodyAttribute(nsIEditor* editor, nsIDOMElement* element, nsString& name, nsString& value); nsresult SetBodyAttributes(nsString& attributes); + + #if !defined(XP_MAC) PRBool IsLastWindow(); #endif /* XP_MAC */ diff --git a/mailnews/compose/src/nsMsgCopy.cpp b/mailnews/compose/src/nsMsgCopy.cpp index 64be53cb18c..911dac8c4cf 100644 --- a/mailnews/compose/src/nsMsgCopy.cpp +++ b/mailnews/compose/src/nsMsgCopy.cpp @@ -184,7 +184,7 @@ nsMsgCopy::nsMsgCopy() nsMsgCopy::~nsMsgCopy() { - PR_FREEIF(mSavePref); + PR_Free(mSavePref); } nsresult @@ -222,25 +222,22 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity, { rv = GetDraftsFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl); isDraft = PR_TRUE; - if (!dstFolder || NS_FAILED(rv)) { - return NS_MSG_UNABLE_TO_SAVE_DRAFT; - } + if (!dstFolder || NS_FAILED(rv)) + return NS_MSG_UNABLE_TO_SAVE_DRAFT; } else if (aMode == nsIMsgSend::nsMsgSaveAsTemplate) // SaveAsTemplate (Templates) { rv = GetTemplatesFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl); isDraft = PR_FALSE; - if (!dstFolder || NS_FAILED(rv) || CHECK_SIMULATED_ERROR(SIMULATED_SEND_ERROR_5)) { + if (!dstFolder || NS_FAILED(rv) || CHECK_SIMULATED_ERROR(SIMULATED_SEND_ERROR_5)) return NS_MSG_UNABLE_TO_SAVE_TEMPLATE; - } } else // SaveInSentFolder (Sent) - nsMsgDeliverNow or nsMsgSendUnsent { rv = GetSentFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl); isDraft = PR_FALSE; - if (!dstFolder || NS_FAILED(rv)) { - return NS_MSG_COULDNT_OPEN_FCC_FOLDER; - } + if (!dstFolder || NS_FAILED(rv)) + return NS_MSG_COULDNT_OPEN_FCC_FOLDER; } mMode = aMode; diff --git a/mailnews/compose/src/nsMsgSend.cpp b/mailnews/compose/src/nsMsgSend.cpp index b9bfe90d7bf..7796b66823e 100644 --- a/mailnews/compose/src/nsMsgSend.cpp +++ b/mailnews/compose/src/nsMsgSend.cpp @@ -461,6 +461,8 @@ nsMsgComposeAndSend::Clear() m_attachments[i].mURL = nsnull; + // is this needed? the destructor for the attachments + // should be freeing these strings. PR_FREEIF (m_attachments [i].m_type); PR_FREEIF (m_attachments [i].m_charset); PR_FREEIF (m_attachments [i].m_override_type); @@ -2737,7 +2739,7 @@ nsMsgComposeAndSend::HackAttachments(const nsMsgAttachmentData *attachments, if (printfString) { SetStatusMessage(printfString); - PR_FREEIF(printfString); + PR_Free(printfString); } /* As SnarfAttachment will call GatherMimeAttachments when it will be done (this is an async process), @@ -3200,24 +3202,14 @@ nsMsgComposeAndSend::DeliverMessage() PRBool mail_p = ((mCompFields->GetTo() && *mCompFields->GetTo()) || (mCompFields->GetCc() && *mCompFields->GetCc()) || (mCompFields->GetBcc() && *mCompFields->GetBcc())); - PRBool news_p = (mCompFields->GetNewsgroups() && - *(mCompFields->GetNewsgroups()) ? PR_TRUE : PR_FALSE); - - if ( m_deliver_mode != nsMsgSaveAsDraft && m_deliver_mode != nsMsgSaveAsTemplate ) { - NS_ASSERTION(mail_p || news_p, "message without destination"); - } + PRBool news_p = mCompFields->GetNewsgroups() && *(mCompFields->GetNewsgroups()); + NS_ASSERTION(!( m_deliver_mode != nsMsgSaveAsDraft && m_deliver_mode != nsMsgSaveAsTemplate) || (mail_p || news_p), "message without destination"); if (m_deliver_mode == nsMsgQueueForLater) - { return QueueForLater(); - } else if (m_deliver_mode == nsMsgSaveAsDraft) - { return SaveAsDraft(); - } else if (m_deliver_mode == nsMsgSaveAsTemplate) - { return SaveAsTemplate(); - } // // Ok, we are about to send the file that we have built up...but what @@ -3246,29 +3238,32 @@ nsMsgComposeAndSend::DeliverMessage() { nsresult ignoreMe; Fail(NS_ERROR_BUT_DONT_SHOW_ALERT, printfString, &ignoreMe); - PR_FREEIF(printfString); + PR_Free(printfString); return NS_ERROR_FAILURE; } else - PR_FREEIF(printfString); + PR_Free(printfString); } } } - if (news_p) { - if (mail_p) { - mSendMailAlso = PR_TRUE; - } - return DeliverFileAsNews(); /* will call DeliverFileAsMail if it needs to */ - } - else if (mail_p) { + if (news_p) + { + if (mail_p) + mSendMailAlso = PR_TRUE; + + return DeliverFileAsNews(); /* will call DeliverFileAsMail if it needs to */ + } + else if (mail_p) + { return DeliverFileAsMail(); - } - else { - return NS_ERROR_UNEXPECTED; - } - + } + else + { + return NS_ERROR_UNEXPECTED; + } + return NS_OK; } @@ -4274,7 +4269,8 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, else turi = GetFolderURIFromUserPrefs(mode, mUserIdentity); status = MessageFolderIsLocal(mUserIdentity, mode, turi, &folderIsLocal); - if (NS_FAILED(status)) { goto FAIL; } + if (NS_FAILED(status)) + goto FAIL; // Tell the user we are copying the message... mComposeBundle->GetStringByID(NS_MSG_START_COPY_MESSAGE, getter_Copies(msg)); @@ -4296,7 +4292,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, if (printfString) { SetStatusMessage(printfString); - PR_FREEIF(printfString); + PR_Free(printfString); } } @@ -4340,7 +4336,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, { PRInt32 len = PL_strlen(buf); n = tempOutfile.write(buf, len); - PR_FREEIF(buf); + PR_Free(buf); if (n != len) { status = NS_ERROR_FAILURE; @@ -4361,7 +4357,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, { PRInt32 len = PL_strlen(buf); n = tempOutfile.write(buf, len); - PR_FREEIF(buf); + PR_Free(buf); if (n != len) { status = NS_ERROR_FAILURE; @@ -4471,7 +4467,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, PRInt32 len = strlen(buf); n = tempOutfile.write(buf, len); PR_Free(buf); - PR_FREEIF(convBcc); + PR_Free(convBcc); if (n != len) { status = NS_ERROR_FAILURE; @@ -4513,7 +4509,6 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, host_and_port ? host_and_port : "", secure_p ? "/secure" : ""); PR_FREEIF(orig_hap); - orig_hap = 0; if (!line) { status = NS_ERROR_OUT_OF_MEMORY; @@ -4522,7 +4517,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, PRInt32 len = PL_strlen(line); n = tempOutfile.write(line, len); - PR_FREEIF(line); + PR_Free(line); if (n != len) { status = NS_ERROR_FAILURE; @@ -4530,8 +4525,7 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, } } - PR_FREEIF(orig_hap); - orig_hap = 0; + PR_Free(orig_hap); } // @@ -4573,10 +4567,9 @@ nsMsgComposeAndSend::MimeDoFCC(nsFileSpec *input_file, } FAIL: - if (ibuffer) - PR_FREEIF(ibuffer); - if (obuffer && obuffer != ibuffer) - PR_FREEIF(obuffer); + PR_Free(ibuffer); + if (obuffer != ibuffer) + PR_Free(obuffer); if (tempOutfile.is_open()) @@ -4605,7 +4598,7 @@ FAIL: // status = StartMessageCopyOperation(mCopyFileSpec, mode, turi); } - PR_FREEIF(turi); + PR_Free(turi); return status; } @@ -4664,8 +4657,7 @@ NS_IMETHODIMP nsMsgComposeAndSend::GetSendReport(nsIMsgSendReport * *aSendReport) { NS_ENSURE_ARG_POINTER(aSendReport); - *aSendReport = mSendReport; - NS_IF_ADDREF(*aSendReport); + NS_IF_ADDREF(*aSendReport = mSendReport); return NS_OK; } @@ -4746,8 +4738,7 @@ NS_IMETHODIMP nsMsgComposeAndSend::GetDeliveryMode(nsMsgDeliverMode *aDeliveryMo NS_IMETHODIMP nsMsgComposeAndSend::GetProgress(nsIMsgProgress **_retval) { NS_ENSURE_ARG(_retval); - *_retval = mSendProgress; - NS_IF_ADDREF(*_retval); + NS_IF_ADDREF(*_retval = mSendProgress); return NS_OK; } @@ -4763,8 +4754,7 @@ NS_IMETHODIMP nsMsgComposeAndSend::GetOutputStream(nsOutputFileStream * *_retval NS_IMETHODIMP nsMsgComposeAndSend::GetRunningRequest(nsIRequest **request) { NS_ENSURE_ARG(request); - *request = mRunningRequest; - NS_IF_ADDREF(*request); + NS_IF_ADDREF(*request = mRunningRequest); return NS_OK; } NS_IMETHODIMP nsMsgComposeAndSend::SetRunningRequest(nsIRequest *request) @@ -4789,8 +4779,7 @@ NS_IMETHODIMP nsMsgComposeAndSend::SetStatus(nsresult aStatus) NS_IMETHODIMP nsMsgComposeAndSend::GetCryptoclosure(nsIMsgComposeSecure ** aCryptoclosure) { NS_ENSURE_ARG(aCryptoclosure); - *aCryptoclosure = m_crypto_closure; - NS_IF_ADDREF(*aCryptoclosure); + NS_IF_ADDREF(*aCryptoclosure = m_crypto_closure); return NS_OK; } diff --git a/mailnews/compose/src/nsMsgSend.h b/mailnews/compose/src/nsMsgSend.h index a8bff7b5533..dea4111ef77 100644 --- a/mailnews/compose/src/nsMsgSend.h +++ b/mailnews/compose/src/nsMsgSend.h @@ -195,18 +195,16 @@ public: // internal callback only. This way, no thread boundry issues and // we can get away without all of the listener array code. // - void (*m_attachments_done_callback) ( - nsresult status, - const PRUnichar *error_msg, - struct nsMsgAttachedFile *attachments); + void (*m_attachments_done_callback) (nsresult status, + const PRUnichar *error_msg, struct nsMsgAttachedFile *attachments); // // Define QueryInterface, AddRef and Release for this class // - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS nsMsgComposeAndSend(); - virtual ~nsMsgComposeAndSend(); + virtual ~nsMsgComposeAndSend(); // Delivery and completion callback routines... @@ -235,11 +233,11 @@ public: // // FCC operations... // - nsresult MimeDoFCC (nsFileSpec *input_file, - nsMsgDeliverMode mode, - const char *bcc_header, - const char *fcc_header, - const char *news_url); + nsresult MimeDoFCC (nsFileSpec *input_file, + nsMsgDeliverMode mode, + const char *bcc_header, + const char *fcc_header, + const char *news_url); // Init() will allow for either message creation without delivery or full // message creation and send operations diff --git a/mailnews/compose/src/nsMsgSendLater.cpp b/mailnews/compose/src/nsMsgSendLater.cpp index e17f65a1d2b..252e6ecf5ca 100644 --- a/mailnews/compose/src/nsMsgSendLater.cpp +++ b/mailnews/compose/src/nsMsgSendLater.cpp @@ -393,6 +393,7 @@ SendOperationListener::OnStopSending(const char *aMsgID, nsresult aStatus, const if (NS_SUCCEEDED(rv) && prefs) prefs->GetBoolPref("mail.really_delete_draft", &deleteMsgs); + mSendLater->SetOrigMsgDisposition(); if (deleteMsgs) { mSendLater->DeleteCurrentMessage(); @@ -719,6 +720,48 @@ nsMsgSendLater::SendUnsentMessages(nsIMsgIdentity *identity) return StartNextMailFileSend(); } +nsresult nsMsgSendLater::SetOrigMsgDisposition() +{ + // We're finished sending a queued message. We need to look at mMessage + // and see if we need to set replied/forwarded + // flags for the original message that this message might be a reply to + // or forward of. + nsXPIDLCString originalMsgURIs; + nsXPIDLCString queuedDisposition; + mMessage->GetStringProperty(ORIG_URI_PROPERTY, getter_Copies(originalMsgURIs)); + mMessage->GetStringProperty(QUEUED_DISPOSITION_PROPERTY, getter_Copies(queuedDisposition)); + if (!queuedDisposition.IsEmpty()) + { + char *uriList = PL_strdup(originalMsgURIs.get()); + if (!uriList) + return NS_ERROR_OUT_OF_MEMORY; + char *newStr = uriList; + char *uri; + while (nsnull != (uri = nsCRT::strtok(newStr, ",", &newStr))) + { + nsCOMPtr msgHdr; + nsresult rv = GetMsgDBHdrFromURI(uri, getter_AddRefs(msgHdr)); + NS_ENSURE_SUCCESS(rv,rv); + if (msgHdr) + { + // get the folder for the message resource + nsCOMPtr msgFolder; + msgHdr->GetFolder(getter_AddRefs(msgFolder)); + if (msgFolder) + { + nsMsgDispositionState dispositionSetting = nsIMsgFolder::nsMsgDispositionState_Replied; + if (queuedDisposition.Equals("forwarded")) + dispositionSetting = nsIMsgFolder::nsMsgDispositionState_Forwarded; + + msgFolder->AddMessageDispositionState(msgHdr, dispositionSetting); + } + } + } + PR_Free(uriList); + } + return NS_OK; +} + nsresult nsMsgSendLater::DeleteCurrentMessage() { diff --git a/mailnews/compose/src/nsMsgSendLater.h b/mailnews/compose/src/nsMsgSendLater.h index a34b6719935..78fa2bf844c 100644 --- a/mailnews/compose/src/nsMsgSendLater.h +++ b/mailnews/compose/src/nsMsgSendLater.h @@ -100,7 +100,7 @@ public: nsresult CompleteMailFileSend(); nsresult DeleteCurrentMessage(); - + nsresult SetOrigMsgDisposition(); // Necessary for creating a valid list of recipients nsresult BuildHeaders(); nsresult DeliverQueuedLine(char *line, PRInt32 length);