diff --git a/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.cpp b/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.cpp index db9e40dba0f..2bee88c8207 100644 --- a/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.cpp +++ b/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.cpp @@ -28,13 +28,15 @@ #include "nsIMsgFilter.h" #include "nsIMsgFilterList.h" +#include "nsXPIDLString.h" + NS_IMPL_ISUPPORTS1(nsMsgFilterDataSource, nsIRDFDataSource) nsrefcnt nsMsgFilterDataSource::mGlobalRefCount = 0; nsCOMPtr nsMsgFilterDataSource::kNC_Child; nsCOMPtr nsMsgFilterDataSource::kNC_Name; -nsCOMPtr nsMsgFilterDataSource::mFolderArcsOut; +nsCOMPtr nsMsgFilterDataSource::mFilterListArcsOut; nsCOMPtr nsMsgFilterDataSource::mFilterArcsOut; nsMsgFilterDataSource::nsMsgFilterDataSource() @@ -57,7 +59,7 @@ nsMsgFilterDataSource::~nsMsgFilterDataSource() nsresult nsMsgFilterDataSource::cleanupGlobalObjects() { - mFolderArcsOut = nsnull; + mFilterListArcsOut = nsnull; mFilterArcsOut = nsnull; kNC_Child = nsnull; kNC_Name = nsnull; @@ -70,8 +72,8 @@ nsMsgFilterDataSource::initGlobalObjects(nsIRDFService *rdf) rdf->GetResource(NC_RDF_CHILD, getter_AddRefs(kNC_Child)); rdf->GetResource(NC_RDF_NAME, getter_AddRefs(kNC_Name)); - NS_NewISupportsArray(getter_AddRefs(mFolderArcsOut)); - mFolderArcsOut->AppendElement(kNC_Child); + NS_NewISupportsArray(getter_AddRefs(mFilterListArcsOut)); + mFilterListArcsOut->AppendElement(kNC_Child); NS_NewISupportsArray(getter_AddRefs(mFilterArcsOut)); mFilterArcsOut->AppendElement(kNC_Name); @@ -95,16 +97,24 @@ nsMsgFilterDataSource::GetTargets(nsIRDFResource *aSource, rv = aSource->GetDelegate("filter", NS_GET_IID(nsIMsgFilterList), (void **)getter_AddRefs(filterList)); if (NS_SUCCEEDED(rv)) - rv = getFilterListTargets(filterList, aProperty, aTruthValue, resourceList); + rv = getFilterListTargets(filterList, aSource, aProperty, + aTruthValue, resourceList); else { // maybe it's just a filter nsCOMPtr filter; rv = aSource->GetDelegate("filter", NS_GET_IID(nsIMsgFilter), - (void **)getter_AddRefs(filterList)); + (void **)getter_AddRefs(filter)); if (NS_SUCCEEDED(rv)) rv = getFilterTargets(filter, aProperty, aTruthValue, resourceList); } - return NS_RDF_NO_VALUE; + + nsArrayEnumerator *cursor = new nsArrayEnumerator(resourceList); + NS_ENSURE_TRUE(cursor, NS_ERROR_OUT_OF_MEMORY); + + *aResult = cursor; + NS_ADDREF(*aResult); + + return NS_OK; } @@ -114,11 +124,12 @@ nsMsgFilterDataSource::ArcLabelsOut(nsIRDFResource *aSource, { nsresult rv; nsCOMPtr arcs; - - nsCOMPtr folder = - do_QueryInterface(aSource, &rv); + + nsCOMPtr filterList; + rv = aSource->GetDelegate("filter", NS_GET_IID(nsIMsgFilterList), + (void **)getter_AddRefs(filterList)); if (NS_SUCCEEDED(rv)) { - arcs = mFolderArcsOut; + arcs = mFilterListArcsOut; } else { @@ -144,3 +155,59 @@ nsMsgFilterDataSource::ArcLabelsOut(nsIRDFResource *aSource, return NS_OK; } + +// takes a base resource, like mailbox://username@host/folder and returns +// the array that corresponds to all the filters. +// it does this quickly because it knows the sub-filters will be in the form +// +// mailbox://username@host/folder#filter0 +// mailbox://username@host/folder#filter1 +// mailbox://username@host/folder#filter2 +// mailbox://username@host/folder#filter3 +// +// and so forth +nsresult +nsMsgFilterDataSource::getFilterListTargets(nsIMsgFilterList *aFilterList, + nsIRDFResource *aSource, + nsIRDFResource *aProperty, + PRBool aTruthValue, + nsISupportsArray *aResult) +{ + nsresult rv; + + // get the URI of the source resource, say mailbox://username@host/folder + // from there we'll append "#filter", and then enumerate the + // filters to get all the resources like + // mailbox://username@host/folder#filter4 + nsXPIDLCString filterListUri; + aSource->GetValue(getter_Copies(filterListUri)); + + nsCAutoString filterUri((const char *)filterListUri); + filterUri.Append("#filter"); + + // we'll use the length of this base string to truncate the string later + PRInt32 baseFilterUriLength = filterUri.Length(); + + // now start looping through the filters + // we're not actually touching any filters here, just creating + // resources that correspond to them. + PRUint32 filterCount; + rv = aFilterList->GetFilterCount(&filterCount); + if (NS_FAILED(rv)) return rv; + + PRUint32 i; + for (i=0; i filterResource; + rv = getRDFService()->GetResource(filterUri.GetBuffer(), + getter_AddRefs(filterResource)); + if (NS_SUCCEEDED(rv)) + aResult->AppendElement(filterResource); + + // now reduce the URI back to the base uri + filterUri.Truncate(baseFilterUriLength); + } + + return NS_OK; +} diff --git a/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.h b/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.h index f158db131fd..2ed91cae120 100644 --- a/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.h +++ b/mozilla/mailnews/base/search/src/nsMsgFilterDataSource.h @@ -29,38 +29,51 @@ #include "nsCOMPtr.h" #include "nsISupportsArray.h" +class nsIMsgFilter; class nsMsgFilterDataSource : public nsMsgRDFDataSource { - public: - nsMsgFilterDataSource(); - virtual ~nsMsgFilterDataSource(); +public: + nsMsgFilterDataSource(); + virtual ~nsMsgFilterDataSource(); - NS_DECL_ISUPPORTS - NS_IMETHOD GetTargets(nsIRDFResource *source, - nsIRDFResource *property, - PRBool aTruthValue, - nsISimpleEnumerator **_retval); - NS_IMETHOD ArcLabelsOut(nsIRDFResource *source, - nsISimpleEnumerator **_retval); + NS_DECL_ISUPPORTS + NS_IMETHOD GetTargets(nsIRDFResource *source, + nsIRDFResource *property, + PRBool aTruthValue, + nsISimpleEnumerator **_retval); + NS_IMETHOD ArcLabelsOut(nsIRDFResource *source, + nsISimpleEnumerator **_retval); - private: +private: - static nsrefcnt mGlobalRefCount; + // GetTargets helpers + nsresult getFilterTarget(nsIMsgFilter *aFilter, + nsIRDFResource *aProperty, + PRBool aTruthValue, + nsIRDFResource **aResult); + + nsresult getFilterListTargets(nsIMsgFilterList *aFilter, + nsIRDFResource *aSource, + nsIRDFResource *aProperty, + PRBool aTruthValue, + nsISupportsArray *aResult); + + static nsrefcnt mGlobalRefCount; - static nsresult initGlobalObjects(nsIRDFService* rdf); - static nsresult cleanupGlobalObjects(); - static nsresult getServerArcsOut(); - static nsresult getFilterArcsOut(); + static nsresult initGlobalObjects(nsIRDFService* rdf); + static nsresult cleanupGlobalObjects(); + static nsresult getServerArcsOut(); + static nsresult getFilterArcsOut(); - // arcs out - static nsCOMPtr mFolderArcsOut; - static nsCOMPtr mFilterArcsOut; + // arcs out + static nsCOMPtr mFilterListArcsOut; + static nsCOMPtr mFilterArcsOut; - // resources used - static nsCOMPtr kNC_Child; - static nsCOMPtr kNC_Name; + // resources used + static nsCOMPtr kNC_Child; + static nsCOMPtr kNC_Name; };