diff --git a/mailnews/base/public/nsIFolderListener.idl b/mailnews/base/public/nsIFolderListener.idl index f576033d9468..af098909167d 100644 --- a/mailnews/base/public/nsIFolderListener.idl +++ b/mailnews/base/public/nsIFolderListener.idl @@ -27,8 +27,8 @@ interface nsIFolder; [scriptable, uuid(1c5ef9f0-d1c0-11d2-94CA-006097222B83)] /* XXX regenerate */ interface nsIFolderListener : nsISupports { - void OnItemAdded(in nsIFolder parentFolder, in nsISupports item); - void OnItemRemoved(in nsIFolder parentFolder, in nsISupports item); + 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 OnItemPropertyFlagChanged(in nsISupports item, in string property, in unsigned long oldFlag, in unsigned long newFlag); diff --git a/mailnews/base/public/nsIMsgMailSession.idl b/mailnews/base/public/nsIMsgMailSession.idl index c70a0bcd9b84..8f6e78cab4e4 100644 --- a/mailnews/base/public/nsIMsgMailSession.idl +++ b/mailnews/base/public/nsIMsgMailSession.idl @@ -62,8 +62,8 @@ interface nsIMsgMailSession : nsISupports { in unsigned long oldValue, in unsigned long newValue); - void NotifyFolderItemAdded(in nsIFolder folder, in nsISupports item); - void NotifyFolderItemDeleted(in nsIFolder folder, in nsISupports item); + void NotifyFolderItemAdded(in nsISupports parentItem, in nsISupports item, in string viewString); + void NotifyFolderItemDeleted(in nsISupports parentItem, in nsISupports item, in string viewString); void NotifyFolderLoaded(in nsIFolder folder); void AddMsgWindow(in nsIMsgWindow msgWindow); diff --git a/mailnews/base/resources/content/commandglue.js b/mailnews/base/resources/content/commandglue.js index 320d0de8a47b..33e7b2062f61 100644 --- a/mailnews/base/resources/content/commandglue.js +++ b/mailnews/base/resources/content/commandglue.js @@ -25,7 +25,7 @@ var msgComposeService = Components.classes['component://netscape/messengercompose'].getService(); -msgComposeService = msgComposeService.QueryInterface(Components.interfaces.nsIMsgComposeService); +msgComposeService = msgComposeService.QueryInterface(Components.interfaces.nsIMsgComposeService); var mailSession = Components.classes["component://netscape/messenger/services/session"].getService(Components.interfaces.nsIMsgMailSession); var accountManager = mailSession.accountManager; @@ -182,11 +182,13 @@ function ChangeFolderByDOMNode(folderNode) var uri = folderNode.getAttribute('id'); dump(uri + "\n"); + var isThreaded = folderNode.getAttribute('threaded'); + if (uri) - ChangeFolderByURI(uri); + ChangeFolderByURI(uri, isThreaded == "true", ""); } -function ChangeFolderByURI(uri) +function ChangeFolderByURI(uri, isThreaded, sortID) { dump('In ChangeFolderByURI\n'); var resource = RDF.GetResource(uri); @@ -205,6 +207,8 @@ function ChangeFolderByURI(uri) try { gCurrentLoadingFolderURI = uri; + gCurrentLoadingFolderIsThreaded = isThreaded; + gCurrentLoadingFolderSortID = sortID; msgfolder.startFolderLoading(); msgfolder.updateFolder(msgWindow); } @@ -215,20 +219,25 @@ function ChangeFolderByURI(uri) else { gCurrentLoadingFolderURI = ""; + gCurrentLoadingFolderIsThreaded = false; + gCurrentLoadingFolderSortID = ""; msgfolder.updateFolder(msgWindow); - RerootFolder(uri, msgfolder); + RerootFolder(uri, msgfolder, isThreaded, sortID); } } -function RerootFolder(uri, newFolder) +function RerootFolder(uri, newFolder, isThreaded, sortID) { - dump('In reroot folder\n'); + dump('In reroot folder\n'); var folder = GetThreadTreeFolder(); ClearThreadTreeSelection(); //Set the window's new open folder. msgWindow.openFolder = newFolder; + //Set threaded state + ShowThreads(isThreaded); + folder.setAttribute('ref', uri); var afterFolderLoadTime = new Date(); @@ -438,6 +447,8 @@ function IsSpecialFolderSelected(folderName) function ChangeThreadView() { + var folder = GetSelectedFolder(); + var threadColumn = document.getElementById('ThreadColumnHeader'); if(threadColumn) { @@ -445,10 +456,14 @@ function ChangeThreadView() if(currentView== 'threaded') { ShowThreads(false); + if(folder) + folder.setAttribute('threaded', ""); } else if(currentView == 'unthreaded') { ShowThreads(true); + if(folder) + folder.setAttribute('threaded', "true"); } RefreshThreadTreeView(); } diff --git a/mailnews/base/resources/content/folderPane.xul b/mailnews/base/resources/content/folderPane.xul index 505828f57738..c3981654189f 100644 --- a/mailnews/base/resources/content/folderPane.xul +++ b/mailnews/base/resources/content/folderPane.xul @@ -40,7 +40,8 @@ SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder" 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"> + ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType" + persist="threaded"> diff --git a/mailnews/base/resources/content/msgMail3PaneWindow.js b/mailnews/base/resources/content/msgMail3PaneWindow.js index 197b98035b75..88dc88835c3b 100644 --- a/mailnews/base/resources/content/msgMail3PaneWindow.js +++ b/mailnews/base/resources/content/msgMail3PaneWindow.js @@ -35,7 +35,9 @@ var messageDSProgID = datasourceProgIDPrefix + "mailnewsmessages"; var gFolderTree; var gThreadTree; -var gCurrentLoadingFolderURI +var gCurrentLoadingFolderURI; +var gCurrentLoadingFolderIsThreaded = false; +var gCurrentLoadingFolderSortID =""; // get the messenger instance var messenger = Components.classes[messengerProgID].createInstance(); @@ -60,9 +62,9 @@ msgWindow = msgWindow.QueryInterface(Components.interfaces.nsIMsgWindow); // the folderListener object var folderListener = { - OnItemAdded: function(parentFolder, item) {}, + OnItemAdded: function(parentItem, item, view) {}, - OnItemRemoved: function(parentFolder, item){}, + OnItemRemoved: function(parentItem, item, view){}, OnItemPropertyChanged: function(item, property, oldValue, newValue) {}, @@ -85,7 +87,9 @@ var folderListener = { { msgFolder.endFolderLoading(); dump("before reroot in OnFolderLoaded\n"); - RerootFolder(uri, msgFolder); + RerootFolder(uri, msgFolder, gCurrentLoadingFolderIsThreaded, gCurrentLoadingFolderSortID); + gCurrentLoadingFolderIsThreaded = FALSE; + gCurrentLoadingFolderSortID = ""; } } } @@ -204,7 +208,7 @@ function loadStartFolder() var pref = Components.classes[prefProgID].getService(Components.interfaces.nsIPref); var startFolder = pref.CopyCharPref("mailnews.start_folder"); - ChangeFolderByURI(startFolder); + //ChangeFolderByURI(startFolder); // var folder = OpenFolderTreeToFolder(startFolder); } catch(ex) { @@ -391,4 +395,14 @@ function StopUrls() msgWindow.StopUrls(); } +function GetSelectedFolder() +{ + var tree = GetFolderTree(); + var selection = tree.selectedItems; + if(selection.length > 0) + return selection[0]; + else + return null; + +} diff --git a/mailnews/base/src/nsMsgFolderDataSource.cpp b/mailnews/base/src/nsMsgFolderDataSource.cpp index 1b47682ce7ff..bdcb349e09a3 100644 --- a/mailnews/base/src/nsMsgFolderDataSource.cpp +++ b/mailnews/base/src/nsMsgFolderDataSource.cpp @@ -322,12 +322,7 @@ NS_IMETHODIMP nsMsgFolderDataSource::GetTargets(nsIRDFResource* source, else if ((kNC_MessageChild == property)) { PRBool showThreads; - nsCOMPtr messageView; - rv = mWindow->GetMessageView(getter_AddRefs(messageView)); - if(NS_FAILED(rv)) return rv; - - rv = messageView->GetShowThreads(&showThreads); - if(NS_FAILED(rv)) return rv; + GetIsThreaded(&showThreads); if(showThreads) { @@ -349,12 +344,10 @@ NS_IMETHODIMP nsMsgFolderDataSource::GetTargets(nsIRDFResource* source, if (NS_SUCCEEDED(rv)) { PRUint32 viewType; - nsCOMPtr messageView; - rv = mWindow->GetMessageView(getter_AddRefs(messageView)); - if(NS_FAILED(rv)) return rv; + rv = GetViewType(&viewType); + if(NS_FAILED(rv)) + return rv; - rv = messageView->GetViewType(&viewType); - if(NS_FAILED(rv)) return rv; nsMessageViewMessageEnumerator * messageEnumerator = new nsMessageViewMessageEnumerator(messages, viewType); if(!messageEnumerator) @@ -656,67 +649,63 @@ nsMsgFolderDataSource::DoCommand(nsISupportsArray/**/* aSources, return NS_OK; } -NS_IMETHODIMP nsMsgFolderDataSource::OnItemAdded(nsIFolder *parentFolder, nsISupports *item) +NS_IMETHODIMP nsMsgFolderDataSource::OnItemAdded(nsISupports *parentItem, nsISupports *item, const char* viewString) +{ + return OnItemAddedOrRemoved(parentItem, item, viewString, PR_TRUE); +} + +NS_IMETHODIMP nsMsgFolderDataSource::OnItemRemoved(nsISupports *parentItem, nsISupports *item, const char* viewString) +{ + return OnItemAddedOrRemoved(parentItem, item, viewString, PR_FALSE); +} + +nsresult nsMsgFolderDataSource::OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, const char* viewString, PRBool added) { nsresult rv; nsCOMPtr message; nsCOMPtr folder; nsCOMPtr parentResource; + nsCOMPtr parentFolder; - if(NS_SUCCEEDED(parentFolder->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(parentResource)))) + parentFolder = do_QueryInterface(parentItem); + //If the parent isn't a folder then we don't handle it. + if(!parentFolder) + return NS_OK; + + parentResource = do_QueryInterface(parentItem); + //If it's not a resource, we don't handle it either + if(!parentResource) + return NS_OK; + + //If it is a message + if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(message)))) { - //If we are adding a message - if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(message)))) + //If we're in a threaded view only do this if the view passed in is the thread view. Or if we're in + //a non threaded view only do this if the view passed in is the flat view. + + PRBool isThreaded, isThreadNotification; + GetIsThreaded(&isThreaded); + isThreadNotification = PL_strcmp(viewString, "threadMessageView") == 0; + + if((isThreaded && isThreadNotification) || + (!isThreaded && !isThreadNotification)) { nsCOMPtr itemNode(do_QueryInterface(item, &rv)); if(NS_SUCCEEDED(rv)) { - //Notify folders that a message was added. - NotifyObservers(parentResource, kNC_MessageChild, itemNode, PR_TRUE); - } - } - //If we are adding a folder - else if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folder)))) - { - nsCOMPtr itemNode(do_QueryInterface(item, &rv)); - if(NS_SUCCEEDED(rv)) - { - //Notify folders that a message was added. - NotifyObservers(parentResource, kNC_Child, itemNode, PR_TRUE); + //Notify folders that a message was added or deleted. + NotifyObservers(parentResource, kNC_MessageChild, itemNode, added); } } } - return NS_OK; -} - -NS_IMETHODIMP nsMsgFolderDataSource::OnItemRemoved(nsIFolder *parentFolder, nsISupports *item) -{ - nsresult rv; - nsCOMPtr message; - nsCOMPtr folder; - nsCOMPtr parentResource; - - if(NS_SUCCEEDED(parentFolder->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(parentResource)))) + //If we are doing this to a folder + else if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folder)))) { - //If we are removing a message - if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(message)))) + nsCOMPtr itemNode(do_QueryInterface(item, &rv)); + if(NS_SUCCEEDED(rv)) { - nsCOMPtr itemNode(do_QueryInterface(item, &rv)); - if(NS_SUCCEEDED(rv)) - { - //Notify folders that a message was deleted. - NotifyObservers(parentResource, kNC_MessageChild, itemNode, PR_FALSE); - } - } - //If we are removing a folder - else if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folder)))) - { - nsCOMPtr itemNode(do_QueryInterface(item, &rv)); - if(NS_SUCCEEDED(rv)) - { - //Notify folders that a message was deleted. - NotifyObservers(parentResource, kNC_Child, itemNode, PR_FALSE); - } + //Notify folders that a message was added or deleted. + NotifyObservers(parentResource, kNC_Child, itemNode, added); } } return NS_OK; diff --git a/mailnews/base/src/nsMsgFolderDataSource.h b/mailnews/base/src/nsMsgFolderDataSource.h index d28008d86ca0..829e1475d941 100644 --- a/mailnews/base/src/nsMsgFolderDataSource.h +++ b/mailnews/base/src/nsMsgFolderDataSource.h @@ -157,6 +157,9 @@ protected: nsresult CreateArcsOutEnumerator(); + nsresult OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, + const char* viewString, PRBool added); + static nsIRDFResource* kNC_Child; static nsIRDFResource* kNC_MessageChild; static nsIRDFResource* kNC_Folder; diff --git a/mailnews/base/src/nsMsgMailSession.cpp b/mailnews/base/src/nsMsgMailSession.cpp index f80b7d85e9cd..7ed0a390e74b 100644 --- a/mailnews/base/src/nsMsgMailSession.cpp +++ b/mailnews/base/src/nsMsgMailSession.cpp @@ -198,7 +198,7 @@ nsMsgMailSession::NotifyFolderItemPropertyFlagChanged(nsISupports *item, } -NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemAdded(nsIFolder *folder, nsISupports *item) +NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemAdded(nsISupports *parentItem, nsISupports *item, const char* viewString) { nsresult rv; PRUint32 count; @@ -209,14 +209,14 @@ NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemAdded(nsIFolder *folder, nsISupp for(PRUint32 i = 0; i < count; i++) { nsCOMPtr listener = getter_AddRefs((nsIFolderListener*)mListeners->ElementAt(i)); - listener->OnItemAdded(folder, item); + listener->OnItemAdded(parentItem, item, viewString); } return NS_OK; } -NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemDeleted(nsIFolder *folder, nsISupports *item) +NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString) { nsresult rv; PRUint32 count; @@ -227,7 +227,7 @@ NS_IMETHODIMP nsMsgMailSession::NotifyFolderItemDeleted(nsIFolder *folder, nsISu for(PRUint32 i = 0; i < count; i++) { nsCOMPtr listener = getter_AddRefs((nsIFolderListener*)mListeners->ElementAt(i)); - listener->OnItemRemoved(folder, item); + listener->OnItemRemoved(parentItem, item, viewString); } return NS_OK; diff --git a/mailnews/base/src/nsMsgMessageDataSource.cpp b/mailnews/base/src/nsMsgMessageDataSource.cpp index 573e6842ada2..7119e53aa266 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.cpp +++ b/mailnews/base/src/nsMsgMessageDataSource.cpp @@ -339,11 +339,7 @@ NS_IMETHODIMP nsMsgMessageDataSource::GetTargets(nsIRDFResource* source, nsCOMPtr converter; NS_NewMessageFromMsgHdrEnumerator(messages, msgfolder, getter_AddRefs(converter)); PRUint32 viewType; - nsCOMPtr messageView; - rv = mWindow->GetMessageView(getter_AddRefs(messageView)); - if(NS_FAILED(rv)) return rv; - - rv = messageView->GetViewType(&viewType); + rv = GetViewType(&viewType); if(NS_FAILED(rv)) return rv; nsMessageViewMessageEnumerator * messageEnumerator = @@ -569,14 +565,55 @@ nsMsgMessageDataSource::DoCommand(nsISupportsArray/**/* aSources return NS_OK; } -NS_IMETHODIMP nsMsgMessageDataSource::OnItemAdded(nsIFolder *parentFolder, nsISupports *item) +NS_IMETHODIMP nsMsgMessageDataSource::OnItemAdded(nsISupports *parentItem, nsISupports *item, const char *viewString) { - return NS_OK; + return OnItemAddedOrRemoved(parentItem, item, viewString, PR_TRUE); } -NS_IMETHODIMP nsMsgMessageDataSource::OnItemRemoved(nsIFolder *parentFolder, nsISupports *item) +NS_IMETHODIMP nsMsgMessageDataSource::OnItemRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString) { - return NS_OK; + return OnItemAddedOrRemoved(parentItem, item, viewString, PR_FALSE); +} + +nsresult nsMsgMessageDataSource::OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString, PRBool added) +{ + + nsresult rv; + nsCOMPtr message; + nsCOMPtr parentResource; + nsCOMPtr parentMessage; + + parentMessage = do_QueryInterface(parentItem); + //If the parent isn't a message then we don't handle it. + if(!parentMessage) + return NS_OK; + + parentResource = do_QueryInterface(parentItem); + //If it's not a resource, we don't handle it either + if(!parentResource) + return NS_OK; + + //If we are removing a message + if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(message)))) + { + //We only handle threaded views + + PRBool isThreaded, isThreadNotification; + GetIsThreaded(&isThreaded); + isThreadNotification = PL_strcmp(viewString, "threadMessageView") == 0; + + if((isThreaded && isThreadNotification)) + { + nsCOMPtr itemNode(do_QueryInterface(item, &rv)); + if(NS_SUCCEEDED(rv)) + { + //Notify folders that a message was deleted. + NotifyObservers(parentResource, kNC_MessageChild, itemNode, added); + } + } + } + return NS_OK; + } NS_IMETHODIMP nsMsgMessageDataSource::OnItemPropertyChanged(nsISupports *item, const char *property, @@ -1009,17 +1046,6 @@ nsMsgMessageDataSource::createMessageMessageChildNode(nsIMessage *message, } -nsresult -nsMsgMessageDataSource::GetIsThreaded(PRBool *threaded) -{ - nsresult rv; - nsCOMPtr messageView; - rv = mWindow->GetMessageView(getter_AddRefs(messageView)); - if (NS_FAILED(rv)) return rv; - - return messageView->GetShowThreads(threaded); -} - nsresult nsMsgMessageDataSource::GetMessageFolderAndThread(nsIMessage *message, nsIMsgFolder **folder, nsIMsgThread **thread) @@ -1142,13 +1168,47 @@ nsresult nsMsgMessageDataSource::DoMessageHasAssertion(nsIMessage *message, nsIR if(!hasAssertion) return NS_ERROR_NULL_POINTER; + *hasAssertion = PR_FALSE; + //We're not keeping track of negative assertions on messages. if(!tv) { - *hasAssertion = PR_FALSE; return NS_OK; } + //first check to see if message child property + if(kNC_MessageChild == property) + { + PRBool isThreaded; + GetIsThreaded(&isThreaded); + + //We only care if we're in the threaded view. Otherwise just say we don't have the assertion. + if(isThreaded) + { + //If the message is the threadParent of the target then it has the assertion. Otherwise it doesn't + + nsCOMPtr childMessage = do_QueryInterface(target); + if(!childMessage) + return NS_OK; + + nsMsgKey threadParent, msgKey; + rv = message->GetMessageKey(&msgKey); + if(NS_FAILED(rv)) + return rv; + + rv = childMessage->GetThreadParent(&threadParent); + if(NS_FAILED(rv)) + return rv; + + *hasAssertion = (msgKey == threadParent); + return NS_OK; + } + else + { + return NS_OK; + } + + } nsCOMPtr messageResource(do_QueryInterface(message, &rv)); if(NS_FAILED(rv)) diff --git a/mailnews/base/src/nsMsgMessageDataSource.h b/mailnews/base/src/nsMsgMessageDataSource.h index afaaa6fa1896..b3da6f006ded 100644 --- a/mailnews/base/src/nsMsgMessageDataSource.h +++ b/mailnews/base/src/nsMsgMessageDataSource.h @@ -113,7 +113,6 @@ public: protected: nsresult GetSenderName(nsAutoString& sender, nsAutoString *senderUserName); - nsresult GetIsThreaded(PRBool *threaded); nsresult createMessageNode(nsIMessage *message, nsIRDFResource *property, nsIRDFNode **target); @@ -168,6 +167,9 @@ protected: nsresult CreateLiterals(nsIRDFService *rdf); nsresult CreateArcsOutEnumerators(); + nsresult OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString, + PRBool added); + static nsIRDFResource* kNC_Subject; static nsIRDFResource* kNC_SubjectCollation; static nsIRDFResource* kNC_Sender; diff --git a/mailnews/base/src/nsMsgNotificationManager.cpp b/mailnews/base/src/nsMsgNotificationManager.cpp index 0c944a90660d..48c0efcdf27c 100644 --- a/mailnews/base/src/nsMsgNotificationManager.cpp +++ b/mailnews/base/src/nsMsgNotificationManager.cpp @@ -148,12 +148,12 @@ nsresult nsMsgNotificationManager::Init() } -NS_IMETHODIMP nsMsgNotificationManager::OnItemAdded(nsIFolder *parentFolder, nsISupports *item) +NS_IMETHODIMP nsMsgNotificationManager::OnItemAdded(nsISupports *parentItem, nsISupports *item, const char* viewString) { return NS_OK; } -NS_IMETHODIMP nsMsgNotificationManager::OnItemRemoved(nsIFolder *parentFolder, nsISupports *item) +NS_IMETHODIMP nsMsgNotificationManager::OnItemRemoved(nsISupports *parentItem, nsISupports *item, const char* viewString) { return NS_OK; } diff --git a/mailnews/base/src/nsMsgRDFDataSource.cpp b/mailnews/base/src/nsMsgRDFDataSource.cpp index 16c69a74970a..8260a78e2d8e 100644 --- a/mailnews/base/src/nsMsgRDFDataSource.cpp +++ b/mailnews/base/src/nsMsgRDFDataSource.cpp @@ -313,6 +313,42 @@ NS_IMETHODIMP nsMsgRDFDataSource::SetWindow(nsIMsgWindow * aWindow) return NS_OK; } +nsresult +nsMsgRDFDataSource::GetIsThreaded(PRBool *threaded) +{ + nsresult rv; + if(!mWindow) + { + *threaded = PR_FALSE; + return NS_OK; + } + + nsCOMPtr messageView; + rv = mWindow->GetMessageView(getter_AddRefs(messageView)); + if (NS_FAILED(rv)) return rv; + + return messageView->GetShowThreads(threaded); +} + +nsresult +nsMsgRDFDataSource::GetViewType(PRUint32 *viewType) +{ + nsresult rv; + + if(!mWindow) + { + return NS_ERROR_NULL_POINTER; + } + + nsCOMPtr messageView; + rv = mWindow->GetMessageView(getter_AddRefs(messageView)); + if(NS_FAILED(rv)) return rv; + + rv = messageView->GetViewType(viewType); + return rv; + +} + nsIRDFService * nsMsgRDFDataSource::getRDFService() { diff --git a/mailnews/base/src/nsMsgRDFDataSource.h b/mailnews/base/src/nsMsgRDFDataSource.h index acae04babeca..e580c3bc3c5a 100644 --- a/mailnews/base/src/nsMsgRDFDataSource.h +++ b/mailnews/base/src/nsMsgRDFDataSource.h @@ -61,6 +61,8 @@ class nsMsgRDFDataSource : public nsIRDFDataSource, nsCOMPtr kEmptyArray; PRBool m_shuttingDown; + nsresult GetIsThreaded(PRBool *threaded); + nsresult GetViewType(PRUint32 *viewType); private: nsIRDFService *mRDFService; diff --git a/mailnews/base/util/nsMsgDBFolder.cpp b/mailnews/base/util/nsMsgDBFolder.cpp index b20d2b19d92c..6eb8be616db7 100644 --- a/mailnews/base/util/nsMsgDBFolder.cpp +++ b/mailnews/base/util/nsMsgDBFolder.cpp @@ -327,52 +327,95 @@ NS_IMETHODIMP nsMsgDBFolder::OnKeyChange(nsMsgKey aKeyChanged, PRUint32 aOldFlag NS_IMETHODIMP nsMsgDBFolder::OnKeyDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey, PRInt32 aFlags, nsIDBChangeListener * aInstigator) { - nsCOMPtr pMsgDBHdr; - nsresult rv = mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(pMsgDBHdr)); - if(NS_SUCCEEDED(rv) && pMsgDBHdr) - { - nsCOMPtr message; - rv = CreateMessageFromMsgDBHdr(pMsgDBHdr, getter_AddRefs(message)); - if(NS_SUCCEEDED(rv)) - { - nsCOMPtr msgSupports(do_QueryInterface(message, &rv)); - if(NS_SUCCEEDED(rv)) - { - NotifyItemDeleted(msgSupports); - } - UpdateSummaryTotals(PR_TRUE); - } - } - - return NS_OK; + //Do both flat and thread notifications + return OnKeyAddedOrDeleted(aKeyChanged, aParentKey, aFlags, aInstigator, PR_FALSE, PR_TRUE, PR_TRUE); } NS_IMETHODIMP nsMsgDBFolder::OnKeyAdded(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags, nsIDBChangeListener * aInstigator) { - nsresult rv; + //Do both flat and thread notifications + return OnKeyAddedOrDeleted(aKeyChanged, aParentKey, aFlags, aInstigator, PR_TRUE, PR_TRUE, PR_TRUE); +} + +nsresult nsMsgDBFolder::OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags, + nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread) +{ nsCOMPtr msgDBHdr; - rv = mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(msgDBHdr)); - if(NS_SUCCEEDED(rv) && msgDBHdr) + nsCOMPtr parentDBHdr; + nsresult rv = mDatabase->GetMsgHdrForKey(aKeyChanged, getter_AddRefs(msgDBHdr)); + if(NS_FAILED(rv)) + return rv; + + rv = mDatabase->GetMsgHdrForKey(aParentKey, getter_AddRefs(parentDBHdr)); + if(NS_FAILED(rv)) + return rv; + + if(msgDBHdr) { nsCOMPtr message; rv = CreateMessageFromMsgDBHdr(msgDBHdr, getter_AddRefs(message)); - if(NS_SUCCEEDED(rv)) + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr msgSupports(do_QueryInterface(message)); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(msgSupports && NS_SUCCEEDED(rv) && doFlat) { - nsCOMPtr msgSupports(do_QueryInterface(message)); - if(msgSupports) - { - NotifyItemAdded(msgSupports); - } - UpdateSummaryTotals(PR_TRUE); + if(added) + NotifyItemAdded(folderSupports, msgSupports, "flatMessageView"); + else + NotifyItemDeleted(folderSupports, msgSupports, "flatMessageView"); } + if(doThread) + { + if(parentDBHdr) + { + nsCOMPtr parentMessage; + rv = CreateMessageFromMsgDBHdr(parentDBHdr, getter_AddRefs(parentMessage)); + if(NS_FAILED(rv)) + return rv; + + nsCOMPtr parentSupports(do_QueryInterface(parentMessage)); + if(msgSupports && NS_SUCCEEDED(rv)) + { + if(added) + NotifyItemAdded(parentSupports, msgSupports, "threadMessageView"); + else + NotifyItemDeleted(parentSupports, msgSupports, "threadMessageView"); + + } + } + //if there's not a header then in threaded view the folder is the parent. + else + { + if(msgSupports && folderSupports) + { + if(added) + NotifyItemAdded(folderSupports, msgSupports, "threadMessageView"); + else + NotifyItemDeleted(folderSupports, msgSupports, "threadMessageView"); + } + } + } + UpdateSummaryTotals(PR_TRUE); } return NS_OK; + } + NS_IMETHODIMP nsMsgDBFolder::OnParentChanged(nsMsgKey aKeyChanged, nsMsgKey oldParent, nsMsgKey newParent, nsIDBChangeListener * aInstigator) { + //In reality we probably want to just change the parent because otherwise we will lose things like + //selection. + + //First delete the child from the old threadParent + OnKeyAddedOrDeleted(aKeyChanged, oldParent, 0, aInstigator, PR_FALSE, PR_FALSE, PR_TRUE); + //Then add it to the new threadParent + OnKeyAddedOrDeleted(aKeyChanged, newParent, 0, aInstigator, PR_TRUE, PR_FALSE, PR_TRUE); return NS_OK; } diff --git a/mailnews/base/util/nsMsgDBFolder.h b/mailnews/base/util/nsMsgDBFolder.h index 559f8af0423c..3260dddb172f 100644 --- a/mailnews/base/util/nsMsgDBFolder.h +++ b/mailnews/base/util/nsMsgDBFolder.h @@ -72,6 +72,8 @@ protected: virtual nsresult GetDatabase() = 0; virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags); nsresult ReadFromFolderCache(nsIMsgFolderCacheElement *element); + nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags, + nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread); protected: nsCOMPtr mDatabase; diff --git a/mailnews/base/util/nsMsgFolder.cpp b/mailnews/base/util/nsMsgFolder.cpp index 260e773e7058..c51da4f8271e 100644 --- a/mailnews/base/util/nsMsgFolder.cpp +++ b/mailnews/base/util/nsMsgFolder.cpp @@ -706,8 +706,10 @@ NS_IMETHODIMP nsMsgFolder::PropagateDelete(nsIMsgFolder *folder, PRBool deleteSt //Remove self as parent child->SetParent(nsnull); nsCOMPtr childSupports(do_QueryInterface(child)); - if(childSupports) - NotifyItemDeleted(childSupports); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) + NotifyItemDeleted(folderSupports, childSupports, "folderView"); break; } } @@ -744,8 +746,10 @@ NS_IMETHODIMP nsMsgFolder::RecursiveDelete(PRBool deleteStorage) mSubFolders->RemoveElement(child); // unlink it from this's child list child->SetParent(nsnull); nsCOMPtr childSupports(do_QueryInterface(child)); - if(childSupports) - NotifyItemDeleted(childSupports); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) + NotifyItemDeleted(folderSupports, childSupports, "folderView"); } cnt--; } @@ -1707,7 +1711,7 @@ nsresult nsMsgFolder::NotifyPropertyFlagChanged(nsISupports *item, char *propert return NS_OK; } -nsresult nsMsgFolder::NotifyItemAdded(nsISupports *item) +nsresult nsMsgFolder::NotifyItemAdded(nsISupports *parentItem, nsISupports *item, const char* viewString) { static PRBool notify = PR_TRUE; @@ -1719,20 +1723,20 @@ nsresult nsMsgFolder::NotifyItemAdded(nsISupports *item) { //Folderlistener's aren't refcounted. nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i); - listener->OnItemAdded(this, item); + listener->OnItemAdded(parentItem, item, viewString); } //Notify listeners who listen to every folder nsresult rv; NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv); if(NS_SUCCEEDED(rv)) - mailSession->NotifyFolderItemAdded(this, item); + mailSession->NotifyFolderItemAdded(parentItem, item, viewString); return NS_OK; } -nsresult nsMsgFolder::NotifyItemDeleted(nsISupports *item) +nsresult nsMsgFolder::NotifyItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString) { PRInt32 i; @@ -1740,13 +1744,13 @@ nsresult nsMsgFolder::NotifyItemDeleted(nsISupports *item) { //Folderlistener's aren't refcounted. nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i); - listener->OnItemRemoved(this, item); + listener->OnItemRemoved(parentItem, item, viewString); } //Notify listeners who listen to every folder nsresult rv; NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv); if(NS_SUCCEEDED(rv)) - mailSession->NotifyFolderItemDeleted(this, item); + mailSession->NotifyFolderItemDeleted(parentItem, item, viewString); return NS_OK; diff --git a/mailnews/base/util/nsMsgFolder.h b/mailnews/base/util/nsMsgFolder.h index dd1d48c24b9a..766f4627b546 100644 --- a/mailnews/base/util/nsMsgFolder.h +++ b/mailnews/base/util/nsMsgFolder.h @@ -219,8 +219,8 @@ protected: nsresult NotifyPropertyChanged(char *property, char* oldValue, char* newValue); nsresult NotifyPropertyFlagChanged(nsISupports *item, char *property, PRUint32 oldValue, PRUint32 newValue); - nsresult NotifyItemAdded(nsISupports *item); - nsresult NotifyItemDeleted(nsISupports *item); + nsresult NotifyItemAdded(nsISupports *parentItem, nsISupports *item, const char *viewString); + nsresult NotifyItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString); nsresult NotifyFolderLoaded(); // this is a little helper function that is not part of the public interface. diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index 8067a09db7aa..763842a4f4ef 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -586,11 +586,15 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName } if(NS_SUCCEEDED(rv) && child) { - nsCOMPtr folderSupports = do_QueryInterface(child, &rv); - if(NS_SUCCEEDED(rv)) - NotifyItemAdded(folderSupports); - } + nsCOMPtr childSupports(do_QueryInterface(child)); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) + { + NotifyItemAdded(folderSupports, childSupports, "folderView"); + } + } return rv; } diff --git a/mailnews/local/src/nsLocalMailFolder.cpp b/mailnews/local/src/nsLocalMailFolder.cpp index b8f7d49cda95..b80f55b698df 100644 --- a/mailnews/local/src/nsLocalMailFolder.cpp +++ b/mailnews/local/src/nsLocalMailFolder.cpp @@ -671,11 +671,13 @@ nsMsgLocalMailFolder::CreateSubfolder(const char *folderName) } if(rv == NS_OK && child) { - nsCOMPtr folderSupports(do_QueryInterface(child, &rv)); - - if(NS_SUCCEEDED(rv)) + nsCOMPtr childSupports(do_QueryInterface(child)); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) { - NotifyItemAdded(folderSupports); + + NotifyItemAdded(folderSupports, childSupports, "folderView"); } } return rv; diff --git a/mailnews/news/src/nsNewsFolder.cpp b/mailnews/news/src/nsNewsFolder.cpp index f3267db82018..680fccc2eed0 100644 --- a/mailnews/news/src/nsNewsFolder.cpp +++ b/mailnews/news/src/nsNewsFolder.cpp @@ -484,11 +484,13 @@ NS_IMETHODIMP nsMsgNewsFolder::CreateSubfolder(const char *newsgroupname) } if(NS_SUCCEEDED(rv) && child) { - nsCOMPtr folderSupports(do_QueryInterface(child, &rv)); - - if(NS_SUCCEEDED(rv)) + nsCOMPtr childSupports(do_QueryInterface(child)); + nsCOMPtr folderSupports; + rv = QueryInterface(nsCOMTypeInfo::GetIID(), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) { - NotifyItemAdded(folderSupports); + + NotifyItemAdded(folderSupports, childSupports, "folderView"); } } return rv;