Mozilla/mozilla/mailnews/compose/src/nsMsgCreate.cpp
alecf%netscape.com 6e8ceeb034 fix for #45797 - remove deprecated NS_IMPL_ISUPPORTS from mail
r=sspitzer
sr=mscott
iho=warren


git-svn-id: svn://10.0.0.236/trunk@83329 18797224-902f-48f8-a5cc-f745e15eee43
2000-12-06 22:24:41 +00:00

275 lines
8.2 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsCOMPtr.h"
#include "nsIURL.h"
#include "nsIEventQueueService.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsIGenericFactory.h"
#include "nsIServiceManager.h"
#include "nsIStreamListener.h"
#include "nsIStreamConverter.h"
#include "nsIChannel.h"
#include "nsIMimeStreamConverter.h"
#include "nsFileStream.h"
#include "nsFileSpec.h"
#include "nsMimeTypes.h"
#include "nsIPref.h"
#include "nsICharsetConverterManager.h"
#include "prprf.h"
#include "nsMsgCreate.h"
#include "nsMsgCompUtils.h"
#include "nsIMsgMessageService.h"
#include "nsMsgUtils.h"
#include "nsMsgDeliveryListener.h"
#include "nsIMsgAccountManager.h"
#include "nsIMsgIdentity.h"
#include "nsIEnumerator.h"
#include "nsIMessage.h"
#include "nsIRDFResource.h"
#include "nsMsgBaseCID.h"
#include "nsMsgCopy.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsNetUtil.h"
#include "nsMsgMimeCID.h"
#include "nsIMsgMailSession.h"
#include "nsIMsgMailNewsUrl.h"
#include "nsMsgBaseCID.h"
// CID's needed
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
//
// Implementation...
//
nsMsgDraft::nsMsgDraft()
{
NS_INIT_REFCNT();
mURI = nsnull;
mMessageService = nsnull;
mOutType = nsMimeOutput::nsMimeMessageDraftOrTemplate;
mAddInlineHeaders = PR_FALSE;
}
nsMsgDraft::~nsMsgDraft()
{
if (mMessageService)
{
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
}
PR_FREEIF(mURI);
}
/* the following macro actually implement addref, release and query interface for our component. */
NS_IMPL_ISUPPORTS1(nsMsgDraft, nsIMsgDraft)
/* this function will be used by the factory to generate an Message Compose Fields Object....*/
nsresult
NS_NewMsgDraft(const nsIID &aIID, void ** aInstancePtrResult)
{
/* note this new macro for assertions...they can take a string describing the assertion */
NS_PRECONDITION(nsnull != aInstancePtrResult, "nsnull ptr");
if (nsnull != aInstancePtrResult)
{
nsMsgDraft *pQuote = new nsMsgDraft();
if (pQuote)
return pQuote->QueryInterface(aIID, aInstancePtrResult);
else
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
}
else
return NS_ERROR_NULL_POINTER; /* aInstancePtrResult was NULL....*/
}
// stream converter
static NS_DEFINE_CID(kStreamConverterCID, NS_MAILNEWS_MIME_STREAM_CONVERTER_CID);
nsIMessage *
GetIMessageFromURI(const PRUnichar *msgURI)
{
nsresult rv;
nsIRDFResource *myRDFNode = nsnull;
nsCAutoString convertString; convertString.AssignWithConversion(msgURI);
nsIMessage *returnMessage;
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv) || (!rdfService))
return nsnull;
rdfService->GetResource(convertString, &myRDFNode);
if (!myRDFNode)
return nsnull;
myRDFNode->QueryInterface(NS_GET_IID(nsIMessage), (void **)&returnMessage);
NS_IF_RELEASE(myRDFNode);
return returnMessage;
}
nsresult
nsMsgDraft::ProcessDraftOrTemplateOperation(const PRUnichar *msgURI, nsMimeOutputType aOutType,
nsIMsgIdentity * identity, nsIMessage **aMsgToReplace)
{
nsresult rv;
mOutType = aOutType;
if (!msgURI)
return NS_ERROR_INVALID_ARG;
nsString convertString(msgURI);
mURI = convertString.ToNewCString();
if (!mURI)
return NS_ERROR_OUT_OF_MEMORY;
rv = GetMessageServiceFromURI(mURI, &mMessageService);
if (NS_FAILED(rv) && !mMessageService)
{
return rv;
}
NS_ADDREF(this);
// Now, we can create a mime parser (nsIStreamConverter)!
nsCOMPtr<nsIStreamConverter> mimeParser;
rv = nsComponentManager::CreateInstance(kStreamConverterCID,
NULL, NS_GET_IID(nsIStreamConverter),
(void **) getter_AddRefs(mimeParser));
if (NS_FAILED(rv) || !mimeParser)
{
Release();
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
#ifdef NS_DEBUG
printf("Failed to create MIME stream converter...\n");
#endif
return rv;
}
// Set us as the output stream for HTML data from libmime...
nsCOMPtr<nsIMimeStreamConverter> mimeConverter = do_QueryInterface(mimeParser);
if (mimeConverter)
{
mimeConverter->SetMimeOutputType(mOutType); // Set the type of output for libmime
mimeConverter->SetForwardInline(mAddInlineHeaders);
mimeConverter->SetIdentity(identity);
}
nsCOMPtr<nsIStreamListener> convertedListener = do_QueryInterface(mimeParser);
if (!convertedListener)
{
Release();
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
#ifdef NS_DEBUG
printf("Unable to get the nsIStreamListener interface from libmime\n");
#endif
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIURI> aURL;
rv = CreateStartupUrl(mURI, getter_AddRefs(aURL));
// HACK: if we are forwarding a message and that message used a charset over ride
// (as speciifed in the top most window (assuming the reply originated from that window)
// then use that over ride charset instead of the charset specified in the message
nsCOMPtr <nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID);
nsXPIDLString mailCharset;
if (mailSession)
{
nsCOMPtr<nsIMsgWindow> msgWindow;
mailSession->GetTopmostMsgWindow(getter_AddRefs(msgWindow));
if (msgWindow)
{
msgWindow->GetMailCharacterSet(getter_Copies(mailCharset));
if (mailCharset)
{
nsCOMPtr<nsIMsgI18NUrl> i18nUrl(do_QueryInterface(aURL));
if (i18nUrl)
i18nUrl->SetCharsetOverRide(mailCharset);
}
}
}
nsCOMPtr<nsIChannel> dummyChannel;
rv = NS_NewInputStreamChannel(getter_AddRefs(dummyChannel), aURL, nsnull, nsnull, -1);
if (NS_FAILED(mimeParser->AsyncConvertData(nsnull, nsnull, nsnull, dummyChannel)))
{
Release();
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
#ifdef NS_DEBUG
printf("Unable to set the output stream for the mime parser...\ncould be failure to create internal libmime data\n");
#endif
return NS_ERROR_UNEXPECTED;
}
// Make sure we return this if requested!
if (aMsgToReplace)
*aMsgToReplace = GetIMessageFromURI(msgURI);
// Now, just plug the two together and get the hell out of the way!
rv = mMessageService->DisplayMessage(mURI, convertedListener, nsnull, nsnull, mailCharset, nsnull);
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
Release();
if (NS_FAILED(rv))
return rv;
else
return NS_OK;
}
nsresult
nsMsgDraft::OpenDraftMsg(const PRUnichar *msgURI, nsIMessage **aMsgToReplace,
nsIMsgIdentity * identity, PRBool addInlineHeaders)
{
// We should really never get here, but if we do, just return
// with an error
if (!msgURI)
return NS_ERROR_FAILURE;
mAddInlineHeaders = addInlineHeaders;
return ProcessDraftOrTemplateOperation(msgURI, nsMimeOutput::nsMimeMessageDraftOrTemplate,
identity, aMsgToReplace);
}
nsresult
nsMsgDraft::OpenEditorTemplate(const PRUnichar *msgURI, nsIMessage **aMsgToReplace,
nsIMsgIdentity * identity)
{
return ProcessDraftOrTemplateOperation(msgURI, nsMimeOutput::nsMimeMessageEditorTemplate,
identity, aMsgToReplace);
}