diff --git a/mozilla/mail/extensions/Makefile.in b/mozilla/mail/extensions/Makefile.in
index 570ed01ea84..404155d0931 100644
--- a/mozilla/mail/extensions/Makefile.in
+++ b/mozilla/mail/extensions/Makefile.in
@@ -26,7 +26,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
-DIRS = offline
+DIRS = offline newsblog
ifdef MOZ_PSM
BUILD_SMIME=1
diff --git a/mozilla/mail/extensions/newsblog/content/Feed.js b/mozilla/mail/extensions/newsblog/content/Feed.js
index 89ff844be50..7c2ddebef9d 100755
--- a/mozilla/mail/extensions/newsblog/content/Feed.js
+++ b/mozilla/mail/extensions/newsblog/content/Feed.js
@@ -481,6 +481,10 @@ function storeNextItem()
{
item.feed.removeInvalidItems();
+ // let's be sure to flush any feed item changes back to disk
+ var ds = getItemsDS(item.feed.server);
+ ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
+
if (item.feed.downloadCallback)
item.feed.downloadCallback.downloaded(item.feed, kNewsBlogSuccess);
diff --git a/mozilla/mail/extensions/newsblog/content/feed-properties.xul b/mozilla/mail/extensions/newsblog/content/feed-properties.xul
index 197248f9b9b..8645c692bd7 100644
--- a/mozilla/mail/extensions/newsblog/content/feed-properties.xul
+++ b/mozilla/mail/extensions/newsblog/content/feed-properties.xul
@@ -37,6 +37,7 @@
diff --git a/mozilla/mail/extensions/newsblog/content/utils.js b/mozilla/mail/extensions/newsblog/content/utils.js
index 39a6617601e..f3ba1ef576a 100755
--- a/mozilla/mail/extensions/newsblog/content/utils.js
+++ b/mozilla/mail/extensions/newsblog/content/utils.js
@@ -109,6 +109,9 @@ function updateFolderFeedUrl(aFolder, aFeedUrl, aRemoveUrl)
}
else
folderInfo.SetCharPtrProperty("feedUrl", oldFeedUrl + kFeedUrlDelimiter + aFeedUrl);
+
+ // commit the db to preserve our changes
+ msgdb.Close(true);
}
function getNodeValue(node) {
diff --git a/mozilla/mail/extensions/newsblog/js/newsblog.js b/mozilla/mail/extensions/newsblog/js/newsblog.js
index cf69b9497ce..51d3a97f5ec 100755
--- a/mozilla/mail/extensions/newsblog/js/newsblog.js
+++ b/mozilla/mail/extensions/newsblog/js/newsblog.js
@@ -85,6 +85,48 @@ var nsNewsBlogFeedDownloader =
feed.download(true, progressNotifier);
},
+ updateSubscriptionsDS: function(aFolder, aUnsubscribe)
+ {
+ if (!gExternalScriptsLoaded)
+ loadScripts();
+
+ // an rss folder was just renamed...we need to update our feed data source
+ var msgdb = aFolder.QueryInterface(Components.interfaces.nsIMsgFolder).getMsgDatabase(null);
+ var folderInfo = msgdb.dBFolderInfo;
+ var feedurls = {};
+ folderInfo.GetCharPtrProperty("feedUrl", feedurls);
+ feedurls = feedurls.value;
+
+ var feedUrlArray = feedurls.split("|");
+
+ var rdf = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
+ var ds = getSubscriptionsDS(aFolder.server);
+
+ for (url in feedUrlArray)
+ {
+ if (feedUrlArray[url])
+ {
+ id = rdf.GetResource(feedUrlArray[url]);
+ // get the node for the current folder URI
+ var node = ds.GetTarget(id, FZ_DESTFOLDER, true);
+
+ // we need to check and see if the folder is a child of the trash...if it is, then we can
+ // treat this as an unsubscribe action
+ if (aUnsubscribe)
+ {
+ var feeds = getSubscriptionsList(aFolder.server);
+ var index = feeds.IndexOf(id);
+ if (index != -1)
+ feeds.RemoveElementAt(index, false);
+ removeAssertions(ds, id);
+ }
+ ds.Change(id, FZ_DESTFOLDER, node, rdf.GetResource(aFolder.URI));
+ }
+ } // for each feed url in the folder property
+
+ ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); // flush any changes
+ },
+
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsINewsBlogFeedDownloader) ||
diff --git a/mozilla/mailnews/local/public/nsINewsBlogFeedDownloader.idl b/mozilla/mailnews/local/public/nsINewsBlogFeedDownloader.idl
index a12241fc52b..ec530988a8d 100755
--- a/mozilla/mailnews/local/public/nsINewsBlogFeedDownloader.idl
+++ b/mozilla/mailnews/local/public/nsINewsBlogFeedDownloader.idl
@@ -50,5 +50,10 @@ interface nsINewsBlogFeedDownloader : nsISupports
/* A convient method to subscribe to feeds without going through the subscribe UI
used by drag and drop */
void subscribeToFeed(in string aUrl, in nsIMsgFolder aFolder, in nsIMsgWindow aMsgWindow);
+
+ /* called when the RSS Incoming Server detects a change to an RSS folder. For instance, the user just
+ deleted an RSS folder and we need to update the subscriptions data source. Or the user renamed an RSS folder...
+ */
+ void updateSubscriptionsDS(in nsIMsgFolder aFolder, in boolean aUnsubscribe);
};
diff --git a/mozilla/mailnews/local/src/nsRssIncomingServer.cpp b/mozilla/mailnews/local/src/nsRssIncomingServer.cpp
index 602074ae8c7..11dd84668cf 100755
--- a/mozilla/mailnews/local/src/nsRssIncomingServer.cpp
+++ b/mozilla/mailnews/local/src/nsRssIncomingServer.cpp
@@ -39,22 +39,45 @@
#include "nsRssIncomingServer.h"
#include "nsMsgFolderFlags.h"
#include "nsINewsBlogFeedDownloader.h"
+#include "nsIMsgMailSession.h"
+#include "nsMsgBaseCID.h"
+#include "nsIRDFResource.h"
#include "nsIMsgLocalMailFolder.h"
#include "nsIDBFolderInfo.h"
-NS_IMPL_ISUPPORTS_INHERITED2(nsRssIncomingServer,
+nsrefcnt nsRssIncomingServer::gInstanceCount = 0;
+
+NS_IMPL_ISUPPORTS_INHERITED3(nsRssIncomingServer,
nsMsgIncomingServer,
nsIRssIncomingServer,
+ nsIFolderListener,
nsILocalMailIncomingServer)
nsRssIncomingServer::nsRssIncomingServer()
{
m_canHaveFilters = PR_TRUE;
+
+ if (gInstanceCount == 0)
+ {
+ nsresult rv;
+ nsCOMPtr mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
+
+ if (NS_SUCCEEDED(rv))
+ mailSession->AddFolderListener(this, nsIFolderListener::added);
+ }
+
+ gInstanceCount++;
}
nsRssIncomingServer::~nsRssIncomingServer()
{
+ gInstanceCount--;
+
+ // I used to have code here which unregistered the global rss folder listener with the
+ // mail session. But the rss incoming server is held until shutdown when we shut down the
+ // account datasource. And at shutdown the mail session explicitly releases all of its folder listeners
+ // anyway so this was effectively a no-op...
}
nsresult nsRssIncomingServer::FillInDataSourcePath(const nsAString& aDataSourceName, nsILocalFile ** aLocation)
@@ -135,25 +158,28 @@ NS_IMETHODIMP nsRssIncomingServer::PerformBiff(nsIMsgWindow *aMsgWindow)
GetRootMsgFolder(getter_AddRefs(rootRSSFolder));
// enumerate over the RSS folders and ping each one
- nsCOMPtr folderEnumerator;
- rv = rootRSSFolder->GetSubFolders(getter_AddRefs(folderEnumerator));
+ nsCOMPtr allDescendents;
+ NS_NewISupportsArray(getter_AddRefs(allDescendents));
+ rv = rootRSSFolder->ListDescendents(allDescendents);
NS_ENSURE_SUCCESS(rv, rv);
- nsresult more = folderEnumerator->First();
+ PRUint32 cnt =0;
+ allDescendents->Count(&cnt);
+
nsCOMPtr supports;
nsCOMPtr urlListener;
+ nsCOMPtr rssFolder;
- while (NS_SUCCEEDED(more))
+ for (PRUint32 index = 0; index < cnt; index++)
{
- rv = folderEnumerator->CurrentItem(getter_AddRefs(supports));
- nsCOMPtr rssFolder = do_QueryInterface(supports);
+ supports = getter_AddRefs(allDescendents->ElementAt(index));
+ rssFolder = do_QueryInterface(supports, &rv);
if (rssFolder)
{
urlListener = do_QueryInterface(rssFolder);
// WARNING: Never call GetNewMail with the root folder or you will trigger an infinite loop...
GetNewMail(aMsgWindow, urlListener, rssFolder, nsnull);
}
- more = folderEnumerator->Next();
}
return NS_OK;
@@ -226,3 +252,99 @@ NS_IMETHODIMP nsRssIncomingServer::GetSupportsDiskSpace(PRBool *aSupportsDiskSpa
*aSupportsDiskSpace = PR_FALSE;
return NS_OK;
}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemAdded(nsISupports *parentItem, nsISupports *item, const char *viewString)
+{
+ nsCOMPtr folder = do_QueryInterface(item);
+ NS_ENSURE_TRUE(folder, NS_OK); // just kick out with a success code if the item in question is not a folder
+
+ nsCOMPtr server;
+ nsresult rv = folder->GetServer(getter_AddRefs(server));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsXPIDLCString type;
+ rv = server->GetType(getter_Copies(type));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (type.Equals("rss"))
+ {
+ nsCOMPtr rssDownloader = do_GetService("@mozilla.org/newsblog-feed-downloader;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // did the user just delete this folder (adding it to trash?)
+ nsCOMPtr rootMsgFolder;
+ nsCOMPtr trashFolder;
+ rv = GetRootFolder(getter_AddRefs(rootMsgFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRUint32 numFolders;
+ rv = rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, 1, &numFolders, getter_AddRefs(trashFolder));
+
+ PRBool unsubscribe = PR_FALSE;
+ if (trashFolder)
+ trashFolder->IsAncestorOf(folder, &unsubscribe);
+
+ rssDownloader->UpdateSubscriptionsDS(folder, unsubscribe);
+
+ // if the user was moving or deleting a set of nested folders, we only seem to get a single OnItemAdded
+ // notification. So we need to iterate over all of the descedent folders of the folder whose location has
+ // changed.
+
+ nsCOMPtr allDescendents;
+ NS_NewISupportsArray(getter_AddRefs(allDescendents));
+ rv = folder->ListDescendents(allDescendents);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRUint32 cnt =0;
+ allDescendents->Count(&cnt);
+
+ nsCOMPtr supports;
+ nsCOMPtr rssFolder;
+
+ for (PRUint32 index = 0; index < cnt; index++)
+ {
+ supports = getter_AddRefs(allDescendents->ElementAt(index));
+ rssFolder = do_QueryInterface(supports, &rv);
+ if (rssFolder)
+ rssDownloader->UpdateSubscriptionsDS(rssFolder, unsubscribe);
+ }
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemPropertyChanged(nsISupports *item, nsIAtom *property, const char *oldValue, const char *newValue)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemIntPropertyChanged(nsISupports *item, nsIAtom *property, PRInt32 oldValue, PRInt32 newValue)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemBoolPropertyChanged(nsISupports *item, nsIAtom *property, PRBool oldValue, PRBool newValue)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemUnicharPropertyChanged(nsISupports *item, nsIAtom *property, const PRUnichar *oldValue, const PRUnichar *newValue)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemPropertyFlagChanged(nsISupports *item, nsIAtom *property, PRUint32 oldFlag, PRUint32 newFlag)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsRssIncomingServer::OnItemEvent(nsIMsgFolder *aFolder, nsIAtom *aEvent)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/mozilla/mailnews/local/src/nsRssIncomingServer.h b/mozilla/mailnews/local/src/nsRssIncomingServer.h
index 1f1381c5d77..bd07bdc80e9 100755
--- a/mozilla/mailnews/local/src/nsRssIncomingServer.h
+++ b/mozilla/mailnews/local/src/nsRssIncomingServer.h
@@ -40,17 +40,19 @@
#include "nsIRssIncomingServer.h"
#include "nsILocalMailIncomingServer.h"
#include "nsMsgIncomingServer.h"
-
+#include "nsIFolderListener.h"
class nsRssIncomingServer : public nsMsgIncomingServer,
public nsIRssIncomingServer,
- public nsILocalMailIncomingServer
+ public nsILocalMailIncomingServer,
+ public nsIFolderListener
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIRSSINCOMINGSERVER
NS_DECL_NSILOCALMAILINCOMINGSERVER
+ NS_DECL_NSIFOLDERLISTENER
NS_IMETHOD GetLocalStoreType(char **);
NS_IMETHOD GetOfflineSupportLevel(PRInt32 *aSupportLevel);
@@ -62,6 +64,7 @@ public:
virtual ~nsRssIncomingServer();
protected:
nsresult FillInDataSourcePath(const nsAString& aDataSourceName, nsILocalFile ** aLocation);
+ static nsrefcnt gInstanceCount;
};
#endif /* __nsRssIncomingServer_h */