nsresult nsLocalMoveCopyMsgTxn::UndoTransactionInternal() { nsresult rv = NS_ERROR_FAILURE; if (mUndoFolderListener) { nsCOMPtr<nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = mailSession->RemoveFolderListener(mUndoFolderListener); NS_ENSURE_SUCCESS(rv,rv); NS_RELEASE(mUndoFolderListener); mUndoFolderListener = nullptr; } nsCOMPtr<nsIMsgDatabase> srcDB; nsCOMPtr<nsIMsgDatabase> dstDB; nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = srcFolder->GetMsgDatabase(getter_AddRefs(srcDB)); if(NS_FAILED(rv)) return rv; rv = dstFolder->GetMsgDatabase(getter_AddRefs(dstDB)); if (NS_FAILED(rv)) return rv; uint32_t count = m_srcKeyArray.Length(); uint32_t i; nsCOMPtr<nsIMsgDBHdr> oldHdr; nsCOMPtr<nsIMsgDBHdr> newHdr; // protect against a bogus undo txn without any source keys // see bug #179856 for details NS_ASSERTION(count, "no source keys"); if (!count) return NS_ERROR_UNEXPECTED; if (m_isMove) { if (m_srcIsImap4) { bool deleteFlag = true; //message has been deleted -we are trying to undo it CheckForToggleDelete(srcFolder, m_srcKeyArray[0], &deleteFlag); //there could have been a toggle. rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, deleteFlag); } else if (m_canUndelete) { nsCOMPtr<nsIMutableArray> srcMessages = do_CreateInstance(NS_ARRAY_CONTRACTID); nsCOMPtr<nsIMutableArray> dstMessages = do_CreateInstance(NS_ARRAY_CONTRACTID); srcDB->StartBatch(); for (i = 0; i < count; i++) { rv = dstDB->GetMsgHdrForKey(m_dstKeyArray[i], getter_AddRefs(oldHdr)); NS_ASSERTION(oldHdr, "fatal ... cannot get old msg header\n"); if (NS_SUCCEEDED(rv) && oldHdr) { rv = srcDB->CopyHdrFromExistingHdr(m_srcKeyArray[i], oldHdr, true, getter_AddRefs(newHdr)); NS_ASSERTION(newHdr, "fatal ... cannot create new msg header\n"); if (NS_SUCCEEDED(rv) && newHdr) { newHdr->SetStatusOffset(m_srcStatusOffsetArray[i]); srcDB->UndoDelete(newHdr); srcMessages->AppendElement(newHdr, false); // (we want to keep these two lists in sync) dstMessages->AppendElement(oldHdr, false); } } } srcDB->EndBatch(); nsCOMPtr<nsIMsgFolderNotificationService> notifier(do_GetService(NS_MSGNOTIFICATIONSERVICE_CONTRACTID)); if (notifier) { // Remember that we're actually moving things back from the destination // to the source! notifier->NotifyMsgsMoveCopyCompleted(true, dstMessages, srcFolder, srcMessages); } nsCOMPtr <nsIMsgLocalMailFolder> localFolder = do_QueryInterface(srcFolder); if (localFolder) localFolder->MarkMsgsOnPop3Server(srcMessages, POP3_NONE /*deleteMsgs*/); } else // undoing a move means moving the messages back. { nsCOMPtr<nsIMutableArray> dstMessages = do_CreateInstance(NS_ARRAY_CONTRACTID); nsCOMPtr<nsIMsgDBHdr> dstHdr; m_numHdrsCopied = 0; m_srcKeyArray.Clear(); for (i = 0; i < count; i++) { dstDB->GetMsgHdrForKey(m_dstKeyArray[i], getter_AddRefs(dstHdr)); NS_ASSERTION(dstHdr, "fatal ... cannot get old msg header\n"); if (dstHdr) { nsCString messageId; dstHdr->GetMessageId(getter_Copies(messageId)); dstMessages->AppendElement(dstHdr, false); m_copiedMsgIds.AppendElement(messageId); } } srcFolder->AddFolderListener(this); m_undoing = true; return srcFolder->CopyMessages(dstFolder, dstMessages, true, nullptr, nullptr, false, false); } srcDB->SetSummaryValid(true); } dstDB->DeleteMessages(m_dstKeyArray.Length(), m_dstKeyArray.Elements(), nullptr); dstDB->SetSummaryValid(true); return rv; }
NS_IMETHODIMP nsLocalMoveCopyMsgTxn::RedoTransaction() { nsresult rv; nsCOMPtr<nsIMsgDatabase> srcDB; nsCOMPtr<nsIMsgDatabase> dstDB; nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = srcFolder->GetMsgDatabase(getter_AddRefs(srcDB)); if(NS_FAILED(rv)) return rv; rv = dstFolder->GetMsgDatabase(getter_AddRefs(dstDB)); if (NS_FAILED(rv)) return rv; uint32_t count = m_srcKeyArray.Length(); uint32_t i; nsCOMPtr<nsIMsgDBHdr> oldHdr; nsCOMPtr<nsIMsgDBHdr> newHdr; nsCOMPtr<nsIMutableArray> srcMessages = do_CreateInstance(NS_ARRAY_CONTRACTID); nsCOMPtr <nsISupports> msgSupports; for (i=0; i<count; i++) { rv = srcDB->GetMsgHdrForKey(m_srcKeyArray[i], getter_AddRefs(oldHdr)); NS_ASSERTION(oldHdr, "fatal ... cannot get old msg header\n"); if (NS_SUCCEEDED(rv) && oldHdr) { msgSupports =do_QueryInterface(oldHdr); srcMessages->AppendElement(msgSupports, false); if (m_canUndelete) { rv = dstDB->CopyHdrFromExistingHdr(m_dstKeyArray[i], oldHdr, true, getter_AddRefs(newHdr)); NS_ASSERTION(newHdr, "fatal ... cannot get new msg header\n"); if (NS_SUCCEEDED(rv) && newHdr) { if (i < m_dstSizeArray.Length()) rv = newHdr->SetMessageSize(m_dstSizeArray[i]); dstDB->UndoDelete(newHdr); } } } } dstDB->SetSummaryValid(true); if (m_isMove) { if (m_srcIsImap4) { // protect against a bogus undo txn without any source keys // see bug #179856 for details NS_ASSERTION(!m_srcKeyArray.IsEmpty(), "no source keys"); if (m_srcKeyArray.IsEmpty()) return NS_ERROR_UNEXPECTED; bool deleteFlag = false; //message is un-deleted- we are trying to redo CheckForToggleDelete(srcFolder, m_srcKeyArray[0], &deleteFlag); // there could have been a toggle rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, deleteFlag); } else if (m_canUndelete) { nsCOMPtr <nsIMsgLocalMailFolder> localFolder = do_QueryInterface(srcFolder); if (localFolder) localFolder->MarkMsgsOnPop3Server(srcMessages, POP3_DELETE /*deleteMsgs*/); rv = srcDB->DeleteMessages(m_srcKeyArray.Length(), m_srcKeyArray.Elements(), nullptr); srcDB->SetSummaryValid(true); } else { nsCOMPtr<nsIMsgDBHdr> srcHdr; m_numHdrsCopied = 0; m_dstKeyArray.Clear(); for (i = 0; i < count; i++) { srcDB->GetMsgHdrForKey(m_srcKeyArray[i], getter_AddRefs(srcHdr)); NS_ASSERTION(srcHdr, "fatal ... cannot get old msg header\n"); if (srcHdr) { nsCString messageId; srcHdr->GetMessageId(getter_Copies(messageId)); m_copiedMsgIds.AppendElement(messageId); } } dstFolder->AddFolderListener(this); m_undoing = false; return dstFolder->CopyMessages(srcFolder, srcMessages, true, nullptr, nullptr, false, false); } } return rv; }
nsresult nsLocalMoveCopyMsgTxn::UndoTransactionInternal() { nsresult rv = NS_ERROR_FAILURE; if (mUndoFolderListener) { nsCOMPtr<nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = mailSession->RemoveFolderListener(mUndoFolderListener); NS_ENSURE_SUCCESS(rv,rv); NS_RELEASE(mUndoFolderListener); mUndoFolderListener = nsnull; } nsCOMPtr<nsIMsgDatabase> srcDB; nsCOMPtr<nsIMsgDatabase> dstDB; nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv); NS_ENSURE_SUCCESS(rv,rv); rv = srcFolder->GetMsgDatabase(nsnull, getter_AddRefs(srcDB)); if(NS_FAILED(rv)) return rv; rv = dstFolder->GetMsgDatabase(nsnull, getter_AddRefs(dstDB)); if (NS_FAILED(rv)) return rv; PRUint32 count = m_srcKeyArray.Length(); PRUint32 i; nsCOMPtr<nsIMsgDBHdr> oldHdr; nsCOMPtr<nsIMsgDBHdr> newHdr; // protect against a bogus undo txn without any source keys // see bug #179856 for details NS_ASSERTION(count, "no source keys"); if (!count) return NS_ERROR_UNEXPECTED; if (m_isMove) { if (m_srcIsImap4) { PRBool deleteFlag = PR_TRUE; //message has been deleted -we are trying to undo it CheckForToggleDelete(srcFolder, m_srcKeyArray[0], &deleteFlag); //there could have been a toggle. rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, deleteFlag); } else { nsCOMPtr<nsIMutableArray> srcMessages = do_CreateInstance(NS_ARRAY_CONTRACTID); for (i=0; i<count; i++) { rv = dstDB->GetMsgHdrForKey(m_dstKeyArray[i], getter_AddRefs(oldHdr)); NS_ASSERTION(oldHdr, "fatal ... cannot get old msg header\n"); if (NS_SUCCEEDED(rv) && oldHdr) { rv = srcDB->CopyHdrFromExistingHdr(m_srcKeyArray[i], oldHdr, PR_TRUE, getter_AddRefs(newHdr)); NS_ASSERTION(newHdr, "fatal ... cannot create new msg header\n"); if (NS_SUCCEEDED(rv) && newHdr) { newHdr->SetStatusOffset(m_srcStatusOffsetArray[i]); srcDB->UndoDelete(newHdr); srcMessages->AppendElement(newHdr, PR_FALSE); } } } nsCOMPtr <nsIMsgLocalMailFolder> localFolder = do_QueryInterface(srcFolder); if (localFolder) localFolder->MarkMsgsOnPop3Server(srcMessages, POP3_NONE /*deleteMsgs*/); } srcDB->SetSummaryValid(PR_TRUE); } dstDB->DeleteMessages(&m_dstKeyArray, nsnull); dstDB->SetSummaryValid(PR_TRUE); return rv; }