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:
naving%netscape.com 2002-02-08 03:30:20 +00:00
Родитель 2b7b07bdb8
Коммит 8bb5fdc086
7 изменённых файлов: 132 добавлений и 57 удалений

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

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