зеркало из 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
|
||||
nsMsgDatabase::UndoDelete(nsIMsgDBHdr *msgHdr)
|
||||
nsMsgDatabase::UndoDelete(nsIMsgDBHdr *aMsgHdr)
|
||||
{
|
||||
if (msgHdr)
|
||||
if (aMsgHdr)
|
||||
{
|
||||
SetHdrFlag(msgHdr, PR_FALSE, MSG_FLAG_EXPUNGED);
|
||||
// ** do we need to update folder info regarding the message size
|
||||
nsMsgHdr* msgHdr = NS_STATIC_CAST(nsMsgHdr*, aMsgHdr); // closed system, so this is ok
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -2612,8 +2612,9 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
|||
if (newHdr)
|
||||
newHdr->AndFlags(~MSG_FLAG_OFFLINE, &newHdrFlags);
|
||||
}
|
||||
else
|
||||
mCopyState->m_undoMsgTxn = nsnull; //null out the transaction because we can't undo w/o the msg db
|
||||
// we can do undo with the dest folder db, see bug #198909
|
||||
//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)
|
||||
|
@ -2625,8 +2626,11 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
|||
if (!isImap || !mCopyState->m_copyingMultipleMessages)
|
||||
{
|
||||
nsMsgKey aKey;
|
||||
PRUint32 statusOffset;
|
||||
mCopyState->m_message->GetMessageKey(&aKey);
|
||||
mCopyState->m_message->GetStatusOffset(&statusOffset);
|
||||
localUndoTxn->AddSrcKey(aKey);
|
||||
localUndoTxn->AddSrcStatusOffset(statusOffset);
|
||||
localUndoTxn->AddDstKey(mCopyState->m_curDstKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsIUrlListener.h"
|
||||
#include "nsIMsgLocalMailFolder.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIMsgMailSession.h"
|
||||
|
||||
static NS_DEFINE_CID(kMailboxServiceCID, NS_IMAILBOXSERVICE_IID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
@ -100,6 +101,8 @@ nsLocalMoveCopyMsgTxn::Init(nsIMsgFolder* srcFolder, nsIMsgFolder* dstFolder,
|
|||
rv = SetDstFolder(dstFolder);
|
||||
m_isMove = isMove;
|
||||
|
||||
mUndoFolderListener = nsnull;
|
||||
|
||||
nsXPIDLCString uri;
|
||||
if (!srcFolder) return rv;
|
||||
rv = srcFolder->GetURI(getter_Copies(uri));
|
||||
|
@ -142,6 +145,14 @@ nsLocalMoveCopyMsgTxn::AddSrcKey(nsMsgKey aKey)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLocalMoveCopyMsgTxn::AddSrcStatusOffset(PRUint32 aStatusOffset)
|
||||
{
|
||||
m_srcStatusOffsetArray.Add(aStatusOffset);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsLocalMoveCopyMsgTxn::AddDstKey(nsMsgKey aKey)
|
||||
{
|
||||
|
@ -221,11 +232,60 @@ nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder,
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -236,6 +296,7 @@ nsLocalMoveCopyMsgTxn::UndoTransaction()
|
|||
|
||||
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;
|
||||
|
||||
|
@ -277,8 +338,9 @@ nsLocalMoveCopyMsgTxn::UndoTransaction()
|
|||
"fatal ... cannot create new msg header\n");
|
||||
if (NS_SUCCEEDED(rv) && newHdr)
|
||||
{
|
||||
newHdr->SetStatusOffset(m_srcStatusOffsetArray.GetAt(i));
|
||||
srcDB->UndoDelete(newHdr);
|
||||
msgSupports =do_QueryInterface(newHdr);
|
||||
msgSupports = do_QueryInterface(newHdr);
|
||||
srcMessages->AppendElement(msgSupports);
|
||||
}
|
||||
}
|
||||
|
@ -379,3 +441,60 @@ nsLocalMoveCopyMsgTxn::RedoTransaction()
|
|||
|
||||
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, \
|
||||
{ 0xaf, 0xad, 0x00, 0x10, 0x83, 0x00, 0x2d, 0xa8 } }
|
||||
|
||||
class nsLocalUndoFolderListener;
|
||||
|
||||
class nsLocalMoveCopyMsgTxn : public nsMsgTxn
|
||||
{
|
||||
public:
|
||||
|
@ -71,6 +73,7 @@ public:
|
|||
|
||||
// helper
|
||||
nsresult AddSrcKey(nsMsgKey aKey);
|
||||
nsresult AddSrcStatusOffset(PRUint32 statusOffset);
|
||||
nsresult AddDstKey(nsMsgKey aKey);
|
||||
nsresult AddDstMsgSize(PRUint32 msgSize);
|
||||
nsresult SetSrcFolder(nsIMsgFolder* srcFolder);
|
||||
|
@ -82,15 +85,32 @@ public:
|
|||
nsresult UndoImapDeleteFlag(nsIMsgFolder* aFolder,
|
||||
nsMsgKeyArray& aKeyArray,
|
||||
PRBool deleteFlag);
|
||||
nsresult UndoTransactionInternal();
|
||||
|
||||
private:
|
||||
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;
|
||||
nsMsgKeyArray m_dstKeyArray;
|
||||
PRBool m_isMove;
|
||||
PRBool m_srcIsImap4;
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче