зеркало из https://github.com/mozilla/gecko-dev.git
Sorting optimizations. (Sort-of) review by putterman@netscape.com
This commit is contained in:
Родитель
545ae7fd61
Коммит
6222e5412c
|
@ -26,16 +26,16 @@
|
|||
|
||||
|
||||
[ptr] native nsIRDFDataSourceHandle( nsIRDFDataSource *);
|
||||
interface sortState;
|
||||
|
||||
interface nsIContent;
|
||||
interface nsIDOMNode;
|
||||
|
||||
|
||||
[scriptable, uuid(BFD05261-834C-11d2-8EAC-00805F29F371)]
|
||||
interface nsIXULSortService : nsISupports
|
||||
{
|
||||
void Sort(in nsIDOMNode node, in string sortResource, in string sortDirection);
|
||||
[noscript] void InsertContainerNode(in nsIRDFCompositeDataSource db, in nsIRDFDataSourceHandle cacheHandle, in nsIContent root, in nsIContent trueParent,
|
||||
[noscript] void InsertContainerNode(in nsIRDFCompositeDataSource db, in sortState sortStatePtr, in nsIContent root, in nsIContent trueParent,
|
||||
in nsIContent container, in nsIContent node, in boolean aNotify);
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert John Churchill <rjc@netscape.com>
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
|
@ -131,10 +132,12 @@ static const char kXULNameSpaceURI[]
|
|||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, BookmarkSeparator);
|
||||
|
||||
|
||||
typedef struct _sortStruct {
|
||||
nsCOMPtr<nsIRDFResource> sortProperty;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty2;
|
||||
PRBool firstFlag;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
|
||||
nsCOMPtr<nsIRDFCompositeDataSource> db;
|
||||
nsCOMPtr<nsIRDFService> rdfService;
|
||||
nsCOMPtr<nsIRDFDataSource> mInner;
|
||||
|
@ -146,6 +149,7 @@ typedef struct _sortStruct {
|
|||
PRBool descendingSort;
|
||||
PRBool naturalOrderSort;
|
||||
PRBool inbetweenSeparatorSort;
|
||||
|
||||
} sortStruct, *sortPtr;
|
||||
|
||||
|
||||
|
@ -211,10 +215,9 @@ nsresult GetTreeCell(nsIContent *node, PRInt32 colIndex, nsIContent **cell);
|
|||
nsresult SortTreeChildren(nsIContent *container, sortPtr sortInfo);
|
||||
nsresult DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection);
|
||||
|
||||
static nsresult GetCachedTarget(sortPtr sortInfo, nsIRDFResource* aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult);
|
||||
static nsresult GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProperty, const char *suffix, nsIRDFResource **res);
|
||||
static nsresult GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortProperty, sortPtr sortInfo, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty, sortPtr sortInfo, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetCachedTarget(sortPtr sortInfo, PRBool useCache, nsIRDFResource* aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult);
|
||||
static nsresult GetResourceValue(nsIRDFResource *res1, sortPtr sortInfo, PRBool first, PRBool useCache, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetNodeValue(nsIContent *node1, sortPtr sortInfo, PRBool first, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetTreeCell(sortPtr sortInfo, nsIContent *node, PRInt32 cellIndex, nsIContent **cell);
|
||||
static nsresult GetNodeTextValue(sortPtr sortInfo, nsIContent *node, nsString & val);
|
||||
|
||||
|
@ -628,7 +631,7 @@ XULSortServiceImpl::SetSortHints(nsIContent *tree, const nsString &sortResource,
|
|||
tree->SetAttribute(kNameSpaceID_RDF, kResourceAtom, sortResource, PR_FALSE);
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
tree->SetAttribute(kNameSpaceID_RDF, kResource2Atom, sortDirection, PR_FALSE);
|
||||
tree->SetAttribute(kNameSpaceID_RDF, kResource2Atom, sortResource2, PR_FALSE);
|
||||
else tree->UnsetAttribute(kNameSpaceID_RDF, kResource2Atom, PR_FALSE);
|
||||
}
|
||||
else
|
||||
|
@ -911,103 +914,37 @@ XULSortServiceImpl::CompareNodes(nsIRDFNode *cellNode1, PRBool isCollationKey1,
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetCachedTarget(sortPtr sortInfo, nsIRDFResource* aSource,
|
||||
XULSortServiceImpl::GetCachedTarget(sortPtr sortInfo, PRBool useCache, nsIRDFResource* aSource,
|
||||
nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult)
|
||||
{
|
||||
nsresult rv = NS_OK, rvTemp;
|
||||
nsresult rv;
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
if (!(sortInfo->mInner))
|
||||
{
|
||||
// if we don't have a mInner, create one
|
||||
rvTemp = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
||||
rv = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
||||
nsnull, NS_GET_IID(nsIRDFDataSource), (void **)&(sortInfo->mInner));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
}
|
||||
|
||||
rv = NS_RDF_NO_VALUE;
|
||||
if (sortInfo->mInner)
|
||||
{
|
||||
// else, if we do have a mInner, look for the resource in it
|
||||
rv = sortInfo->mInner->GetTarget(aSource, aProperty, aTruthValue, aResult);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && (rv == NS_RDF_NO_VALUE) && (sortInfo->db))
|
||||
{
|
||||
// if we don't have a cached value, look it up in the document's DB
|
||||
if (NS_SUCCEEDED(rv = (sortInfo->db)->GetTarget(aSource, aProperty,
|
||||
aTruthValue, aResult)) && (rv != NS_RDF_NO_VALUE))
|
||||
if (useCache == PR_TRUE)
|
||||
{
|
||||
// and if we have a value, cache it away in our mInner also
|
||||
rvTemp = sortInfo->mInner->Assert(aSource, aProperty, *aResult, PR_TRUE);
|
||||
// if we do have a mInner, look for the resource in it
|
||||
rv = sortInfo->mInner->GetTarget(aSource, aProperty, aTruthValue, aResult);
|
||||
}
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProperty, const char *suffix, nsIRDFResource **res)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
*res = nsnull;
|
||||
|
||||
const char *sortPropertyURI = nsnull;
|
||||
rv = sortProperty->GetValueConst(&sortPropertyURI);
|
||||
if (NS_SUCCEEDED(rv) && (sortPropertyURI))
|
||||
{
|
||||
nsAutoString resName(sortPropertyURI);
|
||||
if (suffix) resName += suffix;
|
||||
|
||||
if (!(sortInfo->resCache))
|
||||
else if (sortInfo->db)
|
||||
{
|
||||
// if we don't have a cache, create one
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(sortInfo->resCache));
|
||||
}
|
||||
else
|
||||
{
|
||||
// else, if we do have a cache, look for the resource in it
|
||||
PRUint32 numRes;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->resCache->Count(&numRes)))
|
||||
// if we don't have a cached value, look it up in the document's DB
|
||||
if (NS_SUCCEEDED(rv = (sortInfo->db)->GetTarget(aSource, aProperty,
|
||||
aTruthValue, aResult)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
PRUint32 loop;
|
||||
for (loop=0; loop<numRes; loop++)
|
||||
{
|
||||
nsCOMPtr<nsISupports> iSupports;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->resCache->GetElementAt(loop,
|
||||
getter_AddRefs(iSupports))))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> aRes = do_QueryInterface(iSupports);
|
||||
if (aRes)
|
||||
{
|
||||
const char *resURI = nsnull;
|
||||
if (NS_SUCCEEDED(rv = aRes->GetValueConst(&resURI)) && (resURI))
|
||||
{
|
||||
if (resName.Equals(resURI))
|
||||
{
|
||||
// found res in cache, so just return it
|
||||
*res = aRes;
|
||||
NS_ADDREF(*res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*res))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> sortRes;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->rdfService->GetUnicodeResource(resName.GetUnicode(),
|
||||
getter_AddRefs(sortRes))) && (sortRes))
|
||||
{
|
||||
*res = sortRes;
|
||||
NS_ADDREF(*res);
|
||||
|
||||
// and add it into the cache array
|
||||
if (sortInfo->resCache)
|
||||
{
|
||||
sortInfo->resCache->AppendElement(sortRes);
|
||||
}
|
||||
// and if we have a value, cache it away in our mInner also (ignore errors)
|
||||
sortInfo->mInner->Assert(aSource, aProperty, *aResult, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1017,7 +954,7 @@ XULSortServiceImpl::GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProp
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortProperty, sortPtr sortInfo,
|
||||
XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, sortPtr sortInfo, PRBool first, PRBool useCache,
|
||||
nsIRDFNode **target, PRBool &isCollationKey)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -1025,16 +962,17 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
*target = nsnull;
|
||||
isCollationKey = PR_FALSE;
|
||||
|
||||
if ((res1) && (sortInfo->naturalOrderSort == PR_FALSE) && (sortInfo->sortProperty))
|
||||
if ((res1) && (sortInfo->naturalOrderSort == PR_FALSE))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> modSortRes;
|
||||
|
||||
// for any given property, first ask the graph for its value with "?collation=true" appended
|
||||
// to indicate that if there is a collation key available for this value, we want it
|
||||
if (NS_SUCCEEDED(rv = GetCachedResource(sortInfo, sortInfo->sortProperty, "?collation=true",
|
||||
getter_AddRefs(modSortRes))) && (modSortRes))
|
||||
|
||||
modSortRes = (first) ? sortInfo->sortPropertyColl : sortInfo->sortPropertyColl2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, modSortRes,
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
isCollationKey = PR_TRUE;
|
||||
|
@ -1046,10 +984,10 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
// to indicate that if there is any distinction between its display value and sorting
|
||||
// value, we want the sorting value (so that, for example, a mail datasource could strip
|
||||
// off a "Re:" on a mail message subject)
|
||||
if (NS_SUCCEEDED(rv = GetCachedResource(sortInfo, sortInfo->sortProperty, "?sort=true",
|
||||
getter_AddRefs(modSortRes))) && (modSortRes))
|
||||
modSortRes = (first) ? sortInfo->sortPropertySort : sortInfo->sortPropertySort2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, modSortRes,
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
}
|
||||
|
@ -1058,9 +996,13 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
if (!(*target))
|
||||
{
|
||||
// if no collation key and no special sorting value, just get the property value
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, sortProperty,
|
||||
PR_TRUE, target) && (rv != NS_RDF_NO_VALUE)))
|
||||
modSortRes = (first) ? sortInfo->sortProperty : sortInfo->sortProperty2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target) && (rv != NS_RDF_NO_VALUE)))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1012,7 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty, sortPtr sortInfo,
|
||||
XULSortServiceImpl::GetNodeValue(nsIContent *node1, sortPtr sortInfo, PRBool first,
|
||||
nsIRDFNode **theNode, PRBool &isCollationKey)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -1115,7 +1057,11 @@ XULSortServiceImpl::GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty
|
|||
{
|
||||
if (res1)
|
||||
{
|
||||
rv = GetResourceValue(res1, sortProperty, sortInfo, theNode, isCollationKey);
|
||||
rv = GetResourceValue(res1, sortInfo, first, PR_TRUE, theNode, isCollationKey);
|
||||
if ((rv == NS_RDF_NO_VALUE) || (!*theNode))
|
||||
{
|
||||
rv = GetResourceValue(res1, sortInfo, first, PR_FALSE, theNode, isCollationKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1247,13 +1193,8 @@ XULSortServiceImpl::InplaceSort(nsIContent *node1, nsIContent *node2, sortPtr so
|
|||
sortOrder = 0;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> cellNode1, cellNode2;
|
||||
GetNodeValue(node1, sortInfo->sortProperty, sortInfo, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo->sortProperty, sortInfo, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
if ((!cellNode1) && (!cellNode2) && (sortInfo->sortProperty2 == nsnull))
|
||||
{
|
||||
rv = GetNodeValue(node1, kNC_Name, sortInfo, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
rv = GetNodeValue(node2, kNC_Name, sortInfo, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
}
|
||||
GetNodeValue(node1, sortInfo, PR_TRUE, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo, PR_TRUE, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
|
||||
PRBool bothValid = PR_FALSE;
|
||||
rv = CompareNodes(cellNode1, isCollationKey1, cellNode2, isCollationKey2, bothValid, sortOrder);
|
||||
|
@ -1263,14 +1204,16 @@ XULSortServiceImpl::InplaceSort(nsIContent *node1, nsIContent *node2, sortPtr so
|
|||
// nodes appear to be equivalent, check for secondary sort criteria
|
||||
if (sortInfo->sortProperty2 != nsnull)
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> temp = sortInfo->sortProperty;
|
||||
sortInfo->sortProperty = sortInfo->sortProperty2;
|
||||
sortInfo->sortProperty2 = nsnull;
|
||||
cellNode1 = nsnull;
|
||||
cellNode2 = nsnull;
|
||||
isCollationKey1 = PR_FALSE;
|
||||
isCollationKey2 = PR_FALSE;
|
||||
|
||||
GetNodeValue(node1, sortInfo, PR_FALSE, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo, PR_FALSE, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
|
||||
rv = InplaceSort(node1, node2, sortInfo, sortOrder);
|
||||
|
||||
sortInfo->sortProperty2 = sortInfo->sortProperty;
|
||||
sortInfo->sortProperty = temp;
|
||||
bothValid = PR_FALSE;
|
||||
rv = CompareNodes(cellNode1, isCollationKey1, cellNode2, isCollationKey2, bothValid, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1437,9 +1380,24 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, sortPtr sortInfo)
|
|||
}
|
||||
|
||||
|
||||
// rjc: yes, I'm lame. For the moment, "class sortState" is defined both here and in
|
||||
// nsRDFGenericBuilder.cpp so any changes made here must also (exactly) be made there also.
|
||||
|
||||
typedef class sortState
|
||||
{
|
||||
public:
|
||||
nsAutoString sortResource, sortResource2;
|
||||
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
} sortStateClass;
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDataSource **cacheHandle, nsIContent *root,
|
||||
XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState *sortState, nsIContent *root,
|
||||
nsIContent *trueParent, nsIContent *container, nsIContent *node, PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -1457,9 +1415,9 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
sortInfo.sortProperty = nsnull;
|
||||
sortInfo.sortProperty2 = nsnull;
|
||||
sortInfo.inbetweenSeparatorSort = PR_FALSE;
|
||||
if (cacheHandle != nsnull)
|
||||
if (sortState->mCache)
|
||||
{
|
||||
sortInfo.mInner = *cacheHandle; // Note: this can/might be null
|
||||
sortInfo.mInner = sortState->mCache; // Note: this can/might be null
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1505,13 +1463,71 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
|
||||
if (sortInfoAvailable)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
if (sortResource2.Length() > 0)
|
||||
if (sortState->sortResource.Equals(sortResource) && sortState->sortResource2.Equals(sortResource2))
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortInfo.sortProperty = sortState->sortProperty;
|
||||
sortInfo.sortProperty2 = sortState->sortProperty2;
|
||||
sortInfo.sortPropertyColl = sortState->sortPropertyColl;
|
||||
sortInfo.sortPropertyColl2 = sortState->sortPropertyColl2;
|
||||
sortInfo.sortPropertySort = sortState->sortPropertySort;
|
||||
sortInfo.sortPropertySort2 = sortState->sortPropertySort2;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAutoString temp;
|
||||
|
||||
// either first time, or must have changing sorting info, so flush state cache
|
||||
sortState->sortProperty = nsnull; sortState->sortProperty2 = nsnull;
|
||||
sortState->sortPropertyColl = nsnull; sortState->sortPropertyColl2 = nsnull;
|
||||
sortState->sortPropertySort = nsnull; sortState->sortPropertySort2 = nsnull;
|
||||
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortResource = sortResource;
|
||||
sortState->sortProperty = sortInfo.sortProperty;
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertyColl = sortInfo.sortPropertyColl;
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertySort = sortInfo.sortPropertySort;
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortResource2 = sortResource2;
|
||||
sortState->sortProperty2 = sortInfo.sortProperty2;
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertyColl2 = sortInfo.sortPropertyColl2;
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertySort2 = sortInfo.sortPropertySort2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// either first time, or must have changing sorting info, so flush state cache
|
||||
sortState->sortResource.Truncate();
|
||||
sortState->sortResource2.Truncate();
|
||||
|
||||
sortState->sortProperty = nsnull; sortState->sortProperty2 = nsnull;
|
||||
sortState->sortPropertyColl = nsnull; sortState->sortPropertyColl2 = nsnull;
|
||||
sortState->sortPropertySort = nsnull; sortState->sortPropertySort2 = nsnull;
|
||||
}
|
||||
|
||||
// set up sort order info
|
||||
|
@ -1634,10 +1650,9 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
container->AppendChildTo(node, aNotify);
|
||||
}
|
||||
|
||||
if ((cacheHandle) && (sortInfo.mInner) && ((*cacheHandle) != sortInfo.mInner.get()))
|
||||
if ((!sortState->mCache) && (sortInfo.mInner))
|
||||
{
|
||||
*cacheHandle = sortInfo.mInner;
|
||||
NS_ADDREF(*cacheHandle);
|
||||
sortState->mCache = sortInfo.mInner;
|
||||
}
|
||||
return(NS_OK);
|
||||
}
|
||||
|
@ -1695,10 +1710,6 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
sortInfo.kTreeCellAtom = kTreeCellAtom;
|
||||
sortInfo.kNameSpaceID_XUL = kNameSpaceID_XUL;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(),
|
||||
getter_AddRefs(sortInfo.sortProperty))))
|
||||
return(rv);
|
||||
|
||||
// determine new sort resource and direction to use
|
||||
if (sortDirection.EqualsIgnoreCase("natural"))
|
||||
{
|
||||
|
@ -1718,6 +1729,37 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
PRBool found;
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, sortResource2,
|
||||
sortInfo.inbetweenSeparatorSort, sortInfo.colIndex, found))) return(rv);
|
||||
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
nsAutoString temp;
|
||||
temp = sortResource;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
}
|
||||
|
||||
SetSortHints(treeNode, sortResource, sortDirection, sortResource2, sortInfo.inbetweenSeparatorSort, found);
|
||||
|
||||
nsCOMPtr<nsIContent> treeBody;
|
||||
|
@ -1731,8 +1773,8 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
if (NS_FAILED(rv = treeBody->GetParent(*getter_AddRefs(treeParent)))) return(rv);
|
||||
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
|
||||
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
|
||||
|
||||
if (NS_FAILED(rv = treeParent->AppendChildTo(treeBody, PR_TRUE))) return(rv);
|
||||
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,22 @@ static NS_DEFINE_CID(kIHTMLElementFactoryIID, NS_IHTML_ELEMENT_FACTORY_IID);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// rjc: yes, I'm lame. For the moment, "class sortState" is defined both here and in
|
||||
// nsXULSortService.cpp so any changes made here must also (exactly) be made there also.
|
||||
|
||||
typedef class sortState
|
||||
{
|
||||
public:
|
||||
// state match strings
|
||||
nsAutoString sortResource, sortResource2;
|
||||
|
||||
// state variables
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
} sortStateClass;
|
||||
|
||||
class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder,
|
||||
public nsIRDFObserver
|
||||
{
|
||||
|
@ -309,7 +325,9 @@ protected:
|
|||
nsCOMPtr<nsIContent> mRoot;
|
||||
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
sortState sortState;
|
||||
|
||||
// pseudo-constants
|
||||
static nsrefcnt gRefCnt;
|
||||
|
@ -2068,18 +2086,8 @@ RDFGenericBuilderImpl::BuildContentFromTemplate(nsIContent *aTemplateNode,
|
|||
|
||||
if (gXULSortService && isResourceElement)
|
||||
{
|
||||
if (mCache)
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
(nsIRDFDataSource **)&mCache,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
getter_AddRefs(mCache),
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
rv = gXULSortService->InsertContainerNode(mDB, &sortState,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -26,16 +26,16 @@
|
|||
|
||||
|
||||
[ptr] native nsIRDFDataSourceHandle( nsIRDFDataSource *);
|
||||
interface sortState;
|
||||
|
||||
interface nsIContent;
|
||||
interface nsIDOMNode;
|
||||
|
||||
|
||||
[scriptable, uuid(BFD05261-834C-11d2-8EAC-00805F29F371)]
|
||||
interface nsIXULSortService : nsISupports
|
||||
{
|
||||
void Sort(in nsIDOMNode node, in string sortResource, in string sortDirection);
|
||||
[noscript] void InsertContainerNode(in nsIRDFCompositeDataSource db, in nsIRDFDataSourceHandle cacheHandle, in nsIContent root, in nsIContent trueParent,
|
||||
[noscript] void InsertContainerNode(in nsIRDFCompositeDataSource db, in sortState sortStatePtr, in nsIContent root, in nsIContent trueParent,
|
||||
in nsIContent container, in nsIContent node, in boolean aNotify);
|
||||
};
|
||||
|
||||
|
|
|
@ -118,6 +118,22 @@ static NS_DEFINE_CID(kIHTMLElementFactoryIID, NS_IHTML_ELEMENT_FACTORY_IID);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// rjc: yes, I'm lame. For the moment, "class sortState" is defined both here and in
|
||||
// nsXULSortService.cpp so any changes made here must also (exactly) be made there also.
|
||||
|
||||
typedef class sortState
|
||||
{
|
||||
public:
|
||||
// state match strings
|
||||
nsAutoString sortResource, sortResource2;
|
||||
|
||||
// state variables
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
} sortStateClass;
|
||||
|
||||
class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder,
|
||||
public nsIRDFObserver
|
||||
{
|
||||
|
@ -309,7 +325,9 @@ protected:
|
|||
nsCOMPtr<nsIContent> mRoot;
|
||||
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
sortState sortState;
|
||||
|
||||
// pseudo-constants
|
||||
static nsrefcnt gRefCnt;
|
||||
|
@ -2068,18 +2086,8 @@ RDFGenericBuilderImpl::BuildContentFromTemplate(nsIContent *aTemplateNode,
|
|||
|
||||
if (gXULSortService && isResourceElement)
|
||||
{
|
||||
if (mCache)
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
(nsIRDFDataSource **)&mCache,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
getter_AddRefs(mCache),
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
rv = gXULSortService->InsertContainerNode(mDB, &sortState,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Robert John Churchill <rjc@netscape.com>
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
*/
|
||||
|
||||
|
@ -131,10 +132,12 @@ static const char kXULNameSpaceURI[]
|
|||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name);
|
||||
DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, BookmarkSeparator);
|
||||
|
||||
|
||||
typedef struct _sortStruct {
|
||||
nsCOMPtr<nsIRDFResource> sortProperty;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty2;
|
||||
PRBool firstFlag;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
|
||||
nsCOMPtr<nsIRDFCompositeDataSource> db;
|
||||
nsCOMPtr<nsIRDFService> rdfService;
|
||||
nsCOMPtr<nsIRDFDataSource> mInner;
|
||||
|
@ -146,6 +149,7 @@ typedef struct _sortStruct {
|
|||
PRBool descendingSort;
|
||||
PRBool naturalOrderSort;
|
||||
PRBool inbetweenSeparatorSort;
|
||||
|
||||
} sortStruct, *sortPtr;
|
||||
|
||||
|
||||
|
@ -211,10 +215,9 @@ nsresult GetTreeCell(nsIContent *node, PRInt32 colIndex, nsIContent **cell);
|
|||
nsresult SortTreeChildren(nsIContent *container, sortPtr sortInfo);
|
||||
nsresult DoSort(nsIDOMNode* node, const nsString& sortResource, const nsString& sortDirection);
|
||||
|
||||
static nsresult GetCachedTarget(sortPtr sortInfo, nsIRDFResource* aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult);
|
||||
static nsresult GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProperty, const char *suffix, nsIRDFResource **res);
|
||||
static nsresult GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortProperty, sortPtr sortInfo, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty, sortPtr sortInfo, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetCachedTarget(sortPtr sortInfo, PRBool useCache, nsIRDFResource* aSource, nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult);
|
||||
static nsresult GetResourceValue(nsIRDFResource *res1, sortPtr sortInfo, PRBool first, PRBool useCache, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetNodeValue(nsIContent *node1, sortPtr sortInfo, PRBool first, nsIRDFNode **, PRBool &isCollationKey);
|
||||
static nsresult GetTreeCell(sortPtr sortInfo, nsIContent *node, PRInt32 cellIndex, nsIContent **cell);
|
||||
static nsresult GetNodeTextValue(sortPtr sortInfo, nsIContent *node, nsString & val);
|
||||
|
||||
|
@ -628,7 +631,7 @@ XULSortServiceImpl::SetSortHints(nsIContent *tree, const nsString &sortResource,
|
|||
tree->SetAttribute(kNameSpaceID_RDF, kResourceAtom, sortResource, PR_FALSE);
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
tree->SetAttribute(kNameSpaceID_RDF, kResource2Atom, sortDirection, PR_FALSE);
|
||||
tree->SetAttribute(kNameSpaceID_RDF, kResource2Atom, sortResource2, PR_FALSE);
|
||||
else tree->UnsetAttribute(kNameSpaceID_RDF, kResource2Atom, PR_FALSE);
|
||||
}
|
||||
else
|
||||
|
@ -911,103 +914,37 @@ XULSortServiceImpl::CompareNodes(nsIRDFNode *cellNode1, PRBool isCollationKey1,
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetCachedTarget(sortPtr sortInfo, nsIRDFResource* aSource,
|
||||
XULSortServiceImpl::GetCachedTarget(sortPtr sortInfo, PRBool useCache, nsIRDFResource* aSource,
|
||||
nsIRDFResource *aProperty, PRBool aTruthValue, nsIRDFNode **aResult)
|
||||
{
|
||||
nsresult rv = NS_OK, rvTemp;
|
||||
nsresult rv;
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
if (!(sortInfo->mInner))
|
||||
{
|
||||
// if we don't have a mInner, create one
|
||||
rvTemp = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
||||
rv = nsComponentManager::CreateInstance(kRDFInMemoryDataSourceCID,
|
||||
nsnull, NS_GET_IID(nsIRDFDataSource), (void **)&(sortInfo->mInner));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
}
|
||||
|
||||
rv = NS_RDF_NO_VALUE;
|
||||
if (sortInfo->mInner)
|
||||
{
|
||||
// else, if we do have a mInner, look for the resource in it
|
||||
rv = sortInfo->mInner->GetTarget(aSource, aProperty, aTruthValue, aResult);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && (rv == NS_RDF_NO_VALUE) && (sortInfo->db))
|
||||
{
|
||||
// if we don't have a cached value, look it up in the document's DB
|
||||
if (NS_SUCCEEDED(rv = (sortInfo->db)->GetTarget(aSource, aProperty,
|
||||
aTruthValue, aResult)) && (rv != NS_RDF_NO_VALUE))
|
||||
if (useCache == PR_TRUE)
|
||||
{
|
||||
// and if we have a value, cache it away in our mInner also
|
||||
rvTemp = sortInfo->mInner->Assert(aSource, aProperty, *aResult, PR_TRUE);
|
||||
// if we do have a mInner, look for the resource in it
|
||||
rv = sortInfo->mInner->GetTarget(aSource, aProperty, aTruthValue, aResult);
|
||||
}
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProperty, const char *suffix, nsIRDFResource **res)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
*res = nsnull;
|
||||
|
||||
const char *sortPropertyURI = nsnull;
|
||||
rv = sortProperty->GetValueConst(&sortPropertyURI);
|
||||
if (NS_SUCCEEDED(rv) && (sortPropertyURI))
|
||||
{
|
||||
nsAutoString resName(sortPropertyURI);
|
||||
if (suffix) resName += suffix;
|
||||
|
||||
if (!(sortInfo->resCache))
|
||||
else if (sortInfo->db)
|
||||
{
|
||||
// if we don't have a cache, create one
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(sortInfo->resCache));
|
||||
}
|
||||
else
|
||||
{
|
||||
// else, if we do have a cache, look for the resource in it
|
||||
PRUint32 numRes;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->resCache->Count(&numRes)))
|
||||
// if we don't have a cached value, look it up in the document's DB
|
||||
if (NS_SUCCEEDED(rv = (sortInfo->db)->GetTarget(aSource, aProperty,
|
||||
aTruthValue, aResult)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
PRUint32 loop;
|
||||
for (loop=0; loop<numRes; loop++)
|
||||
{
|
||||
nsCOMPtr<nsISupports> iSupports;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->resCache->GetElementAt(loop,
|
||||
getter_AddRefs(iSupports))))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> aRes = do_QueryInterface(iSupports);
|
||||
if (aRes)
|
||||
{
|
||||
const char *resURI = nsnull;
|
||||
if (NS_SUCCEEDED(rv = aRes->GetValueConst(&resURI)) && (resURI))
|
||||
{
|
||||
if (resName.Equals(resURI))
|
||||
{
|
||||
// found res in cache, so just return it
|
||||
*res = aRes;
|
||||
NS_ADDREF(*res);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*res))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> sortRes;
|
||||
if (NS_SUCCEEDED(rv = sortInfo->rdfService->GetUnicodeResource(resName.GetUnicode(),
|
||||
getter_AddRefs(sortRes))) && (sortRes))
|
||||
{
|
||||
*res = sortRes;
|
||||
NS_ADDREF(*res);
|
||||
|
||||
// and add it into the cache array
|
||||
if (sortInfo->resCache)
|
||||
{
|
||||
sortInfo->resCache->AppendElement(sortRes);
|
||||
}
|
||||
// and if we have a value, cache it away in our mInner also (ignore errors)
|
||||
sortInfo->mInner->Assert(aSource, aProperty, *aResult, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1017,7 +954,7 @@ XULSortServiceImpl::GetCachedResource(sortPtr sortInfo, nsIRDFResource *sortProp
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortProperty, sortPtr sortInfo,
|
||||
XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, sortPtr sortInfo, PRBool first, PRBool useCache,
|
||||
nsIRDFNode **target, PRBool &isCollationKey)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -1025,16 +962,17 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
*target = nsnull;
|
||||
isCollationKey = PR_FALSE;
|
||||
|
||||
if ((res1) && (sortInfo->naturalOrderSort == PR_FALSE) && (sortInfo->sortProperty))
|
||||
if ((res1) && (sortInfo->naturalOrderSort == PR_FALSE))
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> modSortRes;
|
||||
|
||||
// for any given property, first ask the graph for its value with "?collation=true" appended
|
||||
// to indicate that if there is a collation key available for this value, we want it
|
||||
if (NS_SUCCEEDED(rv = GetCachedResource(sortInfo, sortInfo->sortProperty, "?collation=true",
|
||||
getter_AddRefs(modSortRes))) && (modSortRes))
|
||||
|
||||
modSortRes = (first) ? sortInfo->sortPropertyColl : sortInfo->sortPropertyColl2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, modSortRes,
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
isCollationKey = PR_TRUE;
|
||||
|
@ -1046,10 +984,10 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
// to indicate that if there is any distinction between its display value and sorting
|
||||
// value, we want the sorting value (so that, for example, a mail datasource could strip
|
||||
// off a "Re:" on a mail message subject)
|
||||
if (NS_SUCCEEDED(rv = GetCachedResource(sortInfo, sortInfo->sortProperty, "?sort=true",
|
||||
getter_AddRefs(modSortRes))) && (modSortRes))
|
||||
modSortRes = (first) ? sortInfo->sortPropertySort : sortInfo->sortPropertySort2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, modSortRes,
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target)) && (rv != NS_RDF_NO_VALUE))
|
||||
{
|
||||
}
|
||||
|
@ -1058,9 +996,13 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
if (!(*target))
|
||||
{
|
||||
// if no collation key and no special sorting value, just get the property value
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, res1, sortProperty,
|
||||
PR_TRUE, target) && (rv != NS_RDF_NO_VALUE)))
|
||||
modSortRes = (first) ? sortInfo->sortProperty : sortInfo->sortProperty2;
|
||||
if (modSortRes)
|
||||
{
|
||||
if (NS_SUCCEEDED(rv = GetCachedTarget(sortInfo, useCache, res1, modSortRes,
|
||||
PR_TRUE, target) && (rv != NS_RDF_NO_VALUE)))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1070,7 +1012,7 @@ XULSortServiceImpl::GetResourceValue(nsIRDFResource *res1, nsIRDFResource *sortP
|
|||
|
||||
|
||||
nsresult
|
||||
XULSortServiceImpl::GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty, sortPtr sortInfo,
|
||||
XULSortServiceImpl::GetNodeValue(nsIContent *node1, sortPtr sortInfo, PRBool first,
|
||||
nsIRDFNode **theNode, PRBool &isCollationKey)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -1115,7 +1057,11 @@ XULSortServiceImpl::GetNodeValue(nsIContent *node1, nsIRDFResource *sortProperty
|
|||
{
|
||||
if (res1)
|
||||
{
|
||||
rv = GetResourceValue(res1, sortProperty, sortInfo, theNode, isCollationKey);
|
||||
rv = GetResourceValue(res1, sortInfo, first, PR_TRUE, theNode, isCollationKey);
|
||||
if ((rv == NS_RDF_NO_VALUE) || (!*theNode))
|
||||
{
|
||||
rv = GetResourceValue(res1, sortInfo, first, PR_FALSE, theNode, isCollationKey);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1247,13 +1193,8 @@ XULSortServiceImpl::InplaceSort(nsIContent *node1, nsIContent *node2, sortPtr so
|
|||
sortOrder = 0;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> cellNode1, cellNode2;
|
||||
GetNodeValue(node1, sortInfo->sortProperty, sortInfo, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo->sortProperty, sortInfo, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
if ((!cellNode1) && (!cellNode2) && (sortInfo->sortProperty2 == nsnull))
|
||||
{
|
||||
rv = GetNodeValue(node1, kNC_Name, sortInfo, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
rv = GetNodeValue(node2, kNC_Name, sortInfo, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
}
|
||||
GetNodeValue(node1, sortInfo, PR_TRUE, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo, PR_TRUE, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
|
||||
PRBool bothValid = PR_FALSE;
|
||||
rv = CompareNodes(cellNode1, isCollationKey1, cellNode2, isCollationKey2, bothValid, sortOrder);
|
||||
|
@ -1263,14 +1204,16 @@ XULSortServiceImpl::InplaceSort(nsIContent *node1, nsIContent *node2, sortPtr so
|
|||
// nodes appear to be equivalent, check for secondary sort criteria
|
||||
if (sortInfo->sortProperty2 != nsnull)
|
||||
{
|
||||
nsCOMPtr<nsIRDFResource> temp = sortInfo->sortProperty;
|
||||
sortInfo->sortProperty = sortInfo->sortProperty2;
|
||||
sortInfo->sortProperty2 = nsnull;
|
||||
cellNode1 = nsnull;
|
||||
cellNode2 = nsnull;
|
||||
isCollationKey1 = PR_FALSE;
|
||||
isCollationKey2 = PR_FALSE;
|
||||
|
||||
GetNodeValue(node1, sortInfo, PR_FALSE, getter_AddRefs(cellNode1), isCollationKey1);
|
||||
GetNodeValue(node2, sortInfo, PR_FALSE, getter_AddRefs(cellNode2), isCollationKey2);
|
||||
|
||||
rv = InplaceSort(node1, node2, sortInfo, sortOrder);
|
||||
|
||||
sortInfo->sortProperty2 = sortInfo->sortProperty;
|
||||
sortInfo->sortProperty = temp;
|
||||
bothValid = PR_FALSE;
|
||||
rv = CompareNodes(cellNode1, isCollationKey1, cellNode2, isCollationKey2, bothValid, sortOrder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1437,9 +1380,24 @@ XULSortServiceImpl::SortTreeChildren(nsIContent *container, sortPtr sortInfo)
|
|||
}
|
||||
|
||||
|
||||
// rjc: yes, I'm lame. For the moment, "class sortState" is defined both here and in
|
||||
// nsRDFGenericBuilder.cpp so any changes made here must also (exactly) be made there also.
|
||||
|
||||
typedef class sortState
|
||||
{
|
||||
public:
|
||||
nsAutoString sortResource, sortResource2;
|
||||
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
} sortStateClass;
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDataSource **cacheHandle, nsIContent *root,
|
||||
XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, sortState *sortState, nsIContent *root,
|
||||
nsIContent *trueParent, nsIContent *container, nsIContent *node, PRBool aNotify)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -1457,9 +1415,9 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
sortInfo.sortProperty = nsnull;
|
||||
sortInfo.sortProperty2 = nsnull;
|
||||
sortInfo.inbetweenSeparatorSort = PR_FALSE;
|
||||
if (cacheHandle != nsnull)
|
||||
if (sortState->mCache)
|
||||
{
|
||||
sortInfo.mInner = *cacheHandle; // Note: this can/might be null
|
||||
sortInfo.mInner = sortState->mCache; // Note: this can/might be null
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1505,13 +1463,71 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
|
||||
if (sortInfoAvailable)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
if (sortResource2.Length() > 0)
|
||||
if (sortState->sortResource.Equals(sortResource) && sortState->sortResource2.Equals(sortResource2))
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortInfo.sortProperty = sortState->sortProperty;
|
||||
sortInfo.sortProperty2 = sortState->sortProperty2;
|
||||
sortInfo.sortPropertyColl = sortState->sortPropertyColl;
|
||||
sortInfo.sortPropertyColl2 = sortState->sortPropertyColl2;
|
||||
sortInfo.sortPropertySort = sortState->sortPropertySort;
|
||||
sortInfo.sortPropertySort2 = sortState->sortPropertySort2;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsAutoString temp;
|
||||
|
||||
// either first time, or must have changing sorting info, so flush state cache
|
||||
sortState->sortProperty = nsnull; sortState->sortProperty2 = nsnull;
|
||||
sortState->sortPropertyColl = nsnull; sortState->sortPropertyColl2 = nsnull;
|
||||
sortState->sortPropertySort = nsnull; sortState->sortPropertySort2 = nsnull;
|
||||
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortResource = sortResource;
|
||||
sortState->sortProperty = sortInfo.sortProperty;
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertyColl = sortInfo.sortPropertyColl;
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertySort = sortInfo.sortPropertySort;
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortResource2 = sortResource2;
|
||||
sortState->sortProperty2 = sortInfo.sortProperty2;
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertyColl2 = sortInfo.sortPropertyColl2;
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
sortState->sortPropertySort2 = sortInfo.sortPropertySort2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// either first time, or must have changing sorting info, so flush state cache
|
||||
sortState->sortResource.Truncate();
|
||||
sortState->sortResource2.Truncate();
|
||||
|
||||
sortState->sortProperty = nsnull; sortState->sortProperty2 = nsnull;
|
||||
sortState->sortPropertyColl = nsnull; sortState->sortPropertyColl2 = nsnull;
|
||||
sortState->sortPropertySort = nsnull; sortState->sortPropertySort2 = nsnull;
|
||||
}
|
||||
|
||||
// set up sort order info
|
||||
|
@ -1634,10 +1650,9 @@ XULSortServiceImpl::InsertContainerNode(nsIRDFCompositeDataSource *db, nsIRDFDat
|
|||
container->AppendChildTo(node, aNotify);
|
||||
}
|
||||
|
||||
if ((cacheHandle) && (sortInfo.mInner) && ((*cacheHandle) != sortInfo.mInner.get()))
|
||||
if ((!sortState->mCache) && (sortInfo.mInner))
|
||||
{
|
||||
*cacheHandle = sortInfo.mInner;
|
||||
NS_ADDREF(*cacheHandle);
|
||||
sortState->mCache = sortInfo.mInner;
|
||||
}
|
||||
return(NS_OK);
|
||||
}
|
||||
|
@ -1695,10 +1710,6 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
sortInfo.kTreeCellAtom = kTreeCellAtom;
|
||||
sortInfo.kNameSpaceID_XUL = kNameSpaceID_XUL;
|
||||
|
||||
if (NS_FAILED(rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(),
|
||||
getter_AddRefs(sortInfo.sortProperty))))
|
||||
return(rv);
|
||||
|
||||
// determine new sort resource and direction to use
|
||||
if (sortDirection.EqualsIgnoreCase("natural"))
|
||||
{
|
||||
|
@ -1718,6 +1729,37 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
PRBool found;
|
||||
if (NS_FAILED(rv = GetSortColumnIndex(treeNode, sortResource, sortDirection, sortResource2,
|
||||
sortInfo.inbetweenSeparatorSort, sortInfo.colIndex, found))) return(rv);
|
||||
|
||||
rv = gRDFService->GetUnicodeResource(sortResource.GetUnicode(), getter_AddRefs(sortInfo.sortProperty));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
nsAutoString temp;
|
||||
temp = sortResource;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
if (sortResource2.Length() > 0)
|
||||
{
|
||||
rv = gRDFService->GetUnicodeResource(sortResource2.GetUnicode(), getter_AddRefs(sortInfo.sortProperty2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?collation=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertyColl2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
|
||||
temp = sortResource2;
|
||||
temp += "?sort=true";
|
||||
rv = gRDFService->GetUnicodeResource(temp.GetUnicode(), getter_AddRefs(sortInfo.sortPropertySort2));
|
||||
if (NS_FAILED(rv)) return(rv);
|
||||
}
|
||||
|
||||
SetSortHints(treeNode, sortResource, sortDirection, sortResource2, sortInfo.inbetweenSeparatorSort, found);
|
||||
|
||||
nsCOMPtr<nsIContent> treeBody;
|
||||
|
@ -1731,8 +1773,8 @@ XULSortServiceImpl::DoSort(nsIDOMNode* node, const nsString& sortResource,
|
|||
if (NS_FAILED(rv = treeBody->GetParent(*getter_AddRefs(treeParent)))) return(rv);
|
||||
if (NS_FAILED(rv = treeParent->IndexOf(treeBody, treeBodyIndex))) return(rv);
|
||||
if (NS_FAILED(rv = treeParent->RemoveChildAt(treeBodyIndex, PR_TRUE))) return(rv);
|
||||
|
||||
if (NS_FAILED(rv = treeParent->AppendChildTo(treeBody, PR_TRUE))) return(rv);
|
||||
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,22 @@ static NS_DEFINE_CID(kIHTMLElementFactoryIID, NS_IHTML_ELEMENT_FACTORY_IID);
|
|||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// rjc: yes, I'm lame. For the moment, "class sortState" is defined both here and in
|
||||
// nsXULSortService.cpp so any changes made here must also (exactly) be made there also.
|
||||
|
||||
typedef class sortState
|
||||
{
|
||||
public:
|
||||
// state match strings
|
||||
nsAutoString sortResource, sortResource2;
|
||||
|
||||
// state variables
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsIRDFResource> sortProperty, sortProperty2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertyColl, sortPropertyColl2;
|
||||
nsCOMPtr<nsIRDFResource> sortPropertySort, sortPropertySort2;
|
||||
} sortStateClass;
|
||||
|
||||
class RDFGenericBuilderImpl : public nsIRDFContentModelBuilder,
|
||||
public nsIRDFObserver
|
||||
{
|
||||
|
@ -309,7 +325,9 @@ protected:
|
|||
nsCOMPtr<nsIContent> mRoot;
|
||||
|
||||
nsCOMPtr<nsIRDFDataSource> mCache;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
sortState sortState;
|
||||
|
||||
// pseudo-constants
|
||||
static nsrefcnt gRefCnt;
|
||||
|
@ -2068,18 +2086,8 @@ RDFGenericBuilderImpl::BuildContentFromTemplate(nsIContent *aTemplateNode,
|
|||
|
||||
if (gXULSortService && isResourceElement)
|
||||
{
|
||||
if (mCache)
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
(nsIRDFDataSource **)&mCache,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = gXULSortService->InsertContainerNode(mDB,
|
||||
getter_AddRefs(mCache),
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
rv = gXULSortService->InsertContainerNode(mDB, &sortState,
|
||||
mRoot, trueParent, aRealNode, realKid, aNotify);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче