nsresult nsMsgAskBooleanQuestionByID(nsIPrompt * aPrompt, PRInt32 msgID, PRBool *answer, const PRUnichar * windowTitle) { nsresult rv; nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle)); NS_ENSURE_SUCCESS(rv, rv); nsString msg; bundle->GetStringFromID(msgID, getter_Copies(msg)); return nsMsgAskBooleanQuestionByString(aPrompt, msg.get(), answer, windowTitle); }
nsresult nsMsgAttachmentHandler::UrlExit(nsresult status, const PRUnichar* aMsg) { NS_ASSERTION(m_mime_delivery_state != nsnull, "not-null m_mime_delivery_state"); // Close the file, but don't delete the disk file (or the file spec.) if (mOutFile) { mOutFile->Close(); mOutFile = nsnull; } // this silliness is because Windows nsILocalFile caches its file size // so if an output stream writes to it, it will still return the original // cached size. if (mTmpFile) { nsCOMPtr <nsIFile> tmpFile; mTmpFile->Clone(getter_AddRefs(tmpFile)); mTmpFile = do_QueryInterface(tmpFile); } mRequest = nsnull; // First things first, we are now going to see if this is an HTML // Doc and if it is, we need to see if we can determine the charset // for this part by sniffing the HTML file. // This is needed only when the charset is not set already. // (e.g. a charset may be specified in HTTP header) // if (!m_type.IsEmpty() && m_charset.IsEmpty() && m_type.LowerCaseEqualsLiteral(TEXT_HTML)) m_charset = nsMsgI18NParseMetaCharset(mTmpFile); nsresult mimeDeliveryStatus; m_mime_delivery_state->GetStatus(&mimeDeliveryStatus); if (mimeDeliveryStatus == NS_ERROR_ABORT) status = NS_ERROR_ABORT; if (NS_FAILED(status) && status != NS_ERROR_ABORT && NS_SUCCEEDED(mimeDeliveryStatus)) { // At this point, we should probably ask a question to the user // if we should continue without this attachment. // bool keepOnGoing = true; nsCString turl; nsString msg; PRUnichar *printfString = nsnull; nsresult rv; nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle)); NS_ENSURE_SUCCESS(rv, rv); nsMsgDeliverMode mode = nsIMsgSend::nsMsgDeliverNow; m_mime_delivery_state->GetDeliveryMode(&mode); if (mode == nsIMsgSend::nsMsgSaveAsDraft || mode == nsIMsgSend::nsMsgSaveAsTemplate) bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SAVING, getter_Copies(msg)); else bundle->GetStringFromID(NS_MSG_FAILURE_ON_OBJ_EMBED_WHILE_SENDING, getter_Copies(msg)); if (!m_realName.IsEmpty()) printfString = nsTextFormatter::smprintf(msg.get(), m_realName.get()); else if (NS_SUCCEEDED(mURL->GetSpec(turl)) && !turl.IsEmpty()) { nsCAutoString unescapedUrl; MsgUnescapeString(turl, 0, unescapedUrl); if (unescapedUrl.IsEmpty()) printfString = nsTextFormatter::smprintf(msg.get(), turl.get()); else printfString = nsTextFormatter::smprintf(msg.get(), unescapedUrl.get()); } else printfString = nsTextFormatter::smprintf(msg.get(), "?"); nsCOMPtr<nsIPrompt> aPrompt; if (m_mime_delivery_state) m_mime_delivery_state->GetDefaultPrompt(getter_AddRefs(aPrompt)); nsMsgAskBooleanQuestionByString(aPrompt, printfString, &keepOnGoing); PR_FREEIF(printfString); if (keepOnGoing) { status = 0; m_bogus_attachment = true; //That will cause this attachment to be ignored. } else { status = NS_ERROR_ABORT; m_mime_delivery_state->SetStatus(status); nsresult ignoreMe; m_mime_delivery_state->Fail(status, nsnull, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, 0, nsnull); SetMimeDeliveryState(nsnull); return status; } } m_done = true; // // Ok, now that we have the file here on disk, we need to see if there was // a need to do conversion to plain text...if so, the magic happens here, // otherwise, just move on to other attachments... // if (NS_SUCCEEDED(status) && !m_type.LowerCaseEqualsLiteral(TEXT_PLAIN) && m_desiredType.LowerCaseEqualsLiteral(TEXT_PLAIN)) { // // Conversion to plain text desired. // PRInt32 width = 72; nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID)); if (pPrefBranch) pPrefBranch->GetIntPref("mailnews.wraplength", &width); // Let sanity reign! if (width == 0) width = 72; else if (width < 10) width = 10; else if (width > 30000) width = 30000; // // Now use the converter service here to do the right // thing and convert this data to plain text for us! // nsAutoString conData; if (NS_SUCCEEDED(LoadDataFromFile(mTmpFile, conData, true))) { if (NS_SUCCEEDED(ConvertBufToPlainText(conData, UseFormatFlowed(m_charset.get())))) { if (mDeleteFile) mTmpFile->Remove(false); nsCOMPtr<nsIOutputStream> outputStream; nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(outputStream), mTmpFile, PR_WRONLY | PR_CREATE_FILE, 00600); if (NS_SUCCEEDED(rv)) { nsCAutoString tData; if (NS_FAILED(ConvertFromUnicode(m_charset.get(), conData, tData))) LossyCopyUTF16toASCII(conData, tData); if (!tData.IsEmpty()) { PRUint32 bytesWritten; (void) outputStream->Write(tData.get(), tData.Length(), &bytesWritten); } outputStream->Close(); // this silliness is because Windows nsILocalFile caches its file size // so if an output stream writes to it, it will still return the original // cached size. if (mTmpFile) { nsCOMPtr <nsIFile> tmpFile; mTmpFile->Clone(getter_AddRefs(tmpFile)); mTmpFile = do_QueryInterface(tmpFile); } } } } m_type = m_desiredType; m_desiredType.Truncate(); m_encoding.Truncate(); } PRUint32 pendingAttachmentCount = 0; m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); NS_ASSERTION (pendingAttachmentCount > 0, "no more pending attachment"); m_mime_delivery_state->SetPendingAttachmentCount(pendingAttachmentCount - 1); bool processAttachmentsSynchronously = false; m_mime_delivery_state->GetProcessAttachmentsSynchronously(&processAttachmentsSynchronously); if (NS_SUCCEEDED(status) && processAttachmentsSynchronously) { /* Find the next attachment which has not yet been loaded, if any, and start it going. */ PRUint32 i; nsMsgAttachmentHandler *next = 0; nsMsgAttachmentHandler *attachments = nsnull; PRUint32 attachmentCount = 0; m_mime_delivery_state->GetAttachmentCount(&attachmentCount); if (attachmentCount) m_mime_delivery_state->GetAttachmentHandlers(&attachments); for (i = 0; i < attachmentCount; i++) { if (!attachments[i].m_done) { next = &attachments[i]; // // rhp: We need to get a little more understanding to failed URL // requests. So, at this point if most of next is NULL, then we // should just mark it fetched and move on! We probably ignored // this earlier on in the send process. // if ( (!next->mURL) && (next->m_uri.IsEmpty()) ) { attachments[i].m_done = true; m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); m_mime_delivery_state->SetPendingAttachmentCount(pendingAttachmentCount - 1); next->mPartUserOmissionOverride = true; next = nsnull; continue; } break; } } if (next) { int status = next->SnarfAttachment(mCompFields); if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, nsnull, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, 0, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } } } m_mime_delivery_state->GetPendingAttachmentCount(&pendingAttachmentCount); if (pendingAttachmentCount == 0) { // If this is the last attachment, then either complete the // delivery (if successful) or report the error by calling // the exit routine and terminating the delivery. if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, aMsg, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } else { status = m_mime_delivery_state->GatherMimeAttachments (); if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); m_mime_delivery_state->NotifyListenerOnStopSending(nsnull, status, aMsg, nsnull); SetMimeDeliveryState(nsnull); return NS_ERROR_UNEXPECTED; } } } else { // If this is not the last attachment, but it got an error, // then report that error and continue if (NS_FAILED(status)) { nsresult ignoreMe; m_mime_delivery_state->Fail(status, aMsg, &ignoreMe); } } SetMimeDeliveryState(nsnull); return NS_OK; }
/* nsresult displayReport (in nsIPrompt prompt, in boolean showErrorOnly, in boolean dontShowReportTwice); */ NS_IMETHODIMP nsMsgSendReport::DisplayReport(nsIPrompt *prompt, PRBool showErrorOnly, PRBool dontShowReportTwice, nsresult *_retval) { NS_ENSURE_ARG_POINTER(_retval); nsresult currError = NS_OK; mProcessReport[mCurrentProcess]->GetError(&currError); *_retval = currError; if (dontShowReportTwice && mAlreadyDisplayReport) return NS_OK; if (showErrorOnly && NS_SUCCEEDED(currError)) return NS_OK; nsXPIDLString currMessage; mProcessReport[mCurrentProcess]->GetMessage(getter_Copies(currMessage)); nsCOMPtr<nsIMsgStringService> composebundle (do_GetService(NS_MSG_COMPOSESTRINGSERVICE_CONTRACTID)); if (!composebundle) { //TODO need to display a generic hardcoded message mAlreadyDisplayReport = PR_TRUE; return NS_OK; } nsXPIDLString dialogTitle; nsXPIDLString dialogMessage; if (NS_SUCCEEDED(currError)) { //TODO display a success error message return NS_OK; } //Do we have an explanation of the error? if no, try to build one... if (currMessage.IsEmpty()) { switch (currError) { case NS_BINDING_ABORTED: case NS_ERROR_SEND_FAILED: case NS_ERROR_SEND_FAILED_BUT_NNTP_OK: case NS_MSG_FAILED_COPY_OPERATION: case NS_MSG_UNABLE_TO_SEND_LATER: case NS_MSG_UNABLE_TO_SAVE_DRAFT: case NS_MSG_UNABLE_TO_SAVE_TEMPLATE: //Ignore, don't need to repeat ourself. break; case NS_ERROR_MSG_MULTILINGUAL_SEND: // already displayed an alert, no additional message is needed // return to the compose window mAlreadyDisplayReport = PR_TRUE; return NS_OK; default: nsAutoString errorMsg; nsMsgBuildErrorMessageByID(currError, errorMsg); if (! errorMsg.IsEmpty()) currMessage.Assign(errorMsg); break; } } if (mDeliveryMode == nsIMsgCompDeliverMode::Now || mDeliveryMode == nsIMsgCompDeliverMode::SendUnsent) { // SMTP is taking care of it's own error message and will return NS_ERROR_BUT_DONT_SHOW_ALERT as error code. // In that case, we must not show an alert ourself. if (currError == NS_ERROR_BUT_DONT_SHOW_ALERT) { mAlreadyDisplayReport = PR_TRUE; return NS_OK; } composebundle->GetStringByID(NS_MSG_SEND_ERROR_TITLE, getter_Copies(dialogTitle)); PRInt32 preStrId = NS_ERROR_SEND_FAILED; PRBool askToGoBackToCompose = PR_FALSE; switch (mCurrentProcess) { case process_BuildMessage : preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = PR_FALSE; break; case process_NNTP : preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = PR_FALSE; break; case process_SMTP : PRBool nntpProceeded; mProcessReport[process_NNTP]->GetProceeded(&nntpProceeded); if (nntpProceeded) preStrId = NS_ERROR_SEND_FAILED_BUT_NNTP_OK; else preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = PR_FALSE; break; case process_Copy: preStrId = NS_MSG_FAILED_COPY_OPERATION; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; case process_FCC: preStrId = NS_MSG_FAILED_COPY_OPERATION; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; } composebundle->GetStringByID(preStrId, getter_Copies(dialogMessage)); //Do we already have an error message? if (!askToGoBackToCompose && currMessage.IsEmpty()) { //we don't have an error description but we can put a generic explanation composebundle->GetStringByID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage)); } if (!currMessage.IsEmpty()) { nsAutoString temp((const PRUnichar *)dialogMessage); // Because of bug 74726, we cannot use directly an XPIDLString //Don't need to repeat ourself! if (! currMessage.Equals(temp)) { if (! dialogMessage.IsEmpty()) temp.AppendLiteral("\n"); temp.Append(currMessage); dialogMessage.Assign(temp); } } if (askToGoBackToCompose) { PRBool oopsGiveMeBackTheComposeWindow = PR_TRUE; nsXPIDLString text1; composebundle->GetStringByID(NS_MSG_ASK_TO_COMEBACK_TO_COMPOSE, getter_Copies(text1)); nsAutoString temp((const PRUnichar *)dialogMessage); // Because of bug 74726, we cannot use directly an XPIDLString if (! dialogMessage.IsEmpty()) temp.AppendLiteral("\n"); temp.Append(text1); dialogMessage.Assign(temp); nsMsgAskBooleanQuestionByString(prompt, dialogMessage, &oopsGiveMeBackTheComposeWindow, dialogTitle); if (!oopsGiveMeBackTheComposeWindow) *_retval = NS_OK; } else nsMsgDisplayMessageByString(prompt, dialogMessage, dialogTitle); } else { PRInt32 titleID; PRInt32 preStrId; switch (mDeliveryMode) { case nsIMsgCompDeliverMode::Later: titleID = NS_MSG_SENDLATER_ERROR_TITLE; preStrId = NS_MSG_UNABLE_TO_SEND_LATER; break; case nsIMsgCompDeliverMode::AutoSaveAsDraft: case nsIMsgCompDeliverMode::SaveAsDraft: titleID = NS_MSG_SAVE_DRAFT_TITLE; preStrId = NS_MSG_UNABLE_TO_SAVE_DRAFT; break; case nsIMsgCompDeliverMode::SaveAsTemplate: titleID = NS_MSG_SAVE_TEMPLATE_TITLE; preStrId = NS_MSG_UNABLE_TO_SAVE_TEMPLATE; break; default: /* This should never happend! */ titleID = NS_MSG_SEND_ERROR_TITLE; preStrId = NS_ERROR_SEND_FAILED; break; } composebundle->GetStringByID(titleID, getter_Copies(dialogTitle)); composebundle->GetStringByID(preStrId, getter_Copies(dialogMessage)); //Do we have an error message... if (currMessage.IsEmpty()) { //we don't have an error description but we can put a generic explanation composebundle->GetStringByID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage)); } if (!currMessage.IsEmpty()) { nsAutoString temp((const PRUnichar *)dialogMessage); // Because of bug 74726, we cannot use directly an XPIDLString if (! dialogMessage.IsEmpty()) temp.AppendLiteral("\n"); temp.Append(currMessage); dialogMessage.Assign(temp); } nsMsgDisplayMessageByString(prompt, dialogMessage, dialogTitle); } mAlreadyDisplayReport = PR_TRUE; return NS_OK; }
/* nsresult displayReport (in nsIPrompt prompt, in boolean showErrorOnly, in boolean dontShowReportTwice); */ NS_IMETHODIMP nsMsgSendReport::DisplayReport(nsIPrompt *prompt, bool showErrorOnly, bool dontShowReportTwice, nsresult *_retval) { NS_ENSURE_ARG_POINTER(_retval); nsresult currError = NS_OK; mProcessReport[mCurrentProcess]->GetError(&currError); *_retval = currError; if (dontShowReportTwice && mAlreadyDisplayReport) return NS_OK; if (showErrorOnly && NS_SUCCEEDED(currError)) return NS_OK; nsString currMessage; mProcessReport[mCurrentProcess]->GetMessage(getter_Copies(currMessage)); nsresult rv; // don't step on currError. nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle)); if (NS_FAILED(rv)) { //TODO need to display a generic hardcoded message mAlreadyDisplayReport = true; return NS_OK; } nsString dialogTitle; nsString dialogMessage; if (NS_SUCCEEDED(currError)) { //TODO display a success error message return NS_OK; } //Do we have an explanation of the error? if no, try to build one... if (currMessage.IsEmpty()) { switch (currError) { case NS_BINDING_ABORTED: case NS_ERROR_SEND_FAILED: case NS_ERROR_SEND_FAILED_BUT_NNTP_OK: case NS_MSG_FAILED_COPY_OPERATION: case NS_MSG_UNABLE_TO_SEND_LATER: case NS_MSG_UNABLE_TO_SAVE_DRAFT: case NS_MSG_UNABLE_TO_SAVE_TEMPLATE: //Ignore, don't need to repeat ourself. break; default: nsMsgGetMessageByID(currError, currMessage); break; } } if (mDeliveryMode == nsIMsgCompDeliverMode::Now || mDeliveryMode == nsIMsgCompDeliverMode::SendUnsent) { // SMTP is taking care of it's own error message and will return NS_ERROR_BUT_DONT_SHOW_ALERT as error code. // In that case, we must not show an alert ourself. if (currError == NS_ERROR_BUT_DONT_SHOW_ALERT) { mAlreadyDisplayReport = true; return NS_OK; } bundle->GetStringFromID(NS_MSG_SEND_ERROR_TITLE, getter_Copies(dialogTitle)); PRInt32 preStrId = NS_ERROR_SEND_FAILED; bool askToGoBackToCompose = false; switch (mCurrentProcess) { case process_BuildMessage : preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = false; break; case process_NNTP : preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = false; break; case process_SMTP : bool nntpProceeded; mProcessReport[process_NNTP]->GetProceeded(&nntpProceeded); if (nntpProceeded) preStrId = NS_ERROR_SEND_FAILED_BUT_NNTP_OK; else preStrId = NS_ERROR_SEND_FAILED; askToGoBackToCompose = false; break; case process_Copy: preStrId = NS_MSG_FAILED_COPY_OPERATION; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; case process_FCC: preStrId = NS_MSG_FAILED_COPY_OPERATION; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; } bundle->GetStringFromID(preStrId, getter_Copies(dialogMessage)); //Do we already have an error message? if (!askToGoBackToCompose && currMessage.IsEmpty()) { //we don't have an error description but we can put a generic explanation bundle->GetStringFromID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage)); } if (!currMessage.IsEmpty()) { //Don't need to repeat ourself! if (!currMessage.Equals(dialogMessage)) { if (!dialogMessage.IsEmpty()) dialogMessage.Append(PRUnichar('\n')); dialogMessage.Append(currMessage); } } if (askToGoBackToCompose) { bool oopsGiveMeBackTheComposeWindow = true; nsString text1; bundle->GetStringFromID(NS_MSG_ASK_TO_COMEBACK_TO_COMPOSE, getter_Copies(text1)); if (!dialogMessage.IsEmpty()) dialogMessage.AppendLiteral("\n"); dialogMessage.Append(text1); nsMsgAskBooleanQuestionByString(prompt, dialogMessage.get(), &oopsGiveMeBackTheComposeWindow, dialogTitle.get()); if (!oopsGiveMeBackTheComposeWindow) *_retval = NS_OK; } else nsMsgDisplayMessageByString(prompt, dialogMessage.get(), dialogTitle.get()); } else { PRInt32 titleID; PRInt32 preStrId; switch (mDeliveryMode) { case nsIMsgCompDeliverMode::Later: titleID = NS_MSG_SENDLATER_ERROR_TITLE; preStrId = NS_MSG_UNABLE_TO_SEND_LATER; break; case nsIMsgCompDeliverMode::AutoSaveAsDraft: case nsIMsgCompDeliverMode::SaveAsDraft: titleID = NS_MSG_SAVE_DRAFT_TITLE; preStrId = NS_MSG_UNABLE_TO_SAVE_DRAFT; break; case nsIMsgCompDeliverMode::SaveAsTemplate: titleID = NS_MSG_SAVE_TEMPLATE_TITLE; preStrId = NS_MSG_UNABLE_TO_SAVE_TEMPLATE; break; default: /* This should never happend! */ titleID = NS_MSG_SEND_ERROR_TITLE; preStrId = NS_ERROR_SEND_FAILED; break; } bundle->GetStringFromID(titleID, getter_Copies(dialogTitle)); // preStrId could be a string ID or it could be an error code...yuck. bundle->GetStringFromID(NS_IS_MSG_ERROR(preStrId) ? NS_ERROR_GET_CODE(preStrId) : preStrId, getter_Copies(dialogMessage)); //Do we have an error message... if (currMessage.IsEmpty()) { //we don't have an error description but we can put a generic explanation bundle->GetStringFromID(NS_MSG_GENERIC_FAILURE_EXPLANATION, getter_Copies(currMessage)); } if (!currMessage.IsEmpty()) { if (!dialogMessage.IsEmpty()) dialogMessage.Append(PRUnichar('\n')); dialogMessage.Append(currMessage); } nsMsgDisplayMessageByString(prompt, dialogMessage.get(), dialogTitle.get()); } mAlreadyDisplayReport = true; return NS_OK; }
/* nsresult displayReport (in nsIPrompt prompt, in boolean showErrorOnly, in * boolean dontShowReportTwice); */ NS_IMETHODIMP nsMsgSendReport::DisplayReport(nsIPrompt *prompt, bool showErrorOnly, bool dontShowReportTwice, nsresult *_retval) { NS_ENSURE_ARG_POINTER(_retval); NS_ENSURE_TRUE(mCurrentProcess >= 0 && mCurrentProcess <= SEND_LAST_PROCESS, NS_ERROR_NOT_INITIALIZED); nsresult currError = NS_OK; mProcessReport[mCurrentProcess]->GetError(&currError); *_retval = currError; if (dontShowReportTwice && mAlreadyDisplayReport) return NS_OK; if (showErrorOnly && NS_SUCCEEDED(currError)) return NS_OK; nsString currMessage; mProcessReport[mCurrentProcess]->GetMessage(getter_Copies(currMessage)); nsresult rv; // don't step on currError. nsCOMPtr<nsIStringBundleService> bundleService = mozilla::services::GetStringBundleService(); NS_ENSURE_TRUE(bundleService, NS_ERROR_UNEXPECTED); nsCOMPtr<nsIStringBundle> bundle; rv = bundleService->CreateBundle( "chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle)); if (NS_FAILED(rv)) { // TODO need to display a generic hardcoded message mAlreadyDisplayReport = true; return NS_OK; } nsString dialogTitle; nsString dialogMessage; if (NS_SUCCEEDED(currError)) { // TODO display a success error message return NS_OK; } // Do we have an explanation of the error? if no, try to build one... if (currMessage.IsEmpty()) { #ifdef __GNUC__ // Temporary workaround until bug 783526 is fixed. # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wswitch" #endif switch (currError) { case NS_BINDING_ABORTED: case NS_MSG_UNABLE_TO_SEND_LATER: case NS_MSG_UNABLE_TO_SAVE_DRAFT: case NS_MSG_UNABLE_TO_SAVE_TEMPLATE: // Ignore, don't need to repeat ourself. break; default: const char *errorString = errorStringNameForErrorCode(currError); nsMsgGetMessageByName(errorString, currMessage); break; } #ifdef __GNUC__ # pragma GCC diagnostic pop #endif } if (mDeliveryMode == nsIMsgCompDeliverMode::Now || mDeliveryMode == nsIMsgCompDeliverMode::SendUnsent) { // SMTP is taking care of it's own error message and will return // NS_ERROR_BUT_DONT_SHOW_ALERT as error code. In that case, we must not // show an alert ourself. if (currError == NS_ERROR_BUT_DONT_SHOW_ALERT) { mAlreadyDisplayReport = true; return NS_OK; } bundle->GetStringFromName("sendMessageErrorTitle", dialogTitle); const char *preStrName = "sendFailed"; bool askToGoBackToCompose = false; switch (mCurrentProcess) { case process_BuildMessage: preStrName = "sendFailed"; askToGoBackToCompose = false; break; case process_NNTP: preStrName = "sendFailed"; askToGoBackToCompose = false; break; case process_SMTP: bool nntpProceeded; mProcessReport[process_NNTP]->GetProceeded(&nntpProceeded); if (nntpProceeded) preStrName = "sendFailedButNntpOk"; else preStrName = "sendFailed"; askToGoBackToCompose = false; break; case process_Copy: preStrName = "failedCopyOperation"; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; case process_FCC: preStrName = "failedCopyOperation"; askToGoBackToCompose = (mDeliveryMode == nsIMsgCompDeliverMode::Now); break; } bundle->GetStringFromName(preStrName, dialogMessage); // Do we already have an error message? if (!askToGoBackToCompose && currMessage.IsEmpty()) { // we don't have an error description but we can put a generic explanation bundle->GetStringFromName("genericFailureExplanation", currMessage); } if (!currMessage.IsEmpty()) { // Don't need to repeat ourself! if (!currMessage.Equals(dialogMessage)) { if (!dialogMessage.IsEmpty()) dialogMessage.Append(char16_t('\n')); dialogMessage.Append(currMessage); } } if (askToGoBackToCompose) { bool oopsGiveMeBackTheComposeWindow = true; nsString text1; bundle->GetStringFromName("returnToComposeWindowQuestion", text1); if (!dialogMessage.IsEmpty()) dialogMessage.AppendLiteral("\n"); dialogMessage.Append(text1); nsMsgAskBooleanQuestionByString(prompt, dialogMessage.get(), &oopsGiveMeBackTheComposeWindow, dialogTitle.get()); if (!oopsGiveMeBackTheComposeWindow) *_retval = NS_OK; } else nsMsgDisplayMessageByString(prompt, dialogMessage.get(), dialogTitle.get()); } else { const char *title; const char *messageName; switch (mDeliveryMode) { case nsIMsgCompDeliverMode::Later: title = "sendLaterErrorTitle"; messageName = "unableToSendLater"; break; case nsIMsgCompDeliverMode::AutoSaveAsDraft: case nsIMsgCompDeliverMode::SaveAsDraft: title = "saveDraftErrorTitle"; messageName = "unableToSaveDraft"; break; case nsIMsgCompDeliverMode::SaveAsTemplate: title = "saveTemplateErrorTitle"; messageName = "unableToSaveTemplate"; break; default: /* This should never happen! */ title = "sendMessageErrorTitle"; messageName = "sendFailed"; break; } bundle->GetStringFromName(title, dialogTitle); bundle->GetStringFromName(messageName, dialogMessage); // Do we have an error message... if (currMessage.IsEmpty()) { // we don't have an error description but we can put a generic explanation bundle->GetStringFromName("genericFailureExplanation", currMessage); } if (!currMessage.IsEmpty()) { if (!dialogMessage.IsEmpty()) dialogMessage.Append(char16_t('\n')); dialogMessage.Append(currMessage); } nsMsgDisplayMessageByString(prompt, dialogMessage.get(), dialogTitle.get()); } mAlreadyDisplayReport = true; return NS_OK; }