зеркало из https://github.com/mozilla/pjs.git
fix undo of local mail delete, r/sr/a=sspitzer 188245
This commit is contained in:
Родитель
9c9c92c812
Коммит
bcd1cb5c89
|
@ -1593,12 +1593,14 @@ NS_IMETHODIMP nsMsgDatabase::DeleteHeader(nsIMsgDBHdr *msg, nsIDBChangeListener
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsMsgDatabase::UndoDelete(nsIMsgDBHdr *msgHdr)
|
nsMsgDatabase::UndoDelete(nsIMsgDBHdr *aMsgHdr)
|
||||||
{
|
{
|
||||||
if (msgHdr)
|
if (aMsgHdr)
|
||||||
{
|
{
|
||||||
SetHdrFlag(msgHdr, PR_FALSE, MSG_FLAG_EXPUNGED);
|
nsMsgHdr* msgHdr = NS_STATIC_CAST(nsMsgHdr*, aMsgHdr); // closed system, so this is ok
|
||||||
// ** do we need to update folder info regarding the message size
|
// force deleted flag, so SetHdrFlag won't bail out because deleted flag isn't set
|
||||||
|
msgHdr->m_flags |= MSG_FLAG_EXPUNGED;
|
||||||
|
SetHdrFlag(msgHdr, PR_FALSE, MSG_FLAG_EXPUNGED); // clear deleted flag in db
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2612,8 +2612,9 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
||||||
if (newHdr)
|
if (newHdr)
|
||||||
newHdr->AndFlags(~MSG_FLAG_OFFLINE, &newHdrFlags);
|
newHdr->AndFlags(~MSG_FLAG_OFFLINE, &newHdrFlags);
|
||||||
}
|
}
|
||||||
else
|
// we can do undo with the dest folder db, see bug #198909
|
||||||
mCopyState->m_undoMsgTxn = nsnull; //null out the transaction because we can't undo w/o the msg db
|
//else
|
||||||
|
// mCopyState->m_undoMsgTxn = nsnull; //null out the transaction because we can't undo w/o the msg db
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we plan on allowing undo, (if we have a mCopyState->m_parseMsgState or not)
|
// if we plan on allowing undo, (if we have a mCopyState->m_parseMsgState or not)
|
||||||
|
@ -2625,8 +2626,11 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
||||||
if (!isImap || !mCopyState->m_copyingMultipleMessages)
|
if (!isImap || !mCopyState->m_copyingMultipleMessages)
|
||||||
{
|
{
|
||||||
nsMsgKey aKey;
|
nsMsgKey aKey;
|
||||||
|
PRUint32 statusOffset;
|
||||||
mCopyState->m_message->GetMessageKey(&aKey);
|
mCopyState->m_message->GetMessageKey(&aKey);
|
||||||
|
mCopyState->m_message->GetStatusOffset(&statusOffset);
|
||||||
localUndoTxn->AddSrcKey(aKey);
|
localUndoTxn->AddSrcKey(aKey);
|
||||||
|
localUndoTxn->AddSrcStatusOffset(statusOffset);
|
||||||
localUndoTxn->AddDstKey(mCopyState->m_curDstKey);
|
localUndoTxn->AddDstKey(mCopyState->m_curDstKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "nsIUrlListener.h"
|
#include "nsIUrlListener.h"
|
||||||
#include "nsIMsgLocalMailFolder.h"
|
#include "nsIMsgLocalMailFolder.h"
|
||||||
#include "nsIEventQueueService.h"
|
#include "nsIEventQueueService.h"
|
||||||
|
#include "nsIMsgMailSession.h"
|
||||||
|
|
||||||
static NS_DEFINE_CID(kMailboxServiceCID, NS_IMAILBOXSERVICE_IID);
|
static NS_DEFINE_CID(kMailboxServiceCID, NS_IMAILBOXSERVICE_IID);
|
||||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||||
|
@ -100,6 +101,8 @@ nsLocalMoveCopyMsgTxn::Init(nsIMsgFolder* srcFolder, nsIMsgFolder* dstFolder,
|
||||||
rv = SetDstFolder(dstFolder);
|
rv = SetDstFolder(dstFolder);
|
||||||
m_isMove = isMove;
|
m_isMove = isMove;
|
||||||
|
|
||||||
|
mUndoFolderListener = nsnull;
|
||||||
|
|
||||||
nsXPIDLCString uri;
|
nsXPIDLCString uri;
|
||||||
if (!srcFolder) return rv;
|
if (!srcFolder) return rv;
|
||||||
rv = srcFolder->GetURI(getter_Copies(uri));
|
rv = srcFolder->GetURI(getter_Copies(uri));
|
||||||
|
@ -142,6 +145,14 @@ nsLocalMoveCopyMsgTxn::AddSrcKey(nsMsgKey aKey)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsLocalMoveCopyMsgTxn::AddSrcStatusOffset(PRUint32 aStatusOffset)
|
||||||
|
{
|
||||||
|
m_srcStatusOffsetArray.Add(aStatusOffset);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsLocalMoveCopyMsgTxn::AddDstKey(nsMsgKey aKey)
|
nsLocalMoveCopyMsgTxn::AddDstKey(nsMsgKey aKey)
|
||||||
{
|
{
|
||||||
|
@ -221,11 +232,60 @@ nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsLocalMoveCopyMsgTxn::UndoTransaction()
|
nsLocalMoveCopyMsgTxn::UndoTransaction()
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIMsgDatabase> dstDB;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||||
|
if (NS_FAILED(rv) || !dstFolder) return rv;
|
||||||
|
nsCOMPtr<nsIMsgLocalMailFolder> dstlocalMailFolder = do_QueryReferent(m_dstFolder, &rv);
|
||||||
|
if (NS_FAILED(rv) || !dstlocalMailFolder) return rv;
|
||||||
|
dstlocalMailFolder->GetDatabaseWOReparse(getter_AddRefs(dstDB));
|
||||||
|
|
||||||
|
if (!dstDB)
|
||||||
|
{
|
||||||
|
mUndoFolderListener = new nsLocalUndoFolderListener(this, dstFolder);
|
||||||
|
if (!mUndoFolderListener)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
NS_ADDREF(mUndoFolderListener);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIMsgMailSession> mailSession =
|
||||||
|
do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
rv = mailSession->AddFolderListener(mUndoFolderListener, nsIFolderListener::event);
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
|
||||||
|
rv = dstFolder->GetMsgDatabase(nsnull, getter_AddRefs(dstDB));
|
||||||
|
NS_ENSURE_SUCCESS(rv,rv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = UndoTransactionInternal();
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsLocalMoveCopyMsgTxn::UndoTransactionInternal()
|
||||||
{
|
{
|
||||||
nsresult rv = NS_ERROR_FAILURE;
|
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> srcDB;
|
||||||
nsCOMPtr<nsIMsgDatabase> dstDB;
|
nsCOMPtr<nsIMsgDatabase> dstDB;
|
||||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||||
|
@ -236,6 +296,7 @@ nsLocalMoveCopyMsgTxn::UndoTransaction()
|
||||||
|
|
||||||
rv = srcFolder->GetMsgDatabase(nsnull, getter_AddRefs(srcDB));
|
rv = srcFolder->GetMsgDatabase(nsnull, getter_AddRefs(srcDB));
|
||||||
if(NS_FAILED(rv)) return rv;
|
if(NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
rv = dstFolder->GetMsgDatabase(nsnull, getter_AddRefs(dstDB));
|
rv = dstFolder->GetMsgDatabase(nsnull, getter_AddRefs(dstDB));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
@ -277,8 +338,9 @@ nsLocalMoveCopyMsgTxn::UndoTransaction()
|
||||||
"fatal ... cannot create new msg header\n");
|
"fatal ... cannot create new msg header\n");
|
||||||
if (NS_SUCCEEDED(rv) && newHdr)
|
if (NS_SUCCEEDED(rv) && newHdr)
|
||||||
{
|
{
|
||||||
|
newHdr->SetStatusOffset(m_srcStatusOffsetArray.GetAt(i));
|
||||||
srcDB->UndoDelete(newHdr);
|
srcDB->UndoDelete(newHdr);
|
||||||
msgSupports =do_QueryInterface(newHdr);
|
msgSupports = do_QueryInterface(newHdr);
|
||||||
srcMessages->AppendElement(msgSupports);
|
srcMessages->AppendElement(msgSupports);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -379,3 +441,60 @@ nsLocalMoveCopyMsgTxn::RedoTransaction()
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsLocalUndoFolderListener, nsIFolderListener)
|
||||||
|
|
||||||
|
nsLocalUndoFolderListener::nsLocalUndoFolderListener(nsLocalMoveCopyMsgTxn *aTxn, nsIMsgFolder *aFolder)
|
||||||
|
{
|
||||||
|
mTxn = aTxn;
|
||||||
|
mFolder = aFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsLocalUndoFolderListener::~nsLocalUndoFolderListener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemAdded(nsISupports *parentItem, nsISupports *item, const char *viewString)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemPropertyChanged(nsISupports *item, nsIAtom *property, const char *oldValue, const char *newValue)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemIntPropertyChanged(nsISupports *item, nsIAtom *property, PRInt32 oldValue, PRInt32 newValue)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemBoolPropertyChanged(nsISupports *item, nsIAtom *property, PRBool oldValue, PRBool newValue)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemUnicharPropertyChanged(nsISupports *item, nsIAtom *property, const PRUnichar *oldValue, const PRUnichar *newValue)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemPropertyFlagChanged(nsISupports *item, nsIAtom *property, PRUint32 oldFlag, PRUint32 newFlag)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsLocalUndoFolderListener::OnItemEvent(nsIFolder *item, nsIAtom *event)
|
||||||
|
{
|
||||||
|
nsCOMPtr <nsIAtom> folderLoadedAtom = NS_NewAtom("FolderLoaded");
|
||||||
|
nsCOMPtr <nsIMsgFolder> itemFolder = do_QueryInterface(item);
|
||||||
|
if (mTxn && mFolder && folderLoadedAtom == event && item == mFolder)
|
||||||
|
return mTxn->UndoTransactionInternal();
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
0x874363b4, 0x242e, 0x11d3, \
|
0x874363b4, 0x242e, 0x11d3, \
|
||||||
{ 0xaf, 0xad, 0x00, 0x10, 0x83, 0x00, 0x2d, 0xa8 } }
|
{ 0xaf, 0xad, 0x00, 0x10, 0x83, 0x00, 0x2d, 0xa8 } }
|
||||||
|
|
||||||
|
class nsLocalUndoFolderListener;
|
||||||
|
|
||||||
class nsLocalMoveCopyMsgTxn : public nsMsgTxn
|
class nsLocalMoveCopyMsgTxn : public nsMsgTxn
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -71,6 +73,7 @@ public:
|
||||||
|
|
||||||
// helper
|
// helper
|
||||||
nsresult AddSrcKey(nsMsgKey aKey);
|
nsresult AddSrcKey(nsMsgKey aKey);
|
||||||
|
nsresult AddSrcStatusOffset(PRUint32 statusOffset);
|
||||||
nsresult AddDstKey(nsMsgKey aKey);
|
nsresult AddDstKey(nsMsgKey aKey);
|
||||||
nsresult AddDstMsgSize(PRUint32 msgSize);
|
nsresult AddDstMsgSize(PRUint32 msgSize);
|
||||||
nsresult SetSrcFolder(nsIMsgFolder* srcFolder);
|
nsresult SetSrcFolder(nsIMsgFolder* srcFolder);
|
||||||
|
@ -82,15 +85,32 @@ public:
|
||||||
nsresult UndoImapDeleteFlag(nsIMsgFolder* aFolder,
|
nsresult UndoImapDeleteFlag(nsIMsgFolder* aFolder,
|
||||||
nsMsgKeyArray& aKeyArray,
|
nsMsgKeyArray& aKeyArray,
|
||||||
PRBool deleteFlag);
|
PRBool deleteFlag);
|
||||||
|
nsresult UndoTransactionInternal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsWeakPtr m_srcFolder;
|
nsWeakPtr m_srcFolder;
|
||||||
nsMsgKeyArray m_srcKeyArray;
|
nsMsgKeyArray m_srcKeyArray; // used when src is local or imap
|
||||||
|
nsUInt32Array m_srcStatusOffsetArray; // used when src is local
|
||||||
nsWeakPtr m_dstFolder;
|
nsWeakPtr m_dstFolder;
|
||||||
nsMsgKeyArray m_dstKeyArray;
|
nsMsgKeyArray m_dstKeyArray;
|
||||||
PRBool m_isMove;
|
PRBool m_isMove;
|
||||||
PRBool m_srcIsImap4;
|
PRBool m_srcIsImap4;
|
||||||
nsUInt32Array m_dstSizeArray;
|
nsUInt32Array m_dstSizeArray;
|
||||||
|
nsLocalUndoFolderListener *mUndoFolderListener;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsLocalUndoFolderListener : public nsIFolderListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIFOLDERLISTENER
|
||||||
|
|
||||||
|
nsLocalUndoFolderListener(nsLocalMoveCopyMsgTxn *aTxn, nsIMsgFolder *aFolder);
|
||||||
|
virtual ~nsLocalUndoFolderListener();
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsLocalMoveCopyMsgTxn *mTxn;
|
||||||
|
nsIMsgFolder *mFolder;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче