fix undo of local mail delete, r/sr/a=sspitzer 188245

This commit is contained in:
bienvenu%netscape.com 2003-05-10 20:14:20 +00:00
Родитель 9c9c92c812
Коммит bcd1cb5c89
4 изменённых файлов: 154 добавлений и 9 удалений

Просмотреть файл

@ -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