From 533c46ea39c94091529c9d0602afa34364c2e2d2 Mon Sep 17 00:00:00 2001 From: "sspitzer%netscape.com" Date: Thu, 1 Jun 2000 02:41:03 +0000 Subject: [PATCH] fix for a bunch of subscribe problems. #39263, imap subscribe only working to the second level deep #40238, subscribed imap folders not showing up as subscribed. #39261, imap folders showing up as full paths, not leaf names. r=mscott --- .../base/public/nsISubscribableServer.idl | 7 +- mailnews/base/resources/content/subscribe.js | 49 ++++-- mailnews/base/resources/content/subscribe.xul | 2 +- mailnews/base/src/nsSubscribableServer.cpp | 140 ++++++++++++++++-- mailnews/base/src/nsSubscribableServer.h | 2 + .../imap/public/nsIImapIncomingServer.idl | 2 + mailnews/imap/public/nsIImapService.idl | 3 + mailnews/imap/src/nsImapIncomingServer.cpp | 85 ++++++++++- mailnews/imap/src/nsImapIncomingServer.h | 2 + mailnews/imap/src/nsImapProtocol.cpp | 8 + mailnews/imap/src/nsImapService.cpp | 51 ++++++- mailnews/news/src/nsNntpIncomingServer.cpp | 54 ++++++- 12 files changed, 358 insertions(+), 47 deletions(-) diff --git a/mailnews/base/public/nsISubscribableServer.idl b/mailnews/base/public/nsISubscribableServer.idl index f98ce2302124..816d803a11d7 100644 --- a/mailnews/base/public/nsISubscribableServer.idl +++ b/mailnews/base/public/nsISubscribableServer.idl @@ -37,15 +37,18 @@ interface nsISubscribableServer : nsISupports { void setIncomingServer(in nsIMsgIncomingServer server); void setDelimiter(in char delimiter); void populateSubscribeDatasource(in nsIMsgWindow aMsgWindow, in boolean forceToServer); + void populateSubscribeDatasourceWithName(in nsIMsgWindow aMsgWindow, in boolean forceToServer, in string name); attribute nsISubscribeListener subscribeListener; void startPopulatingSubscribeDS(); void stopPopulatingSubscribeDS(); void findAndAddParentToSubscribeDS(in string uri, in string serverUri, in string aName, in nsIRDFResource aChildResource); - void setPropertiesInSubscribeDS(in string uri, in wstring aName, in nsIRDFResource aResource); - void addToSubscribeDS(in string aName); + void setPropertiesInSubscribeDS(in string uri, in wstring aName, in nsIRDFResource aResource, in boolean subscribed, in boolean changeIfExists); + void addToSubscribeDS(in string aName, in boolean addAsSubscribed, in boolean changeIfExists); void setAsSubscribedInSubscribeDS(in string aURI); void updateSubscribedInSubscribeDS(); void subscribe(in wstring name); void unsubscribe(in wstring name); + void setShowFullName(in boolean showFullName); + void subscribeCleanup(); }; diff --git a/mailnews/base/resources/content/subscribe.js b/mailnews/base/resources/content/subscribe.js index ddea7fb9ade5..e7c730cc06ce 100644 --- a/mailnews/base/resources/content/subscribe.js +++ b/mailnews/base/resources/content/subscribe.js @@ -2,6 +2,7 @@ var gSubscribeTree = null; var okCallback = null; var gChangeTable = {}; var gServerURI = null; +var gSubscribableServer = null; var RDF = null; var gSubscribeDS = null; var gStatusBar = null; @@ -46,7 +47,7 @@ function SetServerTypeSpecificTextValues() element = document.getElementById("foldersheaderlabel"); element.setAttribute('value',stringval); - // XXX todo, fix this hack + // xxx todo, fix this hack // qi the server to get a nsISubscribable server // and ask it for the delimiter if (serverType == "nntp") { @@ -90,8 +91,17 @@ function SetUpServerMenu() var MySubscribeListener = { OnStopPopulating: function() { - //dump("root subscribe tree at: "+ gServerURI +"\n"); - gSubscribeTree.setAttribute('ref',gServerURI); + // only re-root the tree, if it is null. + // otherwise, we are in here because we are populating + // a part of the tree + + var refValue = gSubscribeTree.getAttribute('ref'); + //dump("ref = " + refValue + refValue.length + "\n"); + if (refValue == "null") { + dump("root subscribe tree at: "+ gServerURI +"\n"); + gSubscribeTree.setAttribute('ref',gServerURI); + } + // Turn progress meter off. gStatusBar.setAttribute("mode","normal"); } @@ -110,14 +120,14 @@ function SetUpTree(forceToServer) var server = folder.server; try { - subscribableServer = server.QueryInterface(Components.interfaces.nsISubscribableServer); + gSubscribableServer = server.QueryInterface(Components.interfaces.nsISubscribableServer); - subscribableServer.subscribeListener = MySubscribeListener; + gSubscribableServer.subscribeListener = MySubscribeListener; // Turn progress meter on. gStatusBar.setAttribute("mode","undetermined"); - subscribableServer.populateSubscribeDatasource(null /* eventually, a nsIMsgWindow */, forceToServer); + gSubscribableServer.populateSubscribeDatasource(null /* eventually, a nsIMsgWindow */, forceToServer); } catch (ex) { dump("failed to populate subscribe ds: " + ex + "\n"); @@ -128,7 +138,7 @@ function SubscribeOnLoad() { //dump("SubscribeOnLoad()\n"); - gSubscribeTree = document.getElementById('subscribetree'); + gSubscribeTree = document.getElementById('subscribetree'); gStatusBar = document.getElementById('statusbar-icon'); gNameField = document.getElementById('namefield'); @@ -153,11 +163,12 @@ function SubscribeOnLoad() //dump("folder="+folder+"\n"); //dump("folder.server="+folder.server+"\n"); try { - subscribableServer = folder.server.QueryInterface(Components.interfaces.nsISubscribableServer); + gSubscribableServer = folder.server.QueryInterface(Components.interfaces.nsISubscribableServer); gServerURI = folder.server.serverURI; } catch (ex) { dump("not a subscribable server\n"); + gSubscribableServer = null; gServerURI = null; } } @@ -191,6 +202,9 @@ function subscribeOK() if (top.okCallback) { top.okCallback(top.gServerURI,top.gChangeTable); } + if (gSubscribableServer) { + gSubscribableServer.subscribeCleanup(); + } return true; } @@ -198,6 +212,9 @@ function subscribeCancel() { //dump("in subscribeCancel()\n"); Stop(); + if (gSubscribableServer) { + gSubscribableServer.subscribeCleanup(); + } return true; } @@ -207,6 +224,7 @@ function SetState(uri,name,state,stateStr) if (!uri || !stateStr) return; try { + // xxx should we move this code into nsSubscribableServer.cpp? var src = RDF.GetResource(uri, true); var prop = RDF.GetResource("http://home.netscape.com/NC-rdf#Subscribed", true); var oldLiteral = gSubscribeDS.GetTarget(src, prop, true); @@ -306,7 +324,20 @@ function SubscribeOnClick(event) } else { var targetclass = event.target.getAttribute('class'); - if (targetclass != 'tree-cell-twisty') { + if (targetclass == 'tree-cell-twisty') { + var treeitem = event.target.parentNode.parentNode.parentNode; + var open = treeitem.getAttribute('open'); + if(open == "true") { + var name = treeitem.getAttribute("name"); + dump("do twisty for " + name +"\n"); + + // Turn progress meter on. + gStatusBar.setAttribute("mode","undetermined"); + + gSubscribableServer.populateSubscribeDatasourceWithName(null /* eventually, a nsIMsgWindow */, true /* force to server */, name); + } + } + else { var name = event.target.parentNode.parentNode.getAttribute('name'); gNameField.setAttribute('value',name); } diff --git a/mailnews/base/resources/content/subscribe.xul b/mailnews/base/resources/content/subscribe.xul index 1ea816f7d557..c9a998205927 100644 --- a/mailnews/base/resources/content/subscribe.xul +++ b/mailnews/base/resources/content/subscribe.xul @@ -89,7 +89,7 @@ Rights Reserved. - + diff --git a/mailnews/base/src/nsSubscribableServer.cpp b/mailnews/base/src/nsSubscribableServer.cpp index 3b79ff9761ef..50c55a39b8f5 100644 --- a/mailnews/base/src/nsSubscribableServer.cpp +++ b/mailnews/base/src/nsSubscribableServer.cpp @@ -38,6 +38,9 @@ #define DEBUG_SUBSCRIBE 1 #endif +#define TRUE_LITERAL_STR "true" +#define FALSE_LITERAL_STR "false" + static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); @@ -47,6 +50,7 @@ nsSubscribableServer::nsSubscribableServer(void) { NS_INIT_REFCNT(); mDelimiter = '.'; + mShowFullName = PR_TRUE; } nsSubscribableServer::~nsSubscribableServer(void) @@ -85,13 +89,23 @@ nsSubscribableServer::SetAsSubscribedInSubscribeDS(const char *aURI) if(NS_FAILED(rv)) return rv; if (!mSubscribeDatasource) return NS_ERROR_FAILURE; - nsCOMPtr oldLiteral; - rv = mSubscribeDatasource->GetTarget(resource, kNC_Subscribed, PR_TRUE, getter_AddRefs(oldLiteral)); + nsCOMPtr oldNode; + rv = mSubscribeDatasource->GetTarget(resource, kNC_Subscribed, PR_TRUE, getter_AddRefs(oldNode)); if(NS_FAILED(rv)) return rv; - rv = mSubscribeDatasource->Change(resource, kNC_Subscribed, oldLiteral, kTrueLiteral); + //check if literal is already true + nsCOMPtr oldLiteral = do_QueryInterface(oldNode); + if (!oldLiteral) return NS_ERROR_FAILURE; + const PRUnichar *subscribedLiteralStr; + rv = oldLiteral->GetValueConst(&subscribedLiteralStr); if(NS_FAILED(rv)) return rv; + // if it was already "true", do nothing + if (nsCRT::strcmp(subscribedLiteralStr,TRUE_LITERAL_STR)) { + rv = mSubscribeDatasource->Change(resource, kNC_Subscribed, oldNode, kTrueLiteral); + if(NS_FAILED(rv)) return rv; + } + return NS_OK; } @@ -148,7 +162,7 @@ nsresult CreateUnicodeStringFromUtf7(const char *aSourceString, PRUnichar **aUni return (convertedString) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } NS_IMETHODIMP -nsSubscribableServer::AddToSubscribeDS(const char *aName) +nsSubscribableServer::AddToSubscribeDS(const char *aName, PRBool addAsSubscribed, PRBool changeIfExists) { nsresult rv; @@ -156,7 +170,7 @@ nsSubscribableServer::AddToSubscribeDS(const char *aName) if (!aName) return NS_ERROR_FAILURE; #ifdef DEBUG_SUBSCRIBE - printf("AddToSubscribeDS(%s)\n",aName); + printf("AddToSubscribeDS(%s,%d,%d)\n",aName,addAsSubscribed,changeIfExists); #endif nsXPIDLCString serverUri; @@ -176,7 +190,7 @@ nsSubscribableServer::AddToSubscribeDS(const char *aName) rv = CreateUnicodeStringFromUtf7(aName, getter_Copies(unicodeName)); if (NS_FAILED(rv)) return rv; - rv = SetPropertiesInSubscribeDS((const char *) uri, (const PRUnichar *)unicodeName, resource); + rv = SetPropertiesInSubscribeDS((const char *) uri, (const PRUnichar *)unicodeName, resource, addAsSubscribed, changeIfExists); if (NS_FAILED(rv)) return rv; rv = FindAndAddParentToSubscribeDS((const char *) uri, (const char *)serverUri, aName, resource); @@ -186,23 +200,96 @@ nsSubscribableServer::AddToSubscribeDS(const char *aName) } NS_IMETHODIMP -nsSubscribableServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource) +nsSubscribableServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource, PRBool subscribed, PRBool changeIfExists) { nsresult rv; #ifdef DEBUG_SUBSCRIBE - printf("SetPropertiesInSubscribeDS(%s,??,??)\n",uri); + printf("SetPropertiesInSubscribeDS(%s,??,??,%d,%d)\n",uri,subscribed,changeIfExists); #endif nsCOMPtr nameLiteral; rv = mRDFService->GetLiteral(aName, getter_AddRefs(nameLiteral)); if(NS_FAILED(rv)) return rv; - rv = mSubscribeDatasource->Assert(aResource, kNC_Name, nameLiteral, PR_TRUE); + PRBool nameExists = PR_TRUE; + nsCOMPtr nameNode; + // should be HasAssertion(), since we don't need to get at the literal + rv = mSubscribeDatasource->GetTarget(aResource, kNC_Name, PR_TRUE, getter_AddRefs(nameNode)); if(NS_FAILED(rv)) return rv; + if ((!nameNode) && (rv == NS_RDF_NO_VALUE)) { + nameExists = PR_FALSE; + } - rv = mSubscribeDatasource->Assert(aResource, kNC_Subscribed, kFalseLiteral, PR_TRUE); + if (!nameExists) { + rv = mSubscribeDatasource->Assert(aResource, kNC_Name, nameLiteral, PR_TRUE); + if(NS_FAILED(rv)) return rv; + + if (mShowFullName) { + rv = mSubscribeDatasource->Assert(aResource, kNC_LeafName, nameLiteral, PR_TRUE); + if(NS_FAILED(rv)) return rv; + } + else { + nsAutoString leafStr(aName); + PRInt32 leafPos = leafStr.RFindChar(mDelimiter,PR_TRUE); + if (leafPos != -1) { + leafStr.Cut(0,leafPos + 1); + } + + nsCOMPtr leafLiteral; + rv = mRDFService->GetLiteral(leafStr.GetUnicode(), getter_AddRefs(leafLiteral)); + if(NS_FAILED(rv)) return rv; + + rv = mSubscribeDatasource->Assert(aResource, kNC_LeafName, leafLiteral, PR_TRUE); + if(NS_FAILED(rv)) return rv; + } + } + + PRBool subscribedExists = PR_TRUE; + nsCOMPtr subscribedNode; + rv = mSubscribeDatasource->GetTarget(aResource, kNC_Subscribed, PR_TRUE, getter_AddRefs(subscribedNode)); if(NS_FAILED(rv)) return rv; + if ((!subscribedNode) && (rv == NS_RDF_NO_VALUE)) { + subscribedExists = PR_FALSE; + } + + if (subscribed) { + if (!subscribedExists) { + rv = mSubscribeDatasource->Assert(aResource, kNC_Subscribed, kTrueLiteral, PR_TRUE); + if(NS_FAILED(rv)) return rv; + } + else if (changeIfExists) { + nsCOMPtr subscribedLiteral = do_QueryInterface(subscribedNode); + if (!subscribedLiteral) return NS_ERROR_FAILURE; + const PRUnichar *subscribedLiteralStr; + rv = subscribedLiteral->GetValueConst(&subscribedLiteralStr); + if(NS_FAILED(rv)) return rv; + + if (nsCRT::strcmp(subscribedLiteralStr,TRUE_LITERAL_STR)) { + rv = mSubscribeDatasource->Change(aResource, kNC_Subscribed, subscribedNode, kTrueLiteral); + if(NS_FAILED(rv)) return rv; + } + } + } + else { + if (!subscribedExists) { + rv = mSubscribeDatasource->Assert(aResource, kNC_Subscribed, kFalseLiteral, PR_TRUE); + if(NS_FAILED(rv)) return rv; + } + else if (changeIfExists) { + nsCOMPtr subscribedLiteral = do_QueryInterface(subscribedNode); + if (!subscribedLiteral) return NS_ERROR_FAILURE; + const PRUnichar *subscribedLiteralStr; + rv = subscribedLiteral->GetValueConst(&subscribedLiteralStr); + if(NS_FAILED(rv)) return rv; + + if (nsCRT::strcmp(subscribedLiteralStr,FALSE_LITERAL_STR)) { + rv = mSubscribeDatasource->Change(aResource, kNC_Subscribed, subscribedNode, kFalseLiteral); + if(NS_FAILED(rv)) return rv; + } + } + } + return rv; } @@ -258,7 +345,7 @@ nsSubscribableServer::FindAndAddParentToSubscribeDS(const char *uri, const char rv = CreateUnicodeStringFromUtf7((const char *)nameCStr, getter_Copies(unicodeName)); if (NS_FAILED(rv)) return rv; - rv = SetPropertiesInSubscribeDS((const char *)uriCStr, (const PRUnichar *)unicodeName, parentResource); + rv = SetPropertiesInSubscribeDS((const char *)uriCStr, (const PRUnichar *)unicodeName, parentResource, PR_FALSE, PR_FALSE /* change if exists */); if(NS_FAILED(rv)) return rv; } @@ -291,6 +378,7 @@ nsSubscribableServer::StopPopulatingSubscribeDS() mRDFService = nsnull; mSubscribeDatasource = nsnull; kNC_Name = nsnull; + kNC_LeafName = nsnull; kNC_Child = nsnull; kNC_Subscribed = nsnull; @@ -313,6 +401,10 @@ nsSubscribableServer::StartPopulatingSubscribeDS() NS_ASSERTION(NS_SUCCEEDED(rv) && kNC_Name,"no name resource"); if (NS_FAILED(rv)) return rv; + rv = mRDFService->GetResource("http://home.netscape.com/NC-rdf#LeafName", getter_AddRefs(kNC_LeafName)); + NS_ASSERTION(NS_SUCCEEDED(rv) && kNC_LeafName,"no leaf name resource"); + if (NS_FAILED(rv)) return rv; + rv = mRDFService->GetResource("http://home.netscape.com/NC-rdf#child", getter_AddRefs(kNC_Child)); NS_ASSERTION(NS_SUCCEEDED(rv) && kNC_Child,"no child resource"); if (NS_FAILED(rv)) return rv; @@ -322,12 +414,12 @@ nsSubscribableServer::StartPopulatingSubscribeDS() if (NS_FAILED(rv)) return rv; nsAutoString trueString; - trueString.AssignWithConversion("true"); + trueString.AssignWithConversion(TRUE_LITERAL_STR); rv = mRDFService->GetLiteral(trueString.GetUnicode(), getter_AddRefs(kTrueLiteral)); if(NS_FAILED(rv)) return rv; nsAutoString falseString; - falseString.AssignWithConversion("false"); + falseString.AssignWithConversion(FALSE_LITERAL_STR); rv = mRDFService->GetLiteral(falseString.GetUnicode(), getter_AddRefs(kFalseLiteral)); if(NS_FAILED(rv)) return rv; @@ -337,7 +429,6 @@ nsSubscribableServer::StartPopulatingSubscribeDS() NS_IMETHODIMP nsSubscribableServer::SetSubscribeListener(nsISubscribeListener *aListener) { - if (!aListener) return NS_ERROR_NULL_POINTER; mSubscribeListener = aListener; return NS_OK; } @@ -353,6 +444,20 @@ nsSubscribableServer::GetSubscribeListener(nsISubscribeListener **aListener) return NS_OK; } +NS_IMETHODIMP +nsSubscribableServer::SubscribeCleanup() +{ + NS_ASSERTION(PR_FALSE,"override this."); + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsSubscribableServer::PopulateSubscribeDatasourceWithName(nsIMsgWindow *aMsgWindow, PRBool aForceToServer, const char *name) +{ + NS_ASSERTION(PR_FALSE,"override this."); + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP nsSubscribableServer::PopulateSubscribeDatasource(nsIMsgWindow *aMsgWindow, PRBool aForceToServer) { @@ -373,3 +478,10 @@ nsSubscribableServer::Unsubscribe(const PRUnichar *aName) NS_ASSERTION(PR_FALSE,"override this."); return NS_ERROR_FAILURE; } + +NS_IMETHODIMP +nsSubscribableServer::SetShowFullName(PRBool showFullName) +{ + mShowFullName = showFullName; + return NS_OK; +} diff --git a/mailnews/base/src/nsSubscribableServer.h b/mailnews/base/src/nsSubscribableServer.h index f143b47285c9..ec7f422aea2e 100644 --- a/mailnews/base/src/nsSubscribableServer.h +++ b/mailnews/base/src/nsSubscribableServer.h @@ -45,12 +45,14 @@ private: nsCOMPtr mSubscribeDatasource; nsCOMPtr mRDFService; nsCOMPtr kNC_Name; + nsCOMPtr kNC_LeafName; nsCOMPtr kNC_Child; nsCOMPtr kNC_Subscribed; nsCOMPtr kTrueLiteral; nsCOMPtr kFalseLiteral; nsCOMPtr mIncomingServer; char mDelimiter; + PRBool mShowFullName; }; #endif // nsSubscribableServer_h__ diff --git a/mailnews/imap/public/nsIImapIncomingServer.idl b/mailnews/imap/public/nsIImapIncomingServer.idl index b4c037b1cc6f..8fa8c12203d0 100644 --- a/mailnews/imap/public/nsIImapIncomingServer.idl +++ b/mailnews/imap/public/nsIImapIncomingServer.idl @@ -72,4 +72,6 @@ interface nsIImapIncomingServer : nsISupports { void PseudoInterruptMsgLoad(in nsIImapUrl aImapUrl, out boolean interrupted); void ResetConnection(in string folderName); void CreatePRUnicharStringFromUTF7(in string aSourceString, out wstring aUnicodeStr); + + attribute boolean doingLsub; }; diff --git a/mailnews/imap/public/nsIImapService.idl b/mailnews/imap/public/nsIImapService.idl index 19d6a8a38021..d83583a9a198 100644 --- a/mailnews/imap/public/nsIImapService.idl +++ b/mailnews/imap/public/nsIImapService.idl @@ -140,11 +140,13 @@ interface nsIImapService : nsISupports void discoverChildren(in nsIEventQueue aClientEventQueue, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, + in string name, out nsIURI aURL); void discoverLevelChildren(in nsIEventQueue aClientEventQueue, in nsIMsgFolder aImapMailFolder, in nsIUrlListener aUrlListener, + in string name, in long aLevel, out nsIURI aURL); @@ -203,4 +205,5 @@ interface nsIImapService : nsISupports in nsIUrlListener aUrlListener); void buildSubscribeDatasource(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow); + void buildSubscribeDatasourceWithName(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow, in string name); }; diff --git a/mailnews/imap/src/nsImapIncomingServer.cpp b/mailnews/imap/src/nsImapIncomingServer.cpp index 9eb4a6b16988..b6881caf073c 100644 --- a/mailnews/imap/src/nsImapIncomingServer.cpp +++ b/mailnews/imap/src/nsImapIncomingServer.cpp @@ -91,6 +91,7 @@ nsImapIncomingServer::nsImapIncomingServer() m_waitingForConnectionInfo = PR_FALSE; m_redirectedLogonRetries = 0; mDoingSubscribeDialog = PR_FALSE; + mDoingLsub = PR_FALSE; } nsImapIncomingServer::~nsImapIncomingServer() @@ -630,6 +631,15 @@ NS_IMETHODIMP nsImapIncomingServer::ResetConnection(const char* folderName) return rv; } +NS_IMETHODIMP +nsImapIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow) +{ +#ifdef DEBUG_jefft + printf("jefft, implement me\n"); +#endif + return NS_OK; +} + NS_IMETHODIMP nsImapIncomingServer::PerformBiff() { nsresult rv; @@ -685,7 +695,7 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const char *folderPath, if (!folderPath || !*folderPath) return NS_ERROR_NULL_POINTER; if (mDoingSubscribeDialog) { - rv = AddToSubscribeDS(folderPath); + rv = AddToSubscribeDS(folderPath, mDoingLsub /* add as subscribed */, mDoingLsub /* change if exists */); return rv; } @@ -1828,6 +1838,29 @@ NS_IMETHODIMP nsImapIncomingServer::OnLogonRedirectionReply(const PRUnichar *pHo } +NS_IMETHODIMP +nsImapIncomingServer::PopulateSubscribeDatasourceWithName(nsIMsgWindow *aMsgWindow, PRBool aForceToServer /*ignored*/, const char *name) +{ + nsresult rv; +#ifdef DEBUG_sspitzer + printf("in PopulateSubscribeDatasourceWithName(%s)\n",name); +#endif + mDoingSubscribeDialog = PR_TRUE; + + // xxx todo can we do: rv = mInner->StartPopulatingSubscribeDS(); ? + rv = StartPopulatingSubscribeDS(); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr imapService = do_GetService(kImapServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + if (!imapService) return NS_ERROR_FAILURE; + + rv = imapService->BuildSubscribeDatasourceWithName(this, aMsgWindow, name); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + NS_IMETHODIMP nsImapIncomingServer::PopulateSubscribeDatasource(nsIMsgWindow *aMsgWindow, PRBool aForceToServer /*ignored*/) { @@ -1880,6 +1913,14 @@ nsImapIncomingServer::SetIncomingServer(nsIMsgIncomingServer *aServer) return mInner->SetIncomingServer(aServer); } +NS_IMETHODIMP +nsImapIncomingServer::SetShowFullName(PRBool showFullName) +{ + NS_ASSERTION(mInner,"not initialized"); + if (!mInner) return NS_ERROR_FAILURE; + return mInner->SetShowFullName(showFullName); +} + NS_IMETHODIMP nsImapIncomingServer::SetDelimiter(char aDelimiter) { @@ -1906,20 +1947,20 @@ nsImapIncomingServer::UpdateSubscribedInSubscribeDS() } NS_IMETHODIMP -nsImapIncomingServer::AddToSubscribeDS(const char *aName) +nsImapIncomingServer::AddToSubscribeDS(const char *aName, PRBool addAsSubscribed,PRBool changeIfExists) { NS_ASSERTION(mInner,"not initialized"); if (!mInner) return NS_ERROR_FAILURE; - return mInner->AddToSubscribeDS(aName); + return mInner->AddToSubscribeDS(aName, addAsSubscribed, changeIfExists); } NS_IMETHODIMP -nsImapIncomingServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource) +nsImapIncomingServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource, PRBool subscribed, PRBool changeIfExists) { NS_ASSERTION(mInner,"not initialized"); if (!mInner) return NS_ERROR_FAILURE; - return mInner->SetPropertiesInSubscribeDS(uri,aName,aResource); + return mInner->SetPropertiesInSubscribeDS(uri,aName,aResource,subscribed,changeIfExists); } NS_IMETHODIMP @@ -1948,7 +1989,20 @@ nsImapIncomingServer::StopPopulatingSubscribeDS() rv = mInner->StopPopulatingSubscribeDS(); if (NS_FAILED(rv)) return rv; - mInner = nsnull; + return NS_OK; +} + + +NS_IMETHODIMP +nsImapIncomingServer::SubscribeCleanup() +{ + nsresult rv; + if (mInner) { + rv = mInner->SetSubscribeListener(nsnull); + if (NS_FAILED(rv)) return rv; + + mInner = nsnull; + } return NS_OK; } @@ -1966,6 +2020,9 @@ nsImapIncomingServer::StartPopulatingSubscribeDS() rv = SetDelimiter('/'); // is this aways the case? need to talk to jefft if (NS_FAILED(rv)) return rv; + rv = SetShowFullName(PR_FALSE); + if (NS_FAILED(rv)) return rv; + return mInner->StartPopulatingSubscribeDS(); } @@ -2038,3 +2095,19 @@ nsImapIncomingServer::SubscribeToFolder(const PRUnichar *aName, PRBool subscribe if (NS_FAILED(rv)) return rv; return NS_OK; } + +NS_IMETHODIMP +nsImapIncomingServer::SetDoingLsub(PRBool doingLsub) +{ + mDoingLsub = doingLsub; + return NS_OK; +} + +NS_IMETHODIMP +nsImapIncomingServer::GetDoingLsub(PRBool *doingLsub) +{ + if (!doingLsub) return NS_ERROR_NULL_POINTER; + + *doingLsub = mDoingLsub; + return NS_OK; +} diff --git a/mailnews/imap/src/nsImapIncomingServer.h b/mailnews/imap/src/nsImapIncomingServer.h index adfdbe243f40..56d3fb50a8ad 100644 --- a/mailnews/imap/src/nsImapIncomingServer.h +++ b/mailnews/imap/src/nsImapIncomingServer.h @@ -59,6 +59,7 @@ public: NS_DECL_NSIURLLISTENER NS_IMETHOD PerformBiff(); + NS_IMETHOD PerformExpand(nsIMsgWindow *aMsgWindow); NS_IMETHOD CloseCachedConnections(); protected: @@ -92,6 +93,7 @@ private: // subscribe dialog stuff PRBool mDoingSubscribeDialog; + PRBool mDoingLsub; nsresult AddFolderToSubscribeDialog(const char *parentUri, const char *uri,const char *folderName); nsCOMPtr mInner; }; diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp index f1ef59e91bf0..7ff8c1e1b49a 100644 --- a/mailnews/imap/src/nsImapProtocol.cpp +++ b/mailnews/imap/src/nsImapProtocol.cpp @@ -5350,16 +5350,24 @@ void nsImapProtocol::DiscoverAllAndSubscribedBoxes() secondLevelPattern += delimiter; secondLevelPattern += '%'; } + + nsresult rv; + nsCOMPtr imapServer = do_QueryInterface(m_server, &rv); + if (NS_FAILED(rv) || !imapServer) return; + if (allPattern.Length()) { + imapServer->SetDoingLsub(PR_TRUE); Lsub(allPattern, PR_TRUE); // LSUB all the subscribed } if (topLevelPattern.Length()) { + imapServer->SetDoingLsub(PR_FALSE); List(topLevelPattern, PR_TRUE); // LIST the top level } if (secondLevelPattern.Length()) { + imapServer->SetDoingLsub(PR_FALSE); List(secondLevelPattern, PR_TRUE); // LIST the second level } } diff --git a/mailnews/imap/src/nsImapService.cpp b/mailnews/imap/src/nsImapService.cpp index b653729f27b0..828f105ab63e 100644 --- a/mailnews/imap/src/nsImapService.cpp +++ b/mailnews/imap/src/nsImapService.cpp @@ -1503,6 +1503,7 @@ NS_IMETHODIMP nsImapService::DiscoverChildren(nsIEventQueue* aClientEventQueue, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, + const char *folderName, nsIURI** aURL) { NS_ASSERTION (aImapMailFolder && aClientEventQueue, @@ -1523,15 +1524,13 @@ nsImapService::DiscoverChildren(nsIEventQueue* aClientEventQueue, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; - GetFolderName(aImapMailFolder, getter_Copies(folderName)); - if (nsCRT::strlen(folderName) > 0) + if (folderName && (nsCRT::strlen(folderName) > 0)) { nsCOMPtr uri = do_QueryInterface(aImapUrl); urlSpec.Append("/discoverchildren>"); urlSpec.AppendWithConversion(hierarchySeparator); - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); // mscott - this cast to a char * is okay...there's a bug in the XPIDL // compiler that is preventing in string parameters from showing up as // const char *. hopefully they will fix it soon. @@ -1554,6 +1553,7 @@ NS_IMETHODIMP nsImapService::DiscoverLevelChildren(nsIEventQueue* aClientEventQueue, nsIMsgFolder* aImapMailFolder, nsIUrlListener* aUrlListener, + const char *folderName, PRInt32 level, nsIURI** aURL) { @@ -1574,15 +1574,13 @@ nsImapService::DiscoverLevelChildren(nsIEventQueue* aClientEventQueue, if (NS_SUCCEEDED(rv)) { - nsXPIDLCString folderName; - GetFolderName(aImapMailFolder, getter_Copies(folderName)); - if (nsCRT::strlen(folderName) > 0) + if (folderName && (nsCRT::strlen(folderName) > 0)) { nsCOMPtr uri = do_QueryInterface(aImapUrl); urlSpec.Append("/discoverlevelchildren>"); urlSpec.AppendInt(level); urlSpec.AppendWithConversion(hierarchySeparator); // hierarchySeparator "/" - urlSpec.Append((const char *) folderName); + urlSpec.Append(folderName); rv = uri->SetSpec((char *) urlSpec.GetBuffer()); if (NS_SUCCEEDED(rv)) @@ -2759,6 +2757,43 @@ nsImapService::GetDefaultCopiesAndFoldersPrefsToServer(PRBool *aDefaultCopiesAnd return NS_OK; } +NS_IMETHODIMP +nsImapService::BuildSubscribeDatasourceWithName(nsIImapIncomingServer *aServer, nsIMsgWindow *aMsgWindow, const char *folderName) +{ + nsresult rv; + +#ifdef DEBUG_sspitzer + printf("BuildSubscribeDatasourceWithName(%s)\n",folderName); +#endif + nsCOMPtr server = do_QueryInterface(aServer); + if (!server) return NS_ERROR_FAILURE; + + nsCOMPtr rootFolder; + rv = server->GetRootFolder(getter_AddRefs(rootFolder)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr rootMsgFolder = do_QueryInterface(rootFolder, &rv); + if (NS_FAILED(rv)) return rv; + if (!rootMsgFolder) return NS_ERROR_FAILURE; + + nsCOMPtr listener = do_QueryInterface(aServer, &rv); + if (NS_FAILED(rv)) return rv; + if (!listener) return NS_ERROR_FAILURE; + + nsCOMPtr queue; + // get the Event Queue for this thread... + NS_WITH_SERVICE(nsIEventQueueService, pEventQService, kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + + rv = pEventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue)); + if (NS_FAILED(rv)) return rv; + + rv = DiscoverChildren(queue, rootMsgFolder, listener, folderName, nsnull); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + NS_IMETHODIMP nsImapService::BuildSubscribeDatasource(nsIImapIncomingServer *aServer, nsIMsgWindow *aMsgWindow) { diff --git a/mailnews/news/src/nsNntpIncomingServer.cpp b/mailnews/news/src/nsNntpIncomingServer.cpp index c95b1ed60a3a..8894e5ee3835 100644 --- a/mailnews/news/src/nsNntpIncomingServer.cpp +++ b/mailnews/news/src/nsNntpIncomingServer.cpp @@ -692,7 +692,7 @@ addGroupFunction(nsCString &aElement, void *aData) nsNntpIncomingServer *server; server = (nsNntpIncomingServer *)aData; - rv = server->AddToSubscribeDS((const char *)aElement); + rv = server->AddToSubscribeDS((const char *)aElement, PR_FALSE, PR_TRUE); NS_ASSERTION(NS_SUCCEEDED(rv),"AddToSubscribeDS failed"); return PR_TRUE; } @@ -814,6 +814,34 @@ nsNntpIncomingServer::PopulateSubscribeDatasourceFromHostInfo(nsIMsgWindow *aMsg return NS_OK; } +NS_IMETHODIMP +nsNntpIncomingServer::PopulateSubscribeDatasourceWithName(nsIMsgWindow *aMsgWindow, PRBool aForceToServer, const char *name) +{ + nsresult rv; + +#ifdef DEBUG_sspitzer + printf("PopulateSubscribeDatasourceWithName(%s)\n",name); +#endif + + rv = StopPopulatingSubscribeDS(); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + +NS_IMETHODIMP +nsNntpIncomingServer::SubscribeCleanup() +{ + nsresult rv; + if (mInner) { + rv = mInner->SetSubscribeListener(nsnull); + if (NS_FAILED(rv)) return rv; + + mInner = nsnull; + } + return NS_OK; +} + NS_IMETHODIMP nsNntpIncomingServer::PopulateSubscribeDatasource(nsIMsgWindow *aMsgWindow, PRBool aForceToServer) { @@ -859,7 +887,7 @@ nsNntpIncomingServer::AddNewsgroupToSubscribeDS(const char *aName) // since this comes from the server, append it to the list mGroupsOnServer.AppendCString(aName); - rv = AddToSubscribeDS(aName); + rv = AddToSubscribeDS(aName, PR_FALSE, PR_TRUE); if (NS_FAILED(rv)) return rv; return NS_OK; } @@ -872,6 +900,14 @@ nsNntpIncomingServer::SetIncomingServer(nsIMsgIncomingServer *aServer) return mInner->SetIncomingServer(aServer); } +NS_IMETHODIMP +nsNntpIncomingServer::SetShowFullName(PRBool showFullName) +{ + NS_ASSERTION(mInner,"not initialized"); + if (!mInner) return NS_ERROR_FAILURE; + return mInner->SetShowFullName(showFullName); +} + NS_IMETHODIMP nsNntpIncomingServer::SetDelimiter(char aDelimiter) { @@ -927,19 +963,19 @@ nsNntpIncomingServer::UpdateSubscribedInSubscribeDS() } NS_IMETHODIMP -nsNntpIncomingServer::AddToSubscribeDS(const char *aName) +nsNntpIncomingServer::AddToSubscribeDS(const char *aName, PRBool addAsSubscribed, PRBool changeIfExists) { NS_ASSERTION(mInner,"not initialized"); if (!mInner) return NS_ERROR_FAILURE; - return mInner->AddToSubscribeDS(aName); + return mInner->AddToSubscribeDS(aName,addAsSubscribed,changeIfExists); } NS_IMETHODIMP -nsNntpIncomingServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource) +nsNntpIncomingServer::SetPropertiesInSubscribeDS(const char *uri, const PRUnichar *aName, nsIRDFResource *aResource, PRBool subscribed, PRBool changeIfExists) { NS_ASSERTION(mInner,"not initialized"); if (!mInner) return NS_ERROR_FAILURE; - return mInner->SetPropertiesInSubscribeDS(uri,aName,aResource); + return mInner->SetPropertiesInSubscribeDS(uri,aName,aResource,subscribed,changeIfExists); } NS_IMETHODIMP @@ -968,7 +1004,8 @@ nsNntpIncomingServer::StopPopulatingSubscribeDS() rv = mInner->StopPopulatingSubscribeDS(); if (NS_FAILED(rv)) return rv; - mInner = nsnull; + //xxx todo when do I set this to null? + //mInner = nsnull; return NS_OK; } @@ -986,6 +1023,9 @@ nsNntpIncomingServer::StartPopulatingSubscribeDS() rv = SetDelimiter('.'); if (NS_FAILED(rv)) return rv; + rv = SetShowFullName(PR_TRUE); + if (NS_FAILED(rv)) return rv; + return mInner->StartPopulatingSubscribeDS(); }