Files
Mozilla/mozilla/mailnews/local/src/nsLocalUndoTxn.cpp
bienvenu%netscape.com 4be85f382d new paramater to selectFolder
git-svn-id: svn://10.0.0.236/trunk@42375 18797224-902f-48f8-a5cc-f745e15eee43
1999-08-05 23:27:10 +00:00

332 lines
9.6 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998, 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsLocalUndoTxn.h"
#include "nsImapCore.h"
#include "nsMsgImapCID.h"
#include "nsIImapService.h"
#include "nsIUrlListener.h"
#include "nsIEventQueueService.h"
static NS_DEFINE_CID(kMailboxServiceCID, NS_IMAILBOXSERVICE_IID);
static NS_DEFINE_CID(kCImapService, NS_IMAPSERVICE_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
nsLocalMoveCopyMsgTxn::nsLocalMoveCopyMsgTxn() :
m_isMove(PR_FALSE), m_srcIsImap4(PR_FALSE)
{
Init(nsnull, nsnull, PR_FALSE);
}
nsLocalMoveCopyMsgTxn::nsLocalMoveCopyMsgTxn(nsIMsgFolder* srcFolder,
nsIMsgFolder* dstFolder,
PRBool isMove) :
m_isMove(PR_FALSE), m_srcIsImap4(PR_FALSE)
{
Init(srcFolder, dstFolder, isMove);
}
nsLocalMoveCopyMsgTxn::~nsLocalMoveCopyMsgTxn()
{
}
NS_IMPL_ADDREF_INHERITED(nsLocalMoveCopyMsgTxn, nsMsgTxn)
NS_IMPL_RELEASE_INHERITED(nsLocalMoveCopyMsgTxn, nsMsgTxn)
NS_IMETHODIMP
nsLocalMoveCopyMsgTxn::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
*aInstancePtr = nsnull;
if (aIID.Equals(nsLocalMoveCopyMsgTxn::GetIID()))
{
*aInstancePtr = NS_STATIC_CAST(nsLocalMoveCopyMsgTxn*, this);
}
if (*aInstancePtr)
{
NS_ADDREF_THIS();
return NS_OK;
}
return nsMsgTxn::QueryInterface(aIID, aInstancePtr);
}
nsresult
nsLocalMoveCopyMsgTxn::Init(nsIMsgFolder* srcFolder, nsIMsgFolder* dstFolder,
PRBool isMove)
{
nsresult rv;
rv = SetSrcFolder(srcFolder);
rv = SetDstFolder(dstFolder);
m_isMove = isMove;
char *uri = nsnull;
if (!srcFolder) return rv;
rv = srcFolder->GetURI(&uri);
nsString2 protocolType(uri, eOneByte);
PR_FREEIF(uri);
protocolType.SetLength(protocolType.FindChar(':'));
if (protocolType.EqualsIgnoreCase("imap"))
{
m_srcIsImap4 = PR_TRUE;
}
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::SetSrcFolder(nsIMsgFolder* srcFolder)
{
nsresult rv = NS_ERROR_NULL_POINTER;
if (srcFolder)
m_srcFolder = do_QueryInterface(srcFolder, &rv);
return rv;
}
nsresult
nsLocalMoveCopyMsgTxn::SetDstFolder(nsIMsgFolder* dstFolder)
{
nsresult rv = NS_ERROR_NULL_POINTER;
if (dstFolder)
m_dstFolder = do_QueryInterface(dstFolder, &rv);
return rv;
}
nsresult
nsLocalMoveCopyMsgTxn::AddSrcKey(nsMsgKey aKey)
{
m_srcKeyArray.Add(aKey);
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::AddDstKey(nsMsgKey aKey)
{
m_dstKeyArray.Add(aKey);
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::AddDstMsgSize(PRUint32 msgSize)
{
m_dstSizeArray.Add(msgSize);
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::SetUndoString(nsString *aString)
{
if (!aString) return NS_ERROR_NULL_POINTER;
m_undoString = *aString;
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::SetRedoString(nsString* aString)
{
if (!aString) return NS_ERROR_NULL_POINTER;
m_redoString = *aString;
return NS_OK;
}
NS_IMETHODIMP
nsLocalMoveCopyMsgTxn::GetUndoString(nsString* aString)
{
if (!aString) return NS_ERROR_NULL_POINTER;
*aString = m_undoString;
return NS_OK;
}
NS_IMETHODIMP
nsLocalMoveCopyMsgTxn::GetRedoString(nsString* aString)
{
if (!aString) return NS_ERROR_NULL_POINTER;
*aString = m_redoString;
return NS_OK;
}
nsresult
nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder,
nsMsgKeyArray& keyArray,
PRBool addFlag)
{
nsresult rv = NS_ERROR_FAILURE;
if (m_srcIsImap4)
{
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIUrlListener> urlListener;
nsString2 msgIds("", eOneByte);
PRUint32 i, count = keyArray.GetSize();
urlListener = do_QueryInterface(folder, &rv);
for (i=0; i < count; i++)
{
if (msgIds.Length() > 0)
msgIds.Append(',');
msgIds.Append((PRInt32) keyArray.GetAt(i));
}
nsCOMPtr<nsIEventQueue> eventQueue;
NS_WITH_SERVICE(nsIEventQueueService, pEventQService,
kEventQueueServiceCID, &rv);
if (NS_SUCCEEDED(rv) && pEventQService)
{
pEventQService->GetThreadEventQueue(PR_GetCurrentThread(),
getter_AddRefs(eventQueue));
if (eventQueue)
{
if (addFlag)
rv =imapService->AddMessageFlags(eventQueue, folder,
urlListener, nsnull,
msgIds.GetBuffer(),
kImapMsgDeletedFlag,
PR_TRUE);
else
rv = imapService->SubtractMessageFlags(eventQueue,
folder,
urlListener, nsnull,
msgIds.GetBuffer(),
kImapMsgDeletedFlag,
PR_TRUE);
if (NS_SUCCEEDED(rv))
imapService->SelectFolder(eventQueue, folder,
urlListener, nsnull, nsnull);
}
}
}
rv = NS_OK; // always return NS_OK to indicate that the src is imap
}
else
{
rv = NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
nsLocalMoveCopyMsgTxn::Undo()
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIMsgDatabase> srcDB;
nsCOMPtr<nsIMsgDatabase> dstDB;
rv = m_srcFolder->GetMsgDatabase(getter_AddRefs(srcDB));
if(NS_FAILED(rv)) return rv;
rv = m_dstFolder->GetMsgDatabase(getter_AddRefs(dstDB));
if (NS_FAILED(rv)) return rv;
PRUint32 count = m_srcKeyArray.GetSize();
PRUint32 i;
nsCOMPtr<nsIMsgDBHdr> oldHdr;
nsCOMPtr<nsIMsgDBHdr> newHdr;
if (m_isMove)
{
if (m_srcIsImap4)
{
rv = UndoImapDeleteFlag(m_srcFolder, m_srcKeyArray, PR_FALSE);
}
else
{
for (i=0; i<count; i++)
{
rv = dstDB->GetMsgHdrForKey(m_dstKeyArray.GetAt(i),
getter_AddRefs(oldHdr));
NS_ASSERTION(oldHdr, "fatal ... cannot get old msg header\n");
if (NS_SUCCEEDED(rv) && oldHdr)
{
rv = srcDB->CopyHdrFromExistingHdr(m_srcKeyArray.GetAt(i),
oldHdr,
getter_AddRefs(newHdr));
NS_ASSERTION(newHdr,
"fatal ... cannot create new msg header\n");
if (NS_SUCCEEDED(rv) && newHdr)
srcDB->UndoDelete(newHdr);
}
}
}
srcDB->Commit(nsMsgDBCommitType::kLargeCommit);
}
dstDB->DeleteMessages(&m_dstKeyArray, nsnull);
dstDB->Commit(nsMsgDBCommitType::kLargeCommit);
return rv;
}
NS_IMETHODIMP
nsLocalMoveCopyMsgTxn::Redo()
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsIMsgDatabase> srcDB;
nsCOMPtr<nsIMsgDatabase> dstDB;
rv = m_srcFolder->GetMsgDatabase(getter_AddRefs(srcDB));
if(NS_FAILED(rv)) return rv;
rv = m_dstFolder->GetMsgDatabase(getter_AddRefs(dstDB));
if (NS_FAILED(rv)) return rv;
PRUint32 count = m_srcKeyArray.GetSize();
PRUint32 i;
nsCOMPtr<nsIMsgDBHdr> oldHdr;
nsCOMPtr<nsIMsgDBHdr> newHdr;
for (i=0; i<count; i++)
{
rv = srcDB->GetMsgHdrForKey(m_srcKeyArray.GetAt(i),
getter_AddRefs(oldHdr));
NS_ASSERTION(oldHdr, "fatal ... cannot get old msg header\n");
if (NS_SUCCEEDED(rv) && oldHdr)
{
rv = dstDB->CopyHdrFromExistingHdr(m_dstKeyArray.GetAt(i),
oldHdr,
getter_AddRefs(newHdr));
NS_ASSERTION(newHdr, "fatal ... cannot get new msg header\n");
if (NS_SUCCEEDED(rv) && newHdr)
{
if (m_dstSizeArray.GetSize() > i)
rv = newHdr->SetMessageSize(m_dstSizeArray.GetAt(i));
dstDB->UndoDelete(newHdr);
}
}
}
dstDB->Commit(nsMsgDBCommitType::kLargeCommit);
if (m_isMove)
{
if (m_srcIsImap4)
{
rv = UndoImapDeleteFlag(m_srcFolder, m_srcKeyArray, PR_TRUE);
}
else
{
rv = srcDB->DeleteMessages(&m_srcKeyArray, nsnull);
srcDB->Commit(nsMsgDBCommitType::kLargeCommit);
}
}
return rv;
}