зеркало из https://github.com/mozilla/pjs.git
implement offline undo of imap delete r=naving, sr=sspitzer a=asa 93128
This commit is contained in:
Родитель
1e367845e7
Коммит
dc15073f81
|
@ -198,13 +198,14 @@ nsresult nsMsgThread::RerootThread(nsIMsgDBHdr *newParentOfOldRoot, nsIMsgDBHdr
|
|||
do
|
||||
{
|
||||
ancestorHdr->GetThreadParent(&newHdrAncestor);
|
||||
if (newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey)
|
||||
if (newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey && newHdrAncestor != newRoot)
|
||||
{
|
||||
newRoot = newHdrAncestor;
|
||||
rv = m_mdbDB->GetMsgHdrForKey(newRoot, getter_AddRefs(ancestorHdr));
|
||||
}
|
||||
}
|
||||
while (NS_SUCCEEDED(rv) && ancestorHdr && newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey);
|
||||
while (NS_SUCCEEDED(rv) && ancestorHdr && newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey
|
||||
&& newHdrAncestor != newRoot);
|
||||
SetThreadRootKey(newRoot);
|
||||
ReparentNonReferenceChildrenOf(oldRoot, newRoot, announcer);
|
||||
if (ancestorHdr)
|
||||
|
|
|
@ -2916,7 +2916,6 @@ NS_IMETHODIMP nsImapMailFolder::StoreImapFlags(PRInt32 flags, PRBool addFlags, n
|
|||
GetDatabase(nsnull);
|
||||
if (mDatabase)
|
||||
{
|
||||
// UndoManager *undoManager = NULL;
|
||||
PRUint32 total = numKeys;
|
||||
|
||||
for (PRUint32 keyIndex=0; keyIndex < total; keyIndex++)
|
||||
|
@ -2926,25 +2925,6 @@ NS_IMETHODIMP nsImapMailFolder::StoreImapFlags(PRInt32 flags, PRBool addFlags, n
|
|||
SetFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
|
||||
if (NS_SUCCEEDED(rv) && op)
|
||||
{
|
||||
#if 0
|
||||
MailDB *originalDB = NULL;
|
||||
if (op->GetOperationFlags() & kMoveResult)
|
||||
{
|
||||
// get the op in the source db and change the flags there
|
||||
OfflineImapOperation *originalOp = GetOriginalOp(op, &originalDB);
|
||||
if (originalOp)
|
||||
{
|
||||
if (undoManager && undoManager->GetState() == UndoIdle && NET_IsOffline()) {
|
||||
OfflineIMAPUndoAction *undoAction = new
|
||||
OfflineIMAPUndoAction(paneForFlagUrl, (MSG_FolderInfo*) this, op->GetMessageKey(), kFlagsChanged,
|
||||
this, NULL, flags, NULL, addFlags);
|
||||
if (undoAction)
|
||||
undoManager->AddUndoAction(undoAction);
|
||||
}
|
||||
op = originalOp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
imapMessageFlagsType newFlags;
|
||||
op->GetNewFlags(&newFlags);
|
||||
|
||||
|
@ -2952,13 +2932,6 @@ NS_IMETHODIMP nsImapMailFolder::StoreImapFlags(PRInt32 flags, PRBool addFlags, n
|
|||
op->SetFlagOperation(newFlags | flags);
|
||||
else
|
||||
op->SetFlagOperation(newFlags & ~flags);
|
||||
#if 0
|
||||
if (originalDB)
|
||||
{
|
||||
originalDB->Close();
|
||||
originalDB = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mDatabase->Commit(nsMsgDBCommitType::kLargeCommit); // flush offline flags
|
||||
|
@ -4895,11 +4868,11 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
{
|
||||
NS_ENSURE_ARG(messages);
|
||||
nsresult rv = NS_OK;
|
||||
nsresult stopit = 0;
|
||||
nsCOMPtr <nsIMsgDatabase> sourceMailDB;
|
||||
nsresult stopit = 0;
|
||||
nsCOMPtr <nsIMsgDatabase> sourceMailDB;
|
||||
nsCOMPtr <nsIDBFolderInfo> srcDbFolderInfo;
|
||||
srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(srcDbFolderInfo), getter_AddRefs(sourceMailDB));
|
||||
PRBool deleteToTrash = PR_FALSE;
|
||||
PRBool deleteToTrash = PR_FALSE;
|
||||
PRUint32 srcCount;
|
||||
messages->Count(&srcCount);
|
||||
nsCOMPtr<nsIImapIncomingServer> imapServer;
|
||||
|
@ -4913,18 +4886,13 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
}
|
||||
if (sourceMailDB)
|
||||
{
|
||||
#ifdef DOING_OFFLINEUNDO_YET
|
||||
UndoManager *undoManager = NULL;
|
||||
|
||||
if (state && state->sourcePane)
|
||||
undoManager = state->sourcePane->GetUndoManager();
|
||||
|
||||
PRBool shouldUndoOffline = undoManager && NET_IsOffline();
|
||||
if (shouldUndoOffline)
|
||||
undoManager->StartBatch();
|
||||
#endif
|
||||
// save the future ops in the source DB, if this is not a imap->local copy/move
|
||||
|
||||
nsCOMPtr <nsITransactionManager> txnMgr;
|
||||
if (msgWindow)
|
||||
msgWindow->GetTransactionManager(getter_AddRefs(txnMgr));
|
||||
if (txnMgr)
|
||||
txnMgr->BeginBatch();
|
||||
GetDatabase(nsnull);
|
||||
if (mDatabase)
|
||||
{
|
||||
|
@ -5013,16 +4981,28 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
}
|
||||
else
|
||||
sourceOp->AddMessageCopyOperation(folderURI); // offline copy
|
||||
#ifdef DOING_OFFLINEUNDO_YET
|
||||
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
|
||||
{ // only need undo if we're really offline and not pseudo offline
|
||||
OfflineIMAPUndoAction *undoAction = new
|
||||
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, sourceOp->GetMessageKey(), opType,
|
||||
sourceMailDB->GetFolderInfo(), dstFolder, 0, NULL, 0);
|
||||
if (undoAction)
|
||||
undoManager->AddUndoAction(undoAction);
|
||||
|
||||
nsMsgKeyArray srcKeyArray;
|
||||
nsCOMPtr<nsIUrlListener> urlListener;
|
||||
|
||||
sourceOp->GetOperation(&opType);
|
||||
srcKeyArray.Add(originalKey);
|
||||
rv = QueryInterface(NS_GET_IID(nsIUrlListener), getter_AddRefs(urlListener));
|
||||
nsImapOfflineTxn *undoMsgTxn = new
|
||||
nsImapOfflineTxn(srcFolder, &srcKeyArray, this, isMove, opType, message,
|
||||
m_eventQueue, urlListener);
|
||||
|
||||
if (undoMsgTxn)
|
||||
{
|
||||
if (isMove)
|
||||
undoMsgTxn->SetTransactionType(nsIMessenger::eMoveMsg);
|
||||
else
|
||||
undoMsgTxn->SetTransactionType(nsIMessenger::eCopyMsg);
|
||||
// we're adding this undo action before the delete is successful. This is evil,
|
||||
// but 4.5 did it as well.
|
||||
if (txnMgr)
|
||||
txnMgr->DoTransaction(undoMsgTxn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
PRBool hasMsgOffline = PR_FALSE;
|
||||
srcFolder->HasMsgOffline(originalKey, &hasMsgOffline);
|
||||
|
@ -5075,16 +5055,21 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
SetFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
|
||||
destOp->SetSourceFolderURI(originalSrcFolderURI);
|
||||
destOp->SetMessageKey(originalKey);
|
||||
#ifdef DOING_OFFLINEUNDO_YET
|
||||
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
|
||||
{
|
||||
OfflineIMAPUndoAction *undoAction = new
|
||||
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, destOp->GetMessageKey(), kAddedHeader,
|
||||
state->destDB->GetFolderInfo(), dstFolder, 0, newMailHdr);
|
||||
if (undoAction)
|
||||
undoManager->AddUndoAction(undoAction);
|
||||
nsCOMPtr<nsIUrlListener> urlListener;
|
||||
|
||||
QueryInterface(NS_GET_IID(nsIUrlListener), getter_AddRefs(urlListener));
|
||||
nsMsgKeyArray keyArray;
|
||||
keyArray.Add(fakeBase + sourceKeyIndex);
|
||||
nsImapOfflineTxn *undoMsgTxn = new
|
||||
nsImapOfflineTxn(this, &keyArray, this, isMove, nsIMsgOfflineImapOperation::kAddedHeader,
|
||||
newMailHdr, m_eventQueue, urlListener);
|
||||
if (undoMsgTxn)
|
||||
{
|
||||
if (txnMgr)
|
||||
txnMgr->DoTransaction(undoMsgTxn);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -5093,23 +5078,39 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
successfulCopy = NS_SUCCEEDED(stopit);
|
||||
|
||||
|
||||
nsMsgKey msgKey;
|
||||
mailHdr->GetMessageKey(&msgKey);
|
||||
if (isMove && successfulCopy)
|
||||
{
|
||||
nsMsgKeyArray srcKeyArray;
|
||||
nsCOMPtr<nsIUrlListener> urlListener;
|
||||
|
||||
srcKeyArray.Add(msgKey);
|
||||
rv = QueryInterface(NS_GET_IID(nsIUrlListener), getter_AddRefs(urlListener));
|
||||
|
||||
nsOfflineImapOperationType opType = nsIMsgOfflineImapOperation::kDeletedMsg;
|
||||
if (!deleteToTrash)
|
||||
opType = nsIMsgOfflineImapOperation::kMsgMarkedDeleted;
|
||||
#ifdef DOING_OFFLINEUNDO_YET
|
||||
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
|
||||
{
|
||||
OfflineIMAPUndoAction *undoAction = new
|
||||
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, mailHdr->GetMessageKey(), opType,
|
||||
sourceMailDB->GetFolderInfo(), dstFolder, 0, mailHdr);
|
||||
if (undoAction)
|
||||
undoManager->AddUndoAction(undoAction);
|
||||
}
|
||||
#endif
|
||||
nsMsgKey msgKey;
|
||||
mailHdr->GetMessageKey(&msgKey);
|
||||
srcKeyArray.Add(msgKey);
|
||||
nsImapOfflineTxn *undoMsgTxn = new
|
||||
nsImapOfflineTxn(srcFolder, &srcKeyArray, this, isMove, opType, mailHdr,
|
||||
m_eventQueue, urlListener);
|
||||
if (undoMsgTxn)
|
||||
{
|
||||
if (isMove)
|
||||
{
|
||||
if (mFlags & MSG_FOLDER_FLAG_TRASH)
|
||||
undoMsgTxn->SetTransactionType(nsIMessenger::eDeleteMsg);
|
||||
else
|
||||
undoMsgTxn->SetTransactionType(nsIMessenger::eMoveMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
undoMsgTxn->SetTransactionType(nsIMessenger::eCopyMsg);
|
||||
}
|
||||
if (txnMgr)
|
||||
txnMgr->DoTransaction(undoMsgTxn);
|
||||
}
|
||||
if (deleteToTrash)
|
||||
sourceMailDB->DeleteMessage(msgKey, nsnull, PR_FALSE);
|
||||
else
|
||||
|
@ -5141,11 +5142,8 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
|
|||
SummaryChanged();
|
||||
srcFolder->SummaryChanged();
|
||||
}
|
||||
|
||||
#ifdef DOING_OFFLINEUNDO_YET
|
||||
if (shouldUndoOffline)
|
||||
undoManager->EndBatch();
|
||||
#endif
|
||||
if (txnMgr)
|
||||
txnMgr->EndBatch();
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && isMove)
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsIIMAPHostSessionList.h"
|
||||
#include "nsIMsgIncomingServer.h"
|
||||
|
||||
#include "nsIDBFolderInfo.h"
|
||||
|
||||
static NS_DEFINE_CID(kCImapService, NS_IMAPSERVICE_CID);
|
||||
static NS_DEFINE_CID(kCImapHostSessionList, NS_IIMAPHOSTSESSIONLIST_CID);
|
||||
|
@ -57,62 +57,62 @@ nsImapMoveCopyMsgTxn::Init(
|
|||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue* eventQueue, nsIUrlListener* urlListener)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_NewISupportsArray(getter_AddRefs(m_srcHdrs));
|
||||
m_srcMsgIdString = srcMsgIdString;
|
||||
m_idsAreUids = idsAreUids;
|
||||
m_isMove = isMove;
|
||||
m_srcFolder = getter_AddRefs(NS_GetWeakReference(srcFolder));
|
||||
m_dstFolder = getter_AddRefs(NS_GetWeakReference(dstFolder));
|
||||
m_eventQueue = do_QueryInterface(eventQueue, &rv);
|
||||
if (urlListener)
|
||||
m_urlListener = do_QueryInterface(urlListener, &rv);
|
||||
m_srcKeyArray.CopyArray(srcKeyArray);
|
||||
m_dupKeyArray.CopyArray(srcKeyArray);
|
||||
nsXPIDLCString uri;
|
||||
rv = srcFolder->GetURI(getter_Copies(uri));
|
||||
nsCString protocolType(uri);
|
||||
protocolType.SetLength(protocolType.FindChar(':'));
|
||||
// ** jt -- only do this for mailbox protocol
|
||||
if (protocolType.EqualsIgnoreCase("mailbox"))
|
||||
nsresult rv;
|
||||
NS_NewISupportsArray(getter_AddRefs(m_srcHdrs));
|
||||
m_srcMsgIdString = srcMsgIdString;
|
||||
m_idsAreUids = idsAreUids;
|
||||
m_isMove = isMove;
|
||||
m_srcFolder = getter_AddRefs(NS_GetWeakReference(srcFolder));
|
||||
m_dstFolder = getter_AddRefs(NS_GetWeakReference(dstFolder));
|
||||
m_eventQueue = do_QueryInterface(eventQueue, &rv);
|
||||
if (urlListener)
|
||||
m_urlListener = do_QueryInterface(urlListener, &rv);
|
||||
m_srcKeyArray.CopyArray(srcKeyArray);
|
||||
m_dupKeyArray.CopyArray(srcKeyArray);
|
||||
nsXPIDLCString uri;
|
||||
rv = srcFolder->GetURI(getter_Copies(uri));
|
||||
nsCString protocolType(uri);
|
||||
protocolType.SetLength(protocolType.FindChar(':'));
|
||||
// ** jt -- only do this for mailbox protocol
|
||||
if (protocolType.EqualsIgnoreCase("mailbox"))
|
||||
{
|
||||
m_srcIsPop3 = PR_TRUE;
|
||||
PRUint32 i, count = m_srcKeyArray.GetSize();
|
||||
nsCOMPtr<nsIMsgDatabase> srcDB;
|
||||
rv = srcFolder->GetMsgDatabase(nsnull, getter_AddRefs(srcDB));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIMsgDBHdr> srcHdr;
|
||||
nsCOMPtr<nsIMsgDBHdr> copySrcHdr;
|
||||
nsMsgKey pseudoKey;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
m_srcIsPop3 = PR_TRUE;
|
||||
PRUint32 i, count = m_srcKeyArray.GetSize();
|
||||
nsCOMPtr<nsIMsgDatabase> srcDB;
|
||||
rv = srcFolder->GetMsgDatabase(nsnull, getter_AddRefs(srcDB));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIMsgDBHdr> srcHdr;
|
||||
nsCOMPtr<nsIMsgDBHdr> copySrcHdr;
|
||||
nsMsgKey pseudoKey;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
rv = srcDB->GetMsgHdrForKey(m_srcKeyArray.GetAt(i),
|
||||
getter_AddRefs(srcHdr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
PRUint32 msgSize;
|
||||
rv = srcHdr->GetMessageSize(&msgSize);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_srcSizeArray.Add(msgSize);
|
||||
if (isMove)
|
||||
{
|
||||
rv = srcDB->GetMsgHdrForKey(m_srcKeyArray.GetAt(i),
|
||||
getter_AddRefs(srcHdr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
PRUint32 msgSize;
|
||||
rv = srcHdr->GetMessageSize(&msgSize);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
m_srcSizeArray.Add(msgSize);
|
||||
if (isMove)
|
||||
{
|
||||
srcDB->GetNextPseudoMsgKey(&pseudoKey);
|
||||
pseudoKey--;
|
||||
m_dupKeyArray.SetAt(i,pseudoKey);
|
||||
rv = srcDB->CopyHdrFromExistingHdr(pseudoKey,
|
||||
srcHdr, PR_FALSE,
|
||||
getter_AddRefs(copySrcHdr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(copySrcHdr);
|
||||
m_srcHdrs->AppendElement(supports);
|
||||
}
|
||||
}
|
||||
}
|
||||
srcDB->GetNextPseudoMsgKey(&pseudoKey);
|
||||
pseudoKey--;
|
||||
m_dupKeyArray.SetAt(i,pseudoKey);
|
||||
rv = srcDB->CopyHdrFromExistingHdr(pseudoKey,
|
||||
srcHdr, PR_FALSE,
|
||||
getter_AddRefs(copySrcHdr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(copySrcHdr);
|
||||
m_srcHdrs->AppendElement(supports);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsImapMoveCopyMsgTxn::~nsImapMoveCopyMsgTxn()
|
||||
|
@ -146,61 +146,61 @@ nsImapMoveCopyMsgTxn::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_IMETHODIMP
|
||||
nsImapMoveCopyMsgTxn::UndoTransaction(void)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIImapService> imapService(do_GetService(kCImapService, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (m_isMove || !m_dstFolder)
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIImapService> imapService(do_GetService(kCImapService, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (m_isMove || !m_dstFolder)
|
||||
{
|
||||
if (m_srcIsPop3)
|
||||
{
|
||||
if (m_srcIsPop3)
|
||||
{
|
||||
rv = UndoMailboxDelete();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder) return rv;
|
||||
nsCOMPtr<nsIUrlListener> srcListener =
|
||||
do_QueryInterface(srcFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// ** make sure we are in the selected state; use lite select
|
||||
// folder so we won't hit performance hard
|
||||
rv = imapService->LiteSelectFolder(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = imapService->SubtractMessageFlags(
|
||||
m_eventQueue, srcFolder, srcListener, nsnull,
|
||||
m_srcMsgIdString.get(), kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (DeleteIsMoveToTrash(srcFolder))
|
||||
rv = imapService->GetHeaders(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
PR_TRUE);
|
||||
}
|
||||
rv = UndoMailboxDelete();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (m_dstKeyArray.GetSize() > 0)
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||
if (NS_FAILED(rv) || !dstFolder) return rv;
|
||||
|
||||
nsCOMPtr<nsIUrlListener> dstListener;
|
||||
|
||||
dstListener = do_QueryInterface(dstFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// ** make sire we are in the selected state; use lite select folder
|
||||
// so we won't hit preformace hard
|
||||
rv = imapService->LiteSelectFolder(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = imapService->AddMessageFlags(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull,
|
||||
m_dstMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder) return rv;
|
||||
nsCOMPtr<nsIUrlListener> srcListener =
|
||||
do_QueryInterface(srcFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// ** make sure we are in the selected state; use lite select
|
||||
// folder so we won't hit performance hard
|
||||
rv = imapService->LiteSelectFolder(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = imapService->SubtractMessageFlags(
|
||||
m_eventQueue, srcFolder, srcListener, nsnull,
|
||||
m_srcMsgIdString.get(), kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (DeleteIsMoveToTrash(srcFolder))
|
||||
rv = imapService->GetHeaders(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
PR_TRUE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
if (m_dstKeyArray.GetSize() > 0)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||
if (NS_FAILED(rv) || !dstFolder) return rv;
|
||||
|
||||
nsCOMPtr<nsIUrlListener> dstListener;
|
||||
|
||||
dstListener = do_QueryInterface(dstFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// ** make sire we are in the selected state; use lite select folder
|
||||
// so we won't hit preformace hard
|
||||
rv = imapService->LiteSelectFolder(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = imapService->AddMessageFlags(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull,
|
||||
m_dstMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -402,3 +402,213 @@ PRBool nsImapMoveCopyMsgTxn::DeleteIsMoveToTrash(nsIMsgFolder *folder)
|
|||
retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsImapOfflineTxn::nsImapOfflineTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
nsIMsgFolder* dstFolder, PRBool isMove, nsOfflineImapOperationType opType,
|
||||
nsIMsgDBHdr *srcHdr,
|
||||
nsIEventQueue* eventQueue, nsIUrlListener* urlListener)
|
||||
{
|
||||
Init(srcFolder, srcKeyArray, nsnull, dstFolder, PR_TRUE,
|
||||
isMove, eventQueue, urlListener);
|
||||
|
||||
m_opType = opType;
|
||||
m_flags = 0;
|
||||
m_addFlags = PR_FALSE;
|
||||
m_header = srcHdr;
|
||||
if (opType == nsIMsgOfflineImapOperation::kDeletedMsg)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> srcDB;
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
|
||||
nsresult rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
|
||||
if (NS_SUCCEEDED(rv) && srcDB)
|
||||
{
|
||||
nsMsgKey pseudoKey;
|
||||
nsCOMPtr <nsIMsgDBHdr> copySrcHdr;
|
||||
|
||||
srcDB->GetNextPseudoMsgKey(&pseudoKey);
|
||||
pseudoKey--;
|
||||
m_dupKeyArray.SetAt(0, pseudoKey);
|
||||
rv = srcDB->CopyHdrFromExistingHdr(pseudoKey, srcHdr, PR_FALSE, getter_AddRefs(copySrcHdr));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(copySrcHdr);
|
||||
m_srcHdrs->AppendElement(supports);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsImapOfflineTxn::~nsImapOfflineTxn()
|
||||
{
|
||||
}
|
||||
|
||||
// Open the database and find the key for the offline operation that we want to
|
||||
// undo, then remove it from the database, we also hold on to this
|
||||
// data for a redo operation.
|
||||
NS_IMETHODIMP nsImapOfflineTxn::UndoTransaction(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder)
|
||||
return rv;
|
||||
nsCOMPtr <nsIMsgOfflineImapOperation> op;
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
nsCOMPtr <nsIMsgDatabase> srcDB;
|
||||
nsCOMPtr <nsIMsgDatabase> destDB;
|
||||
|
||||
nsMsgKey hdrKey = nsMsgKey_None;
|
||||
|
||||
if (m_header)
|
||||
m_header->GetMessageKey(&hdrKey);
|
||||
|
||||
rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
switch (m_opType)
|
||||
{
|
||||
case nsIMsgOfflineImapOperation::kMsgMoved:
|
||||
case nsIMsgOfflineImapOperation::kMsgCopy:
|
||||
case nsIMsgOfflineImapOperation::kAddedHeader:
|
||||
case nsIMsgOfflineImapOperation::kFlagsChanged:
|
||||
rv = srcDB->GetOfflineOpForKey(hdrKey, PR_FALSE, getter_AddRefs(op));
|
||||
if (NS_SUCCEEDED(rv) && op)
|
||||
{
|
||||
srcDB->RemoveOfflineOp(op);
|
||||
op = nsnull;
|
||||
}
|
||||
if (m_header && (m_opType == nsIMsgOfflineImapOperation::kAddedHeader))
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> mailHdr;
|
||||
nsMsgKey msgKey;
|
||||
m_header->GetMessageKey(&msgKey);
|
||||
rv = srcDB->GetMsgHdrForKey(msgKey, getter_AddRefs(mailHdr));
|
||||
if (mailHdr)
|
||||
srcDB->DeleteHeader(mailHdr, nsnull, PR_TRUE, PR_FALSE);
|
||||
}
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kDeletedMsg:
|
||||
{
|
||||
nsMsgKey msgKey;
|
||||
m_header->GetMessageKey(&msgKey);
|
||||
nsCOMPtr<nsIMsgDBHdr> undeletedHdr;
|
||||
m_srcHdrs->QueryElementAt(0, NS_GET_IID(nsIMsgDBHdr), getter_AddRefs(undeletedHdr));
|
||||
if (undeletedHdr)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> newHdr;
|
||||
|
||||
srcDB->CopyHdrFromExistingHdr (msgKey, undeletedHdr, PR_TRUE, getter_AddRefs(newHdr));
|
||||
}
|
||||
srcDB->Close(PR_TRUE);
|
||||
srcFolder->SummaryChanged();
|
||||
}
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kMsgMarkedDeleted:
|
||||
srcDB->MarkImapDeleted(hdrKey, PR_FALSE, nsnull);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
srcDB->Close(PR_TRUE);
|
||||
srcFolder->SummaryChanged();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapOfflineTxn::RedoTransaction(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder)
|
||||
return rv;
|
||||
nsCOMPtr <nsIMsgOfflineImapOperation> op;
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
nsCOMPtr <nsIMsgDatabase> srcDB;
|
||||
nsCOMPtr <nsIMsgDatabase> destDB;
|
||||
rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsMsgKey hdrKey = nsMsgKey_None;
|
||||
|
||||
if (m_header)
|
||||
m_header->GetMessageKey(&hdrKey);
|
||||
|
||||
switch (m_opType)
|
||||
{
|
||||
case nsIMsgOfflineImapOperation::kMsgMoved:
|
||||
case nsIMsgOfflineImapOperation::kMsgCopy:
|
||||
rv = srcDB->GetOfflineOpForKey(hdrKey, PR_FALSE, getter_AddRefs(op));
|
||||
if (NS_SUCCEEDED(rv) && op)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||
if (dstFolder)
|
||||
{
|
||||
nsXPIDLCString folderURI;
|
||||
dstFolder->GetURI(getter_Copies(folderURI));
|
||||
|
||||
|
||||
if (m_opType == nsIMsgOfflineImapOperation::kMsgMoved)
|
||||
{
|
||||
op->SetDestinationFolderURI(folderURI); // offline move
|
||||
}
|
||||
if (m_opType == nsIMsgOfflineImapOperation::kMsgCopy)
|
||||
{
|
||||
op->SetOperation(nsIMsgOfflineImapOperation::kMsgMoved);
|
||||
op->AddMessageCopyOperation(folderURI); // offline copy
|
||||
}
|
||||
dstFolder->SummaryChanged();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kAddedHeader:
|
||||
{
|
||||
nsCOMPtr <nsIMsgDBHdr> restoreHdr;
|
||||
nsMsgKey msgKey;
|
||||
m_header->GetMessageKey(&msgKey);
|
||||
nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||
rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(destDB));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (m_header)
|
||||
destDB->CopyHdrFromExistingHdr (msgKey, m_header, PR_TRUE, getter_AddRefs(restoreHdr));
|
||||
destDB->Close(PR_TRUE);
|
||||
dstFolder->SummaryChanged();
|
||||
rv = destDB->GetOfflineOpForKey(hdrKey, PR_TRUE, getter_AddRefs(op));
|
||||
if (NS_SUCCEEDED(rv) && op)
|
||||
{
|
||||
nsXPIDLCString folderURI;
|
||||
srcFolder->GetURI(getter_Copies(folderURI));
|
||||
op->SetSourceFolderURI(folderURI);
|
||||
}
|
||||
dstFolder->SummaryChanged();
|
||||
destDB->Close(PR_TRUE);
|
||||
}
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kDeletedMsg:
|
||||
srcDB->DeleteMessage(hdrKey, nsnull, PR_TRUE);
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kMsgMarkedDeleted:
|
||||
srcDB->MarkImapDeleted(hdrKey, PR_TRUE, nsnull);
|
||||
break;
|
||||
case nsIMsgOfflineImapOperation::kFlagsChanged:
|
||||
rv = srcDB->GetOfflineOpForKey(hdrKey, PR_TRUE, getter_AddRefs(op));
|
||||
if (NS_SUCCEEDED(rv) && op)
|
||||
{
|
||||
imapMessageFlagsType newMsgFlags;
|
||||
op->GetNewFlags(&newMsgFlags);
|
||||
if (m_addFlags)
|
||||
op->SetFlagOperation(newMsgFlags | m_flags);
|
||||
else
|
||||
op->SetFlagOperation(newMsgFlags & ~m_flags);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
srcDB->Close(PR_TRUE);
|
||||
srcDB = nsnull;
|
||||
srcFolder->SummaryChanged();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998, 1999 Netscape Communications Corporation. All
|
||||
* Copyright (C) 1998-2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -30,6 +30,7 @@
|
|||
#include "nsIEventQueue.h"
|
||||
#include "nsMsgTxn.h"
|
||||
#include "nsMsgKeyArray.h"
|
||||
#include "nsIMsgOfflineImapOperation.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
|
@ -41,52 +42,77 @@
|
|||
class nsImapMoveCopyMsgTxn : public nsMsgTxn
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMAPMOVECOPYMSGTXN_IID)
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMAPMOVECOPYMSGTXN_IID)
|
||||
|
||||
nsImapMoveCopyMsgTxn();
|
||||
nsImapMoveCopyMsgTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
const char* srcMsgIdString, nsIMsgFolder* dstFolder,
|
||||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
virtual ~nsImapMoveCopyMsgTxn();
|
||||
nsImapMoveCopyMsgTxn();
|
||||
nsImapMoveCopyMsgTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
const char* srcMsgIdString, nsIMsgFolder* dstFolder,
|
||||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
virtual ~nsImapMoveCopyMsgTxn();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_IMETHOD UndoTransaction(void);
|
||||
NS_IMETHOD RedoTransaction(void);
|
||||
NS_IMETHOD UndoTransaction(void);
|
||||
NS_IMETHOD RedoTransaction(void);
|
||||
|
||||
// helper
|
||||
nsresult SetCopyResponseUid(nsMsgKeyArray* keyArray,
|
||||
const char *msgIdString);
|
||||
nsresult GetSrcKeyArray(nsMsgKeyArray& srcKeyArray);
|
||||
nsresult GetDstKeyArray(nsMsgKeyArray& dstKeyArray);
|
||||
nsresult AddDstKey(nsMsgKey aKey);
|
||||
nsresult UndoMailboxDelete();
|
||||
nsresult RedoMailboxDelete();
|
||||
nsresult Init(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
const char* srcMsgIdString, nsIMsgFolder* dstFolder,
|
||||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
PRBool DeleteIsMoveToTrash(nsIMsgFolder* folder);
|
||||
// helper
|
||||
nsresult SetCopyResponseUid(nsMsgKeyArray* keyArray,
|
||||
const char *msgIdString);
|
||||
nsresult GetSrcKeyArray(nsMsgKeyArray& srcKeyArray);
|
||||
nsresult GetDstKeyArray(nsMsgKeyArray& dstKeyArray);
|
||||
nsresult AddDstKey(nsMsgKey aKey);
|
||||
nsresult UndoMailboxDelete();
|
||||
nsresult RedoMailboxDelete();
|
||||
nsresult Init(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
const char* srcMsgIdString, nsIMsgFolder* dstFolder,
|
||||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
PRBool DeleteIsMoveToTrash(nsIMsgFolder* folder);
|
||||
|
||||
private:
|
||||
protected:
|
||||
|
||||
nsWeakPtr m_srcFolder;
|
||||
nsCOMPtr<nsISupportsArray> m_srcHdrs;
|
||||
nsMsgKeyArray m_dupKeyArray;
|
||||
nsMsgKeyArray m_srcKeyArray;
|
||||
nsCString m_srcMsgIdString;
|
||||
nsWeakPtr m_dstFolder;
|
||||
nsMsgKeyArray m_dstKeyArray;
|
||||
nsCString m_dstMsgIdString;
|
||||
nsCOMPtr<nsIEventQueue> m_eventQueue;
|
||||
nsCOMPtr<nsIUrlListener> m_urlListener;
|
||||
PRBool m_idsAreUids;
|
||||
PRBool m_isMove;
|
||||
PRBool m_srcIsPop3;
|
||||
nsUInt32Array m_srcSizeArray;
|
||||
nsWeakPtr m_srcFolder;
|
||||
nsCOMPtr<nsISupportsArray> m_srcHdrs;
|
||||
nsMsgKeyArray m_dupKeyArray;
|
||||
nsMsgKeyArray m_srcKeyArray;
|
||||
nsCString m_srcMsgIdString;
|
||||
nsWeakPtr m_dstFolder;
|
||||
nsMsgKeyArray m_dstKeyArray;
|
||||
nsCString m_dstMsgIdString;
|
||||
nsCOMPtr<nsIEventQueue> m_eventQueue;
|
||||
nsCOMPtr<nsIUrlListener> m_urlListener;
|
||||
PRBool m_idsAreUids;
|
||||
PRBool m_isMove;
|
||||
PRBool m_srcIsPop3;
|
||||
nsUInt32Array m_srcSizeArray;
|
||||
};
|
||||
|
||||
class nsImapOfflineTxn : public nsImapMoveCopyMsgTxn
|
||||
{
|
||||
public:
|
||||
nsImapOfflineTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
nsIMsgFolder* dstFolder,
|
||||
PRBool isMove,
|
||||
nsOfflineImapOperationType opType,
|
||||
nsIMsgDBHdr *srcHdr,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
virtual ~nsImapOfflineTxn();
|
||||
|
||||
NS_IMETHOD UndoTransaction(void);
|
||||
NS_IMETHOD RedoTransaction(void);
|
||||
void SetAddFlags(PRBool addFlags) {m_addFlags = addFlags;}
|
||||
void SetFlags(PRUint32 flags) {m_flags = flags;}
|
||||
protected:
|
||||
nsOfflineImapOperationType m_opType;
|
||||
nsCOMPtr <nsIMsgDBHdr> m_header;
|
||||
// these two are used to undo flag changes, which we don't currently do.
|
||||
PRBool m_addFlags;
|
||||
PRUint32 m_flags;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче