From aae571ade189ac86f5c1fb5649f643d8249d3733 Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Thu, 30 Mar 2000 23:08:53 +0000 Subject: [PATCH] more work on imap delete model, r=putterman 16805 --- .../base/resources/content/threadPane.xul | 4 +- mailnews/base/resources/skin/threadPane.css | 5 ++ mailnews/base/src/nsMsgMessageDataSource.cpp | 43 +++++++++++- mailnews/base/src/nsMsgMessageDataSource.h | 3 + mailnews/base/src/nsMsgRDFUtils.h | 1 + mailnews/base/util/nsMsgDBFolder.cpp | 2 +- mailnews/db/msgdb/public/nsIMsgDatabase.idl | 3 +- mailnews/db/msgdb/public/nsMsgDatabase.h | 3 +- mailnews/db/msgdb/src/nsMsgDatabase.cpp | 36 +++++++++- mailnews/imap/src/nsImapIncomingServer.cpp | 2 +- mailnews/imap/src/nsImapMailFolder.cpp | 68 +++++++++++-------- 11 files changed, 130 insertions(+), 40 deletions(-) diff --git a/mailnews/base/resources/content/threadPane.xul b/mailnews/base/resources/content/threadPane.xul index 0652bf3e1c63..cf8d6874a4da 100644 --- a/mailnews/base/resources/content/threadPane.xul +++ b/mailnews/base/resources/content/threadPane.xul @@ -54,7 +54,9 @@ Rights Reserved. Status="rdf:http://home.netscape.com/NC-rdf#Status" Flagged="rdf:http://home.netscape.com/NC-rdf#Flagged" Priority="rdf:http://home.netscape.com/NC-rdf#Priority" - IsUnread="rdf:http://home.netscape.com/NC-rdf#IsUnread"> + IsUnread="rdf:http://home.netscape.com/NC-rdf#IsUnread" + IsImapDeleted="rdf:http://home.netscape.com/NC-rdf#IsImapDeleted"> + diff --git a/mailnews/base/resources/skin/threadPane.css b/mailnews/base/resources/skin/threadPane.css index 4b80c920af5c..79add627bae5 100644 --- a/mailnews/base/resources/skin/threadPane.css +++ b/mailnews/base/resources/skin/threadPane.css @@ -22,6 +22,11 @@ treeitem[IsUnread="true"] > treerow { font-weight: bold; } +treeitem[IsImapDeleted="true"] > treerow { + font-weight: lighter; + font-style: italic; +} + treeitem[Priority="Highest"] > treerow > treecell.prioritycol > .tree-button { color:red; diff --git a/mailnews/base/src/nsMsgMessageDataSource.cpp b/mailnews/base/src/nsMsgMessageDataSource.cpp index b2e770361cfe..588bdaf57f02 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.cpp +++ b/mailnews/base/src/nsMsgMessageDataSource.cpp @@ -61,6 +61,7 @@ nsIRDFResource* nsMsgMessageDataSource::kNC_Total = nsnull; nsIRDFResource* nsMsgMessageDataSource::kNC_Unread = nsnull; nsIRDFResource* nsMsgMessageDataSource::kNC_MessageChild = nsnull; nsIRDFResource* nsMsgMessageDataSource::kNC_IsUnread = nsnull; +nsIRDFResource* nsMsgMessageDataSource::kNC_IsImapDeleted = nsnull; nsIRDFResource* nsMsgMessageDataSource::kNC_OrderReceived = nsnull; nsIRDFResource* nsMsgMessageDataSource::kNC_OrderReceivedSort = nsnull; @@ -114,6 +115,7 @@ nsMsgMessageDataSource::~nsMsgMessageDataSource (void) NS_RELEASE2(kNC_Unread, refcnt); NS_RELEASE2(kNC_MessageChild, refcnt); NS_RELEASE2(kNC_IsUnread, refcnt); + NS_RELEASE2(kNC_IsImapDeleted, refcnt); NS_RELEASE2(kNC_OrderReceived, refcnt); NS_RELEASE2(kNC_OrderReceivedSort, refcnt); @@ -168,6 +170,7 @@ nsresult nsMsgMessageDataSource::Init() rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_Unread); rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild); rdf->GetResource(NC_RDF_ISUNREAD, &kNC_IsUnread); + rdf->GetResource(NC_RDF_ISIMAPDELETED, &kNC_IsImapDeleted); rdf->GetResource(NC_RDF_ORDERRECEIVED, &kNC_OrderReceived); rdf->GetResource(NC_RDF_ORDERRECEIVED_SORT, &kNC_OrderReceivedSort); @@ -392,7 +395,7 @@ NS_IMETHODIMP nsMsgMessageDataSource::GetTargets(nsIRDFResource* source, else if((kNC_Subject == property) || (kNC_Date == property) || (kNC_Status == property) || (kNC_Flagged == property) || (kNC_Priority == property) || (kNC_Size == property) || - (kNC_IsUnread == property) || (kNC_OrderReceived == property)) + (kNC_IsUnread == property) || (kNC_IsImapDeleted == property) || (kNC_OrderReceived == property)) { nsSingletonEnumerator* cursor = new nsSingletonEnumerator(source); @@ -517,6 +520,7 @@ nsMsgMessageDataSource::getMessageArcLabelsOut(PRBool showThreads, (*arcs)->AppendElement(kNC_Priority); (*arcs)->AppendElement(kNC_Size); (*arcs)->AppendElement(kNC_IsUnread); + (*arcs)->AppendElement(kNC_IsImapDeleted); (*arcs)->AppendElement(kNC_OrderReceived); return NS_OK; @@ -770,7 +774,10 @@ nsresult nsMsgMessageDataSource::OnChangeStatus(nsIRDFResource *resource, PRUint } } - + else if(changedFlag & MSG_FLAG_IMAP_DELETED) + { + OnChangeIsImapDeleted(resource, oldFlag, newFlag); + } return NS_OK; } @@ -800,6 +807,18 @@ nsresult nsMsgMessageDataSource::OnChangeIsUnread(nsIRDFResource *resource, PRUi return rv; } +nsresult nsMsgMessageDataSource::OnChangeIsImapDeleted(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag) +{ + nsresult rv; + nsCOMPtr newIsImapDeletedNode; + + newIsImapDeletedNode = (newFlag & MSG_FLAG_IMAP_DELETED) ? kTrueLiteral : kFalseLiteral; + + rv = NotifyPropertyChanged(resource, kNC_IsImapDeleted, newIsImapDeletedNode); + + return rv; +} + nsresult nsMsgMessageDataSource::OnChangeUnreadMessageCount(nsIMessage *message) { nsresult rv; @@ -898,6 +917,8 @@ nsMsgMessageDataSource::createMessageNode(nsIMessage *message, rv = createMessageUnreadNode(message, target); else if((kNC_IsUnread == property)) rv = createMessageIsUnreadNode(message, target); + else if((kNC_IsImapDeleted == property)) + rv = createMessageIsImapDeletedNode(message, target); else if ((kNC_MessageChild == property)) rv = createMessageMessageChildNode(message, target); else if ((kNC_OrderReceived == property)) @@ -1030,6 +1051,24 @@ nsMsgMessageDataSource::createMessageIsUnreadNode(nsIMessage *message, nsIRDFNod return NS_OK; } +nsresult +nsMsgMessageDataSource::createMessageIsImapDeletedNode(nsIMessage *message, nsIRDFNode **target) +{ + nsresult rv; + PRUint32 flags; + rv = message->GetFlags(&flags); + if(NS_FAILED(rv)) + return rv; + if(flags & MSG_FLAG_IMAP_DELETED) + *target = kTrueLiteral; + else + *target = kFalseLiteral; + + NS_IF_ADDREF(*target); + return NS_OK; +} + + nsresult nsMsgMessageDataSource::createMessageOrderReceivedNode(nsIMessage *message, nsIRDFNode **target) { diff --git a/mailnews/base/src/nsMsgMessageDataSource.h b/mailnews/base/src/nsMsgMessageDataSource.h index ccd369d8d619..a5a2259057b9 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.h +++ b/mailnews/base/src/nsMsgMessageDataSource.h @@ -142,6 +142,7 @@ protected: nsIRDFNode **target); nsresult createMessageIsUnreadNode(nsIMessage *message, nsIRDFNode **target); + nsresult createMessageIsImapDeletedNode(nsIMessage *message, nsIRDFNode **target); nsresult createMessageOrderReceivedNode(nsIMessage *message, nsIRDFNode **target); nsresult createMessageOrderReceivedSortNode(nsIMessage *message, nsIRDFNode **target); @@ -174,6 +175,7 @@ protected: nsresult OnChangeStatus(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag); nsresult OnChangeStatusString(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag); nsresult OnChangeIsUnread(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag); + nsresult OnChangeIsImapDeleted(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag); nsresult OnChangeUnreadMessageCount(nsIMessage *message); nsresult OnChangeTotalMessageCount(nsIMessage *message); @@ -193,6 +195,7 @@ protected: static nsIRDFResource* kNC_Unread; static nsIRDFResource* kNC_MessageChild; static nsIRDFResource* kNC_IsUnread; + static nsIRDFResource* kNC_IsImapDeleted; static nsIRDFResource* kNC_OrderReceived; static nsIRDFResource* kNC_OrderReceivedSort; diff --git a/mailnews/base/src/nsMsgRDFUtils.h b/mailnews/base/src/nsMsgRDFUtils.h index 1d23004126c0..9e92bee85ac3 100644 --- a/mailnews/base/src/nsMsgRDFUtils.h +++ b/mailnews/base/src/nsMsgRDFUtils.h @@ -46,6 +46,7 @@ typedef struct _nsMsgRDFNotification { #define NC_RDF_PRIORITY NC_NAMESPACE_URI "Priority" #define NC_RDF_SIZE NC_NAMESPACE_URI "Size" #define NC_RDF_ISUNREAD NC_NAMESPACE_URI "IsUnread" +#define NC_RDF_ISIMAPDELETED NC_NAMESPACE_URI "IsImapDeleted" #define NC_RDF_ORDERRECEIVED NC_NAMESPACE_URI "OrderReceived" #define NC_RDF_CHILD NC_NAMESPACE_URI "child" diff --git a/mailnews/base/util/nsMsgDBFolder.cpp b/mailnews/base/util/nsMsgDBFolder.cpp index 0e39531fd474..bf572ece89e6 100644 --- a/mailnews/base/util/nsMsgDBFolder.cpp +++ b/mailnews/base/util/nsMsgDBFolder.cpp @@ -427,7 +427,7 @@ nsresult nsMsgDBFolder::SendFlagNotifications(nsISupports *item, PRUint32 oldFla PRUint32 changedFlags = oldFlags ^ newFlags; if((changedFlags & MSG_FLAG_READ) || (changedFlags & MSG_FLAG_REPLIED) - || (changedFlags & MSG_FLAG_FORWARDED)|| (changedFlags & MSG_FLAG_NEW)) + || (changedFlags & MSG_FLAG_FORWARDED)|| (changedFlags & MSG_FLAG_NEW) || (changedFlags & MSG_FLAG_IMAP_DELETED)) { rv = NotifyPropertyFlagChanged(item, kStatusAtom, oldFlags, newFlags); } diff --git a/mailnews/db/msgdb/public/nsIMsgDatabase.idl b/mailnews/db/msgdb/public/nsIMsgDatabase.idl index 965b9bd2e910..41eb6c633d6b 100644 --- a/mailnews/db/msgdb/public/nsIMsgDatabase.idl +++ b/mailnews/db/msgdb/public/nsIMsgDatabase.idl @@ -155,8 +155,7 @@ interface nsIMsgDatabase : nsIDBChangeAnnouncer { void MarkOffline(in nsMsgKey key, in boolean offline, in nsIDBChangeListener instigator); - // returns NS_OK on success, NS_COMFALSE on failure - [noscript] void AllMsgKeysImapDeleted(in nsMsgKeyArrayPtr keys); + [noscript] void AllMsgKeysImapDeleted(in nsMsgKeyArrayPtr keys, out boolean allDeleted); void MarkImapDeleted(in nsMsgKey key, in boolean deleted, in nsIDBChangeListener instigator); diff --git a/mailnews/db/msgdb/public/nsMsgDatabase.h b/mailnews/db/msgdb/public/nsMsgDatabase.h index d4fc2d6d5fa0..76010f258961 100644 --- a/mailnews/db/msgdb/public/nsMsgDatabase.h +++ b/mailnews/db/msgdb/public/nsMsgDatabase.h @@ -171,8 +171,7 @@ public: NS_IMETHOD MarkOffline(nsMsgKey key, PRBool offline, nsIDBChangeListener *instigator); - // returns NS_OK on success, NS_COMFALSE on failure - NS_IMETHOD AllMsgKeysImapDeleted(nsMsgKeyArray *keys); + NS_IMETHOD AllMsgKeysImapDeleted(nsMsgKeyArray *keys, PRBool *allKeysDeleted); NS_IMETHOD MarkImapDeleted(nsMsgKey key, PRBool deleted, nsIDBChangeListener *instigator); diff --git a/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mailnews/db/msgdb/src/nsMsgDatabase.cpp index 00a7a7b2d6bf..c6d56bff898f 100644 --- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -1462,9 +1462,41 @@ NS_IMETHODIMP nsMsgDatabase::MarkOffline(nsMsgKey key, PRBool offline, } NS_IMETHODIMP -nsMsgDatabase::AllMsgKeysImapDeleted(nsMsgKeyArray *keys) +nsMsgDatabase::AllMsgKeysImapDeleted(nsMsgKeyArray *keys, PRBool *allKeysDeleted) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!keys || ! allKeysDeleted) + return NS_ERROR_NULL_POINTER; + + for (PRUint32 kindex = 0; kindex < keys->GetSize(); kindex++) + { + nsMsgKey key = keys->ElementAt(kindex); + nsIMsgDBHdr *msgHdr = NULL; + + PRBool hasKey; + + if (NS_SUCCEEDED(ContainsKey(key, &hasKey)) && hasKey) + { + nsresult err = GetMsgHdrForKey(key, &msgHdr); + if (NS_FAILED(err)) + { + // ### we drop this error -probably OK. + err = NS_MSG_MESSAGE_NOT_FOUND; + break; + } + if (msgHdr) + { + PRUint32 flags; + (void)msgHdr->GetFlags(&flags); + if (! (flags & MSG_FLAG_IMAP_DELETED)) + { + *allKeysDeleted = PR_FALSE; + return NS_OK; + } + } + } + } + *allKeysDeleted = PR_TRUE; + return NS_OK; } NS_IMETHODIMP nsMsgDatabase::MarkImapDeleted(nsMsgKey key, PRBool deleted, diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index 1de1133871cd..d31331ee906b 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -127,7 +127,7 @@ NS_IMETHODIMP nsImapIncomingServer::SetKey(const char * aKey) // override nsMsg nsMsgImapDeleteModel deleteModel; GetDeleteModel(&deleteModel); hostSession->SetDeleteIsMoveToTrashForHost(aKey, deleteModel == nsMsgImapDeleteModels::MoveToTrash); - hostSession->SetShowDeletedMessagesForHost(aKey, deleteModel != nsMsgImapDeleteModels::IMAPDelete); + hostSession->SetShowDeletedMessagesForHost(aKey, deleteModel == nsMsgImapDeleteModels::IMAPDelete); char *personalNamespace = nsnull; char *publicNamespace = nsnull; diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 6cee14962c81..afa28e6941d5 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -1396,12 +1396,12 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages, deleteImmediatelyNoTrash = PR_TRUE; } - rv = BuildIdsAndKeyArray(messages, messageIds, srcKeyArray); - if (NS_FAILED(rv)) return rv; + rv = BuildIdsAndKeyArray(messages, messageIds, srcKeyArray); + if (NS_FAILED(rv)) return rv; - nsCOMPtr rootFolder; - nsCOMPtr trashFolder; + nsCOMPtr rootFolder; + nsCOMPtr trashFolder; if (!deleteImmediatelyNoTrash) { @@ -1417,47 +1417,56 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages, deleteImmediatelyNoTrash = PR_TRUE; } } - if ((NS_SUCCEEDED(rv) && deleteImmediatelyNoTrash) || deleteModel == nsMsgImapDeleteModels::IMAPDelete ) - { - rv = StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE, srcKeyArray); + if ((NS_SUCCEEDED(rv) && deleteImmediatelyNoTrash) || deleteModel == nsMsgImapDeleteModels::IMAPDelete ) + { + rv = StoreImapFlags(kImapMsgDeletedFlag, PR_TRUE, srcKeyArray); if (NS_SUCCEEDED(rv)) { - if (mDatabase && deleteModel != nsMsgImapDeleteModels::IMAPDelete) + if (mDatabase) { - mDatabase->DeleteMessages(&srcKeyArray,NULL); -// if(!isMove) + if (deleteModel == nsMsgImapDeleteModels::IMAPDelete) { + PRBool allKeysImapDeleted; + mDatabase->AllMsgKeysImapDeleted(&srcKeyArray, &allKeysImapDeleted); + for (PRUint32 kindex = 0; kindex < srcKeyArray.GetSize(); kindex++) + { + nsMsgKey key = srcKeyArray.ElementAt(kindex); + mDatabase->MarkImapDeleted(key, !allKeysImapDeleted, nsnull); + } + } + else + { + mDatabase->DeleteMessages(&srcKeyArray,NULL); NotifyDeleteOrMoveMessagesCompleted(this); } } - - return rv; - } - } - else - { + } + return rv; + } + else + { if (msgWindow) { nsCOMPtr txnMgr; msgWindow->GetTransactionManager(getter_AddRefs(txnMgr)); - if (txnMgr) SetTransactionManager(txnMgr); + if (txnMgr) SetTransactionManager(txnMgr); } - - if(trashFolder) + + if(trashFolder) { - nsCOMPtr srcFolder; - nsCOMPtrsrcSupport; - PRUint32 count = 0; - rv = messages->Count(&count); + nsCOMPtr srcFolder; + nsCOMPtrsrcSupport; + PRUint32 count = 0; + rv = messages->Count(&count); - rv = QueryInterface(NS_GET_IID(nsIMsgFolder), - getter_AddRefs(srcFolder)); - rv = trashFolder->CopyMessages(srcFolder, messages, PR_TRUE, msgWindow, nsnull); + rv = QueryInterface(NS_GET_IID(nsIMsgFolder), + getter_AddRefs(srcFolder)); + rv = trashFolder->CopyMessages(srcFolder, messages, PR_TRUE, msgWindow, nsnull); } - } - return rv; + } + return rv; } PRBool @@ -1910,7 +1919,7 @@ NS_IMETHODIMP nsImapMailFolder::NormalEndHeaderParseStream(nsIImapProtocol* } } // here we need to tweak flags from uid state.. - if (!m_msgMovedByFilter) + if (!m_msgMovedByFilter || !DeleteIsMoveToTrash()) mDatabase->AddNewHdrToDB(newMsgHdr, PR_TRUE); // I don't think we want to do this - it does bad things like set the size incorrectly. // m_msgParser->FinishHeader(); @@ -2845,6 +2854,7 @@ nsImapMailFolder::NotifyMessageFlags(PRUint32 flags, nsMsgKey msgKey) mDatabase->MarkHdrRead(dbHdr, (flags & kImapMsgSeenFlag) != 0, nsnull); mDatabase->MarkHdrReplied(dbHdr, (flags & kImapMsgAnsweredFlag) != 0, nsnull); mDatabase->MarkHdrMarked(dbHdr, (flags & kImapMsgFlaggedFlag) != 0, nsnull); + mDatabase->MarkImapDeleted(msgKey, (flags & kImapMsgDeletedFlag) != 0, nsnull); } }