Changes for Drafts and Templates

This commit is contained in:
rhp%netscape.com 1999-07-31 19:59:35 +00:00
Родитель 9331740482
Коммит 975ad90fb9
17 изменённых файлов: 714 добавлений и 98 удалений

Просмотреть файл

@ -60,6 +60,7 @@ interface nsIMessenger : nsISupports {
void Undo();
void Redo();
void SendUnsentMessages();
void LoadFirstDraft();
void SetDocumentCharset(in wstring characterSet);
};

Просмотреть файл

@ -47,6 +47,7 @@ Rights Reserved.
<!ENTITY saveAsTemplateCmd.label ".Template">
<!ENTITY getNewMsgCmd.label "Get New Messages">
<!ENTITY sendUnsentCmd.label "Send Unsent Messages">
<!ENTITY loadFirstDraft.label "Load First Draft Message">
<!ENTITY subscribeCmd.label "Subscribe">
<!ENTITY emptyTrashCmd.label ".Empty Trash">
<!ENTITY importCmd.label ".Import...">
@ -281,6 +282,7 @@ Rights Reserved.
<menuseparator/>
<menuitem value="&getNewMsgCmd.label;" onaction="MsgGetMessage();"/>
<menuitem value="&sendUnsentCmd.label;" onaction="MsgSendUnsentMsg();"/>
<menuitem value="&loadFirstDraft.label;" onaction="MsgLoadFirstDraft();"/>
<menuitem value="&emptyTrashCmd.label;" onaction="MsgEmptyTrash();"/>
<menuitem value="&subscribeCmd.label;" onaction="MsgSubscribe();"/>
<menuseparator/>

Просмотреть файл

@ -259,6 +259,10 @@ function MsgSendUnsentMsg()
{
messenger.SendUnsentMessages();
}
function MsgLoadFirstDraft()
{
messenger.LoadFirstDraft();
}
function MsgUpdateMsgCount() {}
function MsgRenameFolder() {}
function MsgEmptyTrash() {}

Просмотреть файл

@ -75,6 +75,7 @@
#include "nsIMsgSendLater.h"
#include "nsMsgCompCID.h"
#include "nsIMsgSendLaterListener.h"
#include "nsIMsgDraft.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID);
@ -86,6 +87,7 @@ static NS_DEFINE_CID(kTransactionManagerCID, NS_TRANSACTIONMANAGER_CID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kMsgSendLaterCID, NS_MSGSENDLATER_CID);
static NS_DEFINE_CID(kCopyMessageStreamListenerCID, NS_COPYMESSAGESTREAMLISTENER_CID);
static NS_DEFINE_CID(kMsgDraftCID, NS_MSGDRAFT_CID);
class nsMessenger : public nsIMessenger
{
@ -125,6 +127,7 @@ public:
NS_IMETHOD Undo();
NS_IMETHOD Redo();
NS_IMETHOD SendUnsentMessages();
NS_IMETHOD LoadFirstDraft();
NS_IMETHOD SetDocumentCharset(const PRUnichar *characterSet);
protected:
@ -1305,3 +1308,22 @@ nsMessenger::SendUnsentMessages()
}
return NS_OK;
}
NS_IMETHODIMP
nsMessenger::LoadFirstDraft()
{
nsresult rv;
nsCOMPtr<nsIMsgDraft> pMsgDraft;
rv = nsComponentManager::CreateInstance(kMsgDraftCID, NULL, nsCOMTypeInfo<nsIMsgDraft>::GetIID(),
(void **)getter_AddRefs(pMsgDraft));
if (NS_SUCCEEDED(rv) && pMsgDraft)
{
printf("We succesfully obtained a nsIMsgDraft interface....\n");
// This should really pass in a URI, but for now, just to test, we can pass in nsnull
pMsgDraft->OpenDraftMsg(nsnull, nsnull);
}
return NS_OK;
}

Просмотреть файл

@ -36,6 +36,8 @@
#include "nsIServiceManager.h"
#include "nsCOMPtr.h"
#include "nsMsgQuote.h"
#include "nsIMsgDraft.h"
#include "nsMsgCreate.h" // For drafts...I know, awful file name...
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -48,6 +50,7 @@ static NS_DEFINE_CID(kCSmtpServiceCID, NS_SMTPSERVICE_CID);
static NS_DEFINE_CID(kCMsgComposeServiceCID, NS_MSGCOMPOSESERVICE_CID);
static NS_DEFINE_CID(kCMsgQuoteCID, NS_MSGQUOTE_CID);
static NS_DEFINE_CID(kCSmtpUrlCID, NS_SMTPURL_CID);
static NS_DEFINE_CID(kMsgDraftCID, NS_MSGDRAFT_CID);
////////////////////////////////////////////////////////////
@ -185,6 +188,12 @@ nsresult nsMsgComposeFactory::CreateInstance(nsISupports *aOuter, const nsIID &a
return NS_NewMsgSendLater(aIID, aResult);
}
// do they want a Draft interface?
else if (mClassID.Equals(kMsgDraftCID))
{
return NS_NewMsgDraft(aIID, aResult);
}
else if (mClassID.Equals(kCMsgComposeServiceCID))
{
nsMsgComposeService * aMsgCompService = new nsMsgComposeService();
@ -310,6 +319,13 @@ extern "C" NS_EXPORT nsresult NSRegisterSelf(nsISupports* aServMgr, const char*
path, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) finalResult = rv;
// For Drafts...
rv = compMgr->RegisterComponent(kMsgDraftCID,
"Message Drafts",
"Xcomponent://netscape/messengercompose/drafts",
path, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) finalResult = rv;
return finalResult;
}
@ -346,5 +362,8 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* path)
rv = compMgr->UnregisterComponent(kCMsgQuoteCID, path);
if (NS_FAILED(rv)) finalResult = rv;
rv = compMgr->UnregisterComponent(kMsgDraftCID, path);
if (NS_FAILED(rv)) finalResult = rv;
return finalResult;
}

Просмотреть файл

@ -32,6 +32,7 @@ XPIDLSRCS = \
nsIMsgSendLaterListener.idl \
nsIMsgSend.idl \
nsIMsgSendLater.idl \
nsIMsgDraft.idl \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -27,6 +27,7 @@ XPIDLSRCS = \
.\nsIMsgSendLaterListener.idl \
.\nsIMsgSend.idl \
.\nsIMsgSendLater.idl \
.\nsIMsgDraft.idl \
$(NULL)
################################################################################

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- 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.0 (the "NPL"); you may not use this file except in
@ -15,12 +15,448 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "rosetta_mailnews.h"
#include "nsMsgSend.h"
#include "nsMsgSendPart.h"
#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 "nsIStreamConverter2.h"
#include "nsIMimeStreamConverter.h"
#include "nsFileStream.h"
#include "nsFileSpec.h"
#include "nsMimeTypes.h"
#include "nsIPref.h"
#include "nsMsgCompPrefs.h"
#include "nsMsgCreate.h"
#include "nsICharsetConverterManager.h"
#include "prprf.h"
#include "nsMsgCreate.h"
#include "nsMsgCompUtils.h"
#include "nsIMsgMessageService.h"
#include "nsMsgUtils.h"
#include "nsMsgDeliveryListener.h"
#include "nsIMsgMailSession.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"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
// CID's needed
static NS_DEFINE_CID(kCMsgMailSessionCID, NS_MSGMAILSESSION_CID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
//
// Implementation...
//
nsMsgDraft::nsMsgDraft()
{
NS_INIT_REFCNT();
mTmpFileSpec = nsnull;
mTmpIFileSpec = nsnull;
mURI = nsnull;
mMessageService = nsnull;
mOutType = nsMimeOutput::nsMimeMessageDraftOrTemplate;
}
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_ISUPPORTS(nsMsgDraft, nsCOMTypeInfo<nsIMsgDraft>::GetIID());
/* 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_STREAM_CONVERTER_CID);
////////////////////////////////////////////////////////////////////////////////////
// THIS IS A TEMPORARY CLASS THAT MAKES A DISK FILE LOOK LIKE A nsIInputStream
// INTERFACE...this may already exist, but I didn't find it. Eventually, you would
// just plugin a Necko stream when they are all rewritten to be new style streams
////////////////////////////////////////////////////////////////////////////////////
class DraftFileInputStreamImpl : public nsIInputStream
{
public:
DraftFileInputStreamImpl(void)
{
NS_INIT_REFCNT();
mBufLen = 0;
mInFile = nsnull;
}
virtual ~DraftFileInputStreamImpl(void)
{
if (mInFile) delete mInFile;
}
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIBaseStream interface
NS_IMETHOD Close(void)
{
if (mInFile)
mInFile->close();
return NS_OK;
}
// nsIInputStream interface
NS_IMETHOD GetLength(PRUint32 *_retval)
{
*_retval = mBufLen;
return NS_OK;
}
/* unsigned long Read (in charStar buf, in unsigned long count); */
NS_IMETHOD Read(char * buf, PRUint32 count, PRUint32 *_retval)
{
nsCRT::memcpy(buf, mBuf, mBufLen);
*_retval = mBufLen;
return NS_OK;
}
NS_IMETHOD OpenDiskFile(nsFileSpec fs);
NS_IMETHOD PumpFileStream();
private:
PRUint32 mBufLen;
char mBuf[8192];
nsIOFileStream *mInFile;
};
nsresult
DraftFileInputStreamImpl::OpenDiskFile(nsFileSpec fs)
{
mInFile = new nsIOFileStream(fs);
if (!mInFile)
return NS_ERROR_NULL_POINTER;
mInFile->seek(0);
return NS_OK;
}
nsresult
DraftFileInputStreamImpl::PumpFileStream()
{
if (mInFile->eof())
return NS_BASE_STREAM_EOF;
mBufLen = mInFile->read(mBuf, sizeof(mBuf));
if (mBufLen > 0)
return NS_OK;
else
return NS_BASE_STREAM_EOF;
}
NS_IMPL_ISUPPORTS(DraftFileInputStreamImpl, nsCOMTypeInfo<nsIInputStream>::GetIID());
////////////////////////////////////////////////////////////////////////////////////
// End of DraftFileInputStreamImpl()
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
nsresult
SaveDraftMessageCompleteCallback(nsIURI *aURL, nsresult aExitCode, void *tagData)
{
nsresult rv = NS_OK;
if (!tagData)
{
return NS_ERROR_INVALID_ARG;
}
nsMsgDraft *ptr = (nsMsgDraft *) tagData;
if (ptr->mMessageService)
{
ReleaseMessageServiceFromURI(ptr->mURI, ptr->mMessageService);
ptr->mMessageService = nsnull;
}
/* mscott - the NS_BINDING_ABORTED is a hack to get around a problem I have
with the necko code...it returns this and treats it as an error when
it really isn't an error! I'm trying to get them to change this.
*/
if (NS_FAILED(aExitCode) && aExitCode != NS_BINDING_ABORTED)
{
NS_RELEASE(ptr);
return aExitCode;
}
// Create a mime parser (nsIStreamConverter)!
nsCOMPtr<nsIStreamConverter2> mimeParser;
rv = nsComponentManager::CreateInstance(kStreamConverterCID,
NULL, nsCOMTypeInfo<nsIStreamConverter2>::GetIID(),
(void **) getter_AddRefs(mimeParser));
if (NS_FAILED(rv) || !mimeParser)
{
NS_RELEASE(ptr);
printf("Failed to create MIME stream converter...\n");
return rv;
}
// This is the producer stream that will deliver data from the disk file...
// ...someday, we'll just get streams from Necko.
// mscott --> the type for a nsCOMPtr needs to be an interface.
// but this class (which is only temporary anyway) is mixing and matching
// interface calls and implementation calls....so you really can't use a
// com ptr. to get around it, I'm using fileStream to make calls on the
// methods that aren't supported by the nsIInputStream and "in" for
// methods that are supported as part of the interface...
DraftFileInputStreamImpl * fileStream = new DraftFileInputStreamImpl();
nsCOMPtr<nsIInputStream> in = do_QueryInterface(fileStream);
if (!in || !fileStream)
{
NS_RELEASE(ptr);
printf("Failed to create nsIInputStream\n");
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_FAILED(fileStream->OpenDiskFile(*(ptr->mTmpFileSpec))))
{
NS_RELEASE(ptr);
printf("Unable to open input file\n");
return NS_ERROR_FAILURE;
}
// Set us as the output stream for HTML data from libmime...
nsCOMPtr<nsIMimeStreamConverter> mimeConverter = do_QueryInterface(mimeParser);
if (mimeConverter)
mimeConverter->SetMimeOutputType(ptr->mOutType); // Set the type of output for libmime
if (NS_FAILED(mimeParser->Init(aURL, nsnull /* no listener necessary */, nsnull /* the channel */)))
{
NS_RELEASE(ptr);
printf("Unable to set the output stream for the mime parser...\ncould be failure to create internal libmime data\n");
return NS_ERROR_UNEXPECTED;
}
// Assuming this is an RFC822 message...
mimeParser->OnStartRequest(nsnull, aURL);
// Just pump all of the data from the file into libmime...
while (NS_SUCCEEDED(fileStream->PumpFileStream()))
{
PRUint32 len;
in->GetLength(&len);
mimeParser->OnDataAvailable(nsnull, aURL, in, 0, len);
}
mimeParser->OnStopRequest(nsnull, aURL, NS_OK, nsnull);
in->Close();
ptr->mTmpFileSpec->Delete(PR_FALSE);
NS_RELEASE(ptr);
return NS_OK;
}
nsIMessage *
GetIMessageFromURI(const PRUnichar *msgURI)
{
nsresult rv;
nsIRDFResource *myRDFNode = nsnull;
nsString2 convertString(msgURI);
char *tmpURI = nsnull;
nsIMessage *returnMessage;
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv) || (!rdfService))
return nsnull;
tmpURI = convertString.ToNewCString();
if (!tmpURI)
return nsnull;
rdfService->GetResource(tmpURI, &myRDFNode);
PR_FREEIF(tmpURI);
if (!myRDFNode)
return nsnull;
myRDFNode->QueryInterface(nsCOMTypeInfo<nsIMessage>::GetIID(), (void **)&returnMessage);
NS_IF_RELEASE(myRDFNode);
return returnMessage;
}
nsresult
nsMsgDraft::ProcessDraftOrTemplateOperation(const PRUnichar *msgURI, nsMimeOutputType aOutType,
nsIMessage **aMsgToReplace)
{
nsresult rv;
mOutType = aOutType;
if (!msgURI)
return NS_ERROR_INVALID_ARG;
mTmpFileSpec = nsMsgCreateTempFileSpec("nsdraft.tmp");
if (!mTmpFileSpec)
return NS_ERROR_FAILURE;
NS_NewFileSpecWithSpec(*mTmpFileSpec, &mTmpIFileSpec);
if (!mTmpIFileSpec)
return NS_ERROR_FAILURE;
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);
nsMsgDeliveryListener *sendListener = new nsMsgDeliveryListener(SaveDraftMessageCompleteCallback,
nsFileSaveDelivery, this);
if (!sendListener)
{
ReleaseMessageServiceFromURI(mURI, mMessageService);
mMessageService = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
// Make sure we return this if requested!
if (aMsgToReplace)
*aMsgToReplace = GetIMessageFromURI(msgURI);
return mMessageService->SaveMessageToDisk(mURI, mTmpIFileSpec, PR_FALSE, sendListener, nsnull);
}
nsresult
nsMsgDraft::OpenDraftMsg(const PRUnichar *msgURI, nsIMessage **aMsgToReplace)
{
PRUnichar *HackUpAURIToPlayWith(void); // RICHIE - forward declare for now
if (!msgURI)
{
printf("RICHIE: DO THIS UNTIL THE FE CAN REALLY SUPPORT US!\n");
msgURI = HackUpAURIToPlayWith();
}
return ProcessDraftOrTemplateOperation(msgURI, nsMimeOutput::nsMimeMessageDraftOrTemplate,
aMsgToReplace);
}
nsresult
nsMsgDraft::OpenEditorTemplate(const PRUnichar *msgURI, nsIMessage **aMsgToReplace)
{
return ProcessDraftOrTemplateOperation(msgURI, nsMimeOutput::nsMimeMessageEditorTemplate,
aMsgToReplace);
}
//////////////////////////////////////////////////////////////////////////////////////////
// RICHIE - This is a temp routine to get a URI from the Drafts folder and use that
// for loading into the compose window.
//////////////////////////////////////////////////////////////////////////////////////////
// RICHIE - EVERYTHING AFTER THIS COMMENT IS A TEMP HACK!!!
//////////////////////////////////////////////////////////////////////////////////////////
PRUnichar *
HackUpAURIToPlayWith(void)
{
PRUnichar *playURI = nsnull;
char *folderURI = nsnull;
nsresult rv = NS_OK;
// temporary hack to get the current identity
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kCMsgMailSessionCID, &rv);
if (NS_FAILED(rv))
return nsnull;
nsCOMPtr<nsIMsgIdentity> identity = nsnull;
rv = mailSession->GetCurrentIdentity(getter_AddRefs(identity));
if (NS_FAILED(rv))
return nsnull;
//
// Find the users drafts folder...
//
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
prefs->CopyCharPref("mail.default_drafts_uri", &folderURI);
//
// Now, get the drafts folder...
//
nsIMsgFolder *folder = LocateMessageFolder(identity, nsMsgSaveAsDraft, folderURI);
PR_FREEIF(folderURI);
if (!folder)
return nsnull;
nsIEnumerator *enumerator;
rv = folder->GetMessages(&enumerator);
if (NS_FAILED(rv) || (!enumerator))
{
// RICHIE - Possible bug that will bite us in this hack...
printf("*** NOTICE *** If you failed, more than likely, this is the problem\ndescribed by Bug #10344.\n\7");
return nsnull;
}
enumerator->First();
if (enumerator->IsDone() == NS_OK)
{
NS_IF_RELEASE(enumerator);
return nsnull;
}
nsCOMPtr<nsISupports> currentItem;
rv = enumerator->CurrentItem(getter_AddRefs(currentItem));
if (NS_FAILED(rv))
{
NS_IF_RELEASE(enumerator);
return nsnull;
}
nsCOMPtr<nsIMessage> message;
message = do_QueryInterface(currentItem);
if (!message)
{
NS_IF_RELEASE(enumerator);
return nsnull;
}
nsCOMPtr<nsIRDFResource> myRDFNode;
myRDFNode = do_QueryInterface(message, &rv);
if (NS_FAILED(rv) || (!myRDFNode))
{
NS_IF_RELEASE(enumerator);
return nsnull;
}
NS_IF_RELEASE(enumerator);
char *tURI;
myRDFNode->GetValue(&tURI);
nsString2 workURI(tURI);
return workURI.ToNewUnicode();
}

Просмотреть файл

@ -19,7 +19,40 @@
#ifndef _nsMsgCreate_H_
#define _nsMsgCreate_H_
#include "nsIMsgDraft.h"
#include "nsFileSpec.h"
#include "nsIFileSpec.h"
#include "nsIMsgMessageService.h"
#include "nsIMimeStreamConverter.h"
class nsMsgDraft: public nsIMsgDraft {
public:
nsMsgDraft();
virtual ~nsMsgDraft();
/* this macro defines QueryInterface, AddRef and Release for this class */
NS_DECL_ISUPPORTS
/* long QuoteMessage (in wstring msgURI, in nsIOutputStream outStream, nsIMessage **aMsgToReplace); */
NS_IMETHOD OpenDraftMsg(const PRUnichar *msgURI, nsIMessage **aMsgToReplace);
/* long QuoteMessage (in wstring msgURI, in nsIOutputStream outStream, nsIMessage **aMsgToReplace); */
NS_IMETHOD OpenEditorTemplate(const PRUnichar *msgURI, nsIMessage **aMsgToReplace);
nsresult ProcessDraftOrTemplateOperation(const PRUnichar *msgURI, nsMimeOutputType aOutType,
nsIMessage **aMsgToReplace);
//
// Implementation data...
//
nsFileSpec *mTmpFileSpec;
nsIFileSpec *mTmpIFileSpec;
char *mURI;
nsIMsgMessageService *mMessageService;
nsMimeOutputType mOutType;
};
// Will be used by factory to generate a nsMsgQuote class...
nsresult NS_NewMsgDraft(const nsIID &aIID, void ** aInstancePtrResult);
#endif /* _nsMsgCreate_H_ */

Просмотреть файл

@ -236,11 +236,6 @@ SaveQuoteMessageCompleteCallback(nsIURI *aURL, nsresult aExitCode, void *tagData
}
// Set us as the output stream for HTML data from libmime...
// SHERRY --> rhp, i need you to verify the arguments for this call...
// i just hacked them up to get it to build.
char * contentType = nsnull;
nsMimeOutputType outType;
nsCOMPtr<nsIMimeStreamConverter> mimeConverter = do_QueryInterface(mimeParser);
if (mimeConverter)
mimeConverter->SetMimeOutputType(nsMimeOutput::nsMimeMessageQuoting);

Просмотреть файл

@ -384,7 +384,7 @@ SendOperationListener::OnStopSending(const char *aMsgID, nsresult aStatus, const
//
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
if (NS_SUCCEEDED(rv) && prefs)
prefs->GetBoolPref("mail.really_delete_unsent_messages", &deleteMsgs);
prefs->GetBoolPref("mail.default_drafts_uri", &deleteMsgs);
if (deleteMsgs)
{

Просмотреть файл

@ -315,8 +315,10 @@ nsMimeHtmlEmitter::StartAttachment(const char *name, const char *contentType, co
UtilityWrite("\" target=new>");
}
UtilityWrite("<img SRC=\"resource:/res/network/gopher-unknown.gif\" BORDER=0 ALIGN=ABSCENTER>");
UtilityWrite("<CENTER>");
UtilityWrite("<img SRC=\"resource:/chrome/editor/skin/default/images/ED_NewFile.gif\" BORDER=0 ALIGN=ABSCENTER>");
UtilityWrite(name);
UtilityWrite("</CENTER>");
if (mAttachContentType)
UtilityWrite("</a>");

Просмотреть файл

@ -305,7 +305,7 @@ nsMimeXmlEmitter::StartAttachment(const char *name, const char *contentType, con
++mAttachCount;
sprintf(buf, "<mailattachment id=%d>", mAttachCount);
sprintf(buf, "<mailattachment id=\"%d\">", mAttachCount);
UtilityWrite(buf);
AddAttachmentField(HEADER_PARM_FILENAME, name);

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsMsgCompCID.h"
#include "nsIStreamConverter2.h"
#include "nsIMsgComposeService.h"
#include "nsIMsgCompose.h"
//
// Header strings...
@ -200,46 +201,84 @@ typedef enum {
nsMsg_UUENCODE_BINARY_BOOL_HEADER_MASK,
nsMsg_ATTACH_VCARD_BOOL_HEADER_MASK,
nsMsg_LAST_BOOL_HEADER_MASK // last boolean header mask; must be the last one
// DON'T remove.
// DON'T remove.
} nsMsgBoolHeaderSet;
static void
mime_dump_attachments ( nsMsgAttachmentData *attachData )
{
PRInt32 i = 0;
struct nsMsgAttachmentData *tmp = attachData;
while ( (tmp) && (tmp->real_name) )
{
printf("Real Name : %s\n", tmp->real_name);
if ( tmp->url )
{
char *spec = nsnull;
tmp->url->GetSpec(&spec);
printf("URL : %s\n", spec);
}
printf("Desired Type : %s\n", tmp->desired_type);
printf("Real Type : %s\n", tmp->real_type);
printf("Real Encoding : %s\n", tmp->real_encoding);
printf("Description : %s\n", tmp->description);
printf("Mac Type : %s\n", tmp->x_mac_type);
printf("Mac Creator : %s\n", tmp->x_mac_creator);
i++;
tmp++;
}
}
nsresult
CreateTheComposeWindow(nsIMsgCompFields *compFields,
nsMsgAttachmentData *remoteAttachments)
nsMsgAttachmentData *attachmentList,
nsMsgEditorType editorType)
{
nsresult rv;
nsresult rv;
MSG_ComposeFormat format = MSGCOMP_FORMAT_Default;
#ifdef NS_DEBUG
printf("RICHIE: Need to do something with the attachment data!!!!\n");
mime_dump_attachments ( attachmentList );
#endif
NS_WITH_SERVICE(nsIMsgComposeService, msgComposeService, kCMsgComposeServiceCID, &rv);
if ((NS_FAILED(rv)) || (!msgComposeService))
return rv;
if (editorType == nsMsgPlainTextEditor)
format = MSGCOMP_FORMAT_PlainText;
else if (editorType == nsMsgHTMLEditor)
format = MSGCOMP_FORMAT_HTML;
rv = msgComposeService->OpenComposeWindowWithCompFields(
nsString2("chrome://messengercompose/content/").GetUnicode(),
MSGCOMP_TYPE_New,
compFields);
format, compFields);
return rv;
}
nsIMsgCompFields *
CreateCompositionFields(const char *from,
const char *reply_to,
const char *to,
const char *cc,
const char *bcc,
const char *fcc,
const char *newsgroups,
const char *followup_to,
const char *organization,
const char *subject,
const char *references,
const char *other_random_headers,
const char *priority,
const char *attachment,
const char *newspost_url,
PRBool xlate_p,
PRBool sign_p)
CreateCompositionFields(const char *from,
const char *reply_to,
const char *to,
const char *cc,
const char *bcc,
const char *fcc,
const char *newsgroups,
const char *followup_to,
const char *organization,
const char *subject,
const char *references,
const char *other_random_headers,
const char *priority,
const char *attachment,
const char *newspost_url,
PRBool xlate_p,
PRBool sign_p)
{
nsIMsgCompFields *cFields = nsnull;
@ -253,6 +292,7 @@ CreateCompositionFields(const char *from,
// Now set all of the passed in stuff...
cFields->SetFrom(nsString2(from).GetUnicode());
cFields->SetSubject(nsString2(subject).GetUnicode());
cFields->SetReplyTo(nsString2(reply_to).GetUnicode());
cFields->SetTo(nsString2(to).GetUnicode());
cFields->SetCc(nsString2(cc).GetUnicode());
@ -330,7 +370,6 @@ mime_free_attach_data ( nsMsgAttachmentData *attachData, int cleanupCount)
for ( i=0; i < cleanupCount; i++, tmp++ )
{
PR_FREEIF(tmp->real_name);
if ( tmp->url )
delete tmp->url;
PR_FREEIF(tmp->real_name);
@ -366,7 +405,7 @@ mime_free_attachments ( nsMsgAttachedFile *attachments, int count )
PR_FREEIF ( cur->x_mac_creator );
if ( cur->file_spec )
{
cur->file_spec->Delete(PR_FALSE);
cur->file_spec->Delete(PR_FALSE);
delete ( cur->file_spec );
}
}
@ -425,10 +464,6 @@ mime_draft_process_attachments(mime_draft_data *mdd)
mime_SACopy ( &(tmp->real_name), tmpSpec );
}
printf("ATTACHMENT %d: Type = %s\n", i, tmpFile->type);
printf("ATTACHMENT %d: Encoding = %s\n", i, tmpFile->encoding);
printf("ATTACHMENT %d: Description = %s\n", i, tmpFile->description);
if ( tmpFile->type )
{
mime_SACopy ( &(tmp->desired_type), tmpFile->type );
@ -1247,6 +1282,11 @@ mime_parse_stream_complete (nsMIMESession *stream)
{
editorType = nsMsgPlainTextEditor;
}
// Since we have body text, then we should set the compose fields with
// this data.
if (editorType == nsMsgPlainTextEditor)
fields->SetTheForcePlainText(PR_TRUE);
if (forward_inline)
{
@ -1267,11 +1307,30 @@ mime_parse_stream_complete (nsMIMESession *stream)
if ( (NS_SUCCEEDED(res)) && (newBody && newBody != body))
{
PR_FREEIF(body);
body = newBody;
bodyLen = newBodyLen;
// RICHIE SHERRY
//
// Insert the META tag to tell Gecko it's UTF-8...
//
nsString aNewBody("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">");
aNewBody.Append(newBody);
PR_FREEIF(newBody);
fields->SetCharacterSet(nsString("UTF-8").GetUnicode());
fields->SetBody(aNewBody.GetUnicode());
// RICHIE SHERRY
// RICHIE SHERRY OLD STUFF body = newBody;
// RICHIE SHERRY OLD STUFF bodyLen = newBodyLen;
}
else
{
fields->SetCharacterSet(nsString(mdd->mailcharset).GetUnicode());
fields->SetBody(nsString(body).GetUnicode());
}
PR_FREEIF(body);
} // end if (messageBody)
//
// At this point, we need to create a message compose window or editor
// window via XP-COM with the information that we have retrieved from
@ -1286,7 +1345,7 @@ mime_parse_stream_complete (nsMIMESession *stream)
#ifdef NS_DEBUG
printf("Time to create the composition window WITH a body!!!!\n");
#endif
CreateTheComposeWindow(fields, newAttachData);
CreateTheComposeWindow(fields, newAttachData, editorType);
}
PR_FREEIF(body);
@ -1301,14 +1360,14 @@ mime_parse_stream_complete (nsMIMESession *stream)
if (mdd->format_out == nsMimeOutput::nsMimeMessageEditorTemplate)
{
printf("RICHIE: Time to create the EDITOR with this template - NO body!!!!\n");
CreateTheComposeWindow(fields, newAttachData);
CreateTheComposeWindow(fields, newAttachData, nsMsgDefault);
}
else
{
#ifdef NS_DEBUG
printf("Time to create the composition window WITHOUT a body!!!!\n");
#endif
CreateTheComposeWindow(fields, newAttachData);
CreateTheComposeWindow(fields, newAttachData, nsMsgDefault);
}
}
}
@ -1319,7 +1378,7 @@ mime_parse_stream_complete (nsMIMESession *stream)
GetMailXlateionPreference(),
GetMailSigningPreference());
if (fields)
CreateTheComposeWindow(fields, newAttachData);
CreateTheComposeWindow(fields, newAttachData, nsMsgDefault);
}
if ( mdd->headers )
@ -1327,12 +1386,27 @@ mime_parse_stream_complete (nsMIMESession *stream)
//
// Free the original attachment structure...
// Make sure we only cleanup the local copy of the memory and not kill
// files we need on disk
//
if (mdd->attachments)
{
int i;
nsMsgAttachedFile *cur = mdd->attachments;
for ( i = 0; i < mdd->attachments_count; i++, cur++ )
{
if ( cur->file_spec )
{
delete ( cur->file_spec );
cur->file_spec = nsnull;
}
}
mime_free_attachments( mdd->attachments, mdd->attachments_count );
}
PR_FREEIF(mdd);
if (fields)
NS_RELEASE(fields);
@ -1433,6 +1507,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
char *hdr_value = NULL, *parm_value = NULL;
PRBool needURL = PR_FALSE;
PRBool creatingMsgBody = PR_TRUE;
PRBool bodyPart = PR_FALSE;
PR_ASSERT (mdd && headers);
if (!mdd || !headers)
@ -1477,6 +1552,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
return MIME_OUT_OF_MEMORY;
newAttachment = mdd->messageBody;
creatingMsgBody = PR_TRUE;
bodyPart = PR_TRUE;
}
else
{
@ -1522,30 +1598,8 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
workURLSpec = PL_strdup(contLoc);
PR_FREEIF(contLoc);
if (workURLSpec)
{
parm_value = PL_strdup(workURLSpec);
if (parm_value)
{
char *cp = NULL, *cp1=NULL ;
nsUnescape(parm_value);
// strip '"'
cp = parm_value;
while (*cp == '"')
cp++;
if ((cp1 = PL_strchr(cp, '"')))
*cp1 = 0;
nsMimeNewURI(&(newAttachment->orig_url), cp);
NS_ADDREF(newAttachment->orig_url);
PR_FREEIF(workURLSpec);
workURLSpec = PL_strdup(cp);
PR_FREEIF(parm_value);
}
}
mdd->curAttachment = newAttachment;
mdd->curAttachment = newAttachment;
newAttachment->type = MimeHeaders_get ( headers, HEADER_CONTENT_TYPE, PR_TRUE, PR_FALSE );
//
@ -1595,6 +1649,29 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
}
}
// This needs to be done so the attachment structure has a handle
// on the temp file for this attachment...
// if ( (tmpSpec) && (!bodyPart) )
if (tmpSpec)
{
char *tmpSpecStr = PR_smprintf("file://%s", tmpSpec->GetNativePathCString());
if (tmpSpecStr)
{
char *slashPtr = tmpSpecStr;
while (*slashPtr)
{
if (*slashPtr == '\\')
*slashPtr = '/';
slashPtr++;
}
nsMimeNewURI(&(newAttachment->orig_url), tmpSpecStr);
NS_IF_ADDREF(newAttachment->orig_url);
PR_FREEIF(tmpSpecStr);
}
}
PR_FREEIF(workURLSpec);
if (!tmpSpec)
return MIME_OUT_OF_MEMORY;

Просмотреть файл

@ -326,8 +326,6 @@ NS_IMETHODIMP nsStreamConverter::QueryInterface(REFNSIID aIID, void** aInstanceP
NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutListener, nsIChannel *aChannel)
{
nsresult rv = NS_OK;
if (!aOutListener)
return NS_ERROR_NULL_POINTER;
mOutListener = aOutListener;
@ -391,8 +389,8 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
// or nsMimeMessageEditorTemplate where we don't need any emitters
//
if ( (newType != nsMimeOutput::nsMimeMessageDraftOrTemplate) ||
(newType != nsMimeOutput::nsMimeMessageEditorTemplate) )
if ( (newType != nsMimeOutput::nsMimeMessageDraftOrTemplate) &&
(newType != nsMimeOutput::nsMimeMessageEditorTemplate) )
{
nsAutoString progID (eOneByte);
progID = "component://netscape/messenger/mimeemitter;type=";
@ -567,7 +565,8 @@ nsStreamConverter::OnStartRequest(nsIChannel * aChannel, nsISupports *ctxt)
#endif
// forward the start rquest to any listeners
mOutListener->OnStartRequest(aChannel, ctxt);
if (mOutListener)
mOutListener->OnStartRequest(aChannel, ctxt);
return NS_OK;
}
@ -607,7 +606,8 @@ nsStreamConverter::OnStopRequest(nsIChannel * aChannel, nsISupports *ctxt, nsres
InternalCleanup();
// forward on top request to any listeners
mOutListener->OnStopRequest(aChannel, ctxt, status, errorMsg);
if (mOutListener)
mOutListener->OnStopRequest(aChannel, ctxt, status, errorMsg);
// Time to return...
return NS_OK;

Просмотреть файл

@ -30,7 +30,6 @@ PROGRAM= .\$(OBJDIR)\$(EXENAME).exe
OBJS= .\$(OBJDIR)\mimetest.obj
LLIBS= \
$(DIST)\lib\rdf.lib \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\uconv.lib \
$(LIBNSPR)

Просмотреть файл

@ -41,6 +41,14 @@
#include "msgCore.h"
#include "nsIIOService.h"
#include "nsMimeEmitterCID.h"
#include "nsIAppShellService.h"
#include "nsAppShellCIDs.h"
#include "nsMsgBaseCID.h"
#include "nsIMsgMailSession.h"
#ifdef XP_PC
#include <windows.h>
#endif
////////////////////////////////////////////////////////////////////////////////////
// THIS IS THE STUFF TO GET THE TEST HARNESS OFF THE GROUND
@ -77,6 +85,7 @@
// I18N
static NS_DEFINE_CID(charsetCID, CONV_CID);
NS_DEFINE_IID(kConvMeIID, CONV_IID);
static NS_DEFINE_CID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
// prefs
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
@ -96,6 +105,8 @@ static NS_DEFINE_CID(kHtmlEmitterCID, NS_HTML_MIME_EMITTER_CID);
static NS_DEFINE_CID(kXmlEmitterCID, NS_XML_MIME_EMITTER_CID);
static NS_DEFINE_CID(kRawEmitterCID, NS_RAW_MIME_EMITTER_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
nsICharsetConverterManager *ccMan = nsnull;
static nsresult
@ -198,7 +209,9 @@ private:
PRBool mInClosingTag;
nsMimeOutputType mOutFormat;
};
NS_IMPL_ISUPPORTS(ConsoleOutputStreamListener, nsIOutputStream::GetIID());
//NS_IMPL_ISUPPORTS2(ConsoleOutputStreamListener, nsIOutputStream, nsIStreamListener);
NS_IMPL_ISUPPORTS(ConsoleOutputStreamListener, nsIStreamListener::GetIID());
#define TAB_SPACES 2
@ -413,12 +426,15 @@ main(int argc, char** argv)
// Get an event queue started...
NS_WITH_SERVICE(nsIEventQueueService, theEventQueueService, kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
rv = theEventQueueService->CreateThreadEventQueue();
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create thread event queue");
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv))
return rv;
// Do the conversion!
DoRFC822toHTMLConversion(argv[1], argc);
// Cleanup stuff necessary...
@ -435,6 +451,11 @@ DoRFC822toHTMLConversion(char *filename, int numArgs)
nsMimeOutputType outFormat;
char *contentType = nsnull;
if (numArgs >= 3)
outFormat = nsMimeOutput::nsMimeMessageDraftOrTemplate;
else
outFormat = nsMimeOutput::nsMimeMessageQuoting;
char *opts = PL_strchr(filename, '?');
char save;
if (opts)
@ -466,14 +487,18 @@ DoRFC822toHTMLConversion(char *filename, int numArgs)
return rv;
}
// Create the consumer output stream.. this will receive all the HTML from libmime
ConsoleOutputStreamListener *ptr = new ConsoleOutputStreamListener();
nsCOMPtr<nsIStreamListener> out = (nsIStreamListener *) ptr;
if (!out)
nsCOMPtr<nsIStreamListener> out = nsnull;
ConsoleOutputStreamListener *ptr = nsnull;
if (outFormat != nsMimeOutput::nsMimeMessageDraftOrTemplate)
{
printf("Failed to create nsIOutputStream\n");
return NS_ERROR_FAILURE;
// Create the consumer output stream.. this will receive all the HTML from libmime
ptr = new ConsoleOutputStreamListener();
out = do_QueryInterface(ptr);
if (!out)
{
printf("Failed to create nsIOutputStream\n");
return NS_ERROR_FAILURE;
}
}
// This is the producer stream that will deliver data from the disk file...
@ -501,24 +526,23 @@ DoRFC822toHTMLConversion(char *filename, int numArgs)
}
// Set us as the output stream for HTML data from libmime...
// if (numArgs >= 3)
nsCOMPtr<nsIMimeStreamConverter> mimeStream = do_QueryInterface(mimeParser);
mimeStream->SetMimeOutputType(nsMimeOutput::nsMimeMessageHeaderDisplay);
rv = mimeParser->Init(theURI, out, nsnull);
mimeStream->SetMimeOutputType(outFormat);
rv = mimeParser->Init(theURI, out, nsnull);
if (NS_FAILED(rv) || !mimeParser)
{
printf("Unable to set the output stream for the mime parser...\ncould be failure to create internal libmime data\n");
return NS_ERROR_FAILURE;
}
if (contentType)
{
printf("Content type for output = %s\n", contentType);
PR_FREEIF(contentType);
}
ptr->SetFormat(outFormat);
if (ptr)
ptr->SetFormat(outFormat);
// Assuming this is an RFC822 message...
mimeParser->OnStartRequest(nsnull, theURI);