More work on copying/moving messages.

This commit is contained in:
putterman%netscape.com 1999-04-01 23:42:41 +00:00
parent 58c4f5a346
commit 8c3ed7e4b2
8 changed files with 142 additions and 21 deletions

View File

@ -7,6 +7,7 @@
#include "nsISupports.h" /* interface nsISupports */
#include "nsIInputStream.h" /* interface nsIInputStream */
#include "nsIMessage.h" /* interface nsIMessage */
#ifdef XPIDL_JS_STUBS
#include "jsapi.h"
@ -27,14 +28,14 @@ class nsICopyMessageListener : public nsISupports {
return iid;
}
/* void BeginCopy (); */
NS_IMETHOD BeginCopy() = 0;
/* void BeginCopy (in nsIMessage message); */
NS_IMETHOD BeginCopy(nsIMessage *message) = 0;
/* void CopyData (in nsIInputStream aIStream, in long aLength); */
NS_IMETHOD CopyData(nsIInputStream *aIStream, PRInt32 aLength) = 0;
/* void EndCopy (); */
NS_IMETHOD EndCopy() = 0;
/* void EndCopy (in boolean copySucceeded); */
NS_IMETHOD EndCopy(PRBool copySucceeded) = 0;
#ifdef XPIDL_JS_STUBS
static NS_EXPORT_(JSObject *) InitJSClass(JSContext *cx);

View File

@ -18,6 +18,7 @@
#include "nsISupports.idl"
#include "nsIInputStream.idl"
#include "nsIMessage.idl"
[uuid(53CA78FE-E231-11d2-8A4D-0060B0FC04D2)]
@ -26,7 +27,7 @@
interface nsICopyMessageListener : nsISupports
{
void BeginCopy();
void BeginCopy(in nsIMessage message);
void CopyData(in nsIInputStream aIStream, in long aLength);
void EndCopy();
void EndCopy(in boolean copySucceeded);
};

View File

@ -17,12 +17,91 @@
*/
#include "nsCopyMessageStreamListener.h"
#include "nsIMsgMailNewsUrl.h"
#include "nsIMailboxUrl.h"
#include "nsIRDFService.h"
#include "nsIRDFNode.h"
#include "nsRDFCID.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
/* the following macros actually implement addref, release and query interface for our component. */
NS_IMPL_ADDREF(nsCopyMessageStreamListener)
NS_IMPL_RELEASE(nsCopyMessageStreamListener)
NS_IMPL_QUERY_INTERFACE(nsCopyMessageStreamListener, nsIStreamListener::GetIID()); /* we need to pass in the interface ID of this interface */
static nsresult GetMessage(nsIURL *aURL, nsIMessage **message)
{
nsIMsgUriUrl *uriURL;
char* uri;
nsresult rv;
if(!message)
return NS_ERROR_NULL_POINTER;
//Need to get message we are about to copy
rv = aURL->QueryInterface(nsIMsgUriUrl::GetIID(), (void**)&uriURL);
if(NS_FAILED(rv))
return rv;
rv = uriURL->GetURI(&uri);
NS_RELEASE(uriURL);
if(NS_FAILED(rv))
return rv;
nsIRDFService *rdfService;
if(NS_SUCCEEDED(rv = nsServiceManager::GetService(kRDFServiceCID,
nsIRDFService::GetIID(),
(nsISupports**) &rdfService)))
{
nsIRDFResource *messageResource;
if(NS_SUCCEEDED(rdfService->GetResource(uri, &messageResource)))
{
messageResource->QueryInterface(nsIMessage::GetIID(), (void**)message);
NS_RELEASE(messageResource);
}
nsServiceManager::ReleaseService(kRDFServiceCID, rdfService);
}
delete[] uri;
return rv;
}
static nsresult IsMoveMessage(nsIURL *aURL, PRBool *isMoveMessage)
{
if(!isMoveMessage)
return NS_ERROR_NULL_POINTER;
*isMoveMessage = PR_FALSE;
nsIMailboxUrl *mailboxURL;
if(NS_SUCCEEDED(aURL->QueryInterface(nsIMailboxUrl::GetIID(), (void**)&mailboxURL)))
{
nsMailboxAction mailboxAction;
mailboxURL->GetMailboxAction(&mailboxAction);
NS_IF_RELEASE(mailboxURL);
*isMoveMessage = (mailboxAction == nsMailboxActionMoveMessage);
}
return NS_OK;
}
static nsresult DeleteMessage(nsIURL *aURL, nsIMsgFolder *srcFolder)
{
nsIMessage *message = nsnull;
nsresult rv;
rv = GetMessage(aURL, &message);
if(NS_SUCCEEDED(rv) && srcFolder)
rv = srcFolder->DeleteMessage(message);
NS_IF_RELEASE(message);
return rv;
}
nsCopyMessageStreamListener::nsCopyMessageStreamListener(nsIMsgFolder *srcFolder,
nsICopyMessageListener *destination,
nsISupports *listenerData)
@ -81,7 +160,16 @@ NS_IMETHODIMP nsCopyMessageStreamListener::OnDataAvailable(nsIURL* aURL, nsIInpu
}
NS_IMETHODIMP nsCopyMessageStreamListener::OnStartBinding(nsIURL* aURL, const char *aContentType)
{
return mDestination->BeginCopy();
nsIMessage *message = nsnull;
nsresult rv;
rv = GetMessage(aURL, &message);
rv = mDestination->BeginCopy(message);
if(message)
NS_RELEASE(message);
return rv;
}
NS_IMETHODIMP nsCopyMessageStreamListener::OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax)
@ -96,5 +184,16 @@ NS_IMETHODIMP nsCopyMessageStreamListener::OnStatus(nsIURL* aURL, const PRUnicha
NS_IMETHODIMP nsCopyMessageStreamListener::OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg)
{
return mDestination->EndCopy();
//If this is a move and we finished the copy, delete the old message.
if(aStatus == NS_BINDING_SUCCEEDED)
{
PRBool moveMessage;
IsMoveMessage(aURL, &moveMessage);
if(moveMessage)
{
DeleteMessage(aURL, mSrcFolder);
}
}
return mDestination->EndCopy(aStatus == NS_BINDING_SUCCEEDED);
}

View File

@ -451,7 +451,7 @@ static nsresult CopyMessages(JSContext *cx, JSObject *obj, uintN argc, jsval *ar
argv[2]);
if (!rBool || NS_OK != nativeThis->CopyMessages(srcFolder, dstFolder, messages, PR_FALSE)) {
if (!rBool || NS_OK != nativeThis->CopyMessages(srcFolder, dstFolder, messages, isMove)) {
return NS_ERROR_FAILURE;
}

View File

@ -323,7 +323,6 @@ nsMsgLocalMailFolder::GetMessages(nsIEnumerator* *result)
nsresult rv = GetPath(path);
if (NS_FAILED(rv)) return rv;
//END DEBUGGING
nsresult folderOpen;
if(!NS_SUCCEEDED(folderOpen = nsMailDatabase::Open(path, PR_TRUE, &mMailDatabase, PR_FALSE)) &&
folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE || folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING )
@ -335,8 +334,6 @@ nsMsgLocalMailFolder::GetMessages(nsIEnumerator* *result)
if(mMailDatabase)
{
//if(strcmp(path.GetLeafName(), "test3") != 0)
// return mMailDatabase->EnumerateMessages(result);
mMailDatabase->AddListener(this);
@ -1020,7 +1017,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::OnAnnouncerGoingAway(nsIDBChangeAnnouncer *
}
//nsICopyMessageListener
NS_IMETHODIMP nsMsgLocalMailFolder::BeginCopy()
NS_IMETHODIMP nsMsgLocalMailFolder::BeginCopy(nsIMessage *message)
{
PRBool isLocked;
@ -1038,6 +1035,13 @@ NS_IMETHODIMP nsMsgLocalMailFolder::BeginCopy()
//Before we continue we should verify that there is enough diskspace.
//XXX How do we do this?
mCopyState->fileStream = new nsOutputFileStream(path, PR_WRONLY | PR_CREATE_FILE);
//The new key is the end of the file
mCopyState->fileStream->seek(PR_SEEK_END, 0);
mCopyState->dstKey = mCopyState->fileStream->tell();
mCopyState->message = message;
if(mCopyState->message)
mCopyState->message->AddRef();
return NS_OK;
}
@ -1068,17 +1072,31 @@ NS_IMETHODIMP nsMsgLocalMailFolder::CopyData(nsIInputStream *aIStream, PRInt32 a
return rv;
}
NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy()
NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
{
mCopyState->fileStream->close();
delete mCopyState->fileStream;
//Copy the header to the new database
if(copySucceeded && mCopyState->message)
{
nsIMessage *newHdr;
mMailDatabase->CopyHdrFromExistingHdr(mCopyState->dstKey, mCopyState->message, &newHdr);
NS_IF_RELEASE(newHdr);
}
if(mCopyState->fileStream)
{
mCopyState->fileStream->close();
delete mCopyState->fileStream;
}
if(mCopyState->message)
mCopyState->message->Release();
delete mCopyState;
mCopyState = nsnull;
//we finished the copy so someone else can write to us.
PRBool haveSemaphore;
nsresult rv = TestSemaphore(NS_STATIC_CAST(nsIMsgLocalMailFolder*, this), &haveSemaphore);
if(rv && haveSemaphore)
if(NS_SUCCEEDED(rv) && haveSemaphore)
ReleaseSemaphore(NS_STATIC_CAST(nsIMsgLocalMailFolder*, this));
return NS_OK;

View File

@ -34,6 +34,8 @@
typedef struct {
nsOutputFileStream *fileStream;
nsIMessage *message;
nsMsgKey dstKey;
} nsLocalMailCopyState;
class nsMsgLocalMailFolder : public nsMsgFolder, public nsIMsgLocalMailFolder,
@ -124,9 +126,9 @@ public:
NS_IMETHOD OnAnnouncerGoingAway(nsIDBChangeAnnouncer * instigator);
//nsICopyMessageListener
NS_IMETHOD BeginCopy();
NS_IMETHOD BeginCopy(nsIMessage *message);
NS_IMETHOD CopyData(nsIInputStream *aIStream, PRInt32 aLength);
NS_IMETHOD EndCopy();
NS_IMETHOD EndCopy(PRBool copySucceeded);
protected:

View File

@ -164,7 +164,8 @@
</menu>
<menuitem name="Edit Message as New" onclick="MsgEditMessageAsNew();"/>
<separator/>
<menu name="Move Message" datasources="rdf:mailnews" id="mailbox:/" open="true">
<menu name="Move Message" datasources="rdf:mailnews" id="mailbox:/" open="true"
onclick="MsgMoveMessage(event.target)">
</menu>
<menu name="Copy Message" datasources="rdf:mailnews" id="mailbox:/" open="true"
onclick="MsgCopyMessage(event.target)">

View File

@ -204,7 +204,6 @@ function MsgPreviousFlaggedMessage() {}
function MsgGoBack() {}
function MsgGoForward() {}
function MsgEditMessageAsNew() {}
function MsgMoveMessage() {}
function MsgAddSenderToAddressBook() {}
function MsgAddAllToAddressBook() {}
function MsgMarkMsgAsRead() {}