diff --git a/mailnews/base/public/nsIFolderListener.idl b/mailnews/base/public/nsIFolderListener.idl index af098909167..f9fd5be1fc4 100644 --- a/mailnews/base/public/nsIFolderListener.idl +++ b/mailnews/base/public/nsIFolderListener.idl @@ -30,6 +30,8 @@ interface nsIFolderListener : nsISupports { void OnItemAdded(in nsISupports parentItem, in nsISupports item, in string viewString); void OnItemRemoved(in nsISupports parentItem, in nsISupports item, in string viewString); void OnItemPropertyChanged(in nsISupports item, in string property, in string oldValue, in string newValue); + void OnItemIntPropertyChanged(in nsISupports item, in string property, in long oldValue, in long newValue); + void OnItemBoolPropertyChanged(in nsISupports item, in string property, in boolean oldValue, in boolean newValue); void OnItemPropertyFlagChanged(in nsISupports item, in string property, in unsigned long oldFlag, in unsigned long newFlag); void OnFolderLoaded(in nsIFolder aFolder); diff --git a/mailnews/base/public/nsIMsgMailSession.idl b/mailnews/base/public/nsIMsgMailSession.idl index 8f6e78cab4e..c609c050d78 100644 --- a/mailnews/base/public/nsIMsgMailSession.idl +++ b/mailnews/base/public/nsIMsgMailSession.idl @@ -57,6 +57,14 @@ interface nsIMsgMailSession : nsISupports { in string property, in string oldValue, in string newValue); + void NotifyFolderItemIntPropertyChanged(in nsISupports item, + in string property, + in long oldValue, + in long newValue); + void NotifyFolderItemBoolPropertyChanged(in nsISupports item, + in string property, + in boolean oldValue, + in boolean newValue); void NotifyFolderItemPropertyFlagChanged(in nsISupports item, in string property, in unsigned long oldValue, diff --git a/mailnews/base/resources/content/commandglue.js b/mailnews/base/resources/content/commandglue.js index be7582797d9..37e77bf1e35 100644 --- a/mailnews/base/resources/content/commandglue.js +++ b/mailnews/base/resources/content/commandglue.js @@ -240,12 +240,31 @@ function RerootFolder(uri, newFolder, isThreaded, sortID) folder.setAttribute('ref', uri); + UpdateStatusMessageCounts(newFolder); + var afterFolderLoadTime = new Date(); var timeToLoad = (afterFolderLoadTime.getTime() - gBeforeFolderLoadTime.getTime())/1000; if(showPerformance) dump("Time to load " + uri + " is " + timeToLoad + " seconds\n"); } + +function UpdateStatusMessageCounts(folder) +{ + var unreadElement = GetUnreadCountElement(); + var totalElement = GetTotalCountElement(); + if(folder && unreadElement && totalElement) + { + var numUnread = folder.getNumUnread(false); + var numTotal = folder.getTotalMessages(false); + + unreadElement.setAttribute("value", numUnread); + totalElement.setAttribute("value", numTotal); + + } + +} + function SortThreadPane(column, sortKey) { var node = document.getElementById(column); diff --git a/mailnews/base/resources/content/folderPane.xul b/mailnews/base/resources/content/folderPane.xul index ca024f5db73..26412e08494 100644 --- a/mailnews/base/resources/content/folderPane.xul +++ b/mailnews/base/resources/content/folderPane.xul @@ -42,11 +42,11 @@ BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState" IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer" ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType" + HasUnreadMessages="rdf:http://home.netscape.com/NC-rdf#HasUnreadMessages" + SubfoldersHaveUnreadMesages="rdf:http://home.netscape.com/NC-rdf#SubfoldersHaveUnreadMessages" persist="threaded"> - - @@ -54,14 +54,8 @@ - - - - - - diff --git a/mailnews/base/resources/content/messenger.xul b/mailnews/base/resources/content/messenger.xul index 2328f0c3204..433fd628b5e 100644 --- a/mailnews/base/resources/content/messenger.xul +++ b/mailnews/base/resources/content/messenger.xul @@ -558,6 +558,10 @@ Rights Reserved. + + + + diff --git a/mailnews/base/resources/content/msgMail3PaneWindow.js b/mailnews/base/resources/content/msgMail3PaneWindow.js index 14df06850eb..1636cbcca19 100644 --- a/mailnews/base/resources/content/msgMail3PaneWindow.js +++ b/mailnews/base/resources/content/msgMail3PaneWindow.js @@ -36,6 +36,8 @@ var messageDSProgID = datasourceProgIDPrefix + "mailnewsmessages"; var gFolderTree; var gThreadTree; var gThreadAndMessagePaneSplitter = null; +var gUnreadCount = null; +var gTotalCount = null; var gCurrentLoadingFolderURI; var gCurrentLoadingFolderIsThreaded = false; @@ -70,6 +72,36 @@ var folderListener = { OnItemPropertyChanged: function(item, property, oldValue, newValue) {}, + OnItemIntPropertyChanged: function(item, property, oldValue, newValue) + { + if(property == "TotalMessages" || property == "TotalUnreadMessages") + { + folder = item.QueryInterface(Components.interfaces.nsIMsgFolder); + if(folder) + { + var folderResource = folder.QueryInterface(Components.interfaces.nsIRDFResource); + if(folderResource) + { + var folderURI = folderResource.Value; + var currentLoadedFolder = GetThreadTreeFolder(); + var currentURI = currentLoadedFolder.getAttribute('ref'); + if(currentURI == folderURI) + { + UpdateStatusMessageCounts(folder); + } + } + + + } + + + + } + + }, + + OnItemBoolPropertyChanged: function(item, property, oldValue, newValue) {}, + OnItemPropertyFlagChanged: function(item, property, oldFlag, newFlag) {}, OnFolderLoaded: function (folder) @@ -367,6 +399,20 @@ function GetThreadAndMessagePaneSplitter() return splitter; } +function GetUnreadCountElement() +{ + if(gUnreadCount) return gUnreadCount; + var unreadCount = document.getElementById('unreadMessageCount'); + gUnreadCount = unreadCount; + return unreadCount; +} +function GetTotalCountElement() +{ + if(gTotalCount) return gTotalCount; + var totalCount = document.getElementById('totalMessageCount'); + gTotalCount = totalCount; + return totalCount; +} function IsThreadAndMessagePaneSplitterCollapsed() { var splitter = GetThreadAndMessagePaneSplitter(); diff --git a/mailnews/base/resources/locale/en-US/messenger.dtd b/mailnews/base/resources/locale/en-US/messenger.dtd index e9fe3d28c25..519711d2503 100644 --- a/mailnews/base/resources/locale/en-US/messenger.dtd +++ b/mailnews/base/resources/locale/en-US/messenger.dtd @@ -250,6 +250,8 @@ Rights Reserved. + + diff --git a/mailnews/base/resources/skin/folderPane.css b/mailnews/base/resources/skin/folderPane.css index 6a4b2a99e35..886e132dabe 100644 --- a/mailnews/base/resources/skin/folderPane.css +++ b/mailnews/base/resources/skin/folderPane.css @@ -128,6 +128,17 @@ treeitem[IsServer="true"][ServerType="nntp"] > treerow > treecell > .tree-icon list-style-image: url("chrome://messenger/skin/server-news.gif"); } +/*All Servers*/ +treeitem[IsServer="true"] > treerow > treecell +{ + font-weight: bold; +} + +treeitem[HasUnreadMessages="true"] > treerow > treecell +{ + font-weight: bold; +} + #folder-panel { min-width: 10px; } diff --git a/mailnews/base/src/nsMsgFolderDataSource.cpp b/mailnews/base/src/nsMsgFolderDataSource.cpp index bdcb349e09a..55b736305fe 100644 --- a/mailnews/base/src/nsMsgFolderDataSource.cpp +++ b/mailnews/base/src/nsMsgFolderDataSource.cpp @@ -66,6 +66,8 @@ nsIRDFResource* nsMsgFolderDataSource::kNC_TotalMessages= nsnull; nsIRDFResource* nsMsgFolderDataSource::kNC_TotalUnreadMessages= nsnull; nsIRDFResource* nsMsgFolderDataSource::kNC_Charset = nsnull; nsIRDFResource* nsMsgFolderDataSource::kNC_BiffState = nsnull; +nsIRDFResource* nsMsgFolderDataSource::kNC_HasUnreadMessages = nsnull; +nsIRDFResource* nsMsgFolderDataSource::kNC_SubfoldersHaveUnreadMessages = nsnull; // commands nsIRDFResource* nsMsgFolderDataSource::kNC_Delete= nsnull; @@ -113,6 +115,8 @@ nsMsgFolderDataSource::~nsMsgFolderDataSource (void) NS_RELEASE2(kNC_TotalUnreadMessages, refcnt); NS_RELEASE2(kNC_Charset, refcnt); NS_RELEASE2(kNC_BiffState, refcnt); + NS_RELEASE2(kNC_HasUnreadMessages, refcnt); + NS_RELEASE2(kNC_SubfoldersHaveUnreadMessages, refcnt); NS_RELEASE2(kNC_Delete, refcnt); NS_RELEASE2(kNC_NewFolder, refcnt); @@ -156,6 +160,8 @@ nsresult nsMsgFolderDataSource::Init() rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_TotalUnreadMessages); rdf->GetResource(NC_RDF_CHARSET, &kNC_Charset); rdf->GetResource(NC_RDF_BIFFSTATE, &kNC_BiffState); + rdf->GetResource(NC_RDF_HASUNREADMESSAGES, &kNC_HasUnreadMessages); + rdf->GetResource(NC_RDF_SUBFOLDERSHAVEUNREADMESSAGES, &kNC_SubfoldersHaveUnreadMessages); rdf->GetResource(NC_RDF_DELETE, &kNC_Delete); rdf->GetResource(NC_RDF_NEWFOLDER, &kNC_NewFolder); @@ -168,6 +174,7 @@ nsresult nsMsgFolderDataSource::Init() rdf->GetResource(NC_RDF_RENAME, &kNC_Rename); rdf->GetResource(NC_RDF_EMPTYTRASH, &kNC_EmptyTrash); } + CreateLiterals(rdf); rv = CreateArcsOutEnumerator(); if(NS_FAILED(rv)) return rv; @@ -176,6 +183,17 @@ nsresult nsMsgFolderDataSource::Init() return nsMsgRDFDataSource::Init(); } +nsresult nsMsgFolderDataSource::CreateLiterals(nsIRDFService *rdf) +{ + + nsAutoString str = "true"; + createNode(str, getter_AddRefs(kTrueLiteral), rdf); + str = "false"; + createNode(str, getter_AddRefs(kFalseLiteral), rdf); + return NS_OK; + +} + void nsMsgFolderDataSource::Close() { kFolderArcsOutArray = null_nsCOMPtr(); @@ -715,20 +733,33 @@ NS_IMETHODIMP nsMsgFolderDataSource::OnItemPropertyChanged(nsISupports *item, co const char *oldValue, const char *newValue) { - nsresult rv; - nsCOMPtr resource(do_QueryInterface(item, &rv)); + return NS_OK; +} - if(NS_SUCCEEDED(rv)) +NS_IMETHODIMP nsMsgFolderDataSource::OnItemIntPropertyChanged(nsISupports *item, const char *property, + PRInt32 oldValue, PRInt32 newValue) +{ + //We only care about folder changes + nsCOMPtr folder = do_QueryInterface(item); + if(folder) { + if(PL_strcmp("TotalMessages", property) == 0) { - NotifyPropertyChanged(resource, kNC_TotalMessages, oldValue, newValue); + OnTotalMessagePropertyChanged(folder, oldValue, newValue); } else if(PL_strcmp("TotalUnreadMessages", property) == 0) { - NotifyPropertyChanged(resource, kNC_TotalUnreadMessages, oldValue, newValue); + OnUnreadMessagePropertyChanged(folder, oldValue, newValue); } + } + return NS_OK; +} + +NS_IMETHODIMP nsMsgFolderDataSource::OnItemBoolPropertyChanged(nsISupports *item, const char *property, + PRBool oldValue, PRBool newValue) +{ return NS_OK; } @@ -768,19 +799,6 @@ NS_IMETHODIMP nsMsgFolderDataSource::OnFolderLoaded(nsIFolder *folder) return rv; } -nsresult nsMsgFolderDataSource::NotifyPropertyChanged(nsIRDFResource *resource, - nsIRDFResource *propertyResource, - const char *oldValue, const char *newValue) -{ - nsCOMPtr oldValueNode, newValueNode; - nsString oldValueStr = oldValue; - nsString newValueStr = newValue; - createNode(oldValueStr,getter_AddRefs(oldValueNode), getRDFService()); - createNode(newValueStr, getter_AddRefs(newValueNode), getRDFService()); - NotifyObservers(resource, propertyResource, oldValueNode, PR_FALSE); - NotifyObservers(resource, propertyResource, newValueNode, PR_TRUE); - return NS_OK; -} nsresult nsMsgFolderDataSource::createFolderNode(nsIMsgFolder* folder, nsIRDFResource* property, @@ -810,6 +828,10 @@ nsresult nsMsgFolderDataSource::createFolderNode(nsIMsgFolder* folder, rv = createCharsetNode(folder, target); else if ((kNC_BiffState == property)) rv = createBiffStateNode(folder, target); + else if ((kNC_HasUnreadMessages == property)) + rv = createHasUnreadMessagesNode(folder, target); + else if ((kNC_SubfoldersHaveUnreadMessages == property)) + rv = createSubfoldersHaveUnreadMessagesNode(folder, target); else if ((kNC_Child == property)) rv = createFolderChildNode(folder, target); else if ((kNC_MessageChild == property)) @@ -827,7 +849,7 @@ nsresult nsMsgFolderDataSource::createFolderNameNode(nsIMsgFolder *folder, nsXPIDLString name; nsresult rv = folder->GetName(getter_Copies(name)); if (NS_FAILED(rv)) return rv; - nsString nameString(name); + nsAutoString nameString(name); if(sort) { CreateNameSortString(folder, nameString); @@ -841,34 +863,57 @@ nsresult nsMsgFolderDataSource::createFolderTreeNameNode(nsIMsgFolder *folder, nsIRDFNode **target, PRBool sort) { - nsXPIDLString name; - nsresult rv = folder->GetAbbreviatedName(getter_Copies(name)); - if (NS_FAILED(rv)) return rv; - nsString nameString(name); + nsXPIDLString name; + nsresult rv = folder->GetAbbreviatedName(getter_Copies(name)); + if (NS_FAILED(rv)) return rv; + nsAutoString nameString(name); if(sort) { CreateNameSortString(folder, nameString); } + else + { + PRInt32 unreadMessages; + + nsresult rv; + rv = folder->GetNumUnread(PR_FALSE, &unreadMessages); + if(NS_SUCCEEDED(rv)) + { + CreateUnreadMessagesNameString(unreadMessages, nameString); + } + + } createNode(nameString, target, getRDFService()); return NS_OK; } -nsresult nsMsgFolderDataSource::CreateNameSortString(nsIMsgFolder *folder, nsString &name) +nsresult nsMsgFolderDataSource::CreateNameSortString(nsIMsgFolder *folder, nsAutoString &name) { PRInt32 order; nsresult rv = GetFolderSortOrder(folder, &order); if(NS_FAILED(rv)) return rv; - char * orderString = PR_smprintf("%d", order); - if(!orderString) - return NS_ERROR_OUT_OF_MEMORY; + + nsAutoString orderString; + orderString.Append(order); name.Insert(orderString, 0); - PR_smprintf_free(orderString); return NS_OK; } +nsresult nsMsgFolderDataSource::CreateUnreadMessagesNameString(PRInt32 unreadMessages, nsAutoString &nameString) +{ + //Only do this if unread messages are positive + if(unreadMessages > 0) + { + nameString.Append(" ("); + nameString.Append(unreadMessages); + nameString.Append(')'); + } + return NS_OK; +} + nsresult nsMsgFolderDataSource::createFolderSpecialNode(nsIMsgFolder *folder, nsIRDFNode **target) @@ -877,7 +922,7 @@ nsMsgFolderDataSource::createFolderSpecialNode(nsIMsgFolder *folder, nsresult rv = folder->GetFlags(&flags); if(NS_FAILED(rv)) return rv; - nsString specialFolderString; + nsAutoString specialFolderString; if(flags & MSG_FOLDER_FLAG_INBOX) specialFolderString = "Inbox"; @@ -924,10 +969,13 @@ nsMsgFolderDataSource::createFolderIsServerNode(nsIMsgFolder* folder, rv = folder->GetIsServer(&isServer); if (NS_FAILED(rv)) return rv; + *target = nsnull; + if (isServer) - createNode("true", target, getRDFService()); + *target = kTrueLiteral; else - createNode("false", target, getRDFService()); + *target = kFalseLiteral; + NS_IF_ADDREF(*target); return NS_OK; } @@ -950,18 +998,8 @@ nsMsgFolderDataSource::createTotalMessagesNode(nsIMsgFolder *folder, rv = folder->GetTotalMessages(PR_FALSE, &totalMessages); if(NS_FAILED(rv)) return rv; } - if(totalMessages >= 0) - rv = createNode(totalMessages, target, getRDFService()); - else if(totalMessages == -1) - { - nsString unknownMessages("???"); - createNode(unknownMessages, target, getRDFService()); - } - else if(totalMessages == -2) - { - nsString unknownMessages(""); - createNode(unknownMessages, target, getRDFService()); - } + GetNumMessagesNode(totalMessages, target); + return rv; } @@ -969,7 +1007,7 @@ nsresult nsMsgFolderDataSource::createCharsetNode(nsIMsgFolder *folder, nsIRDFNode **target) { PRUnichar *charset; - nsString charsetStr; + nsAutoString charsetStr; nsresult rv = folder->GetCharset(&charset); //We always need to return a value if(NS_SUCCEEDED(rv)) @@ -991,7 +1029,7 @@ nsMsgFolderDataSource::createBiffStateNode(nsIMsgFolder *folder, nsIRDFNode **ta nsCAutoString biffString; GetBiffStateString(biffState, biffString); - nsString uniStr = biffString; + nsAutoString uniStr = biffString; createNode(uniStr, target, getRDFService()); return NS_OK; } @@ -1027,22 +1065,137 @@ nsMsgFolderDataSource::createUnreadMessagesNode(nsIMsgFolder *folder, rv = folder->GetNumUnread(PR_FALSE, &totalUnreadMessages); if(NS_FAILED(rv)) return rv; } - if(totalUnreadMessages >=0) - rv = createNode(totalUnreadMessages, target, getRDFService()); - else if(totalUnreadMessages == -1) - { - nsString unknownMessages("???"); - createNode(unknownMessages, target, getRDFService()); - } - else if(totalUnreadMessages == -2) - { - nsString unknownMessages(""); - createNode(unknownMessages, target, getRDFService()); - } + GetNumMessagesNode(totalUnreadMessages, target); + return NS_OK; } +nsresult +nsMsgFolderDataSource::createHasUnreadMessagesNode(nsIMsgFolder *folder, nsIRDFNode **target) +{ + + nsresult rv; + + PRBool isServer; + rv = folder->GetIsServer(&isServer); + if (NS_FAILED(rv)) return rv; + + *target = kFalseLiteral; + + PRInt32 totalUnreadMessages; + if(!isServer) + { + rv = folder->GetNumUnread(PR_FALSE, &totalUnreadMessages); + if(NS_FAILED(rv)) return rv; + if(totalUnreadMessages > 0) + *target = kTrueLiteral; + else + *target = kFalseLiteral; + } + NS_IF_ADDREF(*target); + return NS_OK; +} + +nsresult +nsMsgFolderDataSource::OnUnreadMessagePropertyChanged(nsIMsgFolder *folder, PRInt32 oldValue, PRInt32 newValue) +{ + nsCOMPtr folderResource = do_QueryInterface(folder); + if(folderResource) + { + //First send a regular unread message changed notification + nsCOMPtr oldNode; + nsCOMPtr newNode; + + GetNumMessagesNode(oldValue, getter_AddRefs(oldNode)); + GetNumMessagesNode(newValue, getter_AddRefs(newNode)); + NotifyPropertyChanged(folderResource, kNC_TotalUnreadMessages, oldNode, newNode); + + //Now see if hasUnreadMessages has changed + nsCOMPtr oldHasUnreadMessages; + nsCOMPtr newHasUnreadMessages; + if(oldValue <=0 && newValue >0) + { + oldHasUnreadMessages = kFalseLiteral; + newHasUnreadMessages = kTrueLiteral; + NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, oldHasUnreadMessages, newHasUnreadMessages); + } + else if(oldValue > 0 && newValue <= 0) + { + oldHasUnreadMessages = kTrueLiteral; + newHasUnreadMessages = kFalseLiteral; + NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, oldHasUnreadMessages, newHasUnreadMessages); + } + //We will have to change the folderTreeName also + + nsXPIDLString name; + nsresult rv = folder->GetAbbreviatedName(getter_Copies(name)); + if (NS_SUCCEEDED(rv)) + { + nsAutoString oldNameString(name); + nsAutoString newNameString(name); + + CreateUnreadMessagesNameString(oldValue, oldNameString); + CreateUnreadMessagesNameString(newValue, newNameString); + + nsCOMPtr oldNameNode; + nsCOMPtr newNameNode; + createNode(oldNameString, getter_AddRefs(oldNameNode), getRDFService()); + createNode(newNameString, getter_AddRefs(newNameNode), getRDFService()); + + NotifyPropertyChanged(folderResource, kNC_FolderTreeName, oldNameNode, newNameNode); + + } + + } + return NS_OK; +} + + +nsresult +nsMsgFolderDataSource::OnTotalMessagePropertyChanged(nsIMsgFolder *folder, PRInt32 oldValue, PRInt32 newValue) +{ + nsCOMPtr folderResource = do_QueryInterface(folder); + if(folderResource) + { + //First send a regular unread message changed notification + nsCOMPtr oldNode; + nsCOMPtr newNode; + + GetNumMessagesNode(oldValue, getter_AddRefs(oldNode)); + GetNumMessagesNode(newValue, getter_AddRefs(newNode)); + NotifyPropertyChanged(folderResource, kNC_TotalMessages, oldNode, newNode); + } + return NS_OK; +} + +nsresult +nsMsgFolderDataSource::GetNumMessagesNode(PRInt32 numMessages, nsIRDFNode **node) +{ + + if(numMessages >0) + createNode(numMessages, node, getRDFService()); + else if(numMessages == -1) + { + nsAutoString unknownMessages("???"); + createNode(unknownMessages, node, getRDFService()); + } + else + { + nsAutoString unknownMessages(""); + createNode(unknownMessages, node, getRDFService()); + } + return NS_OK; +} + +nsresult +nsMsgFolderDataSource::createSubfoldersHaveUnreadMessagesNode(nsIMsgFolder *folder, nsIRDFNode **target) +{ + nsAutoString unknownMessages("true"); + createNode(unknownMessages, target, getRDFService()); + + return NS_OK; +} nsresult nsMsgFolderDataSource::createFolderChildNode(nsIMsgFolder *folder, nsIRDFNode **target) @@ -1262,7 +1415,8 @@ nsresult nsMsgFolderDataSource::DoFolderHasAssertion(nsIMsgFolder *folder, (kNC_TotalMessages == property) || (kNC_TotalUnreadMessages == property) || (kNC_Charset == property) || - (kNC_BiffState == property)) + (kNC_BiffState == property) || + (kNC_HasUnreadMessages == property)) { nsCOMPtr folderResource(do_QueryInterface(folder, &rv)); diff --git a/mailnews/base/src/nsMsgFolderDataSource.h b/mailnews/base/src/nsMsgFolderDataSource.h index 829e1475d94..de5a3f58f1c 100644 --- a/mailnews/base/src/nsMsgFolderDataSource.h +++ b/mailnews/base/src/nsMsgFolderDataSource.h @@ -109,9 +109,6 @@ public: nsISupportsArray/**/* aArguments); protected: - nsresult NotifyPropertyChanged(nsIRDFResource *resource, nsIRDFResource *propertyResource, - const char *oldValue, const char *newValue); - nsresult GetSenderName(nsAutoString& sender, nsAutoString *senderUserName); nsresult createFolderNode(nsIMsgFolder *folder, nsIRDFResource* property, @@ -127,6 +124,8 @@ protected: nsresult createUnreadMessagesNode(nsIMsgFolder *folder, nsIRDFNode **target); nsresult createCharsetNode(nsIMsgFolder *folder, nsIRDFNode **target); nsresult createBiffStateNode(nsIMsgFolder *folder, nsIRDFNode **target); + nsresult createHasUnreadMessagesNode(nsIMsgFolder *folder, nsIRDFNode **target); + nsresult createSubfoldersHaveUnreadMessagesNode(nsIMsgFolder *folder, nsIRDFNode **target); nsresult createFolderChildNode(nsIMsgFolder *folder, nsIRDFNode **target); nsresult createFolderMessageNode(nsIMsgFolder *folder, nsIRDFNode **target); @@ -152,7 +151,8 @@ protected: nsresult GetBiffStateString(PRUint32 biffState, nsCAutoString & biffStateStr); - nsresult CreateNameSortString(nsIMsgFolder *folder, nsString &name); + nsresult CreateNameSortString(nsIMsgFolder *folder, nsAutoString &name); + nsresult CreateUnreadMessagesNameString(PRInt32 unreadMessages, nsAutoString &nameString); nsresult GetFolderSortOrder(nsIMsgFolder *folder, PRInt32* order); nsresult CreateArcsOutEnumerator(); @@ -160,6 +160,12 @@ protected: nsresult OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, const char* viewString, PRBool added); + nsresult OnUnreadMessagePropertyChanged(nsIMsgFolder *folder, PRInt32 oldValue, PRInt32 newValue); + nsresult OnTotalMessagePropertyChanged(nsIMsgFolder *folder, PRInt32 oldValue, PRInt32 newValue); + nsresult GetNumMessagesNode(PRInt32 numMessages, nsIRDFNode **node); + + nsresult CreateLiterals(nsIRDFService *rdf); + static nsIRDFResource* kNC_Child; static nsIRDFResource* kNC_MessageChild; static nsIRDFResource* kNC_Folder; @@ -176,6 +182,8 @@ protected: static nsIRDFResource* kNC_TotalUnreadMessages; static nsIRDFResource* kNC_Charset; static nsIRDFResource* kNC_BiffState; + static nsIRDFResource* kNC_HasUnreadMessages; + static nsIRDFResource* kNC_SubfoldersHaveUnreadMessages; // commands static nsIRDFResource* kNC_Delete; @@ -188,6 +196,10 @@ protected: static nsIRDFResource* kNC_Rename; static nsIRDFResource* kNC_EmptyTrash; + //Cached literals + nsCOMPtr kTrueLiteral; + nsCOMPtr kFalseLiteral; + static nsrefcnt gFolderResourceRefCnt; nsCOMPtr kFolderArcsOutArray; diff --git a/mailnews/base/src/nsMsgMailSession.cpp b/mailnews/base/src/nsMsgMailSession.cpp index 7ed0a390e74..642919b4394 100644 --- a/mailnews/base/src/nsMsgMailSession.cpp +++ b/mailnews/base/src/nsMsgMailSession.cpp @@ -176,6 +176,49 @@ nsMsgMailSession::NotifyFolderItemPropertyChanged(nsISupports *item, } +NS_IMETHODIMP +nsMsgMailSession::NotifyFolderItemIntPropertyChanged(nsISupports *item, + const char *property, + PRInt32 oldValue, + PRInt32 newValue) +{ + nsresult rv; + PRUint32 count; + rv = mListeners->Count(&count); + if (NS_FAILED(rv)) return rv; + + + for(PRUint32 i = 0; i < count; i++) + { + nsCOMPtr listener = getter_AddRefs((nsIFolderListener*)mListeners->ElementAt(i)); + listener->OnItemIntPropertyChanged(item, property, oldValue, newValue); + } + + return NS_OK; + +} + +NS_IMETHODIMP +nsMsgMailSession::NotifyFolderItemBoolPropertyChanged(nsISupports *item, + const char *property, + PRBool oldValue, + PRBool newValue) +{ + nsresult rv; + PRUint32 count; + rv = mListeners->Count(&count); + if (NS_FAILED(rv)) return rv; + + + for(PRUint32 i = 0; i < count; i++) + { + nsCOMPtr listener = getter_AddRefs((nsIFolderListener*)mListeners->ElementAt(i)); + listener->OnItemBoolPropertyChanged(item, property, oldValue, newValue); + } + + return NS_OK; + +} NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemPropertyFlagChanged(nsISupports *item, const char *property, diff --git a/mailnews/base/src/nsMsgMessageDataSource.cpp b/mailnews/base/src/nsMsgMessageDataSource.cpp index 7119e53aa26..1d5198b7145 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.cpp +++ b/mailnews/base/src/nsMsgMessageDataSource.cpp @@ -624,6 +624,20 @@ NS_IMETHODIMP nsMsgMessageDataSource::OnItemPropertyChanged(nsISupports *item, c return NS_OK; } +NS_IMETHODIMP nsMsgMessageDataSource::OnItemIntPropertyChanged(nsISupports *item, const char *property, + PRInt32 oldValue, PRInt32 newValue) +{ + + return NS_OK; +} + +NS_IMETHODIMP nsMsgMessageDataSource::OnItemBoolPropertyChanged(nsISupports *item, const char *property, + PRBool oldValue, PRBool newValue) +{ + + return NS_OK; +} + NS_IMETHODIMP nsMsgMessageDataSource::OnItemPropertyFlagChanged(nsISupports *item, const char *property, PRUint32 oldFlag, PRUint32 newFlag) { @@ -1146,20 +1160,6 @@ nsMsgMessageDataSource::DoMarkMessagesFlagged(nsISupportsArray *messages, PRBool return rv; } -nsresult nsMsgMessageDataSource::NotifyPropertyChanged(nsIRDFResource *resource, - nsIRDFResource *propertyResource, - const char *oldValue, const char *newValue) -{ - nsCOMPtr oldValueNode, newValueNode; - nsString oldValueStr = oldValue; - nsString newValueStr = newValue; - createNode(oldValueStr,getter_AddRefs(oldValueNode), getRDFService()); - createNode(newValueStr, getter_AddRefs(newValueNode), getRDFService()); - NotifyObservers(resource, propertyResource, oldValueNode, PR_FALSE); - NotifyObservers(resource, propertyResource, newValueNode, PR_TRUE); - return NS_OK; -} - nsresult nsMsgMessageDataSource::DoMessageHasAssertion(nsIMessage *message, nsIRDFResource *property, nsIRDFNode *target, PRBool tv, PRBool *hasAssertion) diff --git a/mailnews/base/src/nsMsgMessageDataSource.h b/mailnews/base/src/nsMsgMessageDataSource.h index b3da6f006de..2b0f1c8c6b9 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.h +++ b/mailnews/base/src/nsMsgMessageDataSource.h @@ -151,10 +151,6 @@ protected: nsresult DoMarkMessagesRead(nsISupportsArray *messages, PRBool markRead); nsresult DoMarkMessagesFlagged(nsISupportsArray *messages, PRBool markFlagged); - nsresult NotifyPropertyChanged(nsIRDFResource *resource, - nsIRDFResource *propertyResource, - const char *oldValue, const char *newValue); - nsresult DoMessageHasAssertion(nsIMessage *message, nsIRDFResource *property, nsIRDFNode *target, PRBool tv, PRBool *hasAssertion); diff --git a/mailnews/base/src/nsMsgNotificationManager.cpp b/mailnews/base/src/nsMsgNotificationManager.cpp index 48c0efcdf27..bc4e82a2489 100644 --- a/mailnews/base/src/nsMsgNotificationManager.cpp +++ b/mailnews/base/src/nsMsgNotificationManager.cpp @@ -178,6 +178,20 @@ NS_IMETHODIMP nsMsgNotificationManager::OnItemPropertyChanged(nsISupports *item, return rv; } +NS_IMETHODIMP nsMsgNotificationManager::OnItemIntPropertyChanged(nsISupports *item, const char *property, + PRInt32 oldValue, PRInt32 newValue) +{ + + return NS_OK; +} + +NS_IMETHODIMP nsMsgNotificationManager::OnItemBoolPropertyChanged(nsISupports *item, const char *property, + PRBool oldValue, PRBool newValue) +{ + + return NS_OK; +} + NS_IMETHODIMP nsMsgNotificationManager::OnItemPropertyFlagChanged(nsISupports *item, const char *property, PRUint32 oldFlag, PRUint32 newFlag) { diff --git a/mailnews/base/src/nsMsgRDFDataSource.cpp b/mailnews/base/src/nsMsgRDFDataSource.cpp index 8f6185d0cde..1dce3e72821 100644 --- a/mailnews/base/src/nsMsgRDFDataSource.cpp +++ b/mailnews/base/src/nsMsgRDFDataSource.cpp @@ -364,6 +364,30 @@ nsMsgRDFDataSource::getRDFService() return mRDFService; } +nsresult nsMsgRDFDataSource::NotifyPropertyChanged(nsIRDFResource *resource, + nsIRDFResource *propertyResource, + const char *oldValue, const char *newValue) +{ + nsCOMPtr oldValueNode, newValueNode; + nsString oldValueStr = oldValue; + nsString newValueStr = newValue; + createNode(oldValueStr,getter_AddRefs(oldValueNode), getRDFService()); + createNode(newValueStr, getter_AddRefs(newValueNode), getRDFService()); + NotifyPropertyChanged(resource, propertyResource, oldValueNode, newValueNode); + return NS_OK; +} + +nsresult nsMsgRDFDataSource::NotifyPropertyChanged(nsIRDFResource *resource, + nsIRDFResource *propertyResource, + nsIRDFNode *oldNode, nsIRDFNode *newNode) +{ + + NotifyObservers(resource, propertyResource, oldNode, PR_FALSE); + NotifyObservers(resource, propertyResource, newNode, PR_TRUE); + return NS_OK; + +} + nsresult nsMsgRDFDataSource::NotifyObservers(nsIRDFResource *subject, nsIRDFResource *property, nsIRDFNode *object, diff --git a/mailnews/base/src/nsMsgRDFDataSource.h b/mailnews/base/src/nsMsgRDFDataSource.h index f17e40bbbe9..14e56c4491c 100644 --- a/mailnews/base/src/nsMsgRDFDataSource.h +++ b/mailnews/base/src/nsMsgRDFDataSource.h @@ -56,6 +56,12 @@ class nsMsgRDFDataSource : public nsIRDFDataSource, static PRBool unassertEnumFunc(nsISupports *aElement, void *aData); nsresult NotifyObservers(nsIRDFResource *subject, nsIRDFResource *property, nsIRDFNode *object, PRBool assert); + nsresult NotifyPropertyChanged(nsIRDFResource *resource, + nsIRDFResource *propertyResource, + const char *oldValue, const char *newValue); + nsresult NotifyPropertyChanged(nsIRDFResource *resource, + nsIRDFResource *propertyResource, + nsIRDFNode *oldNode, nsIRDFNode *newNode); nsresult GetTransactionManager(nsISupportsArray *sources, nsITransactionManager **aTransactionManager); nsCOMPtr mWindow; diff --git a/mailnews/base/src/nsMsgRDFUtils.h b/mailnews/base/src/nsMsgRDFUtils.h index 59ec4b12ff7..c55fd00f56e 100644 --- a/mailnews/base/src/nsMsgRDFUtils.h +++ b/mailnews/base/src/nsMsgRDFUtils.h @@ -43,7 +43,7 @@ typedef struct _nsMsgRDFNotification { #define NC_RDF_DATE NC_NAMESPACE_URI "Date" #define NC_RDF_STATUS NC_NAMESPACE_URI "Status" #define NC_RDF_FLAGGED NC_NAMESPACE_URI "Flagged" -#define NC_RDF_PRIORITY NC_NAMESPACE_URI "Priority" +#define NC_RDF_PRIORITY NC_NAMESPACE_URI "Priority" #define NC_RDF_SIZE NC_NAMESPACE_URI "Size" #define NC_RDF_CHILD NC_NAMESPACE_URI "child" @@ -52,12 +52,14 @@ typedef struct _nsMsgRDFNotification { #define NC_RDF_FOLDERTREENAME NC_NAMESPACE_URI "FolderTreeName" #define NC_RDF_FOLDER NC_NAMESPACE_URI "Folder" #define NC_RDF_SPECIALFOLDER NC_NAMESPACE_URI "SpecialFolder" -#define NC_RDF_SERVERTYPE NC_NAMESPACE_URI "ServerType" -#define NC_RDF_ISSERVER NC_NAMESPACE_URI "IsServer" +#define NC_RDF_SERVERTYPE NC_NAMESPACE_URI "ServerType" +#define NC_RDF_ISSERVER NC_NAMESPACE_URI "IsServer" #define NC_RDF_TOTALMESSAGES NC_NAMESPACE_URI "TotalMessages" #define NC_RDF_TOTALUNREADMESSAGES NC_NAMESPACE_URI "TotalUnreadMessages" #define NC_RDF_CHARSET NC_NAMESPACE_URI "Charset" #define NC_RDF_BIFFSTATE NC_NAMESPACE_URI "BiffState" +#define NC_RDF_HASUNREADMESSAGES NC_NAMESPACE_URI "HasUnreadMessages" +#define NC_RDF_SUBFOLDERSHAVEUNREADMESSAGES NC_NAMESPACE_URI "SubfoldersHaveUnreadMessages" //Sort Properties #define NC_RDF_SUBJECT_COLLATION_SORT NC_NAMESPACE_URI "Subject?collation=true" diff --git a/mailnews/base/util/nsMsgFolder.cpp b/mailnews/base/util/nsMsgFolder.cpp index 99f2ebf2451..b126dff17f7 100644 --- a/mailnews/base/util/nsMsgFolder.cpp +++ b/mailnews/base/util/nsMsgFolder.cpp @@ -995,28 +995,27 @@ PRInt32 nsMsgFolder::GetNumPendingTotalMessages() void nsMsgFolder::ChangeNumPendingUnread(PRInt32 delta) { - if (delta) + if(delta) { - char *oldUnreadMessagesStr = PR_smprintf("%d", mNumUnreadMessages + mNumPendingUnreadMessages); + PRInt32 oldUnreadMessages = mNumUnreadMessages + mNumPendingUnreadMessages; mNumPendingUnreadMessages += delta; - char *unreadMessagesStr = PR_smprintf("%d",mNumUnreadMessages + mNumPendingUnreadMessages); - NotifyPropertyChanged("TotalUnreadMessages", oldUnreadMessagesStr, unreadMessagesStr); - PR_smprintf_free(unreadMessagesStr); - PR_smprintf_free(oldUnreadMessagesStr); + PRInt32 newUnreadMessages = mNumUnreadMessages + mNumPendingUnreadMessages; + + NotifyIntPropertyChanged("TotalUnreadMessages", oldUnreadMessages, newUnreadMessages); } } void nsMsgFolder::ChangeNumPendingTotalMessages(PRInt32 delta) { - if (delta) + if(delta) { - char *oldTotalMessagesStr = PR_smprintf("%d", mNumTotalMessages + mNumPendingTotalMessages); + PRInt32 oldTotalMessages = mNumTotalMessages + mNumPendingTotalMessages; mNumPendingTotalMessages += delta; - char *totalMessagesStr = PR_smprintf("%d",mNumTotalMessages + mNumPendingTotalMessages); - NotifyPropertyChanged("TotalMessages", oldTotalMessagesStr, totalMessagesStr); - PR_smprintf_free(totalMessagesStr); - PR_smprintf_free(oldTotalMessagesStr); + PRInt32 newTotalMessages = mNumTotalMessages + mNumPendingTotalMessages; + + NotifyIntPropertyChanged("TotalMessages", oldTotalMessages, newTotalMessages); } + } #ifdef HAVE_DB @@ -1705,6 +1704,56 @@ nsresult nsMsgFolder::NotifyPropertyChanged(char *property, char *oldValue, char } +nsresult nsMsgFolder::NotifyIntPropertyChanged(char *property, PRInt32 oldValue, PRInt32 newValue) +{ + nsCOMPtr supports; + if(NS_SUCCEEDED(QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(supports)))) + { + PRInt32 i; + for(i = 0; i < mListeners->Count(); i++) + { + //Folderlistener's aren't refcounted. + nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i); + listener->OnItemIntPropertyChanged(supports, property, oldValue, newValue); + } + + //Notify listeners who listen to every folder + nsresult rv; + NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv); + if(NS_SUCCEEDED(rv)) + mailSession->NotifyFolderItemIntPropertyChanged(supports, property, oldValue, newValue); + + } + + return NS_OK; + +} + +nsresult nsMsgFolder::NotifyBoolPropertyChanged(char *property, PRBool oldValue, PRBool newValue) +{ + nsCOMPtr supports; + if(NS_SUCCEEDED(QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(supports)))) + { + PRInt32 i; + for(i = 0; i < mListeners->Count(); i++) + { + //Folderlistener's aren't refcounted. + nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i); + listener->OnItemBoolPropertyChanged(supports, property, oldValue, newValue); + } + + //Notify listeners who listen to every folder + nsresult rv; + NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv); + if(NS_SUCCEEDED(rv)) + mailSession->NotifyFolderItemBoolPropertyChanged(supports, property, oldValue, newValue); + + } + + return NS_OK; + +} + nsresult nsMsgFolder::NotifyPropertyFlagChanged(nsISupports *item, char *property, PRUint32 oldValue, PRUint32 newValue) { diff --git a/mailnews/base/util/nsMsgFolder.h b/mailnews/base/util/nsMsgFolder.h index 58ee0ae2179..345cf5d3de2 100644 --- a/mailnews/base/util/nsMsgFolder.h +++ b/mailnews/base/util/nsMsgFolder.h @@ -218,6 +218,8 @@ public: protected: nsresult NotifyPropertyChanged(char *property, char* oldValue, char* newValue); + nsresult NotifyIntPropertyChanged(char *property, PRInt32 oldValue, PRInt32 newValue); + nsresult NotifyBoolPropertyChanged(char *property, PRBool oldValue, PRBool newValue); nsresult NotifyPropertyFlagChanged(nsISupports *item, char *property, PRUint32 oldValue, PRUint32 newValue); nsresult NotifyItemAdded(nsISupports *parentItem, nsISupports *item, const char *viewString); diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 08736bc0c27..51708e61532 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -777,20 +777,12 @@ NS_IMETHODIMP nsImapMailFolder::UpdateSummaryTotals(PRBool force) //Need to notify listeners that total count changed. if(oldTotalMessages != newTotalMessages) { - char *oldTotalMessagesStr = PR_smprintf("%d", oldTotalMessages); - char *totalMessagesStr = PR_smprintf("%d",newTotalMessages); - NotifyPropertyChanged("TotalMessages", oldTotalMessagesStr, totalMessagesStr); - PR_smprintf_free(totalMessagesStr); - PR_smprintf_free(oldTotalMessagesStr); + NotifyIntPropertyChanged("TotalMessages", oldTotalMessages, newTotalMessages); } if(oldUnreadMessages != newUnreadMessages) { - char *oldUnreadMessagesStr = PR_smprintf("%d", oldUnreadMessages); - char *totalUnreadMessages = PR_smprintf("%d",newUnreadMessages); - NotifyPropertyChanged("TotalUnreadMessages", oldUnreadMessagesStr, totalUnreadMessages); - PR_smprintf_free(totalUnreadMessages); - PR_smprintf_free(oldUnreadMessagesStr); + NotifyIntPropertyChanged("TotalUnreadMessages", oldUnreadMessages, newUnreadMessages); } return rv; diff --git a/mailnews/local/src/nsLocalMailFolder.cpp b/mailnews/local/src/nsLocalMailFolder.cpp index 1c03763aaa1..f4725428caf 100644 --- a/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mailnews/local/src/nsLocalMailFolder.cpp @@ -878,20 +878,12 @@ NS_IMETHODIMP nsMsgLocalMailFolder::UpdateSummaryTotals(PRBool force) //Need to notify listeners that total count changed. if(oldTotalMessages != mNumTotalMessages) { - char *oldTotalMessagesStr = PR_smprintf("%d", oldTotalMessages); - char *totalMessagesStr = PR_smprintf("%d",mNumTotalMessages); - NotifyPropertyChanged("TotalMessages", oldTotalMessagesStr, totalMessagesStr); - PR_smprintf_free(totalMessagesStr); - PR_smprintf_free(oldTotalMessagesStr); + NotifyIntPropertyChanged("TotalMessages", oldTotalMessages, mNumTotalMessages); } if(oldUnreadMessages != mNumUnreadMessages) { - char *oldUnreadMessagesStr = PR_smprintf("%d", oldUnreadMessages); - char *totalUnreadMessages = PR_smprintf("%d",mNumUnreadMessages); - NotifyPropertyChanged("TotalUnreadMessages", oldUnreadMessagesStr, totalUnreadMessages); - PR_smprintf_free(totalUnreadMessages); - PR_smprintf_free(oldUnreadMessagesStr); + NotifyIntPropertyChanged("TotalUnreadMessages", oldUnreadMessages, mNumUnreadMessages); } return NS_OK; diff --git a/mailnews/news/src/nsNewsFolder.cpp b/mailnews/news/src/nsNewsFolder.cpp index 71bb7d59df6..98e0883c753 100644 --- a/mailnews/news/src/nsNewsFolder.cpp +++ b/mailnews/news/src/nsNewsFolder.cpp @@ -229,6 +229,7 @@ nsMsgNewsFolder::AddSubfolder(nsAutoString name, nsIMsgFolder **child, char *set nsCOMPtr folderSupports(do_QueryInterface(folder)); if(folderSupports) mSubFolders->AppendElement(folderSupports); + folder->SetParent(this); *child = folder; folder->SetParent(this); NS_ADDREF(*child); @@ -716,20 +717,12 @@ NS_IMETHODIMP nsMsgNewsFolder::UpdateSummaryTotals(PRBool force) //Need to notify listeners that total count changed. if(oldTotalMessages != mNumTotalMessages) { - char *oldTotalMessagesStr = PR_smprintf("%d", oldTotalMessages); - char *totalMessagesStr = PR_smprintf("%d",mNumTotalMessages); - NotifyPropertyChanged("TotalMessages", oldTotalMessagesStr, totalMessagesStr); - PR_FREEIF(totalMessagesStr); - PR_FREEIF(oldTotalMessagesStr); + NotifyIntPropertyChanged("TotalMessages", oldTotalMessages, mNumTotalMessages); } if(oldUnreadMessages != mNumUnreadMessages) { - char *oldUnreadMessagesStr = PR_smprintf("%d", oldUnreadMessages); - char *totalUnreadMessages = PR_smprintf("%d",mNumUnreadMessages); - NotifyPropertyChanged("TotalUnreadMessages", oldUnreadMessagesStr, totalUnreadMessages); - PR_FREEIF(totalUnreadMessages); - PR_FREEIF(oldUnreadMessagesStr); + NotifyIntPropertyChanged("TotalUnreadMessages", oldUnreadMessages, mNumUnreadMessages); } return NS_OK; diff --git a/suite/locales/en-US/chrome/mailnews/messenger.dtd b/suite/locales/en-US/chrome/mailnews/messenger.dtd index e9fe3d28c25..519711d2503 100644 --- a/suite/locales/en-US/chrome/mailnews/messenger.dtd +++ b/suite/locales/en-US/chrome/mailnews/messenger.dtd @@ -250,6 +250,8 @@ Rights Reserved. + +