59694. sr=bievenu. Add the capability to toggle imap deletes using
delete button when the delete model is imap-delete model. Also update undo/redo to reflect such toggling.
This commit is contained in:
Родитель
2b7b07bdb8
Коммит
8bb5fdc086
|
@ -36,6 +36,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsMsgTxn.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsMsgTxn)
|
||||
|
@ -104,3 +105,17 @@ nsMsgTxn::SetTransactionType(PRUint32 txnType)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//none of the callers pass null aFolder
|
||||
nsresult
|
||||
nsMsgTxn::CheckForToggleDelete(nsIMsgFolder *aFolder, const nsMsgKey &aMsgKey, PRBool *aResult)
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> message;
|
||||
nsresult rv = aFolder->GetMessageHeader(aMsgKey, getter_AddRefs(message));
|
||||
PRUint32 flags;
|
||||
if (NS_SUCCEEDED(rv) && message)
|
||||
{
|
||||
message->GetFlags(&flags);
|
||||
*aResult = (flags & MSG_FLAG_IMAP_DELETED) != 0;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ class NS_MSG_BASE nsMsgTxn : public nsITransaction
|
|||
protected:
|
||||
nsCOMPtr<nsIMsgWindow> m_msgWindow;
|
||||
PRUint32 m_txnType;
|
||||
nsresult CheckForToggleDelete(nsIMsgFolder *aFolder, const nsMsgKey &aMsgKey, PRBool *aResult);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1896,7 +1896,7 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
|||
PRBool deleteImmediatelyNoTrash = PR_FALSE;
|
||||
nsCAutoString messageIds;
|
||||
nsMsgKeyArray srcKeyArray;
|
||||
|
||||
PRBool deleteMsgs = PR_TRUE; //used for toggling delete status - default is true
|
||||
nsMsgImapDeleteModel deleteModel = nsMsgImapDeleteModels::MoveToTrash;
|
||||
|
||||
nsCOMPtr<nsIImapIncomingServer> imapServer;
|
||||
|
@ -1926,6 +1926,7 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
|||
rv = rootFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH,
|
||||
1, &numFolders,
|
||||
getter_AddRefs(trashFolder));
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && trashFolder != 0, "couldn't find trash");
|
||||
|
||||
// if we can't find the trash, we'll just have to do an imap delete and pretend this is the trash
|
||||
|
@ -1953,14 +1954,37 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
|||
txnMgr->DoTransaction(undoMsgTxn);
|
||||
}
|
||||
|
||||
rv = StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE, srcKeyArray.GetArray(), srcKeyArray.GetSize());
|
||||
if (deleteModel == nsMsgImapDeleteModels::IMAPDelete && !deleteStorage)
|
||||
{
|
||||
PRUint32 cnt, flags;
|
||||
rv = messages->Count(&cnt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
deleteMsgs = PR_FALSE;
|
||||
for (PRUint32 i=0; i <cnt; i++)
|
||||
{
|
||||
nsCOMPtr <nsISupports> msgSupports = getter_AddRefs(messages->ElementAt(i));
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr = do_QueryInterface(msgSupports);
|
||||
if (msgHdr)
|
||||
{
|
||||
msgHdr->GetFlags(&flags);
|
||||
if (!(flags & MSG_FLAG_IMAP_DELETED))
|
||||
{
|
||||
deleteMsgs = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = StoreImapFlags(kImapMsgDeletedFlag, deleteMsgs, srcKeyArray.GetArray(), srcKeyArray.GetSize());
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (mDatabase)
|
||||
{
|
||||
if (deleteModel == nsMsgImapDeleteModels::IMAPDelete)
|
||||
{
|
||||
MarkMessagesImapDeleted(&srcKeyArray, PR_TRUE, mDatabase);
|
||||
|
||||
MarkMessagesImapDeleted(&srcKeyArray, deleteMsgs, mDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1968,15 +1992,12 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
|||
mDatabase->DeleteMessages(&srcKeyArray,nsnull);
|
||||
EnableNotifications(allMessageCountNotifications, PR_TRUE);
|
||||
NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// have to move the messages to the trash
|
||||
else
|
||||
else // have to move the messages to the trash
|
||||
{
|
||||
if(trashFolder)
|
||||
{
|
||||
|
|
|
@ -174,21 +174,41 @@ nsImapMoveCopyMsgTxn::UndoTransaction(void)
|
|||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder) return rv;
|
||||
if (NS_FAILED(rv) || !srcFolder)
|
||||
return rv;
|
||||
nsCOMPtr<nsIUrlListener> srcListener =
|
||||
do_QueryInterface(srcFolder, &rv);
|
||||
if (NS_FAILED(rv)) return 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))
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
PRBool deletedMsgs = PR_TRUE; //default is true unless imapDelete model
|
||||
nsMsgImapDeleteModel deleteModel;
|
||||
rv = GetImapDeleteModel(srcFolder, &deleteModel);
|
||||
PRBool deleteIsMoveToTrash = NS_FAILED(rv) || deleteModel == nsMsgImapDeleteModels::MoveToTrash;
|
||||
|
||||
if (NS_SUCCEEDED(rv) && deleteModel == nsMsgImapDeleteModels::IMAPDelete)
|
||||
CheckForToggleDelete(srcFolder, m_srcKeyArray.GetAt(0), &deletedMsgs);
|
||||
|
||||
if (deletedMsgs)
|
||||
rv = imapService->SubtractMessageFlags(
|
||||
m_eventQueue, srcFolder, srcListener, nsnull,
|
||||
m_srcMsgIdString.get(), kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
else
|
||||
rv = imapService->AddMessageFlags(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (deleteIsMoveToTrash)
|
||||
rv = imapService->GetHeaders(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
|
@ -234,21 +254,36 @@ nsImapMoveCopyMsgTxn::RedoTransaction(void)
|
|||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
|
||||
if (NS_FAILED(rv) || !srcFolder) return rv;
|
||||
if (NS_FAILED(rv) || !srcFolder)
|
||||
return rv;
|
||||
nsCOMPtr<nsIUrlListener> srcListener =
|
||||
do_QueryInterface(srcFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRBool deletedMsgs = PR_FALSE; //default will be false unless imapDeleteModel;
|
||||
nsMsgImapDeleteModel deleteModel;
|
||||
rv = GetImapDeleteModel(srcFolder, &deleteModel);
|
||||
if (NS_SUCCEEDED(rv) && deleteModel == nsMsgImapDeleteModels::IMAPDelete)
|
||||
rv = CheckForToggleDelete(srcFolder, m_srcKeyArray.GetAt(0), &deletedMsgs);
|
||||
|
||||
// ** make sire we are in the selected state; use lite select
|
||||
// folder so we won't hit preformace hard
|
||||
rv = imapService->LiteSelectFolder(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = imapService->AddMessageFlags(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (deletedMsgs)
|
||||
rv = imapService->SubtractMessageFlags(
|
||||
m_eventQueue, srcFolder, srcListener, nsnull,
|
||||
m_srcMsgIdString.get(), kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
else
|
||||
rv = imapService->AddMessageFlags(m_eventQueue, srcFolder,
|
||||
srcListener, nsnull,
|
||||
m_srcMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
}
|
||||
}
|
||||
if (m_dstKeyArray.GetSize() > 0)
|
||||
|
@ -259,19 +294,24 @@ nsImapMoveCopyMsgTxn::RedoTransaction(void)
|
|||
nsCOMPtr<nsIUrlListener> dstListener;
|
||||
|
||||
dstListener = do_QueryInterface(dstFolder, &rv);
|
||||
if (NS_FAILED(rv)) return 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;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = imapService->SubtractMessageFlags(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull,
|
||||
m_dstMsgIdString.get(),
|
||||
kImapMsgDeletedFlag,
|
||||
m_idsAreUids);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (DeleteIsMoveToTrash(dstFolder))
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsMsgImapDeleteModel deleteModel;
|
||||
rv = GetImapDeleteModel(dstFolder, &deleteModel);
|
||||
if (NS_FAILED(rv) || deleteModel == nsMsgImapDeleteModels::MoveToTrash)
|
||||
rv = imapService->GetHeaders(m_eventQueue, dstFolder,
|
||||
dstListener, nsnull,
|
||||
m_dstMsgIdString.get(),
|
||||
|
@ -343,7 +383,7 @@ nsImapMoveCopyMsgTxn::UndoMailboxDelete()
|
|||
PRUint32 i;
|
||||
nsCOMPtr<nsIMsgDBHdr> oldHdr;
|
||||
nsCOMPtr<nsIMsgDBHdr> newHdr;
|
||||
nsCOMPtr<nsISupports> aSupport;
|
||||
nsCOMPtr<nsISupports> aSupport;
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
aSupport = getter_AddRefs(m_srcHdrs->ElementAt(i));
|
||||
|
@ -398,28 +438,20 @@ nsImapMoveCopyMsgTxn::RedoMailboxDelete()
|
|||
return rv;
|
||||
}
|
||||
|
||||
PRBool nsImapMoveCopyMsgTxn::DeleteIsMoveToTrash(nsIMsgFolder *folder)
|
||||
nsresult nsImapMoveCopyMsgTxn::GetImapDeleteModel(nsIMsgFolder *aFolder, nsMsgImapDeleteModel *aDeleteModel)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool retVal = PR_FALSE;
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
nsXPIDLCString serverKey;
|
||||
if (!folder) return PR_FALSE;
|
||||
rv = folder->GetServer(getter_AddRefs(server));
|
||||
if (NS_FAILED(rv)) return PR_FALSE;
|
||||
rv = server->GetKey(getter_Copies(serverKey));
|
||||
if (NS_FAILED(rv) || !serverKey) return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIImapHostSessionList> hostSession =
|
||||
do_GetService(kCImapHostSessionList, &rv);
|
||||
if (NS_FAILED(rv) || !hostSession) return PR_FALSE;
|
||||
rv = hostSession->GetDeleteIsMoveToTrashForHost((const char*) serverKey,
|
||||
retVal);
|
||||
return retVal;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
if (!aFolder)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
rv = aFolder->GetServer(getter_AddRefs(server));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryInterface(server, &rv);
|
||||
if (NS_SUCCEEDED(rv) && imapServer)
|
||||
rv = imapServer->GetDeleteModel(aDeleteModel);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsImapOfflineTxn::nsImapOfflineTxn(nsIMsgFolder* srcFolder, nsMsgKeyArray* srcKeyArray,
|
||||
nsIMsgFolder* dstFolder, PRBool isMove, nsOfflineImapOperationType opType,
|
||||
nsIMsgDBHdr *srcHdr,
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsIMsgFolder.h"
|
||||
#include "nsImapCore.h"
|
||||
#include "nsIImapService.h"
|
||||
#include "nsIImapIncomingServer.h"
|
||||
#include "nsIUrlListener.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsMsgTxn.h"
|
||||
|
@ -85,7 +86,6 @@ public:
|
|||
PRBool idsAreUids, PRBool isMove,
|
||||
nsIEventQueue *eventQueue,
|
||||
nsIUrlListener *urlListener);
|
||||
PRBool DeleteIsMoveToTrash(nsIMsgFolder* folder);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -103,6 +103,8 @@ protected:
|
|||
PRBool m_isMove;
|
||||
PRBool m_srcIsPop3;
|
||||
nsUInt32Array m_srcSizeArray;
|
||||
|
||||
nsresult GetImapDeleteModel(nsIMsgFolder* aFolder, nsMsgImapDeleteModel *aDeleteModel);
|
||||
};
|
||||
|
||||
class nsImapOfflineTxn : public nsImapMoveCopyMsgTxn
|
||||
|
|
|
@ -160,7 +160,7 @@ nsLocalMoveCopyMsgTxn::AddDstMsgSize(PRUint32 msgSize)
|
|||
nsresult
|
||||
nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder,
|
||||
nsMsgKeyArray& keyArray,
|
||||
PRBool addFlag)
|
||||
PRBool deleteFlag)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (m_srcIsImap4)
|
||||
|
@ -195,7 +195,7 @@ nsLocalMoveCopyMsgTxn::UndoImapDeleteFlag(nsIMsgFolder* folder,
|
|||
// folder so use lite select to do the trick
|
||||
rv = imapService->LiteSelectFolder(eventQueue, folder,
|
||||
urlListener, nsnull);
|
||||
if (addFlag)
|
||||
if (!deleteFlag)
|
||||
rv =imapService->AddMessageFlags(eventQueue, folder,
|
||||
urlListener, nsnull,
|
||||
msgIds.get(),
|
||||
|
@ -249,7 +249,9 @@ nsLocalMoveCopyMsgTxn::UndoTransaction()
|
|||
{
|
||||
if (m_srcIsImap4)
|
||||
{
|
||||
rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, PR_FALSE);
|
||||
PRBool deleteFlag = PR_TRUE; //message has been deleted -we are trying to undo it
|
||||
CheckForToggleDelete(srcFolder, m_srcKeyArray.GetAt(0), &deleteFlag); //there could have been a toggle.
|
||||
rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, deleteFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -332,7 +334,9 @@ nsLocalMoveCopyMsgTxn::RedoTransaction()
|
|||
{
|
||||
if (m_srcIsImap4)
|
||||
{
|
||||
rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, PR_TRUE);
|
||||
PRBool deleteFlag = PR_FALSE; //message is un-deleted- we are trying to redo
|
||||
CheckForToggleDelete(srcFolder, m_srcKeyArray.GetAt(0), &deleteFlag); // there could have been a toggle
|
||||
rv = UndoImapDeleteFlag(srcFolder, m_srcKeyArray, deleteFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
PRBool isMove);
|
||||
nsresult UndoImapDeleteFlag(nsIMsgFolder* aFolder,
|
||||
nsMsgKeyArray& aKeyArray,
|
||||
PRBool addFlag);
|
||||
PRBool deleteFlag);
|
||||
|
||||
private:
|
||||
nsWeakPtr m_srcFolder;
|
||||
|
|
Загрузка…
Ссылка в новой задаче